From babe0fd0e29aedfa2e1d473fbb3dcec915a3b575 Mon Sep 17 00:00:00 2001 From: rgrimes Date: Thu, 26 May 1994 05:23:31 +0000 Subject: BSD 4.4 Lite usr.sbin Sources --- usr.sbin/sendmail/FAQ | 343 + usr.sbin/sendmail/KNOWNBUGS | 131 + usr.sbin/sendmail/Makefile | 24 + usr.sbin/sendmail/READ_ME | 239 + usr.sbin/sendmail/RELEASE_NOTES | 2556 ++++++++ usr.sbin/sendmail/cf/README | 1232 ++++ usr.sbin/sendmail/cf/cf/Makefile | 86 + usr.sbin/sendmail/cf/cf/Makefile.dist | 85 + usr.sbin/sendmail/cf/cf/clientproto.mc | 49 + usr.sbin/sendmail/cf/cf/knecht.mc | 44 + usr.sbin/sendmail/cf/cf/mail.cs.mc | 55 + usr.sbin/sendmail/cf/cf/mail.eecs.mc | 54 + usr.sbin/sendmail/cf/cf/tcpproto.mc | 50 + usr.sbin/sendmail/cf/cf/ucbarpa.mc | 43 + usr.sbin/sendmail/cf/cf/ucbvax.mc | 101 + usr.sbin/sendmail/cf/cf/uucpproto.mc | 49 + usr.sbin/sendmail/cf/feature/allmasquerade.m4 | 41 + usr.sbin/sendmail/cf/feature/always_add_domain.m4 | 40 + usr.sbin/sendmail/cf/feature/bitdomain.m4 | 49 + usr.sbin/sendmail/cf/feature/domaintable.m4 | 40 + usr.sbin/sendmail/cf/feature/mailertable.m4 | 40 + usr.sbin/sendmail/cf/feature/nocanonify.m4 | 40 + usr.sbin/sendmail/cf/feature/nodns.m4 | 40 + usr.sbin/sendmail/cf/feature/notsticky.m4 | 40 + usr.sbin/sendmail/cf/feature/nouucp.m4 | 40 + usr.sbin/sendmail/cf/feature/nullclient.m4 | 61 + usr.sbin/sendmail/cf/feature/redirect.m4 | 48 + usr.sbin/sendmail/cf/feature/use_cw_file.m4 | 46 + usr.sbin/sendmail/cf/feature/uucpdomain.m4 | 49 + usr.sbin/sendmail/cf/hack/cssubdomain.m4 | 44 + usr.sbin/sendmail/cf/m4/cf.m4 | 149 + usr.sbin/sendmail/cf/m4/nullrelay.m4 | 302 + usr.sbin/sendmail/cf/m4/proto.m4 | 689 ++ usr.sbin/sendmail/cf/m4/version.m4 | 39 + usr.sbin/sendmail/cf/mailer/fax.m4 | 50 + usr.sbin/sendmail/cf/mailer/local.m4 | 66 + usr.sbin/sendmail/cf/mailer/pop.m4 | 53 + usr.sbin/sendmail/cf/mailer/smtp.m4 | 126 + usr.sbin/sendmail/cf/mailer/usenet.m4 | 47 + usr.sbin/sendmail/cf/mailer/uucp.m4 | 172 + usr.sbin/sendmail/cf/ostype/aix3.m4 | 40 + usr.sbin/sendmail/cf/ostype/aux.m4 | 43 + usr.sbin/sendmail/cf/ostype/bsd4.3.m4 | 39 + usr.sbin/sendmail/cf/ostype/bsd4.4.m4 | 42 + usr.sbin/sendmail/cf/ostype/bsdi1.0.m4 | 38 + usr.sbin/sendmail/cf/ostype/dgux.m4 | 39 + usr.sbin/sendmail/cf/ostype/domainos.m4 | 42 + usr.sbin/sendmail/cf/ostype/dynix3.2.m4 | 39 + usr.sbin/sendmail/cf/ostype/linux.m4 | 38 + usr.sbin/sendmail/cf/ostype/nextstep.m4 | 44 + usr.sbin/sendmail/cf/ostype/osf1.m4 | 41 + usr.sbin/sendmail/cf/ostype/riscos4.5.m4 | 42 + usr.sbin/sendmail/cf/ostype/sco3.2.m4 | 45 + usr.sbin/sendmail/cf/ostype/solaris2.m4 | 43 + usr.sbin/sendmail/cf/ostype/sunos3.5.m4 | 37 + usr.sbin/sendmail/cf/ostype/sunos4.1.m4 | 37 + usr.sbin/sendmail/cf/ostype/svr4.m4 | 45 + usr.sbin/sendmail/cf/sh/makeinfo.sh | 77 + usr.sbin/sendmail/cf/siteconfig/uucp.cogsci.m4 | 6 + usr.sbin/sendmail/cf/siteconfig/uucp.old.arpa.m4 | 4 + usr.sbin/sendmail/cf/siteconfig/uucp.ucbarpa.m4 | 1 + usr.sbin/sendmail/cf/siteconfig/uucp.ucbvax.m4 | 73 + usr.sbin/sendmail/contrib/README | 10 + usr.sbin/sendmail/contrib/bitdomain.c | 409 ++ usr.sbin/sendmail/contrib/converting.sun.configs | 446 ++ usr.sbin/sendmail/contrib/expn.pl | 1365 ++++ usr.sbin/sendmail/contrib/mail.local.linux | 205 + usr.sbin/sendmail/contrib/mh.patch | 193 + usr.sbin/sendmail/contrib/mmuegel | 2079 +++++++ usr.sbin/sendmail/contrib/oldbind.compat.c | 79 + usr.sbin/sendmail/contrib/xla/README | 207 + usr.sbin/sendmail/contrib/xla/xla.c | 532 ++ usr.sbin/sendmail/doc/changes/Makefile | 13 + usr.sbin/sendmail/doc/changes/changes.me | 997 +++ usr.sbin/sendmail/doc/changes/changes.ps | 1088 ++++ usr.sbin/sendmail/doc/intro/Makefile | 13 + usr.sbin/sendmail/doc/intro/intro.me | 1478 +++++ usr.sbin/sendmail/doc/intro/intro.ps | 1295 ++++ usr.sbin/sendmail/doc/op/Makefile | 13 + usr.sbin/sendmail/doc/op/op.me | 6921 +++++++++++++++++++++ usr.sbin/sendmail/doc/op/op.ps | 5477 ++++++++++++++++ usr.sbin/sendmail/doc/usenix/Makefile | 12 + usr.sbin/sendmail/doc/usenix/usenix.me | 1076 ++++ usr.sbin/sendmail/doc/usenix/usenix.ps | 1004 +++ usr.sbin/sendmail/mailstats/Makefile | 8 + usr.sbin/sendmail/mailstats/mailstats.c | 209 + usr.sbin/sendmail/makemap/Makefile | 8 + usr.sbin/sendmail/makemap/makemap.8 | 128 + usr.sbin/sendmail/makemap/makemap.c | 373 ++ usr.sbin/sendmail/praliases/Makefile | 9 + usr.sbin/sendmail/praliases/praliases.c | 132 + usr.sbin/sendmail/src/Makefile | 42 + usr.sbin/sendmail/src/READ_ME | 872 +++ usr.sbin/sendmail/src/TRACEFLAGS | 64 + usr.sbin/sendmail/src/alias.c | 770 +++ usr.sbin/sendmail/src/aliases.5 | 106 + usr.sbin/sendmail/src/arpadate.c | 173 + usr.sbin/sendmail/src/clock.c | 276 + usr.sbin/sendmail/src/collect.c | 579 ++ usr.sbin/sendmail/src/conf.c | 2377 +++++++ usr.sbin/sendmail/src/conf.h | 1191 ++++ usr.sbin/sendmail/src/convtime.c | 197 + usr.sbin/sendmail/src/daemon.c | 1547 +++++ usr.sbin/sendmail/src/deliver.c | 2409 +++++++ usr.sbin/sendmail/src/domain.c | 769 +++ usr.sbin/sendmail/src/envelope.c | 777 +++ usr.sbin/sendmail/src/err.c | 561 ++ usr.sbin/sendmail/src/headers.c | 1192 ++++ usr.sbin/sendmail/src/macro.c | 279 + usr.sbin/sendmail/src/mailq.1 | 88 + usr.sbin/sendmail/src/mailstats.h | 49 + usr.sbin/sendmail/src/main.c | 1479 +++++ usr.sbin/sendmail/src/makesendmail | 113 + usr.sbin/sendmail/src/map.c | 1339 ++++ usr.sbin/sendmail/src/mci.c | 398 ++ usr.sbin/sendmail/src/newaliases.1 | 68 + usr.sbin/sendmail/src/parseaddr.c | 1964 ++++++ usr.sbin/sendmail/src/pathnames.h | 46 + usr.sbin/sendmail/src/queue.c | 1571 +++++ usr.sbin/sendmail/src/readcf.c | 1681 +++++ usr.sbin/sendmail/src/recipient.c | 1059 ++++ usr.sbin/sendmail/src/savemail.c | 833 +++ usr.sbin/sendmail/src/sendmail.8 | 501 ++ usr.sbin/sendmail/src/sendmail.h | 973 +++ usr.sbin/sendmail/src/sendmail.hf | 58 + usr.sbin/sendmail/src/srvrsmtp.c | 1032 +++ usr.sbin/sendmail/src/stab.c | 166 + usr.sbin/sendmail/src/stats.c | 130 + usr.sbin/sendmail/src/sysexits.c | 67 + usr.sbin/sendmail/src/trace.c | 131 + usr.sbin/sendmail/src/udb.c | 985 +++ usr.sbin/sendmail/src/useful.h | 77 + usr.sbin/sendmail/src/usersmtp.c | 905 +++ usr.sbin/sendmail/src/util.c | 1467 +++++ usr.sbin/sendmail/src/version.c | 39 + 135 files changed, 65486 insertions(+) create mode 100644 usr.sbin/sendmail/FAQ create mode 100644 usr.sbin/sendmail/KNOWNBUGS create mode 100644 usr.sbin/sendmail/Makefile create mode 100644 usr.sbin/sendmail/READ_ME create mode 100644 usr.sbin/sendmail/RELEASE_NOTES create mode 100644 usr.sbin/sendmail/cf/README create mode 100644 usr.sbin/sendmail/cf/cf/Makefile create mode 100644 usr.sbin/sendmail/cf/cf/Makefile.dist create mode 100644 usr.sbin/sendmail/cf/cf/clientproto.mc create mode 100644 usr.sbin/sendmail/cf/cf/knecht.mc create mode 100644 usr.sbin/sendmail/cf/cf/mail.cs.mc create mode 100644 usr.sbin/sendmail/cf/cf/mail.eecs.mc create mode 100644 usr.sbin/sendmail/cf/cf/tcpproto.mc create mode 100644 usr.sbin/sendmail/cf/cf/ucbarpa.mc create mode 100644 usr.sbin/sendmail/cf/cf/ucbvax.mc create mode 100644 usr.sbin/sendmail/cf/cf/uucpproto.mc create mode 100644 usr.sbin/sendmail/cf/feature/allmasquerade.m4 create mode 100644 usr.sbin/sendmail/cf/feature/always_add_domain.m4 create mode 100644 usr.sbin/sendmail/cf/feature/bitdomain.m4 create mode 100644 usr.sbin/sendmail/cf/feature/domaintable.m4 create mode 100644 usr.sbin/sendmail/cf/feature/mailertable.m4 create mode 100644 usr.sbin/sendmail/cf/feature/nocanonify.m4 create mode 100644 usr.sbin/sendmail/cf/feature/nodns.m4 create mode 100644 usr.sbin/sendmail/cf/feature/notsticky.m4 create mode 100644 usr.sbin/sendmail/cf/feature/nouucp.m4 create mode 100644 usr.sbin/sendmail/cf/feature/nullclient.m4 create mode 100644 usr.sbin/sendmail/cf/feature/redirect.m4 create mode 100644 usr.sbin/sendmail/cf/feature/use_cw_file.m4 create mode 100644 usr.sbin/sendmail/cf/feature/uucpdomain.m4 create mode 100644 usr.sbin/sendmail/cf/hack/cssubdomain.m4 create mode 100644 usr.sbin/sendmail/cf/m4/cf.m4 create mode 100644 usr.sbin/sendmail/cf/m4/nullrelay.m4 create mode 100644 usr.sbin/sendmail/cf/m4/proto.m4 create mode 100644 usr.sbin/sendmail/cf/m4/version.m4 create mode 100644 usr.sbin/sendmail/cf/mailer/fax.m4 create mode 100644 usr.sbin/sendmail/cf/mailer/local.m4 create mode 100644 usr.sbin/sendmail/cf/mailer/pop.m4 create mode 100644 usr.sbin/sendmail/cf/mailer/smtp.m4 create mode 100644 usr.sbin/sendmail/cf/mailer/usenet.m4 create mode 100644 usr.sbin/sendmail/cf/mailer/uucp.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/aix3.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/aux.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/bsd4.3.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/bsd4.4.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/bsdi1.0.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/dgux.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/domainos.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/dynix3.2.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/linux.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/nextstep.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/osf1.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/riscos4.5.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/sco3.2.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/solaris2.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/sunos3.5.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/sunos4.1.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/svr4.m4 create mode 100644 usr.sbin/sendmail/cf/sh/makeinfo.sh create mode 100644 usr.sbin/sendmail/cf/siteconfig/uucp.cogsci.m4 create mode 100644 usr.sbin/sendmail/cf/siteconfig/uucp.old.arpa.m4 create mode 100644 usr.sbin/sendmail/cf/siteconfig/uucp.ucbarpa.m4 create mode 100644 usr.sbin/sendmail/cf/siteconfig/uucp.ucbvax.m4 create mode 100644 usr.sbin/sendmail/contrib/README create mode 100644 usr.sbin/sendmail/contrib/bitdomain.c create mode 100644 usr.sbin/sendmail/contrib/converting.sun.configs create mode 100755 usr.sbin/sendmail/contrib/expn.pl create mode 100644 usr.sbin/sendmail/contrib/mail.local.linux create mode 100644 usr.sbin/sendmail/contrib/mh.patch create mode 100644 usr.sbin/sendmail/contrib/mmuegel create mode 100644 usr.sbin/sendmail/contrib/oldbind.compat.c create mode 100644 usr.sbin/sendmail/contrib/xla/README create mode 100644 usr.sbin/sendmail/contrib/xla/xla.c create mode 100644 usr.sbin/sendmail/doc/changes/Makefile create mode 100644 usr.sbin/sendmail/doc/changes/changes.me create mode 100644 usr.sbin/sendmail/doc/changes/changes.ps create mode 100644 usr.sbin/sendmail/doc/intro/Makefile create mode 100644 usr.sbin/sendmail/doc/intro/intro.me create mode 100644 usr.sbin/sendmail/doc/intro/intro.ps create mode 100644 usr.sbin/sendmail/doc/op/Makefile create mode 100644 usr.sbin/sendmail/doc/op/op.me create mode 100644 usr.sbin/sendmail/doc/op/op.ps create mode 100644 usr.sbin/sendmail/doc/usenix/Makefile create mode 100644 usr.sbin/sendmail/doc/usenix/usenix.me create mode 100644 usr.sbin/sendmail/doc/usenix/usenix.ps create mode 100644 usr.sbin/sendmail/mailstats/Makefile create mode 100644 usr.sbin/sendmail/mailstats/mailstats.c create mode 100644 usr.sbin/sendmail/makemap/Makefile create mode 100644 usr.sbin/sendmail/makemap/makemap.8 create mode 100644 usr.sbin/sendmail/makemap/makemap.c create mode 100644 usr.sbin/sendmail/praliases/Makefile create mode 100644 usr.sbin/sendmail/praliases/praliases.c create mode 100644 usr.sbin/sendmail/src/Makefile create mode 100644 usr.sbin/sendmail/src/READ_ME create mode 100644 usr.sbin/sendmail/src/TRACEFLAGS create mode 100644 usr.sbin/sendmail/src/alias.c create mode 100644 usr.sbin/sendmail/src/aliases.5 create mode 100644 usr.sbin/sendmail/src/arpadate.c create mode 100644 usr.sbin/sendmail/src/clock.c create mode 100644 usr.sbin/sendmail/src/collect.c create mode 100644 usr.sbin/sendmail/src/conf.c create mode 100644 usr.sbin/sendmail/src/conf.h create mode 100644 usr.sbin/sendmail/src/convtime.c create mode 100644 usr.sbin/sendmail/src/daemon.c create mode 100644 usr.sbin/sendmail/src/deliver.c create mode 100644 usr.sbin/sendmail/src/domain.c create mode 100644 usr.sbin/sendmail/src/envelope.c create mode 100644 usr.sbin/sendmail/src/err.c create mode 100644 usr.sbin/sendmail/src/headers.c create mode 100644 usr.sbin/sendmail/src/macro.c create mode 100644 usr.sbin/sendmail/src/mailq.1 create mode 100644 usr.sbin/sendmail/src/mailstats.h create mode 100644 usr.sbin/sendmail/src/main.c create mode 100644 usr.sbin/sendmail/src/makesendmail create mode 100644 usr.sbin/sendmail/src/map.c create mode 100644 usr.sbin/sendmail/src/mci.c create mode 100644 usr.sbin/sendmail/src/newaliases.1 create mode 100644 usr.sbin/sendmail/src/parseaddr.c create mode 100644 usr.sbin/sendmail/src/pathnames.h create mode 100644 usr.sbin/sendmail/src/queue.c create mode 100644 usr.sbin/sendmail/src/readcf.c create mode 100644 usr.sbin/sendmail/src/recipient.c create mode 100644 usr.sbin/sendmail/src/savemail.c create mode 100644 usr.sbin/sendmail/src/sendmail.8 create mode 100644 usr.sbin/sendmail/src/sendmail.h create mode 100644 usr.sbin/sendmail/src/sendmail.hf create mode 100644 usr.sbin/sendmail/src/srvrsmtp.c create mode 100644 usr.sbin/sendmail/src/stab.c create mode 100644 usr.sbin/sendmail/src/stats.c create mode 100644 usr.sbin/sendmail/src/sysexits.c create mode 100644 usr.sbin/sendmail/src/trace.c create mode 100644 usr.sbin/sendmail/src/udb.c create mode 100644 usr.sbin/sendmail/src/useful.h create mode 100644 usr.sbin/sendmail/src/usersmtp.c create mode 100644 usr.sbin/sendmail/src/util.c create mode 100644 usr.sbin/sendmail/src/version.c (limited to 'usr.sbin') 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 ... 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
'' 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 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 , + , or 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 + . + 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:'' 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 . + 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 + . + 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 . + NetBSD from Adam Glass . + 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 around + them in non-SMTP envelopes (SMTP envelopes already do + this properly). + Avoid wierd headers on unbalanced punctuation of the form: + ``Joe User ; 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 + ). + 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 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: set sender to
+ 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 ), 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 `` '', auto-quote the first + ``'' part, giving ``"" ''. 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 -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 + . + Solaris 2 compatibility changes. Provided by Bob Cunningham + , John Oleynick + + 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 " $3 + the input "user@a.b.c" failed instead of being properly + rewritten as "user@a..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 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 . + 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 + + @(#)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(`') + +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 "@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") 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 ..." 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
'' 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 + ... + 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 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 + +# 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 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 s through +R< @ $+ > $* $@ < @ $1 > $2 resolve + +# 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 +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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() { + 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() { + 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() { + 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 = ; + 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] + # [NAME] <[(NAME)] ADDR + # ADDR [(NAME)] + # (NAME) ADDR + # [(NAME)] + # + if ($newaddr =~ /^\<(.*)\>$/) { + print "\n" if $debug; + $newaddr = &trim($1); + print "na = $newaddr\n" if $debug; + } + if ($newaddr =~ /^([^\<\>]*)\<([^\<\>]*)\>([^\<\>]*)$/) { + # address has a < > pair in it. + print "N:$1 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() { + 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(); + 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 =~ /^\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\ \ \ \ 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 +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(V122.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,;'%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@2%DW9J%<)AH@ +MK$$:]"@(D4Z:1J4@L*F&&0\)X=^TA4)I5G0I6$NE,(M6:"19I1A5H)L<2C@ +M'+UYV6=Q!YI!QQTL4IMJL%C",6EUR#:J[,'^C;$&GG>P,5]PV4H97@*[^A(\7$7/ZGCA:>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#(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`A6]>XG +MA=1LCPK=^U[XQK>\W_$OADQP(JY\V$;X13$)OAL"%0Z(/4`609"$',+QP!@$ +M)EQH"E`X9!(:>2'Y%2&$O"%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\$"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=RR%[NP9"0PJ$$-!B.3FMBD(XSAR0T@8]OF#N5,E_D(9[@R +M7>=:][K8E:IIVN.,= +M>=G+/+9*3YH@)H?VC!4UFPH4O+B%M0%%RT`(4A"#%#6J"#&*0A;"D(8.=H2&'H7,420CE))`Y:0.1VE*N*K2E03,L;0E4!P9!@TOU8%29*5AIFIFK>A/D(=/*R.A!=&+?>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.SKK.&-/^KV6G3X%@:_`0YB@B,<@+Z&.&4OKD6.JUEQ)'>T`)G!;MT<7N>&_P[5=D7=7>]^%SQ=&@]YRF.>&=&H +MQNH!-'MOC"/XQ$<^\Z%O"NK[^?L"VL7Y^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($/Y4QL05=``(] +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(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"9F<:1\U0R-AL'($>1H#R9F8*8478@9D +M<"'3EA"<607%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`: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``>*)S5>;,">@KH#*[4H8`)T8+5LD*>TJYA/ZQK# +M809-"@<":@085P+%@;S=>:IMT)2VB[NZNY@),+9;``-9Z)XGP`4P<`*<.;(^ +M.[:>&`/69`;Z.0[W8:P3KH\`A(`9C\+?H^XG&BZK+ +M6P.3JZ2]FU;Y,08H<`(^<`+!"0=Y2KG@>[(SNJ\)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*2']=;6=>8EN:085<@9;,!==<"'X809; +M@`,J@!,R0`/IC)MGL06H-#]RFT=.D+;4^994BV@VTLU_`C%EP+KJ6<0J@*FH +M003U03)#TA]L]:5A9Y,$'K7 +MG,N+VL6T$/=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_!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:"*-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:)#ODU*>J#(\S*&*8NW*VJWM\PX.B>+.21_KFD3&:C:^E)GNX+SNE_">]C\*$) +M`,,&#S`V7LTXJ^5O^>0)$>583MJ7&JNWHR:+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*6+C'+`>WZ>%]F[4J +M@`902YK$#W)\J/TAYYM9JS)N<-8YW?R6TB]?8`9J,1!Y\-^&*#5?PTSA;7IB+#,`!R?6D +M9E\.,X#<3V%]"*3``.<-=B)%V(\.4,!NIZ0JFX"#="`P\TD)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&`@$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!'#`9GK`"Q@5C,4%[*-?)`;F@'M@%?%H;RV6P4@`!@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(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<*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;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/\)+"@`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,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!$)&`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 +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 + + + 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" +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 &mH 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 +;# +;# 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 = ; +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 () +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 () +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: +;# +;# ((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 +((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 .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 . +.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 +# +# 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 +# +# 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 +*/ + +#include +#include +#include +#include + +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 + * (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 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'' +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 '' 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')-.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 F02.5 E F1 +(\215ag has been added to pass in body type information.)2.5 E(The)127 658.8 Q +F03.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 F02.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 F04.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 ')-.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 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 +.)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 )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 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 " " > /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 " " > /dev/console + mv $tffile $qffile + else + echo \-n " " > /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 " " > /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 " " > /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 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 " +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 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 " +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: +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 " " > /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 " " > /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 " " > /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 " " > /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 " " > /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 F02.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 F03.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 F03.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 F02.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 F02.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 F03.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 +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 F02.5 E F1 +(option; the syntax is:)2.5 E(deb)142 433.8 Q(ug-\215ag:)-.2 E F0200.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 F02.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 F02.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 F02.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 F02.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 F02.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 F32.47 E F0(z\))2.2 E +F3(+)2.2 E F1(\()2.2 E F2(nrcpt).36 E F32.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 F03.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 F03.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 +F02.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 ).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 +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 F03.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 F02.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(\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 F04.388 E F1(or)4.388 E F04.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 F03.249 E F1 +(and)3.249 E F03.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 E117 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 )-.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 F02.965 E F1(or)2.965 +E F02.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 +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 F0A 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 F02.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 F02.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 F02.5 E F1 +(\215ag has been added to pass in body type information.)2.5 E(The)127 610.8 Q +F02.5 E F1(\215ag has been added to pass in protocol information.)2.5 E +(The)127 627 Q F02.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 F04.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 \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 E72 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 Q72 325.8 Q F2(type)A F1 +(Indicate body type.)144 325.8 Q72 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 Q72 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 E72 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(.)A72 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(.)A72 +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 E72 487.2 Q F2(addr)2.5 E F1(An obsolete form of)144 487.2 Q/F3 10 +/Times-Bold@0 SF2.5 E F1(.)A72 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 Q72 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 Q72 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 +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 Q72 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 +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: ).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 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 +.)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 )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 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 +#include +#include + +#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 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 +#include +#include +#include +#include +#include +#include "useful.h" +#include "conf.h" + +#ifdef NDBM +#include +#endif + +#ifdef NEWDB +#include +#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 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 +#include +#ifdef NEWDB +#include +#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 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 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 ), + 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 , , + , or 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 + #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" + 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 + , 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 + #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 + 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" + 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 . + 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 + +#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 +# 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 +# include +# include +# include + +/* +** 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 +#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 + +#ifndef LA_AVENRUN +# ifdef SYSTEM5 +# define LA_AVENRUN "avenrun" +# else +# define LA_AVENRUN "_avenrun" +# endif +#endif + +/* _PATH_UNIX should be defined in */ +#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 + +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 +#else +# include +#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 + +/* 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 +# endif +# ifdef BSD4_4 +# include +# include +# 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 +#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 + +/* + * 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 implementation */ +#define SFS_MOUNT 4 /* use implementation */ +#define SFS_STATFS 5 /* use implementation */ +#define SFS_STATVFS 6 /* use implementation */ + +#ifndef SFS_TYPE +# define SFS_TYPE SFS_NONE +#endif + +#if SFS_TYPE == SFS_USTAT +# include +#endif +#if SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS +# include +#endif +#if SFS_TYPE == SFS_VFS +# include +#endif +#if SFS_TYPE == SFS_MOUNT +# include +#endif +#if SFS_TYPE == SFS_STATVFS +# include +#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 + +/* + * 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 + +# 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 +# include +# include +# include +# include +# include +# include + +/********************************************************************** +** 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 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 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 +# 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 statfs() implementation */ +# include + +# ifdef SUNOS403 + /* special tweaking for SunOS 4.0.3 */ +# include +# 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 +# include + +# 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 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 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 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 +# define ERRLIST_PREDEFINED /* don't declare sys_errlist */ +# ifndef LA_TYPE +# define LA_TYPE LA_SUBR +# endif +# define SFS_TYPE SFS_MOUNT /* use 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 +# define ERRLIST_PREDEFINED /* don't declare sys_errlist */ +# define SFS_TYPE SFS_MOUNT /* use 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 +# define ERRLIST_PREDEFINED /* don't declare sys_errlist */ +# ifndef LA_TYPE +# define LA_TYPE LA_SUBR +# endif +# define SFS_TYPE SFS_MOUNT /* use 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 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 ). +** 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 statfs() impl */ +# undef NETUNIX /* no unix domain socket support */ +#endif + + +/* +** ConvexOS 11.0 and later +** +** "Todd C. Miller" 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 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 +** Florian La Roche +** Karl London +** +** 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 */ +# ifndef LA_TYPE +# define LA_TYPE LA_PROCSTR +# endif +# define SFS_TYPE SFS_VFS /* use statfs() impl */ +# include +# undef atol /* wounded in */ +#endif + + +/* +** DELL SVR4 Issue 2.2, and others +** From Kimmo Suominen +** +** It's on #ifdef DELL_SVR4 because Solaris also gets __svr4__ +** defined, and the definitions conflict. +** +** Peter Wemm 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 +# 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 statfs() implementation */ +# undef WIFEXITED +# undef WEXITSTATUS +#endif + + +/* +** Encore UMAX V +** +** Not extensively tested. +*/ + +#ifdef UMAXV +# include +# 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 . +** +** 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 . +*/ + +#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 */ +# 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 . +*/ + +#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 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 +*/ + +#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 & Don Lewis +** +** 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 . +*/ + +#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 +*/ + +#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 . +*/ + +#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 +# 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 + +# define VA_LOCAL_DECL va_list ap; +# define VA_START(f) va_start(ap, f) +# define VA_END va_end(ap) + +# else + +# include + +# define VA_LOCAL_DECL va_list ap; +# define VA_START(f) va_start(ap) +# define VA_END va_end(ap) + +# endif + +#ifdef HASUNAME +# include +# 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 +# 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 +#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 +# include + +#if NAMED_BIND +# include +# include +#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 +#include +#if NAMED_BIND +#include +#include + +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 " 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 +#include +#include +#include + +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) ? "" : 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 + +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 + +/* +** 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 +# include +# include + +/* +** 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 +# 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 = ""; + for (h = e->e_header; h != NULL; h = h->h_link) + { + if (h->h_value == NULL) + { + if (tTd(32, 1)) + printf("%s: \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 +#include +#endif +#include + +# 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
\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 ? "" : 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 +#endif +#ifdef NEWDB +#include +#endif +#ifdef NIS +#include +#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 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 : ""); + 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 */ + 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 +# include +# include + +# 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 +# include +#if NAMED_BIND +# include +# include +#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 + +/* +** 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 + +/* +** 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include "conf.h" +# include "useful.h" + +# ifdef LOG +# include +# endif /* LOG */ + +# ifdef DAEMON +# include +# endif +# ifdef NETUNIX +# include +# endif +# ifdef NETINET +# include +# endif +# ifdef NETISO +# include +# endif +# ifdef NETNS +# include +# endif +# ifdef NETX25 +# include +# 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 */ +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 ". +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 [ ] +help The HELP command gives help info. +helo HELO +helo Introduce yourself. +ehlo EHLO +ehlo Introduce yourself, and request extended SMTP mode. +mail MAIL FROM: +mail Specifies the sender. +rcpt RCPT TO: +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 +vrfy Verify an address. If you want to see what it aliases +vrfy to, use EXPN instead. +expn EXPN +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: +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: +soml Send or mail. If the user is logged in, send directly, +soml otherwise mail. Not supported in this implementation. +saml SAML FROM: +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 + +# 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 ? "" : 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.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 +#include +#include + +#ifdef HESIOD +#include +#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 + +/* 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 +# include + +# 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 (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 + /* +** 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(""); + 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 + +#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 in line. +** +** Looks for the combination and turns it into the +** UNIX canonical character. It only takes one line, +** i.e., it is assumed that the first 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 +#include + +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"; -- cgit v1.1 From 4064c975aecd240a5063dada3fb0df210fb8592f Mon Sep 17 00:00:00 2001 From: rgrimes Date: Thu, 26 May 1994 05:23:31 +0000 Subject: BSD 4.4 Lite usr.sbin Sources --- usr.sbin/quot/quot.8 | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 usr.sbin/quot/quot.8 (limited to 'usr.sbin') diff --git a/usr.sbin/quot/quot.8 b/usr.sbin/quot/quot.8 new file mode 100644 index 0000000..b1aefde --- /dev/null +++ b/usr.sbin/quot/quot.8 @@ -0,0 +1,84 @@ +.\" Copyright (c) 1980, 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. +.\" +.\" @(#)quot.8 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt QUOT 8 +.Os BSD 4 +.Sh NAME +.Nm quot +.Nd display total block usage per user for a file system +.Sh SYNOPSIS +.Nm quot +.Op Fl ncf +.Op Ar filesystem Ar ... +.Sh DESCRIPTION +The +.Nm quot +command +displays the total count of blocks owned by a user for the filesystem +.Ar filesystem . +If the filesystem option +.Ar filesystem +is not specified, +the file systems listed in +.Pa /etc/fstab +are used. +The following options are available: +.Bl -tag -width Ds +.It Fl c +Display information on file size and block usage. The file sizes +are listed in the first column, the second column contains a count +of how many files of that size were found and the third column +lists the cumulative block usage for the displayed size and all smaller +files. +.It Fl f +For each user, +the number of files (inodes) owned is displayed in addition +to the block usage. +.It Fl n +A list sorted by block usage is displayed. +This is the result of +.Nm quot +executing the following command: +.Bd -literal -offset indent +ncheck filesystem \&| sort +0n \&| quot \-n filesystem +.Ed +.El +.Sh SEE ALSO +.Xr ls 1 , +.Xr du 1 +.Sh HISTORY +The +.Nm +command appeared in +.At 32v . -- cgit v1.1 From 2233bc697f5b3c6554e87ec91137e1740ea659f5 Mon Sep 17 00:00:00 2001 From: rgrimes Date: Thu, 26 May 1994 05:23:31 +0000 Subject: BSD 4.4 Lite usr.sbin Sources --- usr.sbin/portmap/Makefile | 8 + usr.sbin/portmap/portmap.8 | 110 +++++++++ usr.sbin/portmap/portmap.c | 541 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 659 insertions(+) create mode 100644 usr.sbin/portmap/Makefile create mode 100644 usr.sbin/portmap/portmap.8 create mode 100644 usr.sbin/portmap/portmap.c (limited to 'usr.sbin') diff --git a/usr.sbin/portmap/Makefile b/usr.sbin/portmap/Makefile new file mode 100644 index 0000000..244a192 --- /dev/null +++ b/usr.sbin/portmap/Makefile @@ -0,0 +1,8 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= portmap +DPADD= ${LIBRPC} +LDADD= -lrpc +MAN8= portmap.0 + +.include diff --git a/usr.sbin/portmap/portmap.8 b/usr.sbin/portmap/portmap.8 new file mode 100644 index 0000000..a651f5f --- /dev/null +++ b/usr.sbin/portmap/portmap.8 @@ -0,0 +1,110 @@ +.\" Copyright (c) 1987 Sun Microsystems +.\" Copyright (c) 1990, 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. +.\" +.\" @(#)portmap.8 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt PORTMAP 8 +.Os BSD 4.3 +.Sh NAME +.Nm portmap +.Nd +.Tn DARPA +port to +.Tn RPC +program number mapper +.Sh SYNOPSIS +.Nm portmap +.Op Fl d +.Sh DESCRIPTION +.Nm Portmap +is a server that converts +.Tn RPC +program numbers into +.Tn DARPA +protocol port numbers. +It must be running in order to make +.Tn RPC +calls. +.Pp +When an +.Tn RPC +server is started, it will tell +.Nm portmap +what port number it is listening to, and what +.Tn RPC +program numbers it is prepared to serve. +When a client wishes to make an +.Tn RPC +call to a given program number, +it will first contact +.Nm portmap +on the server machine to determine +the port number where +.Tn RPC +packets should be sent. +.Pp +.Nm Portmap +must be started before any +.Tn RPC +servers are invoked. +.Pp +Normally +.Nm portmap +forks and dissociates itself from the terminal +like any other daemon. +.Nm Portmap +then logs errors using +.Xr syslog 3 . +.Pp +Option available: +.Bl -tag -width Ds +.It Fl d +(debug) prevents +.Nm portmap +from running as a daemon, +and causes errors and debugging information +to be printed to the standard error output. +.El +.Sh SEE ALSO +.Xr inetd.conf 5 , +.Xr rpcinfo 8 , +.Xr inetd 8 +.Sh BUGS +If +.Nm portmap +crashes, all servers must be restarted. +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.3 diff --git a/usr.sbin/portmap/portmap.c b/usr.sbin/portmap/portmap.c new file mode 100644 index 0000000..3118a28 --- /dev/null +++ b/usr.sbin/portmap/portmap.c @@ -0,0 +1,541 @@ +/*- + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1990, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)portmap.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* +@(#)portmap.c 2.3 88/08/11 4.0 RPCSRC +static char sccsid[] = "@(#)portmap.c 1.32 87/08/06 Copyr 1984 Sun Micro"; +*/ + +/* + * portmap.c, Implements the program,version to port number mapping for + * rpc. + */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void reg_service(); +void reap(); +static void callit(); +struct pmaplist *pmaplist; +int debugging = 0; +extern int errno; + +main(argc, argv) + int argc; + char **argv; +{ + SVCXPRT *xprt; + int sock, c; + struct sockaddr_in addr; + int len = sizeof(struct sockaddr_in); + register struct pmaplist *pml; + + while ((c = getopt(argc, argv, "d")) != EOF) { + switch (c) { + + case 'd': + debugging = 1; + break; + + default: + (void) fprintf(stderr, "usage: %s [-d]\n", argv[0]); + exit(1); + } + } + + if (!debugging && daemon(0, 0)) { + (void) fprintf(stderr, "portmap: fork: %s", strerror(errno)); + exit(1); + } + + openlog("portmap", debugging ? LOG_PID | LOG_PERROR : LOG_PID, + LOG_DAEMON); + + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + syslog(LOG_ERR, "cannot create udp socket: %m"); + exit(1); + } + + addr.sin_addr.s_addr = 0; + addr.sin_family = AF_INET; + addr.sin_port = htons(PMAPPORT); + if (bind(sock, (struct sockaddr *)&addr, len) != 0) { + syslog(LOG_ERR, "cannot bind udp: %m"); + exit(1); + } + + if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) { + syslog(LOG_ERR, "couldn't do udp_create"); + exit(1); + } + /* make an entry for ourself */ + pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist)); + pml->pml_next = 0; + pml->pml_map.pm_prog = PMAPPROG; + pml->pml_map.pm_vers = PMAPVERS; + pml->pml_map.pm_prot = IPPROTO_UDP; + pml->pml_map.pm_port = PMAPPORT; + pmaplist = pml; + + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + syslog(LOG_ERR, "cannot create tcp socket: %m"); + exit(1); + } + if (bind(sock, (struct sockaddr *)&addr, len) != 0) { + syslog(LOG_ERR, "cannot bind udp: %m"); + exit(1); + } + if ((xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE)) + == (SVCXPRT *)NULL) { + syslog(LOG_ERR, "couldn't do tcp_create"); + exit(1); + } + /* make an entry for ourself */ + pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist)); + pml->pml_map.pm_prog = PMAPPROG; + pml->pml_map.pm_vers = PMAPVERS; + pml->pml_map.pm_prot = IPPROTO_TCP; + pml->pml_map.pm_port = PMAPPORT; + pml->pml_next = pmaplist; + pmaplist = pml; + + (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE); + + (void)signal(SIGCHLD, reap); + svc_run(); + syslog(LOG_ERR, "run_svc returned unexpectedly"); + abort(); +} + +#ifndef lint +/* need to override perror calls in rpc library */ +void +perror(what) + const char *what; +{ + + syslog(LOG_ERR, "%s: %m", what); +} +#endif + +static struct pmaplist * +find_service(prog, vers, prot) + u_long prog, vers, prot; +{ + register struct pmaplist *hit = NULL; + register struct pmaplist *pml; + + for (pml = pmaplist; pml != NULL; pml = pml->pml_next) { + if ((pml->pml_map.pm_prog != prog) || + (pml->pml_map.pm_prot != prot)) + continue; + hit = pml; + if (pml->pml_map.pm_vers == vers) + break; + } + return (hit); +} + +/* + * 1 OK, 0 not + */ +void +reg_service(rqstp, xprt) + struct svc_req *rqstp; + SVCXPRT *xprt; +{ + struct pmap reg; + struct pmaplist *pml, *prevpml, *fnd; + int ans, port; + caddr_t t; + + if (debugging) + (void) fprintf(stderr, "server: about do a switch\n"); + switch (rqstp->rq_proc) { + + case PMAPPROC_NULL: + /* + * Null proc call + */ + if (!svc_sendreply(xprt, xdr_void, (caddr_t)0) && debugging) { + abort(); + } + break; + + case PMAPPROC_SET: + /* + * Set a program,version to port mapping + */ + if (!svc_getargs(xprt, xdr_pmap, ®)) + svcerr_decode(xprt); + else { + /* + * check to see if already used + * find_service returns a hit even if + * the versions don't match, so check for it + */ + fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot); + if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) { + if (fnd->pml_map.pm_port == reg.pm_port) { + ans = 1; + goto done; + } + else { + ans = 0; + goto done; + } + } else { + /* + * add to END of list + */ + pml = (struct pmaplist *) + malloc((u_int)sizeof(struct pmaplist)); + pml->pml_map = reg; + pml->pml_next = 0; + if (pmaplist == 0) { + pmaplist = pml; + } else { + for (fnd= pmaplist; fnd->pml_next != 0; + fnd = fnd->pml_next); + fnd->pml_next = pml; + } + ans = 1; + } + done: + if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) && + debugging) { + (void) fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_UNSET: + /* + * Remove a program,version to port mapping. + */ + if (!svc_getargs(xprt, xdr_pmap, ®)) + svcerr_decode(xprt); + else { + ans = 0; + for (prevpml = NULL, pml = pmaplist; pml != NULL; ) { + if ((pml->pml_map.pm_prog != reg.pm_prog) || + (pml->pml_map.pm_vers != reg.pm_vers)) { + /* both pml & prevpml move forwards */ + prevpml = pml; + pml = pml->pml_next; + continue; + } + /* found it; pml moves forward, prevpml stays */ + ans = 1; + t = (caddr_t)pml; + pml = pml->pml_next; + if (prevpml == NULL) + pmaplist = pml; + else + prevpml->pml_next = pml; + free(t); + } + if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) && + debugging) { + (void) fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_GETPORT: + /* + * Lookup the mapping for a program,version and return its port + */ + if (!svc_getargs(xprt, xdr_pmap, ®)) + svcerr_decode(xprt); + else { + fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot); + if (fnd) + port = fnd->pml_map.pm_port; + else + port = 0; + if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&port)) && + debugging) { + (void) fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_DUMP: + /* + * Return the current set of mapped program,version + */ + if (!svc_getargs(xprt, xdr_void, NULL)) + svcerr_decode(xprt); + else { + if ((!svc_sendreply(xprt, xdr_pmaplist, + (caddr_t)&pmaplist)) && debugging) { + (void) fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_CALLIT: + /* + * Calls a procedure on the local machine. If the requested + * procedure is not registered this procedure does not return + * error information!! + * This procedure is only supported on rpc/udp and calls via + * rpc/udp. It passes null authentication parameters. + */ + callit(rqstp, xprt); + break; + + default: + svcerr_noproc(xprt); + break; + } +} + + +/* + * Stuff for the rmtcall service + */ +#define ARGSIZE 9000 + +struct encap_parms { + u_long arglen; + char *args; +}; + +static bool_t +xdr_encap_parms(xdrs, epp) + XDR *xdrs; + struct encap_parms *epp; +{ + + return (xdr_bytes(xdrs, &(epp->args), &(epp->arglen), ARGSIZE)); +} + +struct rmtcallargs { + u_long rmt_prog; + u_long rmt_vers; + u_long rmt_port; + u_long rmt_proc; + struct encap_parms rmt_args; +}; + +static bool_t +xdr_rmtcall_args(xdrs, cap) + register XDR *xdrs; + register struct rmtcallargs *cap; +{ + + /* does not get a port number */ + if (xdr_u_long(xdrs, &(cap->rmt_prog)) && + xdr_u_long(xdrs, &(cap->rmt_vers)) && + xdr_u_long(xdrs, &(cap->rmt_proc))) { + return (xdr_encap_parms(xdrs, &(cap->rmt_args))); + } + return (FALSE); +} + +static bool_t +xdr_rmtcall_result(xdrs, cap) + register XDR *xdrs; + register struct rmtcallargs *cap; +{ + if (xdr_u_long(xdrs, &(cap->rmt_port))) + return (xdr_encap_parms(xdrs, &(cap->rmt_args))); + return (FALSE); +} + +/* + * only worries about the struct encap_parms part of struct rmtcallargs. + * The arglen must already be set!! + */ +static bool_t +xdr_opaque_parms(xdrs, cap) + XDR *xdrs; + struct rmtcallargs *cap; +{ + + return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen)); +} + +/* + * This routine finds and sets the length of incoming opaque paraters + * and then calls xdr_opaque_parms. + */ +static bool_t +xdr_len_opaque_parms(xdrs, cap) + register XDR *xdrs; + struct rmtcallargs *cap; +{ + register u_int beginpos, lowpos, highpos, currpos, pos; + + beginpos = lowpos = pos = xdr_getpos(xdrs); + highpos = lowpos + ARGSIZE; + while ((int)(highpos - lowpos) >= 0) { + currpos = (lowpos + highpos) / 2; + if (xdr_setpos(xdrs, currpos)) { + pos = currpos; + lowpos = currpos + 1; + } else { + highpos = currpos - 1; + } + } + xdr_setpos(xdrs, beginpos); + cap->rmt_args.arglen = pos - beginpos; + return (xdr_opaque_parms(xdrs, cap)); +} + +/* + * Call a remote procedure service + * This procedure is very quiet when things go wrong. + * The proc is written to support broadcast rpc. In the broadcast case, + * a machine should shut-up instead of complain, less the requestor be + * overrun with complaints at the expense of not hearing a valid reply ... + * + * This now forks so that the program & process that it calls can call + * back to the portmapper. + */ +static void +callit(rqstp, xprt) + struct svc_req *rqstp; + SVCXPRT *xprt; +{ + struct rmtcallargs a; + struct pmaplist *pml; + u_short port; + struct sockaddr_in me; + int pid, so = -1; + CLIENT *client; + struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred; + struct timeval timeout; + char buf[ARGSIZE]; + + timeout.tv_sec = 5; + timeout.tv_usec = 0; + a.rmt_args.args = buf; + if (!svc_getargs(xprt, xdr_rmtcall_args, &a)) + return; + if ((pml = find_service(a.rmt_prog, a.rmt_vers, + (u_long)IPPROTO_UDP)) == NULL) + return; + /* + * fork a child to do the work. Parent immediately returns. + * Child exits upon completion. + */ + if ((pid = fork()) != 0) { + if (pid < 0) + syslog(LOG_ERR, "CALLIT (prog %lu): fork: %m", + a.rmt_prog); + return; + } + port = pml->pml_map.pm_port; + get_myaddress(&me); + me.sin_port = htons(port); + client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &so); + if (client != (CLIENT *)NULL) { + if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) { + client->cl_auth = authunix_create(au->aup_machname, + au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids); + } + a.rmt_port = (u_long)port; + if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a, + xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) { + svc_sendreply(xprt, xdr_rmtcall_result, (caddr_t)&a); + } + AUTH_DESTROY(client->cl_auth); + clnt_destroy(client); + } + (void)close(so); + exit(0); +} + +void +reap() +{ + while (wait3((int *)NULL, WNOHANG, (struct rusage *)NULL) > 0); +} -- cgit v1.1 From 862fdf11a2ede45dec0da01ed575525d79468981 Mon Sep 17 00:00:00 2001 From: rgrimes Date: Thu, 26 May 1994 05:23:31 +0000 Subject: BSD 4.4 Lite usr.sbin Sources --- usr.sbin/Makefile | 26 + usr.sbin/Makefile.inc | 3 + usr.sbin/ac/ac.8 | 107 + usr.sbin/accton/Makefile | 6 + usr.sbin/accton/accton.c | 95 + usr.sbin/amd/Makefile | 5 + usr.sbin/amd/amd/ChangeLog | 1169 ++++ usr.sbin/amd/amd/Makefile | 33 + usr.sbin/amd/amd/afs_ops.c | 1816 ++++++ usr.sbin/amd/amd/am_ops.c | 181 + usr.sbin/amd/amd/amd.8 | 232 + usr.sbin/amd/amd/amd.c | 344 ++ usr.sbin/amd/amd/amq_subr.c | 464 ++ usr.sbin/amd/amd/clock.c | 241 + usr.sbin/amd/amd/efs_ops.c | 135 + usr.sbin/amd/amd/get_args.c | 336 + usr.sbin/amd/amd/host_ops.c | 681 +++ usr.sbin/amd/amd/ifs_ops.c | 195 + usr.sbin/amd/amd/info_file.c | 276 + usr.sbin/amd/amd/info_hes.c | 697 +++ usr.sbin/amd/amd/info_ndbm.c | 123 + usr.sbin/amd/amd/info_nis.c | 247 + usr.sbin/amd/amd/info_passwd.c | 162 + usr.sbin/amd/amd/info_union.c | 153 + usr.sbin/amd/amd/map.c | 1140 ++++ usr.sbin/amd/amd/mapc.c | 914 +++ usr.sbin/amd/amd/misc_rpc.c | 333 + usr.sbin/amd/amd/mntfs.c | 367 ++ usr.sbin/amd/amd/mount_fs.c | 273 + usr.sbin/amd/amd/mtab.c | 108 + usr.sbin/amd/amd/nfs_ops.c | 809 +++ usr.sbin/amd/amd/nfs_start.c | 435 ++ usr.sbin/amd/amd/nfs_subr.c | 552 ++ usr.sbin/amd/amd/nfsx_ops.c | 516 ++ usr.sbin/amd/amd/opts.c | 835 +++ usr.sbin/amd/amd/pfs_ops.c | 169 + usr.sbin/amd/amd/restart.c | 181 + usr.sbin/amd/amd/rpc_fwd.c | 430 ++ usr.sbin/amd/amd/sched.c | 325 + usr.sbin/amd/amd/sfs_ops.c | 208 + usr.sbin/amd/amd/srvr_afs.c | 205 + usr.sbin/amd/amd/srvr_nfs.c | 719 +++ usr.sbin/amd/amd/ufs_ops.c | 178 + usr.sbin/amd/amd/umount_fs.c | 225 + usr.sbin/amd/amd/util.c | 648 ++ usr.sbin/amd/amd/wire.c | 281 + usr.sbin/amd/amd/xutil.c | 491 ++ usr.sbin/amd/amq/Makefile | 15 + usr.sbin/amd/amq/amq.8 | 130 + usr.sbin/amd/amq/amq.c | 666 ++ usr.sbin/amd/config/Configure | 60 + usr.sbin/amd/config/Makefile.aix3 | 5 + usr.sbin/amd/config/Makefile.bsd44 | 8 + usr.sbin/amd/config/Makefile.config | 91 + usr.sbin/amd/config/Makefile.hpux | 13 + usr.sbin/amd/config/Makefile.irix | 10 + usr.sbin/amd/config/Makefile.irix3 | 13 + usr.sbin/amd/config/Makefile.irix4 | 14 + usr.sbin/amd/config/Makefile.stellix | 10 + usr.sbin/amd/config/RELEASE | 1 + usr.sbin/amd/config/arch | 126 + usr.sbin/amd/config/misc-aix3.h | 96 + usr.sbin/amd/config/misc-hpux.h | 79 + usr.sbin/amd/config/misc-irix.h | 50 + usr.sbin/amd/config/misc-next.h | 44 + usr.sbin/amd/config/misc-stellix.h | 65 + usr.sbin/amd/config/misc-ultrix.h | 55 + usr.sbin/amd/config/mount_aix.c | 153 + usr.sbin/amd/config/mount_irix.c | 83 + usr.sbin/amd/config/mount_stellix.c | 76 + usr.sbin/amd/config/mtab_aix.c | 137 + usr.sbin/amd/config/mtab_bsd.c | 114 + usr.sbin/amd/config/mtab_file.c | 472 ++ usr.sbin/amd/config/mtab_ultrix.c | 115 + usr.sbin/amd/config/newvers.sh | 88 + usr.sbin/amd/config/os-acis43.h | 83 + usr.sbin/amd/config/os-aix3.h | 181 + usr.sbin/amd/config/os-aux.h | 117 + usr.sbin/amd/config/os-bsd44.h | 191 + usr.sbin/amd/config/os-concentrix.h | 79 + usr.sbin/amd/config/os-convex.h | 80 + usr.sbin/amd/config/os-defaults.h | 143 + usr.sbin/amd/config/os-dgux.h | 114 + usr.sbin/amd/config/os-fpx4.h | 92 + usr.sbin/amd/config/os-hcx.h | 81 + usr.sbin/amd/config/os-hlh42.h | 89 + usr.sbin/amd/config/os-hpux.h | 150 + usr.sbin/amd/config/os-irix.h | 133 + usr.sbin/amd/config/os-irix3.h | 133 + usr.sbin/amd/config/os-irix4.h | 150 + usr.sbin/amd/config/os-next.h | 79 + usr.sbin/amd/config/os-pyrOSx.h | 80 + usr.sbin/amd/config/os-riscix.h | 88 + usr.sbin/amd/config/os-sos3.h | 79 + usr.sbin/amd/config/os-sos4.h | 116 + usr.sbin/amd/config/os-stellix.h | 108 + usr.sbin/amd/config/os-type | 128 + usr.sbin/amd/config/os-u2_2.h | 161 + usr.sbin/amd/config/os-u3_0.h | 154 + usr.sbin/amd/config/os-u4_0.h | 158 + usr.sbin/amd/config/os-u4_2.h | 153 + usr.sbin/amd/config/os-umax43.h | 79 + usr.sbin/amd/config/os-utek.h | 49 + usr.sbin/amd/config/os-utx32.h | 85 + usr.sbin/amd/config/os-xinu43.h | 112 + usr.sbin/amd/doc/Makefile | 53 + usr.sbin/amd/doc/amdref.cps | 381 ++ usr.sbin/amd/doc/amdref.ps | 6429 ++++++++++++++++++++ usr.sbin/amd/doc/amdref.texinfo | 4554 ++++++++++++++ usr.sbin/amd/doc/texinfo.tex | 2192 +++++++ usr.sbin/amd/fsinfo/Makefile | 30 + usr.sbin/amd/fsinfo/conf/automounts | 48 + usr.sbin/amd/fsinfo/conf/csg_sun3 | 18 + usr.sbin/amd/fsinfo/conf/csg_vax | 67 + usr.sbin/amd/fsinfo/conf/diskless_sun3_sos4 | 9 + .../amd/fsinfo/conf/hosts/achilles.doc.ic.ac.uk | 116 + .../amd/fsinfo/conf/hosts/bigears.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/dylan.doc.ic.ac.uk | 68 + .../amd/fsinfo/conf/hosts/flamingo.doc.ic.ac.uk | 104 + .../amd/fsinfo/conf/hosts/ganymede.doc.ic.ac.uk | 33 + usr.sbin/amd/fsinfo/conf/hosts/gould.doc.ic.ac.uk | 477 ++ usr.sbin/amd/fsinfo/conf/hosts/gummo.doc.ic.ac.uk | 12 + usr.sbin/amd/fsinfo/conf/hosts/ivax.doc.ic.ac.uk | 84 + .../amd/fsinfo/conf/hosts/obsidian.doc.ic.ac.uk | 28 + .../amd/fsinfo/conf/hosts/pelican.doc.ic.ac.uk | 208 + usr.sbin/amd/fsinfo/conf/hosts/rvax.doc.ic.ac.uk | 66 + usr.sbin/amd/fsinfo/conf/hosts/sky.doc.ic.ac.uk | 79 + usr.sbin/amd/fsinfo/conf/hosts/svax.doc.ic.ac.uk | 66 + usr.sbin/amd/fsinfo/conf/hosts/tcsun1.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tcsun2.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tcsun3.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tcsun4.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tcsun5.doc.ic.ac.uk | 3 + .../amd/fsinfo/conf/hosts/toytown.doc.ic.ac.uk | 116 + usr.sbin/amd/fsinfo/conf/hosts/truth.doc.ic.ac.uk | 9 + usr.sbin/amd/fsinfo/conf/hosts/tsun1.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun10.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun11.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun12.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun13.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun14.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun15.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun16.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun17.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun18.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun19.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun2.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun3.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun4.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun5.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun6.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun7.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun8.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsun9.doc.ic.ac.uk | 3 + usr.sbin/amd/fsinfo/conf/hosts/tsunfs.doc.ic.ac.uk | 211 + usr.sbin/amd/fsinfo/conf/hosts/whoops.doc.ic.ac.uk | 21 + usr.sbin/amd/fsinfo/conf/users | 106 + usr.sbin/amd/fsinfo/fsi_analyze.c | 645 ++ usr.sbin/amd/fsinfo/fsi_data.h | 236 + usr.sbin/amd/fsinfo/fsi_dict.c | 125 + usr.sbin/amd/fsinfo/fsi_gram.y | 394 ++ usr.sbin/amd/fsinfo/fsi_lex.l | 403 ++ usr.sbin/amd/fsinfo/fsi_util.c | 573 ++ usr.sbin/amd/fsinfo/fsinfo.8 | 77 + usr.sbin/amd/fsinfo/fsinfo.c | 275 + usr.sbin/amd/fsinfo/fsinfo.h | 159 + usr.sbin/amd/fsinfo/wr_atab.c | 284 + usr.sbin/amd/fsinfo/wr_bparam.c | 101 + usr.sbin/amd/fsinfo/wr_dumpset.c | 88 + usr.sbin/amd/fsinfo/wr_exportfs.c | 100 + usr.sbin/amd/fsinfo/wr_fstab.c | 303 + usr.sbin/amd/include/am.h | 567 ++ usr.sbin/amd/include/config.h | 142 + usr.sbin/amd/include/fstype.h | 148 + usr.sbin/amd/include/re.h | 21 + usr.sbin/amd/include/remagic.h | 5 + usr.sbin/amd/include/uwait.h | 83 + usr.sbin/amd/maps/a_master | 79 + usr.sbin/amd/maps/a_net | 3 + usr.sbin/amd/mk-amd-map/Makefile | 11 + usr.sbin/amd/mk-amd-map/mk-amd-map.8 | 59 + usr.sbin/amd/mk-amd-map/mk-amd-map.c | 384 ++ usr.sbin/amd/rpcx/amq.h | 153 + usr.sbin/amd/rpcx/amq.x | 185 + usr.sbin/amd/rpcx/amq_clnt.c | 181 + usr.sbin/amd/rpcx/amq_svc.c | 136 + usr.sbin/amd/rpcx/amq_xdr.c | 251 + usr.sbin/amd/rpcx/mount.h | 124 + usr.sbin/amd/rpcx/mount_xdr.c | 206 + usr.sbin/amd/rpcx/nfs_prot.h | 389 ++ usr.sbin/amd/rpcx/nfs_prot_svc.c | 198 + usr.sbin/amd/rpcx/nfs_prot_xdr.c | 627 ++ usr.sbin/amd/text/COPYRIGHT | 3 + usr.sbin/amd/text/INSTALL | 194 + usr.sbin/amd/text/README | 37 + usr.sbin/amd/text/amd.start.ex | 87 + usr.sbin/arp/Makefile | 13 + usr.sbin/arp/arp.8 | 127 + usr.sbin/arp/arp.c | 514 ++ usr.sbin/arp/arp4.4 | 124 + usr.sbin/bad144/Makefile | 7 + usr.sbin/bad144/bad144.8 | 186 + usr.sbin/bad144/bad144.c | 662 ++ usr.sbin/chown/Makefile | 9 + usr.sbin/chown/chgrp.1 | 136 + usr.sbin/chown/chown.8 | 149 + usr.sbin/chown/chown.c | 273 + usr.sbin/chroot/Makefile | 6 + usr.sbin/chroot/chroot.8 | 79 + usr.sbin/chroot/chroot.c | 96 + usr.sbin/config.new/Makefile | 14 + usr.sbin/config.new/config.h | 281 + usr.sbin/config.new/config.new.8 | 167 + usr.sbin/config.new/files.c | 262 + usr.sbin/config.new/gram.y | 392 ++ usr.sbin/config.new/hash.c | 279 + usr.sbin/config.new/main.c | 466 ++ usr.sbin/config.new/mkheaders.c | 148 + usr.sbin/config.new/mkioconf.c | 395 ++ usr.sbin/config.new/mkmakefile.c | 364 ++ usr.sbin/config.new/mkswap.c | 118 + usr.sbin/config.new/pack.c | 520 ++ usr.sbin/config.new/scan.l | 238 + usr.sbin/config.new/sem.c | 974 +++ usr.sbin/config.new/sem.h | 61 + usr.sbin/config.new/util.c | 262 + usr.sbin/config/Makefile | 12 + usr.sbin/config/SMM.doc/0.t | 88 + usr.sbin/config/SMM.doc/1.t | 61 + usr.sbin/config/SMM.doc/2.t | 188 + usr.sbin/config/SMM.doc/3.t | 299 + usr.sbin/config/SMM.doc/4.t | 442 ++ usr.sbin/config/SMM.doc/5.t | 271 + usr.sbin/config/SMM.doc/6.t | 239 + usr.sbin/config/SMM.doc/Makefile | 10 + usr.sbin/config/SMM.doc/a.t | 162 + usr.sbin/config/SMM.doc/b.t | 137 + usr.sbin/config/SMM.doc/c.t | 109 + usr.sbin/config/SMM.doc/d.t | 272 + usr.sbin/config/SMM.doc/e.t | 114 + usr.sbin/config/SMM.doc/spell.ok | 306 + usr.sbin/config/config.8 | 174 + usr.sbin/config/config.h | 212 + usr.sbin/config/config.y | 1109 ++++ usr.sbin/config/lang.l | 215 + usr.sbin/config/main.c | 268 + usr.sbin/config/mkglue.c | 400 ++ usr.sbin/config/mkheaders.c | 207 + usr.sbin/config/mkioconf.c | 1085 ++++ usr.sbin/config/mkmakefile.c | 623 ++ usr.sbin/config/mkswapconf.c | 216 + usr.sbin/config/mkubglue.c | 196 + usr.sbin/dev_mkdb/Makefile | 6 + usr.sbin/dev_mkdb/dev_mkdb.8 | 81 + usr.sbin/dev_mkdb/dev_mkdb.c | 181 + usr.sbin/diskpart/Makefile | 6 + usr.sbin/diskpart/diskpart.8 | 143 + usr.sbin/diskpart/diskpart.c | 474 ++ usr.sbin/edquota/Makefile | 6 + usr.sbin/edquota/edquota.8 | 150 + usr.sbin/edquota/edquota.c | 722 +++ usr.sbin/edquota/pathnames.h | 39 + usr.sbin/eeprom/Makefile | 6 + usr.sbin/eeprom/eeprom.8 | 69 + usr.sbin/eeprom/eeprom.c | 204 + usr.sbin/eeprom/pathnames.h | 45 + usr.sbin/inetd/Makefile | 7 + usr.sbin/inetd/inetd.8 | 375 ++ usr.sbin/inetd/inetd.c | 1255 ++++ usr.sbin/inetd/pathnames.h | 38 + usr.sbin/iostat/Makefile | 11 + usr.sbin/iostat/iostat.8 | 142 + usr.sbin/iostat/iostat.c | 391 ++ usr.sbin/kgmon/Makefile | 14 + usr.sbin/kgmon/kgmon.8 | 122 + usr.sbin/kgmon/kgmon.c | 520 ++ usr.sbin/kvm_mkdb/Makefile | 7 + usr.sbin/kvm_mkdb/extern.h | 38 + usr.sbin/kvm_mkdb/kvm_mkdb.8 | 69 + usr.sbin/kvm_mkdb/kvm_mkdb.c | 111 + usr.sbin/kvm_mkdb/nlist.c | 186 + usr.sbin/kvm_mkdb/testdb.c | 113 + usr.sbin/lpr/Makefile | 6 + usr.sbin/lpr/SMM.doc/0.t | 68 + usr.sbin/lpr/SMM.doc/1.t | 77 + usr.sbin/lpr/SMM.doc/2.t | 141 + usr.sbin/lpr/SMM.doc/3.t | 73 + usr.sbin/lpr/SMM.doc/4.t | 206 + usr.sbin/lpr/SMM.doc/5.t | 116 + usr.sbin/lpr/SMM.doc/6.t | 94 + usr.sbin/lpr/SMM.doc/7.t | 226 + usr.sbin/lpr/SMM.doc/Makefile | 10 + usr.sbin/lpr/SMM.doc/spell.ok | 70 + usr.sbin/lpr/common_source/common.c | 352 ++ usr.sbin/lpr/common_source/displayq.c | 449 ++ usr.sbin/lpr/common_source/lp.h | 126 + usr.sbin/lpr/common_source/lp.local.h | 80 + usr.sbin/lpr/common_source/pathnames.h | 50 + usr.sbin/lpr/common_source/printcap.c | 458 ++ usr.sbin/lpr/common_source/rmjob.c | 339 ++ usr.sbin/lpr/common_source/startdaemon.c | 108 + usr.sbin/lpr/filters/Makefile | 7 + usr.sbin/lpr/filters/lpf.c | 217 + usr.sbin/lpr/lpc/Makefile | 12 + usr.sbin/lpr/lpc/cmds.c | 1107 ++++ usr.sbin/lpr/lpc/cmdtab.c | 79 + usr.sbin/lpr/lpc/extern.h | 58 + usr.sbin/lpr/lpc/lpc.8 | 174 + usr.sbin/lpr/lpc/lpc.c | 277 + usr.sbin/lpr/lpc/lpc.h | 45 + usr.sbin/lpr/lpd/Makefile | 11 + usr.sbin/lpr/lpd/extern.h | 39 + usr.sbin/lpr/lpd/lpd.8 | 249 + usr.sbin/lpr/lpd/lpd.c | 507 ++ usr.sbin/lpr/lpd/lpdchar.c | 1066 ++++ usr.sbin/lpr/lpd/printjob.c | 1377 +++++ usr.sbin/lpr/lpd/recvjob.c | 358 ++ usr.sbin/lpr/lpq/Makefile | 12 + usr.sbin/lpr/lpq/lpq.1 | 134 + usr.sbin/lpr/lpq/lpq.c | 126 + usr.sbin/lpr/lpr/Makefile | 12 + usr.sbin/lpr/lpr/lpr.1 | 256 + usr.sbin/lpr/lpr/lpr.c | 744 +++ usr.sbin/lpr/lprm/Makefile | 12 + usr.sbin/lpr/lprm/lprm.1 | 145 + usr.sbin/lpr/lprm/lprm.c | 144 + usr.sbin/lpr/lptest/Makefile | 6 + usr.sbin/lpr/lptest/lptest.1 | 74 + usr.sbin/lpr/lptest/lptest.c | 83 + usr.sbin/lpr/pac/Makefile | 10 + usr.sbin/lpr/pac/pac.8 | 106 + usr.sbin/lpr/pac/pac.c | 444 ++ usr.sbin/mtree/Makefile | 8 + usr.sbin/mtree/compare.c | 271 + usr.sbin/mtree/create.c | 290 + usr.sbin/mtree/extern.h | 44 + usr.sbin/mtree/misc.c | 125 + usr.sbin/mtree/mtree.8 | 249 + usr.sbin/mtree/mtree.c | 146 + usr.sbin/mtree/mtree.h | 88 + usr.sbin/mtree/spec.c | 280 + usr.sbin/mtree/verify.c | 202 + usr.sbin/pstat/Makefile | 10 + usr.sbin/pstat/pstat.8 | 321 + usr.sbin/pstat/pstat.c | 1110 ++++ usr.sbin/pwd_mkdb/Makefile | 7 + usr.sbin/pwd_mkdb/pw_scan.c | 122 + usr.sbin/pwd_mkdb/pw_scan.h | 36 + usr.sbin/pwd_mkdb/pwd_mkdb.8 | 128 + usr.sbin/pwd_mkdb/pwd_mkdb.c | 387 ++ usr.sbin/quotaon/Makefile | 8 + usr.sbin/quotaon/quotaon.8 | 139 + usr.sbin/quotaon/quotaon.c | 251 + usr.sbin/repquota/Makefile | 6 + usr.sbin/repquota/repquota.8 | 103 + usr.sbin/repquota/repquota.c | 379 ++ usr.sbin/rmt/Makefile | 6 + usr.sbin/rmt/rmt.8 | 217 + usr.sbin/rmt/rmt.c | 244 + usr.sbin/rwhod/Makefile | 6 + usr.sbin/rwhod/rwhod.8 | 146 + usr.sbin/rwhod/rwhod.c | 539 ++ usr.sbin/sendmail/cf/cf/alpha.mc | 41 + usr.sbin/sendmail/cf/cf/auspex.mc | 42 + usr.sbin/sendmail/cf/cf/chez.mc | 44 + usr.sbin/sendmail/cf/cf/cogsci.mc | 41 + usr.sbin/sendmail/cf/cf/cs-exposed.mc | 40 + usr.sbin/sendmail/cf/cf/cs-hidden.mc | 40 + usr.sbin/sendmail/cf/cf/hpux-cs-exposed.mc | 41 + usr.sbin/sendmail/cf/cf/hpux-cs-hidden.mc | 41 + usr.sbin/sendmail/cf/cf/osf1-cs-exposed.mc | 41 + usr.sbin/sendmail/cf/cf/osf1-cs-hidden.mc | 41 + usr.sbin/sendmail/cf/cf/python.mc | 52 + usr.sbin/sendmail/cf/cf/riscos-cs-exposed.mc | 41 + usr.sbin/sendmail/cf/cf/s2k.mc | 42 + usr.sbin/sendmail/cf/cf/sample.mc | 40 + usr.sbin/sendmail/cf/cf/sleepy.mc | 43 + usr.sbin/sendmail/cf/cf/sunos3.5-cs-exposed.mc | 41 + usr.sbin/sendmail/cf/cf/sunos3.5-cs-hidden.mc | 41 + usr.sbin/sendmail/cf/cf/sunos4.1-cs-exposed.mc | 41 + usr.sbin/sendmail/cf/cf/sunos4.1-cs-hidden.mc | 41 + usr.sbin/sendmail/cf/cf/udb.mc | 41 + usr.sbin/sendmail/cf/cf/ultrix4.1-cs-exposed.mc | 41 + usr.sbin/sendmail/cf/cf/ultrix4.1-cs-hidden.mc | 41 + usr.sbin/sendmail/cf/cf/vangogh.mc | 44 + usr.sbin/sendmail/cf/domain/Berkeley.m4 | 42 + usr.sbin/sendmail/cf/domain/cs.exposed.m4 | 40 + usr.sbin/sendmail/cf/domain/cs.hidden.m4 | 38 + usr.sbin/sendmail/cf/domain/eecs.hidden.m4 | 38 + usr.sbin/sendmail/cf/domain/s2k.m4 | 38 + usr.sbin/sendmail/cf/ostype/hpux.m4 | 44 + usr.sbin/sendmail/cf/ostype/irix.m4 | 41 + usr.sbin/sendmail/cf/ostype/ultrix4.1.m4 | 38 + usr.sbin/sendmail/contrib/rcpt-streaming | 305 + usr.sbin/sendmail/doc/Makefile | 5 + usr.sbin/sendmail/doc/op/spell.ok | 324 + usr.sbin/sendmail/doc/rfc/rfc819.txt | 1044 ++++ usr.sbin/sendmail/doc/rfc/rfc821.txt | 4050 ++++++++++++ usr.sbin/sendmail/doc/rfc/rfc822.txt | 2901 +++++++++ usr.sbin/sendmail/makemap/Makefile.dist | 81 + usr.sbin/sendmail/praliases/Makefile.dist | 81 + usr.sbin/sendmail/src/Makefile.386BSD | 42 + usr.sbin/sendmail/src/Makefile.AIX | 113 + usr.sbin/sendmail/src/Makefile.AUX | 105 + usr.sbin/sendmail/src/Makefile.BSD43 | 123 + usr.sbin/sendmail/src/Makefile.BSDI | 32 + usr.sbin/sendmail/src/Makefile.CLIX | 115 + usr.sbin/sendmail/src/Makefile.ConvexOS | 105 + usr.sbin/sendmail/src/Makefile.DGUX | 101 + usr.sbin/sendmail/src/Makefile.Dell | 113 + usr.sbin/sendmail/src/Makefile.DomainOS | 123 + usr.sbin/sendmail/src/Makefile.Dynix | 113 + usr.sbin/sendmail/src/Makefile.FreeBSD | 50 + usr.sbin/sendmail/src/Makefile.HP-UX | 105 + usr.sbin/sendmail/src/Makefile.IRIX | 109 + usr.sbin/sendmail/src/Makefile.Linux | 120 + usr.sbin/sendmail/src/Makefile.Mach386 | 107 + usr.sbin/sendmail/src/Makefile.NCR3000 | 109 + usr.sbin/sendmail/src/Makefile.NeXT | 114 + usr.sbin/sendmail/src/Makefile.NetBSD | 46 + usr.sbin/sendmail/src/Makefile.OSF1 | 109 + usr.sbin/sendmail/src/Makefile.PTX | 114 + usr.sbin/sendmail/src/Makefile.RISCos | 117 + usr.sbin/sendmail/src/Makefile.SCO | 104 + usr.sbin/sendmail/src/Makefile.SVR4 | 113 + usr.sbin/sendmail/src/Makefile.Solaris | 115 + usr.sbin/sendmail/src/Makefile.SunOS | 111 + usr.sbin/sendmail/src/Makefile.SunOS.4.0.3 | 113 + usr.sbin/sendmail/src/Makefile.SunOS.5.x | 115 + usr.sbin/sendmail/src/Makefile.Titan | 114 + usr.sbin/sendmail/src/Makefile.ULTRIX | 107 + usr.sbin/sendmail/src/Makefile.UMAX | 114 + usr.sbin/sendmail/src/Makefile.Utah | 40 + usr.sbin/sendmail/src/Makefile.dist | 107 + usr.sbin/sendmail/src/TODO | 287 + usr.sbin/sliplogin/Makefile | 9 + usr.sbin/sliplogin/pathnames.h | 46 + usr.sbin/sliplogin/slip.hosts | 11 + usr.sbin/sliplogin/slip.login | 12 + usr.sbin/sliplogin/sliplogin.8 | 220 + usr.sbin/sliplogin/sliplogin.c | 381 ++ usr.sbin/sysctl/Makefile | 6 + usr.sbin/sysctl/pathconf.c | 229 + usr.sbin/sysctl/sysctl.8 | 208 + usr.sbin/sysctl/sysctl.c | 572 ++ usr.sbin/syslogd/Makefile | 9 + usr.sbin/syslogd/pathnames.h | 40 + usr.sbin/syslogd/syslog.conf.5 | 224 + usr.sbin/syslogd/syslogd.8 | 122 + usr.sbin/syslogd/syslogd.c | 1131 ++++ usr.sbin/timed/Makefile | 5 + usr.sbin/timed/SMM.doc/timed/Makefile | 11 + usr.sbin/timed/SMM.doc/timed/date | 53 + usr.sbin/timed/SMM.doc/timed/loop | 54 + usr.sbin/timed/SMM.doc/timed/spell.ok | 34 + usr.sbin/timed/SMM.doc/timed/time | 53 + usr.sbin/timed/SMM.doc/timed/timed.ms | 504 ++ usr.sbin/timed/SMM.doc/timed/unused | 53 + usr.sbin/timed/SMM.doc/timedop/Makefile | 7 + usr.sbin/timed/SMM.doc/timedop/timed.ms | 279 + usr.sbin/timed/timed/CHANGES | 144 + usr.sbin/timed/timed/Makefile | 13 + usr.sbin/timed/timed/acksend.c | 132 + usr.sbin/timed/timed/byteorder.c | 86 + usr.sbin/timed/timed/candidate.c | 167 + usr.sbin/timed/timed/cksum.c | 87 + usr.sbin/timed/timed/correct.c | 294 + usr.sbin/timed/timed/extern.h | 89 + usr.sbin/timed/timed/globals.h | 186 + usr.sbin/timed/timed/master.c | 907 +++ usr.sbin/timed/timed/measure.c | 353 ++ usr.sbin/timed/timed/networkdelta.c | 264 + usr.sbin/timed/timed/pathnames.h | 44 + usr.sbin/timed/timed/readmsg.c | 488 ++ usr.sbin/timed/timed/slave.c | 715 +++ usr.sbin/timed/timed/timed.8 | 219 + usr.sbin/timed/timed/timed.c | 980 +++ usr.sbin/timed/timedc/Makefile | 11 + usr.sbin/timed/timedc/cmds.c | 526 ++ usr.sbin/timed/timedc/cmdtab.c | 57 + usr.sbin/timed/timedc/extern.h | 52 + usr.sbin/timed/timedc/timedc.8 | 145 + usr.sbin/timed/timedc/timedc.c | 261 + usr.sbin/timed/timedc/timedc.h | 66 + usr.sbin/traceroute/Makefile | 8 + usr.sbin/traceroute/README | 126 + usr.sbin/traceroute/mean.awk | 50 + usr.sbin/traceroute/median.awk | 67 + usr.sbin/traceroute/traceroute.8 | 336 + usr.sbin/traceroute/traceroute.c | 835 +++ usr.sbin/trpt/Makefile | 8 + usr.sbin/trpt/trpt.8 | 151 + usr.sbin/trpt/trpt.c | 414 ++ usr.sbin/trsp/Makefile | 9 + usr.sbin/trsp/trsp.8 | 141 + usr.sbin/trsp/trsp.c | 433 ++ usr.sbin/update/Makefile | 6 + usr.sbin/update/update.8 | 74 + usr.sbin/update/update.c | 75 + usr.sbin/vipw/Makefile | 7 + usr.sbin/vipw/pw_util.c | 204 + usr.sbin/vipw/pw_util.h | 42 + usr.sbin/vipw/vipw.8 | 93 + usr.sbin/vipw/vipw.c | 127 + 504 files changed, 112536 insertions(+) create mode 100644 usr.sbin/Makefile create mode 100644 usr.sbin/Makefile.inc create mode 100644 usr.sbin/ac/ac.8 create mode 100644 usr.sbin/accton/Makefile create mode 100644 usr.sbin/accton/accton.c create mode 100644 usr.sbin/amd/Makefile create mode 100644 usr.sbin/amd/amd/ChangeLog create mode 100644 usr.sbin/amd/amd/Makefile create mode 100644 usr.sbin/amd/amd/afs_ops.c create mode 100644 usr.sbin/amd/amd/am_ops.c create mode 100644 usr.sbin/amd/amd/amd.8 create mode 100644 usr.sbin/amd/amd/amd.c create mode 100644 usr.sbin/amd/amd/amq_subr.c create mode 100644 usr.sbin/amd/amd/clock.c create mode 100644 usr.sbin/amd/amd/efs_ops.c create mode 100644 usr.sbin/amd/amd/get_args.c create mode 100644 usr.sbin/amd/amd/host_ops.c create mode 100644 usr.sbin/amd/amd/ifs_ops.c create mode 100644 usr.sbin/amd/amd/info_file.c create mode 100644 usr.sbin/amd/amd/info_hes.c create mode 100644 usr.sbin/amd/amd/info_ndbm.c create mode 100644 usr.sbin/amd/amd/info_nis.c create mode 100644 usr.sbin/amd/amd/info_passwd.c create mode 100644 usr.sbin/amd/amd/info_union.c create mode 100644 usr.sbin/amd/amd/map.c create mode 100644 usr.sbin/amd/amd/mapc.c create mode 100644 usr.sbin/amd/amd/misc_rpc.c create mode 100644 usr.sbin/amd/amd/mntfs.c create mode 100644 usr.sbin/amd/amd/mount_fs.c create mode 100644 usr.sbin/amd/amd/mtab.c create mode 100644 usr.sbin/amd/amd/nfs_ops.c create mode 100644 usr.sbin/amd/amd/nfs_start.c create mode 100644 usr.sbin/amd/amd/nfs_subr.c create mode 100644 usr.sbin/amd/amd/nfsx_ops.c create mode 100644 usr.sbin/amd/amd/opts.c create mode 100644 usr.sbin/amd/amd/pfs_ops.c create mode 100644 usr.sbin/amd/amd/restart.c create mode 100644 usr.sbin/amd/amd/rpc_fwd.c create mode 100644 usr.sbin/amd/amd/sched.c create mode 100644 usr.sbin/amd/amd/sfs_ops.c create mode 100644 usr.sbin/amd/amd/srvr_afs.c create mode 100644 usr.sbin/amd/amd/srvr_nfs.c create mode 100644 usr.sbin/amd/amd/ufs_ops.c create mode 100644 usr.sbin/amd/amd/umount_fs.c create mode 100644 usr.sbin/amd/amd/util.c create mode 100644 usr.sbin/amd/amd/wire.c create mode 100644 usr.sbin/amd/amd/xutil.c create mode 100644 usr.sbin/amd/amq/Makefile create mode 100644 usr.sbin/amd/amq/amq.8 create mode 100644 usr.sbin/amd/amq/amq.c create mode 100644 usr.sbin/amd/config/Configure create mode 100644 usr.sbin/amd/config/Makefile.aix3 create mode 100644 usr.sbin/amd/config/Makefile.bsd44 create mode 100644 usr.sbin/amd/config/Makefile.config create mode 100644 usr.sbin/amd/config/Makefile.hpux create mode 100644 usr.sbin/amd/config/Makefile.irix create mode 100644 usr.sbin/amd/config/Makefile.irix3 create mode 100644 usr.sbin/amd/config/Makefile.irix4 create mode 100644 usr.sbin/amd/config/Makefile.stellix create mode 100644 usr.sbin/amd/config/RELEASE create mode 100644 usr.sbin/amd/config/arch create mode 100644 usr.sbin/amd/config/misc-aix3.h create mode 100644 usr.sbin/amd/config/misc-hpux.h create mode 100644 usr.sbin/amd/config/misc-irix.h create mode 100644 usr.sbin/amd/config/misc-next.h create mode 100644 usr.sbin/amd/config/misc-stellix.h create mode 100644 usr.sbin/amd/config/misc-ultrix.h create mode 100644 usr.sbin/amd/config/mount_aix.c create mode 100644 usr.sbin/amd/config/mount_irix.c create mode 100644 usr.sbin/amd/config/mount_stellix.c create mode 100644 usr.sbin/amd/config/mtab_aix.c create mode 100644 usr.sbin/amd/config/mtab_bsd.c create mode 100644 usr.sbin/amd/config/mtab_file.c create mode 100644 usr.sbin/amd/config/mtab_ultrix.c create mode 100644 usr.sbin/amd/config/newvers.sh create mode 100644 usr.sbin/amd/config/os-acis43.h create mode 100644 usr.sbin/amd/config/os-aix3.h create mode 100644 usr.sbin/amd/config/os-aux.h create mode 100644 usr.sbin/amd/config/os-bsd44.h create mode 100644 usr.sbin/amd/config/os-concentrix.h create mode 100644 usr.sbin/amd/config/os-convex.h create mode 100644 usr.sbin/amd/config/os-defaults.h create mode 100644 usr.sbin/amd/config/os-dgux.h create mode 100644 usr.sbin/amd/config/os-fpx4.h create mode 100644 usr.sbin/amd/config/os-hcx.h create mode 100644 usr.sbin/amd/config/os-hlh42.h create mode 100644 usr.sbin/amd/config/os-hpux.h create mode 100644 usr.sbin/amd/config/os-irix.h create mode 100644 usr.sbin/amd/config/os-irix3.h create mode 100644 usr.sbin/amd/config/os-irix4.h create mode 100644 usr.sbin/amd/config/os-next.h create mode 100644 usr.sbin/amd/config/os-pyrOSx.h create mode 100644 usr.sbin/amd/config/os-riscix.h create mode 100644 usr.sbin/amd/config/os-sos3.h create mode 100644 usr.sbin/amd/config/os-sos4.h create mode 100644 usr.sbin/amd/config/os-stellix.h create mode 100644 usr.sbin/amd/config/os-type create mode 100644 usr.sbin/amd/config/os-u2_2.h create mode 100644 usr.sbin/amd/config/os-u3_0.h create mode 100644 usr.sbin/amd/config/os-u4_0.h create mode 100644 usr.sbin/amd/config/os-u4_2.h create mode 100644 usr.sbin/amd/config/os-umax43.h create mode 100644 usr.sbin/amd/config/os-utek.h create mode 100644 usr.sbin/amd/config/os-utx32.h create mode 100644 usr.sbin/amd/config/os-xinu43.h create mode 100644 usr.sbin/amd/doc/Makefile create mode 100644 usr.sbin/amd/doc/amdref.cps create mode 100644 usr.sbin/amd/doc/amdref.ps create mode 100644 usr.sbin/amd/doc/amdref.texinfo create mode 100644 usr.sbin/amd/doc/texinfo.tex create mode 100644 usr.sbin/amd/fsinfo/Makefile create mode 100644 usr.sbin/amd/fsinfo/conf/automounts create mode 100644 usr.sbin/amd/fsinfo/conf/csg_sun3 create mode 100644 usr.sbin/amd/fsinfo/conf/csg_vax create mode 100644 usr.sbin/amd/fsinfo/conf/diskless_sun3_sos4 create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/achilles.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/bigears.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/dylan.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/flamingo.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/ganymede.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/gould.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/gummo.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/ivax.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/obsidian.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/pelican.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/rvax.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/sky.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/svax.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tcsun1.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tcsun2.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tcsun3.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tcsun4.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tcsun5.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/toytown.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/truth.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun1.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun10.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun11.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun12.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun13.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun14.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun15.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun16.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun17.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun18.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun19.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun2.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun3.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun4.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun5.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun6.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun7.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun8.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsun9.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/tsunfs.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/hosts/whoops.doc.ic.ac.uk create mode 100644 usr.sbin/amd/fsinfo/conf/users create mode 100644 usr.sbin/amd/fsinfo/fsi_analyze.c create mode 100644 usr.sbin/amd/fsinfo/fsi_data.h create mode 100644 usr.sbin/amd/fsinfo/fsi_dict.c create mode 100644 usr.sbin/amd/fsinfo/fsi_gram.y create mode 100644 usr.sbin/amd/fsinfo/fsi_lex.l create mode 100644 usr.sbin/amd/fsinfo/fsi_util.c create mode 100644 usr.sbin/amd/fsinfo/fsinfo.8 create mode 100644 usr.sbin/amd/fsinfo/fsinfo.c create mode 100644 usr.sbin/amd/fsinfo/fsinfo.h create mode 100644 usr.sbin/amd/fsinfo/wr_atab.c create mode 100644 usr.sbin/amd/fsinfo/wr_bparam.c create mode 100644 usr.sbin/amd/fsinfo/wr_dumpset.c create mode 100644 usr.sbin/amd/fsinfo/wr_exportfs.c create mode 100644 usr.sbin/amd/fsinfo/wr_fstab.c create mode 100644 usr.sbin/amd/include/am.h create mode 100644 usr.sbin/amd/include/config.h create mode 100644 usr.sbin/amd/include/fstype.h create mode 100644 usr.sbin/amd/include/re.h create mode 100644 usr.sbin/amd/include/remagic.h create mode 100644 usr.sbin/amd/include/uwait.h create mode 100644 usr.sbin/amd/maps/a_master create mode 100644 usr.sbin/amd/maps/a_net create mode 100644 usr.sbin/amd/mk-amd-map/Makefile create mode 100644 usr.sbin/amd/mk-amd-map/mk-amd-map.8 create mode 100644 usr.sbin/amd/mk-amd-map/mk-amd-map.c create mode 100644 usr.sbin/amd/rpcx/amq.h create mode 100644 usr.sbin/amd/rpcx/amq.x create mode 100644 usr.sbin/amd/rpcx/amq_clnt.c create mode 100644 usr.sbin/amd/rpcx/amq_svc.c create mode 100644 usr.sbin/amd/rpcx/amq_xdr.c create mode 100644 usr.sbin/amd/rpcx/mount.h create mode 100644 usr.sbin/amd/rpcx/mount_xdr.c create mode 100644 usr.sbin/amd/rpcx/nfs_prot.h create mode 100644 usr.sbin/amd/rpcx/nfs_prot_svc.c create mode 100644 usr.sbin/amd/rpcx/nfs_prot_xdr.c create mode 100644 usr.sbin/amd/text/COPYRIGHT create mode 100644 usr.sbin/amd/text/INSTALL create mode 100644 usr.sbin/amd/text/README create mode 100644 usr.sbin/amd/text/amd.start.ex create mode 100644 usr.sbin/arp/Makefile create mode 100644 usr.sbin/arp/arp.8 create mode 100644 usr.sbin/arp/arp.c create mode 100644 usr.sbin/arp/arp4.4 create mode 100644 usr.sbin/bad144/Makefile create mode 100644 usr.sbin/bad144/bad144.8 create mode 100644 usr.sbin/bad144/bad144.c create mode 100644 usr.sbin/chown/Makefile create mode 100644 usr.sbin/chown/chgrp.1 create mode 100644 usr.sbin/chown/chown.8 create mode 100644 usr.sbin/chown/chown.c create mode 100644 usr.sbin/chroot/Makefile create mode 100644 usr.sbin/chroot/chroot.8 create mode 100644 usr.sbin/chroot/chroot.c create mode 100644 usr.sbin/config.new/Makefile create mode 100644 usr.sbin/config.new/config.h create mode 100644 usr.sbin/config.new/config.new.8 create mode 100644 usr.sbin/config.new/files.c create mode 100644 usr.sbin/config.new/gram.y create mode 100644 usr.sbin/config.new/hash.c create mode 100644 usr.sbin/config.new/main.c create mode 100644 usr.sbin/config.new/mkheaders.c create mode 100644 usr.sbin/config.new/mkioconf.c create mode 100644 usr.sbin/config.new/mkmakefile.c create mode 100644 usr.sbin/config.new/mkswap.c create mode 100644 usr.sbin/config.new/pack.c create mode 100644 usr.sbin/config.new/scan.l create mode 100644 usr.sbin/config.new/sem.c create mode 100644 usr.sbin/config.new/sem.h create mode 100644 usr.sbin/config.new/util.c create mode 100644 usr.sbin/config/Makefile create mode 100644 usr.sbin/config/SMM.doc/0.t create mode 100644 usr.sbin/config/SMM.doc/1.t create mode 100644 usr.sbin/config/SMM.doc/2.t create mode 100644 usr.sbin/config/SMM.doc/3.t create mode 100644 usr.sbin/config/SMM.doc/4.t create mode 100644 usr.sbin/config/SMM.doc/5.t create mode 100644 usr.sbin/config/SMM.doc/6.t create mode 100644 usr.sbin/config/SMM.doc/Makefile create mode 100644 usr.sbin/config/SMM.doc/a.t create mode 100644 usr.sbin/config/SMM.doc/b.t create mode 100644 usr.sbin/config/SMM.doc/c.t create mode 100644 usr.sbin/config/SMM.doc/d.t create mode 100644 usr.sbin/config/SMM.doc/e.t create mode 100644 usr.sbin/config/SMM.doc/spell.ok create mode 100644 usr.sbin/config/config.8 create mode 100644 usr.sbin/config/config.h create mode 100644 usr.sbin/config/config.y create mode 100644 usr.sbin/config/lang.l create mode 100644 usr.sbin/config/main.c create mode 100644 usr.sbin/config/mkglue.c create mode 100644 usr.sbin/config/mkheaders.c create mode 100644 usr.sbin/config/mkioconf.c create mode 100644 usr.sbin/config/mkmakefile.c create mode 100644 usr.sbin/config/mkswapconf.c create mode 100644 usr.sbin/config/mkubglue.c create mode 100644 usr.sbin/dev_mkdb/Makefile create mode 100644 usr.sbin/dev_mkdb/dev_mkdb.8 create mode 100644 usr.sbin/dev_mkdb/dev_mkdb.c create mode 100644 usr.sbin/diskpart/Makefile create mode 100644 usr.sbin/diskpart/diskpart.8 create mode 100644 usr.sbin/diskpart/diskpart.c create mode 100644 usr.sbin/edquota/Makefile create mode 100644 usr.sbin/edquota/edquota.8 create mode 100644 usr.sbin/edquota/edquota.c create mode 100644 usr.sbin/edquota/pathnames.h create mode 100644 usr.sbin/eeprom/Makefile create mode 100644 usr.sbin/eeprom/eeprom.8 create mode 100644 usr.sbin/eeprom/eeprom.c create mode 100644 usr.sbin/eeprom/pathnames.h create mode 100644 usr.sbin/inetd/Makefile create mode 100644 usr.sbin/inetd/inetd.8 create mode 100644 usr.sbin/inetd/inetd.c create mode 100644 usr.sbin/inetd/pathnames.h create mode 100644 usr.sbin/iostat/Makefile create mode 100644 usr.sbin/iostat/iostat.8 create mode 100644 usr.sbin/iostat/iostat.c create mode 100644 usr.sbin/kgmon/Makefile create mode 100644 usr.sbin/kgmon/kgmon.8 create mode 100644 usr.sbin/kgmon/kgmon.c create mode 100644 usr.sbin/kvm_mkdb/Makefile create mode 100644 usr.sbin/kvm_mkdb/extern.h create mode 100644 usr.sbin/kvm_mkdb/kvm_mkdb.8 create mode 100644 usr.sbin/kvm_mkdb/kvm_mkdb.c create mode 100644 usr.sbin/kvm_mkdb/nlist.c create mode 100644 usr.sbin/kvm_mkdb/testdb.c create mode 100644 usr.sbin/lpr/Makefile create mode 100644 usr.sbin/lpr/SMM.doc/0.t create mode 100644 usr.sbin/lpr/SMM.doc/1.t create mode 100644 usr.sbin/lpr/SMM.doc/2.t create mode 100644 usr.sbin/lpr/SMM.doc/3.t create mode 100644 usr.sbin/lpr/SMM.doc/4.t create mode 100644 usr.sbin/lpr/SMM.doc/5.t create mode 100644 usr.sbin/lpr/SMM.doc/6.t create mode 100644 usr.sbin/lpr/SMM.doc/7.t create mode 100644 usr.sbin/lpr/SMM.doc/Makefile create mode 100644 usr.sbin/lpr/SMM.doc/spell.ok create mode 100644 usr.sbin/lpr/common_source/common.c create mode 100644 usr.sbin/lpr/common_source/displayq.c create mode 100644 usr.sbin/lpr/common_source/lp.h create mode 100644 usr.sbin/lpr/common_source/lp.local.h create mode 100644 usr.sbin/lpr/common_source/pathnames.h create mode 100644 usr.sbin/lpr/common_source/printcap.c create mode 100644 usr.sbin/lpr/common_source/rmjob.c create mode 100644 usr.sbin/lpr/common_source/startdaemon.c create mode 100644 usr.sbin/lpr/filters/Makefile create mode 100644 usr.sbin/lpr/filters/lpf.c create mode 100644 usr.sbin/lpr/lpc/Makefile create mode 100644 usr.sbin/lpr/lpc/cmds.c create mode 100644 usr.sbin/lpr/lpc/cmdtab.c create mode 100644 usr.sbin/lpr/lpc/extern.h create mode 100644 usr.sbin/lpr/lpc/lpc.8 create mode 100644 usr.sbin/lpr/lpc/lpc.c create mode 100644 usr.sbin/lpr/lpc/lpc.h create mode 100644 usr.sbin/lpr/lpd/Makefile create mode 100644 usr.sbin/lpr/lpd/extern.h create mode 100644 usr.sbin/lpr/lpd/lpd.8 create mode 100644 usr.sbin/lpr/lpd/lpd.c create mode 100644 usr.sbin/lpr/lpd/lpdchar.c create mode 100644 usr.sbin/lpr/lpd/printjob.c create mode 100644 usr.sbin/lpr/lpd/recvjob.c create mode 100644 usr.sbin/lpr/lpq/Makefile create mode 100644 usr.sbin/lpr/lpq/lpq.1 create mode 100644 usr.sbin/lpr/lpq/lpq.c create mode 100644 usr.sbin/lpr/lpr/Makefile create mode 100644 usr.sbin/lpr/lpr/lpr.1 create mode 100644 usr.sbin/lpr/lpr/lpr.c create mode 100644 usr.sbin/lpr/lprm/Makefile create mode 100644 usr.sbin/lpr/lprm/lprm.1 create mode 100644 usr.sbin/lpr/lprm/lprm.c create mode 100644 usr.sbin/lpr/lptest/Makefile create mode 100644 usr.sbin/lpr/lptest/lptest.1 create mode 100644 usr.sbin/lpr/lptest/lptest.c create mode 100644 usr.sbin/lpr/pac/Makefile create mode 100644 usr.sbin/lpr/pac/pac.8 create mode 100644 usr.sbin/lpr/pac/pac.c create mode 100644 usr.sbin/mtree/Makefile create mode 100644 usr.sbin/mtree/compare.c create mode 100644 usr.sbin/mtree/create.c create mode 100644 usr.sbin/mtree/extern.h create mode 100644 usr.sbin/mtree/misc.c create mode 100644 usr.sbin/mtree/mtree.8 create mode 100644 usr.sbin/mtree/mtree.c create mode 100644 usr.sbin/mtree/mtree.h create mode 100644 usr.sbin/mtree/spec.c create mode 100644 usr.sbin/mtree/verify.c create mode 100644 usr.sbin/pstat/Makefile create mode 100644 usr.sbin/pstat/pstat.8 create mode 100644 usr.sbin/pstat/pstat.c create mode 100644 usr.sbin/pwd_mkdb/Makefile create mode 100644 usr.sbin/pwd_mkdb/pw_scan.c create mode 100644 usr.sbin/pwd_mkdb/pw_scan.h create mode 100644 usr.sbin/pwd_mkdb/pwd_mkdb.8 create mode 100644 usr.sbin/pwd_mkdb/pwd_mkdb.c create mode 100644 usr.sbin/quotaon/Makefile create mode 100644 usr.sbin/quotaon/quotaon.8 create mode 100644 usr.sbin/quotaon/quotaon.c create mode 100644 usr.sbin/repquota/Makefile create mode 100644 usr.sbin/repquota/repquota.8 create mode 100644 usr.sbin/repquota/repquota.c create mode 100644 usr.sbin/rmt/Makefile create mode 100644 usr.sbin/rmt/rmt.8 create mode 100644 usr.sbin/rmt/rmt.c create mode 100644 usr.sbin/rwhod/Makefile create mode 100644 usr.sbin/rwhod/rwhod.8 create mode 100644 usr.sbin/rwhod/rwhod.c create mode 100644 usr.sbin/sendmail/cf/cf/alpha.mc create mode 100644 usr.sbin/sendmail/cf/cf/auspex.mc create mode 100644 usr.sbin/sendmail/cf/cf/chez.mc create mode 100644 usr.sbin/sendmail/cf/cf/cogsci.mc create mode 100644 usr.sbin/sendmail/cf/cf/cs-exposed.mc create mode 100644 usr.sbin/sendmail/cf/cf/cs-hidden.mc create mode 100644 usr.sbin/sendmail/cf/cf/hpux-cs-exposed.mc create mode 100644 usr.sbin/sendmail/cf/cf/hpux-cs-hidden.mc create mode 100644 usr.sbin/sendmail/cf/cf/osf1-cs-exposed.mc create mode 100644 usr.sbin/sendmail/cf/cf/osf1-cs-hidden.mc create mode 100644 usr.sbin/sendmail/cf/cf/python.mc create mode 100644 usr.sbin/sendmail/cf/cf/riscos-cs-exposed.mc create mode 100644 usr.sbin/sendmail/cf/cf/s2k.mc create mode 100644 usr.sbin/sendmail/cf/cf/sample.mc create mode 100644 usr.sbin/sendmail/cf/cf/sleepy.mc create mode 100644 usr.sbin/sendmail/cf/cf/sunos3.5-cs-exposed.mc create mode 100644 usr.sbin/sendmail/cf/cf/sunos3.5-cs-hidden.mc create mode 100644 usr.sbin/sendmail/cf/cf/sunos4.1-cs-exposed.mc create mode 100644 usr.sbin/sendmail/cf/cf/sunos4.1-cs-hidden.mc create mode 100644 usr.sbin/sendmail/cf/cf/udb.mc create mode 100644 usr.sbin/sendmail/cf/cf/ultrix4.1-cs-exposed.mc create mode 100644 usr.sbin/sendmail/cf/cf/ultrix4.1-cs-hidden.mc create mode 100644 usr.sbin/sendmail/cf/cf/vangogh.mc create mode 100644 usr.sbin/sendmail/cf/domain/Berkeley.m4 create mode 100644 usr.sbin/sendmail/cf/domain/cs.exposed.m4 create mode 100644 usr.sbin/sendmail/cf/domain/cs.hidden.m4 create mode 100644 usr.sbin/sendmail/cf/domain/eecs.hidden.m4 create mode 100644 usr.sbin/sendmail/cf/domain/s2k.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/hpux.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/irix.m4 create mode 100644 usr.sbin/sendmail/cf/ostype/ultrix4.1.m4 create mode 100644 usr.sbin/sendmail/contrib/rcpt-streaming create mode 100644 usr.sbin/sendmail/doc/Makefile create mode 100644 usr.sbin/sendmail/doc/op/spell.ok create mode 100644 usr.sbin/sendmail/doc/rfc/rfc819.txt create mode 100644 usr.sbin/sendmail/doc/rfc/rfc821.txt create mode 100644 usr.sbin/sendmail/doc/rfc/rfc822.txt create mode 100644 usr.sbin/sendmail/makemap/Makefile.dist create mode 100644 usr.sbin/sendmail/praliases/Makefile.dist create mode 100644 usr.sbin/sendmail/src/Makefile.386BSD create mode 100644 usr.sbin/sendmail/src/Makefile.AIX create mode 100644 usr.sbin/sendmail/src/Makefile.AUX create mode 100644 usr.sbin/sendmail/src/Makefile.BSD43 create mode 100644 usr.sbin/sendmail/src/Makefile.BSDI create mode 100644 usr.sbin/sendmail/src/Makefile.CLIX create mode 100644 usr.sbin/sendmail/src/Makefile.ConvexOS create mode 100644 usr.sbin/sendmail/src/Makefile.DGUX create mode 100644 usr.sbin/sendmail/src/Makefile.Dell create mode 100644 usr.sbin/sendmail/src/Makefile.DomainOS create mode 100644 usr.sbin/sendmail/src/Makefile.Dynix create mode 100644 usr.sbin/sendmail/src/Makefile.FreeBSD create mode 100644 usr.sbin/sendmail/src/Makefile.HP-UX create mode 100644 usr.sbin/sendmail/src/Makefile.IRIX create mode 100644 usr.sbin/sendmail/src/Makefile.Linux create mode 100644 usr.sbin/sendmail/src/Makefile.Mach386 create mode 100644 usr.sbin/sendmail/src/Makefile.NCR3000 create mode 100644 usr.sbin/sendmail/src/Makefile.NeXT create mode 100644 usr.sbin/sendmail/src/Makefile.NetBSD create mode 100644 usr.sbin/sendmail/src/Makefile.OSF1 create mode 100644 usr.sbin/sendmail/src/Makefile.PTX create mode 100644 usr.sbin/sendmail/src/Makefile.RISCos create mode 100644 usr.sbin/sendmail/src/Makefile.SCO create mode 100644 usr.sbin/sendmail/src/Makefile.SVR4 create mode 100644 usr.sbin/sendmail/src/Makefile.Solaris create mode 100644 usr.sbin/sendmail/src/Makefile.SunOS create mode 100644 usr.sbin/sendmail/src/Makefile.SunOS.4.0.3 create mode 100644 usr.sbin/sendmail/src/Makefile.SunOS.5.x create mode 100644 usr.sbin/sendmail/src/Makefile.Titan create mode 100644 usr.sbin/sendmail/src/Makefile.ULTRIX create mode 100644 usr.sbin/sendmail/src/Makefile.UMAX create mode 100644 usr.sbin/sendmail/src/Makefile.Utah create mode 100644 usr.sbin/sendmail/src/Makefile.dist create mode 100644 usr.sbin/sendmail/src/TODO create mode 100644 usr.sbin/sliplogin/Makefile create mode 100644 usr.sbin/sliplogin/pathnames.h create mode 100644 usr.sbin/sliplogin/slip.hosts create mode 100644 usr.sbin/sliplogin/slip.login create mode 100644 usr.sbin/sliplogin/sliplogin.8 create mode 100644 usr.sbin/sliplogin/sliplogin.c create mode 100644 usr.sbin/sysctl/Makefile create mode 100644 usr.sbin/sysctl/pathconf.c create mode 100644 usr.sbin/sysctl/sysctl.8 create mode 100644 usr.sbin/sysctl/sysctl.c create mode 100644 usr.sbin/syslogd/Makefile create mode 100644 usr.sbin/syslogd/pathnames.h create mode 100644 usr.sbin/syslogd/syslog.conf.5 create mode 100644 usr.sbin/syslogd/syslogd.8 create mode 100644 usr.sbin/syslogd/syslogd.c create mode 100644 usr.sbin/timed/Makefile create mode 100644 usr.sbin/timed/SMM.doc/timed/Makefile create mode 100644 usr.sbin/timed/SMM.doc/timed/date create mode 100644 usr.sbin/timed/SMM.doc/timed/loop create mode 100644 usr.sbin/timed/SMM.doc/timed/spell.ok create mode 100644 usr.sbin/timed/SMM.doc/timed/time create mode 100644 usr.sbin/timed/SMM.doc/timed/timed.ms create mode 100644 usr.sbin/timed/SMM.doc/timed/unused create mode 100644 usr.sbin/timed/SMM.doc/timedop/Makefile create mode 100644 usr.sbin/timed/SMM.doc/timedop/timed.ms create mode 100644 usr.sbin/timed/timed/CHANGES create mode 100644 usr.sbin/timed/timed/Makefile create mode 100644 usr.sbin/timed/timed/acksend.c create mode 100644 usr.sbin/timed/timed/byteorder.c create mode 100644 usr.sbin/timed/timed/candidate.c create mode 100644 usr.sbin/timed/timed/cksum.c create mode 100644 usr.sbin/timed/timed/correct.c create mode 100644 usr.sbin/timed/timed/extern.h create mode 100644 usr.sbin/timed/timed/globals.h create mode 100644 usr.sbin/timed/timed/master.c create mode 100644 usr.sbin/timed/timed/measure.c create mode 100644 usr.sbin/timed/timed/networkdelta.c create mode 100644 usr.sbin/timed/timed/pathnames.h create mode 100644 usr.sbin/timed/timed/readmsg.c create mode 100644 usr.sbin/timed/timed/slave.c create mode 100644 usr.sbin/timed/timed/timed.8 create mode 100644 usr.sbin/timed/timed/timed.c create mode 100644 usr.sbin/timed/timedc/Makefile create mode 100644 usr.sbin/timed/timedc/cmds.c create mode 100644 usr.sbin/timed/timedc/cmdtab.c create mode 100644 usr.sbin/timed/timedc/extern.h create mode 100644 usr.sbin/timed/timedc/timedc.8 create mode 100644 usr.sbin/timed/timedc/timedc.c create mode 100644 usr.sbin/timed/timedc/timedc.h create mode 100644 usr.sbin/traceroute/Makefile create mode 100644 usr.sbin/traceroute/README create mode 100644 usr.sbin/traceroute/mean.awk create mode 100644 usr.sbin/traceroute/median.awk create mode 100644 usr.sbin/traceroute/traceroute.8 create mode 100644 usr.sbin/traceroute/traceroute.c create mode 100644 usr.sbin/trpt/Makefile create mode 100644 usr.sbin/trpt/trpt.8 create mode 100644 usr.sbin/trpt/trpt.c create mode 100644 usr.sbin/trsp/Makefile create mode 100644 usr.sbin/trsp/trsp.8 create mode 100644 usr.sbin/trsp/trsp.c create mode 100644 usr.sbin/update/Makefile create mode 100644 usr.sbin/update/update.8 create mode 100644 usr.sbin/update/update.c create mode 100644 usr.sbin/vipw/Makefile create mode 100644 usr.sbin/vipw/pw_util.c create mode 100644 usr.sbin/vipw/pw_util.h create mode 100644 usr.sbin/vipw/vipw.8 create mode 100644 usr.sbin/vipw/vipw.c (limited to 'usr.sbin') diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile new file mode 100644 index 0000000..8467608 --- /dev/null +++ b/usr.sbin/Makefile @@ -0,0 +1,26 @@ +# @(#)Makefile 5.20 (Berkeley) 6/12/93 + +SUBDIR= ac accton amd arp chown chroot cron dev_mkdb diskpart edquota \ + inetd kgmon kvm_mkdb lpr mkproto mtree portmap pstat pwd_mkdb \ + quot quotaon repquota rmt rwhod sa sendmail sliplogin sysctl \ + syslogd traceroute trpt trsp update vipw + +.if make(clean) || make(cleandir) +SUBDIR+=bad144 config config.new eeprom iostat timed +.elif ${MACHINE} == "hp300" +SUBDIR+=config iostat timed +.elif ${MACHINE} == "i386" +SUBDIR+=bad144 config iostat +.elif ${MACHINE} == "luna68k" +SUBDIR+=config iostat timed +.elif ${MACHINE} == "mips" +SUBDIR+=config iostat timed +.elif ${MACHINE} == "sparc" +SUBDIR+=config.new eeprom timed +.elif ${MACHINE} == "tahoe" +SUBDIR+=config iostat timed +.elif ${MACHINE} == "vax" +SUBDIR+=bad144 config iostat timed +.endif + +.include diff --git a/usr.sbin/Makefile.inc b/usr.sbin/Makefile.inc new file mode 100644 index 0000000..fd92864 --- /dev/null +++ b/usr.sbin/Makefile.inc @@ -0,0 +1,3 @@ +# @(#)Makefile.inc 8.1 (Berkeley) 6/6/93 + +BINDIR?= /usr/sbin diff --git a/usr.sbin/ac/ac.8 b/usr.sbin/ac/ac.8 new file mode 100644 index 0000000..0c834a7 --- /dev/null +++ b/usr.sbin/ac/ac.8 @@ -0,0 +1,107 @@ +.\" Copyright (c) 1980, 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. +.\" +.\" @(#)ac.8 8.2 (Berkeley) 4/19/94 +.\" +.Dd April 19, 1994 +.Dt AC 8 +.Os BSD 4 +.Sh NAME +.Nm ac +.Nd display connect time accounting +.Sh SYNOPSIS +.Nm ac +.Op Fl d +.Op Fl p +.Op Fl w Ar file +.Op Ar users ... +.Sh DESCRIPTION +If the file +.Pa /var/log/wtmp +exists, +a record of individual +login and logout times are written to it by +.Xr init 8 +and +.Xr login 8 +respectively. +The program +.Nm ac +examines these +records and writes the accumulated connect time for all logins to the +standard output. +.Pp +Options available: +.Bl -tag -width people +.It Fl d +Display the connect times in 24 hour chunks. +.It Fl p +Display individual user totals. +.It Fl w Ar file +Read raw connect time data from +.Ar file +instead of the default file +.Pa /var/log/wtmp . +.It Ar users ... +Display totals for the given individuals +only. +.El +.Pp +If no arguments are given, +.Nm +displays the total amount of login time for all active accounts on the +system. +.Pp +The default +.Pa wtmp +file is an infinitely increasing file +unless frequently truncated. This is normally +done by the daily daemon scripts scheduled by +.Xr cron 8 +which rename and rotate the +.Pa wtmp +files before truncating them (and keeping about a weeks worth on hand). +No login times are collected however, if the file does not exist. +.Sh FILES +.Bl -tag -width /var/log/wtmp.[0-7] -compact +.It Pa /var/log/wtmp +.It Pa /var/log/wtmp.[0-7] +rotated files +.El +.Sh SEE ALSO +.Xr init 8 , +.Xr sa 8 , +.Xr login 1 , +.Xr utmp 5 . +.Sh HISTORY +A +.Nm +command appeared in Version 6 AT&T UNIX. diff --git a/usr.sbin/accton/Makefile b/usr.sbin/accton/Makefile new file mode 100644 index 0000000..15152a6 --- /dev/null +++ b/usr.sbin/accton/Makefile @@ -0,0 +1,6 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= accton +NOMAN= noman + +.include diff --git a/usr.sbin/accton/accton.c b/usr.sbin/accton/accton.c new file mode 100644 index 0000000..c65ef68 --- /dev/null +++ b/usr.sbin/accton/accton.c @@ -0,0 +1,95 @@ +/* + * 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[] = "@(#)accton.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include + +void usage __P((void)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + int ch; + + while ((ch = getopt(argc, argv, "")) != EOF) + switch(ch) { + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + switch(argc) { + case 0: + if (acct(NULL)) { + (void)fprintf(stderr, + "accton: %s\n", strerror(errno)); + exit(1); + } + break; + case 1: + if (acct(*argv)) { + (void)fprintf(stderr, + "accton: %s: %s\n", *argv, strerror(errno)); + exit(1); + } + break; + default: + usage(); + } + exit(0); +} + +void +usage() +{ + (void)fprintf(stderr, "usage: accton [file]\n"); + exit(1); +} diff --git a/usr.sbin/amd/Makefile b/usr.sbin/amd/Makefile new file mode 100644 index 0000000..96405b8 --- /dev/null +++ b/usr.sbin/amd/Makefile @@ -0,0 +1,5 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +SUBDIR= amd amq fsinfo mk-amd-map + +.include diff --git a/usr.sbin/amd/amd/ChangeLog b/usr.sbin/amd/amd/ChangeLog new file mode 100644 index 0000000..2cd1807 --- /dev/null +++ b/usr.sbin/amd/amd/ChangeLog @@ -0,0 +1,1169 @@ +Sun Jun 7 19:01:37 1992 Jan-Simon Pendry (jsp at achilles) + + * Code cut for BSD 4.4 alpha. + +Sun May 31 17:28:52 1992 Jan-Simon Pendry (jsp at achilles) + + * (afs_ops.c) make sure error code is returned to user if there + is an immediate error in afs_lookuppn. + + * (nfs_ops.c) clear out mountd port number after use. + + * (nfs_ops.c) optionally (KICK_KERNEL) run lstat over the old + mount point. This should go somewhere else more appropriate. + +Sun Mar 29 16:22:01 1992 Jan-Simon Pendry (jsp at achilles) + + * (mount_fs.c) FASCIST_DF_COMMAND is now defined as the fstype + you want df to see. + + * (opts.c) fix buffer overrun in slash munging. + + * (host_ops.c) add support for INFORM_MOUNTD. + +Sat Mar 7 10:23:04 1992 Jan-Simon Pendry (jsp at achilles) + + * (nfsx_ops.c) fix buffer overrun problem by allocating sufficient + memory. + + * (afs_ops.c) fix dereference of free'ed memory when calling + assign_error_mntfs. + + * (xutil.c) fix xmalloc and xrealloc to allow zero sized + allocation. + + * (os-type) make it recognise aix3.2 + +Sun Feb 9 13:14:54 1992 Jan-Simon Pendry (jsp at achilles) + + * Release 5.3 Beta + + * hpux 8 support is still missing. + + * (os-bsd44.h) merged in changes for new bsd nfs code. still need + to add in lease and kerberos support. + +Sun Dec 1 16:20:21 1991 Jan-Simon Pendry (jsp at achilles) + + * (info_nis.c) changed so that it remembers if the NIS domainname + is set and doesn't repeatedly complain. Message changed from an + Error to a Warning. + + * (sfs_ops.c) added linkx fstype. linkx is the same as link but + it also checks that the target exists. This makes it useful for + wildcard map entries. + + * (wire.c) applied changes from Dirk Grunwald. Now stands a + better chance of correctly determining the network name. + + * (map.c) changes in timeout_mp to cause second and subsequent + backgrounded unmount attempts to backoff and so reduce the chance + of running more than one backgrounded unmount at a time. + + * (misc_rpc.c) bug fix from Martyn Johnson to avoid xdr_free'ing + the wrong piece of memory. This was causing random core dumps, + often with a stack trace through pickup_rpc_reply. + +Sun Sep 15 21:16:38 1991 Jan-Simon Pendry (jsp at achilles) + + * Release 5.3 alpha 14. + + * (os-osf1.h) merged in OSF/1 support. + +Sun Aug 4 18:25:04 1991 Jan-Simon Pendry (jsp at achilles) + + * (os-stellix.h) merged in Stellix support. + + * (os-u4_2.h) merged in Ultrix 4.2 support. + + * (host_ops.c) made TCP the default transport protocol. Define + HOST_RPC_UDP somewhere to get UDP transport. + + * (many) added support for ${remopts}. Suggested by Steve + Heimlich. remopts is the same as opts, but is used when the + remote server is not on the local network. If it is not set it + defaults to whatever value ${opts} has. + +Tue May 7 22:30:00 1991 Jan-Simon Pendry (jsp at achilles) + + * Checkpoint for Berkeley network tape II. + +Sat May 4 22:06:24 1991 Jan-Simon Pendry (jsp at achilles) + + * New Berkeley Copyright. + + * (mntfs.c) more short-circuiting in realloc_mntfs(). + + * (host_ops.c) increase RPC timeout to 20 seconds. + + * (info_hes.c) now supports lookup in other domains. + + * (srvr_nfs.c) call map_flush_srvr whenever a server comes up. + + * (map.c) added hook to flush hung file servers. + + * (wire.c) make loop step more portable. + + * (util.c) fix for compiling on rios. + +Sun Apr 21 21:54:52 1991 Jan-Simon Pendry (jsp at forest) + + * (util.c) ignore EINVAL returned by rmdir(). + + * (am_ops.c, afs_ops.c) remove SunOS4 map compat code. + + * (nfsx_ops.c) don't clear MFF_MOUNTING until finished mount attempts. + + * (nfsx_ops.c) don't call sched_task more than once. + + * (afs_ops.c) don't call afs_bgmount if a mount is in progress. + + * (info_file.c) handle case where map ends with \ + +Fri Apr 5 19:23:50 1991 Jan-Simon Pendry (jsp at forest) + + * Release 5.3 Alpha 12. + + * (util.c) don't clear MFF_MOUNTING flag if mount is still in progress. + + * (srvr_nfs.c) calls make_nfs_auth() as required. + + * (host_ops.c) calls make_nfs_auth() as required. + + * (afs_ops.c) allow foreground mounts to return pending. This is + used by nfsx_ops.c. + + * (mapc.c) uses new RE_HDR abstraction coping with systems which + already have the re package installed. + + * (nfsx_ops.c) automatically generates a suitable sublink to make + things work. Remounts now work correctly, but are done in the + foreground so there is a possibility that things may hang. This is + too hard to do differently. + +Wed Apr 3 17:49:05 1991 Jan-Simon Pendry (jsp at achilles) + + * (nfs_ops.c) HAS_NFS_QUALIFIED_NAME is a new compile time switch + which puts a qualified domain name into the RPC authentication + instead of using the default value. Abstracted this out into new + routine called make_nfs_auth(). + + * (afs_ops.c) fixed bug which caused spurious ENOENTs to appear. + this was caused by some code motion which also got slightly + altered int the process. moral: don't make two changes at once. + +Sun Mar 17 12:05:27 1991 Jan-Simon Pendry (jsp at forest) + + * Release 5.3 Alpha 11. + + * (amq.8) Updated. + + * (amq.c) Added new -v option which displays the version number of + the target Amd. Also added support to Amd and reworked newvers + script. Got rid of rcs_info.c. + + * (mk-amd-map.c) Changed name of remove function to avoid clash + with ANSI C. + + * (wire.c) Fixed to work with new 4.4BSD sockaddr's. + + * Changed const to Const everywhere and added new define in config.h. + + * (mk-amd-map.c) New -p option which just writes the output to + stdout. Useful for making NIS or Hesiod maps. + + * (amdref) Small updates and clarifications. + +Sat Mar 16 20:35:17 1991 Jan-Simon Pendry (jsp at forest) + + * (amq_subr.c) Flush request now flushes all internal caches. + + * (amq_subr.c) Changed xdr_amq_mount_tree to return only the + required sub-tree. + + * (ifs_ops.c) Added missing return 0; to ifs_mount. + +Sat Mar 9 19:31:25 1991 Jan-Simon Pendry (jsp at forest) + + * (get_args.c) Output the primary network interface information + with the -v option. + + * (mapc.c) Fixed spurious warning about "root" map not supporting + cache mode "all". Added new (unnamed) cache mode MAPC_ROOT. + + * (info_nis.c) Fixed order number testing which was the cause of a + loop. + +Sun Mar 3 17:57:03 1991 Jan-Simon Pendry (jsp at forest) + + * Release 5.3 Alpha 10. + + * Introduced new inet_dquad routine which prints IP addresses in + dotted quad format. The C library routine is not used because it + uses a static buffer and it takes a structure argument on some + machines and unsigned longs on others. This confuses the hell out + of some compilers and causes SEGVs. + + * task_notify becomes do_task_notify to avoid clash with Mach. + + * (mntfs.c) In realloc_mntfs, the private data field wasn't being + cleared out when the mntfs object was being re-used. This meant + that the data might be used for the wrong mount, so causing + various obscure errors. + + * (info_file.c) Reworked to provide support for map cache "sync" + option. + + * (mapc.c) Added new "sync" option to map cache. This ensures + that the cached data doesn't become stale wrt the source. + Currently this isn't implemented for passwd and hesiod maps. + +Wed Feb 27 11:38:07 1991 Jan-Simon Pendry (jsp at forest) + + * (afs_ops.c) Fixed pid put in fs_hostname for toplvl mount. + +Sun Feb 24 19:37:55 1991 Jan-Simon Pendry (jsp at forest) + + * (wire.c) New module which determines the name of the primary + attached network. This could be used to determine which + server to use. + + * (srvr_nfs.c) Changed mount daemon port mapping caching. This is + now much more eager to recompute the mapping than before. Will + also now work even if pinging is switched off (for example "tcp"). + + * (info_nis.c) Added back old NIS reload code to allow NIS maps to + support "regexp" caching. + + * (mapc.c) Added support for "regexp" caching. This is a type of + map cache where the entries are all REs to be matched against the + requested key. This implies "all" since all the keys must be + loaded for the search to work. + +Sat Feb 23 15:32:43 1991 Jan-Simon Pendry (jsp at forest) + + * (afs_ops.c) Avoid spurious error messages about discarding a + retry mntfs. + + * (amq_subr.c) Removed inet_ntoa call due to disagreement between + gcc and libc about 4 byte structure passing. + + * (xutil.c) Changed way initial logging is done to make command + line more usable. Default logging flags are set statically and + can then be modified by -x options. At the end an additional call + to switch_option is made to initialise xlog_level_init. + + * (umount_fs.c) ENOENT now treated the same as EINVAL. If the + filesystem gets removed and the mountpoint deleted then just + assume the filesystem isn't there - which it isn't. + + * (host_ops.c) Now copes with unmount failures by attempting to + remount the filesystems which had been unmounted. + + * (host_ops.c) Added check during fhandle collection to detect + duplicate entries in the export list (from Stefan Petri). + + * (nfsx_ops.c) Reworked to correctly keep track of what is and + isn't mounted. + +Sun Jan 27 16:58:02 1991 Jan-Simon Pendry (jsp at achilles) + + * (misc-next.h) Added missing NeXT config file. + + * Merged Harris HCX/UX support from Chris Metcalf. + + * (ifs_ops.c) added ifs_fmount entry point to keep nfsx_ops happy. + +Sun Jan 13 18:19:19 1991 Jan-Simon Pendry (jsp at beauty) + + * (nfsx_ops.c) play with opt_fs field to make sure it is unique. + +Fri Dec 21 15:35:45 1990 Jan-Simon Pendry (jsp at forest) + + * Release 5.3 Alpha 9. This is still not Beta! + + * (host_ops.c) use normalized hostname in mtab entries, from + Chris Metcalf. + + * (map.c) enum ftype -> ftype, from Andrew Findlay. + +Mon Dec 17 01:11:25 1990 Jan-Simon Pendry (jsp at beauty) + + * (amdref.texinfo) merged in fsinfo documentation from Nick. + +Sat Dec 15 15:39:07 1990 Jan-Simon Pendry (jsp at beauty) + + * (clock.c) minor tweaks to messages. + + * (sfs_ops.c) make the opt_fs field unique, rather than always + ".", but make sure it still begins with a "." to avoid a clash + with any other existing mounts. + + * (amd.c) changed way local IP address is obtained to avoid using + a call to the name server. It was observed that if the power to + the building goes and everything reboots simultaneously then there + would be a good chance that the nameserver would not recover + before Amd on another machine required it. This happened :-) Now + use the RPC get_myaddress call. + + * (info_hes.c) added hesiod_reload code from Bruce Cole. + Optionally compiled when HAS_HESIOD_RELOAD is defined. + + * (amq_subr.c) fix "security" check. + + * (amq.c) make sure a privileged port is allocated. In fact + RPC3.9 and newer make this guarentee but older versions don't so + we do it here. + +Sun Dec 2 21:30:07 1990 Jan-Simon Pendry (jsp at achilles) + + * (afs_ops.c) fixed problem with pointer pre-increment. + +Mon Nov 19 00:31:28 1990 Jan-Simon Pendry (jsp at achilles) + + * (nfs_ops.c) saved filehandle with mntfs structure. this allows + nfsx unmounts to be undone even if the filehandle cache has lost + the entry. all of this is bogus and deserves a rewrite... + +Sun Nov 18 22:55:43 1990 Jan-Simon Pendry (jsp at achilles) + + * (nfsx_ops.c) now handles mounts of root filesystem correctly. + + * (afs_ops.c) fixed dfs_ops definition to call toplvl_mounted when + done, so making sure that a map cache reference is set up. + +Sun Nov 11 21:09:34 1990 Jan-Simon Pendry (jsp at achilles) + + * (fsinfo/wr_fstab.c) has per-ostype fstab rules. + + * (fsinfo/fsi_lex.l) now works correctly with flex. + +Mon Nov 5 00:08:30 1990 Jan-Simon Pendry (jsp at achilles) + + * Release 5.3 Alpha 8. No more new features from now to 5.3Rel. + Call next one Beta. + + * (amdref.texinfo) more updates. + + * (info_union.c) reload routine now adds a wildcard pointing to + the last named directory so that new files get created correctly. + +Sun Nov 4 22:02:50 1990 Jan-Simon Pendry (jsp at achilles) + + * (os-u4_0.h) Ultrix 4.0 support merged. + + * (os-utek.h) Utek 4.0 support merged. + + * (amdref.texinfo) fixed & updated. + + * (nfsx_ops.c) reworked string munging to prevent ..//.. strings + from occuring. + + * (util.c) am_mounted now correctly updates the am_node for + duplicate mounts. + + * (afs_ops.c) added union fstype. derived from "toplvl" except it + causes all the filesystems to be mounted. cannot be used for + filesystem types whose mounts may be defered (eg nfs) since it + doesn't retry the mounts. + + * (info_union.c) map type for union fstype support. currently + can't handle being given automounted filesystems - causes a + deadlock. + +Sun Oct 21 22:56:16 1990 Jan-Simon Pendry (jsp at achilles) + + * (fsinfo/*) finally integrated the fsinfo package. currently no + documentation or man page. this is a pre-req to getting mmd up. + +Sun Oct 14 20:02:11 1990 Jan-Simon Pendry (jsp at achilles) + + * (amdref.texinfo) reworking of documentation continues. + + * (clock.c) reschedule_timeouts() now called in the event that the + system clock goes backwards. this is possible during the average + bootstrap juggling act with timed/xntpd etc. especially useful if + your machines TOY clock gets way ahead of time. + +Sat Oct 6 19:57:55 1990 Jan-Simon Pendry (jsp at achilles) + + * (map.c) when expanding the filehandle for a server which is + down, don't update the ttl on the original node unless a new node + gets allocated. this should give the original mount a chance to + go away as soon as the server comes back. + + * (arch, os-type) Updated. + + * (nfs_ops.c) Added "noconn", "spongy" and "compress" mount + options for 4.4 BSD. + +Sun Sep 30 18:37:54 1990 Jan-Simon Pendry (jsp at beauty) + + * Release 5.3 Alpha 6. + + * (util.c) domain_strip now doesn't leave partial domains behind. + if it can't strip the complete domain it leaves the string untouched. + + * (restart.c) remember to initialise opt_opts field from mtab. + + * (nfs_ops.c) supports "nocto" option for SunOS4.1. + + * (os-irix.h) new SGI Iris port. + + * (os-next.h) new NeXT port. + + * (os-dgux.h) new DG/UX port. + + * (many) fixed problem where mf_opts was being used for two + different purposes. Now have two fields. + + * (mapc.c) error map prints error message whenever used. + + * (mapc.c) wildcard code rewritten. + + * (util.c) slpit into two parts - some code now in xutil.c. This + is used by mmd (not yet shipped). + +Sun Aug 19 19:58:16 1990 Jan-Simon Pendry (jsp at achilles) + + * (srvr_nfs.c) reduce verbosity of "nfs server yoyo is ok" messages. + + * (opts.c) fix deslashification in expand. + + * (nfs_start.c) amq registering done just before the server kicks + in. running amd with nothing to do leaves the portmapper in peace. + + * (mapc.c) bootstrap code abstracted to allow AMQ_MOUNT entry point. + + * (nfsx_ops.c) new filesystem type, supporting groups of nfs + mounts. needs abstracting to allow groups of (*) mounts. + + * (am.h, *_ops.c) am_ops structure changed; corresponding changes + in the filesystem implemention source. Change was to allow nfsx + filesystem implementation. + + * (amd.c) hostname defaults to "localhost" startup code re-ordered + so that logging still works in case things go wrong early. + + * (am_ops.c) new routine to print list of available fs types; used + by the -v option. + + * (info_file.c) bug fix to make reloads work correctly. + + * (mtab_file.c) does locking on single write, to avoid trashing + mount table when a mount and unmount are done at the same time. + + * (mount_fs.c) automount hack removed since afs_ops no longer + needs it. + + * (afs_ops.c) split "auto" into several other filesystem types. + Now much cleaner. + + * (amq.c) new -M option. + + * (amq_subr.c) support for AMQ_MOUNT added. + + * (amq.x) new AMQ_MOUNT RPC call allows mount map entries to be + passed in at run-time. Automount points can now be added + dynamically, but not yet deleted. + +Sat Jun 23 22:12:48 1990 Jan-Simon Pendry (jsp at beauty) + + * Release 5.2 for Berkeley. + + * (*) Re-organised source code layout. Now much more complicated. + + * (map.c) code which flushed the kernel name cache is not really + needed now that the modify times on the automount directories are + correctly updated so ifdef the whole lot. Remove later... + + * (map.c) make sure that the automount directories modify times + are updated when a change occurs so that the nfs client code can + decide when to update its name cache. + + * (srvr_nfs.c) fixed bug which caused mounted filesystems to + appear down when they were up. + + * YP becomes NIS. + +Mon May 28 19:50:34 1990 Jan-Simon Pendry (jsp at achilles) + + * (amd.tex) substantially updated with more explanation of the + theory and more examples. + + * (nfs_stubs.c) statfs now claims to have a single used block. + Avoids ambiguity between 100% and 0% full. + + * (nfs_stubs.c) changed to allow the size of symlinks optionally + to be accurate wrt the length of the string returned. Optional + because it is cheaper to ignore the length when doing a getattr + and just send any length for the readlink. However, this breaks + on some systems (e.g. Ultrix). + + * (mount_fs.c) automount points get marked type "nfs" instead of + "ignore". This is to fix an interaction with getwd(). Can go + away when getwd() gets re-written. Really only applies to SunOS4 + but change applies to everything to keep consistent across platforms. + + * (mount_fs.c) abstracted out mount options into a table and + corresponding loop. + + * (srvr_nfs.c) make sure portmap information is available when + needed, not just after a ping has succeeded. This needed changing + after the ping algorithm got changed. + + * (mntfs.c) fixed incorrect reference to mf_error instead of mf_flags. + + * (nfs_start.c) keep track of number of fds in use, so don't run + select on system maximum (which is bad news if you have a large + system maximum). + + * (host_ops.c) new NFS tree mount filesystem type (ala Sun -hosts). + + * (nfs_ops.c) abstracted out NFS mount code to support host_ops. + + * (afs_ops.c) dfs_readlink now returns the am_node, instead of the + link. This allows getattr to return the correct set of attributes + so keeping Ultrix happy. + + * (afs_ops.c) Make certain the hostname field given to mount() + does not get too long - otherwise random EINVAL errors occur. + + * Putting closing comments on all #endif's + +Sun May 13 16:07:21 1990 Jan-Simon Pendry (jsp at achilles) + + * (srvr_nfs.c) second rewrite of NFS ping algorithm. + +Sun Apr 29 21:12:33 1990 Jan-Simon Pendry (jsp at achilles) + + * (nfs_stubs.c) re-arranged readlink code to avoid need to + pre-mount a direct filesystem whenever possible. + + * (host_ops.c) finally incorporated new module to support /net + mount point. + +Sat Mar 24 13:18:47 1990 Jan-Simon Pendry (jsp at achilles) + + * (nfs_stubs.c) workaround added to rename entry point to avoid + arguments with NFS client code. + + * (srvr_nfs.c) changed the way NFS pings are done and cleaned up + the process for deciding when a server is up or down. Now there + is just a simple time limit on a reply from the server. The limit + is adjusted depending on whether the state of the server is known. + + * (opts.c) fixed bug with ${var/} expansion et al. Added ${varN} + N = 0..7 for use as scratch variables. + + * (mntfs.c) fixed bug in dup_mntfs(). + +Thu Jan 11 16:56:41 1990 Jan-Simon Pendry (jsp at achilles) + + * Release 5.1c. + + * (amq*) has new options. -f flushes the map cache and -m prints + information about mounted filesystem and fileservers. + +Tue Jan 2 14:44:21 1990 Jan-Simon Pendry (jsp at achilles) + + * (util.c) am_mounted() patches the path for "direct" mounted + filesystems - cosmetic. + + * (afs_ops.c) when possible sets a small kernel attribute cache + timeout on the automount points. + + * (nfs_stubs.c) delete() and rmdir() operations implemented. Used + when a mount point is timed out so the kernel name cache gets to + know about the changes. Fixes most ESTALE errors. + + * (nfs_stubs.c) New do_readlink() function added. This is used to + make sure that a filesystem is mounted at the time a link is read + in the case of "direct" mounts. Done so that the length of the + link is available when the initial getattr is done on the mountpoint. + + * (sfs_ops.c) Changed implementation to avoid race conditions. + The link target is re-arranged so that sublink points to the + target and fs always points at ".". + + * Fixed mount flag bug on Ultrix. + + * Added support from Sjoerd Mullender for Alliant FX/4 and Encore + Multimax. + +Thu Dec 7 17:55:29 1989 Jan-Simon Pendry (jsp at achilles) + + * (afs_ops.c) dfs_readlink now does a new_ttl on the node it + returns. + + * (afs_ops.c) next_nonerror_node now implements the task after + which it is named. + +Tue Nov 28 17:20:52 1989 Jan-Simon Pendry (jsp at achilles) + + * Release 5.1b. + + * (restart.c) Generates link nodes for any unrecognised filesystem + types and then marks them so that they are never deleted (since + they could never be automounted later). + + * (os-*.h) Irrelevant #undef's deleted. + + * (arch) Now knows about AIX on RTs. + + * (amq.c) Rationalised the output. Now only gives you what you + asked for. + + * (am.h) New macro: FSRV_ISDOWN(fs), which checks whether a + fileserver is down. + + * (afs_ops.c) When a mount fails due to a timeout the underlying + filesystem is ripped away and replaced with an error fs. This + avoids the possibility of being left with a single error reference + to a valid mounted filesystem. + +Thu Nov 23 18:04:29 1989 Jan-Simon Pendry (jsp at achilles) + + * (nfs_start.c) Re-order bootstrap sequence to avoid potential + deadlock if restart() ends up accessing one of the automount points. + + * (amq.c) Don't produce default mount output if one of the -l, -x + or -D options was used. + + * (umount_fs.c) Add alternative unmount routine for 4.4 BSD. + +Mon Nov 20 16:22:50 1989 Jan-Simon Pendry (jsp at achilles) + + * (os-bsd44.h) Fixed redefinition of UMOUNT_FS. + + * (info_ndbm.c) Added missing #include . + + * (mapc.c) Fixed typo in ifdef around gdbm config entry. + +Sat Nov 18 16:39:13 1989 Jan-Simon Pendry (jsp at achilles) + + * (util.c) If "/" is automounted, make sure it is never timed out. + + * (mtab.c) Missing clock invalidation added in read_mtab (from a file). + + * (mntfs.c) realloc_mntfs simplified. + + * (map.c) Closed a race condition during shutdown when second and + subsequent duplicate mounts were deleted prematurely. + + * (afs_ops.c) Duplicate mounts are now given the correct return + code. + +Fri Nov 17 18:58:18 1989 Jan-Simon Pendry (jsp at achilles) + + * 5.1 Release. + +Thu Nov 16 17:57:02 1989 Jan-Simon Pendry (jsp at achilles) + + * (mntfs.c) Make sure inherit mntfs structures are not cached + after last reference; otherwise a second reference to the + inherited filesystem will get stuck on the inherit rather than the + (now) fully mounted filesystem. + + * (am.c, nfs_start.c) After forking the server, make sure the + parent does not exit until the automount points are mounted. This + allows a clean sequence during system startup. + + * Initial port to 4.4 BSD. Several new configuration abstractions + were added to make this port possible. + +Thu Nov 9 21:42:14 1989 Jan-Simon Pendry (jsp at achilles) + + * (afs_ops.c, opts.c) Added map logging to facilitate mount map + debugging without needing a -DDEBUG version of Amd. + + * (afs_ops.c) Make sure the length of the fs_hostname mount + parameter does not exceed MAXHOSTNAMESZ. + +Wed Nov 8 13:44:02 1989 Jan-Simon Pendry (jsp at achilles) + + * Change the message log format to indicate the severity of the + message to allow simpler analysis of the log file. + +Tue Nov 7 14:11:36 1989 Jan-Simon Pendry (jsp at achilles) + + * 5.0 Patchlevel 11. + + * (os-bsd44.h) Initial guess at 4.4 BSD definitions. + + * (os-aux.h) Port for Macintosh II from Julian Onions. + + * (amq.c) Output formats cleaned up. AMQ_MNTTREE is still broken + in amq_subr.c though. + + * (afs_ops.c) If a mount timed out, for example an NFS server was + down at the time, it was possible for the error code to remain + unset thus jamming that mount node in a state from which it could + not recover. Just make sure that the mf_error field gets filled + in when an error occurs. + + * (afs_ops.c) strsplit is run over /defaults to avoid problems + with whitespace creeping in. + +Sun Nov 5 11:50:51 1989 Jan-Simon Pendry (jsp at achilles) + + * (util.c) am_mounted: Added missing initialisation of stats.s_mtime. + +Fri Nov 3 17:33:02 1989 Jan-Simon Pendry (jsp at achilles) + + * 5.0 Patchlevel 10. + + * Changed the copyright. + +Thu Nov 2 17:07:53 1989 Jan-Simon Pendry (jsp at achilles) + + * 5.0 Patchlevel 9. + + * (opts.c) new option syntax: == != := + + * (nfs_ops.c) Less caching of filehandles. Now cached errors are + discarded after use. + + * (mtab.c) now attempts to deal with a lack of open file slots (ENFILE). + + * (mount_fs.c) automount entries in the mount table now have a + dev= entry in the same way as NFS and UFS. + + * (mntfs.c) mntfs nodes are now cached after the last reference + and discarded seconds later. This avoids + thrashing during a mount. + + * (mapc.c) map default cache mode is now selected with + "mapdefault", not "default" + + * (amd.tex) numerous clarifications. Still more work required... + + * (amq_subr.c) now allows the -x option of amq to operate. + + * (afs_ops.c) afs_bgmount now keeps track of which filesystem + needed retrying and ensures that the mount node in the + continuation correctly points at an unmounted filesystem. This + fixes a problem whereby a valid mounted filesystem could appear to + have failed to mount. + + * Configure now gives more of a running commentary and checks + whether os-type and arch actually worked. + + * Allow spurious ';'s in a mount location. + +Fri Oct 27 14:03:31 1989 Jan-Simon Pendry (jsp at achilles) + + * foo=blah changed to foo:=blah, foo==blah and foo!=blah. + + * -l stderr changed to -l /dev/stderr. + +Thu Oct 19 15:34:28 1989 Jan-Simon Pendry (jsp at achilles) + + * 5.0 Patchlevel 6. + + * LOG_INFO messages have been rationalised so that some + statistics, graphs and so on can be generated. + + * Transaction ID's for RPC calls are now allocated by the + individual callers, rather than from a central pool. This + decreases the load on mount daemons and NFS servers since the + same XID is used for retries when needed. + + * Many fine details of the new data structures have been changed. + Some areas have been optimized. + +Fri Oct 13 12:31:26 1989 Jan-Simon Pendry (jsp at achilles) + + * Restart code re-implemented to work with the new data structures. + + * Fine tuning applied to new NFS server modeling code. + +Thu Oct 12 15:57:24 1989 Jan-Simon Pendry (jsp at achilles) + + * Added ${/var} and ${var/} variable expansions. The first gives + the "basename" component of the variable, the latter gives the + "dirname" component. Additionally, spurious /'s are deleted after + the variable expansions is complete. + + * Added new -C option to allow the machine's cluster name to be + given to amd. ${cluster} fetches the value and can be used as + another selector. + + * Broken the major data struct (am_node) into three layers: + am_node (one for each automount node), mntfs (one for each mounted + filesystem) and fserver (one for each file server). Machine + up/down state is maintained in the fserver layer. Filesystem + mount/unmount state is maintained in the mntfs layer. This change + fixes the last known major problem caused by the lack of a central + focus for filesystem and fileserver status. There is a dummy file + server layer for local filesystems (ufs, link, program, error). + +Tue Oct 10 11:15:42 1989 Jan-Simon Pendry (jsp at achilles) + + * 5.0 Patchlevel 5. + + * (nfs_ops.c) the filehandle cache is now flushed when a + filesystem is unmounted. This avoids ending up with stale + information if a server bounces. + + * (clock.c) new module to implement callouts. Many other + routines changed to use callouts instead of messing with ttl + fields. + +Sun Oct 1 17:08:20 1989 Jan-Simon Pendry (jsp at achilles) + + * 5.0 Patchlevel 3 & 4. + + * Numerous cleanups. + +Wed Sep 13 14:30:05 1989 Jan-Simon Pendry (jsp at achilles) + + * 5.0 Patchlevel 2. + + * (nfs_ops.c) portmap information is not remembered beyond the + basic filehandle cache interval. That avoids problems when a new + portmap and/or rpc.mountd is started and the bound port changes. + + * (mapc.c) cache reloads are automatically done every hour. + + * Removed xlog macro in favour of plog() so that the log level + can be reflected through to syslog(). log() routine renamed to + plog() which takes an extra parameter indicating the log level. + +Tue Sep 5 20:00:19 1989 Jan-Simon Pendry (jsp at achilles) + + * (nfs_ops.c) when a server is known to be down, any cached file + handles and port mapping informaton is flushed since that may have + changed when it comes back up. + + * (map.c) timeout no longer attempts to unmount a hung mount point. + +Mon Sep 4 14:49:18 1989 Jan-Simon Pendry (jsp at achilles) + + * (afs_ops.c) a mount node which timed out during mount is now + retained for the normal timeout interval rather than for a short + period. This avoids wasting time retrying mounts from a server + which is down. + + * (afs_ops.c) hung mounts are now detected and not used as a + duplicate mount - something which defeated the replacement fs + scheme. + + * (nfs_ops.c) keepalive's now back-off when a server has gone + down. + +Thu Aug 31 21:18:35 1989 Jan-Simon Pendry (jsp at achilles) + + * 5.0 Patchlevel 1. + + * Fixed several bugs which showed up in the keepalive + implementation when a gateway went down causing + a different sequence of errors than usual. + +Wed Aug 30 11:29:21 1989 Jan-Simon Pendry (jsp at achilles) + + * (amq.x) now uses a Sun assigned program number. + + * Revision 5.0 - can now start using metaconfig. + +Tue Aug 29 14:36:48 1989 Jan-Simon Pendry (jsp at achilles) + + * (os-u3_0.h, os-type) now knows about DECstations (mips). + + * (nfs_stubs.c) Added hooks to readlink entry point to call + per-fs readlink routine if it exists, otherwise old behaviour. + + * (afs_ops.c) Added implementation of "type=direct". This is + the same as "type=auto" but is itself the link to the + mount point, rather than being a directory containing a list + of links to mount points. + +Mon Aug 28 17:48:15 1989 Jan-Simon Pendry (jsp at achilles) + + * (afs_ops.c) Changed readdir to workaround a problem on + ultrix 3 where it seems to forget that eof has been reached. + +Thu Aug 24 15:17:55 1989 Jan-Simon Pendry (jsp at achilles) + + * Created "beta16". + + * (afs_ops.c) /defaults is located along with every key. + this makes it possible to update the /defaults in + a map and get to use it. + + * (mapc.c) added map cache synchronization support. if + a file or ndbm map is updated the cache is junked so avoiding + things getting out of sync. + +Wed Aug 23 19:17:52 1989 Jan-Simon Pendry (jsp at achilles) + + * (os-u3_0.h) new file to support Ultrix 3.0 + + * (opts.c) allow environment variables to be accessed via + the same ${env} syntax used for options & selectors. + +Tue Aug 22 13:19:49 1989 Jan-Simon Pendry (jsp at achilles) + + * (opts.c, get_args.c) added support for kernel architecture + type to allow /usr/kvm to be automounted under SunOS 4.x. + + * (os-xinu43.h) updated for june '89 release of MORE/bsd. + + * (opts.c) fixed memory allocation problems where some strings + may not have been strdup'ed before they were free'ed so causing + the malloc arena to get into a twist. This caused core dumps on + some machines and infinite loops on others. + + * (*.c) clock handling is now done by a macro. Global variable + clock_valid is > 0 (ie the time) when valid, 0 if invalid. + + * (map.c) timeout code survived a complete rewrite and is now + O(n) rather than O(n^2). + + * (info_hes.c) new database hooks for Hesiod nameserver. + + * (get_args.c) the local sub-domain is picked up from the + hostname if it is not specifed with -d. The subdomain is + then stripped from the hostname. + + * (am.c) when a SIGTERM is received, an immediate abort + occurs - only the top-level automounts are unmounted; all + other mounts stay -- use amd -r to restart. + + * (afs_ops.c) cleaned up key prefix handling. Again updated + the "hostname" string passed to the kernel so that includes + the hostname, pid and mount point. + +Tue Aug 8 16:05:23 1989 Jan-Simon Pendry (jsp at achilles) + + * (nfs_ops.c) changed the way the file handle cache is managed. + No longer gets a race condition between something entering the + cache and being used and discard. + +Tue Jul 25 20:40:51 1989 Jan-Simon Pendry (jsp at achilles) + + * (map.c) changed fh_to_mp2 so that it does not return + ESTALE during shutdown. it returns ENOENT instead which + avoids thrashing with the kernel. + +Sun Jul 23 15:06:10 1989 Jan-Simon Pendry (jsp at achilles) + + * (afs_ops.c) make sure the incoming key from the kernel + does not contain any characters which could cause trouble + during macro expansion (such as `"! etc). + + * (afs_ops.c) fixed contruction of "mtab" entry. + +Fri Jul 21 11:01:05 1989 Jan-Simon Pendry (jsp at achilles) + + * (afs_ops.c) some changes to support the new startup + shutdown scheme. + + * (map.c) startup and shutdown are now done using the + standard interfaces. Startup is done by creating a + private cache map ";root;" and then doing lookups + on all the names in it. Shutdown is done by forcibly + timing out all the mount points including the automount + points. + + * (info_*.c) modified to provide interface required by + mapc.c module. + + * (mapc.c) new module to implement map caching. Caching + can be controlled by an fs option. "all" means cache + the entire map (if possible). "inc" means cache things + incrementally. "none" means never cache things. Each + map type has a default caching mode which is used if + cache option "default" is used. + +Wed Jul 19 16:14:52 1989 Jan-Simon Pendry (jsp at achilles) + + * (sched.c) implements a general sleep/wakeup scheme and uses + it for sub-process handling. + + * (nfs_start.c) task_notify() called from where it used to + be called. + + * (nfs_ops.c) now implements a non-blocking rpc library. + Everything in nfs_ops was changed to use it. This should + not be in this file and will be moved later. + + * (map.c) if a mount point times out and it is deferred then + issue a wakeup so that it can be retried. + + * (map.c) when creating a new mount point fetches the entry + "/defaults" from the associated map if no other options are + specified. + + * (am.c) implements the -p (print process id) option. + + * (afs_ops.c) a mount attempt now has a time-to-live of twenty + seconds. if only deferred attempts are waiting after that + interval the kernel gets sent ETIMEDOUT. + + * (afs_ops.c) the name by which the kernel knows the filesystem + has changed from pid%d@host to /mountpoint@host. That looks + better to users who get hit by it. + +Fri Jul 14 18:46:16 1989 Jan-Simon Pendry (jsp at achilles) + + * (afs_ops.c) now knows about defered mounts - mounts which + are not in progress, not completed, and not failed. + + * (sched.c) added new entry point sched_ast(). This simulates + a completed job. The basic idea is to let something else return + to the main scheduling loop with a guarentee that it will be + called back when some other action has taken place. + + * (nfs_ops.c) implemented a file handle cache. The nfs_init + routine starts up a request for the filehandle and the mount + routine uses it when it arrives. + +Thu Jul 13 18:07:58 1989 Jan-Simon Pendry (jsp at achilles) + + * (afs_ops.c) found a race condition between an error occuring + and the am_node being timed out. Fixed by updating the + time-to-live and keepalive counters in the node whenever + AMF_MOUNTING is cleared. Also changed afs_lookuppn() so that + it doesn't destroy the node when it returns the error code. + This stops thrashing and the node is eventually timed out. + Now the only way a node gets deleted is by the timeout code + which seems more elegant. + +Tue Jul 11 15:36:44 1989 Jan-Simon Pendry (jsp at achilles) + + * Created "beta15". + + * Fixed *all* references to "u2.2". Some where missed in + the original change. They are now u2_2. + + * (mk-amd-map.c) new command. Converts plain files into + ndbm databases for use by the info_ndbm module. Hooks + included for future support for gdbm just as soon as I + can get a copy. + +Sun Jul 9 19:00:22 1989 Jan-Simon Pendry (jsp at achilles) + + * Created "beta14". + + * (get_info.c) code to handle yp and files now split into + new files info_yp.c and info_file.c New support for ndbm + databases is in info_ndbm.c. A table in get_info.c controls + what and in which order things are searched. + + * (map.c, nfs_stubs.c) better handling for hung mount points. + if a filehandle is passed in by the kernel which references + a hung node, then try to find a replacement, possibly by calling + lookup explicitly. + + * (*.c) use new xlog(level)(message) interface + +Thu Jun 8 20:28:55 1989 Jan-Simon Pendry (jsp at achilles) + + * (nfs_ops.c, ufs_ops.c) when compiled with DEBUG, display + the fs options being used. + + * (am.c) make test for root a little more polite. + + * (get_args.c) update Usage message to include -r option. + +Wed Jun 7 16:28:51 1989 Jan-Simon Pendry (jsp at achilles) + + * (rpc_fwd.c) fwd_reply: if the recvfrom call fails because it + is interrupted then try again. + +Tue Jun 6 16:39:15 1989 Jan-Simon Pendry (jsp at achilles) + + * Created "beta12". + + * (afs_ops.c) inheriting mount option list from command line + is now cumulative. A -foo on the command line is prepended + to the default option list taken from the map. This can be + used to override the ``default default'' options in opts.c. + + * (get_args.c, am.c) added new -r (restart) option. Restart of + mounted filesystems is only done if this option is specified. + [Should *not* be specified in /etc/rc.local of course. - wrong] + + * (yp_master.c) make the enumeration error message more verbose + when debugging is enabled. + + * (rpc_fwd.c) rearranged some declarations at the top. Removed + a spurious call to free which was causing grief on some systems, + but not on Sun's. [This problem was the reason for implementing + the -D mem option.] + + * (opts.c) make sure opt_key and opt_path are set to a zero + length string unless otherwise specified. Previously they + were a source of dangling pointers. + + * (nfs_ops.c) make sure that the allocated nfs_private identifiers + are unique even when some filesystem are being restarted. This mean + starting the basic allocation from 1, not zero. + + * (am.h, get_args.c, util.c) added definition and implmentation of + a simple memory allocation trace (D_MEM). + + * (afs_ops.c) afs_lookuppn: tightened up memory allocation and + delay string copying until last possible moment. + +Mon Jun 5 18:01:18 1989 Jan-Simon Pendry (jsp at achilles) + + * (Makefile.com) diffs: added new rule to generate diffs + between versions. + + * (get_info.c) search_file: added a new dlog() to note when + wildcards are returned. + + * (afs_ops.c) afs_lookuppn: call to init_map specifies efs as + the default ops structure. If the location list only contained + defaults and no real mounts then this previously caused a null + pointer dereference. + + * (map.c) last_used_map: Added new variable. Keeps track of the + last used map, which may be wildly different from first_free_map. + This fixes bugs in several routines in this file. + + * (util.c) mkdirs, rmdirs: Changed directory make/unmake. It is + not possible to quickly determine how many directories need to + be created or deleted, so we try to make as many as possible. + + * (opts.c) Added default values for rfs, rhost and fs. + The new defaults guarentee unique names to allow the NFS + keepalive stuff to work. + +Sun Jun 4 16:12:15 1989 Jan-Simon Pendry (jsp at achilles) + + * First draft of documentation included in the next release. + + * Hooks for TFS added, though this still requires a lot of work. + + * Re-implemented option handling. Options are now allocated + dynamically on a per-mount basis in the continuation structure. + + * Changed os type u2.2 to u2_2 to allow for regular expression + matching in selectors. + + * Format of mount maps is now entirely different. Instead of + guessing which filesystem type is being used, it is now explicitly + stated along with the required options. Variable expansion is + done on the options and selectors are also implemented. The + requested name can also contain any of the selectors. + +Wed May 24 15:21:39 1989 Jan-Simon Pendry (jsp at achilles) + + * Re-implemented NFS ping algorithm to use the new RPC forwarding + system. This allowed a large amount of nfs_ops specific code + to be removed from nfs_start.c and moved to nfs_ops.c. + There is still no strategy for hung file systems. At the moment + it will merely try to mount an alternative (or the same again) + to the same place in the file system. + + * Added RPC forwarding package. This supports general RPC gatewaying + over a UDP transport. The idea is to put a packet identifier into + each outgoing RPC packet and then match that up in a database when + a reply comes in. The database records the original packet identifier + (so that it can be replaced), the source address for the packet and + a function to call to do the forwarding. + + * ChangeLog added between beta8 and beta9. Should have done this sooner. diff --git a/usr.sbin/amd/amd/Makefile b/usr.sbin/amd/amd/Makefile new file mode 100644 index 0000000..328fd80 --- /dev/null +++ b/usr.sbin/amd/amd/Makefile @@ -0,0 +1,33 @@ +# @(#)Makefile 8.2 (Berkeley) 4/22/94 + +PROG= amd +MAN8= amd.0 +OS= bsd44 +SRCS= afs_ops.c am_ops.c clock.c util.c xutil.c \ + efs_ops.c mapc.c info_file.c info_hes.c \ + info_ndbm.c info_passwd.c info_nis.c \ + info_union.c map.c srvr_afs.c srvr_nfs.c \ + mntfs.c misc_rpc.c mount_fs.c mount_xdr.c \ + mtab.c mtab_bsd.c nfs_ops.c nfs_prot_svc.c \ + nfs_start.c nfs_subr.c nfs_prot_xdr.c opts.c \ + pfs_ops.c rpc_fwd.c sched.c sfs_ops.c amq_svc.c \ + amq_subr.c umount_fs.c host_ops.c nfsx_ops.c \ + ufs_ops.c ifs_ops.c amd.c get_args.c restart.c wire.c +OBJS+= vers.${PROG}.o +LDADD+= -lrpc +CFLAGS+=-I${.CURDIR}/../rpcx +CFLAGS+=-I${.CURDIR}/../config +CFLAGS+=-I${.CURDIR}/../include +CFLAGS+=-DARCH_REP=\"${MACHINE}\" +CFLAGS+=-DOS_REP=\"${OS}\" +CFLAGS+=-DOS_HDR=\"os-${OS}.h\" +CFLAGS+=${CONFIG} +CLEANFILES+=vers.${PROG}.c vers.${PROG}.o version.amd + +vers.${PROG}.c: ${SRCS:.c=.o} + @d=${.CURDIR}/ sh ${.CURDIR}/../config/newvers.sh ${PROG} ${MACHINE} ${OS} + +.PATH: ${.CURDIR}/../rpcx ${.CURDIR}/../config +.include "Makefile.config" +.include "../../Makefile.inc" +.include diff --git a/usr.sbin/amd/amd/afs_ops.c b/usr.sbin/amd/amd/afs_ops.c new file mode 100644 index 0000000..6dfdc14 --- /dev/null +++ b/usr.sbin/amd/amd/afs_ops.c @@ -0,0 +1,1816 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)afs_ops.c 8.1 (Berkeley) 6/6/93 + * + * $Id: afs_ops.c,v 5.2.2.4 1992/05/31 16:36:36 jsp Exp $ + * + */ + +#include "am.h" + +#define NFS +#define NFSCLIENT + +#include +#ifdef NFS_3 +typedef nfs_fh fhandle_t; +#endif /* NFS_3 */ +#ifdef NFS_HDR +#include NFS_HDR +#endif /* NFS_HDR */ +#include +#include "mount.h" + +/* + * Automount file system + * Direct file system + * Root file system + * Top-level file system + */ + +/* + * Interval between forced retries of a mount. + */ +#define RETRY_INTERVAL 2 + +/* + * AFS needs nothing in particular. + */ +static char *afs_match P((am_opts *fo)); +static char *afs_match(fo) +am_opts *fo; +{ + char *p = fo->opt_rfs; + if (!fo->opt_rfs) { + plog(XLOG_USER, "auto: no mount point named (rfs:=)"); + return 0; + } + if (!fo->opt_fs) { + plog(XLOG_USER, "auto: no map named (fs:=)"); + return 0; + } + /* + * Swap round fs:= and rfs:= options + * ... historical (jsp) + */ + fo->opt_rfs = fo->opt_fs; + fo->opt_fs = p; + /* + * mtab entry turns out to be the name of the mount map + */ + return strdup(fo->opt_rfs ? fo->opt_rfs : "."); +} + +/* + * Mount an automounter directory. + * The automounter is connected into the system + * as a user-level NFS server. mount_toplvl constructs + * the necessary NFS parameters to be given to the + * kernel so that it will talk back to us. + */ +static int mount_toplvl P((char *dir, char *opts)); +static int mount_toplvl(dir, opts) +char *dir; +char *opts; +{ + struct nfs_args nfs_args; + struct mntent mnt; + int retry; + struct sockaddr_in sin; + unsigned short port; + int flags; + extern nfs_fh *root_fh(); + nfs_fh *fhp; + char fs_hostname[MAXHOSTNAMELEN+MAXPATHLEN+1]; + + MTYPE_TYPE type = MOUNT_TYPE_NFS; + + bzero((voidp) &nfs_args, sizeof(nfs_args)); /* Paranoid */ + + mnt.mnt_dir = dir; + mnt.mnt_fsname = pid_fsname; + mnt.mnt_type = MNTTYPE_AUTO; + mnt.mnt_opts = opts; + mnt.mnt_freq = 0; + mnt.mnt_passno = 0; + + retry = hasmntval(&mnt, "retry"); + if (retry <= 0) + retry = 2; /* XXX */ + + /* + * get fhandle of remote path for automount point + */ + + fhp = root_fh(dir); + if (!fhp) { + plog(XLOG_FATAL, "Can't find root file handle for %s", dir); + return EINVAL; + } + + NFS_FH_DREF(nfs_args.fh, (NFS_FH_TYPE) fhp); + + /* + * Create sockaddr to point to the local machine. 127.0.0.1 + * is not used since that will not work in HP-UX clusters and + * this is no more expensive. + */ + bzero((voidp) &sin, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr = myipaddr; + if (port = hasmntval(&mnt, "port")) { + sin.sin_port = htons(port); + } else { + plog(XLOG_ERROR, "no port number specified for %s", dir); + return EINVAL; + } + + /* + * set mount args + */ + NFS_SA_DREF(nfs_args, &sin); + + /* + * Make a ``hostname'' string for the kernel + */ +#ifndef HOSTNAMESZ +#define SHORT_MOUNT_NAME +#endif /* HOSTNAMESZ */ +#ifdef SHORT_MOUNT_NAME + sprintf(fs_hostname, "amd:%d", foreground ? mypid : getppid()); +#else + sprintf(fs_hostname, "pid%d@%s:%s", foreground ? mypid : getppid(), hostname, dir); +#endif /* SHORT_MOUNT_NAME */ + nfs_args.hostname = fs_hostname; + nfs_args.flags |= NFSMNT_HOSTNAME; +#ifdef HOSTNAMESZ + /* + * Most kernels have a name length restriction. + */ + if (strlen(fs_hostname) >= HOSTNAMESZ) + strcpy(fs_hostname + HOSTNAMESZ - 3, ".."); +#endif /* HOSTNAMESZ */ + +#ifdef NFSMNT_DUMBTIMR + nfs_args.flags |= NFSMNT_DUMBTIMR; + plog(XLOG_INFO, "defeating nfs window computation"); +#endif + + /* + * Parse a subset of the standard nfs options. The + * others are probably irrelevant for this application + */ + if (nfs_args.timeo = hasmntval(&mnt, "timeo")) + nfs_args.flags |= NFSMNT_TIMEO; + + if (nfs_args.retrans = hasmntval(&mnt, "retrans")) + nfs_args.flags |= NFSMNT_RETRANS; + +#ifdef NFSMNT_BIODS + if (nfs_args.biods = hasmntval(&mnt, "biods")) + nfs_args.flags |= NFSMNT_BIODS; + +#endif /* NFSMNT_BIODS */ + +#if defined(NFSMNT_ACREGMIN) && defined(NFSMNT_ACREGMAX) + /* + * Don't cache attributes - they are changing under + * the kernel's feet... + */ + nfs_args.acregmin = nfs_args.acregmax = 1; + nfs_args.flags |= NFSMNT_ACREGMIN|NFSMNT_ACREGMAX; +#endif /* defined(NFSMNT_ACREGMIN) && defined(NFSMNT_ACREGMAX) */ + /* + * These two are constructed internally by the calling routine + */ + if (hasmntopt(&mnt, MNTOPT_SOFT) != NULL) + nfs_args.flags |= NFSMNT_SOFT; + +#ifdef MNTOPT_INTR + if (hasmntopt(&mnt, MNTOPT_INTR) != NULL) + nfs_args.flags |= NFSMNT_INT; +#endif /* MNTOPT_INTR */ + + flags = compute_mount_flags(&mnt); +#ifdef ULTRIX_HACK + nfs_args.gfs_flags = flags; + flags &= M_RDONLY; + if (flags & M_RDONLY) + nfs_args.flags |= NFSMNT_RONLY; +#endif /* ULTRIX_HACK */ + return mount_fs(&mnt, flags, (caddr_t) &nfs_args, retry, type); +} + +static void afs_mkcacheref P((mntfs *mf)); +static void afs_mkcacheref(mf) +mntfs *mf; +{ + /* + * Build a new map cache for this node, or re-use + * an existing cache for the same map. + */ + char *cache; + if (mf->mf_fo && mf->mf_fo->opt_cache) + cache = mf->mf_fo->opt_cache; + else + cache = "none"; + mf->mf_private = (voidp) mapc_find(mf->mf_info, cache); + mf->mf_prfree = mapc_free; +} + +/* + * Mount the root... + */ +static int root_mount P((am_node *mp)); +static int root_mount(mp) +am_node *mp; +{ + mntfs *mf = mp->am_mnt; + + mf->mf_mount = strealloc(mf->mf_mount, pid_fsname); + mf->mf_private = (voidp) mapc_find(mf->mf_info, ""); + mf->mf_prfree = mapc_free; + + return 0; +} + +/* + * Mount a sub-mount + */ +static int afs_mount P((am_node *mp)); +static int afs_mount(mp) +am_node *mp; +{ + mntfs *mf = mp->am_mnt; + + /* + * Pseudo-directories are used to provide some structure + * to the automounted directories instead + * of putting them all in the top-level automount directory. + * + * Here, just increment the parent's link count. + */ + mp->am_parent->am_fattr.nlink++; + /* + * Info field of . means use parent's info field. + * Historical - not documented. + */ + if (mf->mf_info[0] == '.' && mf->mf_info[1] == '\0') + mf->mf_info = strealloc(mf->mf_info, mp->am_parent->am_mnt->mf_info); + /* + * Compute prefix: + * + * If there is an option prefix then use that else + * If the parent had a prefix then use that with name + * of this node appended else + * Use the name of this node. + * + * That means if you want no prefix you must say so + * in the map. + */ + if (mf->mf_fo->opt_pref) { + /* + * the prefix specified as an option + */ + mp->am_pref = strdup(mf->mf_fo->opt_pref); + } else { + /* + * else the parent's prefix + * followed by the name + * followed by / + */ + char *ppref = mp->am_parent->am_pref; + if (ppref == 0) + ppref = ""; + mp->am_pref = str3cat((char *) 0, ppref, mp->am_name, "/"); + } + + /* + * Attach a map cache + */ + afs_mkcacheref(mf); + + return 0; +} + +/* + * Mount the top-level + */ +static int toplvl_mount P((am_node *mp)); +static int toplvl_mount(mp) +am_node *mp; +{ + mntfs *mf = mp->am_mnt; + struct stat stb; + char opts[256]; + int error; + char *mnttype; + + /* + * Mounting the automounter. + * Make sure the mount directory exists, construct + * the mount options and call the mount_toplvl routine. + */ + + if (stat(mp->am_path, &stb) < 0) { + return errno; + } else if ((stb.st_mode & S_IFMT) != S_IFDIR) { + plog(XLOG_WARNING, "%s is not a directory", mp->am_path); + return ENOTDIR; + } + + if (mf->mf_ops == &toplvl_ops) mnttype = "indirect"; + else if (mf->mf_ops == &dfs_ops) mnttype = "direct"; +#ifdef HAS_UNION_FS + else if (mf->mf_ops == &union_ops) mnttype = "union"; +#endif + else mnttype = "auto"; + + /* + * Construct some mount options + */ + sprintf(opts, +#ifdef MNTOPT_INTR + "%s,%s,%s=%d,%s=%d,%s=%d,%s", + MNTOPT_INTR, +#else + "%s,%s=%d,%s=%d,%s=%d,%s", +#endif /* MNTOPT_INTR */ + "rw", + "port", nfs_port, + "timeo", afs_timeo, + "retrans", afs_retrans, + mnttype); + + error = mount_toplvl(mf->mf_mount, opts); + if (error) { + errno = error; + plog(XLOG_FATAL, "mount_toplvl: %m"); + return error; + } + + return 0; +} + +static void toplvl_mounted P((mntfs *mf)); +static void toplvl_mounted(mf) +mntfs *mf; +{ + afs_mkcacheref(mf); +} + +#ifdef HAS_UNION_FS +/* + * Create a reference to a union'ed entry + */ +static int create_union_node P((char *dir, voidp arg)); +static int create_union_node(dir, arg) +char *dir; +voidp arg; +{ + if (strcmp(dir, "/defaults") != 0) { + int error = 0; + (void) toplvl_ops.lookuppn(arg, dir, &error, VLOOK_CREATE); + if (error > 0) { + errno = error; /* XXX */ + plog(XLOG_ERROR, "Could not mount %s: %m", dir); + } + return error; + } + return 0; +} + +static void union_mounted P((mntfs *mf)); +static void union_mounted(mf) +mntfs *mf; +{ + int i; + + afs_mkcacheref(mf); + + /* + * Having made the union mount point, + * populate all the entries... + */ + for (i = 0; i <= last_used_map; i++) { + am_node *mp = exported_ap[i]; + if (mp && mp->am_mnt == mf) { + /* return value from create_union_node is ignored by mapc_keyiter */ + (void) mapc_keyiter((mnt_map *) mp->am_mnt->mf_private, + (void (*)P((char*,void*))) create_union_node, mp); + break; + } + } + +#ifdef notdef + /* + * would be nice to flush most of the cache, but we need to + * keep the wildcard and /defaults entries... + */ + mapc_free(mf->mf_private); + mf->mf_private = (voidp) mapc_find(mf->mf_info, "inc"); +/* mapc_add_kv(mf->mf_private, strdup("/defaults"), + strdup("type:=link;opts:=nounmount;sublink:=${key}")); */ +#endif +} +#endif /* HAS_UNION_FS */ + +/* + * Unmount an automount sub-node + */ +static int afs_umount P((am_node *mp)); +static int afs_umount(mp) +am_node *mp; +{ + return 0; +} + +/* + * Unmount a top-level automount node + */ +static int toplvl_umount P((am_node *mp)); +static int toplvl_umount(mp) +am_node *mp; +{ + int error; + + struct stat stb; +again: + /* + * The lstat is needed if this mount is type=direct. + * When that happens, the kernel cache gets confused + * between the underlying type (dir) and the mounted + * type (link) and so needs to be re-synced before + * the unmount. This is all because the unmount system + * call follows links and so can't actually unmount + * a link (stupid!). It was noted that doing an ls -ld + * of the mount point to see why things were not working + * actually fixed the problem - so simulate an ls -ld here. + */ + if (lstat(mp->am_path, &stb) < 0) { +#ifdef DEBUG + dlog("lstat(%s): %m", mp->am_path); +#endif /* DEBUG */ + } + error = UMOUNT_FS(mp->am_path); + if (error == EBUSY) { + plog(XLOG_WARNING, "afs_unmount retrying %s in 1s", mp->am_path); + sleep(1); /* XXX */ + goto again; + } + + return error; +} + +/* + * Unmount an automount node + */ +static void afs_umounted P((am_node *mp)); +static void afs_umounted(mp) +am_node *mp; +{ + /* + * If this is a pseudo-directory then just adjust the link count + * in the parent, otherwise call the generic unmount routine + */ + if (mp->am_parent && mp->am_parent->am_parent) + --mp->am_parent->am_fattr.nlink; +} + +/* + * Mounting a file system may take a significant period of time. The + * problem is that if this is done in the main process thread then + * the entire automounter could be blocked, possibly hanging lots of + * processes on the system. Instead we use a continuation scheme to + * allow mounts to be attempted in a sub-process. When the sub-process + * exits we pick up the exit status (by convention a UN*X error number) + * and continue in a notifier. The notifier gets handed a data structure + * and can then determine whether the mount was successful or not. If + * not, it updates the data structure and tries again until there are no + * more ways to try the mount, or some other permanent error occurs. + * In the mean time no RPC reply is sent, even after the mount is succesful. + * We rely on the RPC retry mechanism to resend the lookup request which + * can then be handled. + */ + + +struct continuation { + char **ivec; /* Current mount info */ + am_node *mp; /* Node we are trying to mount */ + char *key; /* Map key */ + char *info; /* Info string */ + char **xivec; /* Saved strsplit vector */ + char *auto_opts; /* Automount options */ + am_opts fs_opts; /* Filesystem options */ + char *def_opts; /* Default automount options */ + int retry; /* Try again? */ + int tried; /* Have we tried any yet? */ + time_t start; /* Time we started this mount */ + int callout; /* Callout identifier */ +}; + +#define IN_PROGRESS(cp) ((cp)->mp->am_mnt->mf_flags & MFF_MOUNTING) + +/* + * Discard an old continuation + */ +static void free_continuation P((struct continuation *cp)); +static void free_continuation(cp) +struct continuation *cp; +{ + if (cp->callout) + untimeout(cp->callout); + free((voidp) cp->key); + free((voidp) cp->xivec); + free((voidp) cp->info); + free((voidp) cp->auto_opts); + free((voidp) cp->def_opts); + free_opts(&cp->fs_opts); + free((voidp) cp); +} + +static int afs_bgmount P((struct continuation*, int)); + +/* + * Discard the underlying mount point and replace + * with a reference to an error filesystem. + */ +static void assign_error_mntfs P((am_node *mp)); +static void assign_error_mntfs(mp) +am_node *mp; +{ + if (mp->am_error > 0) { + /* + * Save the old error code + */ + int error = mp->am_error; + if (error <= 0) + error = mp->am_mnt->mf_error; + /* + * Discard the old filesystem + */ + free_mntfs(mp->am_mnt); + /* + * Allocate a new error reference + */ + mp->am_mnt = new_mntfs(); + /* + * Put back the error code + */ + mp->am_mnt->mf_error = error; + mp->am_mnt->mf_flags |= MFF_ERROR; + /* + * Zero the error in the mount point + */ + mp->am_error = 0; + } +} + +/* + * The continuation function. This is called by + * the task notifier when a background mount attempt + * completes. + */ +static void afs_cont P((int rc, int term, voidp closure)); +static void afs_cont(rc, term, closure) +int rc; +int term; +voidp closure; +{ + struct continuation *cp = (struct continuation *) closure; + mntfs *mf = cp->mp->am_mnt; + + /* + * Definitely not trying to mount at the moment + */ + mf->mf_flags &= ~MFF_MOUNTING; + /* + * While we are mounting - try to avoid race conditions + */ + new_ttl(cp->mp); + + /* + * Wakeup anything waiting for this mount + */ + wakeup((voidp) mf); + + /* + * Check for termination signal or exit status... + */ + if (rc || term) { + am_node *xmp; + + if (term) { + /* + * Not sure what to do for an error code. + */ + mf->mf_error = EIO; /* XXX ? */ + mf->mf_flags |= MFF_ERROR; + plog(XLOG_ERROR, "mount for %s got signal %d", cp->mp->am_path, term); + } else { + /* + * Check for exit status... + */ + mf->mf_error = rc; + mf->mf_flags |= MFF_ERROR; + errno = rc; /* XXX */ + plog(XLOG_ERROR, "%s: mount (afs_cont): %m", cp->mp->am_path); + } + + /* + * If we get here then that attempt didn't work, so + * move the info vector pointer along by one and + * call the background mount routine again + */ + amd_stats.d_merr++; + cp->ivec++; + xmp = cp->mp; + (void) afs_bgmount(cp, 0); + assign_error_mntfs(xmp); + } else { + /* + * The mount worked. + */ + am_mounted(cp->mp); + free_continuation(cp); + } + + reschedule_timeout_mp(); +} + +/* + * Retry a mount + */ +/*ARGSUSED*/ +static void afs_retry P((int rc, int term, voidp closure)); +static void afs_retry(rc, term, closure) +int rc; +int term; +voidp closure; +{ + struct continuation *cp = (struct continuation *) closure; + int error = 0; + +#ifdef DEBUG + dlog("Commencing retry for mount of %s", cp->mp->am_path); +#endif /* DEBUG */ + + new_ttl(cp->mp); + + if ((cp->start + ALLOWED_MOUNT_TIME) < clocktime()) { + /* + * The entire mount has timed out. + * Set the error code and skip past + * all the info vectors so that + * afs_bgmount will not have any more + * ways to try the mount, so causing + * an error. + */ + plog(XLOG_INFO, "mount of \"%s\" has timed out", cp->mp->am_path); + error = ETIMEDOUT; + while (*cp->ivec) + cp->ivec++; + } + + if (error || !IN_PROGRESS(cp)) { + (void) afs_bgmount(cp, error); + } + reschedule_timeout_mp(); +} + +/* + * Try to mount a file system. Can be called + * directly or in a sub-process by run_task + */ +static int try_mount P((voidp mvp)); +static int try_mount(mvp) +voidp mvp; +{ + /* + * Mount it! + */ + int error; + am_node *mp = (am_node *) mvp; + mntfs *mf = mp->am_mnt; + + /* + * If the directory is not yet made and + * it needs to be made, then make it! + * This may be run in a backgroun process + * in which case the flag setting won't be + * noticed later - but it is set anyway + * just after run_task is called. It + * should probably go away totally... + */ + if (!(mf->mf_flags & MFF_MKMNT) && mf->mf_ops->fs_flags & FS_MKMNT) { + error = mkdirs(mf->mf_mount, 0555); + if (!error) + mf->mf_flags |= MFF_MKMNT; + } + + error = mount_node(mp); +#ifdef DEBUG + if (error > 0) { + errno = error; + dlog("afs call to mount_node failed: %m"); + } +#endif /* DEBUG */ + return error; +} + +/* + * Pick a file system to try mounting and + * do that in the background if necessary + * +For each location: + if it is new -defaults then + extract and process + continue; + fi + if it is a cut then + if a location has been tried then + break; + fi + continue; + fi + parse mount location + discard previous mount location if required + find matching mounted filesystem + if not applicable then + this_error = No such file or directory + continue + fi + if the filesystem failed to be mounted then + this_error = error from filesystem + elif the filesystem is mounting or unmounting then + this_error = -1 + elif the fileserver is down then + this_error = -1 + elif the filesystem is already mounted + this_error = 0 + break + fi + if no error on this mount then + this_error = initialise mount point + fi + if no error on this mount and mount is delayed then + this_error = -1 + fi + if this_error < 0 then + retry = true + fi + if no error on this mount then + make mount point if required + fi + if no error on this mount then + if mount in background then + run mount in background + return -1 + else + this_error = mount in foreground + fi + fi + if an error occured on this mount then + update stats + save error in mount point + fi +endfor + */ + +static int afs_bgmount P((struct continuation *cp, int mpe)); +static int afs_bgmount(cp, mpe) +struct continuation *cp; +int mpe; +{ + mntfs *mf = cp->mp->am_mnt; /* Current mntfs */ + mntfs *mf_retry = 0; /* First mntfs which needed retrying */ + int this_error = -1; /* Per-mount error */ + int hard_error = -1; + int mp_error = mpe; + + /* + * Try to mount each location. + * At the end: + * hard_error == 0 indicates something was mounted. + * hard_error > 0 indicates everything failed with a hard error + * hard_error < 0 indicates nothing could be mounted now + */ + for (; this_error && *cp->ivec; cp->ivec++) { + am_ops *p; + am_node *mp = cp->mp; + char *link_dir; + int dont_retry; + + if (hard_error < 0) + hard_error = this_error; + + this_error = -1; + + if (**cp->ivec == '-') { + /* + * Pick up new defaults + */ + if (cp->auto_opts && *cp->auto_opts) + cp->def_opts = str3cat(cp->def_opts, cp->auto_opts, ";", *cp->ivec+1); + else + cp->def_opts = strealloc(cp->def_opts, *cp->ivec+1); +#ifdef DEBUG + dlog("Setting def_opts to \"%s\"", cp->def_opts); +#endif /* DEBUG */ + continue; + } + + /* + * If a mount has been attempted, and we find + * a cut then don't try any more locations. + */ + if (strcmp(*cp->ivec, "/") == 0 || strcmp(*cp->ivec, "||") == 0) { + if (cp->tried) { +#ifdef DEBUG + dlog("Cut: not trying any more locations for %s", + mp->am_path); +#endif /* DEBUG */ + break; + } + continue; + } + +#ifdef SUNOS4_COMPAT +#ifdef nomore + /* + * By default, you only get this bit on SunOS4. + * If you want this anyway, then define SUNOS4_COMPAT + * in the relevant "os-blah.h" file. + * + * We make the observation that if the local key line contains + * no '=' signs then either it is sick, or it is a SunOS4-style + * "host:fs[:link]" line. In the latter case the am_opts field + * is also assumed to be in old-style, so you can't mix & match. + * You can use ${} expansions for the fs and link bits though... + * + * Actually, this doesn't really cover all the possibilities for + * the latest SunOS automounter and it is debatable whether there + * is any point bothering. + */ + if (strchr(*cp->ivec, '=') == 0) + p = sunos4_match(&cp->fs_opts, *cp->ivec, cp->def_opts, mp->am_path, cp->key, mp->am_parent->am_mnt->mf_info); + else +#endif +#endif /* SUNOS4_COMPAT */ + p = ops_match(&cp->fs_opts, *cp->ivec, cp->def_opts, mp->am_path, cp->key, mp->am_parent->am_mnt->mf_info); + + /* + * Find a mounted filesystem for this node. + */ + mp->am_mnt = mf = realloc_mntfs(mf, p, &cp->fs_opts, cp->fs_opts.opt_fs, + cp->fs_opts.fs_mtab, cp->auto_opts, cp->fs_opts.opt_opts, cp->fs_opts.opt_remopts); + + p = mf->mf_ops; +#ifdef DEBUG + dlog("Got a hit with %s", p->fs_type); +#endif /* DEBUG */ + /* + * Note whether this is a real mount attempt + */ + if (p == &efs_ops) { + plog(XLOG_MAP, "Map entry %s for %s failed to match", *cp->ivec, mp->am_path); + if (this_error <= 0) + this_error = ENOENT; + continue; + } else { + if (cp->fs_opts.fs_mtab) { + plog(XLOG_MAP, "Trying mount of %s on %s fstype %s", + cp->fs_opts.fs_mtab, mp->am_path, p->fs_type); + } + cp->tried = TRUE; + } + + this_error = 0; + dont_retry = FALSE; + + if (mp->am_link) { + free(mp->am_link); + mp->am_link = 0; + } + + link_dir = mf->mf_fo->opt_sublink; + + if (link_dir && *link_dir) { + if (*link_dir == '/') { + mp->am_link = strdup(link_dir); + } else { + mp->am_link = str3cat((char *) 0, + mf->mf_fo->opt_fs, "/", link_dir); + normalize_slash(mp->am_link); + } + } + + if (mf->mf_error > 0) { + this_error = mf->mf_error; + } else if (mf->mf_flags & (MFF_MOUNTING|MFF_UNMOUNTING)) { + /* + * Still mounting - retry later + */ +#ifdef DEBUG + dlog("Duplicate pending mount fstype %s", p->fs_type); +#endif /* DEBUG */ + this_error = -1; + } else if (FSRV_ISDOWN(mf->mf_server)) { + /* + * Would just mount from the same place + * as a hung mount - so give up + */ +#ifdef DEBUG + dlog("%s is already hung - giving up", mf->mf_mount); +#endif /* DEBUG */ + mp_error = EWOULDBLOCK; + dont_retry = TRUE; + this_error = -1; + } else if (mf->mf_flags & MFF_MOUNTED) { +#ifdef DEBUG + dlog("duplicate mount of \"%s\" ...", mf->mf_info); +#endif /* DEBUG */ + /* + * Just call mounted() + */ + am_mounted(mp); + + this_error = 0; + break; + } + + /* + * Will usually need to play around with the mount nodes + * file attribute structure. This must be done here. + * Try and get things initialised, even if the fileserver + * is not known to be up. In the common case this will + * progress things faster. + */ + if (!this_error) { + /* + * Fill in attribute fields. + */ + if (mf->mf_ops->fs_flags & FS_DIRECTORY) + mk_fattr(mp, NFDIR); + else + mk_fattr(mp, NFLNK); + + mp->am_fattr.fileid = mp->am_gen; + + if (p->fs_init) + this_error = (*p->fs_init)(mf); + } + + /* + * Make sure the fileserver is UP before doing any more work + */ + if (!FSRV_ISUP(mf->mf_server)) { +#ifdef DEBUG + dlog("waiting for server %s to become available", mf->mf_server->fs_host); +#endif + this_error = -1; + } + + if (!this_error && mf->mf_fo->opt_delay) { + /* + * If there is a delay timer on the mount + * then don't try to mount if the timer + * has not expired. + */ + int i = atoi(mf->mf_fo->opt_delay); + if (i > 0 && clocktime() < (cp->start + i)) { +#ifdef DEBUG + dlog("Mount of %s delayed by %ds", mf->mf_mount, i - clocktime() + cp->start); +#endif /* DEBUG */ + this_error = -1; + } + } + + if (this_error < 0 && !dont_retry) { + if (!mf_retry) + mf_retry = dup_mntfs(mf); + cp->retry = TRUE; + } + + if (!this_error) + if (p->fs_flags & FS_MBACKGROUND) { + mf->mf_flags |= MFF_MOUNTING; /*XXX*/ +#ifdef DEBUG + dlog("backgrounding mount of \"%s\"", mf->mf_mount); +#endif /* DEBUG */ + if (cp->callout) { + untimeout(cp->callout); + cp->callout = 0; + } + run_task(try_mount, (voidp) mp, afs_cont, (voidp) cp); + mf->mf_flags |= MFF_MKMNT; /* XXX */ + if (mf_retry) free_mntfs(mf_retry); + return -1; + } else { +#ifdef DEBUG + dlog("foreground mount of \"%s\" ...", mf->mf_info); +#endif /* DEBUG */ + this_error = try_mount((voidp) mp); + if (this_error < 0) { + if (!mf_retry) + mf_retry = dup_mntfs(mf); + cp->retry = TRUE; + } + } + + if (this_error >= 0) { + if (this_error > 0) { + amd_stats.d_merr++; + if (mf != mf_retry) { + mf->mf_error = this_error; + mf->mf_flags |= MFF_ERROR; + } + } + /* + * Wakeup anything waiting for this mount + */ + wakeup((voidp) mf); + } + } + + if (this_error && cp->retry) { + free_mntfs(mf); + mf = cp->mp->am_mnt = mf_retry; + /* + * Not retrying again (so far) + */ + cp->retry = FALSE; + cp->tried = FALSE; + /* + * Start at the beginning. + * Rewind the location vector and + * reset the default options. + */ + cp->ivec = cp->xivec; + cp->def_opts = strealloc(cp->def_opts, cp->auto_opts); + /* + * Arrange that afs_bgmount is called + * after anything else happens. + */ +#ifdef DEBUG + dlog("Arranging to retry mount of %s", cp->mp->am_path); +#endif /* DEBUG */ + sched_task(afs_retry, (voidp) cp, (voidp) mf); + if (cp->callout) + untimeout(cp->callout); + cp->callout = timeout(RETRY_INTERVAL, wakeup, (voidp) mf); + + cp->mp->am_ttl = clocktime() + RETRY_INTERVAL; + + /* + * Not done yet - so don't return anything + */ + return -1; + } + + if (hard_error < 0 || this_error == 0) + hard_error = this_error; + + /* + * Discard handle on duff filesystem. + * This should never happen since it + * should be caught by the case above. + */ + if (mf_retry) { + if (hard_error) + plog(XLOG_ERROR, "discarding a retry mntfs for %s", mf_retry->mf_mount); + free_mntfs(mf_retry); + } + + /* + * If we get here, then either the mount succeeded or + * there is no more mount information available. + */ + if (hard_error < 0 && mp_error) + hard_error = cp->mp->am_error = mp_error; + if (hard_error > 0) { + /* + * Set a small(ish) timeout on an error node if + * the error was not a time out. + */ + switch (hard_error) { + case ETIMEDOUT: + case EWOULDBLOCK: + cp->mp->am_timeo = 5; + break; + default: + cp->mp->am_timeo = 17; + break; + } + new_ttl(cp->mp); + } + + /* + * Make sure that the error value in the mntfs has a + * reasonable value. + */ + if (mf->mf_error < 0) { + mf->mf_error = hard_error; + if (hard_error) + mf->mf_flags |= MFF_ERROR; + } + + /* + * In any case we don't need the continuation any more + */ + free_continuation(cp); + + return hard_error; +} + +/* + * Automount interface to RPC lookup routine + */ +static am_node *afs_lookuppn P((am_node *mp, char *fname, int *error_return, int op)); +static am_node *afs_lookuppn(mp, fname, error_return, op) +am_node *mp; +char *fname; +int *error_return; +int op; +{ +#define ereturn(x) { *error_return = x; return 0; } + + /* + * Find the corresponding entry and return + * the file handle for it. + */ + am_node *ap, *new_mp, *ap_hung; + char *info; /* Mount info - where to get the file system */ + char **ivec, **xivec; /* Split version of info */ + char *auto_opts; /* Automount options */ + int error = 0; /* Error so far */ + char path_name[MAXPATHLEN]; /* General path name buffer */ + char *pfname; /* Path for database lookup */ + struct continuation *cp; /* Continuation structure if we need to mount */ + int in_progress = 0; /* # of (un)mount in progress */ + char *dflts; + mntfs *mf; + +#ifdef DEBUG + dlog("in afs_lookuppn"); +#endif /* DEBUG */ + + /* + * If the server is shutting down + * then don't return information + * about the mount point. + */ + if (amd_state == Finishing) { +#ifdef DEBUG + if ((mf = mp->am_mnt) == 0 || mf->mf_ops == &dfs_ops) + dlog("%s mount ignored - going down", fname); + else + dlog("%s/%s mount ignored - going down", mp->am_path, fname); +#endif /* DEBUG */ + ereturn(ENOENT); + } + + /* + * Handle special case of "." and ".." + */ + if (fname[0] == '.') { + if (fname[1] == '\0') + return mp; /* "." is the current node */ + if (fname[1] == '.' && fname[2] == '\0') { + if (mp->am_parent) { +#ifdef DEBUG + dlog(".. in %s gives %s", mp->am_path, mp->am_parent->am_path); +#endif /* DEBUG */ + return mp->am_parent; /* ".." is the parent node */ + } + ereturn(ESTALE); + } + } + + /* + * Check for valid key name. + * If it is invalid then pretend it doesn't exist. + */ + if (!valid_key(fname)) { + plog(XLOG_WARNING, "Key \"%s\" contains a disallowed character", fname); + ereturn(ENOENT); + } + + /* + * Expand key name. + * fname is now a private copy. + */ + fname = expand_key(fname); + + for (ap_hung = 0, ap = mp->am_child; ap; ap = ap->am_osib) { + /* + * Otherwise search children of this node + */ + if (FSTREQ(ap->am_name, fname)) { + mf = ap->am_mnt; + if (ap->am_error) { + error = ap->am_error; + continue; + } + + /* + * If the error code is undefined then it must be + * in progress. + */ + if (mf->mf_error < 0) + goto in_progrss; + + /* + * Check for a hung node + */ + if (FSRV_ISDOWN(mf->mf_server)) { +#ifdef DEBUG + dlog("server hung"); +#endif /* DEBUG */ + error = ap->am_error; + ap_hung = ap; + continue; + } + + /* + * If there was a previous error with this node + * then return that error code. + */ + if (mf->mf_flags & MFF_ERROR) { + error = mf->mf_error; + continue; + } + + if (!(mf->mf_flags & MFF_MOUNTED) /*|| (mf->mf_flags & MFF_UNMOUNTING)*/) { +in_progrss: + /* + * If the fs is not mounted or it is unmounting then there + * is a background (un)mount in progress. In this case + * we just drop the RPC request (return nil) and + * wait for a retry, by which time the (un)mount may + * have completed. + */ +#ifdef DEBUG + dlog("ignoring mount of %s in %s -- in progress", + fname, mf->mf_mount); +#endif /* DEBUG */ + in_progress++; + continue; + } + + /* + * Otherwise we have a hit: return the current mount point. + */ +#ifdef DEBUG + dlog("matched %s in %s", fname, ap->am_path); +#endif /* DEBUG */ + free(fname); + return ap; + } + } + + if (in_progress) { +#ifdef DEBUG + dlog("Waiting while %d mount(s) in progress", in_progress); +#endif /* DEBUG */ + free(fname); + ereturn(-1); + } + + /* + * If an error occured then return it. + */ + if (error) { +#ifdef DEBUG + errno = error; /* XXX */ + dlog("Returning error: %m", error); +#endif /* DEBUG */ + free(fname); + ereturn(error); + } + + /* + * If doing a delete then don't create again! + */ + switch (op) { + case VLOOK_DELETE: + ereturn(ENOENT); + break; + + case VLOOK_CREATE: + break; + + default: + plog(XLOG_FATAL, "Unknown op to afs_lookuppn: 0x%x", op); + ereturn(EINVAL); + break; + } + + /* + * If the server is going down then just return, + * don't try to mount any more file systems + */ + if ((int)amd_state >= (int)Finishing) { +#ifdef DEBUG + dlog("not found - server going down anyway"); +#endif /* DEBUG */ + free(fname); + ereturn(ENOENT); + } + + /* + * If we get there then this is a reference to an, + * as yet, unknown name so we need to search the mount + * map for it. + */ + if (mp->am_pref) { + sprintf(path_name, "%s%s", mp->am_pref, fname); + pfname = path_name; + } else { + pfname = fname; + } + + mf = mp->am_mnt; + +#ifdef DEBUG + dlog("will search map info in %s to find %s", mf->mf_info, pfname); +#endif /* DEBUG */ + /* + * Consult the oracle for some mount information. + * info is malloc'ed and belongs to this routine. + * It ends up being free'd in free_continuation(). + * + * Note that this may return -1 indicating that information + * is not yet available. + */ + error = mapc_search((mnt_map*) mf->mf_private, pfname, &info); + if (error) { + if (error > 0) + plog(XLOG_MAP, "No map entry for %s", pfname); + else + plog(XLOG_MAP, "Waiting on map entry for %s", pfname); + free(fname); + ereturn(error); + } + +#ifdef DEBUG + dlog("mount info is %s", info); +#endif /* DEBUG */ + + /* + * Split info into an argument vector. + * The vector is malloc'ed and belongs to + * this routine. It is free'd in free_continuation() + */ + xivec = ivec = strsplit(info, ' ', '\"'); + + /* + * Default error code... + */ + if (ap_hung) + error = EWOULDBLOCK; + else + error = ENOENT; + + /* + * Allocate a new map + */ + new_mp = exported_ap_alloc(); + if (new_mp == 0) { + free((voidp) xivec); + free((voidp) info); + free((voidp) fname); + ereturn(ENOSPC); + } + + if (mf->mf_auto) + auto_opts = mf->mf_auto; + else + auto_opts = ""; + + auto_opts = strdup(auto_opts); + +#ifdef DEBUG + dlog("searching for /defaults entry"); +#endif /* DEBUG */ + if (mapc_search((mnt_map*) mf->mf_private, "/defaults", &dflts) == 0) { + char *dfl; + char **rvec; +#ifdef DEBUG + dlog("/defaults gave %s", dflts); +#endif /* DEBUG */ + if (*dflts == '-') + dfl = dflts+1; + else + dfl = dflts; + + /* + * Chop the defaults up + */ + rvec = strsplit(dfl, ' ', '\"'); + /* + * Extract first value + */ + dfl = rvec[0]; + + /* + * If there were any values at all... + */ + if (dfl) { + /* + * Log error if there were other values + */ + if (rvec[1]) { +#ifdef DEBUG + dlog("/defaults chopped into %s", dfl); +#endif /* DEBUG */ + plog(XLOG_USER, "More than a single value for /defaults in %s", mf->mf_info); + } + + /* + * Prepend to existing defaults if they exist, + * otherwise just use these defaults. + */ + if (*auto_opts && *dfl) { + char *nopts = (char *) xmalloc(strlen(auto_opts)+strlen(dfl)+2); + sprintf(nopts, "%s;%s", dfl, auto_opts); + free(auto_opts); + auto_opts = nopts; + } else if (*dfl) { + auto_opts = strealloc(auto_opts, dfl); + } + } + free(dflts); + /* + * Don't need info vector any more + */ + free((voidp) rvec); + } + + /* + * Fill it in + */ + init_map(new_mp, fname); + + /* + * Put it in the table + */ + insert_am(new_mp, mp); + + /* + * Fill in some other fields, + * path and mount point. + * + * bugfix: do not prepend old am_path if direct map + * William Sebok + */ + new_mp->am_path = str3cat(new_mp->am_path, + mf->mf_ops == &dfs_ops ? "" : mp->am_path, + *fname == '/' ? "" : "/", fname); + +#ifdef DEBUG + dlog("setting path to %s", new_mp->am_path); +#endif /* DEBUG */ + + /* + * Take private copy of pfname + */ + pfname = strdup(pfname); + + /* + * Construct a continuation + */ + cp = ALLOC(continuation); + cp->mp = new_mp; + cp->xivec = xivec; + cp->ivec = ivec; + cp->info = info; + cp->key = pfname; + cp->auto_opts = auto_opts; + cp->retry = FALSE; + cp->tried = FALSE; + cp->start = clocktime(); + cp->def_opts = strdup(auto_opts); + bzero((voidp) &cp->fs_opts, sizeof(cp->fs_opts)); + + /* + * Try and mount the file system + * If this succeeds immediately (possible + * for a ufs file system) then return + * the attributes, otherwise just + * return an error. + */ + error = afs_bgmount(cp, error); + reschedule_timeout_mp(); + if (!error) { + free(fname); + return new_mp; + } + + if (error && (cp->mp->am_mnt->mf_ops == &efs_ops)) + cp->mp->am_error = error; + + assign_error_mntfs(new_mp); + + free(fname); + + ereturn(error); +#undef ereturn +} + +/* + * Locate next node in sibling list which is mounted + * and is not an error node. + */ +static am_node *next_nonerror_node P((am_node *xp)); +static am_node *next_nonerror_node(xp) +am_node *xp; +{ + mntfs *mf; + + /* + * Bug report (7/12/89) from Rein Tollevik + * Fixes a race condition when mounting direct automounts. + * Also fixes a problem when doing a readdir on a directory + * containing hung automounts. + */ + while (xp && + (!(mf = xp->am_mnt) || /* No mounted filesystem */ + mf->mf_error != 0 || /* There was a mntfs error */ + xp->am_error != 0 || /* There was a mount error */ + !(mf->mf_flags & MFF_MOUNTED) || /* The fs is not mounted */ + (mf->mf_server->fs_flags & FSF_DOWN)) /* The fs may be down */ + ) + xp = xp->am_osib; + + return xp; +} + +static int afs_readdir P((am_node *mp, nfscookie cookie, struct dirlist *dp, struct entry *ep, int count)); +static int afs_readdir(mp, cookie, dp, ep, count) +am_node *mp; +nfscookie cookie; +struct dirlist *dp; +struct entry *ep; +int count; +{ + unsigned int gen = *(unsigned int*) cookie; + am_node *xp; + + dp->eof = FALSE; + + if (gen == 0) { + /* + * In the default instance (which is used to + * start a search) we return "." and "..". + * + * This assumes that the count is big enough + * to allow both "." and ".." to be returned in + * a single packet. If it isn't (which would + * be fairly unbelievable) then tough. + */ +#ifdef DEBUG + dlog("default search"); +#endif /* DEBUG */ + /* + * Check for enough room. This is extremely + * approximate but is more than enough space. + * Really need 2 times: + * 4byte fileid + * 4byte cookie + * 4byte name length + * 4byte name + * plus the dirlist structure + */ + if (count < + (2 * (2 * (sizeof(*ep) + sizeof("..") + 4) + + sizeof(*dp)))) + return EINVAL; + + xp = next_nonerror_node(mp->am_child); + dp->entries = ep; + + /* construct "." */ + ep[0].fileid = mp->am_gen; + ep[0].name = "."; + ep[0].nextentry = &ep[1]; + *(unsigned int *) ep[0].cookie = 0; + + /* construct ".." */ + if (mp->am_parent) + ep[1].fileid = mp->am_parent->am_gen; + else + ep[1].fileid = mp->am_gen; + ep[1].name = ".."; + ep[1].nextentry = 0; + *(unsigned int *) ep[1].cookie = + xp ? xp->am_gen : ~(unsigned int)0; + + if (!xp) dp->eof = TRUE; + return 0; + } + +#ifdef DEBUG + dlog("real child"); +#endif /* DEBUG */ + + if (gen == ~(unsigned int)0) { +#ifdef DEBUG + dlog("End of readdir in %s", mp->am_path); +#endif /* DEBUG */ + dp->eof = TRUE; + dp->entries = 0; + return 0; + } + + xp = mp->am_child; + while (xp && xp->am_gen != gen) + xp = xp->am_osib; + + if (xp) { + int nbytes = count / 2; /* conservative */ + int todo = MAX_READDIR_ENTRIES; + dp->entries = ep; + do { + am_node *xp_next = next_nonerror_node(xp->am_osib); + + if (xp_next) { + *(unsigned int *) ep->cookie = xp_next->am_gen; + } else { + *(unsigned int *) ep->cookie = ~(unsigned int)0; + dp->eof = TRUE; + } + + ep->fileid = xp->am_gen; + ep->name = xp->am_name; + nbytes -= sizeof(*ep) + strlen(xp->am_name) + 1; + + xp = xp_next; + + if (nbytes > 0 && !dp->eof && todo > 1) { + ep->nextentry = ep + 1; + ep++; + --todo; + } else { + todo = 0; + } + } while (todo > 0); + + ep->nextentry = 0; + + return 0; + } + + return ESTALE; + +} + +static am_node *dfs_readlink P((am_node *mp, int *error_return)); +static am_node *dfs_readlink(mp, error_return) +am_node *mp; +int *error_return; +{ + am_node *xp; + int rc = 0; + + xp = next_nonerror_node(mp->am_child); + if (!xp) { + if (!mp->am_mnt->mf_private) + afs_mkcacheref(mp->am_mnt); /* XXX */ + xp = afs_lookuppn(mp, mp->am_path+1, &rc, VLOOK_CREATE); + } + + if (xp) { + new_ttl(xp); /* (7/12/89) from Rein Tollevik */ + return xp; + } + if (amd_state == Finishing) + rc = ENOENT; + *error_return = rc; + return 0; +} + +/* + * Ops structure + */ +am_ops root_ops = { + "root", + 0, /* root_match */ + 0, /* root_init */ + root_mount, + 0, + afs_umount, + 0, + afs_lookuppn, + afs_readdir, + 0, /* root_readlink */ + 0, /* root_mounted */ + 0, /* root_umounted */ + find_afs_srvr, + FS_NOTIMEOUT|FS_AMQINFO|FS_DIRECTORY +}; + +am_ops afs_ops = { + "auto", + afs_match, + 0, /* afs_init */ + afs_mount, + 0, + afs_umount, + 0, + afs_lookuppn, + afs_readdir, + 0, /* afs_readlink */ + 0, /* afs_mounted */ + afs_umounted, + find_afs_srvr, + FS_AMQINFO|FS_DIRECTORY +}; + +am_ops toplvl_ops = { + "toplvl", + afs_match, + 0, /* afs_init */ + toplvl_mount, + 0, + toplvl_umount, + 0, + afs_lookuppn, + afs_readdir, + 0, /* toplvl_readlink */ + toplvl_mounted, + 0, /* toplvl_umounted */ + find_afs_srvr, + FS_MKMNT|FS_NOTIMEOUT|FS_BACKGROUND|FS_AMQINFO|FS_DIRECTORY +}; + +am_ops dfs_ops = { + "direct", + afs_match, + 0, /* dfs_init */ + toplvl_mount, + 0, + toplvl_umount, + 0, + efs_lookuppn, + efs_readdir, + dfs_readlink, + toplvl_mounted, + 0, /* afs_umounted */ + find_afs_srvr, + FS_MKMNT|FS_NOTIMEOUT|FS_BACKGROUND|FS_AMQINFO +}; + +#ifdef HAS_UNION_FS +am_ops union_ops = { + "union", + afs_match, + 0, /* afs_init */ + toplvl_mount, + 0, + toplvl_umount, + 0, + afs_lookuppn, + afs_readdir, + 0, /* toplvl_readlink */ + union_mounted, + 0, /* toplvl_umounted */ + find_afs_srvr, + FS_MKMNT|FS_NOTIMEOUT|FS_BACKGROUND|FS_AMQINFO|FS_DIRECTORY +}; +#endif /* HAS_UNION_FS */ diff --git a/usr.sbin/amd/amd/am_ops.c b/usr.sbin/amd/amd/am_ops.c new file mode 100644 index 0000000..4360110 --- /dev/null +++ b/usr.sbin/amd/amd/am_ops.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)am_ops.c 8.1 (Berkeley) 6/6/93 + * + * $Id: am_ops.c,v 5.2.2.1 1992/02/09 15:08:17 jsp beta $ + * + */ + +#include "am.h" + +static am_ops *vops[] = { +#ifdef HAS_UFS + &ufs_ops, +#endif +#ifdef HAS_NFS + &nfs_ops, +#endif +#ifdef HAS_NFSX + &nfsx_ops, +#endif +#ifdef HAS_HOST + &host_ops, +#endif +#ifdef HAS_SFS + &sfs_ops, +#endif +#ifdef HAS_SFSX + &sfsx_ops, +#endif +#ifdef HAS_LOFS + &lofs_ops, +#endif +#ifdef HAS_PFS + &pfs_ops, +#endif +#ifdef HAS_UNION_FS + &union_ops, +#endif + &afs_ops, /* These four should be last ... */ + &dfs_ops, /* ... */ + &toplvl_ops, /* ... */ + &efs_ops, /* ... in the order afs; dfs; toplvl; efs */ + 0 +}; + +void ops_showfstypes P((FILE *fp)); +void ops_showfstypes(fp) +FILE *fp; +{ + struct am_ops **ap; + int l = 0; + + for (ap = vops; *ap; ap++) { + fputs((*ap)->fs_type, fp); + if (ap[1]) fputs(", ", fp); + l += strlen((*ap)->fs_type) + 2; + if (l > 60) { l = 0; fputs("\n ", fp); } + } +} + +#ifdef SUNOS4_COMPAT +#ifdef nomore +/* + * Crack a SunOS4-style host:fs:sub-link line + * Construct an amd-style line and call the + * normal amd matcher. + */ +am_ops *sunos4_match(fo, key, g_key, path, keym, map) +am_opts *fo; +char *key; +char *g_key; +char *path; +char *keym; +char *map; +{ + char *host = key; + char *fs = strchr(host, ':'); + char *sublink = fs ? strchr(fs+1, ':') : 0; + char keybuf[MAXPATHLEN]; + + sprintf(keybuf, "type:=nfs;rhost:=%s;rfs:=%s;sublink:=%s;opts:=%s", host, + fs ? fs+1 : "", + sublink ? sublink+1 : "", + g_key); + return ops_match(fo, keybuf, "", path, keym, map); +} +#endif +#endif /* SUNOS4_COMPAT */ + +am_ops *ops_match(fo, key, g_key, path, keym, map) +am_opts *fo; +char *key; +char *g_key; +char *path; +char *keym; +char *map; +{ + am_ops **vp; + am_ops *rop = 0; + + /* + * First crack the global opts and the local opts + */ + if (!eval_fs_opts(fo, key, g_key, path, keym, map)) { + rop = &efs_ops; + } else if (fo->opt_type == 0) { + plog(XLOG_USER, "No fs type specified (key = \"%s\", map = \"%s\")", keym, map); + rop = &efs_ops; + } else { + /* + * Next find the correct filesystem type + */ + for (vp = vops; rop = *vp; vp++) + if (strcmp(rop->fs_type, fo->opt_type) == 0) + break; + + if (!rop) { + plog(XLOG_USER, "fs type \"%s\" not recognised", fo->opt_type); + rop = &efs_ops; + } + } + + /* + * Make sure we have a default mount option. + * Otherwise skip past any leading '-'. + */ + if (fo->opt_opts == 0) + fo->opt_opts = "rw,defaults"; + else if (*fo->opt_opts == '-') + fo->opt_opts++; + + /* + * Check the filesystem is happy + */ + if (fo->fs_mtab) + free((voidp) fo->fs_mtab); + + if (fo->fs_mtab = (*rop->fs_match)(fo)) + return rop; + + /* + * Return error file system + */ + fo->fs_mtab = (*efs_ops.fs_match)(fo); + return &efs_ops; +} diff --git a/usr.sbin/amd/amd/amd.8 b/usr.sbin/amd/amd/amd.8 new file mode 100644 index 0000000..9fa01a2 --- /dev/null +++ b/usr.sbin/amd/amd/amd.8 @@ -0,0 +1,232 @@ +.\" +.\" Copyright (c) 1989 Jan-Simon Pendry +.\" Copyright (c) 1989 Imperial College of Science, Technology & Medicine +.\" Copyright (c) 1989, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Jan-Simon Pendry at Imperial College, London. +.\" +.\" 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. +.\" +.\" @(#)amd.8 5.10 (Berkeley) 4/19/94 +.\" +.\" $Id: amd.8,v 5.2.2.1 1992/02/09 15:11:39 jsp beta $ +.\" +.Dd "April 19, 1994" +.Dt AMD 8 +.Os +.Sh NAME +.Nm amd +.Nd automatically mount file systems +.Sh SYNOPSIS +.Nm amd +.Op Fl nprv +.Op Fl a Ar mount_point +.Op Fl c Ar duration +.Op Fl d Ar domain +.Bk -words +.Op Fl k Ar kernel-arch +.Ek +.Op Fl l Ar logfile +.Op Fl t Ar interval.interval +.Bk -words +.Op Fl w Ar interval +.Ek +.Op Fl x Ar log-option +.Op Fl y Ar YP-domain +.Bk -words +.Op Fl C Ar cluster-name +.Ek +.Op Fl D Ar option +.Oo +.Ar directory mapname +.Op Fl map-options +.Oc +.Ar ... +.Sh DESCRIPTION +.Nm Amd +is a daemon that automatically mounts filesystems +whenever a file or directory +within that filesystem is accessed. +Filesystems are automatically unmounted when they +appear to be quiescent. +.Pp +.Nm Amd +operates by attaching itself as an +.Tn NFS +server to each of the specified +.Ar directories . +Lookups within the specified directories +are handled by +.Nm amd , +which uses the map defined by +.Ar mapname +to determine how to resolve the lookup. +Generally, this will be a host name, some filesystem information +and some mount options for the given filesystem. +.Sh OPTIONS +.Bl -tag -width Ds +.It Fl a Ar temporary-directory +Specify an alternative location for the real mount points. +The default is +.Pa /a . +.It Fl c Ar duration +Specify a +.Ar duration , +in seconds, that a looked up name remains +cached when not in use. The default is 5 minutes. +.It Fl d Ar domain +Specify the local domain name. If this option is not +given the domain name is determined from the hostname. +.It Fl k Ar kernel-arch +Specifies the kernel architecture. This is used solely +to set the ${karch} selector. +.It Fl l Ar logfile +Specify a logfile in which to record mount and unmount events. +If +.Ar logfile +is the string +.Em syslog , +the log messages will be sent to the system log daemon by +.Xr syslog 3 . +.It Fl n +Normalize hostnames. +The name referred to by ${rhost} is normalized relative to the +host database before being used. The effect is to translate +aliases into ``official'' names. +.It Fl p +Print +.Em PID . +Outputs the process-id of +.Nm amd +to standard output where it can be saved into a file. +.It Fl r +Restart existing mounts. +.Nm Amd +will scan the mount file table to determine which filesystems +are currently mounted. Whenever one of these would have +been auto-mounted, +.Nm amd +.Em inherits +it. +.It Fl t Ar interval.interval +Specify the +.Ar interval , +in tenths of a second, between +.Tn NFS/RPC/UDP +retries. +The default is 0.8 seconds. +The second values alters the retransmit counter. +Useful defaults are supplied if either or both +values are missing. +.It Fl v +Version. Displays version and configuration information on standard error. +.It Fl w Ar interval +Specify an +.Ar interval , +in seconds, between attempts to dismount +filesystems that have exceeded their cached times. +The default is 2 minutes. +.It Fl y Ar domain +Specify an alternative +.Tn NIS +domain from which to fetch the +.Tn NIS +maps. +The default is the system domain name. +This option is ignored if +.Tn NIS +support is not available. +.It Fl x Ar options +Specify run-time logging options. The options are a comma separated +list chosen from: fatal, error, user, warn, info, map, stats, all. +.It Fl D Ar option +Select from a variety of debug options. Prefixing an +option with the string +.Em no +reverses the effect of that option. Options are cumulative. +The most useful option is +.Ar all . +.El +.Pp +Since +.Fl D +is only used for debugging other options are not documented here: +the current supported set of options is listed by the +.Fl v +option +and a fuller description is available in the program source. +.Sh FILES +.Bl -tag -width /axx +.It Pa /a +directory under which filesystems are dynamically mounted +.El +.Sh CAVEATS +Some care may be required when creating a mount map. +.Pp +Symbolic links on an +.Tn NFS +filesystem can be incredibly inefficient. +In most implementations of +.Tn NFS , +their interpolations are not cached by +the kernel and each time a symbolic link is +encountered during a +.Em lookuppn +translation it costs an +.Tn RPC +call to the +.Tn NFS +server. +A large improvement in real-time +performance could be gained by adding a cache somewhere. +Replacing +.Xr symlinks 2 +with a suitable incarnation of the auto-mounter +results in a large real-time speedup, but also causes a large +number of process context switches. +.Pp +A weird imagination is most useful to gain full advantage of all +the features. +.Sh SEE ALSO +.Xr amq 8 , +.Xr hostname 1 , +.Xr mount 8 , +.Xr umount 8 , +.Rs +.%T Amd \- The 4.4 BSD Automounter +.Re +.Sh AUTHOR +.An Jan-Simon Pendry +, Department of Computing, Imperial College, London, UK. +.Sh HISTORY +The +.Nm amd +utility first appeared in 4.4BSD. diff --git a/usr.sbin/amd/amd/amd.c b/usr.sbin/amd/amd/amd.c new file mode 100644 index 0000000..c3b2b61 --- /dev/null +++ b/usr.sbin/amd/amd/amd.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)amd.c 8.1 (Berkeley) 6/6/93 + * + * $Id: amd.c,v 5.2.2.1 1992/02/09 15:08:15 jsp beta $ + * + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1989, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +/* + * Automounter + */ + +#include "am.h" +#include +#include +#include +#include + +char pid_fsname[16 + MAXHOSTNAMELEN]; /* "kiska.southseas.nz:(pid%d)" */ +char *progname; /* "amd" */ +#ifdef HAS_HOST +#ifdef HOST_EXEC +char *host_helper; +#endif /* HOST_EXEC */ +#endif /* HAS_HOST */ +char *auto_dir = "/a"; +char *hostdomain = "unknown.domain"; +char hostname[MAXHOSTNAMELEN] = "localhost"; /* Hostname */ +char hostd[2*MAXHOSTNAMELEN]; /* Host+domain */ +char *op_sys = OS_REP; /* Name of current op_sys */ +char *arch = ARCH_REP; /* Name of current architecture */ +char *endian = ARCH_ENDIAN; /* Big or Little endian */ +char *wire; +int foreground = 1; /* This is the top-level server */ +int mypid; /* Current process id */ +int immediate_abort; /* Should close-down unmounts be retried */ +struct in_addr myipaddr; /* (An) IP address of this host */ +serv_state amd_state; +struct amd_stats amd_stats; /* Server statistics */ +time_t do_mapc_reload = 0; /* mapc_reload() call required? */ +jmp_buf select_intr; +int select_intr_valid; +int orig_umask; + +/* + * Signal handler: + * SIGINT - tells amd to do a full shutdown, including unmounting all filesystem. + * SIGTERM - tells amd to shutdown now. Just unmounts the automount nodes. + */ +static void sigterm(sig) +int sig; +{ +#ifdef SYS5_SIGNALS + signal(sig, sigterm); +#endif /* SYS5_SIGNALS */ + + switch (sig) { + case SIGINT: + immediate_abort = 15; + break; + + case SIGTERM: + immediate_abort = -1; + /* fall through... */ + + default: + plog(XLOG_WARNING, "WARNING: automounter going down on signal %d", sig); + break; + } + if (select_intr_valid) + longjmp(select_intr, sig); +} + +/* + * Hook for cache reload. + * When a SIGHUP arrives it schedules a call to mapc_reload + */ +/*ARGSUSED*/ +static void sighup(sig) +int sig; +{ +#ifdef SYS5_SIGNALS + signal(sig, sighup); +#endif /* SYS5_SIGNALS */ + +#ifdef DEBUG + if (sig != SIGHUP) + dlog("spurious call to sighup"); +#endif /* DEBUG */ + /* + * Force a reload by zero'ing the timer + */ + if (amd_state == Run) + do_mapc_reload = 0; +} + +/*ARGSUSED*/ +static void parent_exit(sig) +int sig; +{ + exit(0); +} + +static int daemon_mode(P_void) +{ + int bgpid; + + signal(SIGQUIT, parent_exit); + bgpid = background(); + + if (bgpid != 0) { + if (print_pid) { + printf("%d\n", bgpid); + fflush(stdout); + } + /* + * Now wait for the automount points to + * complete. + */ + for (;;) + pause(); + } + + signal(SIGQUIT, SIG_DFL); + + /* + * Pretend we are in the foreground again + */ + foreground = 1; + +#ifdef TIOCNOTTY + { + int t = open("/dev/tty", O_RDWR); + if (t < 0) { + if (errno != ENXIO) /* not an error if already no controlling tty */ + plog(XLOG_WARNING, "Could not open controlling tty: %m"); + } else { + if (ioctl(t, TIOCNOTTY, 0) < 0 && errno != ENOTTY) + plog(XLOG_WARNING, "Could not disassociate tty (TIOCNOTTY): %m"); + (void) close(t); + } + } +#else + (void) setpgrp(); +#endif /* TIOCNOTTY */ + + return getppid(); +} + +main(argc, argv) +int argc; +char *argv[]; +{ + char *domdot; + int ppid = 0; + int error; + + /* + * Make sure some built-in assumptions are true before we start + */ + assert(sizeof(nfscookie) >= sizeof (unsigned int)); + assert(sizeof(int) >= 4); + + /* + * Set processing status. + */ + amd_state = Start; + + /* + * Determine program name + */ + if (argv[0]) { + progname = strrchr(argv[0], '/'); + if (progname && progname[1]) + progname++; + else + progname = argv[0]; + } + + if (!progname) + progname = "amd"; + + /* + * Initialise process id. This is kept + * cached since it is used for generating + * and using file handles. + */ + mypid = getpid(); + + /* + * Get local machine name + */ + if (gethostname(hostname, sizeof(hostname)) < 0) { + plog(XLOG_FATAL, "gethostname: %m"); + going_down(1); + } + /* + * Check it makes sense + */ + if (!*hostname) { + plog(XLOG_FATAL, "host name is not set"); + going_down(1); + } + /* + * Partially initialise hostd[]. This + * is completed in get_args(). + */ + if (domdot = strchr(hostname, '.')) { + /* + * Hostname already contains domainname. + * Split out hostname and domainname + * components + */ + *domdot++ = '\0'; + hostdomain = domdot; + } + strcpy(hostd, hostname); + + /* + * Trap interrupts for shutdowns. + */ + (void) signal(SIGINT, sigterm); + + /* + * Hangups tell us to reload the cache + */ + (void) signal(SIGHUP, sighup); + + /* + * Trap Terminate so that we can shutdown gracefully (some chance) + */ + (void) signal(SIGTERM, sigterm); + /* + * Trap Death-of-a-child. These allow us to + * pick up the exit status of backgrounded mounts. + * See "sched.c". + */ + (void) signal(SIGCHLD, sigchld); + + /* + * Fix-up any umask problems. Most systems default + * to 002 which is not too convenient for our purposes + */ + orig_umask = umask(0); + + /* + * Figure out primary network name + */ + wire = getwire(); + + /* + * Determine command-line arguments + */ + get_args(argc, argv); + + /* + * Get our own IP address so that we + * can mount the automounter. + */ + { struct sockaddr_in sin; + get_myaddress(&sin); + myipaddr.s_addr = sin.sin_addr.s_addr; + } + + /* + * Now check we are root. + */ + if (geteuid() != 0) { + plog(XLOG_FATAL, "Must be root to mount filesystems (euid = %d)", geteuid()); + going_down(1); + } + +#ifdef HAS_NIS_MAPS + /* + * If the domain was specified then bind it here + * to circumvent any default bindings that may + * be done in the C library. + */ + if (domain && yp_bind(domain)) { + plog(XLOG_FATAL, "Can't bind to domain \"%s\"", domain); + going_down(1); + } +#endif /* HAS_NIS_MAPS */ + +#ifdef DEBUG + Debug(D_DAEMON) +#endif /* DEBUG */ + ppid = daemon_mode(); + + sprintf(pid_fsname, "%s:(pid%d)", hostname, mypid); + + do_mapc_reload = clocktime() + ONE_HOUR; + + /* + * Register automounter with system + */ + error = mount_automounter(ppid); + if (error && ppid) + kill(SIGALRM, ppid); + going_down(error); + + abort(); +} diff --git a/usr.sbin/amd/amd/amq_subr.c b/usr.sbin/amd/amd/amq_subr.c new file mode 100644 index 0000000..cf04d9d --- /dev/null +++ b/usr.sbin/amd/amd/amq_subr.c @@ -0,0 +1,464 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)amq_subr.c 8.1 (Berkeley) 6/6/93 + * + * $Id: amq_subr.c,v 5.2.2.1 1992/02/09 15:08:18 jsp beta $ + * + */ +/* + * Auxilliary routines for amq tool + */ + +#include "am.h" +#include "amq.h" +#include + +/*ARGSUSED*/ +voidp +amqproc_null_1(argp, rqstp) +voidp argp; +struct svc_req *rqstp; +{ + static char res; + + return (voidp) &res; +} + +/* + * Return a sub-tree of mounts + */ +/*ARGSUSED*/ +amq_mount_tree_p * +amqproc_mnttree_1(argp, rqstp) +voidp argp; +struct svc_req *rqstp; +{ + static am_node *mp; + mp = find_ap(*(char **) argp); + return (amq_mount_tree_p *) ∓ +} + +/* + * Unmount a single node + */ +/*ARGSUSED*/ +voidp +amqproc_umnt_1(argp, rqstp) +voidp argp; +struct svc_req *rqstp; +{ + static char res; + am_node *mp = find_ap(*(char **) argp); + if (mp) + forcibly_timeout_mp(mp); + + return (voidp) &res; +} + +/* + * Return global statistics + */ +/*ARGSUSED*/ +amq_mount_stats * +amqproc_stats_1(argp, rqstp) +voidp argp; +struct svc_req *rqstp; +{ + return (amq_mount_stats *) &amd_stats; +} + +/* + * Return the entire tree of mount nodes + */ +/*ARGSUSED*/ +amq_mount_tree_list * +amqproc_export_1(argp, rqstp) +voidp argp; +struct svc_req *rqstp; +{ + static amq_mount_tree_list aml; + + aml.amq_mount_tree_list_val = (amq_mount_tree_p *) &exported_ap[0]; + aml.amq_mount_tree_list_len = 1; /* XXX */ + + return &aml; +} + +int * +amqproc_setopt_1(argp, rqstp) +voidp argp; +struct svc_req *rqstp; +{ + static int rc; + + amq_setopt *opt = (amq_setopt *) argp; + + rc = 0; + switch (opt->as_opt) { + case AMOPT_DEBUG: +#ifdef DEBUG + if (debug_option(opt->as_str)) + rc = EINVAL; +#else + rc = EINVAL; +#endif /* DEBUG */ + break; + + case AMOPT_LOGFILE: +#ifdef not_yet + if (switch_to_logfile(opt->as_str)) + rc = EINVAL; +#else + rc = EACCES; +#endif /* not_yet */ + break; + + case AMOPT_XLOG: + if (switch_option(opt->as_str)) + rc = EINVAL; + break; + + case AMOPT_FLUSHMAPC: + if (amd_state == Run) { + plog(XLOG_INFO, "amq says flush cache"); + do_mapc_reload = 0; + flush_nfs_fhandle_cache((fserver *) 0); + flush_srvr_nfs_cache(); + } + break; + } + return &rc; +} + +amq_mount_info_list * +amqproc_getmntfs_1(argp, rqstp) +voidp argp; +struct svc_req *rqstp; +{ +extern qelem mfhead; + return (amq_mount_info_list *) &mfhead; /* XXX */ +} + +static int ok_security(rqstp) +struct svc_req *rqstp; +{ + struct sockaddr_in *sin; + + sin = svc_getcaller(rqstp->rq_xprt); + if (ntohs(sin->sin_port) >= 1024 || + !(sin->sin_addr.s_addr == htonl(0x7f000001) || + sin->sin_addr.s_addr == myipaddr.s_addr)) { + char dq[20]; + plog(XLOG_INFO, "AMQ request from %s.%d DENIED", + inet_dquad(dq, sin->sin_addr.s_addr), + ntohs(sin->sin_port)); + return(0); + } + return(1); +} + +int * +amqproc_mount_1(argp, rqstp) +voidp argp; +struct svc_req *rqstp; +{ + static int rc; + char *s = *(amq_string *) argp; + char *cp; + + plog(XLOG_INFO, "amq requested mount of %s", s); + /* + * Minimalist security check. + */ + if (!ok_security(rqstp)) { + rc = EACCES; + return &rc; + } + + /* + * Find end of key + */ + for (cp = (char *) s; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++) + ; + + if (!*cp) { + plog(XLOG_INFO, "amqproc_mount: Invalid arguments"); + rc = EINVAL; + return &rc; + } + *cp++ = '\0'; + + /* + * Find start of value + */ + while (*cp && isascii(*cp) && isspace(*cp)) + cp++; + + root_newmap(s, cp, (char *) 0); + rc = mount_auto_node(s, (voidp) root_node); + if (rc < 0) + return 0; + return &rc; +} + +amq_string * +amqproc_getvers_1(argp, rqstp) +voidp argp; +struct svc_req *rqstp; +{ +static amq_string res; + res = version; + return &res; +} + +/* + * XDR routines. + */ +bool_t +xdr_amq_string(xdrs, objp) + XDR *xdrs; + amq_string *objp; +{ + if (!xdr_string(xdrs, objp, AMQ_STRLEN)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_amq_setopt(xdrs, objp) + XDR *xdrs; + amq_setopt *objp; +{ + if (!xdr_enum(xdrs, (enum_t *)&objp->as_opt)) { + return (FALSE); + } + if (!xdr_string(xdrs, &objp->as_str, AMQ_STRLEN)) { + return (FALSE); + } + return (TRUE); +} + +/* + * More XDR routines - Should be used for OUTPUT ONLY. + */ +bool_t +xdr_amq_mount_tree_node(xdrs, objp) + XDR *xdrs; + amq_mount_tree *objp; +{ + am_node *mp = (am_node *) objp; + + if (!xdr_amq_string(xdrs, &mp->am_mnt->mf_info)) { + return (FALSE); + } + if (!xdr_amq_string(xdrs, &mp->am_path)) { + return (FALSE); + } + if (!xdr_amq_string(xdrs, mp->am_link ? &mp->am_link : &mp->am_mnt->mf_mount)) { + return (FALSE); + } + if (!xdr_amq_string(xdrs, &mp->am_mnt->mf_ops->fs_type)) { + return (FALSE); + } + if (!xdr_long(xdrs, &mp->am_stats.s_mtime)) { + return (FALSE); + } + if (!xdr_u_short(xdrs, &mp->am_stats.s_uid)) { + return (FALSE); + } + if (!xdr_int(xdrs, &mp->am_stats.s_getattr)) { + return (FALSE); + } + if (!xdr_int(xdrs, &mp->am_stats.s_lookup)) { + return (FALSE); + } + if (!xdr_int(xdrs, &mp->am_stats.s_readdir)) { + return (FALSE); + } + if (!xdr_int(xdrs, &mp->am_stats.s_readlink)) { + return (FALSE); + } + if (!xdr_int(xdrs, &mp->am_stats.s_statfs)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_amq_mount_subtree(xdrs, objp) + XDR *xdrs; + amq_mount_tree *objp; +{ + am_node *mp = (am_node *) objp; + + if (!xdr_amq_mount_tree_node(xdrs, objp)) { + return (FALSE); + } + if (!xdr_pointer(xdrs, (char **)&mp->am_osib, sizeof(amq_mount_tree), xdr_amq_mount_subtree)) { + return (FALSE); + } + if (!xdr_pointer(xdrs, (char **)&mp->am_child, sizeof(amq_mount_tree), xdr_amq_mount_subtree)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_amq_mount_tree(xdrs, objp) + XDR *xdrs; + amq_mount_tree *objp; +{ + am_node *mp = (am_node *) objp; + am_node *mnil = 0; + + if (!xdr_amq_mount_tree_node(xdrs, objp)) { + return (FALSE); + } + if (!xdr_pointer(xdrs, (char **)&mnil, sizeof(amq_mount_tree), xdr_amq_mount_subtree)) { + return (FALSE); + } + if (!xdr_pointer(xdrs, (char **)&mp->am_child, sizeof(amq_mount_tree), xdr_amq_mount_subtree)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_amq_mount_tree_p(xdrs, objp) + XDR *xdrs; + amq_mount_tree_p *objp; +{ + if (!xdr_pointer(xdrs, (char **)objp, sizeof(amq_mount_tree), xdr_amq_mount_tree)) { + return (FALSE); + } + return (TRUE); +} + + +bool_t +xdr_amq_mount_stats(xdrs, objp) + XDR *xdrs; + amq_mount_stats *objp; +{ + if (!xdr_int(xdrs, &objp->as_drops)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->as_stale)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->as_mok)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->as_merr)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->as_uerr)) { + return (FALSE); + } + return (TRUE); +} + + +bool_t +xdr_amq_mount_tree_list(xdrs, objp) + XDR *xdrs; + amq_mount_tree_list *objp; +{ + if (!xdr_array(xdrs, (char **)&objp->amq_mount_tree_list_val, (u_int *)&objp->amq_mount_tree_list_len, ~0, sizeof(amq_mount_tree_p), xdr_amq_mount_tree_p)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_amq_mount_info_qelem(xdrs, qhead) + XDR *xdrs; + qelem *qhead; +{ + /* + * Compute length of list + */ + mntfs *mf; + u_int len = 0; + for (mf = LAST(mntfs, qhead); mf != HEAD(mntfs, qhead); mf = PREV(mntfs, mf)) { + if (!(mf->mf_ops->fs_flags & FS_AMQINFO)) + continue; + len++; + } + xdr_u_int(xdrs, &len); + + /* + * Send individual data items + */ + for (mf = LAST(mntfs, qhead); mf != HEAD(mntfs, qhead); mf = PREV(mntfs, mf)) { + int up; + if (!(mf->mf_ops->fs_flags & FS_AMQINFO)) + continue; + + if (!xdr_amq_string(xdrs, &mf->mf_ops->fs_type)) { + return (FALSE); + } + if (!xdr_amq_string(xdrs, &mf->mf_mount)) { + return (FALSE); + } + if (!xdr_amq_string(xdrs, &mf->mf_info)) { + return (FALSE); + } + if (!xdr_amq_string(xdrs, &mf->mf_server->fs_host)) { + return (FALSE); + } + if (!xdr_int(xdrs, &mf->mf_error)) { + return (FALSE); + } + if (!xdr_int(xdrs, &mf->mf_refc)) { + return (FALSE); + } + if (mf->mf_server->fs_flags & FSF_ERROR) + up = 0; + else switch (mf->mf_server->fs_flags & (FSF_DOWN|FSF_VALID)) { + case FSF_DOWN|FSF_VALID: up = 0; break; + case FSF_VALID: up = 1; break; + default: up = -1; break; + } + if (!xdr_int(xdrs, &up)) { + return (FALSE); + } + } + return (TRUE); +} diff --git a/usr.sbin/amd/amd/clock.c b/usr.sbin/amd/amd/clock.c new file mode 100644 index 0000000..91e11ee --- /dev/null +++ b/usr.sbin/amd/amd/clock.c @@ -0,0 +1,241 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)clock.c 8.1 (Berkeley) 6/6/93 + * + * $Id: clock.c,v 5.2.2.1 1992/02/09 15:08:20 jsp beta $ + * + */ + +/* + * Callouts. + * + * Modelled on kernel object of the same name. + * See usual references. + * + * Use of a heap-based mechanism was rejected: + * 1. more complex implementation needed. + * 2. not obvious that a list is too slow for Amd. + */ + +#include "am.h" + +typedef struct callout callout; +struct callout { + callout *c_next; /* List of callouts */ + void (*c_fn)(); /* Function to call */ + voidp c_closure; /* Closure to pass to call */ + time_t c_time; /* Time of call */ + int c_id; /* Unique identifier */ +}; + +static callout callouts; /* List of pending callouts */ +static callout *free_callouts; /* Cache of free callouts */ +static int nfree_callouts; /* Number on free list */ +static int callout_id; /* Next free callout identifier */ +time_t next_softclock; /* Time of next call to softclock() */ + +/* + * Number of callout slots we keep on the free list + */ +#define CALLOUT_FREE_SLOP 10 + +/* + * Global assumption: valid id's are non-zero. + */ +#define CID_ALLOC() (++callout_id) +#define CID_UNDEF (0) + +static callout *alloc_callout(P_void); +static callout *alloc_callout() +{ + callout *cp = free_callouts; + if (cp) { + --nfree_callouts; + free_callouts = free_callouts->c_next; + return cp; + } + return ALLOC(callout); +} + +static void free_callout P((callout *cp)); +static void free_callout(cp) +callout *cp; +{ + if (nfree_callouts > CALLOUT_FREE_SLOP) { + free((voidp) cp); + } else { + cp->c_next = free_callouts; + free_callouts = cp; + nfree_callouts++; + } +} + +/* + * Schedule a callout. + * + * (*fn)(closure) will be called at clocktime() + secs + */ +int timeout P((unsigned int secs, void (*fn)(), voidp closure)); +int timeout(secs, fn, closure) +unsigned int secs; +void (*fn)(); +voidp closure; +{ + callout *cp, *cp2; + time_t t = clocktime() + secs; + + /* + * Allocate and fill in a new callout structure + */ + callout *cpnew = alloc_callout(); + cpnew->c_closure = closure; + cpnew->c_fn = fn; + cpnew->c_time = t; + cpnew->c_id = CID_ALLOC(); + + if (t < next_softclock) + next_softclock = t; + + /* + * Find the correct place in the list + */ + for (cp = &callouts; cp2 = cp->c_next; cp = cp2) + if (cp2->c_time >= t) + break; + + /* + * And link it in + */ + cp->c_next = cpnew; + cpnew->c_next = cp2; + + /* + * Return callout identifier + */ + return cpnew->c_id; +} + +/* + * De-schedule a callout + */ +void untimeout P((int id)); +void untimeout(id) +int id; +{ + callout *cp, *cp2; + for (cp = &callouts; cp2 = cp->c_next; cp = cp2) { + if (cp2->c_id == id) { + cp->c_next = cp2->c_next; + free_callout(cp2); + break; + } + } +} + +/* + * Reschedule after clock changed + */ +void reschedule_timeouts P((time_t now, time_t then)); +void reschedule_timeouts(now, then) +time_t now; +time_t then; +{ + callout *cp; + + for (cp = callouts.c_next; cp; cp = cp->c_next) { + if (cp->c_time >= now && cp->c_time <= then) { + plog(XLOG_WARNING, "job %d rescheduled to run immediately", cp->c_id); +#ifdef DEBUG + dlog("rescheduling job %d back %d seconds", + cp->c_id, cp->c_time - now); +#endif + next_softclock = cp->c_time = now; + } + } +} + +/* + * Clock handler + */ +int softclock(P_void); +int softclock() +{ + time_t now; + callout *cp; + + do { + if (task_notify_todo) + do_task_notify(); + + now = clocktime(); + + /* + * While there are more callouts waiting... + */ + while ((cp = callouts.c_next) && cp->c_time <= now) { + /* + * Extract first from list, save fn & closure and + * unlink callout from list and free. + * Finally call function. + * + * The free is done first because + * it is quite common that the + * function will call timeout() + * and try to allocate a callout + */ + void (*fn)() = cp->c_fn; + voidp closure = cp->c_closure; + + callouts.c_next = cp->c_next; + free_callout(cp); +#ifdef DEBUG + /*dlog("Calling %#x(%#x)", fn, closure);*/ +#endif /* DEBUG */ + (*fn)(closure); + } + + } while (task_notify_todo); + + /* + * Return number of seconds to next event, + * or 0 if there is no event. + */ + if (cp = callouts.c_next) + return cp->c_time - now; + return 0; +} diff --git a/usr.sbin/amd/amd/efs_ops.c b/usr.sbin/amd/amd/efs_ops.c new file mode 100644 index 0000000..6630277 --- /dev/null +++ b/usr.sbin/amd/amd/efs_ops.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)efs_ops.c 8.1 (Berkeley) 6/6/93 + * + * $Id: efs_ops.c,v 5.2.2.1 1992/02/09 15:08:21 jsp beta $ + * + */ + +#include "am.h" + +#ifdef HAS_EFS + +/* + * Error file system. + * This is used as a last resort catchall if + * nothing else worked. EFS just returns lots + * of error codes, except for unmount which + * always works of course. + */ + +/* + * EFS file system always matches + */ +static char *efs_match(fo) +am_opts *fo; +{ + return strdup("(error-hook)"); +} + +/*ARGSUSED*/ +static int efs_fmount(mf) +mntfs *mf; +{ + return ENOENT; +} + +/*ARGSUSED*/ +static int efs_fumount(mf) +mntfs *mf; +{ + /* + * Always succeed + */ + + return 0; +} + +/* + * EFS interface to RPC lookup() routine. + * Should never get here in the automounter. + * If we do then just give an error. + */ +/*ARGSUSED*/ +am_node *efs_lookuppn(mp, fname, error_return, op) +am_node *mp; +char *fname; +int *error_return; +int op; +{ + *error_return = ESTALE; + return 0; +} + +/* + * EFS interface to RPC readdir() routine. + * Should never get here in the automounter. + * If we do then just give an error. + */ +/*ARGSUSED*/ +int efs_readdir(mp, cookie, dp, ep, count) +am_node *mp; +nfscookie cookie; +dirlist *dp; +entry *ep; +int count; +{ + return ESTALE; +} + +/* + * Ops structure + */ +am_ops efs_ops = { + "error", + efs_match, + 0, /* efs_init */ + auto_fmount, + efs_fmount, + auto_fumount, + efs_fumount, + efs_lookuppn, + efs_readdir, + 0, /* efs_readlink */ + 0, /* efs_mounted */ + 0, /* efs_umounted */ + find_afs_srvr, + FS_DISCARD +}; + +#endif /* HAS_EFS */ diff --git a/usr.sbin/amd/amd/get_args.c b/usr.sbin/amd/amd/get_args.c new file mode 100644 index 0000000..0567d5d --- /dev/null +++ b/usr.sbin/amd/amd/get_args.c @@ -0,0 +1,336 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)get_args.c 8.1 (Berkeley) 6/6/93 + * + * $Id: get_args.c,v 5.2.2.1 1992/02/09 15:08:23 jsp beta $ + * + */ + +/* + * Argument decode + */ + +#include "am.h" +#ifdef HAS_SYSLOG +#include +#endif /* HAS_SYSLOG */ +#include + +extern int optind; +extern char *optarg; + +#if defined(DEBUG) && defined(PARANOID) +char **gargv; +#endif /* defined(DEBUG) && defined(PARANOID) */ +int restart_existing_mounts; +int print_pid; +int normalize_hosts; +char *karch; /* Kernel architecture */ +char *cluster; /* Cluster name */ +#ifdef HAS_NIS_MAPS +char *domain; /* YP domain */ +#endif /* HAS_NIS_MAPS */ +#ifdef UPDATE_MTAB +char *mtab; +#endif /* UPDATE_MTAB */ +int afs_timeo = -1; +int afs_retrans = -1; +int am_timeo = AM_TTL; +int am_timeo_w = AM_TTL_W; + +#ifdef DEBUG +/* + * List of debug options. + */ +static struct opt_tab dbg_opt[] = { + { "all", D_ALL }, /* All */ + { "amq", D_AMQ }, /* Register for AMQ program */ + { "daemon", D_DAEMON }, /* Enter daemon mode */ + { "full", D_FULL }, /* Program trace */ + { "mem", D_MEM }, /* Trace memory allocations */ + { "mtab", D_MTAB }, /* Use local mtab file */ + { "str", D_STR }, /* Debug string munging */ + { "test", D_TEST }, /* Full debug - but no daemon */ + { "trace", D_TRACE }, /* Protocol trace */ + { 0, 0 } +}; + +int debug_flags = D_AMQ /* Register AMQ */ + |D_DAEMON /* Enter daemon mode */ + ; + +/* + * Switch on/off debug options + */ +int debug_option(opt) +char *opt; +{ + return cmdoption(opt, dbg_opt, &debug_flags); +} +#endif /* DEBUG */ + +void get_args(c, v) +int c; +char *v[]; +{ + int opt_ch; + int usage = 0; + char *logfile = 0; + char *sub_domain = 0; + + while ((opt_ch = getopt(c, v, "mnprva:c:d:h:k:l:t:w:x:y:C:D:")) != EOF) + switch (opt_ch) { + case 'a': + if (*optarg != '/') { + fprintf(stderr, "%s: -a option must begin with a '/'\n", + progname); + exit(1); + } + auto_dir = optarg; + break; + + case 'c': + am_timeo = atoi(optarg); + if (am_timeo <= 0) + am_timeo = AM_TTL; + break; + + case 'd': + sub_domain = optarg; + break; + + case 'h': +#if defined(HAS_HOST) && defined(HOST_EXEC) + host_helper = optarg; +#else + plog(XLOG_USER, "-h: option ignored. HOST_EXEC is not enabled."); + break; +#endif /* defined(HAS_HOST) && defined(HOST_EXEC) */ + + case 'k': + karch = optarg; + break; + + case 'l': + logfile = optarg; + break; + + case 'm': + plog(XLOG_USER, "The -m option is no longer supported."); + plog(XLOG_USER, "... Use `ypcat -k am.master` on the command line instead"); + break; + + case 'n': + normalize_hosts = 1; + break; + + case 'p': + print_pid = 1; + break; + + case 'r': + restart_existing_mounts = 1; + break; + + case 't': + /* timeo.retrans */ + { char *dot = strchr(optarg, '.'); + if (dot) *dot = '\0'; + if (*optarg) { + afs_timeo = atoi(optarg); + } + if (dot) { + afs_retrans = atoi(dot+1); + *dot = '.'; + } + } + break; + + case 'v': + fprintf(stderr, "%s%s (%s-endian).\n", copyright, version, endian); + fputs("Map support for: ", stderr); + mapc_showtypes(stderr); + fputs(".\nFS: ", stderr); + ops_showfstypes(stderr); + fputs(".\n", stderr); + fprintf(stderr, "Primary network is %s.\n", wire); + exit(0); + break; + + case 'w': + am_timeo_w = atoi(optarg); + if (am_timeo_w <= 0) + am_timeo_w = AM_TTL_W; + break; + + case 'x': + usage += switch_option(optarg); + break; + + case 'y': +#ifdef HAS_NIS_MAPS + domain = optarg; +#else + plog(XLOG_USER, "-y: option ignored. No NIS support available."); +#endif /* HAS_NIS_MAPS */ + break; + + case 'C': + cluster = optarg; + break; + + case 'D': +#ifdef DEBUG + usage += debug_option(optarg); +#else + fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n", progname); +#endif /* DEBUG */ + break; + + default: + usage = 1; + break; + } + + if (xlog_level_init == ~0) { + (void) switch_option(""); +#ifdef DEBUG + usage += switch_option("debug"); +#endif /* DEBUG */ + } else { +#ifdef DEBUG + usage += switch_option("debug"); +#endif /* DEBUG */ + } + + if (usage) + goto show_usage; + + while (optind <= c-2) { + char *dir = v[optind++]; + char *map = v[optind++]; + char *opts = ""; + if (v[optind] && *v[optind] == '-') + opts = &v[optind++][1]; + + root_newmap(dir, opts, map); + } + + if (optind == c) { +#ifdef hpux + /* + * HP-UX can't handle ./mtab + * That system is sick - really. + */ +#ifdef DEBUG + debug_option("nomtab"); +#endif /* DEBUG */ +#endif /* hpux */ + + /* + * Append domain name to hostname. + * sub_domain overrides hostdomain + * if given. + */ + if (sub_domain) + hostdomain = sub_domain; + if (*hostdomain == '.') + hostdomain++; + strcat(hostd, "."); + strcat(hostd, hostdomain); + +#ifdef UPDATE_MTAB +#ifdef DEBUG + if (debug_flags & D_MTAB) + mtab = DEBUG_MTAB; + else +#endif /* DEBUG */ + mtab = MOUNTED; +#else +#ifdef DEBUG + { if (debug_flags & D_MTAB) { + dlog("-D mtab option ignored"); + } } +#endif /* DEBUG */ +#endif /* UPDATE_MTAB */ + + if (switch_to_logfile(logfile) != 0) + plog(XLOG_USER, "Cannot switch logfile"); + + /* + * If the kernel architecture was not specified + * then use the machine architecture. + */ + if (karch == 0) + karch = arch; + + if (cluster == 0) + cluster = hostdomain; + + if (afs_timeo <= 0) + afs_timeo = AFS_TIMEO; + if (afs_retrans <= 0) + afs_retrans = AFS_RETRANS; + if (afs_retrans <= 0) + afs_retrans = 3; /* XXX */ + return; + } + +show_usage: + fprintf(stderr, +"Usage: %s [-mnprv] [-a mnt_point] [-c cache_time] [-d domain]\n\ +\t[-k kernel_arch] [-l logfile|\"syslog\"] [-t afs_timeout]\n\ +\t[-w wait_timeout] [-C cluster_name]", progname); + +#if defined(HAS_HOST) && defined(HOST_EXEC) + fputs(" [-h host_helper]\n", stderr); +#endif /* defined(HAS_HOST) && defined(HOST_EXEC) */ + +#ifdef HAS_NIS_MAPS + fputs(" [-y nis-domain]\n", stderr); +#else + fputc('\n', stderr); +#endif /* HAS_NIS_MAPS */ + + show_opts('x', xlog_opt); +#ifdef DEBUG + show_opts('D', dbg_opt); +#endif /* DEBUG */ + fprintf(stderr, "\t{directory mapname [-map_options]} ...\n"); + exit(1); +} diff --git a/usr.sbin/amd/amd/host_ops.c b/usr.sbin/amd/amd/host_ops.c new file mode 100644 index 0000000..ba0dedb --- /dev/null +++ b/usr.sbin/amd/amd/host_ops.c @@ -0,0 +1,681 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)host_ops.c 8.1 (Berkeley) 6/6/93 + * + * $Id: host_ops.c,v 5.2.2.2 1992/05/31 16:36:08 jsp Exp $ + * + */ + +#include "am.h" + +#ifdef HAS_HOST + +#include "mount.h" +#include + +/* + * NFS host file system. + * Mounts all exported filesystems from a given host. + * This has now degenerated into a mess but will not + * be rewritten. Amd 6 will support the abstractions + * needed to make this work correctly. + */ + +/* + * Define HOST_RPC_UDP to use dgram instead of stream RPC. + * Datagrams are generally much faster. + */ +/*#define HOST_RPC_UDP*/ + +/* + * Define HOST_MKDIRS to make Amd automatically try + * to create the mount points. + */ +#define HOST_MKDIRS + +/* + * Determine the mount point + */ +#define MAKE_MNTPT(mntpt, ex, mf) { \ + if (strcmp((ex)->ex_dir, "/") == 0) \ + strcpy((mntpt), (mf)->mf_mount); \ + else \ + sprintf((mntpt), "%s%s", (mf)->mf_mount, (ex)->ex_dir); \ +} + +/* + * Execute needs the same as NFS plus a helper command + */ +static char *host_match P((am_opts *fo)); +static char *host_match(fo) +am_opts *fo; +{ +#ifdef HOST_EXEC + if (!host_helper) { + plog(XLOG_USER, "No host helper command given"); + return FALSE; + } +#endif /* HOST_EXEC */ + + /* + * Make sure rfs is specified to keep nfs_match happy... + */ + if (!fo->opt_rfs) + fo->opt_rfs = "/"; + + + return (*nfs_ops.fs_match)(fo); +} + +static int host_init(mf) +mntfs *mf; +{ + if (strchr(mf->mf_info, ':') == 0) + return ENOENT; + return 0; +} + +/* + * Two implementations: + * HOST_EXEC gets you the external version. The program specified with + * the -h option is called. The external program is not published... + * roll your own. + * + * Otherwise you get the native version. Faster but makes the program + * bigger. + */ + +#ifndef HOST_EXEC + +static bool_t +xdr_pri_free(xdr_args, args_ptr) +xdrproc_t xdr_args; +caddr_t args_ptr; +{ + XDR xdr; + xdr.x_op = XDR_FREE; + return ((*xdr_args)(&xdr, args_ptr)); +} + +static int do_mount P((fhstatus *fhp, char *dir, char *fs_name, char *opts, mntfs *mf)); +static int do_mount(fhp, dir, fs_name, opts, mf) +fhstatus *fhp; +char *dir; +char *fs_name; +char *opts; +mntfs *mf; +{ + struct stat stb; +#ifdef DEBUG + dlog("host: mounting fs %s on %s\n", fs_name, dir); +#endif /* DEBUG */ +#ifdef HOST_MKDIRS + (void) mkdirs(dir, 0555); +#endif /* HOST_MKDIRS */ + if (stat(dir, &stb) < 0 || (stb.st_mode & S_IFMT) != S_IFDIR) { + plog(XLOG_ERROR, "No mount point for %s - skipping", dir); + return ENOENT; + } + + return mount_nfs_fh(fhp, dir, fs_name, opts, mf); +} + +static int sortfun P((exports *a, exports *b)); +static int sortfun(a, b) +exports *a,*b; +{ + return strcmp((*a)->ex_dir, (*b)->ex_dir); +} + +/* + * Get filehandle + */ +static int fetch_fhandle P((CLIENT *client, char *dir, fhstatus *fhp)); +static int fetch_fhandle(client, dir, fhp) +CLIENT *client; +char *dir; +fhstatus *fhp; +{ + struct timeval tv; + enum clnt_stat clnt_stat; + + /* + * Pick a number, any number... + */ + tv.tv_sec = 20; + tv.tv_usec = 0; + +#ifdef DEBUG + dlog("Fetching fhandle for %s", dir); +#endif /* DEBUG */ + /* + * Call the mount daemon on the remote host to + * get the filehandle. + */ + clnt_stat = clnt_call(client, MOUNTPROC_MNT, xdr_dirpath, &dir, xdr_fhstatus, fhp, tv); + if (clnt_stat != RPC_SUCCESS) { + extern char *clnt_sperrno(); + char *msg = clnt_sperrno(clnt_stat); + plog(XLOG_ERROR, "mountd rpc failed: %s", msg); + return EIO; + } + /* + * Check status of filehandle + */ + if (fhp->fhs_status) { +#ifdef DEBUG + errno = fhp->fhs_status; + dlog("fhandle fetch failed: %m"); +#endif /* DEBUG */ + return fhp->fhs_status; + } + return 0; +} + +/* + * Scan mount table to see if something already mounted + */ +static int already_mounted P((mntlist *mlist, char*dir)); +static int already_mounted(mlist, dir) +mntlist *mlist; +char *dir; +{ + mntlist *ml; + + for (ml = mlist; ml; ml = ml->mnext) + if (strcmp(ml->mnt->mnt_dir, dir) == 0) + return 1; + return 0; +} + +/* + * Mount the export tree from a host + */ +static int host_fmount P((mntfs *mf)); +static int host_fmount(mf) +mntfs *mf; +{ + struct timeval tv2; + CLIENT *client; + enum clnt_stat clnt_stat; + int n_export; + int j, k; + exports exlist = 0, ex; + exports *ep = 0; + fhstatus *fp = 0; + char *host = mf->mf_server->fs_host; + int error = 0; + struct sockaddr_in sin; + int sock = RPC_ANYSOCK; + int ok = FALSE; + mntlist *mlist; + char fs_name[MAXPATHLEN], *rfs_dir; + char mntpt[MAXPATHLEN]; + struct timeval tv; + tv.tv_sec = 10; tv.tv_usec = 0; + + /* + * Read the mount list + */ + mlist = read_mtab(mf->mf_mount); + + /* + * Unlock the mount list + */ + unlock_mntlist(); + + /* + * Take a copy of the server address + */ + sin = *mf->mf_server->fs_ip; + + /* + * Zero out the port - make sure we recompute + */ + sin.sin_port = 0; + /* + * Make a client end-point. + * Try TCP first + */ + if ((client = clnttcp_create(&sin, MOUNTPROG, MOUNTVERS, &sock, 0, 0)) == NULL && + (client = clntudp_create(&sin, MOUNTPROG, MOUNTVERS, tv, &sock)) == NULL) { + plog(XLOG_ERROR, "Failed to make rpc connection to mountd on %s", host); + error = EIO; + goto out; + } + + if (!nfs_auth) { + error = make_nfs_auth(); + if (error) + goto out; + } + + client->cl_auth = nfs_auth; + +#ifdef DEBUG + dlog("Fetching export list from %s", host); +#endif /* DEBUG */ + + /* + * Fetch the export list + */ + tv2.tv_sec = 10; tv2.tv_usec = 0; + clnt_stat = clnt_call(client, MOUNTPROC_EXPORT, xdr_void, 0, xdr_exports, &exlist, tv2); + if (clnt_stat != RPC_SUCCESS) { + /*clnt_perror(client, "rpc");*/ + error = EIO; + goto out; + } + + /* + * Figure out how many exports were returned + */ + for (n_export = 0, ex = exlist; ex; ex = ex->ex_next) { + /*printf("export %s\n", ex->ex_dir);*/ + n_export++; + } +#ifdef DEBUG + /*dlog("%d exports returned\n", n_export);*/ +#endif /* DEBUG */ + + /* + * Allocate an array of pointers into the list + * so that they can be sorted. If the filesystem + * is already mounted then ignore it. + */ + ep = (exports *) xmalloc(n_export * sizeof(exports)); + for (j = 0, ex = exlist; ex; ex = ex->ex_next) { + MAKE_MNTPT(mntpt, ex, mf); + if (!already_mounted(mlist, mntpt)) + ep[j++] = ex; + } + n_export = j; + + /* + * Sort into order. + * This way the mounts are done in order down the tree, + * instead of any random order returned by the mount + * daemon (the protocol doesn't specify...). + */ + qsort(ep, n_export, sizeof(exports), sortfun); + + /* + * Allocate an array of filehandles + */ + fp = (fhstatus *) xmalloc(n_export * sizeof(fhstatus)); + + /* + * Try to obtain filehandles for each directory. + * If a fetch fails then just zero out the array + * reference but discard the error. + */ + for (j = k = 0; j < n_export; j++) { + /* Check and avoid a duplicated export entry */ + if (j > k && ep[k] && strcmp(ep[j]->ex_dir, ep[k]->ex_dir) == 0) { +#ifdef DEBUG + dlog("avoiding dup fhandle requested for %s", ep[j]->ex_dir); +#endif + ep[j] = 0; + } else { + k = j; + if (error = fetch_fhandle(client, ep[j]->ex_dir, &fp[j])) + ep[j] = 0; + } + } + + /* + * Mount each filesystem for which we have a filehandle. + * If any of the mounts succeed then mark "ok" and return + * error code 0 at the end. If they all fail then return + * the last error code. + */ + strncpy(fs_name, mf->mf_info, sizeof(fs_name)); + if ((rfs_dir = strchr(fs_name, ':')) == (char *) 0) { + plog(XLOG_FATAL, "host_fmount: mf_info has no colon"); + error = EINVAL; + goto out; + } + ++rfs_dir; + for (j = 0; j < n_export; j++) { + ex = ep[j]; + if (ex) { + strcpy(rfs_dir, ex->ex_dir); + MAKE_MNTPT(mntpt, ex, mf); + if (do_mount(&fp[j], mntpt, fs_name, mf->mf_mopts, mf) == 0) + ok = TRUE; + } + } + + /* + * Clean up and exit + */ +out: + discard_mntlist(mlist); + if (ep) + free(ep); + if (fp) + free(fp); + if (client) + clnt_destroy(client); + if (exlist) + xdr_pri_free(xdr_exports, &exlist); + if (ok) + return 0; + return error; +} + +/* + * Return true if pref is a directory prefix of dir. + * + * TODO: + * Does not work if pref is "/". + */ +static int directory_prefix P((char *pref, char *dir)); +static int directory_prefix(pref, dir) +char *pref; +char *dir; +{ + int len = strlen(pref); + if (strncmp(pref, dir, len) != 0) + return FALSE; + if (dir[len] == '/' || dir[len] == '\0') + return TRUE; + return FALSE; +} + +/* + * Unmount a mount tree + */ +static int host_fumount P((mntfs *mf)); +static int host_fumount(mf) +mntfs *mf; +{ + mntlist *ml, *mprev; + int xerror = 0; + + /* + * Read the mount list + */ + mntlist *mlist = read_mtab(mf->mf_mount); + + /* + * Unlock the mount list + */ + unlock_mntlist(); + + /* + * Reverse list... + */ + ml = mlist; + mprev = 0; + while (ml) { + mntlist *ml2 = ml->mnext; + ml->mnext = mprev; + mprev = ml; + ml = ml2; + } + mlist = mprev; + + /* + * Unmount all filesystems... + */ + for (ml = mlist; ml && !xerror; ml = ml->mnext) { + char *dir = ml->mnt->mnt_dir; + if (directory_prefix(mf->mf_mount, dir)) { + int error; +#ifdef DEBUG + dlog("host: unmounts %s", dir); +#endif /* DEBUG */ + /* + * Unmount "dir" + */ + error = UMOUNT_FS(dir); + /* + * Keep track of errors + */ + if (error) { + if (!xerror) + xerror = error; + if (error != EBUSY) { + errno = error; + plog("Tree unmount of %s failed: %m", ml->mnt->mnt_dir); + } + } else { +#ifdef HOST_MKDIRS + (void) rmdirs(dir); +#endif /* HOST_MKDIRS */ + } + } + } + + /* + * Throw away mount list + */ + discard_mntlist(mlist); + + /* + * Try to remount, except when we are shutting down. + */ + if (xerror && amd_state != Finishing) { + xerror = host_fmount(mf); + if (!xerror) { + /* + * Don't log this - it's usually too verbose + plog(XLOG_INFO, "Remounted host %s", mf->mf_info); + */ + xerror = EBUSY; + } + } + return xerror; +} + +/* + * Tell mountd we're done. + * This is not quite right, because we may still + * have other filesystems mounted, but the existing + * mountd protocol is badly broken anyway. + */ +static void host_umounted(mp) +am_node *mp; +{ +#ifdef INFORM_MOUNTD + mntfs *mf = mp->am_mnt; + char *host; + CLIENT *client; + enum clnt_stat clnt_stat; + struct sockaddr_in sin; + int sock = RPC_ANYSOCK; + struct timeval tv; + tv.tv_sec = 10; tv.tv_usec = 0; + + if (mf->mf_error || mf->mf_refc > 1 || ! mf->mf_server) + return; + + host = mf->mf_server->fs_host; + sin = *mf->mf_server->fs_ip; + + /* + * Zero out the port - make sure we recompute + */ + sin.sin_port = 0; + /* + * Make a client end-point. + * Try TCP first + */ + if ((client = clnttcp_create(&sin, MOUNTPROG, MOUNTVERS, &sock, 0, 0)) == NULL && + (client = clntudp_create(&sin, MOUNTPROG, MOUNTVERS, tv, &sock)) == NULL) { + plog(XLOG_ERROR, "Failed to make rpc connection to mountd on %s", host); + goto out; + } + + if (!nfs_auth) { + if (make_nfs_auth()) + goto out; + } + + client->cl_auth = nfs_auth; + +#ifdef DEBUG + dlog("Unmounting all from %s", host); +#endif /* DEBUG */ + + clnt_stat = clnt_call(client, MOUNTPROC_UMNTALL, xdr_void, 0, xdr_void, 0, tv); + if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_SYSTEMERROR) { + /* RPC_SYSTEMERROR seems to be returned for no good reason ...*/ + extern char *clnt_sperrno(); + char *msg = clnt_sperrno(clnt_stat); + plog(XLOG_ERROR, "unmount all from %s rpc failed: %s", host, msg, clnt_stat); + goto out; + } + +out: + if (client) + clnt_destroy(client); + +#endif /* INFORM_MOUNTD */ +} + + +#else /* HOST_EXEC */ + +static int host_exec P((char*op, char*host, char*fs, char*opts)); +static int host_exec(op, host, fs, opts) +char *op; +char *host; +char *fs; +char *opts; +{ + int error; + char *argv[7]; + + /* + * Build arg vector + */ + argv[0] = host_helper; + argv[1] = host_helper; + argv[2] = op; + argv[3] = host; + argv[4] = fs; + argv[5] = opts && *opts ? opts : "rw,default"; + argv[6] = 0; + + /* + * Put stdout to stderr + */ + (void) fclose(stdout); + (void) dup(fileno(logfp)); + if (fileno(logfp) != fileno(stderr)) { + (void) fclose(stderr); + (void) dup(fileno(logfp)); + } + /* + * Try the exec + */ +#ifdef DEBUG + Debug(D_FULL) { + char **cp = argv; + plog(XLOG_DEBUG, "executing (un)mount command..."); + while (*cp) { + plog(XLOG_DEBUG, "arg[%d] = '%s'", cp-argv, *cp); + cp++; + } + } +#endif /* DEBUG */ + if (argv[0] == 0 || argv[1] == 0) { + errno = EINVAL; + plog(XLOG_USER, "1st/2nd args missing to (un)mount program"); + } else { + (void) execv(argv[0], argv+1); + } + /* + * Save error number + */ + error = errno; + plog(XLOG_ERROR, "exec %s failed: %m", argv[0]); + + /* + * Return error + */ + return error; +} + +static int host_mount P((am_node *mp)); +static int host_mount(mp) +am_node *mp; +{ + mntfs *mf = mp->am_mnt; + + return host_exec("mount", mf->mf_server->fs_host, mf->mf_mount, mf->mf_opts); +} + +static int host_umount P((am_node *mp)); +static int host_umount(mp) +am_node *mp; +{ + mntfs *mf = mp->am_mnt; + + return host_exec("unmount", mf->mf_server->fs_host, mf->mf_mount, "xxx"); +} + +#endif /* HOST_EXEC */ + +/* + * Ops structure + */ +am_ops host_ops = { + "host", + host_match, + host_init, + auto_fmount, + host_fmount, + auto_fumount, + host_fumount, + efs_lookuppn, + efs_readdir, + 0, /* host_readlink */ + 0, /* host_mounted */ +#ifdef HOST_EXEC + 0, /* host_umounted */ +#else + host_umounted, +#endif + find_nfs_srvr, + FS_MKMNT|FS_BACKGROUND|FS_AMQINFO +}; + +#endif /* HAS_HOST */ diff --git a/usr.sbin/amd/amd/ifs_ops.c b/usr.sbin/amd/amd/ifs_ops.c new file mode 100644 index 0000000..14df832 --- /dev/null +++ b/usr.sbin/amd/amd/ifs_ops.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)ifs_ops.c 8.1 (Berkeley) 6/6/93 + * + * $Id: ifs_ops.c,v 5.2.2.1 1992/02/09 15:08:26 jsp beta $ + * + */ + +#include "am.h" + +#ifdef HAS_IFS + +/* + * Inheritance file system. + * This implements a filesystem restart. + * + * This is a *gross* hack - it knows far too + * much about the way other parts of the + * sytem work. See restart.c too. + */ +static char not_a_filesystem[] = "Attempting to inherit not-a-filesystem"; +/* + * This should never be called. + */ +/*ARGSUSED*/ +static char *ifs_match P((am_opts *fo)); +static char *ifs_match(fo) +am_opts *fo; +{ + plog(XLOG_FATAL, "ifs_match called!"); + return 0; +} + +static int ifs_init P((mntfs *mf)); +static int ifs_init(mf) +mntfs *mf; +{ + mntfs *mf_link = (mntfs *) mf->mf_private; + if (mf_link == 0) { + plog(XLOG_FATAL, not_a_filesystem); + return EINVAL; + } +#ifdef notdef + /* + * Fill in attribute fields + */ + mf_link->mf_fattr.type = NFLNK; + mf_link->mf_fattr.mode = NFSMODE_LNK | 0777; + mf_link->mf_fattr.nlink = 1; + mf_link->mf_fattr.size = MAXPATHLEN / 4; +#endif + if (mf_link->mf_ops->fs_init) + return (*mf_link->mf_ops->fs_init)(mf_link); + return 0; +} + +static mntfs *ifs_inherit P((mntfs *mf)); +static mntfs *ifs_inherit(mf) +mntfs *mf; +{ + /* + * Take the linked mount point and + * propogate. + */ + mntfs *mf_link = (mntfs *) mf->mf_private; + if (mf_link == 0) { + plog(XLOG_FATAL, not_a_filesystem); + return 0; /*XXX*/ + } + + mf_link->mf_fo = mf->mf_fo; +#ifdef notdef + mf_link->mf_fattr.fileid = mf->mf_fattr.fileid; +#endif /* notdef */ + + /* + * Discard the old map. + * Don't call am_unmounted since this + * node was never really mounted in the + * first place. + */ + mf->mf_private = 0; + free_mntfs(mf); + /* + * Free the dangling reference + * to the mount link. + */ + free_mntfs(mf_link); + /* + * Get a hold of the other entry + */ + mf_link->mf_flags &= ~MFF_RESTART; + + /* Say what happened */ + plog(XLOG_INFO, "restarting %s on %s", mf_link->mf_info, mf_link->mf_mount); + + return mf_link; +} + +static int ifs_mount P((am_node *mp)); +static int ifs_mount(mp) +am_node *mp; +{ + mntfs *newmf = ifs_inherit(mp->am_mnt); + if (newmf) { + mp->am_mnt = newmf; + /* + * XXX - must do the am_mounted call here + */ + if (newmf->mf_ops->fs_flags & FS_MBACKGROUND) + am_mounted(mp); + + new_ttl(mp); + return 0; + } + return EINVAL; +} + +static int ifs_fmount P((mntfs *mf)); +static int ifs_fmount(mf) +mntfs *mf; +{ + am_node *mp = find_mf(mf); + if (mp) + return ifs_mount(mp); + return ifs_inherit(mf) ? 0 : EINVAL; +} + +/*ARGSUSED*/ +static int ifs_fumount P((mntfs *mf)); +static int ifs_fumount(mf) +mntfs *mf; +{ + /* + * Always succeed + */ + return 0; +} + +/* + * Ops structure + */ +am_ops ifs_ops = { + "inherit", + ifs_match, + ifs_init, + ifs_mount, + ifs_fmount, + auto_fumount, + ifs_fumount, + efs_lookuppn, + efs_readdir, + 0, /* ifs_readlink */ + 0, /* ifs_mounted */ + 0, /* ifs_umounted */ + find_afs_srvr, + FS_DISCARD +}; + +#endif /* HAS_IFS */ diff --git a/usr.sbin/amd/amd/info_file.c b/usr.sbin/amd/amd/info_file.c new file mode 100644 index 0000000..c43b2a7 --- /dev/null +++ b/usr.sbin/amd/amd/info_file.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)info_file.c 8.1 (Berkeley) 6/6/93 + * + * $Id: info_file.c,v 5.2.2.1 1992/02/09 15:08:28 jsp beta $ + * + */ + +/* + * Get info from file + */ + +#include "am.h" + +#ifdef HAS_FILE_MAPS +#include +#include + +#define MAX_LINE_LEN 2048 + +static int read_line P((char *buf, int size, FILE *fp)); +static int read_line(buf, size, fp) +char *buf; +int size; +FILE *fp; +{ + int done = 0; + + do { + while (fgets(buf, size, fp)) { + int len = strlen(buf); + done += len; + if (len > 1 && buf[len-2] == '\\' && + buf[len-1] == '\n') { + int ch; + buf += len - 2; + size -= len - 2; + *buf = '\n'; buf[1] = '\0'; + /* + * Skip leading white space on next line + */ + while ((ch = getc(fp)) != EOF && + isascii(ch) && isspace(ch)) + ; + (void) ungetc(ch, fp); + } else { + return done; + } + } + } while (size > 0 && !feof(fp)); + + return done; +} + +/* + * Try to locate a key in a file + */ +static int search_or_reload_file P((FILE *fp, char *map, char *key, char **val, mnt_map *m, void (*fn)(mnt_map *m, char*, char*))); +static int search_or_reload_file(fp, map, key, val, m, fn) +FILE *fp; +char *map; +char *key; +char **val; +mnt_map *m; +void (*fn) P((mnt_map*, char*, char*)); +{ + char key_val[MAX_LINE_LEN]; + int chuck = 0; + int line_no = 0; + + while (read_line(key_val, sizeof(key_val), fp)) { + char *kp; + char *cp; + char *hash; + int len = strlen(key_val); + line_no++; + + /* + * Make sure we got the whole line + */ + if (key_val[len-1] != '\n') { + plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map); + chuck = 1; + } else { + key_val[len-1] = '\0'; + } + + /* + * Strip comments + */ + hash = strchr(key_val, '#'); + if (hash) + *hash = '\0'; + + /* + * Find start of key + */ + for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++) + ; + + /* + * Ignore blank lines + */ + if (!*kp) + goto again; + + /* + * Find end of key + */ + for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++) + ; + + /* + * Check whether key matches + */ + if (*cp) + *cp++ = '\0'; + + if (fn || (*key == *kp && strcmp(key, kp) == 0)) { + while (*cp && isascii(*cp) && isspace(*cp)) + cp++; + if (*cp) { + /* + * Return a copy of the data + */ + char *dc = strdup(cp); + if (fn) { + (*fn)(m, strdup(kp), dc); + } else { + *val = dc; +#ifdef DEBUG + dlog("%s returns %s", key, dc); +#endif /* DEBUG */ + } + if (!fn) + return 0; + } else { + plog(XLOG_USER, "%s: line %d has no value field", map, line_no); + } + } + +again: + /* + * If the last read didn't get a whole line then + * throw away the remainder before continuing... + */ + if (chuck) { + while (fgets(key_val, sizeof(key_val), fp) && + !strchr(key_val, '\n')) + ; + chuck = 0; + } + } + + return fn ? 0 : ENOENT; +} + +static FILE *file_open P((char *map, time_t *tp)); +static FILE *file_open(map, tp) +char *map; +time_t *tp; +{ + FILE *mapf = fopen(map, "r"); + if (mapf && tp) { + struct stat stb; + if (fstat(fileno(mapf), &stb) < 0) + *tp = clocktime(); + else + *tp = stb.st_mtime; + } + return mapf; +} + +int file_init P((char *map, time_t *tp)); +int file_init(map, tp) +char *map; +time_t *tp; +{ + FILE *mapf = file_open(map, tp); + if (mapf) { + (void) fclose(mapf); + return 0; + } + return errno; +} + +int file_reload P((mnt_map *m, char *map, void (*fn)())); +int file_reload(m, map, fn) +mnt_map *m; +char *map; +void (*fn)(); +{ + FILE *mapf = file_open(map, (time_t *) 0); + if (mapf) { + int error = search_or_reload_file(mapf, map, 0, 0, m, fn); + (void) fclose(mapf); + return error; + } + + return errno; +} + +int file_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp)); +int file_search(m, map, key, pval, tp) +mnt_map *m; +char *map; +char *key; +char **pval; +time_t *tp; +{ + time_t t; + FILE *mapf = file_open(map, &t); + if (mapf) { + int error; + if (*tp < t) { + *tp = t; + error = -1; + } else { + error = search_or_reload_file(mapf, map, key, pval, 0, 0); + } + (void) fclose(mapf); + return error; + } + + return errno; +} + +int file_mtime P((char *map, time_t *tp)); +int file_mtime(map, tp) +char *map; +time_t *tp; +{ + FILE *mapf = file_open(map, tp); + if (mapf) { + (void) fclose(mapf); + return 0; + } + + return errno; +} +#endif /* HAS_FILE_MAPS */ diff --git a/usr.sbin/amd/amd/info_hes.c b/usr.sbin/amd/amd/info_hes.c new file mode 100644 index 0000000..875cfe7 --- /dev/null +++ b/usr.sbin/amd/amd/info_hes.c @@ -0,0 +1,697 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)info_hes.c 8.1 (Berkeley) 6/6/93 + * + * $Id: info_hes.c,v 5.2.2.1 1992/02/09 15:08:29 jsp beta $ + * + */ + +/* + * Get info from Hesiod + * + * Zone transfer code from Bruce Cole + */ + +#include "am.h" + +#ifdef HAS_HESIOD_MAPS +#include + +#define HES_PREFIX "hesiod." +#define HES_PREFLEN 7 + +#ifdef HAS_HESIOD_RELOAD +#include +#include +#include +#include + +/* + * Patch up broken system include files + */ +#ifndef C_HS +#define C_HS 4 +#endif +#ifndef T_TXT +#define T_TXT 16 +#endif + +static int soacnt; +static struct timeval hs_timeout; +static int servernum; +#endif /* HAS_HESIOD_RELOAD */ + +/* + * No easy way to probe the server - check the map name begins with "hesiod." + */ +int hesiod_init P((char *map, time_t *tp)); +int hesiod_init(map, tp) +char *map; +time_t *tp; +{ +#ifdef DEBUG + dlog("hesiod_init(%s)", map); +#endif + *tp = 0; + return strncmp(map, HES_PREFIX, HES_PREFLEN) == 0 ? 0 : ENOENT; +} + + +/* + * Make Hesiod name. Skip past the "hesiod." + * at the start of the map name and append + * ".automount". The net effect is that a lookup + * of /defaults in hesiod.home will result in a + * call to hes_resolve("/defaults", "home.automount"); + */ +#ifdef notdef +#define MAKE_HES_NAME(dest, src) sprintf(dest, "%s%s", src + HES_PREFLEN, ".automount") +#endif + +/* + * Do a Hesiod nameserver call. + * Modify time is ignored by Hesiod - XXX + */ +int hesiod_search P((mnt_map *m, char *map, char **pval, time_t *tp)); +int hesiod_search(m, map, key, pval, tp) +mnt_map *m; +char *map; +char *key; +char **pval; +time_t *tp; +{ + int error; + char hes_key[MAXPATHLEN]; + char **rvec; +#ifdef DEBUG + dlog("hesiod_search(m=%x, map=%s, key=%s, pval=%x tp=%x)", m, map, key, pval, tp); +#endif + /*MAKE_HES_NAME(hes_map, map);*/ + sprintf(hes_key, "%s.%s", key, map+HES_PREFLEN); + + /* + * Call the resolver + */ +#ifdef DEBUG + dlog("hesiod_search: hes_resolve(%s, %s)", hes_key, "automount"); +#ifdef HAS_HESIOD_RELOAD + if (debug_flags & D_FULL) + _res.options |= RES_DEBUG; +#endif +#endif + rvec = hes_resolve(hes_key, "automount"); + /* + * If a reply was forthcoming then return + * it (and free subsequent replies) + */ + if (rvec && *rvec) { + *pval = *rvec; + while (*++rvec) + free(*rvec); + return 0; + } + + /* + * Otherwise reflect the hesiod error into a Un*x error + */ +#ifdef DEBUG + dlog("hesiod_search: Error: %d", hes_error()); +#endif + switch (hes_error()) { + case HES_ER_NOTFOUND: error = ENOENT; break; + case HES_ER_CONFIG: error = EIO; break; + case HES_ER_NET: error = ETIMEDOUT; break; + default: error = EINVAL; break; + } +#ifdef DEBUG + dlog("hesiod_search: Returning: %d", error); +#endif + return error; +} + +#ifdef HAS_HESIOD_RELOAD +/* + * Zone transfer... + */ + +#define MAXHSNS 8 +#define MAX_NSADDR 16 + +static char *hs_domain; +static mnt_map *hs_map; +static int hs_nscount; +static char nsaddr_list[MAX_NSADDR][sizeof(struct in_addr)]; + +int hesiod_reload P((mnt_map *m, char *map, void (*fn)())); +int hesiod_reload(m, map, fn) +mnt_map *m; +char *map; +void (*fn)(); +{ + char *zone_name, *cp; + short domainlen; + int status; + +#ifdef DEBUG + dlog("hesiod_reload (%x %s %x)", m, map, fn); +#endif DEBUG + if (status = res_init()) { +#ifdef DEBUG + dlog("hesiod_reload: res_init failed with %d", status); +#endif + return(status); + } + _res.retrans = 90; + hs_map = m; + domainlen = strlen(hostdomain); + zone_name = hes_to_bind(map+HES_PREFLEN, "automount"); + if (*zone_name == '.') + zone_name++; + hs_domain = zone_name; + /* Traverse the DNS tree until we find an SOA we can transfer from. + (Our initial zone_name is likely to just be a subtree of a + real zone). */ + do { + /* If we can't find any NS records, go up a level in the + DNS tree */ + if (hs_get_ns_list(zone_name) == 0 && + hs_zone_transfer(zone_name) == 0) + return(0); + /* Move up DNS tree by one component */ + if (cp = strchr(zone_name, '.')) + zone_name = ++cp; + else + break; + } while (strlen(zone_name) >= domainlen); +#ifdef DEBUG + dlog("hesiod_reload: Giving up on %s", hs_domain); +#endif + return(-1); +} + +hs_zone_transfer(domain) +char *domain; +{ + int status, len; + char buf[PACKETSZ]; + /* Want to make sure ansbuf is well alligned */ + long ansbuf[PACKETSZ/sizeof(long)]; + +#ifdef DEBUG + dlog("hs_zone_transfer (%s)", domain); +#endif + if ((len = res_mkquery(QUERY, domain, C_HS, T_AXFR, + (char *)NULL, 0, NULL, buf, PACKETSZ)) == -1) { +#ifdef DEBUG + dlog("hs_zone_transfer: res_mkquery failed"); +#endif + errno = 0; + return(-1); + } + if ((status = hs_res_send(buf, len, (char *)ansbuf, PACKETSZ)) == -1) { +#ifdef DEBUG + dlog("hs_zone_transfer: hs_res_send failed. status %d errno %d", + status, errno); +#endif + errno = 0; + return(-1); + } + return(0); +} + +#define hs_server_addr(ns) ((struct in_addr *) nsaddr_list[ns]) + +hs_res_send(buf, buflen, answer, anslen) +char *buf; +int buflen; +char *answer; +int anslen; +{ + int retry, ns; + u_short id, len; + HEADER *hp = (HEADER *) buf; + struct iovec iov[2]; + static int s = -1; + int status; + struct sockaddr_in server; + + soacnt = 0; + id = hp->id; + /* + * Send request, RETRY times, or until successful + */ + for (retry = _res.retry; retry > 0; retry--) { + for (ns = 0; ns < hs_nscount; ns++) { + hs_timeout.tv_sec = + (_res.retrans << (_res.retry - retry)) + / hs_nscount; + if (hs_timeout.tv_sec <= 0) + hs_timeout.tv_sec = 1; + hs_timeout.tv_usec = 0; + if (s < 0) { + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) { + continue; + } + servernum = ns; + bcopy(hs_server_addr(ns), &server.sin_addr, + sizeof(struct in_addr)); + server.sin_family = AF_INET; + server.sin_port = htons(NAMESERVER_PORT); + + if (connect(s, &server, + sizeof(struct sockaddr)) < 0) { + (void) close(s); + s = -1; + continue; + } + } + /* + * Send length & message + */ + len = htons((u_short)buflen); + iov[0].iov_base = (caddr_t)&len; + iov[0].iov_len = sizeof(len); + iov[1].iov_base = buf; + iov[1].iov_len = buflen; + if (writev(s, iov, 2) != sizeof(len) + buflen) { + (void) close(s); + s = -1; + continue; + } + status = 0; + while (s != -1 && soacnt < 2 && status != -2) { + if ((status = + hs_readresp(s, answer, anslen)) == -1) { + (void) close(s); + s = -1; + continue; + } + } + if (status == -2) { + /* There was a permanent error transfering this + zone. Give up. */ + if (s != -1) { + (void) close(s); + s = -1; + } + return(-1); + } + if (s == -1) + continue; + return (0); + } + } + if (errno == 0) + errno = ETIMEDOUT; + return (-1); +} + +/* Returns: + 0: Success + -1: Error + -2: Permanent failure +*/ +hs_readresp(s, answer, anslen) +int s; +char *answer; +int anslen; +{ + register int len, n; + char *cp; + + cp = answer; + len = sizeof(short); + while (len != 0 && + (n = hs_res_vcread(s, (char *)cp, (int)len, &hs_timeout)) > 0) { + cp += n; + len -= n; + } + if (n <= 0) + return(-1); + cp = answer; + if ((len = _getshort(cp)) > anslen) { +#ifdef DEBUG + dlog("hs_readresp: response too long: %d", len); +#endif + return(-1); + } + while (len != 0 && + (n = hs_res_vcread(s, (char *)cp, (int)len, &hs_timeout)) > 0) { + cp += n; + len -= n; + } + if (n <= 0) + return(-1); + return(hs_parse(answer, answer+PACKETSZ)); +} + +hs_res_vcread(sock, buf, buflen, timeout) +int sock, buflen; +char *buf; +struct timeval *timeout; +{ + register int n; + + if ((n = hs_res_selwait(sock, timeout)) > 0) + return(read(sock, buf, buflen)); + else + return(n); +} + +hs_res_selwait(sock, timeout) +int sock; +struct timeval *timeout; +{ + fd_set dsmask; + register int n; + + /* + * Wait for reply + */ + FD_ZERO(&dsmask); + FD_SET(sock, &dsmask); + n = select(sock+1, &dsmask, (fd_set *)NULL, + (fd_set *)NULL, timeout); + return(n); +} + +/* Returns: + 0: Success + -1: Error + -2: Permanent failure +*/ +hs_parse(msg, eom) +char *msg, *eom; +{ + register char *cp; + register HEADER *hp; + register int n, len; + int qdcount, ancount; + char key[PACKETSZ]; + char *key_cpy, *value, *hs_make_value(); + short type; + + hp = (HEADER *)msg; + if (hp->rcode != NOERROR || hp->opcode != QUERY) { + char dq[20]; +#ifdef DEBUG + dlog("Bad response (%d) from nameserver %s", hp->rcode, inet_dquad(dq, hs_server_addr(servernum)->s_addr)); +#endif DEBUG + return(-1); + } + cp = msg + sizeof(HEADER); + ancount = ntohs(hp->ancount); + qdcount = ntohs(hp->qdcount); + while (qdcount-- > 0) + cp += dn_skipname(cp, eom) + QFIXEDSZ; + if (soacnt == 0 && ancount == 0) { + /* XXX We should look for NS records to find SOA */ +#ifdef DEBUG + dlog("No SOA found"); +#endif + return(-2); + } + while (ancount-- > 0 && cp < eom) { + if ((n = dn_expand(msg, eom, cp, key, PACKETSZ)) < 0) + break; + cp += n; + if ((type = _getshort(cp)) == T_SOA) { + soacnt++; + } + cp += 2*sizeof(u_short) + sizeof(u_long); + len = _getshort(cp); + cp += sizeof(u_short); + /* Check to see if key is in our domain */ + if (type == T_TXT && hs_strip_our_domain(key)) { + value = hs_make_value(cp, len); + if (value == NULL) + return(-1); + key_cpy = strdup(key); +#ifdef DEBUG + dlog("hs_parse: Parsed key: %s, value: %s", key, + value); +#endif + mapc_add_kv(hs_map, key_cpy, value); + } + cp += len; + errno = 0; + } + return(0); +} + +/* Check to see if the domain name in the supplied argument matches + hs_domain. Strip hs_domain from supplied argument if so. */ +hs_strip_our_domain(name) +char *name; +{ + char *end_pos; + short targ_len, cur_len; + + targ_len = strlen(hs_domain); + cur_len = strlen(name); + if (cur_len <= targ_len) + return(0); + end_pos = &name[cur_len - targ_len]; + if (strcmp(end_pos, hs_domain) != 0) + return(0); + if (*--end_pos != '.') + return(0); + *end_pos = '\0'; + return(1); +} + +#define MAXDATA 8*1024 + +char * +hs_make_value(cp, len) +char *cp; +int len; +{ + char *value, *cpcpy, *valuep; + int cnt, nextcnt, totalcnt, lencpy; +#ifdef DEBUG + char *dbgname; + + dbgname = &cp[1]; +#endif DEBUG + + lencpy = len; + cpcpy = cp; + totalcnt = 0; + cnt = *cpcpy++; + while (cnt) { + totalcnt += cnt; + lencpy -= cnt+1; + if (lencpy == 0) + break; + nextcnt = cpcpy[cnt]; + cpcpy = &cpcpy[cnt+1]; + cnt = nextcnt; + } + if (totalcnt < 1 || totalcnt > MAXDATA || totalcnt > len) { +#ifdef DEBUG + dlog("TXT RR not of expected length (%d %d): %s", totalcnt, + len, dbgname); +#endif DEBUG + return(NULL); + } + /* Allocate null terminated string */ + value = (char *) xmalloc(totalcnt+1); + value[totalcnt] = '\0'; + cnt = *cp++; + valuep = value; + while (cnt) { + bcopy(cp, valuep, cnt); + len -= cnt+1; + if (len == 0) + break; + valuep = &valuep[cnt]; + nextcnt = cp[cnt]; + cp = &cp[cnt+1]; + cnt = nextcnt; + } + return(value); +} + +hs_make_ns_query(domain, ansbuf) +char *domain; +char *ansbuf; +{ + int status, len; + char buf[PACKETSZ]; + + if ((len = res_mkquery(QUERY, domain, C_HS, T_NS, + (char *)NULL, 0, NULL, buf, PACKETSZ)) == -1) { +#ifdef DEBUG + dlog("hs_get_ns_list: res_mkquery failed"); +#endif + errno = 0; + return(-1); + } + if ((status = res_send(buf, len, (char *)ansbuf, PACKETSZ)) == -1) { +#ifdef DEBUG + dlog("hs_get_ns_list: res_send failed. status %d errno %d", + status, errno); +#endif + errno = 0; + return(-1); + } + return(0); +} + +static void +add_address(addr) +struct in_addr *addr; +{ + char dq[20]; + bcopy((char *)addr, nsaddr_list[hs_nscount++], sizeof(struct in_addr)); +#ifdef DEBUG + dlog("Adding NS address %s", inet_dquad(dq, addr->s_addr)); +#endif DEBUG +} + +hs_get_ns_list(domain) +char *domain; +{ + register HEADER *hp; + int qdcount, nscount; + register char *cp; + register int n, len; + char key[PACKETSZ], name[PACKETSZ], msg[PACKETSZ], *eom; + register long **hptr; + struct hostent *ghp; + int numns; + char nsname[MAXHSNS][MAXDATA]; + int nshaveaddr[MAXHSNS], i; + short type; + + if (hs_make_ns_query(domain, msg) == -1) + return(-1); + numns = hs_nscount = 0; + eom = &msg[PACKETSZ]; + bzero(nsname, sizeof(nsname)); + hp = (HEADER *)msg; + if (hp->rcode != NOERROR || hp->opcode != QUERY) { +#ifdef DEBUG + dlog("Bad response (%d) from nameserver %#x", hp->rcode, + hs_server_addr(servernum)->s_addr); +#endif DEBUG + return(-1); + } + cp = msg + sizeof(HEADER); + qdcount = ntohs(hp->qdcount); + while (qdcount-- > 0) + cp += dn_skipname(cp, eom) + QFIXEDSZ; + nscount = ntohs(hp->ancount) + ntohs(hp->nscount) + ntohs(hp->arcount); +#ifdef DEBUG + dlog("hs_get_ns_list: Processing %d response records", nscount); +#endif + for (;nscount; nscount--) { + if ((n = dn_expand(msg, eom, cp, key, PACKETSZ)) < 0) + break; + cp += n; + type = _getshort(cp); + cp += 2*sizeof(u_short) + sizeof(u_long); + len = _getshort(cp); + cp += sizeof(u_short); +#ifdef DEBUG + dlog("hs_get_ns_list: Record type: %d", type); +#endif + switch (type) { + case T_NS: + if (numns >= MAXHSNS || strcasecmp(domain, key) != 0) + break; + if ((n = dn_expand(msg, eom, cp, name, PACKETSZ)) < 0) + break; +#ifdef DEBUG + dlog("hs_get_ns_list: NS name: %s", name); +#endif + for (i = 0; i < numns; i++) + if (strcasecmp(nsname[i], name) == 0) + break; + if (i == numns) { +#ifdef DEBUG + dlog("hs_get_ns_list: Saving name %s", name); +#endif + strncpy(nsname[numns], name, MAXDATA); + nshaveaddr[numns] = 0; + numns++; + } + break; + case T_A: + if (hs_nscount == MAX_NSADDR) + break; + for (i = 0; i < numns; i++) { + if (strcasecmp(nsname[i], domain) == 0) { + nshaveaddr[i]++; + add_address((struct in_addr *) cp); + break; + } + } + break; + default: + break; + } + if (hs_nscount == MAX_NSADDR) + break; + cp += len; + errno = 0; + } +#ifdef DEBUG + dlog("hs_get_ns_list: Found %d NS records", numns); +#endif + for (i = 0; i < numns; i++) { + if (nshaveaddr[i]) + continue; + if ((ghp = gethostbyname(nsname[i])) == 0) + continue; + for (hptr = (long **)ghp->h_addr_list; + *hptr && hs_nscount < MAX_NSADDR; hptr++) { + add_address((struct in_addr *) *hptr); + } + } + if (hs_nscount) + return(0); +#ifdef DEBUG + dlog("No NS records found for %s", domain); + return(-1); +#endif DEBUG +} +#endif /* HAS_HESIOD_RELOAD */ +#endif /* HAS_HESIOD_MAPS */ diff --git a/usr.sbin/amd/amd/info_ndbm.c b/usr.sbin/amd/amd/info_ndbm.c new file mode 100644 index 0000000..d3deaa1 --- /dev/null +++ b/usr.sbin/amd/amd/info_ndbm.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)info_ndbm.c 8.1 (Berkeley) 6/6/93 + * + * $Id: info_ndbm.c,v 5.2.2.1 1992/02/09 15:08:31 jsp beta $ + * + */ + +/* + * Get info from NDBM map + */ + +#include "am.h" + +#ifdef HAS_NDBM_MAPS + +#include +#include +#include + +static int search_ndbm P((DBM *db, char *key, char **val)); +static int search_ndbm(db, key, val) +DBM *db; +char *key; +char **val; +{ + datum k, v; + k.dptr = key; + k.dsize = strlen(key) + 1; + v = dbm_fetch(db, k); + if (v.dptr) { + *val = strdup(v.dptr); + return 0; + } + return ENOENT; +} + +int ndbm_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp)); +int ndbm_search(m, map, key, pval, tp) +mnt_map *m; +char *map; +char *key; +char **pval; +time_t *tp; +{ + DBM *db; + + db = dbm_open(map, O_RDONLY, 0); + if (db) { + struct stat stb; + int error; + error = fstat(dbm_pagfno(db), &stb); + if (!error && *tp < stb.st_mtime) { + *tp = stb.st_mtime; + error = -1; + } else { + error = search_ndbm(db, key, pval); + } + (void) dbm_close(db); + return error; + } + + return errno; +} + +int ndbm_init P((char *map, time_t *tp)); +int ndbm_init(map, tp) +char *map; +time_t *tp; +{ + DBM *db; + + db = dbm_open(map, O_RDONLY, 0); + if (db) { + struct stat stb; + + if (fstat(dbm_pagfno(db), &stb) < 0) + *tp = clocktime(); + else + *tp = stb.st_mtime; + dbm_close(db); + return 0; + } + + return errno; +} + +#endif /* HAS_NDBM_MAPS */ diff --git a/usr.sbin/amd/amd/info_nis.c b/usr.sbin/amd/amd/info_nis.c new file mode 100644 index 0000000..ac80f5f --- /dev/null +++ b/usr.sbin/amd/amd/info_nis.c @@ -0,0 +1,247 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)info_nis.c 8.1 (Berkeley) 6/6/93 + * + * $Id: info_nis.c,v 5.2.2.1 1992/02/09 15:08:32 jsp beta $ + * + */ + +/* + * Get info from NIS map + */ + +#include "am.h" + +#ifdef HAS_NIS_MAPS +#include +#include + +/* + * Figure out the nis domain name + */ +static int determine_nis_domain(P_void) +{ +static int nis_not_running = 0; + + char default_domain[YPMAXDOMAIN]; + + if (nis_not_running) + return ENOENT; + + if (getdomainname(default_domain, sizeof(default_domain)) < 0) { + nis_not_running = 1; + plog(XLOG_ERROR, "getdomainname: %m"); + return EIO; + } + + if (!*default_domain) { + nis_not_running = 1; + plog(XLOG_WARNING, "NIS domain name is not set. NIS ignored."); + return ENOENT; + } + + domain = strdup(default_domain); + + return 0; +} + + +#ifdef HAS_NIS_RELOAD +struct nis_callback_data { + mnt_map *ncd_m; + char *ncd_map; + void (*ncd_fn)(); +}; + +/* + * Callback from yp_all + */ +static int callback(status, key, kl, val, vl, data) +int status; +char *key; +int kl; +char *val; +int vl; +struct nis_callback_data *data; +{ + if (status == YP_TRUE) { + /* + * Add to list of maps + */ + char *kp = strnsave(key, kl); + char *vp = strnsave(val, vl); + (*data->ncd_fn)(data->ncd_m, kp, vp); + + /* + * We want more ... + */ + return FALSE; + } else { + /* + * NOMORE means end of map - otherwise log error + */ + if (status != YP_NOMORE) { + /* + * Check what went wrong + */ + int e = ypprot_err(status); + +#ifdef DEBUG + plog(XLOG_ERROR, "yp enumeration of %s: %s, status=%d, e=%d", + data->ncd_map, yperr_string(e), status, e); +#else + plog(XLOG_ERROR, "yp enumeration of %s: %s", data->ncd_map, yperr_string(e)); +#endif + } + + return TRUE; + } +} + +int nis_reload P((mnt_map *m, char *map, void (*fn)())); +int nis_reload(m, map, fn) +mnt_map *m; +char *map; +void (*fn)(); +{ + struct ypall_callback cbinfo; + int error; + struct nis_callback_data data; + + if (!domain) { + error = determine_nis_domain(); + if (error) + return error; + } + + data.ncd_m = m; + data.ncd_map = map; + data.ncd_fn = fn; + cbinfo.data = (voidp) &data; + cbinfo.foreach = callback; + + error = yp_all(domain, map, &cbinfo); + + if (error) + plog(XLOG_ERROR, "error grabbing nis map of %s: %s", map, yperr_string(ypprot_err(error))); + + return error; +} +#endif /* HAS_NIS_RELOAD */ + +/* + * Try to locate a key using NIS. + */ +int nis_search P((mnt_map *m, char *map, char *key, char **val, time_t *tp)); +int nis_search(m, map, key, val, tp) +mnt_map *m; +char *map; +char *key; +char **val; +time_t *tp; +{ + int outlen; + int res; + int order; + + /* + * Make sure domain initialised + */ + if (!domain) { + int error = determine_nis_domain(); + if (error) + return error; + } + + /* + * Check if map has changed + */ + if (yp_order(domain, map, &order)) + return EIO; + if ((time_t) order > *tp) { + *tp = (time_t) order; + return -1; + } + + /* + * Lookup key + */ + res = yp_match(domain, map, key, strlen(key), val, &outlen); + + /* + * Do something interesting with the return code + */ + switch (res) { + case 0: + return 0; + + case YPERR_KEY: + return ENOENT; + + default: + plog(XLOG_ERROR, "%s: %s", map, yperr_string(res)); + return EIO; + } +} + +int nis_init P((char *map, time_t *tp)); +int nis_init(map, tp) +char *map; +time_t *tp; +{ + int order; + + if (!domain) { + int error = determine_nis_domain(); + if (error) + return error; + } + + /* + * To see if the map exists, try to find + * a master for it. + */ + if (yp_order(domain, map, &order)) + return ENOENT; + *tp = (time_t) order; +#ifdef DEBUG + dlog("NIS master for %s@%s has order %d", map, domain, order); +#endif + return 0; +} +#endif /* HAS_NIS_MAPS */ diff --git a/usr.sbin/amd/amd/info_passwd.c b/usr.sbin/amd/amd/info_passwd.c new file mode 100644 index 0000000..3123e38 --- /dev/null +++ b/usr.sbin/amd/amd/info_passwd.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)info_passwd.c 8.1 (Berkeley) 6/6/93 + * + * $Id: info_passwd.c,v 5.2.2.1 1992/02/09 15:08:33 jsp beta $ + * + */ + +/* + * Get info from password "file" + * + * This is experimental and probably doesn't + * do what you expect. + */ + +#include "am.h" + +#ifdef HAS_PASSWD_MAPS +#include + +#define PASSWD_MAP "/etc/passwd" + +/* + * Nothing to probe - check the map name is PASSWD_MAP. + */ +int passwd_init P((char *map, time_t *tp)); +int passwd_init(map, tp) +char *map; +time_t *tp; +{ + *tp = 0; + return strcmp(map, PASSWD_MAP) == 0 ? 0 : ENOENT; +} + + +/* + * Grab the entry via the getpwname routine + * Modify time is ignored by passwd - XXX + */ +int passwd_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp)); +int passwd_search(m, map, key, pval, tp) +mnt_map *m; +char *map; +char *key; +char **pval; +time_t *tp; +{ + char *dir = 0; + struct passwd *pw; + if (strcmp(key, "/defaults") == 0) { + *pval = strdup("type:=nfs"); + return 0; + } + + pw = getpwnam(key); + if (pw) { + /* + * We chop the home directory up as follows: + * /anydir/dom1/dom2/dom3/user + * + * and return + * rfs:=/anydir/dom3;rhost:=dom3.dom2.dom1;sublink:=user + * + * This allows cross-domain entries in your passwd file. + * ... but forget about security! + */ + char *user; + char *p, *q; + char val[MAXPATHLEN]; + char rhost[MAXHOSTNAMELEN]; + dir = strdup(pw->pw_dir); + /* + * Find user name. If no / then Invalid... + */ + user = strrchr(dir, '/'); + if (!user) + goto enoent; + *user++ = '\0'; + /* + * Find start of host "path". If no / then Invalid... + */ + p = strchr(dir+1, '/'); + if (!p) + goto enoent; + *p++ = '\0'; + /* + * At this point, p is dom1/dom2/dom3 + * Copy, backwards, into rhost replacing + * / with . + */ + rhost[0] = '\0'; + do { + q = strrchr(p, '/'); + if (q) { + strcat(rhost, q + 1); + strcat(rhost, "."); + *q = '\0'; + } else { + strcat(rhost, p); + } + } while (q); + /* + * Sanity check + */ + if (*rhost == '\0' || *user == '\0' || *dir == '\0') + goto enoent; + /* + * Make up return string + */ + q = strchr(rhost, '.'); + if (q) + *q = '\0'; + sprintf(val, "rfs:=%s/%s;rhost:=%s;sublink:=%s;fs:=${autodir}%s", + dir, rhost, rhost, user, pw->pw_dir); + if (q) + *q = '.'; + *pval = strdup(val); + return 0; + } + +enoent: + if (dir) + free(dir); + + return ENOENT; +} +#endif /* HAS_PASSWD_MAPS */ diff --git a/usr.sbin/amd/amd/info_union.c b/usr.sbin/amd/amd/info_union.c new file mode 100644 index 0000000..e3062ad --- /dev/null +++ b/usr.sbin/amd/amd/info_union.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)info_union.c 8.1 (Berkeley) 6/6/93 + * + * $Id: info_union.c,v 5.2.2.1 1992/02/09 15:08:34 jsp beta $ + * + */ + +/* + * Get info from the system namespace + * + * NOTE: Cannot handle reads back through the automounter. + * THIS WILL CAUSE A DEADLOCK! + */ + +#include "am.h" + +#ifdef HAS_UNION_MAPS + +#ifdef _POSIX_SOURCE +#include +#define DIRENT struct dirent +#else +#include +#define DIRENT struct direct +#endif + +#define UNION_PREFIX "union:" +#define UNION_PREFLEN 6 + +/* + * No way to probe - check the map name begins with "union:" + */ +int union_init P((char *map, time_t *tp)); +int union_init(map, tp) +char *map; +time_t *tp; +{ + *tp = 0; + return strncmp(map, UNION_PREFIX, UNION_PREFLEN) == 0 ? 0 : ENOENT; +} + +int union_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp)); +int union_search(m, map, key, pval, tp) +mnt_map *m; +char *map; +char *key; +char **pval; +time_t *tp; +{ + char *mapd = strdup(map + UNION_PREFLEN); + char **v = strsplit(mapd, ':', '\"'); + char **p; + for (p = v; p[1]; p++) + ; + *pval = xmalloc(strlen(*p) + 5); + sprintf(*pval, "fs:=%s", *p); + free(mapd); + free(v); + return 0; +} + +int union_reload P((mnt_map *m, char *map, void (*fn)())); +int union_reload(m, map, fn) +mnt_map *m; +char *map; +void (*fn)(); +{ + char *mapd = strdup(map + UNION_PREFLEN); + char **v = strsplit(mapd, ':', '\"'); + char **dir; + + /* + * Add fake /defaults entry + */ + (*fn)(m, strdup("/defaults"), strdup("type:=link;opts:=nounmount;sublink:=${key}")); + + for (dir = v; *dir; dir++) { + int dlen; + DIRENT *dp; + DIR *dirp = opendir(*dir); + if (!dirp) { + plog(XLOG_USER, "Cannot read directory %s: %m", *dir); + continue; + } + dlen = strlen(*dir); +#ifdef DEBUG + dlog("Reading directory %s...", *dir); +#endif + while (dp = readdir(dirp)) { + char *val; + if (dp->d_name[0] == '.' && + (dp->d_name[1] == '\0' || + (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) + continue; + +#ifdef DEBUG + dlog("... gives %s", dp->d_name); +#endif + val = xmalloc(dlen + 5); + sprintf(val, "fs:=%s", *dir); + (*fn)(m, strdup(dp->d_name), val); + } + closedir(dirp); + } + /* + * Add wildcard entry + */ + { char *val = xmalloc(strlen(dir[-1]) + 5); + sprintf(val, "fs:=%s", dir[-1]); + (*fn)(m, strdup("*"), val); + } + free(mapd); + free(v); + return 0; +} + +#endif /* HAS_UNION_MAPS */ diff --git a/usr.sbin/amd/amd/map.c b/usr.sbin/amd/amd/map.c new file mode 100644 index 0000000..6f2acb3 --- /dev/null +++ b/usr.sbin/amd/amd/map.c @@ -0,0 +1,1140 @@ +/*- + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * $Id: map.c,v 5.2.2.1 1992/02/09 15:08:36 jsp beta $ + */ + +#ifndef lint +static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "am.h" + +/* + * Generation Numbers. + * + * Generation numbers are allocated to every node created + * by amd. When a filehandle is computed and sent to the + * kernel, the generation number makes sure that it is safe + * to reallocate a node slot even when the kernel has a cached + * reference to its old incarnation. + * No garbage collection is done, since it is assumed that + * there is no way that 2^32 generation numbers could ever + * be allocated by a single run of amd - there is simply + * not enough cpu time available. + */ +static unsigned int am_gen = 2; /* Initial generation number */ +#define new_gen() (am_gen++) + +am_node **exported_ap = (am_node **) 0; +int exported_ap_size = 0; +int first_free_map = 0; /* First available free slot */ +int last_used_map = -1; /* Last unavailable used slot */ +static int timeout_mp_id; /* Id from last call to timeout */ + +/* + * This is the default attributes field which + * is copied into every new node to be created. + * The individual filesystem fs_init() routines + * patch the copy to represent the particular + * details for the relevant filesystem type + */ +static struct fattr gen_fattr = { + NFLNK, /* type */ + NFSMODE_LNK | 0777, /* mode */ + 1, /* nlink */ + 0, /* uid */ + 0, /* gid */ + 0, /* size */ + 4096, /* blocksize */ + 0, /* rdev */ + 1, /* blocks */ + 0, /* fsid */ + 0, /* fileid */ + { 0, 0 }, /* atime */ + { 0, 0 }, /* mtime */ + { 0, 0 }, /* ctime */ +}; + +/* + * Resize exported_ap map + */ +static int exported_ap_realloc_map P((int nsize)); +static int exported_ap_realloc_map(nsize) +int nsize; +{ +#ifdef notdef + /* + * If a second realloc occasionally causes Amd to die + * in then include this check. + */ + if (exported_ap_size != 0) /* XXX */ + return 0; +#endif + + /* + * this shouldn't happen, but... + */ + if (nsize < 0 || nsize == exported_ap_size) + return 0; + + exported_ap = (am_node **) xrealloc((voidp) exported_ap, nsize * sizeof(am_node*)); + + if (nsize > exported_ap_size) + bzero((char*) (exported_ap+exported_ap_size), + (nsize - exported_ap_size) * sizeof(am_node*)); + exported_ap_size = nsize; + + return 1; +} + + +/* + * The root of the mount tree. + */ +am_node *root_node; + +/* + * Allocate a new mount slot and create + * a new node. + * Fills in the map number of the node, + * but leaves everything else uninitialised. + */ +am_node *exported_ap_alloc(P_void) +{ + am_node *mp, **mpp; + + /* + * First check if there are any slots left, realloc if needed + */ + if (first_free_map >= exported_ap_size) + if (!exported_ap_realloc_map(exported_ap_size + NEXP_AP)) + return 0; + + /* + * Grab the next free slot + */ + mpp = exported_ap + first_free_map; + mp = *mpp = ALLOC(am_node); + bzero((char *) mp, sizeof(*mp)); + + mp->am_mapno = first_free_map++; + + /* + * Update free pointer + */ + while (first_free_map < exported_ap_size && exported_ap[first_free_map]) + first_free_map++; + + if (first_free_map > last_used_map) + last_used_map = first_free_map - 1; + + /* + * Shrink exported_ap if reasonable + */ + if (last_used_map < exported_ap_size - (NEXP_AP + NEXP_AP_MARGIN)) + exported_ap_realloc_map(exported_ap_size - NEXP_AP); + +#ifdef DEBUG + /*dlog("alloc_exp: last_used_map = %d, first_free_map = %d\n", + last_used_map, first_free_map);*/ +#endif /* DEBUG */ + + return mp; +} + +/* + * Free a mount slot + */ +void exported_ap_free P((am_node *mp)); +void exported_ap_free(mp) +am_node *mp; +{ + /* + * Sanity check + */ + if (!mp) + return; + + /* + * Zero the slot pointer to avoid double free's + */ + exported_ap[mp->am_mapno] = 0; + + /* + * Update the free and last_used indices + */ + if (mp->am_mapno == last_used_map) + while (last_used_map >= 0 && exported_ap[last_used_map] == 0) + --last_used_map; + + if (first_free_map > mp->am_mapno) + first_free_map = mp->am_mapno; + +#ifdef DEBUG + /*dlog("free_exp: last_used_map = %d, first_free_map = %d\n", + last_used_map, first_free_map);*/ +#endif /* DEBUG */ + + /* + * Free the mount node + */ + free((voidp) mp); +} + +/* + * Insert mp into the correct place, + * where p_mp is its parent node. + * A new node gets placed as the youngest sibling + * of any other children, and the parent's child + * pointer is adjusted to point to the new child node. + */ +void insert_am(mp, p_mp) +am_node *mp; +am_node *p_mp; +{ + /* + * If this is going in at the root then flag it + * so that it cannot be unmounted by amq. + */ + if (p_mp == root_node) + mp->am_flags |= AMF_ROOT; + /* + * Fill in n-way links + */ + mp->am_parent = p_mp; + mp->am_osib = p_mp->am_child; + if (mp->am_osib) + mp->am_osib->am_ysib = mp; + p_mp->am_child = mp; +} + +/* + * Remove am from its place in the mount tree + */ +void remove_am(mp) +am_node *mp; +{ + /* + * 1. Consistency check + */ + if (mp->am_child && mp->am_parent) { + plog(XLOG_WARNING, "children of \"%s\" still exist - deleting anyway", mp->am_path); + } + + /* + * 2. Update parent's child pointer + */ + if (mp->am_parent && mp->am_parent->am_child == mp) + mp->am_parent->am_child = mp->am_osib; + + /* + * 3. Unlink from sibling chain + */ + if (mp->am_ysib) + mp->am_ysib->am_osib = mp->am_osib; + if (mp->am_osib) + mp->am_osib->am_ysib = mp->am_ysib; +} + +/* + * Compute a new time to live value for a node. + */ +void new_ttl(mp) +am_node *mp; +{ + mp->am_timeo_w = 0; + + mp->am_ttl = clocktime(); + mp->am_fattr.atime.seconds = mp->am_ttl; + mp->am_ttl += mp->am_timeo; /* sun's -tl option */ +} + +void mk_fattr P((am_node *mp, ftype vntype)); +void mk_fattr(mp, vntype) +am_node *mp; +ftype vntype; +{ + switch (vntype) { + case NFDIR: + mp->am_fattr.type = NFDIR; + mp->am_fattr.mode = NFSMODE_DIR | 0555; + mp->am_fattr.nlink = 2; + mp->am_fattr.size = 512; + break; + case NFLNK: + mp->am_fattr.type = NFLNK; + mp->am_fattr.mode = NFSMODE_LNK | 0777; + mp->am_fattr.nlink = 1; + mp->am_fattr.size = 0; + break; + default: + plog(XLOG_FATAL, "Unknown fattr type %d - ignored", vntype); + break; + } +} + +/* + * Initialise an allocated mount node. + * It is assumed that the mount node was bzero'd + * before getting here so anything that would + * be set to zero isn't done here. + */ +void init_map(mp, dir) +am_node *mp; +char *dir; +{ + /* mp->am_mapno initalised by exported_ap_alloc */ + mp->am_mnt = new_mntfs(); + mp->am_name = strdup(dir); + mp->am_path = strdup(dir); + /*mp->am_link = 0;*/ + /*mp->am_parent = 0;*/ + /*mp->am_ysib = 0;*/ + /*mp->am_osib = 0;*/ + /*mp->am_child = 0;*/ + /*mp->am_flags = 0;*/ + /*mp->am_error = 0;*/ + mp->am_gen = new_gen(); + /*mp->am_pref = 0;*/ + + mp->am_timeo = am_timeo; + mp->am_attr.status = NFS_OK; + mp->am_fattr = gen_fattr; + mp->am_fattr.fsid = 42; + mp->am_fattr.fileid = 0; + mp->am_fattr.atime.seconds = clocktime(); + mp->am_fattr.atime.useconds = 0; + mp->am_fattr.mtime = mp->am_fattr.ctime = mp->am_fattr.atime; + + new_ttl(mp); + mp->am_stats.s_mtime = mp->am_fattr.atime.seconds; + /*mp->am_private = 0;*/ +} + +/* + * Free a mount node. + * The node must be already unmounted. + */ +void free_map(mp) +am_node *mp; +{ + remove_am(mp); + + if (mp->am_link) + free(mp->am_link); + if (mp->am_name) + free(mp->am_name); + if (mp->am_path) + free(mp->am_path); + if (mp->am_pref) + free(mp->am_pref); + + if (mp->am_mnt) + free_mntfs(mp->am_mnt); + + exported_ap_free(mp); +} + +/* + * Convert from file handle to + * automount node. + */ +am_node *fh_to_mp3(fhp, rp, c_or_d) +nfs_fh *fhp; +int *rp; +int c_or_d; +{ + struct am_fh *fp = (struct am_fh *) fhp; + am_node *ap = 0; + + /* + * Check process id matches + * If it doesn't then it is probably + * from an old kernel cached filehandle + * which is now out of date. + */ + if (fp->fhh_pid != mypid) + goto drop; + + /* + * Make sure the index is valid before + * exported_ap is referenced. + */ + if (fp->fhh_id < 0 || fp->fhh_id >= exported_ap_size) + goto drop; + + /* + * Get hold of the supposed mount node + */ + ap = exported_ap[fp->fhh_id]; + + /* + * If it exists then maybe... + */ + if (ap) { + /* + * Check the generation number in the node + * matches the one from the kernel. If not + * then the old node has been timed out and + * a new one allocated. + */ + if (ap->am_gen != fp->fhh_gen) { + ap = 0; + goto drop; + } + + /* + * If the node is hung then locate a new node + * for it. This implements the replicated filesystem + * retries. + */ + if (ap->am_mnt && FSRV_ISDOWN(ap->am_mnt->mf_server) && ap->am_parent) { + int error; + am_node *orig_ap = ap; +#ifdef DEBUG + dlog("fh_to_mp3: %s (%s) is hung:- call lookup", + orig_ap->am_path, orig_ap->am_mnt->mf_info); +#endif /* DEBUG */ + /* + * Update modify time of parent node. + * With any luck the kernel will re-stat + * the child node and get new information. + */ + orig_ap->am_fattr.mtime.seconds = clocktime(); + + /* + * Call the parent's lookup routine for an object + * with the same name. This may return -1 in error + * if a mount is in progress. In any case, if no + * mount node is returned the error code is propagated + * to the caller. + */ + if (c_or_d == VLOOK_CREATE) { + ap = (*orig_ap->am_parent->am_mnt->mf_ops->lookuppn)(orig_ap->am_parent, + orig_ap->am_name, &error, c_or_d); + } else { + ap = 0; + error = ESTALE; + } + if (ap == 0) { + if (error < 0 && amd_state == Finishing) + error = ENOENT; + *rp = error; + return 0; + } + /* + * Update last access to original node. This + * avoids timing it out and so sending ESTALE + * back to the kernel. + * XXX - Not sure we need this anymore (jsp, 90/10/6). + */ + new_ttl(orig_ap); + + } + /* + * Disallow references to objects being unmounted, unless + * they are automount points. + */ + if (ap->am_mnt && (ap->am_mnt->mf_flags & MFF_UNMOUNTING) && + !(ap->am_flags & AMF_ROOT)) { + if (amd_state == Finishing) + *rp = ENOENT; + else + *rp = -1; + return 0; + } + new_ttl(ap); + } + +drop: + if (!ap || !ap->am_mnt) { + /* + * If we are shutting down then it is likely + * that this node has disappeared because of + * a fast timeout. To avoid things thrashing + * just pretend it doesn't exist at all. If + * ESTALE is returned, some NFS clients just + * keep retrying (stupid or what - if it's + * stale now, what's it going to be in 5 minutes?) + */ + if (amd_state == Finishing) + *rp = ENOENT; + else + *rp = ESTALE; + amd_stats.d_stale++; + } + + return ap; +} + +am_node *fh_to_mp(fhp) +nfs_fh *fhp; +{ + int dummy; + return fh_to_mp2(fhp, &dummy); +} + +/* + * Convert from automount node to + * file handle. + */ +void mp_to_fh(mp, fhp) +am_node *mp; +struct nfs_fh *fhp; +{ + struct am_fh *fp = (struct am_fh *) fhp; + + /* + * Take the process id + */ + fp->fhh_pid = mypid; + /* + * .. the map number + */ + fp->fhh_id = mp->am_mapno; + /* + * .. and the generation number + */ + fp->fhh_gen = mp->am_gen; + /* + * .. to make a "unique" triple that will never + * be reallocated except across reboots (which doesn't matter) + * or if we are unlucky enough to be given the same + * pid as a previous amd (very unlikely). + */ +} + +static am_node *find_ap2 P((char *dir, am_node *mp)); +static am_node *find_ap2(dir, mp) +char *dir; +am_node *mp; +{ + if (mp) { + am_node *mp2; + if (strcmp(mp->am_path, dir) == 0) + return mp; + + if ((mp->am_mnt->mf_flags & MFF_MOUNTED) && + strcmp(mp->am_mnt->mf_mount, dir) == 0) + return mp; + + mp2 = find_ap2(dir, mp->am_osib); + if (mp2) + return mp2; + return find_ap2(dir, mp->am_child); + } + + return 0; +} + +/* + * Find the mount node corresponding + * to dir. dir can match either the + * automount path or, if the node is + * mounted, the mount location. + */ +am_node *find_ap P((char *dir)); +am_node *find_ap(dir) +char *dir; +{ + int i; + + for (i = last_used_map; i >= 0; --i) { + am_node *mp = exported_ap[i]; + if (mp && (mp->am_flags & AMF_ROOT)) { + mp = find_ap2(dir, exported_ap[i]); + if (mp) + return mp; + } + } + + return 0; +} + +/* + * Find the mount node corresponding + * to the mntfs structure. + */ +am_node *find_mf P((mntfs *mf)); +am_node *find_mf(mf) +mntfs *mf; +{ + int i; + + for (i = last_used_map; i >= 0; --i) { + am_node *mp = exported_ap[i]; + if (mp && mp->am_mnt == mf) + return mp; + } + return 0; +} + +/* + * Get the filehandle for a particular named directory. + * This is used during the bootstrap to tell the kernel + * the filehandles of the initial automount points. + */ +nfs_fh *root_fh(dir) +char *dir; +{ + static nfs_fh nfh; + am_node *mp = root_ap(dir, TRUE); + if (mp) { + mp_to_fh(mp, &nfh); + /* + * Patch up PID to match main server... + */ + if (!foreground) { + long pid = getppid(); + ((struct am_fh *) &nfh)->fhh_pid = pid; +#ifdef DEBUG + dlog("root_fh substitutes pid %d", pid); +#endif + } + return &nfh; + } + + /* + * Should never get here... + */ + plog(XLOG_ERROR, "Can't find root filehandle for %s", dir); + return 0; +} + +am_node *root_ap(dir, path) +char *dir; +int path; +{ + am_node *mp = find_ap(dir); + if (mp && mp->am_parent == root_node) + return mp; + + return 0; +} + +/* + * Timeout all nodes waiting on + * a given Fserver. + */ +void map_flush_srvr P((fserver *fs)); +void map_flush_srvr(fs) +fserver *fs; +{ + int i; + int done = 0; + + for (i = last_used_map; i >= 0; --i) { + am_node *mp = exported_ap[i]; + if (mp && mp->am_mnt && mp->am_mnt->mf_server == fs) { + plog(XLOG_INFO, "Flushed %s; dependent on %s", mp->am_path, fs->fs_host); + mp->am_ttl = clocktime(); + done = 1; + } + } + if (done) + reschedule_timeout_mp(); +} + +/* + * Mount a top level automount node + * by calling lookup in the parent + * (root) node which will cause the + * automount node to be automounted. + */ +int mount_auto_node P((char *dir, voidp arg)); +int mount_auto_node(dir, arg) +char *dir; +voidp arg; +{ + int error = 0; + (void) afs_ops.lookuppn((am_node *) arg, dir, &error, VLOOK_CREATE); + if (error > 0) { + errno = error; /* XXX */ + plog(XLOG_ERROR, "Could not mount %s: %m", dir); + } + return error; +} + +/* + * Cause all the top-level mount nodes + * to be automounted + */ +int mount_exported P((void)); +int mount_exported() +{ + /* + * Iterate over all the nodes to be started + */ + return root_keyiter((void (*)P((char*,void*))) mount_auto_node, root_node); +} + +/* + * Construct top-level node + */ +void make_root_node P((void)); +void make_root_node() +{ + mntfs *root_mnt; + char *rootmap = ROOT_MAP; + root_node = exported_ap_alloc(); + + /* + * Allocate a new map + */ + init_map(root_node, ""); + /* + * Allocate a new mounted filesystem + */ + root_mnt = find_mntfs(&root_ops, (am_opts *) 0, "", rootmap, "", "", ""); + /* + * Replace the initial null reference + */ + free_mntfs(root_node->am_mnt); + root_node->am_mnt = root_mnt; + + /* + * Initialise the root + */ + if (root_mnt->mf_ops->fs_init) + (*root_mnt->mf_ops->fs_init)(root_mnt); + + /* + * Mount the root + */ + root_mnt->mf_error = (*root_mnt->mf_ops->mount_fs)(root_node); +} + +/* + * Cause all the nodes to be unmounted by timing + * them out. + */ +void umount_exported(P_void) +{ + int i; + for (i = last_used_map; i >= 0; --i) { + am_node *mp = exported_ap[i]; + if (mp) { + mntfs *mf = mp->am_mnt; + if (mf->mf_flags & MFF_UNMOUNTING) { + /* + * If this node is being unmounted then + * just ignore it. However, this could + * prevent amd from finishing if the + * unmount gets blocked since the am_node + * will never be free'd. am_unmounted needs + * telling about this possibility. - XXX + */ + continue; + } + if (mf && !(mf->mf_ops->fs_flags & FS_DIRECTORY)) { + /* + * When shutting down this had better + * look like a directory, otherwise it + * can't be unmounted! + */ + mk_fattr(mp, NFDIR); + } + if ((--immediate_abort < 0 && !(mp->am_flags & AMF_ROOT) && mp->am_parent) || + (mf->mf_flags & MFF_RESTART)) { + /* + * Just throw this node away without + * bothering to unmount it. If the + * server is not known to be up then + * don't discard the mounted on directory + * or Amd might hang... + */ + if (mf->mf_server && + (mf->mf_server->fs_flags & (FSF_DOWN|FSF_VALID)) != FSF_VALID) + mf->mf_flags &= ~MFF_MKMNT; + am_unmounted(mp); + } else { + /* + * Any other node gets forcibly + * timed out + */ + mp->am_flags &= ~AMF_NOTIMEOUT; + mp->am_mnt->mf_flags &= ~MFF_RSTKEEP; + mp->am_ttl = 0; + mp->am_timeo = 1; + mp->am_timeo_w = 0; + } + } + } +} + +static int unmount_node P((am_node *mp)); +static int unmount_node(mp) +am_node *mp; +{ + mntfs *mf = mp->am_mnt; + int error; + + if ((mf->mf_flags & MFF_ERROR) || mf->mf_refc > 1) { + /* + * Just unlink + */ +#ifdef DEBUG + if (mf->mf_flags & MFF_ERROR) + dlog("No-op unmount of error node %s", mf->mf_info); +#endif /* DEBUG */ + error = 0; + } else { +#ifdef DEBUG + dlog("Unmounting %s (%s)", mf->mf_mount, mf->mf_info); +#endif /* DEBUG */ + error = (*mf->mf_ops->umount_fs)(mp); + } + + if (error) { +#ifdef DEBUG + errno = error; /* XXX */ + dlog("%s: unmount: %m", mf->mf_mount); +#endif /* DEBUG */ + } + + return error; +} + +#ifdef FLUSH_KERNEL_NAME_CACHE +static void flush_kernel_name_cache P((am_node*)); +static void flush_kernel_name_cache(mp) +am_node *mp; +{ + int islink = (mp->am_mnt->mf_fattr.type == NFLNK); + int isdir = (mp->am_mnt->mf_fattr.type == NFDIR); + int elog = 0; + if (islink) { + if (unlink(mp->am_path) < 0) + elog = 1; + } else if (isdir) { + if (rmdir(mp->am_path) < 0) + elog = 1; + } + if (elog) + plog(XLOG_WARNING, "failed to clear \"%s\" from dnlc: %m", mp->am_path); +} +#endif /* FLUSH_KERNEL_NAME_CACHE */ + +static int unmount_node_wrap P((voidp vp)); +static int unmount_node_wrap(vp) +voidp vp; +{ +#ifndef FLUSH_KERNEL_NAME_CACHE + return unmount_node((am_node*) vp); +#else /* FLUSH_KERNEL_NAME_CACHE */ + /* + * This code should just say: + * return unmount_node((am_node *) vp); + * + * However... + * The kernel keeps a cached copy of filehandles, + * and doesn't ever uncache them (apparently). So + * when Amd times out a node the kernel will have a + * stale filehandle. When the kernel next uses the + * filehandle it gets ESTALE. + * + * The workaround: + * Arrange that when a node is removed an unlink or + * rmdir is done on that path so that the kernel + * cache is done. Yes - yuck. + * + * This can all be removed (and the background + * unmount flag in sfs_ops) if/when the kernel does + * something smarter. + * + * If the unlink or rmdir failed then just log a warning, + * don't fail the unmount. This can occur if the kernel + * client code decides that the object is still referenced + * and should be renamed rather than discarded. + * + * There is still a race condition here... + * if another process is trying to access the same + * filesystem at the time we get here, then + * it will block, since the MF_UNMOUNTING flag will + * be set. That may, or may not, cause the entire + * system to deadlock. Hmmm... + */ + am_node *mp = (am_node *) vp; + int isauto = mp->am_parent && (mp->am_parent->am_mnt->mf_fattr.type == NFDIR); + int error = unmount_node(mp); + if (error) + return error; + if (isauto && (int)amd_state < (int)Finishing) + flush_kernel_name_cache(mp); + + return 0; +#endif /* FLUSH_KERNEL_NAME_CACHE */ +} + +static void free_map_if_success(rc, term, closure) +int rc; +int term; +voidp closure; +{ + am_node *mp = (am_node *) closure; + mntfs *mf = mp->am_mnt; + + /* + * Not unmounting any more + */ + mf->mf_flags &= ~MFF_UNMOUNTING; + + /* + * If a timeout was defered because the underlying filesystem + * was busy then arrange for a timeout as soon as possible. + */ + if (mf->mf_flags & MFF_WANTTIMO) { + mf->mf_flags &= ~MFF_WANTTIMO; + reschedule_timeout_mp(); + } + + if (term) { + plog(XLOG_ERROR, "unmount for %s got signal %d", mp->am_path, term); +#if defined(DEBUG) && defined(SIGTRAP) + /* + * dbx likes to put a trap on exit(). + * Pretend it succeeded for now... + */ + if (term == SIGTRAP) { + am_unmounted(mp); + } +#endif /* DEBUG */ + amd_stats.d_uerr++; + } else if (rc) { + if (rc == EBUSY) { + plog(XLOG_STATS, "\"%s\" on %s still active", mp->am_path, mf->mf_mount); + } else { + errno = rc; /* XXX */ + plog(XLOG_ERROR, "%s: unmount: %m", mp->am_path); + } + amd_stats.d_uerr++; + } else { + am_unmounted(mp); + } + + /* + * Wakeup anything waiting for this mount + */ + wakeup((voidp) mf); +} + +static int unmount_mp(mp) +am_node *mp; +{ + int was_backgrounded = 0; + mntfs *mf = mp->am_mnt; + +#ifdef notdef + plog(XLOG_INFO, "\"%s\" on %s timed out", mp->am_path, mp->am_mnt->mf_mount); +#endif /* notdef */ + + if ((mf->mf_ops->fs_flags & FS_UBACKGROUND) && + (mf->mf_flags & MFF_MOUNTED)) { + if (mf->mf_refc == 1 && !FSRV_ISUP(mf->mf_server)) { + /* + * Don't try to unmount from a server that is known to be down + */ + if (!(mf->mf_flags & MFF_LOGDOWN)) { + /* Only log this once, otherwise gets a bit boring */ + plog(XLOG_STATS, "file server %s is down - timeout of \"%s\" ignored", mf->mf_server->fs_host, mp->am_path); + mf->mf_flags |= MFF_LOGDOWN; + } + } else { + /* Clear logdown flag - since the server must be up */ + mf->mf_flags &= ~MFF_LOGDOWN; +#ifdef DEBUG + dlog("\"%s\" on %s timed out", mp->am_path, mp->am_mnt->mf_mount); + /*dlog("Will background the unmount attempt");*/ +#endif /* DEBUG */ + /* + * Note that we are unmounting this node + */ + mf->mf_flags |= MFF_UNMOUNTING; + run_task(unmount_node_wrap, (voidp) mp, + free_map_if_success, (voidp) mp); + was_backgrounded = 1; +#ifdef DEBUG + dlog("unmount attempt backgrounded"); +#endif /* DEBUG */ + } + } else { +#ifdef DEBUG + dlog("\"%s\" on %s timed out", mp->am_path, mp->am_mnt->mf_mount); + dlog("Trying unmount in foreground"); +#endif + mf->mf_flags |= MFF_UNMOUNTING; + free_map_if_success(unmount_node(mp), 0, (voidp) mp); +#ifdef DEBUG + dlog("unmount attempt done"); +#endif /* DEBUG */ + } + + return was_backgrounded; +} + +void timeout_mp() +{ +#define NEVER (time_t) 0 +#define smallest_t(t1, t2) \ + (t1 != NEVER ? (t2 != NEVER ? (t1 < t2 ? t1 : t2) : t1) : t2) +#define IGNORE_FLAGS (MFF_MOUNTING|MFF_UNMOUNTING|MFF_RESTART) + + int i; + time_t t = NEVER; + time_t now = clocktime(); + int backoff = 0; + +#ifdef DEBUG + dlog("Timing out automount points..."); +#endif /* DEBUG */ + for (i = last_used_map; i >= 0; --i) { + am_node *mp = exported_ap[i]; + mntfs *mf; + /* + * Just continue if nothing mounted, or can't be timed out. + */ + if (!mp || (mp->am_flags & AMF_NOTIMEOUT)) + continue; + /* + * Pick up mounted filesystem + */ + mf = mp->am_mnt; + if (!mf) + continue; + /* + * Don't delete last reference to a restarted filesystem. + */ + if ((mf->mf_flags & MFF_RSTKEEP) && mf->mf_refc == 1) + continue; + /* + * If there is action on this filesystem then ignore it + */ + if (!(mf->mf_flags & IGNORE_FLAGS)) { + int expired = 0; + mf->mf_flags &= ~MFF_WANTTIMO; +#ifdef DEBUG + /*dlog("t is initially @%d, zero in %d secs", t, t - now);*/ +#endif /* DEBUG */ + if (now >= mp->am_ttl) { + if (!backoff) { + expired = 1; + /* + * Move the ttl forward to avoid thrashing effects + * on the next call to timeout! + */ + /* sun's -tw option */ + if (mp->am_timeo_w < 4 * am_timeo_w) + mp->am_timeo_w += am_timeo_w; + mp->am_ttl = now + mp->am_timeo_w; + } else { + /* + * Just backoff this unmount for + * a couple of seconds to avoid + * many multiple unmounts being + * started in parallel. + */ + mp->am_ttl = now + backoff + 1; + } + } + /* + * If the next ttl is smallest, use that + */ + t = smallest_t(t, mp->am_ttl); + +#ifdef DEBUG + /*dlog("after ttl t is @%d, zero in %d secs", t, t - now);*/ +#endif /* DEBUG */ + + if (!mp->am_child && mf->mf_error >= 0 && expired) { + /* + * If the unmount was backgrounded then + * bump the backoff counter. + */ + if (unmount_mp(mp)) { + backoff = 2; +#ifdef DEBUG + /*dlog("backing off subsequent unmounts by at least %d seconds", backoff);*/ +#endif + } + } + } else if (mf->mf_flags & MFF_UNMOUNTING) { + mf->mf_flags |= MFF_WANTTIMO; + } + } + + if (t == NEVER) { +#ifdef DEBUG + dlog("No further timeouts"); +#endif /* DEBUG */ + t = now + ONE_HOUR; + } + + /* + * Sanity check to avoid runaways. + * Absolutely should never get this but + * if you do without this trap amd will thrash. + */ + if (t <= now) { + t = now + 6; /* XXX */ + plog(XLOG_ERROR, "Got a zero interval in timeout_mp()!"); + } + /* + * XXX - when shutting down, make things happen faster + */ + if ((int)amd_state >= (int)Finishing) + t = now + 1; +#ifdef DEBUG + dlog("Next mount timeout in %ds", t - now); +#endif /* DEBUG */ + + timeout_mp_id = timeout(t - now, timeout_mp, 0); + +#undef NEVER +#undef smallest_t +#undef IGNORE_FLAGS +} + +/* + * Cause timeout_mp to be called soonest + */ +void reschedule_timeout_mp() +{ + if (timeout_mp_id) + untimeout(timeout_mp_id); + timeout_mp_id = timeout(0, timeout_mp, 0); +} diff --git a/usr.sbin/amd/amd/mapc.c b/usr.sbin/amd/amd/mapc.c new file mode 100644 index 0000000..2155f19 --- /dev/null +++ b/usr.sbin/amd/amd/mapc.c @@ -0,0 +1,914 @@ +/*- + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * $Id: mapc.c,v 5.2.2.1 1992/02/09 15:08:38 jsp beta $ + */ + +#ifndef lint +static char sccsid[] = "@(#)mapc.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Mount map cache + */ + +#include "am.h" +#ifdef HAS_REGEXP +#include RE_HDR +#endif + +/* + * Hash table size + */ +#define NKVHASH (1 << 2) /* Power of two */ + +/* + * Wildcard key + */ +static char wildcard[] = "*"; + +/* + * Map cache types + * default, none, incremental, all, regexp + * MAPC_RE implies MAPC_ALL and must be numerically + * greater. + */ +#define MAPC_DFLT 0x000 +#define MAPC_NONE 0x001 +#define MAPC_INC 0x002 +#define MAPC_ROOT 0x004 +#define MAPC_ALL 0x010 +#ifdef HAS_REGEXP +#define MAPC_RE 0x020 +#define MAPC_ISRE(m) ((m)->alloc == MAPC_RE) +#else +#define MAPC_ISRE(m) FALSE +#endif +#define MAPC_CACHE_MASK 0x0ff +#define MAPC_SYNC 0x100 + +static struct opt_tab mapc_opt[] = { + { "all", MAPC_ALL }, + { "default", MAPC_DFLT }, + { "inc", MAPC_INC }, + { "mapdefault", MAPC_DFLT }, + { "none", MAPC_NONE }, +#ifdef HAS_REGEXP + { "re", MAPC_RE }, + { "regexp", MAPC_RE }, +#endif + { "sync", MAPC_SYNC }, + { 0, 0 } +}; + +/* + * Lookup recursion + */ +#define MREC_FULL 2 +#define MREC_PART 1 +#define MREC_NONE 0 + +/* + * Cache map operations + */ +typedef void add_fn P((mnt_map*, char*, char*)); +typedef int init_fn P((char*, time_t*)); +typedef int search_fn P((mnt_map*, char*, char*, char**, time_t*)); +typedef int reload_fn P((mnt_map*, char*, add_fn*)); +typedef int mtime_fn P((char*, time_t*)); + +static void mapc_sync P((mnt_map*)); + +/* + * Map type + */ +typedef struct map_type map_type; +struct map_type { + char *name; /* Name of this map type */ + init_fn *init; /* Initialisation */ + reload_fn *reload; /* Reload or fill */ + search_fn *search; /* Search for new entry */ + mtime_fn *mtime; /* Find modify time */ + int def_alloc; /* Default allocation mode */ +}; + +/* + * Key-value pair + */ +typedef struct kv kv; +struct kv { + kv *next; + char *key; + char *val; +}; + +struct mnt_map { + qelem hdr; + int refc; /* Reference count */ + short flags; /* Allocation flags */ + short alloc; /* Allocation mode */ + time_t modify; /* Modify time of map */ + char *map_name; /* Name of this map */ + char *wildcard; /* Wildcard value */ + reload_fn *reload; /* Function to be used for reloads */ + search_fn *search; /* Function to be used for searching */ + mtime_fn *mtime; /* Modify time function */ + kv *kvhash[NKVHASH]; /* Cached data */ +}; + +/* + * Map for root node + */ +static mnt_map *root_map; + +/* + * List of known maps + */ +extern qelem map_list_head; +qelem map_list_head = { &map_list_head, &map_list_head }; + +/* + * Configuration + */ + +/* ROOT MAP */ +static int root_init P((char*, time_t*)); + +/* FILE MAPS */ +#ifdef HAS_FILE_MAPS +extern int file_init P((char*, time_t*)); +extern int file_reload P((mnt_map*, char*, add_fn*)); +extern int file_search P((mnt_map*, char*, char*, char**, time_t*)); +extern int file_mtime P((char*, time_t*)); +#endif /* HAS_FILE_MAPS */ + +/* Network Information Service (NIS) MAPS */ +#ifdef HAS_NIS_MAPS +extern int nis_init P((char*, time_t*)); +#ifdef HAS_NIS_RELOAD +extern int nis_reload P((mnt_map*, char*, add_fn*)); +#else +#define nis_reload error_reload +#endif +extern int nis_search P((mnt_map*, char*, char*, char**, time_t*)); +#define nis_mtime nis_init +#endif /* HAS_NIS_MAPS */ + +/* NDBM MAPS */ +#ifdef HAS_NDBM_MAPS +#ifdef OS_HAS_NDBM +extern int ndbm_init P((char*, time_t*)); +extern int ndbm_search P((mnt_map*, char*, char*, char**, time_t*)); +#define ndbm_mtime ndbm_init +#endif /* OS_HAS_NDBM */ +#endif /* HAS_NDBM_MAPS */ + +/* PASSWD MAPS */ +#ifdef HAS_PASSWD_MAPS +extern int passwd_init P((char*, time_t*)); +extern int passwd_search P((mnt_map*, char*, char*, char**, time_t*)); +#endif /* HAS_PASSWD_MAPS */ + +/* HESIOD MAPS */ +#ifdef HAS_HESIOD_MAPS +extern int hesiod_init P((char*, time_t*)); +#ifdef HAS_HESIOD_RELOAD +extern int hesiod_reload P((mnt_map*, char*, add_fn*)); +#else +#define hesiod_reload error_reload +#endif +extern int hesiod_search P((mnt_map*, char*, char*, char**, time_t*)); +#endif /* HAS_HESIOD_MAPS */ + +/* UNION MAPS */ +#ifdef HAS_UNION_MAPS +extern int union_init P((char*, time_t*)); +extern int union_search P((mnt_map*, char*, char*, char**, time_t*)); +extern int union_reload P((mnt_map*, char*, add_fn*)); +#endif /* HAS_UNION_MAPS */ + +/* ERROR MAP */ +static int error_init P((char*, time_t*)); +static int error_reload P((mnt_map*, char*, add_fn*)); +static int error_search P((mnt_map*, char*, char*, char**, time_t*)); +static int error_mtime P((char*, time_t*)); + +static map_type maptypes[] = { + { "root", root_init, error_reload, error_search, error_mtime, MAPC_ROOT }, + +#ifdef HAS_PASSWD_MAPS + { "passwd", passwd_init, error_reload, passwd_search, error_mtime, MAPC_INC }, +#endif + +#ifdef HAS_HESIOD_MAPS + { "hesiod", hesiod_init, hesiod_reload, hesiod_search, error_mtime, MAPC_ALL }, +#endif + +#ifdef HAS_UNION_MAPS + { "union", union_init, union_reload, union_search, error_mtime, MAPC_ALL }, +#endif + +#ifdef HAS_NIS_MAPS + { "nis", nis_init, nis_reload, nis_search, nis_mtime, MAPC_INC }, +#endif + +#ifdef HAS_NDBM_MAPS + { "ndbm", ndbm_init, error_reload, ndbm_search, ndbm_mtime, MAPC_INC }, +#endif + +#ifdef HAS_FILE_MAPS + { "file", file_init, file_reload, file_search, file_mtime, MAPC_ALL }, +#endif + + { "error", error_init, error_reload, error_search, error_mtime, MAPC_NONE }, +}; + +/* + * Hash function + */ +static unsigned int kvhash_of P((char *key)); +static unsigned int kvhash_of(key) +char *key; +{ + unsigned int i, j; + + for (i = 0; j = *key++; i += j) + ; + + return i % NKVHASH; +} + +void mapc_showtypes P((FILE *fp)); +void mapc_showtypes(fp) +FILE *fp; +{ + map_type *mt; + char *sep = ""; + for (mt = maptypes; mt < maptypes+sizeof(maptypes)/sizeof(maptypes[0]); mt++) { + fprintf(fp, "%s%s", sep, mt->name); + sep = ", "; + } +} + +static Const char *reg_error = "?"; +void regerror P((Const char *m)); +void regerror(m) +Const char *m; +{ + reg_error = m; +} + +/* + * Add key and val to the map m. + * key and val are assumed to be safe copies + */ +void mapc_add_kv P((mnt_map *m, char *key, char *val)); +void mapc_add_kv(m, key, val) +mnt_map *m; +char *key; +char *val; +{ + kv **h; + kv *n; + int hash = kvhash_of(key); + +#ifdef DEBUG + dlog("add_kv: %s -> %s", key, val); +#endif + +#ifdef HAS_REGEXP + if (MAPC_ISRE(m)) { + char keyb[MAXPATHLEN]; + regexp *re; + /* + * Make sure the string is bound to the start and end + */ + sprintf(keyb, "^%s$", key); + re = regcomp(keyb); + if (re == 0) { + plog(XLOG_USER, "error compiling RE \"%s\": %s", keyb, reg_error); + return; + } else { + free(key); + key = (char *) re; + } + } +#endif + + h = &m->kvhash[hash]; + n = ALLOC(kv); + n->key = key; + n->val = val; + n->next = *h; + *h = n; +} + +void mapc_repl_kv P((mnt_map *m, char *key, char *val)); +void mapc_repl_kv(m, key, val) +mnt_map *m; +char *key; +char *val; +{ + kv *k; + + /* + * Compute the hash table offset + */ + k = m->kvhash[kvhash_of(key)]; + + /* + * Scan the linked list for the key + */ + while (k && !FSTREQ(k->key, key)) + k = k->next; + + if (k) { + free(k->val); + k->val = val; + } else { + mapc_add_kv(m, key, val); + } + +} + +/* + * Search a map for a key. + * Calls map specific search routine. + * While map is out of date, keep re-syncing. + */ +static int search_map P((mnt_map *m, char *key, char **valp)); +static int search_map(m, key, valp) +mnt_map *m; +char *key; +char **valp; +{ + int rc; + do { + rc = (*m->search)(m, m->map_name, key, valp, &m->modify); + if (rc < 0) { + plog(XLOG_MAP, "Re-synchronizing cache for map %s", m->map_name); + mapc_sync(m); + } + } while (rc < 0); + + return rc; +} + +/* + * Do a wildcard lookup in the map and + * save the result. + */ +static void mapc_find_wildcard P((mnt_map *m)); +static void mapc_find_wildcard(m) +mnt_map *m; +{ + /* + * Attempt to find the wildcard entry + */ + int rc = search_map(m, wildcard, &m->wildcard); + + if (rc != 0) + m->wildcard = 0; +} + +/* + * Make a duplicate reference to an existing map + */ +#define mapc_dup(m) ((m)->refc++, (m)) + +/* + * Do a map reload + */ +static int mapc_reload_map(m) +mnt_map *m; +{ + int error; +#ifdef DEBUG + dlog("calling map reload on %s", m->map_name); +#endif + error = (*m->reload)(m, m->map_name, mapc_add_kv); + if (error) + return error; + m->wildcard = 0; +#ifdef DEBUG + dlog("calling mapc_search for wildcard"); +#endif + error = mapc_search(m, wildcard, &m->wildcard); + if (error) + m->wildcard = 0; + return 0; +} + +/* + * Create a new map + */ +static mnt_map *mapc_create P((char *map, char *opt)); +static mnt_map *mapc_create(map, opt) +char *map; +char *opt; +{ + mnt_map *m = ALLOC(mnt_map); + map_type *mt; + time_t modify; + int alloc = 0; + + (void) cmdoption(opt, mapc_opt, &alloc); + + for (mt = maptypes; mt < maptypes+sizeof(maptypes)/sizeof(maptypes[0]); mt++) + if ((*mt->init)(map, &modify) == 0) + break; + /* assert: mt in maptypes */ + + m->flags = alloc & ~MAPC_CACHE_MASK; + alloc &= MAPC_CACHE_MASK; + + if (alloc == MAPC_DFLT) + alloc = mt->def_alloc; + switch (alloc) { + default: + plog(XLOG_USER, "Ambiguous map cache type \"%s\"; using \"inc\"", opt); + alloc = MAPC_INC; + /* fallthrough... */ + case MAPC_NONE: + case MAPC_INC: + case MAPC_ROOT: + break; + case MAPC_ALL: + /* + * If there is no support for reload and it was requested + * then back off to incremental instead. + */ + if (mt->reload == error_reload) { + plog(XLOG_WARNING, "Map type \"%s\" does not support cache type \"all\"; using \"inc\"", mt->name); + alloc = MAPC_INC; + } + break; +#ifdef HAS_REGEXP + case MAPC_RE: + if (mt->reload == error_reload) { + plog(XLOG_WARNING, "Map type \"%s\" does not support cache type \"re\"", mt->name); + mt = &maptypes[sizeof(maptypes)/sizeof(maptypes[0]) - 1]; + /* assert: mt->name == "error" */ + } + break; +#endif + } + +#ifdef DEBUG + dlog("Map for %s coming from maptype %s", map, mt->name); +#endif + + m->alloc = alloc; + m->reload = mt->reload; + m->modify = modify; + m->search = alloc >= MAPC_ALL ? error_search : mt->search; + m->mtime = mt->mtime; + bzero((voidp) m->kvhash, sizeof(m->kvhash)); + m->map_name = strdup(map); + m->refc = 1; + m->wildcard = 0; + + /* + * synchronize cache with reality + */ + mapc_sync(m); + + return m; +} + +/* + * Free the cached data in a map + */ +static void mapc_clear P((mnt_map *m)); +static void mapc_clear(m) +mnt_map *m; +{ + int i; + + /* + * For each of the hash slots, chain + * along free'ing the data. + */ + for (i = 0; i < NKVHASH; i++) { + kv *k = m->kvhash[i]; + while (k) { + kv *n = k->next; + free((voidp) k->key); + if (k->val) + free((voidp) k->val); + free((voidp) k); + k = n; + } + } + /* + * Zero the hash slots + */ + bzero((voidp) m->kvhash, sizeof(m->kvhash)); + /* + * Free the wildcard if it exists + */ + if (m->wildcard) { + free(m->wildcard); + m->wildcard = 0; + } +} + +/* + * Find a map, or create one if it does not exist + */ +mnt_map *mapc_find P((char *map, char *opt)); +mnt_map *mapc_find(map, opt) +char *map; +char *opt; +{ + mnt_map *m; + + /* + * Search the list of known maps to see if + * it has already been loaded. If it is found + * then return a duplicate reference to it. + * Otherwise make a new map as required and + * add it to the list of maps + */ + ITER(m, mnt_map, &map_list_head) + if (STREQ(m->map_name, map)) + return mapc_dup(m); + + m = mapc_create(map, opt); + ins_que(&m->hdr, &map_list_head); + return m; +} + +/* + * Free a map. + */ +void mapc_free P((mnt_map *m)); +void mapc_free(m) +mnt_map *m; +{ + /* + * Decrement the reference count. + * If the reference count hits zero + * then throw the map away. + */ + if (m && --m->refc == 0) { + mapc_clear(m); + free((voidp) m->map_name); + rem_que(&m->hdr); + free((voidp) m); + } +} + +/* + * Search the map for the key. + * Put a safe copy in *pval or return + * an error code + */ +int mapc_meta_search P((mnt_map *m, char *key, char **pval, int recurse)); +int mapc_meta_search(m, key, pval, recurse) +mnt_map *m; +char *key; +char **pval; +int recurse; +{ + int error = 0; + kv *k = 0; + + /* + * Firewall + */ + if (!m) { + plog(XLOG_ERROR, "Null map request for %s", key); + return ENOENT; + } + + if (m->flags & MAPC_SYNC) { + /* + * Get modify time... + */ + time_t t; + error = (*m->mtime)(m->map_name, &t); + if (error || t > m->modify) { + m->modify = t; + plog(XLOG_INFO, "Map %s is out of date", m->map_name); + mapc_sync(m); + } + } + + if (!MAPC_ISRE(m)) { + /* + * Compute the hash table offset + */ + k = m->kvhash[kvhash_of(key)]; + + /* + * Scan the linked list for the key + */ + while (k && !FSTREQ(k->key, key)) k = k->next; + + } +#ifdef HAS_REGEXP + else if (recurse == MREC_FULL) { + /* + * Try for an RE match against the entire map. + * Note that this will be done in a "random" + * order. + */ + + int i; + + for (i = 0; i < NKVHASH; i++) { + k = m->kvhash[i]; + while (k) { + if (regexec((regexp *) k->key, key)) + break; + k = k->next; + } + if (k) + break; + } + } +#endif + + /* + * If found then take a copy + */ + if (k) { + if (k->val) + *pval = strdup(k->val); + else + error = ENOENT; + } else if (m->alloc >= MAPC_ALL) { + /* + * If the entire map is cached then this + * key does not exist. + */ + error = ENOENT; + } else { + /* + * Otherwise search the map. If we are + * in incremental mode then add the key + * to the cache. + */ + error = search_map(m, key, pval); + if (!error && m->alloc == MAPC_INC) + mapc_add_kv(m, strdup(key), strdup(*pval)); + } + + /* + * If an error, and a wildcard exists, + * and the key is not internal then + * return a copy of the wildcard. + */ + if (error > 0) { + if (recurse == MREC_FULL && !MAPC_ISRE(m)) { + char wildname[MAXPATHLEN]; + char *subp; + if (*key == '/') + return error; + /* + * Keep chopping sub-directories from the RHS + * and replacing with "/ *" and repeat the lookup. + * For example: + * "src/gnu/gcc" -> "src / gnu / *" -> "src / *" + */ + strcpy(wildname, key); + while (error && (subp = strrchr(wildname, '/'))) { + strcpy(subp, "/*"); +#ifdef DEBUG + dlog("mapc recurses on %s", wildname); +#endif + error = mapc_meta_search(m, wildname, pval, MREC_PART); + if (error) + *subp = 0; + } + if (error > 0 && m->wildcard) { + *pval = strdup(m->wildcard); + error = 0; + } + } + } + + return error; +} + +int mapc_search P((mnt_map *m, char *key, char **pval)); +int mapc_search(m, key, pval) +mnt_map *m; +char *key; +char **pval; +{ + return mapc_meta_search(m, key, pval, MREC_FULL); +} + +/* + * Get map cache in sync with physical representation + */ +static void mapc_sync P((mnt_map *m)); +static void mapc_sync(m) +mnt_map *m; +{ + if (m->alloc != MAPC_ROOT) { + mapc_clear(m); + + if (m->alloc >= MAPC_ALL) + if (mapc_reload_map(m)) + m->alloc = MAPC_INC; + /* + * Attempt to find the wildcard entry + */ + if (m->alloc < MAPC_ALL) + mapc_find_wildcard(m); + } +} + +/* + * Reload all the maps + * Called when Amd gets hit by a SIGHUP. + */ +void mapc_reload(P_void); +void mapc_reload() +{ + mnt_map *m; + + /* + * For all the maps, + * Throw away the existing information. + * Do a reload + * Find the wildcard + */ + ITER(m, mnt_map, &map_list_head) + mapc_sync(m); +} + +/* + * Root map. + * The root map is used to bootstrap amd. + * All the require top-level mounts are added + * into the root map and then the map is iterated + * and a lookup is done on all the mount points. + * This causes the top level mounts to be automounted. + */ + +static int root_init P((char *map, time_t *tp)); +static int root_init(map, tp) +char *map; +time_t *tp; +{ + *tp = clocktime(); + return strcmp(map, ROOT_MAP) == 0 ? 0 : ENOENT; +} + +/* + * Add a new entry to the root map + * + * dir - directory (key) + * opts - mount options + * map - map name + */ +void root_newmap P((char *dir, char *opts, char *map)); +void root_newmap(dir, opts, map) +char *dir; +char *opts; +char *map; +{ + char str[MAXPATHLEN]; + + /* + * First make sure we have a root map to talk about... + */ + if (!root_map) + root_map = mapc_find(ROOT_MAP, "mapdefault"); + + /* + * Then add the entry... + */ + dir = strdup(dir); + if (map) + sprintf(str, "cache:=mapdefault;type:=toplvl;fs:=\"%s\";%s", + map, opts ? opts : ""); + else + strcpy(str, opts); + mapc_repl_kv(root_map, dir, strdup(str)); +} + +int mapc_keyiter P((mnt_map *m, void (*fn)(char*,voidp), voidp arg)); +int mapc_keyiter(m, fn, arg) +mnt_map *m; +void (*fn)P((char*, voidp)); +voidp arg; +{ + int i; + int c = 0; + + for (i = 0; i < NKVHASH; i++) { + kv *k = m->kvhash[i]; + while (k) { + (*fn)(k->key, arg); + k = k->next; + c++; + } + } + + return c; +} + +/* + * Iterate of the the root map + * and call (*fn)() on the key + * of all the nodes. + * Finally throw away the root map. + */ +int root_keyiter P((void (*fn)(char*,voidp), voidp arg)); +int root_keyiter(fn, arg) +void (*fn)P((char*,voidp)); +voidp arg; +{ + if (root_map) { + int c = mapc_keyiter(root_map, fn, arg); +#ifdef notdef + mapc_free(root_map); + root_map = 0; +#endif + return c; + } + return 0; +} + +/* + * Error map + */ +static int error_init P((char *map, time_t *tp)); +static int error_init(map, tp) +char *map; +time_t *tp; +{ + plog(XLOG_USER, "No source data for map %s", map); + *tp = 0; + return 0; +} + +/*ARGSUSED*/ +static int error_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp)); +static int error_search(m, map, key, pval, tp) +mnt_map *m; +char *map; +char *key; +char **pval; +time_t *tp; +{ + return ENOENT; +} + +/*ARGSUSED*/ +static int error_reload P((mnt_map *m, char *map, add_fn *fn)); +static int error_reload(m, map, fn) +mnt_map *m; +char *map; +add_fn *fn; +{ + return ENOENT; +} + +static int error_mtime P((char *map, time_t *tp)); +static int error_mtime(map, tp) +char *map; +time_t *tp; +{ + *tp = 0; + return 0; +} diff --git a/usr.sbin/amd/amd/misc_rpc.c b/usr.sbin/amd/amd/misc_rpc.c new file mode 100644 index 0000000..0fb10c8 --- /dev/null +++ b/usr.sbin/amd/amd/misc_rpc.c @@ -0,0 +1,333 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)misc_rpc.c 8.1 (Berkeley) 6/6/93 + * + * $Id: misc_rpc.c,v 5.2.2.1 1992/02/09 15:08:40 jsp beta $ + * + */ + +/* + * Additions to Sun RPC. + */ + +#include "am.h" + +void rpc_msg_init P((struct rpc_msg *mp, u_long prog, u_long vers, u_long proc)); +void rpc_msg_init(mp, prog, vers, proc) +struct rpc_msg *mp; +unsigned long prog, vers, proc; +{ + /* + * Initialise the message + */ + bzero((voidp) mp, sizeof(*mp)); + mp->rm_xid = 0; + mp->rm_direction = CALL; + mp->rm_call.cb_rpcvers = RPC_MSG_VERSION; + mp->rm_call.cb_prog = prog; + mp->rm_call.cb_vers = vers; + mp->rm_call.cb_proc = proc; +} + +/* + * Field reply to call to mountd + */ +int pickup_rpc_reply P((voidp pkt, int len, voidp where, xdrproc_t where_xdr)); +int pickup_rpc_reply(pkt, len, where, where_xdr) +voidp pkt; +int len; +voidp where; +xdrproc_t where_xdr; +{ + XDR reply_xdr; + int ok; + struct rpc_err err; + struct rpc_msg reply_msg; + int error = 0; + + /*bzero((voidp) &err, sizeof(err));*/ + bzero((voidp) &reply_msg, sizeof(reply_msg)); + + reply_msg.acpted_rply.ar_results.where = (caddr_t) where; + reply_msg.acpted_rply.ar_results.proc = where_xdr; + + xdrmem_create(&reply_xdr, pkt, len, XDR_DECODE); + + ok = xdr_replymsg(&reply_xdr, &reply_msg); + if (!ok) { + error = EIO; + goto drop; + } + _seterr_reply(&reply_msg, &err); + if (err.re_status != RPC_SUCCESS) { + error = EIO; + goto drop; + } + +drop: + if (reply_msg.rm_reply.rp_stat == MSG_ACCEPTED && + reply_msg.acpted_rply.ar_verf.oa_base) { + reply_xdr.x_op = XDR_FREE; + (void)xdr_opaque_auth(&reply_xdr, + &reply_msg.acpted_rply.ar_verf); + } + xdr_destroy(&reply_xdr); + + return error; +} + +int make_rpc_packet P((char *buf, int buflen, unsigned long proc, + struct rpc_msg *mp, voidp arg, xdrproc_t arg_xdr, AUTH *auth)); +int make_rpc_packet(buf, buflen, proc, mp, arg, arg_xdr, auth) +char *buf; +int buflen; +unsigned long proc; +struct rpc_msg *mp; +voidp arg; +xdrproc_t arg_xdr; +AUTH *auth; +{ + XDR msg_xdr; + int len; + + xdrmem_create(&msg_xdr, buf, buflen, XDR_ENCODE); + /* + * Basic protocol header + */ + if (!xdr_callhdr(&msg_xdr, mp)) + return -EIO; + /* + * Called procedure number + */ + if (!xdr_enum(&msg_xdr, &proc)) + return -EIO; + /* + * Authorization + */ + if (!AUTH_MARSHALL(auth, &msg_xdr)) + return -EIO; + /* + * Arguments + */ + if (!(*arg_xdr)(&msg_xdr, arg)) + return -EIO; + /* + * Determine length + */ + len = xdr_getpos(&msg_xdr); + /* + * Throw away xdr + */ + xdr_destroy(&msg_xdr); + return len; +} + + +/* + * Early RPC seems to be missing these.. + * Extracted from the RPC 3.9 sources as indicated + */ + +#ifdef NEED_XDR_POINTER +/* @(#)xdr_reference.c 1.1 87/11/04 3.9 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + + +/* + * xdr_pointer(): + * + * XDR a pointer to a possibly recursive data structure. This + * differs with xdr_reference in that it can serialize/deserialiaze + * trees correctly. + * + * What's sent is actually a union: + * + * union object_pointer switch (boolean b) { + * case TRUE: object_data data; + * case FALSE: void nothing; + * } + * + * > objpp: Pointer to the pointer to the object. + * > obj_size: size of the object. + * > xdr_obj: routine to XDR an object. + * + */ +bool_t +xdr_pointer(xdrs,objpp,obj_size,xdr_obj) + register XDR *xdrs; + char **objpp; + u_int obj_size; + xdrproc_t xdr_obj; +{ + + bool_t more_data; + + more_data = (*objpp != NULL); + if (! xdr_bool(xdrs,&more_data)) { + return (FALSE); + } + if (! more_data) { + *objpp = NULL; + return (TRUE); + } + return (xdr_reference(xdrs,objpp,obj_size,xdr_obj)); +} +#endif /* NEED_XDR_POINTER */ + +#ifdef NEED_CLNT_SPERRNO +/* @(#)clnt_perror.c 1.1 87/11/04 3.9 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +struct rpc_errtab { + enum clnt_stat status; + char *message; +}; + +static struct rpc_errtab rpc_errlist[] = { + { RPC_SUCCESS, + "RPC: Success" }, + { RPC_CANTENCODEARGS, + "RPC: Can't encode arguments" }, + { RPC_CANTDECODERES, + "RPC: Can't decode result" }, + { RPC_CANTSEND, + "RPC: Unable to send" }, + { RPC_CANTRECV, + "RPC: Unable to receive" }, + { RPC_TIMEDOUT, + "RPC: Timed out" }, + { RPC_VERSMISMATCH, + "RPC: Incompatible versions of RPC" }, + { RPC_AUTHERROR, + "RPC: Authentication error" }, + { RPC_PROGUNAVAIL, + "RPC: Program unavailable" }, + { RPC_PROGVERSMISMATCH, + "RPC: Program/version mismatch" }, + { RPC_PROCUNAVAIL, + "RPC: Procedure unavailable" }, + { RPC_CANTDECODEARGS, + "RPC: Server can't decode arguments" }, + { RPC_SYSTEMERROR, + "RPC: Remote system error" }, + { RPC_UNKNOWNHOST, + "RPC: Unknown host" }, +/* { RPC_UNKNOWNPROTO, + "RPC: Unknown protocol" },*/ + { RPC_PMAPFAILURE, + "RPC: Port mapper failure" }, + { RPC_PROGNOTREGISTERED, + "RPC: Program not registered"}, + { RPC_FAILED, + "RPC: Failed (unspecified error)"} +}; + + +/* + * This interface for use by clntrpc + */ +char * +clnt_sperrno(stat) + enum clnt_stat stat; +{ + int i; + + for (i = 0; i < sizeof(rpc_errlist)/sizeof(struct rpc_errtab); i++) { + if (rpc_errlist[i].status == stat) { + return (rpc_errlist[i].message); + } + } + return ("RPC: (unknown error code)"); +} + +#endif /* NEED_CLNT_SPERRNO */ + diff --git a/usr.sbin/amd/amd/mntfs.c b/usr.sbin/amd/amd/mntfs.c new file mode 100644 index 0000000..ef8f17f --- /dev/null +++ b/usr.sbin/amd/amd/mntfs.c @@ -0,0 +1,367 @@ +/*- + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * $Id: mntfs.c,v 5.2.2.1 1992/02/09 15:08:42 jsp beta $ + */ + +#ifndef lint +static char sccsid[] = "@(#)mntfs.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + + +#include "am.h" + +extern qelem mfhead; +qelem mfhead = { &mfhead, &mfhead }; + +int mntfs_allocated; + +#ifdef notdef +/* + * This is the default attributes field which + * is copied into every new node to be created. + * The individual filesystem fs_init() routines + * patch the copy to represent the particular + * details for the relevant filesystem type + */ +static struct fattr gen_fattr = { + NFDIR, /* type */ + NFSMODE_DIR | 0555, /* mode */ + 2, /* nlink */ + 0, /* uid */ + 0, /* gid */ + 512, /* size */ + 4096, /* blocksize */ + 0, /* rdev */ + 1, /* blocks */ + 0, /* fsid */ + 0, /* fileid */ + { 0, 0 }, /* atime */ + { 0, 0 }, /* mtime */ + { 0, 0 }, /* ctime */ +}; +#endif /* notdef */ + +mntfs *dup_mntfs(mf) +mntfs *mf; +{ + if (mf->mf_refc == 0) { + if (mf->mf_cid) + untimeout(mf->mf_cid); + mf->mf_cid = 0; +#ifdef notdef + mf->mf_error = -1; + mf->mf_flags &= ~MFF_ERROR; +#endif + } + mf->mf_refc++; + return mf; +} + +static void init_mntfs P((mntfs *mf, am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)); +static void init_mntfs(mf, ops, mo, mp, info, auto_opts, mopts, remopts) +mntfs *mf; +am_ops *ops; +am_opts *mo; +char *mp; +char *info; +char *auto_opts; +char *mopts; +char *remopts; +{ + mf->mf_ops = ops; + mf->mf_fo = mo; + mf->mf_mount = strdup(mp); + mf->mf_info = strdup(info); + mf->mf_auto = strdup(auto_opts); + mf->mf_mopts = strdup(mopts); + mf->mf_remopts = strdup(remopts); + mf->mf_refc = 1; + mf->mf_flags = 0; + mf->mf_error = -1; + mf->mf_cid = 0; + mf->mf_private = 0; + mf->mf_prfree = 0; +#ifdef notdef + mf->mf_attr.status = NFS_OK; + mf->mf_fattr = gen_fattr; + mf->mf_fattr.fsid = 42; + mf->mf_fattr.fileid = 0; + mf->mf_fattr.atime.seconds = clocktime(); + mf->mf_fattr.atime.useconds = 0; + mf->mf_fattr.mtime = mf->mf_fattr.ctime = mf->mf_fattr.atime; +#endif + + if (ops->ffserver) + mf->mf_server = (*ops->ffserver)(mf); + else + mf->mf_server = 0; +} + +static mntfs *alloc_mntfs P((am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)); +static mntfs *alloc_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts) +am_ops *ops; +am_opts *mo; +char *mp; +char *info; +char *auto_opts; +char *mopts; +char *remopts; +{ + mntfs *mf = ALLOC(mntfs); + init_mntfs(mf, ops, mo, mp, info, auto_opts, mopts, remopts); + ins_que(&mf->mf_q, &mfhead); + mntfs_allocated++; + + return mf; +} + +mntfs *find_mntfs P((am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)); +mntfs *find_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts) +am_ops *ops; +am_opts *mo; +char *mp; +char *info; +char *auto_opts; +char *mopts; +char *remopts; +{ + mntfs *mf; + +#ifdef DEBUG + dlog("Locating mntfs reference to %s", mp); +#endif /* DEBUG */ + ITER(mf, mntfs, &mfhead) { + if (STREQ(mf->mf_mount, mp)) { + /* + * Handle cases where error ops are involved + */ + if (ops == &efs_ops) { + /* + * If the existing ops are not efs_ops + * then continue... + */ + if (mf->mf_ops != &efs_ops) + continue; + } else /* ops != &efs_ops */ { + /* + * If the existing ops are efs_ops + * then continue... + */ + if (mf->mf_ops == &efs_ops) + continue; + } + + if ((mf->mf_flags & MFF_RESTART) && amd_state == Run) { + /* + * Restart a previously mounted filesystem. + */ + mntfs *mf2 = alloc_mntfs(&ifs_ops, mo, mp, info, auto_opts, mopts, remopts); +#ifdef DEBUG + dlog("Restarting filesystem %s", mf->mf_mount); +#endif /* DEBUG */ + /* + * Remember who we are restarting + */ + mf2->mf_private = (voidp) dup_mntfs(mf); + mf2->mf_prfree = free_mntfs; + return mf2; + } + mf->mf_fo = mo; + if (!(mf->mf_flags & (MFF_MOUNTED|MFF_MOUNTING|MFF_UNMOUNTING))) { + fserver *fs; + mf->mf_flags &= ~MFF_ERROR; + mf->mf_error = -1; + mf->mf_auto = strealloc(mf->mf_auto, auto_opts); + mf->mf_mopts = strealloc(mf->mf_mopts, mopts); + mf->mf_remopts = strealloc(mf->mf_remopts, remopts); + mf->mf_info = strealloc(mf->mf_info, info); + if (mf->mf_private && mf->mf_prfree) { + (*mf->mf_prfree)(mf->mf_private); + mf->mf_private = 0; + } + fs = ops->ffserver ? (*ops->ffserver)(mf) : (fserver *) 0; + if (mf->mf_server) + free_srvr(mf->mf_server); + mf->mf_server = fs; + } + return dup_mntfs(mf); + } + } + + return alloc_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts); +} + +mntfs *new_mntfs() +{ + return alloc_mntfs(&efs_ops, (am_opts *) 0, "//nil//", ".", "", "", ""); +} + +static void uninit_mntfs(mf, rmd) +mntfs *mf; +int rmd; +{ + if (mf->mf_mount) free((voidp) mf->mf_mount); + if (mf->mf_auto) free((voidp) mf->mf_auto); + if (mf->mf_mopts) free((voidp) mf->mf_mopts); + if (mf->mf_remopts) free((voidp) mf->mf_remopts); + if (mf->mf_info) free((voidp) mf->mf_info); + if (mf->mf_private && mf->mf_prfree) + (*mf->mf_prfree)(mf->mf_private); + /* + * Clean up any directories that were made + */ + if (rmd && (mf->mf_flags & MFF_MKMNT)) + rmdirs(mf->mf_mount); + + /* + * Clean up the file server + */ + if (mf->mf_server) + free_srvr(mf->mf_server); + + /* + * Don't do a callback on this mount + */ + if (mf->mf_cid) { + untimeout(mf->mf_cid); + mf->mf_cid = 0; + } +} + +static void discard_mntfs(mf) +mntfs *mf; +{ + rem_que(&mf->mf_q); + /* + * Free memory + */ + uninit_mntfs(mf, TRUE); + free((voidp) mf); + + --mntfs_allocated; +} + +void flush_mntfs() +{ + mntfs *mf; + + mf = FIRST(mntfs, &mfhead); + while (mf != HEAD(mntfs, &mfhead)) { + mntfs *mf2 = mf; + mf = NEXT(mntfs, mf); + if (mf2->mf_refc == 0 && mf2->mf_cid) + discard_mntfs(mf2); + } +} + +void free_mntfs(mf) +mntfs *mf; +{ + if (--mf->mf_refc == 0) { + if (mf->mf_flags & MFF_MOUNTED) { + int quoted; + mf->mf_flags &= ~MFF_MOUNTED; + + /* + * Record for posterity + */ + quoted = strchr(mf->mf_info, ' ') != 0; /* cheap */ + plog(XLOG_INFO, "%s%s%s %sed fstype %s from %s", + quoted ? "\"" : "", + mf->mf_info, + quoted ? "\"" : "", + mf->mf_error ? "discard" : "unmount", + mf->mf_ops->fs_type, mf->mf_mount); + } + + if (mf->mf_ops->fs_flags & FS_DISCARD) { +#ifdef DEBUG + dlog("Immediately discarding mntfs for %s", mf->mf_mount); +#endif /* DEBUG */ + discard_mntfs(mf); + } else { +#ifdef DEBUG + if (mf->mf_flags & MFF_RESTART) { + dlog("Discarding remount hook for %s", mf->mf_mount); + } else { + dlog("Discarding last mntfs reference to %s fstype %s", + mf->mf_mount, mf->mf_ops->fs_type); + } + if (mf->mf_flags & (MFF_MOUNTED|MFF_MOUNTING|MFF_UNMOUNTING)) + dlog("mntfs reference for %s still active", mf->mf_mount); +#endif /* DEBUG */ + mf->mf_cid = timeout(ALLOWED_MOUNT_TIME, discard_mntfs, (voidp) mf); + } + } +} + +mntfs *realloc_mntfs P((mntfs *mf, am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)); +mntfs *realloc_mntfs(mf, ops, mo, mp, info, auto_opts, mopts, remopts) +mntfs *mf; +am_ops *ops; +am_opts *mo; +char *mp; +char *info; +char *auto_opts; +char *mopts; +char *remopts; +{ + mntfs *mf2; + if (mf->mf_refc == 1 && mf->mf_ops == &ifs_ops && STREQ(mf->mf_mount, mp)) { + /* + * If we are inheriting then just return + * the same node... + */ + return mf; + } + + /* + * Re-use the existing mntfs if it is mounted. + * This traps a race in nfsx. + */ + if (mf->mf_ops != &efs_ops && + (mf->mf_flags & MFF_MOUNTED) && + !FSRV_ISDOWN(mf->mf_server)) { + mf->mf_fo = mo; + return mf; + } + + mf2 = find_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts); + free_mntfs(mf); + return mf2; +} diff --git a/usr.sbin/amd/amd/mount_fs.c b/usr.sbin/amd/amd/mount_fs.c new file mode 100644 index 0000000..43a0625 --- /dev/null +++ b/usr.sbin/amd/amd/mount_fs.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)mount_fs.c 8.1 (Berkeley) 6/6/93 + * + * $Id: mount_fs.c,v 5.2.2.2 1992/05/31 16:35:45 jsp Exp $ + * + */ + +#include "am.h" +#ifdef NFS_3 +typedef nfs_fh fhandle_t; +#endif /* NFS_3 */ +#include + +#include + +/* + * Standard mount flags + */ +#ifdef hpux +/* + * HP-UX has an annoying feature of printing + * error msgs on /dev/console + */ +#undef M_NOSUID +#endif /* hpux */ + +struct opt_tab mnt_flags[] = { + { "ro", M_RDONLY }, +#ifdef M_CACHE + { "nocache", M_NOCACHE }, +#endif /* M_CACHE */ +#ifdef M_GRPID + { "grpid", M_GRPID }, +#endif /* M_GRPID */ +#ifdef M_MULTI + { "multi", M_MULTI }, +#endif /* M_MULTI */ +#ifdef M_NODEV + { "nodev", M_NODEV }, +#endif /* M_NODEV */ +#ifdef M_NOEXEC + { "noexec", M_NOEXEC }, +#endif /* M_NOEXEC */ +#ifdef M_NOSUB + { "nosub", M_NOSUB }, +#endif /* M_NOSUB */ +#ifdef M_NOSUID + { "nosuid", M_NOSUID }, +#endif /* M_NOSUID */ +#ifdef M_SYNC + { "sync", M_SYNC }, +#endif /* M_SYNC */ + { 0, 0 } +}; + +int compute_mount_flags(mnt) +struct mntent *mnt; +{ + struct opt_tab *opt; + int flags; +#ifdef NFS_4 + flags = M_NEWTYPE; +#else + flags = 0; +#endif /* NFS_4 */ + + /* + * Crack basic mount options + */ + for (opt = mnt_flags; opt->opt; opt++) + flags |= hasmntopt(mnt, opt->opt) ? opt->flag : 0; + + return flags; +} + +int mount_fs P((struct mntent *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type)); +int mount_fs(mnt, flags, mnt_data, retry, type) +struct mntent *mnt; +int flags; +caddr_t mnt_data; +int retry; +MTYPE_TYPE type; +{ + int error = 0; +#ifdef MNTINFO_DEV + struct stat stb; + char *xopts = 0; +#endif /* MNTINFO_DEV */ + +#ifdef DEBUG +#ifdef NFS_4 + dlog("%s fstype %s (%s) flags %#x (%s)", + mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts); +#else + dlog("%s fstype %d (%s) flags %#x (%s)", + mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts); +#endif /* NFS_4 */ +#endif /* DEBUG */ + + /* + * Fake some mount table entries for the automounter + */ +#ifdef FASCIST_DF_COMMAND + /* + * Some systems have a df command which blows up when + * presented with an unknown mount type. + */ + if (STREQ(mnt->mnt_type, MNTTYPE_AUTO)) { + /* + * Try it with the normal name + */ + mnt->mnt_type = FASCIST_DF_COMMAND; + } +#endif /* FASCIST_DF_COMMAND */ + +again: + clock_valid = 0; + error = MOUNT_TRAP(type, mnt, flags, mnt_data); + if (error < 0) + plog(XLOG_ERROR, "%s: mount: %m", mnt->mnt_dir); + if (error < 0 && --retry > 0) { + sleep(1); + goto again; + } + if (error < 0) { +#ifdef notdef + if (automount) + going_down(errno); +#endif + return errno; + } + +#ifdef UPDATE_MTAB +#ifdef MNTINFO_DEV + /* + * Add the extra dev= field to the mount table. + */ + if (lstat(mnt->mnt_dir, &stb) == 0) { + char *zopts = (char *) xmalloc(strlen(mnt->mnt_opts) + 32); + xopts = mnt->mnt_opts; + if (sizeof(stb.st_dev) == 2) { + /* e.g. SunOS 4.1 */ + sprintf(zopts, "%s,%s=%s%04lx", xopts, MNTINFO_DEV, + MNTINFO_PREF, (u_long) stb.st_dev & 0xffff); + } else { + /* e.g. System Vr4 */ + sprintf(zopts, "%s,%s=%s%08lx", xopts, MNTINFO_DEV, + MNTINFO_PREF, (u_long) stb.st_dev); + } + mnt->mnt_opts = zopts; + } +#endif /* MNTINFO_DEV */ + +#ifdef FIXUP_MNTENT + /* + * Additional fields in struct mntent + * are fixed up here + */ + FIXUP_MNTENT(mnt); +#endif + + write_mntent(mnt); +#ifdef MNTINFO_DEV + if (xopts) { + free(mnt->mnt_opts); + mnt->mnt_opts = xopts; + } +#endif /* MNTINFO_DEV */ +#endif /* UPDATE_MTAB */ + + return 0; +} + +#ifdef NEED_MNTOPT_PARSER +/* + * Some systems don't provide these to the user, + * but amd needs them, so... + * + * From: Piete Brooks + */ + +#include + +static char *nextmntopt(p) +char **p; +{ + char *cp = *p; + char *rp; + /* + * Skip past white space + */ + while (*cp && isspace(*cp)) + cp++; + /* + * Word starts here + */ + rp = cp; + /* + * Scan to send of string or separator + */ + while (*cp && *cp != ',') + cp++; + /* + * If separator found the overwrite with nul char. + */ + if (*cp) { + *cp = '\0'; + cp++; + } + /* + * Return value for next call + */ + *p = cp; + return rp; +} + +char *hasmntopt(mnt, opt) +struct mntent *mnt; +char *opt; +{ + char t[MNTMAXSTR]; + char *f; + char *o = t; + int l = strlen(opt); + strcpy(t, mnt->mnt_opts); + + while (*(f = nextmntopt(&o))) + if (strncmp(opt, f, l) == 0) + return f - t + mnt->mnt_opts; + + return 0; +} +#endif /* NEED_MNTOPT_PARSER */ + +#ifdef MOUNT_HELPER_SOURCE +#include MOUNT_HELPER_SOURCE +#endif /* MOUNT_HELPER_SOURCE */ diff --git a/usr.sbin/amd/amd/mtab.c b/usr.sbin/amd/amd/mtab.c new file mode 100644 index 0000000..43b3a26 --- /dev/null +++ b/usr.sbin/amd/amd/mtab.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)mtab.c 8.1 (Berkeley) 6/6/93 + * + * $Id: mtab.c,v 5.2.2.1 1992/02/09 15:08:45 jsp beta $ + * + */ + +#include "am.h" + +/* + * Firewall /etc/mtab entries + */ +void mnt_free P((struct mntent *mp)); +void mnt_free(mp) +struct mntent *mp; +{ + free(mp->mnt_fsname); + free(mp->mnt_dir); + free(mp->mnt_type); + free(mp->mnt_opts); + free((voidp) mp); +} + +/* + * Discard memory allocated for mount list + */ +void discard_mntlist P((mntlist *mp)); +void discard_mntlist(mp) +mntlist *mp; +{ + mntlist *mp2; + + while (mp2 = mp) { + mp = mp->mnext; + if (mp2->mnt) + mnt_free(mp2->mnt); + free((voidp) mp2); + } +} + +/* + * Throw away a mount list + */ +void free_mntlist P((mntlist *mp)); +void free_mntlist(mp) +mntlist *mp; +{ + discard_mntlist(mp); + unlock_mntlist(); +} + +/* + * Utility routine which determines the value of a + * numeric option in the mount options (such as port=%d). + * Returns 0 if the option is not specified. + */ +int hasmntval P((struct mntent *mnt, char *opt)); +int hasmntval(mnt, opt) +struct mntent *mnt; +char *opt; +{ + char *str = hasmntopt(mnt, opt); + if (str) { + char *eq = strchr(str, '='); + if (eq) + return atoi(eq+1); + else + plog(XLOG_USER, "bad numeric option \"%s\" in \"%s\"", opt, str); + } + + return 0; +} diff --git a/usr.sbin/amd/amd/nfs_ops.c b/usr.sbin/amd/amd/nfs_ops.c new file mode 100644 index 0000000..bcfd7a5 --- /dev/null +++ b/usr.sbin/amd/amd/nfs_ops.c @@ -0,0 +1,809 @@ +/*- + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * $Id: nfs_ops.c,v 5.2.2.2 1992/05/31 16:35:05 jsp Exp $ + */ + +#ifndef lint +static char sccsid[] = "@(#)nfs_ops.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "am.h" +#include + +#ifdef HAS_NFS + +#define NFS +#define NFSCLIENT +#ifdef NFS_3 +typedef nfs_fh fhandle_t; +#endif /* NFS_3 */ +#ifdef NFS_HDR +#include NFS_HDR +#endif /* NFS_HDR */ +#include +#include "mount.h" + +/* + * Network file system + */ + +/* + * Convert from nfsstat to UN*X error code + */ +#define unx_error(e) ((int)(e)) + +/* + * The NFS layer maintains a cache of file handles. + * This is *fundamental* to the implementation and + * also allows quick remounting when a filesystem + * is accessed soon after timing out. + * + * The NFS server layer knows to flush this cache + * when a server goes down so avoiding stale handles. + * + * Each cache entry keeps a hard reference to + * the corresponding server. This ensures that + * the server keepalive information is maintained. + * + * The copy of the sockaddr_in here is taken so + * that the port can be twiddled to talk to mountd + * instead of portmap or the NFS server as used + * elsewhere. + * The port# is flushed if a server goes down. + * The IP address is never flushed - we assume + * that the address of a mounted machine never + * changes. If it does, then you have other + * problems... + */ +typedef struct fh_cache fh_cache; +struct fh_cache { + qelem fh_q; /* List header */ + voidp fh_wchan; /* Wait channel */ + int fh_error; /* Valid data? */ + int fh_id; /* Unique id */ + int fh_cid; /* Callout id */ + struct fhstatus fh_handle; /* Handle on filesystem */ + struct sockaddr_in fh_sin; /* Address of mountd */ + fserver *fh_fs; /* Server holding filesystem */ + char *fh_path; /* Filesystem on host */ +}; + +/* + * FH_TTL is the time a file handle will remain in the cache since + * last being used. If the file handle becomes invalid, then it + * will be flushed anyway. + */ +#define FH_TTL (5 * 60) /* five minutes */ +#define FH_TTL_ERROR (30) /* 30 seconds */ + +static int fh_id = 0; +#define FHID_ALLOC() (++fh_id) +extern qelem fh_head; +qelem fh_head = { &fh_head, &fh_head }; + +static int call_mountd P((fh_cache*, unsigned long, fwd_fun, voidp)); + +AUTH *nfs_auth; + +static fh_cache *find_nfs_fhandle_cache P((voidp idv, int done)); +static fh_cache *find_nfs_fhandle_cache(idv, done) +voidp idv; +int done; +{ + fh_cache *fp, *fp2 = 0; + int id = (int) idv; + + ITER(fp, fh_cache, &fh_head) { + if (fp->fh_id == id) { + fp2 = fp; + break; + } + } + +#ifdef DEBUG + if (fp2) { + dlog("fh cache gives fp %#x, fs %s", fp2, fp2->fh_path); + } else { + dlog("fh cache search failed"); + } +#endif /* DEBUG */ + + if (fp2 && !done) { + fp2->fh_error = ETIMEDOUT; + return 0; + } + + return fp2; +} + +/* + * Called when a filehandle appears + */ +static void got_nfs_fh P((voidp pkt, int len, struct sockaddr_in *sa, + struct sockaddr_in *ia, voidp idv, int done)); +static void got_nfs_fh(pkt, len, sa, ia, idv, done) +voidp pkt; +int len; +struct sockaddr_in *sa, *ia; +voidp idv; +int done; +{ + fh_cache *fp = find_nfs_fhandle_cache(idv, done); + if (fp) { + fp->fh_error = pickup_rpc_reply(pkt, len, (voidp) &fp->fh_handle, xdr_fhstatus); + if (!fp->fh_error) { +#ifdef DEBUG + dlog("got filehandle for %s:%s", fp->fh_fs->fs_host, fp->fh_path); +#endif /* DEBUG */ + /* + * Wakeup anything sleeping on this filehandle + */ + if (fp->fh_wchan) { +#ifdef DEBUG + dlog("Calling wakeup on %#x", fp->fh_wchan); +#endif /* DEBUG */ + wakeup(fp->fh_wchan); + } + } + } +} + +void flush_nfs_fhandle_cache P((fserver *fs)); +void flush_nfs_fhandle_cache(fs) +fserver *fs; +{ + fh_cache *fp; + ITER(fp, fh_cache, &fh_head) { + if (fp->fh_fs == fs || fs == 0) { + fp->fh_sin.sin_port = (u_short) 0; + fp->fh_error = -1; + } + } +} + +static void discard_fh P((fh_cache *fp)); +static void discard_fh(fp) +fh_cache *fp; +{ + rem_que(&fp->fh_q); +#ifdef DEBUG + dlog("Discarding filehandle for %s:%s", fp->fh_fs->fs_host, fp->fh_path); +#endif /* DEBUG */ + free_srvr(fp->fh_fs); + free((voidp) fp->fh_path); + free((voidp) fp); +} + +/* + * Determine the file handle for a node + */ +static int prime_nfs_fhandle_cache P((char *path, fserver *fs, struct fhstatus *fhbuf, voidp wchan)); +static int prime_nfs_fhandle_cache(path, fs, fhbuf, wchan) +char *path; +fserver *fs; +struct fhstatus *fhbuf; +voidp wchan; +{ + fh_cache *fp, *fp_save = 0; + int error; + int reuse_id = FALSE; + +#ifdef DEBUG + dlog("Searching cache for %s:%s", fs->fs_host, path); +#endif /* DEBUG */ + + /* + * First search the cache + */ + ITER(fp, fh_cache, &fh_head) { + if (fs == fp->fh_fs && strcmp(path, fp->fh_path) == 0) { + switch (fp->fh_error) { + case 0: + error = fp->fh_error = unx_error(fp->fh_handle.fhs_status); + if (error == 0) { + if (fhbuf) + bcopy((voidp) &fp->fh_handle, (voidp) fhbuf, + sizeof(fp->fh_handle)); + if (fp->fh_cid) + untimeout(fp->fh_cid); + fp->fh_cid = timeout(FH_TTL, discard_fh, (voidp) fp); + } else if (error == EACCES) { + /* + * Now decode the file handle return code. + */ + plog(XLOG_INFO, "Filehandle denied for \"%s:%s\"", + fs->fs_host, path); + } else { + errno = error; /* XXX */ + plog(XLOG_INFO, "Filehandle error for \"%s:%s\": %m", + fs->fs_host, path); + } + + /* + * The error was returned from the remote mount daemon. + * Policy: this error will be cached for now... + */ + return error; + + case -1: + /* + * Still thinking about it, but we can re-use. + */ + fp_save = fp; + reuse_id = TRUE; + break; + + default: + /* + * Return the error. + * Policy: make sure we recompute if required again + * in case this was caused by a network failure. + * This can thrash mountd's though... If you find + * your mountd going slowly then: + * 1. Add a fork() loop to main. + * 2. Remove the call to innetgr() and don't use + * netgroups, especially if you don't use YP. + */ + error = fp->fh_error; + fp->fh_error = -1; + return error; + } + break; + } + } + + /* + * Not in cache + */ + if (fp_save) { + fp = fp_save; + /* + * Re-use existing slot + */ + untimeout(fp->fh_cid); + free_srvr(fp->fh_fs); + free(fp->fh_path); + } else { + fp = ALLOC(fh_cache); + bzero((voidp) fp, sizeof(*fp)); + ins_que(&fp->fh_q, &fh_head); + } + if (!reuse_id) + fp->fh_id = FHID_ALLOC(); + fp->fh_wchan = wchan; + fp->fh_error = -1; + fp->fh_cid = timeout(FH_TTL, discard_fh, (voidp) fp); + + /* + * If the address has changed then don't try to re-use the + * port information + */ + if (fp->fh_sin.sin_addr.s_addr != fs->fs_ip->sin_addr.s_addr) { + fp->fh_sin = *fs->fs_ip; + fp->fh_sin.sin_port = 0; + } + fp->fh_fs = dup_srvr(fs); + fp->fh_path = strdup(path); + + error = call_mountd(fp, MOUNTPROC_MNT, got_nfs_fh, wchan); + if (error) { + /* + * Local error - cache for a short period + * just to prevent thrashing. + */ + untimeout(fp->fh_cid); + fp->fh_cid = timeout(error < 0 ? 2 * ALLOWED_MOUNT_TIME : FH_TTL_ERROR, + discard_fh, (voidp) fp); + fp->fh_error = error; + } else { + error = fp->fh_error; + } + return error; +} + +int make_nfs_auth P((void)) +{ +#ifdef HAS_NFS_QUALIFIED_NAMES + /* + * From: Chris Metcalf + * Use hostd, not just hostname. Note that uids + * and gids and the gidlist are type *int* and not the + * system uid_t and gid_t types. + */ + static int group_wheel = 0; + nfs_auth = authunix_create(hostd, 0, 0, 1, &group_wheel); +#else + nfs_auth = authunix_create_default(); +#endif + if (!nfs_auth) + return ENOBUFS; + return 0; +} + +static int call_mountd P((fh_cache *fp, u_long proc, fwd_fun f, voidp wchan)); +static int call_mountd(fp, proc, f, wchan) +fh_cache *fp; +u_long proc; +fwd_fun f; +voidp wchan; +{ + struct rpc_msg mnt_msg; + int len; + char iobuf[8192]; + int error; + + if (!nfs_auth) { + error = make_nfs_auth(); + if (error) + return error; + } + + if (fp->fh_sin.sin_port == 0) { + u_short port; + error = nfs_srvr_port(fp->fh_fs, &port, wchan); + if (error) + return error; + fp->fh_sin.sin_port = port; + } + + rpc_msg_init(&mnt_msg, MOUNTPROG, MOUNTVERS, (unsigned long) 0); + len = make_rpc_packet(iobuf, sizeof(iobuf), proc, + &mnt_msg, (voidp) &fp->fh_path, xdr_nfspath, nfs_auth); + + if (len > 0) { + error = fwd_packet(MK_RPC_XID(RPC_XID_MOUNTD, fp->fh_id), + (voidp) iobuf, len, &fp->fh_sin, &fp->fh_sin, (voidp) fp->fh_id, f); + } else { + error = -len; + } +/* + * It may be the case that we're sending to the wrong MOUNTD port. This + * occurs if mountd is restarted on the server after the port has been + * looked up and stored in the filehandle cache somewhere. The correct + * solution, if we're going to cache port numbers is to catch the ICMP + * port unreachable reply from the server and cause the portmap request + * to be redone. The quick solution here is to invalidate the MOUNTD + * port. + */ + fp->fh_sin.sin_port = 0; + + return error; +} + +/*-------------------------------------------------------------------------*/ + +/* + * NFS needs the local filesystem, remote filesystem + * remote hostname. + * Local filesystem defaults to remote and vice-versa. + */ +static char *nfs_match(fo) +am_opts *fo; +{ + char *xmtab; + if (fo->opt_fs && !fo->opt_rfs) + fo->opt_rfs = fo->opt_fs; + if (!fo->opt_rfs) { + plog(XLOG_USER, "nfs: no remote filesystem specified"); + return FALSE; + } + if (!fo->opt_rhost) { + plog(XLOG_USER, "nfs: no remote host specified"); + return FALSE; + } + /* + * Determine magic cookie to put in mtab + */ + xmtab = (char *) xmalloc(strlen(fo->opt_rhost) + strlen(fo->opt_rfs) + 2); + sprintf(xmtab, "%s:%s", fo->opt_rhost, fo->opt_rfs); +#ifdef DEBUG + dlog("NFS: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"", + fo->opt_rhost, fo->opt_rfs, fo->opt_fs); +#endif /* DEBUG */ + + return xmtab; +} + +/* + * Initialise am structure for nfs + */ +static int nfs_init(mf) +mntfs *mf; +{ + if (!mf->mf_private) { + int error; + struct fhstatus fhs; + + char *colon = strchr(mf->mf_info, ':'); + if (colon == 0) + return ENOENT; + + error = prime_nfs_fhandle_cache(colon+1, mf->mf_server, &fhs, (voidp) mf); + if (!error) { + mf->mf_private = (voidp) ALLOC(fhstatus); + mf->mf_prfree = (void (*)()) free; + bcopy((voidp) &fhs, mf->mf_private, sizeof(fhs)); + } + return error; + } + + return 0; +} + +int mount_nfs_fh P((struct fhstatus *fhp, char *dir, char *fs_name, char *opts, mntfs *mf)); +int mount_nfs_fh(fhp, dir, fs_name, opts, mf) +struct fhstatus *fhp; +char *dir; +char *fs_name; +char *opts; +mntfs *mf; +{ + struct nfs_args nfs_args; + struct mntent mnt; + int retry; + char *colon; + /*char *path;*/ + char host[MAXHOSTNAMELEN + MAXPATHLEN + 2]; + fserver *fs = mf->mf_server; + int flags; + char *xopts; + int error; +#ifdef notdef + unsigned short port; +#endif /* notdef */ + + MTYPE_TYPE type = MOUNT_TYPE_NFS; + + bzero((voidp) &nfs_args, sizeof(nfs_args)); /* Paranoid */ + + /* + * Extract host name to give to kernel + */ + if (!(colon = strchr(fs_name, ':'))) + return ENOENT; +#ifndef NFS_ARGS_NEEDS_PATH + *colon = '\0'; +#endif + strncpy(host, fs_name, sizeof(host)); +#ifndef NFS_ARGS_NEEDS_PATH + *colon = ':'; +#endif /* NFS_ARGS_NEEDS_PATH */ + /*path = colon + 1;*/ + + if (mf->mf_remopts && *mf->mf_remopts && !islocalnet(fs->fs_ip->sin_addr.s_addr)) + xopts = strdup(mf->mf_remopts); + else + xopts = strdup(opts); + + bzero((voidp) &nfs_args, sizeof(nfs_args)); + + mnt.mnt_dir = dir; + mnt.mnt_fsname = fs_name; + mnt.mnt_type = MTAB_TYPE_NFS; + mnt.mnt_opts = xopts; + mnt.mnt_freq = 0; + mnt.mnt_passno = 0; + + retry = hasmntval(&mnt, "retry"); + if (retry <= 0) + retry = 1; /* XXX */ + +/*again:*/ + + /* + * set mount args + */ + NFS_FH_DREF(nfs_args.fh, (NFS_FH_TYPE) fhp->fhstatus_u.fhs_fhandle); + +#ifdef ULTRIX_HACK + nfs_args.optstr = mnt.mnt_opts; +#endif /* ULTRIX_HACK */ + + nfs_args.hostname = host; + nfs_args.flags |= NFSMNT_HOSTNAME; +#ifdef HOSTNAMESZ + /* + * Most kernels have a name length restriction. + */ + if (strlen(host) >= HOSTNAMESZ) + strcpy(host + HOSTNAMESZ - 3, ".."); +#endif /* HOSTNAMESZ */ + + if (nfs_args.rsize = hasmntval(&mnt, "rsize")) + nfs_args.flags |= NFSMNT_RSIZE; + + if (nfs_args.wsize = hasmntval(&mnt, "wsize")) + nfs_args.flags |= NFSMNT_WSIZE; + + if (nfs_args.timeo = hasmntval(&mnt, "timeo")) + nfs_args.flags |= NFSMNT_TIMEO; + + if (nfs_args.retrans = hasmntval(&mnt, "retrans")) + nfs_args.flags |= NFSMNT_RETRANS; + +#ifdef NFSMNT_BIODS + if (nfs_args.biods = hasmntval(&mnt, "biods")) + nfs_args.flags |= NFSMNT_BIODS; + +#endif /* NFSMNT_BIODS */ + +#ifdef NFSMNT_MAXGRPS + if (nfs_args.maxgrouplist = hasmntval(&mnt, "maxgroups")) + nfs_args.flags |= NFSMNT_MAXGRPS; +#endif /* NFSMNT_MAXGRPS */ + +#ifdef notdef +/* + * This isn't supported by the ping algorithm yet. + * In any case, it is all done in nfs_init(). + */ + if (port = hasmntval(&mnt, "port")) + sin.sin_port = htons(port); + else + sin.sin_port = htons(NFS_PORT); /* XXX should use portmapper */ +#endif /* notdef */ + + if (hasmntopt(&mnt, MNTOPT_SOFT) != NULL) + nfs_args.flags |= NFSMNT_SOFT; + +#ifdef NFSMNT_SPONGY + if (hasmntopt(&mnt, "spongy") != NULL) { + nfs_args.flags |= NFSMNT_SPONGY; + if (nfs_args.flags & NFSMNT_SOFT) { + plog(XLOG_USER, "Mount opts soft and spongy are incompatible - soft ignored"); + nfs_args.flags &= ~NFSMNT_SOFT; + } + } +#endif /* MNTOPT_SPONGY */ + +#ifdef MNTOPT_INTR + if (hasmntopt(&mnt, MNTOPT_INTR) != NULL) + nfs_args.flags |= NFSMNT_INT; +#endif /* MNTOPT_INTR */ + +#ifdef MNTOPT_NODEVS + if (hasmntopt(&mnt, MNTOPT_NODEVS) != NULL) + nfs_args.flags |= NFSMNT_NODEVS; +#endif /* MNTOPT_NODEVS */ + +#ifdef MNTOPT_COMPRESS + if (hasmntopt(&mnt, "compress") != NULL) + nfs_args.flags |= NFSMNT_COMPRESS; +#endif /* MNTOPT_COMPRESS */ + +#ifdef MNTOPT_NOCONN + if (hasmntopt(&mnt, "noconn") != NULL) + nfs_args.flags |= NFSMNT_NOCONN; +#endif /* MNTOPT_NOCONN */ + +#ifdef NFSMNT_PGTHRESH + if (nfs_args.pg_thresh = hasmntval(&mnt, "pgthresh")) + nfs_args.flags |= NFSMNT_PGTHRESH; +#endif /* NFSMNT_PGTHRESH */ + + NFS_SA_DREF(nfs_args, fs->fs_ip); + + flags = compute_mount_flags(&mnt); + +#ifdef NFSMNT_NOCTO + if (hasmntopt(&mnt, "nocto") != NULL) + nfs_args.flags |= NFSMNT_NOCTO; +#endif /* NFSMNT_NOCTO */ + +#ifdef HAS_TCP_NFS + if (hasmntopt(&mnt, "tcp") != NULL) + nfs_args.sotype = SOCK_STREAM; +#endif /* HAS_TCP_NFS */ + + +#ifdef ULTRIX_HACK + /* + * Ultrix passes the flags argument as part of the + * mount data structure, rather than using the + * flags argument to the system call. This is + * confusing... + */ + if (!(nfs_args.flags & NFSMNT_PGTHRESH)) { + nfs_args.pg_thresh = 64; /* 64k - XXX */ + nfs_args.flags |= NFSMNT_PGTHRESH; + } + nfs_args.gfs_flags = flags; + flags &= M_RDONLY; + if (flags & M_RDONLY) + nfs_args.flags |= NFSMNT_RONLY; +#endif /* ULTRIX_HACK */ + + error = mount_fs(&mnt, flags, (caddr_t) &nfs_args, retry, type); + free(xopts); + return error; +} + +static int mount_nfs(dir, fs_name, opts, mf) +char *dir; +char *fs_name; +char *opts; +mntfs *mf; +{ +#ifdef notdef + int error; + struct fhstatus fhs; + char *colon; + + if (!(colon = strchr(fs_name, ':'))) + return ENOENT; + +#ifdef DEBUG + dlog("locating fhandle for %s", fs_name); +#endif /* DEBUG */ + error = prime_nfs_fhandle_cache(colon+1, mf->mf_server, &fhs, (voidp) 0); + + if (error) + return error; + + return mount_nfs_fh(&fhs, dir, fs_name, opts, mf); +#endif + if (!mf->mf_private) { + plog(XLOG_ERROR, "Missing filehandle for %s", fs_name); + return EINVAL; + } + + return mount_nfs_fh((struct fhstatus *) mf->mf_private, dir, fs_name, opts, mf); +} + +static int nfs_fmount(mf) +mntfs *mf; +{ + int error; + + error = mount_nfs(mf->mf_mount, mf->mf_info, mf->mf_mopts, mf); + +#ifdef DEBUG + if (error) { + errno = error; + dlog("mount_nfs: %m"); + } +#endif /* DEBUG */ + return error; +} + +static int nfs_fumount(mf) +mntfs *mf; +{ + int error = UMOUNT_FS(mf->mf_mount); + if (error) + return error; + + return 0; +} + +static void nfs_umounted(mp) +am_node *mp; +{ +#ifdef INFORM_MOUNTD + /* + * Don't bother to inform remote mountd + * that we are finished. Until a full + * track of filehandles is maintained + * the mountd unmount callback cannot + * be done correctly anyway... + */ + + mntfs *mf = mp->am_mnt; + fserver *fs; + char *colon, *path; + + if (mf->mf_error || mf->mf_refc > 1) + return; + + fs = mf->mf_server; + + /* + * Call the mount daemon on the server to + * announce that we are not using the fs any more. + * + * This is *wrong*. The mountd should be called + * when the fhandle is flushed from the cache, and + * a reference held to the cached entry while the + * fs is mounted... + */ + colon = path = strchr(mf->mf_info, ':'); + if (fs && colon) { + fh_cache f; +#ifdef DEBUG + dlog("calling mountd for %s", mf->mf_info); +#endif /* DEBUG */ + *path++ = '\0'; + f.fh_path = path; + f.fh_sin = *fs->fs_ip; + f.fh_sin.sin_port = (u_short) 0; + f.fh_fs = fs; + f.fh_id = 0; + f.fh_error = 0; + (void) prime_nfs_fhandle_cache(colon+1, mf->mf_server, (struct fhstatus *) 0, (voidp) mf); + (void) call_mountd(&f, MOUNTPROC_UMNT, (fwd_fun) 0, (voidp) 0); + *colon = ':'; + } +#endif /* INFORM_MOUNTD */ + +#ifdef KICK_KERNEL + /* This should go into the mainline code, not in nfs_ops... */ + + /* + * Run lstat over the underlying directory in + * case this was a direct mount. This will + * get the kernel back in sync with reality. + */ + if (mp->am_parent && mp->am_parent->am_path && + STREQ(mp->am_parent->am_mnt->mf_ops->fs_type, "direct")) { + struct stat stb; + int pid; + if ((pid = background()) == 0) { + if (lstat(mp->am_parent->am_path, &stb) < 0) { + plog(XLOG_ERROR, "lstat(%s) after unmount: %m", mp->am_parent->am_path); +#ifdef DEBUG + } else { + dlog("hack lstat(%s): ok", mp->am_parent->am_path); +#endif /* DEBUG */ + } + _exit(0); + } + } +#endif /* KICK_KERNEL */ +} + +/* + * Network file system + */ +am_ops nfs_ops = { + "nfs", + nfs_match, + nfs_init, + auto_fmount, + nfs_fmount, + auto_fumount, + nfs_fumount, + efs_lookuppn, + efs_readdir, + 0, /* nfs_readlink */ + 0, /* nfs_mounted */ + nfs_umounted, + find_nfs_srvr, + FS_MKMNT|FS_BACKGROUND|FS_AMQINFO +}; + +#endif /* HAS_NFS */ diff --git a/usr.sbin/amd/amd/nfs_start.c b/usr.sbin/amd/amd/nfs_start.c new file mode 100644 index 0000000..13d36a1 --- /dev/null +++ b/usr.sbin/amd/amd/nfs_start.c @@ -0,0 +1,435 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)nfs_start.c 8.1 (Berkeley) 6/6/93 + * + * $Id: nfs_start.c,v 5.2.2.1 1992/02/09 15:08:51 jsp beta $ + * + */ + +#include "am.h" +#include "amq.h" +#include +#include +extern jmp_buf select_intr; +extern int select_intr_valid; + +#ifdef HAS_TFS +/* + * Use replacement for RPC/UDP transport + * so that we do NFS gatewaying. + */ +#define svcudp_create svcudp2_create +extern SVCXPRT *svcudp2_create P((int)); +#endif /* HAS_TFS */ + +extern void nfs_program_2(); +extern void amq_program_1(); + +unsigned short nfs_port; +SVCXPRT *nfsxprt; + +extern int fwd_sock; +int max_fds = -1; + +#define MASKED_SIGS (sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGCHLD)|sigmask(SIGHUP)) + +#ifdef DEBUG +/* + * Check that we are not burning resources + */ +static void checkup(P_void) +{ + +static int max_fd = 0; +static char *max_mem = 0; + + int next_fd = dup(0); + extern caddr_t sbrk P((int)); + caddr_t next_mem = sbrk(0); + close(next_fd); + + /*if (max_fd < 0) { + max_fd = next_fd; + } else*/ if (max_fd < next_fd) { + dlog("%d new fds allocated; total is %d", + next_fd - max_fd, next_fd); + max_fd = next_fd; + } + + /*if (max_mem == 0) { + max_mem = next_mem; + } else*/ if (max_mem < next_mem) { + dlog("%#x bytes of memory allocated; total is %#x (%d pages)", + next_mem - max_mem, + next_mem, + ((int)next_mem+getpagesize()-1)/getpagesize()); + max_mem = next_mem; + } +} +#endif /* DEBUG */ + +static int do_select(smask, fds, fdp, tvp) +int smask; +int fds; +int *fdp; +struct timeval *tvp; +{ + int sig; + int nsel; + if (sig = setjmp(select_intr)) { + select_intr_valid = 0; + /* Got a signal */ + switch (sig) { + case SIGINT: + case SIGTERM: + amd_state = Finishing; + reschedule_timeout_mp(); + break; + } + nsel = -1; + errno = EINTR; + } else { + select_intr_valid = 1; + /* + * Invalidate the current clock value + */ + clock_valid = 0; + /* + * Allow interrupts. If a signal + * occurs, then it will cause a longjmp + * up above. + */ + (void) sigsetmask(smask); + /* + * Wait for input + */ + nsel = select(fds, fdp, (int *) 0, (int *) 0, + tvp->tv_sec ? tvp : (struct timeval *) 0); + + } + + (void) sigblock(MASKED_SIGS); + + /* + * Perhaps reload the cache? + */ + if (do_mapc_reload < clocktime()) { + mapc_reload(); + do_mapc_reload = clocktime() + ONE_HOUR; + } + return nsel; +} + +/* + * Determine whether anything is left in + * the RPC input queue. + */ +static int rpc_pending_now() +{ + struct timeval tvv; + int nsel; +#ifdef FD_SET + fd_set readfds; + + FD_ZERO(&readfds); + FD_SET(fwd_sock, &readfds); +#else + int readfds = (1 << fwd_sock); +#endif /* FD_SET */ + + tvv.tv_sec = tvv.tv_usec = 0; + nsel = select(max_fds+1, &readfds, (int *) 0, (int *) 0, &tvv); + if (nsel < 1) + return(0); +#ifdef FD_SET + if (FD_ISSET(fwd_sock, &readfds)) + return(1); +#else + if (readfds & (1 << fwd_sock)) + return(1); +#endif + return(0); +} + +static serv_state run_rpc(P_void) +{ + int dtbsz = max_fds + 1; + int smask = sigblock(MASKED_SIGS); + + next_softclock = clocktime(); + + amd_state = Run; + + /* + * Keep on trucking while we are in Run mode. This state + * is switched to Quit after all the file systems have + * been unmounted. + */ + while ((int)amd_state <= (int)Finishing) { + struct timeval tvv; + int nsel; + time_t now; +#ifdef RPC_4 + fd_set readfds; + readfds = svc_fdset; + FD_SET(fwd_sock, &readfds); +#else +#ifdef FD_SET + fd_set readfds; + FD_ZERO(&readfds); + readfds.fds_bits[0] = svc_fds; + FD_SET(fwd_sock, &readfds); +#else + int readfds = svc_fds | (1 << fwd_sock); +#endif /* FD_SET */ +#endif /* RPC_4 */ + +#ifdef DEBUG + checkup(); +#endif /* DEBUG */ + + /* + * If the full timeout code is not called, + * then recompute the time delta manually. + */ + now = clocktime(); + + if (next_softclock <= now) { + if (amd_state == Finishing) + umount_exported(); + tvv.tv_sec = softclock(); + } else { + tvv.tv_sec = next_softclock - now; + } + tvv.tv_usec = 0; + + if (amd_state == Finishing && last_used_map < 0) { + flush_mntfs(); + amd_state = Quit; + break; + } + +#ifdef DEBUG + if (tvv.tv_sec) + dlog("Select waits for %ds", tvv.tv_sec); + else + dlog("Select waits for Godot"); +#endif /* DEBUG */ + + nsel = do_select(smask, dtbsz, &readfds, &tvv); + + + switch (nsel) { + case -1: + if (errno == EINTR) { +#ifdef DEBUG + dlog("select interrupted"); +#endif /* DEBUG */ + continue; + } + perror("select"); + break; + + case 0: +#ifdef DEBUG + /*dlog("select returned 0");*/ +#endif /* DEBUG */ + break; + + default: + /* Read all pending NFS responses at once to avoid + having responses queue up as a consequence of + retransmissions. */ +#ifdef FD_SET + if (FD_ISSET(fwd_sock, &readfds)) { + FD_CLR(fwd_sock, &readfds); +#else + if (readfds & (1 << fwd_sock)) { + readfds &= ~(1 << fwd_sock); +#endif + --nsel; + do { + fwd_reply(); + } while (rpc_pending_now() > 0); + } + + if (nsel) { + /* + * Anything left must be a normal + * RPC request. + */ +#ifdef RPC_4 + svc_getreqset(&readfds); +#else +#ifdef FD_SET + svc_getreq(readfds.fds_bits[0]); +#else + svc_getreq(readfds); +#endif /* FD_SET */ +#endif /* RPC_4 */ + } + break; + } + } + + (void) sigsetmask(smask); + + if (amd_state == Quit) + amd_state = Done; + + return amd_state; +} + +static int bindnfs_port(so) +int so; +{ + unsigned short port; + int error = bind_resv_port(so, &port); + if (error == 0) + nfs_port = port; + return error; +} + +void unregister_amq(P_void) +{ +#ifdef DEBUG + Debug(D_AMQ) +#endif /* DEBUG */ + (void) pmap_unset(AMQ_PROGRAM, AMQ_VERSION); +} + +int mount_automounter(ppid) +int ppid; +{ + int so = socket(AF_INET, SOCK_DGRAM, 0); + SVCXPRT *amqp; + int nmount; + + if (so < 0 || bindnfs_port(so) < 0) { + perror("Can't create privileged nfs port"); + return 1; + } + + if ((nfsxprt = svcudp_create(so)) == NULL || + (amqp = svcudp_create(so)) == NULL) { + plog(XLOG_FATAL, "cannot create rpc/udp service"); + return 2; + } + + if (!svc_register(nfsxprt, NFS_PROGRAM, NFS_VERSION, nfs_program_2, 0)) { + plog(XLOG_FATAL, "unable to register (NFS_PROGRAM, NFS_VERSION, 0)"); + return 3; + } + + /* + * Start RPC forwarding + */ + if (fwd_init() != 0) + return 3; + + /* + * One or other of so, fwd_sock + * must be the highest fd on + * which to select. + */ + if (so > max_fds) + max_fds = so; + if (fwd_sock > max_fds) + max_fds = fwd_sock; + + /* + * Construct the root automount node + */ + make_root_node(); + + /* + * Pick up the pieces from a previous run + * This is likely to (indirectly) need the rpc_fwd package + * so it *must* come after the call to fwd_init(). + */ + if (restart_existing_mounts) + restart(); + + /* + * Mount the top-level auto-mountpoints + */ + nmount = mount_exported(); + + /* + * Now safe to tell parent that we are up and running + */ + if (ppid) + kill(ppid, SIGQUIT); + + if (nmount == 0) { + plog(XLOG_FATAL, "No work to do - quitting"); + amd_state = Done; + return 0; + } + +#ifdef DEBUG + Debug(D_AMQ) { +#endif /* DEBUG */ + /* + * Register with amq + */ + unregister_amq(); + + if (!svc_register(amqp, AMQ_PROGRAM, AMQ_VERSION, amq_program_1, IPPROTO_UDP)) { + plog(XLOG_FATAL, "unable to register (AMQ_PROGRAM, AMQ_VERSION, udp)"); + return 3; + } +#ifdef DEBUG + } +#endif /* DEBUG */ + + /* + * Start timeout_mp rolling + */ + reschedule_timeout_mp(); + + /* + * Start the server + */ + if (run_rpc() != Done) { + plog(XLOG_FATAL, "run_rpc failed"); + amd_state = Done; + } + + return 0; +} diff --git a/usr.sbin/amd/amd/nfs_subr.c b/usr.sbin/amd/amd/nfs_subr.c new file mode 100644 index 0000000..297cf93 --- /dev/null +++ b/usr.sbin/amd/amd/nfs_subr.c @@ -0,0 +1,552 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)nfs_subr.c 8.1 (Berkeley) 6/6/93 + * + * $Id: nfs_subr.c,v 5.2.2.1 1992/02/09 15:08:53 jsp beta $ + * + */ + +#include "am.h" + +/* + * Convert from UN*X to NFS error code + */ +#ifdef NFS_ERROR_MAPPING +NFS_ERROR_MAPPING +#define nfs_error(e) \ + ((nfsstat)((e) > NFS_LOMAP && (e) < NFS_HIMAP ? \ + nfs_errormap[(e) - NFS_LOMAP] : (e))) +#else +#define nfs_error(e) ((nfsstat)(e)) +#endif /* NFS_ERROR_MAPPING */ + +static char *do_readlink P((am_node *mp, int *error_return, struct attrstat **attrpp)); +static char *do_readlink(mp, error_return, attrpp) +am_node *mp; +int *error_return; +struct attrstat **attrpp; +{ + char *ln; + + /* + * If there is a readlink method, then use + * that, otherwise if a link exists use + * that, otherwise use the mount point. + */ + if (mp->am_mnt->mf_ops->readlink) { + int retry = 0; + mp = (*mp->am_mnt->mf_ops->readlink)(mp, &retry); + if (mp == 0) { + *error_return = retry; + return 0; + } + /*reschedule_timeout_mp();*/ + } + if (mp->am_link) { + ln = mp->am_link; + } else { + ln = mp->am_mnt->mf_mount; + } + if (attrpp) + *attrpp = &mp->am_attr; + return ln; +} + +/*ARGSUSED*/ +voidp +nfsproc_null_2(argp, rqstp) +voidp argp; +struct svc_req *rqstp; +{ + static char res; + + return (voidp) &res; +} + + +/*ARGSUSED*/ +struct attrstat * +nfsproc_getattr_2(argp, rqstp) +struct nfs_fh *argp; +struct svc_req *rqstp; +{ + static struct attrstat res; + am_node *mp; + int retry; + +#ifdef DEBUG + Debug(D_TRACE) + plog(XLOG_DEBUG, "gettattr:"); +#endif /* DEBUG */ + + mp = fh_to_mp2(argp, &retry); + if (mp == 0) { +#ifdef PRECISE_SYMLINKS +getattr_retry: +#endif /* PRECISE_SYMLINKS */ + + if (retry < 0) + return 0; + res.status = nfs_error(retry); + } else { + struct attrstat *attrp = &mp->am_attr; +#ifdef PRECISE_SYMLINKS + if (mp->am_fattr.type == NFLNK) { + /* + * Make sure we can read the link, + * and then determine the length. + */ + char *ln = do_readlink(mp, &retry, &attrp); + if (ln == 0) + goto getattr_retry; + } +#endif /* PRECISE_SYMLINKS */ +#ifdef DEBUG + Debug(D_TRACE) + plog(XLOG_DEBUG, "\tstat(%s), size = %d", mp->am_path, attrp->attrstat_u.attributes.size); +#endif /* DEBUG */ + mp->am_stats.s_getattr++; + return attrp; + } + + return &res; +} + + +/*ARGSUSED*/ +struct attrstat * +nfsproc_setattr_2(argp, rqstp) +struct sattrargs *argp; +struct svc_req *rqstp; +{ + static struct attrstat res; + + if (!fh_to_mp(&argp->file)) + res.status = nfs_error(ESTALE); + else + res.status = nfs_error(EROFS); + + return &res; +} + + +/*ARGSUSED*/ +voidp +nfsproc_root_2(argp, rqstp) +voidp argp; +struct svc_req *rqstp; +{ + static char res; + + return (voidp)&res; +} + + +/*ARGSUSED*/ +struct diropres * +nfsproc_lookup_2(argp, rqstp) +struct diropargs *argp; +struct svc_req *rqstp; +{ + static struct diropres res; + am_node *mp; + int retry; + +#ifdef DEBUG + Debug(D_TRACE) + plog(XLOG_DEBUG, "lookup:"); +#endif /* DEBUG */ + + mp = fh_to_mp2(&argp->dir, &retry); + if (mp == 0) { + if (retry < 0) + return 0; + res.status = nfs_error(retry); + } else { + int error; + am_node *ap; +#ifdef DEBUG + Debug(D_TRACE) + plog(XLOG_DEBUG, "\tlookuppn(%s, %s)", mp->am_path, argp->name); +#endif /* DEBUG */ + ap = (*mp->am_mnt->mf_ops->lookuppn)(mp, argp->name, &error, VLOOK_CREATE); + if (ap == 0) { + if (error < 0) { +#ifdef DEBUG + dlog("Not sending RPC reply"); +#endif /* DEBUG */ + amd_stats.d_drops++; + return 0; + } + res.status = nfs_error(error); + } else { + mp_to_fh(ap, &res.diropres_u.diropres.file); + res.diropres_u.diropres.attributes = ap->am_fattr; + res.status = NFS_OK; + } + mp->am_stats.s_lookup++; + /*reschedule_timeout_mp();*/ + } + + return &res; +} + + +/*ARGSUSED*/ +struct readlinkres * +nfsproc_readlink_2(argp, rqstp) +struct nfs_fh *argp; +struct svc_req *rqstp; +{ + static struct readlinkres res; + am_node *mp; + int retry; + +#ifdef DEBUG + Debug(D_TRACE) + plog(XLOG_DEBUG, "readlink:"); +#endif /* DEBUG */ + + mp = fh_to_mp2(argp, &retry); + if (mp == 0) { +readlink_retry: + if (retry < 0) + return 0; + res.status = nfs_error(retry); + } else { + char *ln = do_readlink(mp, &retry, (struct attrstat **) 0); + if (ln == 0) + goto readlink_retry; + res.status = NFS_OK; +#ifdef DEBUG + Debug(D_TRACE) + if (ln) + plog(XLOG_DEBUG, "\treadlink(%s) = %s", mp->am_path, ln); +#endif /* DEBUG */ + res.readlinkres_u.data = ln; + mp->am_stats.s_readlink++; + } + + return &res; +} + + +/*ARGSUSED*/ +struct readres * +nfsproc_read_2(argp, rqstp) +struct readargs *argp; +struct svc_req *rqstp; +{ + static struct readres res; + + bzero((char *)&res, sizeof(res)); + + res.status = nfs_error(EACCES); + + return &res; +} + + +/*ARGSUSED*/ +voidp +nfsproc_writecache_2(argp, rqstp) +voidp argp; +struct svc_req *rqstp; +{ + static char res; + + return (voidp) &res; +} + + +/*ARGSUSED*/ +struct attrstat * +nfsproc_write_2(argp, rqstp) +writeargs *argp; +struct svc_req *rqstp; +{ + static struct attrstat res; + + if (!fh_to_mp(&argp->file)) + res.status = nfs_error(ESTALE); + else + res.status = nfs_error(EROFS); + + return &res; +} + + +/*ARGSUSED*/ +struct diropres * +nfsproc_create_2(argp, rqstp) +createargs *argp; +struct svc_req *rqstp; +{ + static struct diropres res; + + if (!fh_to_mp(&argp->where.dir)) + res.status = nfs_error(ESTALE); + else + res.status = nfs_error(EROFS); + + return &res; +} + + +/*ARGSUSED*/ +static nfsstat * +unlink_or_rmdir(argp, rqstp, unlinkp) +struct diropargs *argp; +struct svc_req *rqstp; +int unlinkp; +{ + static nfsstat res; + int retry; + /*mntfs *mf;*/ + am_node *mp = fh_to_mp3(&argp->dir, &retry, VLOOK_DELETE); + if (mp == 0) { + if (retry < 0) + return 0; + res = nfs_error(retry); + goto out; + } + /*mf = mp->am_mnt;*/ + if (mp->am_fattr.type != NFDIR) { + res = nfs_error(ENOTDIR); + goto out; + } +#ifdef DEBUG + Debug(D_TRACE) + plog(XLOG_DEBUG, "\tremove(%s, %s)", mp->am_path, argp->name); +#endif /* DEBUG */ + mp = (*mp->am_mnt->mf_ops->lookuppn)(mp, argp->name, &retry, VLOOK_DELETE); + if (mp == 0) { + /* + * Ignore retries... + */ + if (retry < 0) + retry = 0; + /* + * Usual NFS workaround... + */ + else if (retry == ENOENT) + retry = 0; + res = nfs_error(retry); + } else { + forcibly_timeout_mp(mp); + res = NFS_OK; + } + +out: + return &res; +} + + +/*ARGSUSED*/ +nfsstat * +nfsproc_remove_2(argp, rqstp) +struct diropargs *argp; +struct svc_req *rqstp; +{ + return unlink_or_rmdir(argp, rqstp, TRUE); +} + +/*ARGSUSED*/ +nfsstat * +nfsproc_rename_2(argp, rqstp) +renameargs *argp; +struct svc_req *rqstp; +{ + static nfsstat res; + if (!fh_to_mp(&argp->from.dir) || !fh_to_mp(&argp->to.dir)) + res = nfs_error(ESTALE); + /* + * If the kernel is doing clever things with referenced files + * then let it pretend... + */ + else if (strncmp(argp->to.name, ".nfs", 4) == 0) + res = NFS_OK; + /* + * otherwise a failure + */ + else + res = nfs_error(EROFS); + return &res; +} + + +/*ARGSUSED*/ +nfsstat * +nfsproc_link_2(argp, rqstp) +linkargs *argp; +struct svc_req *rqstp; +{ + static nfsstat res; + if (!fh_to_mp(&argp->from) || !fh_to_mp(&argp->to.dir)) + res = nfs_error(ESTALE); + else + res = nfs_error(EROFS); + + return &res; +} + + +/*ARGSUSED*/ +nfsstat * +nfsproc_symlink_2(argp, rqstp) +symlinkargs *argp; +struct svc_req *rqstp; +{ + static nfsstat res; + if (!fh_to_mp(&argp->from.dir)) + res = nfs_error(ESTALE); + else + res = nfs_error(EROFS); + + return &res; +} + + +/*ARGSUSED*/ +struct diropres * +nfsproc_mkdir_2(argp, rqstp) +createargs *argp; +struct svc_req *rqstp; +{ + static struct diropres res; + if (!fh_to_mp(&argp->where.dir)) + res.status = nfs_error(ESTALE); + else + res.status = nfs_error(EROFS); + + return &res; +} + + +/*ARGSUSED*/ +nfsstat * +nfsproc_rmdir_2(argp, rqstp) +struct diropargs *argp; +struct svc_req *rqstp; +{ + return unlink_or_rmdir(argp, rqstp, FALSE); +} + + +/*ARGSUSED*/ +struct readdirres * +nfsproc_readdir_2(argp, rqstp) +readdirargs *argp; +struct svc_req *rqstp; +{ + static readdirres res; + static entry e_res[MAX_READDIR_ENTRIES]; + am_node *mp; + int retry; + +#ifdef DEBUG + Debug(D_TRACE) + plog(XLOG_DEBUG, "readdir:"); +#endif /* DEBUG */ + + mp = fh_to_mp2(&argp->dir, &retry); + if (mp == 0) { + if (retry < 0) + return 0; + res.status = nfs_error(retry); + } else { +#ifdef DEBUG + Debug(D_TRACE) + plog(XLOG_DEBUG, "\treaddir(%s)", mp->am_path); +#endif /* DEBUG */ + res.status = nfs_error((*mp->am_mnt->mf_ops->readdir)(mp, argp->cookie, + &res.readdirres_u.reply, e_res, argp->count)); + mp->am_stats.s_readdir++; + } + + return &res; +} + +/*ARGSUSED*/ +struct statfsres * +nfsproc_statfs_2(argp, rqstp) +struct nfs_fh *argp; +struct svc_req *rqstp; +{ + static statfsres res; + am_node *mp; + int retry; + +#ifdef DEBUG + Debug(D_TRACE) + plog(XLOG_DEBUG, "statfs:"); +#endif /* DEBUG */ + + mp = fh_to_mp2(argp, &retry); + if (mp == 0) { + if (retry < 0) + return 0; + res.status = nfs_error(retry); + } else { + statfsokres *fp; +#ifdef DEBUG + Debug(D_TRACE) + plog(XLOG_DEBUG, "\tstat_fs(%s)", mp->am_path); +#endif /* DEBUG */ + /* + * just return faked up file system information + */ + + fp = &res.statfsres_u.reply; + + fp->tsize = 1024; + fp->bsize = 4096; +#ifdef HAS_EMPTY_AUTOMOUNTS + fp->blocks = 0; +#else + fp->blocks = 1; +#endif + fp->bfree = 0; + fp->bavail = 0; + + res.status = NFS_OK; + mp->am_stats.s_statfs++; + } + + return &res; +} diff --git a/usr.sbin/amd/amd/nfsx_ops.c b/usr.sbin/amd/amd/nfsx_ops.c new file mode 100644 index 0000000..ba18cdc --- /dev/null +++ b/usr.sbin/amd/amd/nfsx_ops.c @@ -0,0 +1,516 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)nfsx_ops.c 8.1 (Berkeley) 6/6/93 + * + * $Id: nfsx_ops.c,v 5.2.2.3 1992/05/31 16:13:07 jsp Exp $ + * + */ + +#include "am.h" + +#ifdef HAS_NFSX + +/* + * NFS hierarchical mounts + * + * TODO: Re-implement. + */ + +/* + * The rfs field contains a list of mounts to be done from + * the remote host. + */ +typedef struct nfsx_mnt { + mntfs *n_mnt; + int n_error; +} nfsx_mnt; + +struct nfsx { + int nx_c; /* Number of elements in nx_v */ + nfsx_mnt *nx_v; /* Underlying mounts */ + nfsx_mnt *nx_try; +}; + +static int nfsx_fmount P((mntfs*)); + +static char *nfsx_match(fo) +am_opts *fo; +{ + char *xmtab; + char *ptr; + int len; + + if (!fo->opt_rfs) { + plog(XLOG_USER, "nfsx: no remote filesystem specified"); + return FALSE; + } + if (!fo->opt_rhost) { + plog(XLOG_USER, "nfsx: no remote host specified"); + return FALSE; + } + +#ifdef notdef + /* fiddle sublink, must be last... */ + if (fo->opt_sublink) { + plog(XLOG_WARNING, "nfsx: sublink %s ignored", fo->opt_sublink); + free((voidp) fo->opt_sublink); + fo->opt_sublink = 0; + } +#endif + + /* set default sublink */ + if (fo->opt_sublink == 0) { + ptr = strchr(fo->opt_rfs, ','); + if (ptr && ptr != (fo->opt_rfs + 1)) + fo->opt_sublink = strnsave(fo->opt_rfs + 1, ptr - fo->opt_rfs - 1); + } + + /* + * Remove trailing ",..." from ${fs} + * After deslashifying, overwrite the end of ${fs} with "/" + * to make sure it is unique. + */ + if (ptr = strchr(fo->opt_fs, ',')) + *ptr = '\0'; + deslashify(fo->opt_fs); + /* + * Bump string length to allow trailing / + */ + len = strlen(fo->opt_fs); + fo->opt_fs = xrealloc(fo->opt_fs, len + 1 + 1); + ptr = fo->opt_fs + len; + /* + * Make unique... + */ + *ptr++ = '/'; + *ptr = '\0'; + + /* + * Determine magic cookie to put in mtab + */ + xmtab = str3cat((char *) 0, fo->opt_rhost, ":", fo->opt_rfs); +#ifdef DEBUG + dlog("NFS: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"", + fo->opt_rhost, fo->opt_rfs, fo->opt_fs); +#endif /* DEBUG */ + + return xmtab; +} + +static void nfsx_prfree P((voidp vp)); +static void nfsx_prfree(vp) +voidp vp; +{ + struct nfsx *nx = (struct nfsx *) vp; + int i; + + for (i = 0; i < nx->nx_c; i++) { + mntfs *m = nx->nx_v[i].n_mnt; + if (m) + free_mntfs(m); + } + + free((voidp) nx->nx_v); + free((voidp) nx); +} + +static int nfsx_init(mf) +mntfs *mf; +{ + /* + * mf_info has the form: + * host:/prefix/path,sub,sub,sub + */ + int i; + int glob_error; + struct nfsx *nx; + int asked_for_wakeup = 0; + + nx = (struct nfsx *) mf->mf_private; + + if (nx == 0) { + char **ivec; + char *info = 0; + char *host; + char *pref; + int error = 0; + + info = strdup(mf->mf_info); + host = strchr(info, ':'); + if (!host) { + error = EINVAL; + goto errexit; + } + + pref = host+1; + host = info; + + /* + * Split the prefix off from the suffices + */ + ivec = strsplit(pref, ',', '\''); + + /* + * Count array size + */ + for (i = 0; ivec[i]; i++) + ; + + nx = ALLOC(nfsx); + mf->mf_private = (voidp) nx; + mf->mf_prfree = nfsx_prfree; + + nx->nx_c = i - 1; /* i-1 because we don't want the prefix */ + nx->nx_v = (nfsx_mnt *) xmalloc(nx->nx_c * sizeof(nfsx_mnt)); + { char *mp = 0; + char *xinfo = 0; + char *fs = mf->mf_fo->opt_fs; + char *rfs = 0; + for (i = 0; i < nx->nx_c; i++) { + char *path = ivec[i+1]; + rfs = str3cat(rfs, pref, "/", path); + /* + * Determine the mount point. + * If this is the root, then don't remove + * the trailing slash to avoid mntfs name clashes. + */ + mp = str3cat(mp, fs, "/", rfs); + normalize_slash(mp); + deslashify(mp); + /* + * Determine the mount info + */ + xinfo = str3cat(xinfo, host, *path == '/' ? "" : "/", path); + normalize_slash(xinfo); + if (pref[1] != '\0') + deslashify(xinfo); +#ifdef DEBUG + dlog("nfsx: init mount for %s on %s", xinfo, mp); +#endif + nx->nx_v[i].n_error = -1; + nx->nx_v[i].n_mnt = find_mntfs(&nfs_ops, mf->mf_fo, mp, xinfo, "", mf->mf_mopts, mf->mf_remopts); + } + if (rfs) free(rfs); + if (mp) free(mp); + if (xinfo) free(xinfo); + } + + free((voidp) ivec); +errexit: + if (info) + free(info); + if (error) + return error; + } + + /* + * Iterate through the mntfs's and call + * the underlying init routine on each + */ + glob_error = 0; + for (i = 0; i < nx->nx_c; i++) { + nfsx_mnt *n = &nx->nx_v[i]; + mntfs *m = n->n_mnt; + int error = (*m->mf_ops->fs_init)(m); + /* + * If HARD_NFSX_ERRORS is defined, make any + * initialisation failure a hard error and + * fail the entire group. Otherwise only fail + * if none of the group is mountable (see nfsx_fmount). + */ +#ifdef HARD_NFSX_ERRORS + if (error > 0) + return error; +#else + if (error > 0) + n->n_error = error; +#endif + else if (error < 0) { + glob_error = -1; + if (!asked_for_wakeup) { + asked_for_wakeup = 1; + sched_task(wakeup_task, (voidp) mf, (voidp) m); + } + } + } + + return glob_error; +} + +static void nfsx_cont P((int rc, int term, voidp closure)); +static void nfsx_cont(rc, term, closure) +int rc; +int term; +voidp closure; +{ + mntfs *mf = (mntfs *) closure; + struct nfsx *nx = (struct nfsx *) mf->mf_private; + nfsx_mnt *n = nx->nx_try; + + n->n_mnt->mf_flags &= ~(MFF_ERROR|MFF_MOUNTING); + mf->mf_flags &= ~MFF_ERROR; + + /* + * Wakeup anything waiting for this mount + */ + wakeup((voidp) n->n_mnt); + + if (rc || term) { + if (term) { + /* + * Not sure what to do for an error code. + */ + plog(XLOG_ERROR, "mount for %s got signal %d", n->n_mnt->mf_mount, term); + n->n_error = EIO; + } else { + /* + * Check for exit status + */ + errno = rc; /* XXX */ + plog(XLOG_ERROR, "%s: mount (nfsx_cont): %m", n->n_mnt->mf_mount); + n->n_error = rc; + } + free_mntfs(n->n_mnt); + n->n_mnt = new_mntfs(); + n->n_mnt->mf_error = n->n_error; + n->n_mnt->mf_flags |= MFF_ERROR; + } else { + /* + * The mount worked. + */ + mf_mounted(n->n_mnt); + n->n_error = 0; + } + + /* + * Do the remaining bits + */ + if (nfsx_fmount(mf) >= 0) { + wakeup((voidp) mf); + mf->mf_flags &= ~MFF_MOUNTING; + mf_mounted(mf); + } +} + +static int try_nfsx_mount P((voidp mv)); +static int try_nfsx_mount(mv) +voidp mv; +{ + mntfs *mf = (mntfs *) mv; + int error; + + mf->mf_flags |= MFF_MOUNTING; + error = (*mf->mf_ops->fmount_fs)(mf); + mf->mf_flags &= ~MFF_MOUNTING; + return error; +} + +static int nfsx_remount P((mntfs *mf, int fg)); +static int nfsx_remount(mf, fg) +mntfs *mf; +int fg; +{ + struct nfsx *nx = (struct nfsx *) mf->mf_private; + nfsx_mnt *n; + int glob_error = -1; + + for (n = nx->nx_v; n < nx->nx_v + nx->nx_c; n++) { + mntfs *m = n->n_mnt; + if (n->n_error < 0) { + if (!(m->mf_flags & MFF_MKMNT) && m->mf_ops->fs_flags & FS_MKMNT) { + int error = mkdirs(m->mf_mount, 0555); + if (!error) + m->mf_flags |= MFF_MKMNT; + } + } + } + + /* + * Iterate through the mntfs's and mount each filesystem + * which is not yet mounted. + */ + for (n = nx->nx_v; n < nx->nx_v + nx->nx_c; n++) { + mntfs *m = n->n_mnt; + if (n->n_error < 0) { + /* + * Check fmount entry pt. exists + * and then mount... + */ + if (!m->mf_ops->fmount_fs) { + n->n_error = EINVAL; + } else { +#ifdef DEBUG + dlog("calling underlying fmount on %s", m->mf_mount); +#endif + if (!fg && foreground && (m->mf_ops->fs_flags & FS_MBACKGROUND)) { + m->mf_flags |= MFF_MOUNTING; /* XXX */ +#ifdef DEBUG + dlog("backgrounding mount of \"%s\"", m->mf_info); +#endif + nx->nx_try = n; + run_task(try_nfsx_mount, (voidp) m, nfsx_cont, (voidp) mf); + n->n_error = -1; + return -1; + } else { +#ifdef DEBUG + dlog("foreground mount of \"%s\" ...", mf->mf_info); +#endif + n->n_error = (*m->mf_ops->fmount_fs)(m); + } + } +#ifdef DEBUG + if (n->n_error > 0) { + errno = n->n_error; /* XXX */ + dlog("underlying fmount of %s failed: %m", m->mf_mount); + } +#endif + if (n->n_error == 0) { + glob_error = 0; + } else if (glob_error < 0) { + glob_error = n->n_error; + } + } + } + + return glob_error < 0 ? 0 : glob_error; +} + +static int nfsx_fmount P((mntfs *mf)); +static int nfsx_fmount(mf) +mntfs *mf; +{ + return nfsx_remount(mf, FALSE); +} + +/* + * Unmount an NFS hierarchy. + * Note that this is called in the foreground + * and so may hang under extremely rare conditions. + */ +static int nfsx_fumount(mf) +mntfs *mf; +{ + struct nfsx *nx = (struct nfsx *) mf->mf_private; + nfsx_mnt *n; + int glob_error = 0; + + /* + * Iterate in reverse through the mntfs's and unmount each filesystem + * which is mounted. + */ + for (n = nx->nx_v + nx->nx_c - 1; n >= nx->nx_v; --n) { + mntfs *m = n->n_mnt; + /* + * If this node has not been messed with + * and there has been no error so far + * then try and unmount. + * If an error had occured then zero + * the error code so that the remount + * only tries to unmount those nodes + * which had been successfully unmounted. + */ + if (n->n_error == 0) { +#ifdef DEBUG + dlog("calling underlying fumount on %s", m->mf_mount); +#endif + n->n_error = (*m->mf_ops->fumount_fs)(m); + if (n->n_error) { + glob_error = n->n_error; + n->n_error = 0; + } else { + /* + * Make sure remount gets this node + */ + n->n_error = -1; + } + } + } + + /* + * If any unmounts failed then remount the + * whole lot... + */ + if (glob_error) { + glob_error = nfsx_remount(mf, TRUE); + if (glob_error) { + errno = glob_error; /* XXX */ + plog(XLOG_USER, "nfsx: remount of %s failed: %m", mf->mf_mount); + } + glob_error = EBUSY; + } else { + /* + * Remove all the mount points + */ + for (n = nx->nx_v; n < nx->nx_v + nx->nx_c; n++) { + mntfs *m = n->n_mnt; + if (n->n_error < 0) { + if (m->mf_ops->fs_flags & FS_MKMNT) { + (void) rmdirs(m->mf_mount); + m->mf_flags &= ~MFF_MKMNT; + } + } + free_mntfs(m); + n->n_mnt = 0; + n->n_error = -1; + } + } + + return glob_error; +} + +/* + * Ops structure + */ +am_ops nfsx_ops = { + "nfsx", + nfsx_match, + nfsx_init, + auto_fmount, + nfsx_fmount, + auto_fumount, + nfsx_fumount, + efs_lookuppn, + efs_readdir, + 0, /* nfsx_readlink */ + 0, /* nfsx_mounted */ + 0, /* nfsx_umounted */ + find_nfs_srvr, /* XXX */ + /*FS_UBACKGROUND|*/FS_AMQINFO +}; + +#endif /* HAS_NFSX */ diff --git a/usr.sbin/amd/amd/opts.c b/usr.sbin/amd/amd/opts.c new file mode 100644 index 0000000..54c9675 --- /dev/null +++ b/usr.sbin/amd/amd/opts.c @@ -0,0 +1,835 @@ +/*- + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * $Id: opts.c,v 5.2.2.3 1992/05/31 16:34:13 jsp Exp $ + */ + +#ifndef lint +static char sccsid[] = "@(#)opts.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "am.h" + +extern char *getenv P((const char *)); + +/* + * static copy of the options with + * which to play + */ +static struct am_opts fs_static; + +static char *opt_host = hostname; +static char *opt_hostd = hostd; +static char nullstr[] = ""; +static char *opt_key = nullstr; +static char *opt_map = nullstr; +static char *opt_path = nullstr; + +static char *vars[8]; + +/* + * Length of longest option name + */ +#define NLEN 16 /* conservative */ +#define S(x) (x) , (sizeof(x)-1) +static struct opt { + char *name; /* Name of the option */ + int nlen; /* Length of option name */ + char **optp; /* Pointer to option value string */ + char **sel_p; /* Pointer to selector value string */ +} opt_fields[] = { + /* Options in something corresponding to frequency of use */ + { S("opts"), &fs_static.opt_opts, 0 }, + { S("host"), 0, &opt_host }, + { S("hostd"), 0, &opt_hostd }, + { S("type"), &fs_static.opt_type, 0 }, + { S("rhost"), &fs_static.opt_rhost, 0 }, + { S("rfs"), &fs_static.opt_rfs, 0 }, + { S("fs"), &fs_static.opt_fs, 0 }, + { S("key"), 0, &opt_key }, + { S("map"), 0, &opt_map }, + { S("sublink"), &fs_static.opt_sublink, 0 }, + { S("arch"), 0, &arch }, + { S("dev"), &fs_static.opt_dev, 0 }, + { S("pref"), &fs_static.opt_pref, 0 }, + { S("path"), 0, &opt_path }, + { S("autodir"), 0, &auto_dir }, + { S("delay"), &fs_static.opt_delay, 0 }, + { S("domain"), 0, &hostdomain }, + { S("karch"), 0, &karch }, + { S("cluster"), 0, &cluster }, + { S("wire"), 0, &wire }, + { S("byte"), 0, &endian }, + { S("os"), 0, &op_sys }, + { S("remopts"), &fs_static.opt_remopts, 0 }, + { S("mount"), &fs_static.opt_mount, 0 }, + { S("unmount"), &fs_static.opt_unmount, 0 }, + { S("cache"), &fs_static.opt_cache, 0 }, + { S("user"), &fs_static.opt_user, 0 }, + { S("group"), &fs_static.opt_group, 0 }, + { S("var0"), &vars[0], 0 }, + { S("var1"), &vars[1], 0 }, + { S("var2"), &vars[2], 0 }, + { S("var3"), &vars[3], 0 }, + { S("var4"), &vars[4], 0 }, + { S("var5"), &vars[5], 0 }, + { S("var6"), &vars[6], 0 }, + { S("var7"), &vars[7], 0 }, + { 0, 0, 0, 0 }, +}; + +typedef struct opt_apply opt_apply; +struct opt_apply { + char **opt; + char *val; +}; + +/* + * Specially expand the remote host name first + */ +static opt_apply rhost_expansion[] = { + { &fs_static.opt_rhost, "${host}" }, + { 0, 0 }, +}; +/* + * List of options which need to be expanded + * Note that this the order here _may_ be important. + */ +static opt_apply expansions[] = { +/* { &fs_static.opt_dir, 0 }, */ + { &fs_static.opt_sublink, 0 }, + { &fs_static.opt_rfs, "${path}" }, + { &fs_static.opt_fs, "${autodir}/${rhost}${rfs}" }, + { &fs_static.opt_opts, "rw" }, + { &fs_static.opt_remopts, "${opts}" }, + { &fs_static.opt_mount, 0 }, + { &fs_static.opt_unmount, 0 }, + { 0, 0 }, +}; + +/* + * List of options which need to be free'ed before re-use + */ +static opt_apply to_free[] = { + { &fs_static.fs_glob, 0 }, + { &fs_static.fs_local, 0 }, + { &fs_static.fs_mtab, 0 }, +/* { &fs_static.opt_dir, 0 }, */ + { &fs_static.opt_sublink, 0 }, + { &fs_static.opt_rfs, 0 }, + { &fs_static.opt_fs, 0 }, + { &fs_static.opt_rhost, 0 }, + { &fs_static.opt_opts, 0 }, + { &fs_static.opt_remopts, 0 }, + { &fs_static.opt_mount, 0 }, + { &fs_static.opt_unmount, 0 }, + { &vars[0], 0 }, + { &vars[1], 0 }, + { &vars[2], 0 }, + { &vars[3], 0 }, + { &vars[4], 0 }, + { &vars[5], 0 }, + { &vars[6], 0 }, + { &vars[7], 0 }, + { 0, 0 }, +}; + +/* + * Skip to next option in the string + */ +static char *opt P((char**)); +static char *opt(p) +char **p; +{ + char *cp = *p; + char *dp = cp; + char *s = cp; + +top: + while (*cp && *cp != ';') { + if (*cp == '\"') { + /* + * Skip past string + */ + cp++; + while (*cp && *cp != '\"') + *dp++ = *cp++; + if (*cp) + cp++; + } else { + *dp++ = *cp++; + } + } + + /* + * Skip past any remaining ';'s + */ + while (*cp == ';') + cp++; + + /* + * If we have a zero length string + * and there are more fields, then + * parse the next one. This allows + * sequences of empty fields. + */ + if (*cp && dp == s) + goto top; + + *dp = '\0'; + + *p = cp; + return s; +} + +static int eval_opts P((char*, char*)); +static int eval_opts(opts, mapkey) +char *opts; +char *mapkey; +{ + /* + * Fill in the global structure fs_static by + * cracking the string opts. opts may be + * scribbled on at will. + */ + char *o = opts; + char *f; + + /* + * For each user-specified option + */ + while (*(f = opt(&o))) { + struct opt *op; + enum vs_opt { OldSyn, SelEQ, SelNE, VarAss } vs_opt; + char *eq = strchr(f, '='); + char *opt; + if (!eq || eq[1] == '\0' || eq == f) { + /* + * No value, just continue + */ + plog(XLOG_USER, "key %s: No value component in \"%s\"", mapkey, f); + continue; + } + + /* + * Check what type of operation is happening + * !=, =! is SelNE + * == is SelEQ + * := is VarAss + * = is OldSyn (either SelEQ or VarAss) + */ + if (eq[-1] == '!') { /* != */ + vs_opt = SelNE; + eq[-1] = '\0'; + opt = eq + 1; + } else if (eq[-1] == ':') { /* := */ + vs_opt = VarAss; + eq[-1] = '\0'; + opt = eq + 1; + } else if (eq[1] == '=') { /* == */ + vs_opt = SelEQ; + eq[0] = '\0'; + opt = eq + 2; + } else if (eq[1] == '!') { /* =! */ + vs_opt = SelNE; + eq[0] = '\0'; + opt = eq + 2; + } else { /* = */ + vs_opt = OldSyn; + eq[0] = '\0'; + opt = eq + 1; + } + + /* + * For each recognised option + */ + for (op = opt_fields; op->name; op++) { + /* + * Check whether they match + */ + if (FSTREQ(op->name, f)) { + switch (vs_opt) { +#if AMD_COMPAT <= 5000108 + case OldSyn: + plog(XLOG_WARNING, "key %s: Old syntax selector found: %s=%s", mapkey, f, opt); + if (!op->sel_p) { + *op->optp = opt; + break; + } + /* fall through ... */ +#endif /* 5000108 */ + case SelEQ: + case SelNE: + if (op->sel_p && (STREQ(*op->sel_p, opt) == (vs_opt == SelNE))) { + plog(XLOG_MAP, "key %s: map selector %s (=%s) did not %smatch %s", + mapkey, + op->name, + *op->sel_p, + vs_opt == SelNE ? "not " : "", + opt); + return 0; + } + break; + + case VarAss: + if (op->sel_p) { + plog(XLOG_USER, "key %s: Can't assign to a selector (%s)", mapkey, op->name); + return 0; + } + *op->optp = opt; + break; + } + break; + } + } + + if (!op->name) + plog(XLOG_USER, "key %s: Unrecognised key/option \"%s\"", mapkey, f); + } + + return 1; +} + +/* + * Free an option + */ +static void free_op P((opt_apply*, int)); +/*ARGSUSED*/ +static void free_op(p, b) +opt_apply *p; +int b; +{ + if (*p->opt) { + free(*p->opt); + *p->opt = 0; + } +} + +/* + * Normalize slashes in the string. + */ +void normalize_slash P((char *p)); +void normalize_slash(p) +char *p; +{ + char *f = strchr(p, '/'); + char *f0 = f; + if (f) { + char *t = f; + do { + /* assert(*f == '/'); */ + if (f == f0 && f[0] == '/' && f[1] == '/') { + /* copy double slash iff first */ + *t++ = *f++; + *t++ = *f++; + } else { + /* copy a single / across */ + *t++ = *f++; + } + + /* assert(f[-1] == '/'); */ + /* skip past more /'s */ + while (*f == '/') + f++; + + /* assert(*f != '/'); */ + /* keep copying up to next / */ + while (*f && *f != '/') { + *t++ = *f++; + } + + /* assert(*f == 0 || *f == '/'); */ + + } while (*f); + *t = 0; /* derived from fix by Steven Glassman */ + } +} + +/* + * Macro-expand an option. Note that this does not + * handle recursive expansions. They will go badly wrong. + * If sel is true then old expand selectors, otherwise + * don't expand selectors. + */ +static void expand_op P((opt_apply*, int)); +static void expand_op(p, sel_p) +opt_apply *p; +int sel_p; +{ +/* + * The BUFSPACE macros checks that there is enough space + * left in the expansion buffer. If there isn't then we + * give up completely. This is done to avoid crashing the + * automounter itself (which would be a bad thing to do). + */ +#define BUFSPACE(ep, len) (((ep) + (len)) < expbuf+MAXPATHLEN) +static char expand_error[] = "No space to expand \"%s\""; + + char expbuf[MAXPATHLEN+1]; + char nbuf[NLEN+1]; + char *ep = expbuf; + char *cp = *p->opt; + char *dp; +#ifdef DEBUG + char *cp_orig = *p->opt; +#endif /* DEBUG */ + struct opt *op; + + while (dp = strchr(cp, '$')) { + char ch; + /* + * First copy up to the $ + */ + { int len = dp - cp; + if (BUFSPACE(ep, len)) { + strncpy(ep, cp, len); + ep += len; + } else { + plog(XLOG_ERROR, expand_error, *p->opt); + goto out; + } + } + cp = dp + 1; + ch = *cp++; + if (ch == '$') { + if (BUFSPACE(ep, 1)) { + *ep++ = '$'; + } else { + plog(XLOG_ERROR, expand_error, *p->opt); + goto out; + } + } else if (ch == '{') { + /* Expansion... */ + enum { E_All, E_Dir, E_File, E_Domain, E_Host } todo; + /* + * Find closing brace + */ + char *br_p = strchr(cp, '}'); + int len; + /* + * Check we found it + */ + if (!br_p) { + /* + * Just give up + */ + plog(XLOG_USER, "No closing '}' in \"%s\"", *p->opt); + goto out; + } + len = br_p - cp; + /* + * Figure out which part of the variable to grab. + */ + if (*cp == '/') { + /* + * Just take the last component + */ + todo = E_File; + cp++; + --len; + } else if (br_p[-1] == '/') { + /* + * Take all but the last component + */ + todo = E_Dir; + --len; + } else if (*cp == '.') { + /* + * Take domain name + */ + todo = E_Domain; + cp++; + --len; + } else if (br_p[-1] == '.') { + /* + * Take host name + */ + todo = E_Host; + --len; + } else { + /* + * Take the whole lot + */ + todo = E_All; + } + /* + * Truncate if too long. Since it won't + * match anyway it doesn't matter that + * it has been cut short. + */ + if (len > NLEN) + len = NLEN; + /* + * Put the string into another buffer so + * we can do comparisons. + */ + strncpy(nbuf, cp, len); + nbuf[len] = '\0'; + /* + * Advance cp + */ + cp = br_p + 1; + /* + * Search the option array + */ + for (op = opt_fields; op->name; op++) { + /* + * Check for match + */ + if (len == op->nlen && STREQ(op->name, nbuf)) { + char xbuf[NLEN+3]; + char *val; + /* + * Found expansion. Copy + * the correct value field. + */ + if (!(!op->sel_p == !sel_p)) { + /* + * Copy the string across unexpanded + */ + sprintf(xbuf, "${%s%s%s}", + todo == E_File ? "/" : + todo == E_Domain ? "." : "", + nbuf, + todo == E_Dir ? "/" : + todo == E_Host ? "." : ""); + val = xbuf; + /* + * Make sure expansion doesn't + * munge the value! + */ + todo = E_All; + } else if (op->sel_p) { + val = *op->sel_p; + } else { + val = *op->optp; + } + if (val) { + /* + * Do expansion: + * ${/var} means take just the last part + * ${var/} means take all but the last part + * ${.var} means take all but first part + * ${var.} means take just the first part + * ${var} means take the whole lot + */ + int vlen = strlen(val); + char *vptr = val; + switch (todo) { + case E_Dir: + vptr = strrchr(val, '/'); + if (vptr) + vlen = vptr - val; + vptr = val; + break; + case E_File: + vptr = strrchr(val, '/'); + if (vptr) { + vptr++; + vlen = strlen(vptr); + } else + vptr = val; + break; + case E_Domain: + vptr = strchr(val, '.'); + if (vptr) { + vptr++; + vlen = strlen(vptr); + } else { + vptr = ""; + vlen = 0; + } + break; + case E_Host: + vptr = strchr(val, '.'); + if (vptr) + vlen = vptr - val; + vptr = val; + break; + case E_All: + break; + } +#ifdef DEBUG + /*dlog("Expanding \"%s\" to \"%s\"", nbuf, val);*/ +#endif /* DEBUG */ + if (BUFSPACE(ep, vlen)) { + strcpy(ep, vptr); + ep += vlen; + } else { + plog(XLOG_ERROR, expand_error, *p->opt); + goto out; + } + } + /* + * Done with this variable + */ + break; + } + } + /* + * Check that the search was succesful + */ + if (!op->name) { + /* + * If it wasn't then scan the + * environment for that name + * and use any value found + */ + char *env = getenv(nbuf); + if (env) { + int vlen = strlen(env); + + if (BUFSPACE(ep, vlen)) { + strcpy(ep, env); + ep += vlen; + } else { + plog(XLOG_ERROR, expand_error, *p->opt); + goto out; + } +#ifdef DEBUG + Debug(D_STR) + plog(XLOG_DEBUG, "Environment gave \"%s\" -> \"%s\"", nbuf, env); +#endif /* DEBUG */ + } else { + plog(XLOG_USER, "Unknown sequence \"${%s}\"", nbuf); + } + } + } else { + /* + * Error, error + */ + plog(XLOG_USER, "Unknown $ sequence in \"%s\"", *p->opt); + } + } + +out: + /* + * Handle common case - no expansion + */ + if (cp == *p->opt) { + *p->opt = strdup(cp); + } else { + /* + * Finish off the expansion + */ + if (BUFSPACE(ep, strlen(cp))) { + strcpy(ep, cp); + /*ep += strlen(ep);*/ + } else { + plog(XLOG_ERROR, expand_error, *p->opt); + } + + /* + * Save the exansion + */ + *p->opt = strdup(expbuf); + } + + normalize_slash(*p->opt); + +#ifdef DEBUG + Debug(D_STR) { + plog(XLOG_DEBUG, "Expansion of \"%s\"...", cp_orig); + plog(XLOG_DEBUG, "... is \"%s\"", *p->opt); + } +#endif /* DEBUG */ +} + +/* + * Wrapper for expand_op + */ +static void expand_opts P((opt_apply*, int)); +static void expand_opts(p, sel_p) +opt_apply *p; +int sel_p; +{ + if (*p->opt) { + expand_op(p, sel_p); + } else if (p->val) { + /* + * Do double expansion, remembering + * to free the string from the first + * expansion... + */ + char *s = *p->opt = expand_key(p->val); + expand_op(p, sel_p); + free(s); + } +} + +/* + * Apply a function to a list of options + */ +static void apply_opts(op, ppp, b) +void (*op)(); +opt_apply ppp[]; +int b; +{ + opt_apply *pp; + for (pp = ppp; pp->opt; pp++) + (*op)(pp, b); +} + +/* + * Free the option table + */ +void free_opts(fo) +am_opts *fo; +{ + /* + * Copy in the structure we are playing with + */ + fs_static = *fo; + + /* + * Free previously allocated memory + */ + apply_opts(free_op, to_free, FALSE); +} + +/* + * Expand lookup key + */ +char *expand_key(key) +char *key; +{ + opt_apply oa; + + oa.opt = &key; oa.val = 0; + expand_opts(&oa, TRUE); + + return key; +} + +/* + * Remove trailing /'s from a string + * unless the string is a single / (Steven Glassman) + */ +void deslashify P((char *s)); +void deslashify(s) +char *s; +{ + if (s && *s) { + char *sl = s + strlen(s); + while (*--sl == '/' && sl > s) + *sl = '\0'; + } +} + +int eval_fs_opts(fo, opts, g_opts, path, key, map) +am_opts *fo; +char *opts, *g_opts, *path, *key, *map; +{ + int ok = TRUE; + + free_opts(fo); + + /* + * Clear out the option table + */ + bzero((voidp) &fs_static, sizeof(fs_static)); + bzero((voidp) vars, sizeof(vars)); + bzero((voidp) fo, sizeof(*fo)); + + /* + * Set key, map & path before expansion + */ + opt_key = key; + opt_map = map; + opt_path = path; + + /* + * Expand global options + */ + fs_static.fs_glob = expand_key(g_opts); + + /* + * Expand local options + */ + fs_static.fs_local = expand_key(opts); + + /* + * Expand default (global) options + */ + if (!eval_opts(fs_static.fs_glob, key)) + ok = FALSE; + + /* + * Expand local options + */ + if (ok && !eval_opts(fs_static.fs_local, key)) + ok = FALSE; + + /* + * Normalise remote host name. + * 1. Expand variables + * 2. Normalize relative to host tables + * 3. Strip local domains from the remote host + * name before using it in other expansions. + * This makes mount point names and other things + * much shorter, while allowing cross domain + * sharing of mount maps. + */ + apply_opts(expand_opts, rhost_expansion, FALSE); + if (ok && fs_static.opt_rhost && *fs_static.opt_rhost) + host_normalize(&fs_static.opt_rhost); + + /* + * Macro expand the options. + * Do this regardless of whether we are accepting + * this mount - otherwise nasty things happen + * with memory allocation. + */ + apply_opts(expand_opts, expansions, FALSE); + + /* + * Strip trailing slashes from local pathname... + */ + deslashify(fs_static.opt_fs); + + /* + * ok... copy the data back out. + */ + *fo = fs_static; + + /* + * Clear defined options + */ + opt_key = opt_map = opt_path = nullstr; + + return ok; +} diff --git a/usr.sbin/amd/amd/pfs_ops.c b/usr.sbin/amd/amd/pfs_ops.c new file mode 100644 index 0000000..314f62b --- /dev/null +++ b/usr.sbin/amd/amd/pfs_ops.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)pfs_ops.c 8.1 (Berkeley) 6/6/93 + * + * $Id: pfs_ops.c,v 5.2.2.1 1992/02/09 15:08:56 jsp beta $ + * + */ + +#include "am.h" + +#ifdef HAS_PFS + +/* + * Program file system + */ + +/* + * Execute needs a mount and unmount command. + */ +static char *pfs_match(fo) +am_opts *fo; +{ + char *prog; + if (!fo->opt_mount || !fo->opt_unmount) { + plog(XLOG_USER, "program: no mount/unmount specified"); + return 0; + } + prog = strchr(fo->opt_mount, ' '); + return strdup(prog ? prog+1 : fo->opt_mount); +} + +static int pfs_init(mf) +mntfs *mf; +{ + /* + * Save unmount command + */ + if (mf->mf_refc == 1) { + mf->mf_private = (voidp) strdup(mf->mf_fo->opt_unmount); + mf->mf_prfree = (void (*) ()) free; + } + return 0; +} + +static int pfs_exec(info) +char *info; +{ + char **xivec; + int error; + /* + * Split copy of command info string + */ + info = strdup(info); + if (info == 0) + return ENOBUFS; + xivec = strsplit(info, ' ', '\''); + /* + * Put stdout to stderr + */ + (void) fclose(stdout); + (void) dup(fileno(logfp)); + if (fileno(logfp) != fileno(stderr)) { + (void) fclose(stderr); + (void) dup(fileno(logfp)); + } + /* + * Try the exec + */ +#ifdef DEBUG + Debug(D_FULL) { + char **cp = xivec; + plog(XLOG_DEBUG, "executing (un)mount command..."); + while (*cp) { + plog(XLOG_DEBUG, "arg[%d] = '%s'", cp-xivec, *cp); + cp++; + } + } +#endif /* DEBUG */ + if (xivec[0] == 0 || xivec[1] == 0) { + errno = EINVAL; + plog(XLOG_USER, "1st/2nd args missing to (un)mount program"); + } else { + (void) execv(xivec[0], xivec+1); + } + /* + * Save error number + */ + error = errno; + plog(XLOG_ERROR, "exec failed: %m"); + + /* + * Free allocate memory + */ + free((voidp) info); + free((voidp) xivec); + /* + * Return error + */ + return error; +} + +static int pfs_fmount(mf) +mntfs *mf; +{ + return pfs_exec(mf->mf_fo->opt_mount); +} + +static int pfs_fumount(mf) +mntfs *mf; +{ + return pfs_exec((char *) mf->mf_private); +} + +/* + * Ops structure + */ +am_ops pfs_ops = { + "program", + pfs_match, + pfs_init, + auto_fmount, + pfs_fmount, + auto_fumount, + pfs_fumount, + efs_lookuppn, + efs_readdir, + 0, /* pfs_readlink */ + 0, /* pfs_mounted */ + 0, /* pfs_umounted */ + find_afs_srvr, + FS_BACKGROUND|FS_AMQINFO +}; + +#endif /* HAS_PFS */ diff --git a/usr.sbin/amd/amd/restart.c b/usr.sbin/amd/amd/restart.c new file mode 100644 index 0000000..52a9c87 --- /dev/null +++ b/usr.sbin/amd/amd/restart.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * $Id: restart.c,v 5.2.2.1 1992/02/09 15:08:59 jsp beta $ + * + */ + +#ifndef lint +static char sccsid[] = "@(#)restart.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "am.h" + +/* + * Handle an amd restart. + * + * Scan through the mount list finding all "interesting" mount points. + * Next hack up partial data structures and add the mounted file + * system to the list of known filesystems. This will leave a + * dangling reference to that filesystems, so when the filesystem is + * finally inherited, an extra "free" must be done on it. + * + * This module relies on internal details of other components. If + * you change something else make *sure* restart() still works. + */ +void restart() +{ + /* + * Read the existing mount table + */ + mntlist *ml, *mlp; + + /* + * For each entry, find nfs, ufs or auto mounts + * and create a partial am_node to represent it. + */ + for (mlp = ml = read_mtab("restart"); mlp; mlp = mlp->mnext) { + struct mntent *me = mlp->mnt; + am_ops *fs_ops = 0; + if (STREQ(me->mnt_type, MTAB_TYPE_UFS)) { + /* + * UFS entry + */ + fs_ops = &ufs_ops; + } else if (STREQ(me->mnt_type, MTAB_TYPE_NFS)) { + /* + * NFS entry, or possibly an Amd entry... + */ + int au_pid; + char *colon = strchr(me->mnt_fsname, ':'); + if (colon && sscanf(colon, ":(pid%d)", &au_pid) == 1) { + plog(XLOG_WARNING, "%s is an existing automount point", me->mnt_dir); + fs_ops = &sfs_ops; + } else { + fs_ops = &nfs_ops; + } +#ifdef MTAB_TYPE_MFS + } else if (STREQ(me->mnt_type, MTAB_TYPE_MFS)) { + /* + * MFS entry. Fake with a symlink. + */ + fs_ops = &sfs_ops; +#endif /* MTAB_TYPE_MFS */ + } else { + /* + * Catch everything else with symlinks to + * avoid recursive mounts. This is debatable... + */ + fs_ops = &sfs_ops; + } + + /* + * If we found something to do + */ + if (fs_ops) { + mntfs *mf; + am_opts mo; + char *cp; + cp = strchr(me->mnt_fsname, ':'); + /* + * Partially fake up an opts structure + */ + mo.opt_rhost = 0; + mo.opt_rfs = 0; + if (cp) { + *cp = '\0'; + mo.opt_rhost = strdup(me->mnt_fsname); + mo.opt_rfs = strdup(cp+1); + *cp = ':'; + } else if (fs_ops->ffserver == find_nfs_srvr) { + /* + * Prototype 4.4 BSD used to end up here - + * might as well keep the workaround for now + */ + plog(XLOG_WARNING, "NFS server entry assumed to be %s:/", me->mnt_fsname); + mo.opt_rhost = strdup(me->mnt_fsname); + mo.opt_rfs = strdup("/"); + me->mnt_fsname = str3cat(me->mnt_fsname, mo.opt_rhost, ":", "/"); + } + mo.opt_fs = me->mnt_dir; + mo.opt_opts = me->mnt_opts; + + /* + * Make a new mounted filesystem + */ + mf = find_mntfs(fs_ops, &mo, me->mnt_dir, + me->mnt_fsname, "", me->mnt_opts, ""); + if (mf->mf_refc == 1) { + mf->mf_flags |= MFF_RESTART|MFF_MOUNTED; + mf->mf_error = 0; /* Already mounted correctly */ + mf->mf_fo = 0; + /* + * If the restarted type is a link then + * don't time out. + */ + if (fs_ops == &sfs_ops || fs_ops == &ufs_ops) + mf->mf_flags |= MFF_RSTKEEP; + if (fs_ops->fs_init) { + /* + * Don't care whether this worked since + * it is checked again when the fs is + * inherited. + */ + (void) (*fs_ops->fs_init)(mf); + } + + plog(XLOG_INFO, "%s restarted fstype %s on %s", + me->mnt_fsname, fs_ops->fs_type, me->mnt_dir); + } else { + /* Something strange happened - two mounts at the same place! */ + free_mntfs(mf); + } + /* + * Clean up mo + */ + if (mo.opt_rhost) + free(mo.opt_rhost); + if (mo.opt_rfs) + free(mo.opt_rfs); + } + } + + /* + * Free the mount list + */ + free_mntlist(ml); +} diff --git a/usr.sbin/amd/amd/rpc_fwd.c b/usr.sbin/amd/amd/rpc_fwd.c new file mode 100644 index 0000000..aaf1e0a --- /dev/null +++ b/usr.sbin/amd/amd/rpc_fwd.c @@ -0,0 +1,430 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)rpc_fwd.c 8.1 (Berkeley) 6/6/93 + * + * $Id: rpc_fwd.c,v 5.2.2.1 1992/02/09 15:09:01 jsp beta $ + * + */ + +/* + * RPC packet forwarding + */ + +#include "am.h" +#include +#ifndef F_SETFL +#include +#endif /* F_SETFL */ +#ifndef FNDELAY +#include +#endif /* FNDELAY */ + +/* + * Note that the ID field in the external packet is only + * ever treated as a 32 bit opaque data object, so there + * is no need to convert to and from network byte ordering. + */ + +/* + * Each pending reply has an rpc_forward structure + * associated with it. These have a 15 second lifespan. + * If a new structure is required, then an expired + * one will be re-allocated if available, otherwise a fresh + * one is allocated. Whenever a reply is received the + * structure is discarded. + */ +typedef struct rpc_forward rpc_forward; +struct rpc_forward { + qelem rf_q; /* Linked list */ + time_t rf_ttl; /* Time to live */ + u_int rf_xid; /* Packet id */ + u_int rf_oldid; /* Original packet id */ + fwd_fun rf_fwd; /* Forwarding function */ + voidp rf_ptr; + struct sockaddr_in rf_sin; +}; + +/* + * Head of list of pending replies + */ +extern qelem rpc_head; +qelem rpc_head = { &rpc_head, &rpc_head }; + +static u_int xid; +#define XID_ALLOC() (xid++) + +#define MAX_PACKET_SIZE 8192 /* Maximum UDP packet size */ + +int fwd_sock; + +/* + * Allocate a rely structure + */ +static rpc_forward *fwd_alloc() +{ + time_t now = clocktime(); + rpc_forward *p = 0, *p2; + +#ifdef DEBUG + /*dlog("fwd_alloca: rpc_head = %#x", rpc_head.q_forw);*/ +#endif /* DEBUG */ + /* + * First search for an existing expired one. + */ + ITER(p2, rpc_forward, &rpc_head) { + if (p2->rf_ttl <= now) { + p = p2; + break; + } + } + + /* + * If one couldn't be found then allocate + * a new structure and link it at the + * head of the list. + */ + if (p) { + /* + * Call forwarding function to say that + * this message was junked. + */ +#ifdef DEBUG + dlog("Re-using packet forwarding slot - id %#x", p->rf_xid); +#endif /* DEBUG */ + if (p->rf_fwd) + (*p->rf_fwd)(0, 0, 0, &p->rf_sin, p->rf_ptr, FALSE); + rem_que(&p->rf_q); + } else { + p = ALLOC(rpc_forward); + } + ins_que(&p->rf_q, &rpc_head); + + /* + * Set the time to live field + * Timeout in 43 seconds + */ + p->rf_ttl = now + 43; + +#ifdef DEBUG + /*dlog("fwd_alloca: rpc_head = %#x", rpc_head.q_forw);*/ +#endif /* DEBUG */ + return p; +} + +/* + * Free an allocated reply structure. + * First unlink it from the list, then + * discard it. + */ +static void fwd_free(p) +rpc_forward *p; +{ +#ifdef DEBUG + /*dlog("fwd_free: rpc_head = %#x", rpc_head.q_forw);*/ +#endif /* DEBUG */ + rem_que(&p->rf_q); +#ifdef DEBUG + /*dlog("fwd_free: rpc_head = %#x", rpc_head.q_forw);*/ +#endif /* DEBUG */ + free((voidp) p); +} + +/* + * Initialise the RPC forwarder + */ +int fwd_init() +{ + int on = 1; + + /* + * Create ping socket + */ + fwd_sock = socket(AF_INET, SOCK_DGRAM, 0); + if (fwd_sock < 0) { + plog(XLOG_ERROR, "Unable to create RPC forwarding socket: %m"); + return errno; + } + + /* + * Some things we talk to require a priv port - so make one here + */ + if (bind_resv_port(fwd_sock, (unsigned short *) 0) < 0) + plog(XLOG_ERROR, "can't bind privileged port"); + + if (fcntl(fwd_sock, F_SETFL, FNDELAY) < 0 && + ioctl(fwd_sock, FIONBIO, &on) < 0) { + plog(XLOG_ERROR, "Can't set non-block on forwarding socket: %m"); + return errno; + } + + return 0; +} + +/* + * Locate a packet in the forwarding list + */ +static rpc_forward *fwd_locate(id) +u_int id; +{ + rpc_forward *p; + + ITER(p, rpc_forward, &rpc_head) { + if (p->rf_xid == id) + return p; + } + + return 0; +} + +/* + * This is called to forward a packet to another + * RPC server. The message id is changed and noted + * so that when a reply appears we can tie it up + * correctly. Just matching the reply's source address + * would not work because it might come from a + * different address. + */ +int fwd_packet(type_id, pkt, len, fwdto, replyto, i, cb) +int type_id; +voidp pkt; +int len; +struct sockaddr_in *fwdto, *replyto; +voidp i; +fwd_fun cb; +{ + rpc_forward *p; + u_int *pkt_int; + int error; + + if ((int)amd_state >= (int)Finishing) + return ENOENT; + + /* + * See if the type_id is fully specified. + * If so, then discard any old entries + * for this id. + * Otherwise make sure the type_id is + * fully qualified by allocating an id here. + */ +#ifdef DEBUG + switch (type_id & RPC_XID_MASK) { + case RPC_XID_PORTMAP: dlog("Sending PORTMAP request"); break; + case RPC_XID_MOUNTD: dlog("Sending MOUNTD request %#x", type_id); break; + case RPC_XID_NFSPING: dlog("Sending NFS ping"); break; + default: dlog("UNKNOWN RPC XID"); break; + } +#endif /* DEBUG */ + + if (type_id & ~RPC_XID_MASK) { +#ifdef DEBUG + /*dlog("Fully qualified rpc type provided");*/ +#endif /* DEBUG */ + p = fwd_locate(type_id); + if (p) { +#ifdef DEBUG + dlog("Discarding earlier rpc fwd handle"); +#endif /* DEBUG */ + fwd_free(p); + } + } else { +#ifdef DEBUG + dlog("Allocating a new xid..."); +#endif /* DEBUG */ + type_id = MK_RPC_XID(type_id, XID_ALLOC()); + } + + p = fwd_alloc(); + if (!p) + return ENOBUFS; + + error = 0; + + pkt_int = (u_int *) pkt; + + /* + * Get the original packet id + */ + p->rf_oldid = *pkt_int; + + /* + * Replace with newly allocated id + */ + p->rf_xid = *pkt_int = type_id; + + /* + * The sendto may fail if, for example, the route + * to a remote host is lost because an intermediate + * gateway has gone down. Important to fill in the + * rest of "p" otherwise nasty things happen later... + */ +#ifdef DEBUG + { char dq[20]; + dlog("Sending packet id %#x to %s.%d", p->rf_xid, inet_dquad(dq, fwdto->sin_addr.s_addr), ntohs(fwdto->sin_port)); + } +#endif /* DEBUG */ + if (sendto(fwd_sock, (char *) pkt, len, 0, + (struct sockaddr *) fwdto, sizeof(*fwdto)) < 0) + error = errno; + + /* + * Save callback function and return address + */ + p->rf_fwd = cb; + if (replyto) + p->rf_sin = *replyto; + else + bzero((voidp) &p->rf_sin, sizeof(p->rf_sin)); + p->rf_ptr = i; + + return error; +} + +/* + * Called when some data arrives on the forwarding socket + */ +void fwd_reply() +{ + int len; +#ifdef DYNAMIC_BUFFERS + voidp pkt; +#else + u_int pkt[MAX_PACKET_SIZE/sizeof(u_int)+1]; +#endif /* DYNAMIC_BUFFERS */ + u_int *pkt_int; + int rc; + rpc_forward *p; + struct sockaddr_in src_addr; + int src_addr_len; + + /* + * Determine the length of the packet + */ +#ifdef DYNAMIC_BUFFERS + if (ioctl(fwd_sock, FIONREAD, &len) < 0) { + plog(XLOG_ERROR, "Error reading packet size: %m"); + return; + } + + /* + * Allocate a buffer + */ + pkt = (voidp) malloc((unsigned) len); + if (!pkt) { + plog(XLOG_ERROR, "Out of buffers in fwd_reply"); + return; + } +#else + len = MAX_PACKET_SIZE; +#endif /* DYNAMIC_BUFFERS */ + + /* + * Read the packet and check for validity + */ +again: + src_addr_len = sizeof(src_addr); + rc = recvfrom(fwd_sock, (char *) pkt, len, 0, + (struct sockaddr *) &src_addr, &src_addr_len); + if (rc < 0 || src_addr_len != sizeof(src_addr) || + src_addr.sin_family != AF_INET) { + if (rc < 0 && errno == EINTR) + goto again; + plog(XLOG_ERROR, "Error reading RPC reply: %m"); + goto out; + } + +#ifdef DYNAMIC_BUFFERS + if (rc != len) { + plog(XLOG_ERROR, "Short read in fwd_reply"); + goto out; + } +#endif /* DYNAMIC_BUFFERS */ + + /* + * Do no more work if finishing soon + */ + if ((int)amd_state >= (int)Finishing) + goto out; + + /* + * Find packet reference + */ + pkt_int = (u_int *) pkt; + +#ifdef DEBUG + switch (*pkt_int & RPC_XID_MASK) { + case RPC_XID_PORTMAP: dlog("Receiving PORTMAP reply"); break; + case RPC_XID_MOUNTD: dlog("Receiving MOUNTD reply %#x", *pkt_int); break; + case RPC_XID_NFSPING: dlog("Receiving NFS ping %#x", *pkt_int); break; + default: dlog("UNKNOWN RPC XID"); break; + } +#endif /* DEBUG */ + + p = fwd_locate(*pkt_int); + if (!p) { +#ifdef DEBUG + dlog("Can't forward reply id %#x", *pkt_int); +#endif /* DEBUG */ + goto out; + } + + if (p->rf_fwd) { + /* + * Put the original message id back + * into the packet. + */ + *pkt_int = p->rf_oldid; + + /* + * Call forwarding function + */ + (*p->rf_fwd)((voidp) pkt, rc, &src_addr, &p->rf_sin, p->rf_ptr, TRUE); + } + + /* + * Free forwarding info + */ + fwd_free(p); + +out:; +#ifdef DYNAMIC_BUFFERS + /* + * Free the packet + */ + free((voidp) pkt); +#endif /* DYNAMIC_BUFFERS */ +} diff --git a/usr.sbin/amd/amd/sched.c b/usr.sbin/amd/amd/sched.c new file mode 100644 index 0000000..cd12e3b --- /dev/null +++ b/usr.sbin/amd/amd/sched.c @@ -0,0 +1,325 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)sched.c 8.1 (Berkeley) 6/6/93 + * + * $Id: sched.c,v 5.2.2.1 1992/02/09 15:09:02 jsp beta $ + * + */ + +/* + * Process scheduler + */ + +#include "am.h" +#include +#include WAIT +#include +extern jmp_buf select_intr; +extern int select_intr_valid; + +typedef struct pjob pjob; +struct pjob { + qelem hdr; /* Linked list */ + int pid; /* Process ID of job */ + cb_fun cb_fun; /* Callback function */ + voidp cb_closure; /* Closure for callback */ + union wait w; /* Status filled in by sigchld */ + voidp wchan; /* Wait channel */ +}; + +extern qelem proc_list_head; +qelem proc_list_head = { &proc_list_head, &proc_list_head }; +extern qelem proc_wait_list; +qelem proc_wait_list = { &proc_wait_list, &proc_wait_list }; + +int task_notify_todo; + +void ins_que(elem, pred) +qelem *elem, *pred; +{ + qelem *p = pred->q_forw; + elem->q_back = pred; + elem->q_forw = p; + pred->q_forw = elem; + p->q_back = elem; +} + +void rem_que(elem) +qelem *elem; +{ + qelem *p = elem->q_forw; + qelem *p2 = elem->q_back; + p2->q_forw = p; + p->q_back = p2; +} + +static pjob *sched_job(cf, ca) +cb_fun cf; +voidp ca; +{ + pjob *p = ALLOC(pjob); + + p->cb_fun = cf; + p->cb_closure = ca; + + /* + * Now place on wait queue + */ + ins_que(&p->hdr, &proc_wait_list); + + return p; +} + +void run_task(tf, ta, cf, ca) +task_fun tf; +voidp ta; +cb_fun cf; +voidp ca; +{ + pjob *p = sched_job(cf, ca); + int mask; + + p->wchan = (voidp) p; + + mask = sigblock(sigmask(SIGCHLD)); + + if (p->pid = background()) { + sigsetmask(mask); + return; + } + + exit((*tf)(ta)); + /* firewall... */ + abort(); +} + +/* + * Schedule a task to be run when woken up + */ +void sched_task(cf, ca, wchan) +cb_fun cf; +voidp ca; +voidp wchan; +{ + /* + * Allocate a new task + */ + pjob *p = sched_job(cf, ca); +#ifdef DEBUG_SLEEP + dlog("SLEEP on %#x", wchan); +#endif + p->wchan = wchan; + p->pid = 0; + bzero((voidp) &p->w, sizeof(p->w)); +} + +static void wakeupjob(p) +pjob *p; +{ + rem_que(&p->hdr); + ins_que(&p->hdr, &proc_list_head); + task_notify_todo++; +} + +void wakeup(wchan) +voidp wchan; +{ + pjob *p, *p2; +#ifdef DEBUG_SLEEP + int done = 0; +#endif + if (!foreground) + return; + +#ifdef DEBUG_SLEEP + /*dlog("wakeup(%#x)", wchan);*/ +#endif + /* + * Can't user ITER() here because + * wakeupjob() juggles the list. + */ + for (p = FIRST(pjob, &proc_wait_list); + p2 = NEXT(pjob, p), p != HEAD(pjob, &proc_wait_list); + p = p2) { + if (p->wchan == wchan) { +#ifdef DEBUG_SLEEP + done = 1; +#endif + wakeupjob(p); + } + } + +#ifdef DEBUG_SLEEP + if (!done) + dlog("Nothing SLEEPing on %#x", wchan); +#endif +} + +void wakeup_task(rc, term, cl) +int rc; +int term; +voidp cl; +{ + wakeup(cl); +} + +/*ARGSUSED*/ + +void sigchld(sig) +int sig; +{ + union wait w; + int pid; + +#ifdef SYS5_SIGNALS + if ((pid = wait(&w)) > 0) { +#else + while ((pid = wait3((int *) &w, WNOHANG, (struct rusage *) 0)) > 0) { +#endif /* SYS5_SIGNALS */ + pjob *p, *p2; + + if (WIFSIGNALED(w)) + plog(XLOG_ERROR, "Process %d exited with signal %d", + pid, w.w_termsig); +#ifdef DEBUG + else + dlog("Process %d exited with status %d", + pid, w.w_retcode); +#endif /* DEBUG */ + + for (p = FIRST(pjob, &proc_wait_list); + p2 = NEXT(pjob, p), p != HEAD(pjob, &proc_wait_list); + p = p2) { + if (p->pid == pid) { + p->w = w; + wakeupjob(p); + break; + } + } + +#ifdef DEBUG + if (p) ; else dlog("can't locate task block for pid %d", pid); +#endif /* DEBUG */ + } + +#ifdef SYS5_SIGNALS + signal(sig, sigchld); +#endif /* SYS5_SIGNALS */ + if (select_intr_valid) + longjmp(select_intr, sig); +} + +/* + * Run any pending tasks. + * This must be called with SIGCHLD disabled + */ +void do_task_notify(P_void) +{ + /* + * Keep taking the first item off the list and processing it. + * + * Done this way because the the callback can, quite reasonably, + * queue a new task, so no local reference into the list can be + * held here. + */ + while (FIRST(pjob, &proc_list_head) != HEAD(pjob, &proc_list_head)) { + pjob *p = FIRST(pjob, &proc_list_head); + rem_que(&p->hdr); + /* + * This job has completed + */ + --task_notify_todo; + + /* + * Do callback if it exists + */ + if (p->cb_fun) + (*p->cb_fun)(p->w.w_retcode, + p->w.w_termsig, p->cb_closure); + + free((voidp) p); + } +} + +#ifdef HAS_SVR3_SIGNALS +/* + * 4.2 signal library based on svr3 (4.1+ bsd) interface + * From Stephen C. Pope +#endif + +#ifdef NEED_SFS_MATCH +/* + * SFS needs a link. + */ +static char *sfs_match(fo) +am_opts *fo; +{ + if (!fo->opt_fs) { + plog(XLOG_USER, "link: no fs specified"); + return 0; + } + + /* + * Bug report (14/12/89) from Jay Plett + * If an automount point has the same name as an existing + * link type mount Amd hits a race condition and either hangs + * or causes a symlink loop. + * + * If fs begins with a '/' change the opt_fs & opt_sublink + * fields so that the fs option doesn't end up pointing at + * an existing symlink. + * + * If sublink is nil then set sublink to fs + * else set sublink to fs / sublink + * + * Finally set fs to ".". + */ + if (*fo->opt_fs == '/') { + char *fullpath; + char *link = fo->opt_sublink; + if (link) { + if (*link == '/') + fullpath = strdup(link); + else + fullpath = str3cat((char *)0, fo->opt_fs, "/", link); + } else { + fullpath = strdup(fo->opt_fs); + } + + if (fo->opt_sublink) + free(fo->opt_sublink); + fo->opt_sublink = fullpath; + fo->opt_fs = str3cat(fo->opt_fs, ".", fullpath, ""); + } + + return strdup(fo->opt_fs); +} +#endif + +#ifdef HAS_SFSX +/*ARGUSED*/ +static int sfsx_mount P((am_node *mp)); +static int sfsx_mount(mp) +am_node *mp; +{ + /* + * Check for existence of target. + */ + struct stat stb; + char *ln; + + if (mp->am_link) + ln = mp->am_link; + else /* should never occur */ + ln = mp->am_mnt->mf_mount; + + /* + * Use lstat, not stat, since we don't + * want to know if the ultimate target of + * a symlink chain exists, just the first. + */ + if (lstat(ln, &stb) < 0) + return errno; + + return 0; +} +#endif + +#ifdef HAS_SFS +/*ARGUSED*/ +static int sfs_fmount(mf) +mntfs *mf; +{ + /* + * Wow - this is hard to implement! + */ + + return 0; +} +#endif + +#ifdef NEED_SFS_UMOUNT +/*ARGUSED*/ +static int sfs_fumount(mf) +mntfs *mf; +{ + return 0; +} +#endif + +/* + * Ops structures + */ +#ifdef HAS_SFS +am_ops sfs_ops = { + "link", + sfs_match, + 0, /* sfs_init */ + auto_fmount, + sfs_fmount, + auto_fumount, + sfs_fumount, + efs_lookuppn, + efs_readdir, + 0, /* sfs_readlink */ + 0, /* sfs_mounted */ + 0, /* sfs_umounted */ + find_afs_srvr, +#ifdef FLUSH_KERNEL_NAME_CACHE + FS_UBACKGROUND +#else /* FLUSH_KERNEL_NAME_CACHE */ + 0 +#endif /* FLUSH_KERNEL_NAME_CACHE */ +}; + +#endif /* HAS_SFS */ + +#ifdef HAS_SFSX +struct am_ops sfsx_ops = { + "linkx", + sfs_match, + 0, /* sfsx_init */ + sfsx_mount, + 0, + auto_fumount, + sfs_fumount, + efs_lookuppn, + efs_readdir, + 0, /* sfsx_readlink */ + 0, /* sfsx_mounted */ + 0, /* sfsx_umounted */ + find_afs_srvr, +#ifdef FLUSH_KERNEL_NAME_CACHE + FS_BACKGROUND +#else /* FLUSH_KERNEL_NAME_CACHE */ + FS_MBACKGROUND +#endif /* FLUSH_KERNEL_NAME_CACHE */ +}; + +#endif /* HAS_SFSX */ diff --git a/usr.sbin/amd/amd/srvr_afs.c b/usr.sbin/amd/amd/srvr_afs.c new file mode 100644 index 0000000..0440777 --- /dev/null +++ b/usr.sbin/amd/amd/srvr_afs.c @@ -0,0 +1,205 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)srvr_afs.c 8.1 (Berkeley) 6/6/93 + * + * $Id: srvr_afs.c,v 5.2.2.1 1992/02/09 15:09:05 jsp beta $ + * + */ + +/* + * Automount FS server ("localhost") modeling + */ + +#include "am.h" + +extern qelem afs_srvr_list; +qelem afs_srvr_list = { &afs_srvr_list, &afs_srvr_list }; + +static fserver *localhost; + +/* + * Find an nfs server for the local host + */ +fserver *find_afs_srvr P((mntfs *)); +fserver *find_afs_srvr(mf) +mntfs *mf; +{ + fserver *fs = localhost; + + if (!fs) { + fs = ALLOC(fserver); + fs->fs_refc = 0; + fs->fs_host = strdup("localhost"); + fs->fs_ip = 0; + fs->fs_cid = 0; + fs->fs_pinger = 0; + fs->fs_flags = FSF_VALID; + fs->fs_type = "local"; + fs->fs_private = 0; + fs->fs_prfree = 0; + + ins_que(&fs->fs_q, &afs_srvr_list); + + srvrlog(fs, "starts up"); + + localhost = fs; + } + + fs->fs_refc++; + + return fs; +} + +/*------------------------------------------------------------------*/ + /* Generic routines follow */ + +/* + * Wakeup anything waiting for this server + */ +void wakeup_srvr P((fserver *fs)); +void wakeup_srvr(fs) +fserver *fs; +{ + fs->fs_flags &= ~FSF_WANT; + wakeup((voidp) fs); +} + +/* + * Called when final ttl of server has expired + */ +static void timeout_srvr P((fserver *fs)); +static void timeout_srvr(fs) +fserver *fs; +{ + /* + * If the reference count is still zero then + * we are free to remove this node + */ + if (fs->fs_refc == 0) { +#ifdef DEBUG + dlog("Deleting file server %s", fs->fs_host); +#endif /* DEBUG */ + if (fs->fs_flags & FSF_WANT) + wakeup_srvr(fs); + + /* + * Remove from queue. + */ + rem_que(&fs->fs_q); + /* + * (Possibly) call the private free routine. + */ + if (fs->fs_private && fs->fs_prfree) + (*fs->fs_prfree)(fs->fs_private); + + /* + * Free the net address + */ + if (fs->fs_ip) + free((voidp) fs->fs_ip); + + /* + * Free the host name. + */ + free((voidp) fs->fs_host); + + /* + * Discard the fserver object. + */ + free((voidp) fs); + } +} + +/* + * Free a file server + */ +void free_srvr P((fserver *fs)); +void free_srvr(fs) +fserver *fs; +{ + if (--fs->fs_refc == 0) { + /* + * The reference count is now zero, + * so arrange for this node to be + * removed in AM_TTL seconds if no + * other mntfs is referencing it. + */ + int ttl = (fs->fs_flags & (FSF_DOWN|FSF_ERROR)) ? 19 : AM_TTL; +#ifdef DEBUG + dlog("Last hard reference to file server %s - will timeout in %ds", fs->fs_host, ttl); +#endif /* DEBUG */ + if (fs->fs_cid) { + untimeout(fs->fs_cid); + /* + * Turn off pinging - XXX + */ + fs->fs_flags &= ~FSF_PINGING; + } + /* + * Keep structure lying around for a while + */ + fs->fs_cid = timeout(ttl, timeout_srvr, (voidp) fs); + /* + * Mark the fileserver down and invalid again + */ + fs->fs_flags &= ~FSF_VALID; + fs->fs_flags |= FSF_DOWN; + } +} + +/* + * Make a duplicate fserver reference + */ +fserver *dup_srvr P((fserver *fs)); +fserver *dup_srvr(fs) +fserver *fs; +{ + fs->fs_refc++; + return fs; +} + +/* + * Log state change + */ +void srvrlog P((fserver *fs, char *state)); +void srvrlog(fs, state) +fserver *fs; +char *state; +{ + plog(XLOG_INFO, "file server %s type %s %s", fs->fs_host, fs->fs_type, state); +} diff --git a/usr.sbin/amd/amd/srvr_nfs.c b/usr.sbin/amd/amd/srvr_nfs.c new file mode 100644 index 0000000..4987c95 --- /dev/null +++ b/usr.sbin/amd/amd/srvr_nfs.c @@ -0,0 +1,719 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)srvr_nfs.c 8.1 (Berkeley) 6/6/93 + * + * $Id: srvr_nfs.c,v 5.2.2.1 1992/02/09 15:09:06 jsp beta $ + * + */ + +/* + * NFS server modeling + */ + +#include "am.h" +#include +#include +#include "mount.h" + +extern qelem nfs_srvr_list; +qelem nfs_srvr_list = { &nfs_srvr_list, &nfs_srvr_list }; + +typedef struct nfs_private { + u_short np_mountd; /* Mount daemon port number */ + char np_mountd_inval; /* Port *may* be invalid */ + int np_ping; /* Number of failed ping attempts */ + time_t np_ttl; /* Time when server is thought dead */ + int np_xid; /* RPC transaction id for pings */ + int np_error; /* Error during portmap request */ +} nfs_private; + +static int np_xid; /* For NFS pings */ +#define NPXID_ALLOC() (++np_xid) +/*#define NPXID_ALLOC() ((++np_xid&0x0fffffff) == 0 ? npxid_gc() : np_xid)*/ + +/* + * Number of pings allowed to fail before host is declared down + * - three-fifths of the allowed mount time... +#define MAX_ALLOWED_PINGS ((((ALLOWED_MOUNT_TIME + 5 * AM_PINGER - 1) * 3) / 5) / AM_PINGER) + */ +#define MAX_ALLOWED_PINGS (3 + /* for luck ... */ 1) + +/* + * How often to ping when starting a new server + */ +#define FAST_NFS_PING 3 + +#if (FAST_NFS_PING * MAX_ALLOWED_PINGS) >= ALLOWED_MOUNT_TIME + #error: sanity check failed +/* + you cannot do things this way... + sufficient fast pings must be given the chance to fail + within the allowed mount time + */ +#endif /* (FAST_NFS_PING * MAX_ALLOWED_PINGS) >= ALLOWED_MOUNT_TIME */ + +static int ping_len; +static char ping_buf[sizeof(struct rpc_msg) + 32]; + +/* + * Flush any cached data + */ +void flush_srvr_nfs_cache P((void)); +void flush_srvr_nfs_cache() +{ + fserver *fs = 0; + + ITER(fs, fserver, &nfs_srvr_list) { + nfs_private *np = (nfs_private *) fs->fs_private; + if (np) { + np->np_mountd_inval = TRUE; + np->np_error = -1; + } + } +} + +/* + * Startup the NFS ping + */ +static void start_ping(P_void); +static void start_ping() +{ + XDR ping_xdr; + struct rpc_msg ping_msg; + + rpc_msg_init(&ping_msg, NFS_PROGRAM, NFS_VERSION, NFSPROC_NULL); + + /* + * Create an XDR endpoint + */ + xdrmem_create(&ping_xdr, ping_buf, sizeof(ping_buf), XDR_ENCODE); + + /* + * Create the NFS ping message + */ + if (!xdr_callmsg(&ping_xdr, &ping_msg)) { + plog(XLOG_ERROR, "Couldn't create ping RPC message"); + going_down(3); + } + + /* + * Find out how long it is + */ + ping_len = xdr_getpos(&ping_xdr); + + /* + * Destroy the XDR endpoint - we don't need it anymore + */ + xdr_destroy(&ping_xdr); +} + + +/* + * Called when a portmap reply arrives + */ +/*ARGSUSED*/ +static void got_portmap P((voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia, voidp idv, int done)); +static void got_portmap(pkt, len, sa, ia, idv, done) +voidp pkt; +int len; +struct sockaddr_in *sa; +struct sockaddr_in *ia; +voidp idv; +int done; +{ + fserver *fs2 = (fserver *) idv; + fserver *fs = 0; + + /* + * Find which fileserver we are talking about + */ + ITER(fs, fserver, &nfs_srvr_list) + if (fs == fs2) + break; + + if (fs == fs2) { + u_long port = 0; /* XXX - should be short but protocol is naff */ + int error = done ? pickup_rpc_reply(pkt, len, (voidp) &port, xdr_u_long) : -1; + nfs_private *np = (nfs_private *) fs->fs_private; + if (!error && port) { +#ifdef DEBUG + dlog("got port (%d) for mountd on %s", port, fs->fs_host); +#endif /* DEBUG */ + /* + * Grab the port number. Portmap sends back + * an unsigned long in native ordering, so it + * needs converting to a unsigned short in + * network ordering. + */ + np->np_mountd = htons((u_short) port); + np->np_mountd_inval = FALSE; + np->np_error = 0; + } else { +#ifdef DEBUG + dlog("Error fetching port for mountd on %s", fs->fs_host); +#endif /* DEBUG */ + /* + * Almost certainly no mountd running on remote host + */ + np->np_error = error ? error : ETIMEDOUT; + } + if (fs->fs_flags & FSF_WANT) + wakeup_srvr(fs); + } else if (done) { +#ifdef DEBUG + dlog("Got portmap for old port request"); +#endif /* DEBUG */ + } else { +#ifdef DEBUG + dlog("portmap request timed out"); +#endif /* DEBUG */ + } +} + +/* + * Obtain portmap information + */ +static int call_portmap P((fserver *fs, AUTH *auth, unsigned long prog, unsigned long vers, unsigned long prot)); +static int call_portmap(fs, auth, prog, vers, prot) +fserver *fs; +AUTH *auth; +unsigned long prog, vers, prot; +{ + struct rpc_msg pmap_msg; + int len; + char iobuf[UDPMSGSIZE]; + int error; + struct pmap pmap; + + rpc_msg_init(&pmap_msg, PMAPPROG, PMAPVERS, (unsigned long) 0); + pmap.pm_prog = prog; + pmap.pm_vers = vers; + pmap.pm_prot = prot; + pmap.pm_port = 0; + len = make_rpc_packet(iobuf, sizeof(iobuf), PMAPPROC_GETPORT, + &pmap_msg, (voidp) &pmap, xdr_pmap, auth); + if (len > 0) { + struct sockaddr_in sin; + bzero((voidp) &sin, sizeof(sin)); + sin = *fs->fs_ip; + sin.sin_port = htons(PMAPPORT); + error = fwd_packet(RPC_XID_PORTMAP, (voidp) iobuf, len, + &sin, &sin, (voidp) fs, got_portmap); + } else { + error = -len; + } + return error; +} + +static void nfs_keepalive P((fserver*)); + +static void recompute_portmap P((fserver *fs)); +static void recompute_portmap(fs) +fserver *fs; +{ + int error; + + if (nfs_auth) + error = 0; + else + error = make_nfs_auth(); + + if (error) { + nfs_private *np = (nfs_private *) fs->fs_private; + np->np_error = error; + } else { + call_portmap(fs, nfs_auth, MOUNTPROG, + MOUNTVERS, (unsigned long) IPPROTO_UDP); + } +} + +/* + * This is called when we get a reply to an RPC ping. + * The value of id was taken from the nfs_private + * structure when the ping was transmitted. + */ +/*ARGSUSED*/ +static void nfs_pinged P((voidp pkt, int len, struct sockaddr_in *sp, struct sockaddr_in *tsp, voidp idv, int done)); +static void nfs_pinged(pkt, len, sp, tsp, idv, done) +voidp pkt; +int len; +struct sockaddr_in *sp; +struct sockaddr_in *tsp; +voidp idv; +int done; +{ + int xid = (int) idv; + fserver *fs; +#ifdef DEBUG + int found_map = 0; +#endif /* DEBUG */ + + if (!done) + return; + + /* + * For each node... + */ + ITER(fs, fserver, &nfs_srvr_list) { + nfs_private *np = (nfs_private *) fs->fs_private; + if (np->np_xid == xid) { + /* + * Reset the ping counter. + * Update the keepalive timer. + * Log what happened. + */ + if (fs->fs_flags & FSF_DOWN) { + fs->fs_flags &= ~FSF_DOWN; + if (fs->fs_flags & FSF_VALID) { + srvrlog(fs, "is up"); + } else { + if (np->np_ping > 1) + srvrlog(fs, "ok"); +#ifdef DEBUG + else + srvrlog(fs, "starts up"); +#endif + fs->fs_flags |= FSF_VALID; + } + +#ifdef notdef + /* why ??? */ + if (fs->fs_flags & FSF_WANT) + wakeup_srvr(fs); +#endif /* notdef */ + map_flush_srvr(fs); + } else { + if (fs->fs_flags & FSF_VALID) { +#ifdef DEBUG + dlog("file server %s type nfs is still up", fs->fs_host); +#endif /* DEBUG */ + } else { + if (np->np_ping > 1) + srvrlog(fs, "ok"); + fs->fs_flags |= FSF_VALID; + } + } + + /* + * Adjust ping interval + */ + untimeout(fs->fs_cid); + fs->fs_cid = timeout(fs->fs_pinger, nfs_keepalive, (voidp) fs); + + /* + * Update ttl for this server + */ + np->np_ttl = clocktime() + + (MAX_ALLOWED_PINGS - 1) * FAST_NFS_PING + fs->fs_pinger - 1; + + /* + * New RPC xid... + */ + np->np_xid = NPXID_ALLOC(); + + /* + * Failed pings is zero... + */ + np->np_ping = 0; + + /* + * Recompute portmap information if not known + */ + if (np->np_mountd_inval) + recompute_portmap(fs); + +#ifdef DEBUG + found_map++; +#endif /* DEBUG */ + break; + } + } + +#ifdef DEBUG + if (found_map == 0) + dlog("Spurious ping packet"); +#endif /* DEBUG */ +} + +/* + * Called when no ping-reply received + */ +static void nfs_timed_out P((fserver *fs)); +static void nfs_timed_out(fs) +fserver *fs; +{ + nfs_private *np = (nfs_private *) fs->fs_private; + + /* + * Another ping has failed + */ + np->np_ping++; + + /* + * Not known to be up any longer + */ + if (FSRV_ISUP(fs)) { + fs->fs_flags &= ~FSF_VALID; + if (np->np_ping > 1) + srvrlog(fs, "not responding"); + } + + /* + * If ttl has expired then guess that it is dead + */ + if (np->np_ttl < clocktime()) { + int oflags = fs->fs_flags; + if ((fs->fs_flags & FSF_DOWN) == 0) { + /* + * Server was up, but is now down. + */ + srvrlog(fs, "is down"); + fs->fs_flags |= FSF_DOWN|FSF_VALID; + /* + * Since the server is down, the portmap + * information may now be wrong, so it + * must be flushed from the local cache + */ + flush_nfs_fhandle_cache(fs); + np->np_error = -1; +#ifdef notdef + /* + * Pretend just one ping has failed now + */ + np->np_ping = 1; +#endif + } else { + /* + * Known to be down + */ +#ifdef DEBUG + if ((fs->fs_flags & FSF_VALID) == 0) + srvrlog(fs, "starts down"); +#endif + fs->fs_flags |= FSF_VALID; + } + if (oflags != fs->fs_flags && (fs->fs_flags & FSF_WANT)) + wakeup_srvr(fs); + } else { +#ifdef DEBUG + if (np->np_ping > 1) + dlog("%d pings to %s failed - at most %d allowed", np->np_ping, fs->fs_host, MAX_ALLOWED_PINGS); +#endif /* DEBUG */ + } + + /* + * Run keepalive again + */ + nfs_keepalive(fs); +} + +/* + * Keep track of whether a server is alive + */ +static void nfs_keepalive P((fserver *fs)); +static void nfs_keepalive(fs) +fserver *fs; +{ + int error; + nfs_private *np = (nfs_private *) fs->fs_private; + int fstimeo = -1; + + /* + * Send an NFS ping to this node + */ + + if (ping_len == 0) + start_ping(); + + /* + * Queue the packet... + */ + error = fwd_packet(MK_RPC_XID(RPC_XID_NFSPING, np->np_xid), (voidp) ping_buf, + ping_len, fs->fs_ip, (struct sockaddr_in *) 0, (voidp) np->np_xid, nfs_pinged); + + /* + * See if a hard error occured + */ + switch (error) { + case ENETDOWN: + case ENETUNREACH: + case EHOSTDOWN: + case EHOSTUNREACH: + np->np_ping = MAX_ALLOWED_PINGS; /* immediately down */ + np->np_ttl = (time_t) 0; + /* + * This causes an immediate call to nfs_timed_out + * whenever the server was thought to be up. + * See +++ below. + */ + fstimeo = 0; + break; + + case 0: +#ifdef DEBUG + dlog("Sent NFS ping to %s", fs->fs_host); +#endif /* DEBUG */ + break; + } + +#ifdef DEBUG + /*dlog("keepalive, ping = %d", np->np_ping);*/ +#endif /* DEBUG */ + + /* + * Back off the ping interval if we are not getting replies and + * the remote system is know to be down. + */ + switch (fs->fs_flags & (FSF_DOWN|FSF_VALID)) { + case FSF_VALID: /* Up */ + if (fstimeo < 0) /* +++ see above */ + fstimeo = FAST_NFS_PING; + break; + + case FSF_VALID|FSF_DOWN: /* Down */ + fstimeo = fs->fs_pinger; + break; + + default: /* Unknown */ + fstimeo = FAST_NFS_PING; + break; + } + +#ifdef DEBUG + dlog("NFS timeout in %d seconds", fstimeo); +#endif /* DEBUG */ + + fs->fs_cid = timeout(fstimeo, nfs_timed_out, (voidp) fs); +} + +int nfs_srvr_port P((fserver *fs, u_short *port, voidp wchan)); +int nfs_srvr_port(fs, port, wchan) +fserver *fs; +u_short *port; +voidp wchan; +{ + int error = -1; + if ((fs->fs_flags & FSF_VALID) == FSF_VALID) { + if ((fs->fs_flags & FSF_DOWN) == 0) { + nfs_private *np = (nfs_private *) fs->fs_private; + if (np->np_error == 0) { + *port = np->np_mountd; + error = 0; + } else { + error = np->np_error; + } + /* + * Now go get the port mapping again in case it changed. + * Note that it is used even if (np_mountd_inval) + * is True. The flag is used simply as an + * indication that the mountd may be invalid, not + * that it is known to be invalid. + */ + if (np->np_mountd_inval) + recompute_portmap(fs); + else + np->np_mountd_inval = TRUE; + } else { + error = EWOULDBLOCK; + } + } + if (error < 0 && wchan && !(fs->fs_flags & FSF_WANT)) { + /* + * If a wait channel is supplied, and no + * error has yet occured, then arrange + * that a wakeup is done on the wait channel, + * whenever a wakeup is done on this fs node. + * Wakeup's are done on the fs node whenever + * it changes state - thus causing control to + * come back here and new, better things to happen. + */ + fs->fs_flags |= FSF_WANT; + sched_task(wakeup_task, wchan, (voidp) fs); + } + return error; +} + +static void start_nfs_pings P((fserver *fs, int pingval)); +static void start_nfs_pings(fs, pingval) +fserver *fs; +int pingval; +{ + if (!(fs->fs_flags & FSF_PINGING)) { + fs->fs_flags |= FSF_PINGING; + if (fs->fs_cid) + untimeout(fs->fs_cid); + if (pingval < 0) { + srvrlog(fs, "wired up"); + fs->fs_flags |= FSF_VALID; + fs->fs_flags &= ~FSF_DOWN; + } else { + nfs_keepalive(fs); + } + } else { +#ifdef DEBUG + dlog("Already running pings to %s", fs->fs_host); +#endif /* DEBUG */ + } +} + +/* + * Find an nfs server for a host. + */ +fserver *find_nfs_srvr P((mntfs *mf)); +fserver *find_nfs_srvr(mf) +mntfs *mf; +{ + fserver *fs; + struct hostent *hp = 0; + char *host = mf->mf_fo->opt_rhost; + struct sockaddr_in *ip; + nfs_private *np; + int pingval; + + /* + * Get ping interval from mount options. + * Current only used to decide whether pings + * are required or not. < 0 = no pings. + */ + { struct mntent mnt; + mnt.mnt_opts = mf->mf_mopts; + pingval = hasmntval(&mnt, "ping"); +#ifdef HAS_TCP_NFS + /* + * Over TCP mount, don't bother to do pings. + * This is experimental - maybe you want to + * do pings anyway... + */ + if (pingval == 0 && hasmntopt(&mnt, "tcp")) + pingval = -1; +#endif /* HAS_TCP_NFS */ + } + + + /* + * lookup host address and canonical name + */ + hp = gethostbyname(host); + + /* + * New code from Bob Harris + * Use canonical name to keep track of file server + * information. This way aliases do not generate + * multiple NFS pingers. (Except when we're normalizing + * hosts.) + */ + if (hp && !normalize_hosts) host = hp->h_name; + + ITER(fs, fserver, &nfs_srvr_list) { + if (STREQ(host, fs->fs_host)) { + start_nfs_pings(fs, pingval); + fs->fs_refc++; + return fs; + } + } + + + + /* + * Get here if we can't find an entry + */ + if (hp) { + switch (hp->h_addrtype) { + case AF_INET: + ip = ALLOC(sockaddr_in); + bzero((voidp) ip, sizeof(*ip)); + ip->sin_family = AF_INET; + bcopy((voidp) hp->h_addr, (voidp) &ip->sin_addr, sizeof(ip->sin_addr)); + + ip->sin_port = htons(NFS_PORT); + break; + + default: + ip = 0; + break; + } + } else { + plog(XLOG_USER, "Unknown host: %s", host); + ip = 0; + } + + /* + * Allocate a new server + */ + fs = ALLOC(fserver); + fs->fs_refc = 1; + fs->fs_host = strdup(hp ? hp->h_name : "unknown_hostname"); + if (normalize_hosts) host_normalize(&fs->fs_host); + fs->fs_ip = ip; + fs->fs_cid = 0; + if (ip) { + fs->fs_flags = FSF_DOWN; /* Starts off down */ + } else { + fs->fs_flags = FSF_ERROR|FSF_VALID; + mf->mf_flags |= MFF_ERROR; + mf->mf_error = ENOENT; + } + fs->fs_type = "nfs"; + fs->fs_pinger = AM_PINGER; + np = ALLOC(nfs_private); + bzero((voidp) np, sizeof(*np)); + np->np_mountd_inval = TRUE; + np->np_xid = NPXID_ALLOC(); + np->np_error = -1; + /* + * Initially the server will be deemed dead after + * MAX_ALLOWED_PINGS of the fast variety have failed. + */ + np->np_ttl = clocktime() + MAX_ALLOWED_PINGS * FAST_NFS_PING - 1; + fs->fs_private = (voidp) np; + fs->fs_prfree = (void (*)()) free; + + if (!(fs->fs_flags & FSF_ERROR)) { + /* + * Start of keepalive timer + */ + start_nfs_pings(fs, pingval); + } + + /* + * Add to list of servers + */ + ins_que(&fs->fs_q, &nfs_srvr_list); + + return fs; +} diff --git a/usr.sbin/amd/amd/ufs_ops.c b/usr.sbin/amd/amd/ufs_ops.c new file mode 100644 index 0000000..fd81c37 --- /dev/null +++ b/usr.sbin/amd/amd/ufs_ops.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)ufs_ops.c 8.1 (Berkeley) 6/6/93 + * + * $Id: ufs_ops.c,v 5.2.2.1 1992/02/09 15:09:08 jsp beta $ + * + */ + +#include "am.h" + +#ifdef HAS_UFS + +#include +#ifdef NFS_3 +typedef nfs_fh fhandle_t; +#endif /* NFS_3 */ + +#ifdef UFS_HDR +#include UFS_HDR +#endif /* UFS_HDR */ + +#include + +/* + * UN*X file system + */ + +/* + * UFS needs local filesystem and device. + */ +static char *ufs_match P((am_opts *fo)); +static char *ufs_match(fo) +am_opts *fo; +{ + if (!fo->opt_dev) { + plog(XLOG_USER, "ufs: no device specified"); + return 0; + } + +#ifdef DEBUG + dlog("UFS: mounting device \"%s\" on \"%s\"", + fo->opt_dev, fo->opt_fs); +#endif /* DEBUG */ + + /* + * Determine magic cookie to put in mtab + */ + return strdup(fo->opt_dev); +} + +static mount_ufs(dir, fs_name, opts) +char *dir; +char *fs_name; +char *opts; +{ + struct ufs_args ufs_args; + struct mntent mnt; + int flags; + + /* + * Figure out the name of the file system type. + */ +#ifdef M_NEWTYPE + char *type = MOUNT_TYPE_UFS; +#else + int type = MOUNT_TYPE_UFS; +#endif /* M_NEWTYPE */ + + bzero((voidp) &ufs_args, sizeof(ufs_args)); /* Paranoid */ + + /* + * Fill in the mount structure + */ + mnt.mnt_dir = dir; + mnt.mnt_fsname = fs_name; + mnt.mnt_type = MTAB_TYPE_UFS; + mnt.mnt_opts = opts; + mnt.mnt_freq = 1; + mnt.mnt_passno = 2; + + flags = compute_mount_flags(&mnt); + +#ifdef ULTRIX_HACK + ufs_args.ufs_flags = flags; + ufs_args.ufs_pgthresh = 64; /* 64K - XXX */ + flags &= M_RDONLY; +#else + ufs_args.fspec = fs_name; +#endif /* ULTRIX_HACK */ + + /* + * Call generic mount routine + */ + return mount_fs(&mnt, flags, (caddr_t) &ufs_args, 0, type); +} + +/*ARGSUSED*/ +static int ufs_fmount(mf) +mntfs *mf; +{ + int error; + + error = mount_ufs(mf->mf_mount, mf->mf_info, mf->mf_mopts); + if (error) { + errno = error; + plog(XLOG_ERROR, "mount_ufs: %m"); + return error; + } + + return 0; +} + +static int ufs_fumount(mf) +mntfs *mf; +{ + return UMOUNT_FS(mf->mf_mount); +} + +/* + * Ops structure + */ +am_ops ufs_ops = { + "ufs", + ufs_match, + 0, /* ufs_init */ + auto_fmount, + ufs_fmount, + auto_fumount, + ufs_fumount, + efs_lookuppn, + efs_readdir, + 0, /* ufs_readlink */ + 0, /* ufs_mounted */ + 0, /* ufs_umounted */ + find_afs_srvr, +#ifdef FLUSH_KERNEL_NAME_CACHE + FS_MKMNT|FS_NOTIMEOUT|FS_UBACKGROUND|FS_AMQINFO +#else /* FLUSH_KERNEL_NAME_CACHE */ + FS_MKMNT|FS_NOTIMEOUT|FS_UBACKGROUND|FS_AMQINFO +#endif /* FLUSH_KERNEL_NAME_CACHE */ +}; + +#endif /* HAS_UFS */ diff --git a/usr.sbin/amd/amd/umount_fs.c b/usr.sbin/amd/amd/umount_fs.c new file mode 100644 index 0000000..2c3e73d --- /dev/null +++ b/usr.sbin/amd/amd/umount_fs.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)umount_fs.c 8.1 (Berkeley) 6/6/93 + * + * $Id: umount_fs.c,v 5.2.2.1 1992/02/09 15:09:10 jsp beta $ + * + */ + +#include "am.h" + +#ifdef NEED_UMOUNT_BSD + +int umount_fs P((char *fs_name)); +int umount_fs(fs_name) +char *fs_name; +{ + int error; + +eintr: + error = unmount(fs_name, 0); + if (error < 0) + error = errno; + + switch (error) { + case EINVAL: + case ENOTBLK: + case ENOENT: + plog(XLOG_WARNING, "unmount: %s is not mounted", fs_name); + error = 0; /* Not really an error */ + break; + + case EINTR: +#ifdef DEBUG + /* not sure why this happens, but it does. ask kirk one day... */ + dlog("%s: unmount: %m", fs_name); +#endif /* DEBUG */ + goto eintr; + +#ifdef DEBUG + default: + dlog("%s: unmount: %m", fs_name); + break; +#endif /* DEBUG */ + } + + return error; +} + +#endif /* NEED_UMOUNT_BSD */ + +#ifdef NEED_UMOUNT_OSF + +#include /* For MNT_NOFORCE */ + +int umount_fs(fs_name) +char *fs_name; +{ + int error; + +eintr: + error = umount(fs_name, MNT_NOFORCE); + if (error < 0) + error = errno; + + switch (error) { + case EINVAL: + case ENOTBLK: + plog(XLOG_WARNING, "unmount: %s is not mounted", fs_name); + error = 0; /* Not really an error */ + break; + + case ENOENT: + plog(XLOG_ERROR, "mount point %s: %m", fs_name); + break; + + case EINTR: +#ifdef DEBUG + /* not sure why this happens, but it does. ask kirk one day... */ + dlog("%s: unmount: %m", fs_name); +#endif /* DEBUG */ + goto eintr; + +#ifdef DEBUG + default: + dlog("%s: unmount: %m", fs_name); + break; +#endif /* DEBUG */ + } + + return error; +} + +#endif /* NEED_UMOUNT_OSF */ + +#ifdef NEED_UMOUNT_FS + +int umount_fs(fs_name) +char *fs_name; +{ + mntlist *mlist, *mp, *mp_save = 0; + int error = 0; + + mp = mlist = read_mtab(fs_name); + + /* + * Search the mount table looking for + * the correct (ie last) matching entry + */ + while (mp) { + if (strcmp(mp->mnt->mnt_fsname, fs_name) == 0 || + strcmp(mp->mnt->mnt_dir, fs_name) == 0) + mp_save = mp; + mp = mp->mnext; + } + + if (mp_save) { +#ifdef DEBUG + dlog("Trying unmount(%s)", mp_save->mnt->mnt_dir); +#endif /* DEBUG */ + /* + * This unmount may hang leaving this + * process with an exlusive lock on + * /etc/mtab. Therefore it is necessary + * to unlock mtab, do the unmount, then + * lock mtab (again) and reread it and + * finally update it. + */ + unlock_mntlist(); + if (UNMOUNT_TRAP(mp_save->mnt) < 0) { + switch (error = errno) { + case EINVAL: + case ENOTBLK: + plog(XLOG_WARNING, "unmount: %s is not mounted", mp_save->mnt->mnt_dir); + error = 0; /* Not really an error */ + break; + + case ENOENT: + plog(XLOG_ERROR, "mount point %s: %m", mp_save->mnt->mnt_dir); + break; + + default: +#ifdef DEBUG + dlog("%s: unmount: %m", mp_save->mnt->mnt_dir); +#endif /* DEBUG */ + break; + } + } +#ifdef DEBUG + dlog("Finished unmount(%s)", mp_save->mnt->mnt_dir); +#endif + + +#ifdef UPDATE_MTAB + if (!error) { + free_mntlist(mlist); + mp = mlist = read_mtab(fs_name); + + /* + * Search the mount table looking for + * the correct (ie last) matching entry + */ + mp_save = 0; + while (mp) { + if (strcmp(mp->mnt->mnt_fsname, fs_name) == 0 || + strcmp(mp->mnt->mnt_dir, fs_name) == 0) + mp_save = mp; + mp = mp->mnext; + } + + if (mp_save) { + mnt_free(mp_save->mnt); + mp_save->mnt = 0; + rewrite_mtab(mlist); + } + } +#endif /* UPDATE_MTAB */ + } else { + plog(XLOG_ERROR, "Couldn't find how to unmount %s", fs_name); + /* + * Assume it is already unmounted + */ + error = 0; + } + + free_mntlist(mlist); + + return error; +} + +#endif /* NEED_UMOUNT_FS */ diff --git a/usr.sbin/amd/amd/util.c b/usr.sbin/amd/amd/util.c new file mode 100644 index 0000000..8503cc8 --- /dev/null +++ b/usr.sbin/amd/amd/util.c @@ -0,0 +1,648 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)util.c 8.1 (Berkeley) 6/6/93 + * + * $Id: util.c,v 5.2.2.2 1992/03/07 17:52:06 jsp Exp $ + * + */ + +/* + * Utils + */ + +#include "am.h" +#include +#include +#include + + +char *strnsave(str, len) +Const char *str; +int len; +{ + char *sp = (char *) xmalloc(len+1); + + bcopy(str, sp, len); + sp[len] = 0; + + return sp; +} + +char *strdup(s) +Const char *s; +{ + return strnsave(s, strlen(s)); +} + +/* + * Concatenate three strings and store in buffer pointed to + * by p, making p large enough to hold the strings + */ +char *str3cat(p, s1, s2, s3) +char *p; +char *s1; +char *s2; +char *s3; +{ + int l1 = strlen(s1); + int l2 = strlen(s2); + int l3 = strlen(s3); + p = (char *) xrealloc(p, l1 + l2 + l3 + 1); + bcopy(s1, p, l1); + bcopy(s2, p + l1, l2); + bcopy(s3, p + l1 + l2, l3 + 1); + return p; +} + +char *strealloc(p, s) +char *p; +char *s; +{ + int len = strlen(s) + 1; + + p = (char *) xrealloc((voidp) p, len); + + strcpy(p, s); +#ifdef DEBUG_MEM + malloc_verify(); +#endif /* DEBUG_MEM */ + return p; +} + +char **strsplit P((char *s, int ch, int qc)); +char **strsplit(s, ch, qc) +char *s; +int ch; +int qc; +{ + char **ivec; + int ic = 0; + int done = 0; + + ivec = (char **) xmalloc((ic+1)*sizeof(char *)); + + while (!done) { + char *v; + /* + * skip to split char + */ + while (*s && (ch == ' ' ? (isascii(*s) && isspace(*s)) : *s == ch)) + *s++ = '\0'; + + /* + * End of string? + */ + if (!*s) + break; + + /* + * remember start of string + */ + v = s; + + /* + * skip to split char + */ + while (*s && !(ch == ' ' ? (isascii(*s) && isspace(*s)) : *s == ch)) { + if (*s++ == qc) { + /* + * Skip past string. + */ + s++; + while (*s && *s != qc) + s++; + if (*s == qc) + s++; + } + } + + if (!*s) + done = 1; + *s++ = '\0'; + + /* + * save string in new ivec slot + */ + ivec[ic++] = v; + ivec = (char **) xrealloc((voidp) ivec, (ic+1)*sizeof(char *)); +#ifdef DEBUG + Debug(D_STR) + plog(XLOG_DEBUG, "strsplit saved \"%s\"", v); +#endif /* DEBUG */ + } + +#ifdef DEBUG + Debug(D_STR) + plog(XLOG_DEBUG, "strsplit saved a total of %d strings", ic); +#endif /* DEBUG */ + + ivec[ic] = 0; + + return ivec; +} + +/* + * Strip off the trailing part of a domain + * to produce a short-form domain relative + * to the local host domain. + * Note that this has no effect if the domain + * names do not have the same number of + * components. If that restriction proves + * to be a problem then the loop needs recoding + * to skip from right to left and do partial + * matches along the way -- ie more expensive. + */ +static void domain_strip P((char *otherdom, char *localdom)); +static void domain_strip(otherdom, localdom) +char *otherdom, *localdom; +{ +#ifdef PARTIAL_DOMAINS + char *p1 = otherdom-1; + char *p2 = localdom-1; + + do { + if (p1 = strchr(p1+1, '.')) + if (p2 = strchr(p2+1, '.')) + if (strcmp(p1+1, p2+1) == 0) { + *p1 = '\0'; + break; + } + } while (p1 && p2); +#else + char *p1, *p2; + + if ((p1 = strchr(otherdom, '.')) && + (p2 = strchr(localdom, '.')) && + (strcmp(p1+1, p2+1) == 0)) + *p1 = '\0'; +#endif /* PARTIAL_DOMAINS */ +} + +/* + * Normalize a host name + */ +void host_normalize P((char **chp)); +void host_normalize(chp) +char **chp; +{ + /* + * Normalize hosts is used to resolve host name aliases + * and replace them with the standard-form name. + * Invoked with "-n" command line option. + */ + if (normalize_hosts) { + struct hostent *hp; + clock_valid = 0; + hp = gethostbyname(*chp); + if (hp && hp->h_addrtype == AF_INET) { +#ifdef DEBUG + dlog("Hostname %s normalized to %s", *chp, hp->h_name); +#endif /* DEBUG */ + *chp = strealloc(*chp, hp->h_name); + } + } + domain_strip(*chp, hostd); +} + +/* + * Make a dotted quad from a 32bit IP address + * addr is in network byte order. + * sizeof(buf) needs to be at least 16. + */ +char *inet_dquad P((char *buf, unsigned long addr)); +char *inet_dquad(buf, addr) +char *buf; +unsigned long addr; +{ + addr = ntohl(addr); + sprintf(buf, "%d.%d.%d.%d", + ((addr >> 24) & 0xff), + ((addr >> 16) & 0xff), + ((addr >> 8) & 0xff), + ((addr >> 0) & 0xff)); + return buf; +} + +/* + * Keys are not allowed to contain " ' ! or ; to avoid + * problems with macro expansions. + */ +static char invalid_keys[] = "\"'!;@ \t\n"; +int valid_key P((char *key)); +int valid_key(key) +char *key; +{ + while (*key) + if (strchr(invalid_keys, *key++)) + return FALSE; + return TRUE; +} + +void going_down P((int rc)); +void going_down(rc) +int rc; +{ + if (foreground) { + if (amd_state != Start) { + if (amd_state != Done) + return; + unregister_amq(); + } + } + if (foreground) { + plog(XLOG_INFO, "Finishing with status %d", rc); + } else { +#ifdef DEBUG + dlog("background process exiting with status %d", rc); +#endif /* DEBUG */ + } + + exit(rc); +} + + +int bind_resv_port P((int so, u_short *pp)); +int bind_resv_port(so, pp) +int so; +u_short *pp; +{ + struct sockaddr_in sin; + int rc; + unsigned short port; + + bzero((voidp) &sin, sizeof(sin)); + sin.sin_family = AF_INET; + + port = IPPORT_RESERVED; + + do { + --port; + sin.sin_port = htons(port); + rc = bind(so, (struct sockaddr *) &sin, sizeof(sin)); + } while (rc < 0 && port > IPPORT_RESERVED/2); + + if (pp && rc == 0) + *pp = port; + return rc; +} + +void forcibly_timeout_mp P((am_node *mp)); +void forcibly_timeout_mp(mp) +am_node *mp; +{ + mntfs *mf = mp->am_mnt; + /* + * Arrange to timeout this node + */ + if (mf && ((mp->am_flags & AMF_ROOT) || + (mf->mf_flags & (MFF_MOUNTING|MFF_UNMOUNTING)))) { + if (!(mf->mf_flags & MFF_UNMOUNTING)) + plog(XLOG_WARNING, "ignoring timeout request for active node %s", mp->am_path); + } else { + plog(XLOG_INFO, "\"%s\" forcibly timed out", mp->am_path); + mp->am_flags &= ~AMF_NOTIMEOUT; + mp->am_ttl = clocktime(); + reschedule_timeout_mp(); + } +} + +void mf_mounted P((mntfs *mf)); +void mf_mounted(mf) +mntfs *mf; +{ + int quoted; + int wasmounted = mf->mf_flags & MFF_MOUNTED; + + if (!wasmounted) { + /* + * If this is a freshly mounted + * filesystem then update the + * mntfs structure... + */ + mf->mf_flags |= MFF_MOUNTED; + mf->mf_error = 0; + + /* + * Do mounted callback + */ + if (mf->mf_ops->mounted) + (*mf->mf_ops->mounted)(mf); + + mf->mf_fo = 0; + } + + /* + * Log message + */ + quoted = strchr(mf->mf_info, ' ') != 0; + plog(XLOG_INFO, "%s%s%s %s fstype %s on %s", + quoted ? "\"" : "", + mf->mf_info, + quoted ? "\"" : "", + wasmounted ? "referenced" : "mounted", + mf->mf_ops->fs_type, mf->mf_mount); +} + +void am_mounted P((am_node *mp)); +void am_mounted(mp) +am_node *mp; +{ + mntfs *mf = mp->am_mnt; + + mf_mounted(mf); + + /* + * Patch up path for direct mounts + */ + if (mp->am_parent && mp->am_parent->am_mnt->mf_ops == &dfs_ops) + mp->am_path = str3cat(mp->am_path, mp->am_parent->am_path, "/", "."); + + /* + * Check whether this mount should be cached permanently + */ + if (mf->mf_ops->fs_flags & FS_NOTIMEOUT) { + mp->am_flags |= AMF_NOTIMEOUT; + } else if (mf->mf_mount[1] == '\0' && mf->mf_mount[0] == '/') { + mp->am_flags |= AMF_NOTIMEOUT; + } else { + struct mntent mnt; + if (mf->mf_mopts) { + mnt.mnt_opts = mf->mf_mopts; + if (hasmntopt(&mnt, "nounmount")) + mp->am_flags |= AMF_NOTIMEOUT; + if ((mp->am_timeo = hasmntval(&mnt, "utimeout")) == 0) + mp->am_timeo = am_timeo; + } + } + + /* + * If this node is a symlink then + * compute the length of the returned string. + */ + if (mp->am_fattr.type == NFLNK) + mp->am_fattr.size = strlen(mp->am_link ? mp->am_link : mp->am_mnt->mf_mount); + + /* + * Record mount time + */ + mp->am_fattr.mtime.seconds = mp->am_stats.s_mtime = clocktime(); + new_ttl(mp); + /* + * Update mtime of parent node + */ + if (mp->am_parent && mp->am_parent->am_mnt) + mp->am_parent->am_fattr.mtime.seconds = mp->am_stats.s_mtime; + + + /* + * Update stats + */ + amd_stats.d_mok++; +} + +int mount_node P((am_node *mp)); +int mount_node(mp) +am_node *mp; +{ + mntfs *mf = mp->am_mnt; + int error; + + mf->mf_flags |= MFF_MOUNTING; + error = (*mf->mf_ops->mount_fs)(mp); + mf = mp->am_mnt; + if (error >= 0) + mf->mf_flags &= ~MFF_MOUNTING; + if (!error && !(mf->mf_ops->fs_flags & FS_MBACKGROUND)) { + /* ...but see ifs_mount */ + am_mounted(mp); + } + + return error; +} + +void am_unmounted P((am_node *mp)); +void am_unmounted(mp) +am_node *mp; +{ + mntfs *mf = mp->am_mnt; + + if (!foreground) /* firewall - should never happen */ + return; + +#ifdef DEBUG + /*dlog("in am_unmounted(), foreground = %d", foreground);*/ +#endif /* DEBUG */ + + /* + * Do unmounted callback + */ + if (mf->mf_ops->umounted) + (*mf->mf_ops->umounted)(mp); + + /* + * Update mtime of parent node + */ + if (mp->am_parent && mp->am_parent->am_mnt) + mp->am_parent->am_fattr.mtime.seconds = clocktime(); + + free_map(mp); +} + +int auto_fmount P((am_node *mp)); +int auto_fmount(mp) +am_node *mp; +{ + mntfs *mf = mp->am_mnt; + return (*mf->mf_ops->fmount_fs)(mf); +} + +int auto_fumount P((am_node *mp)); +int auto_fumount(mp) +am_node *mp; +{ + mntfs *mf = mp->am_mnt; + return (*mf->mf_ops->fumount_fs)(mf); +} + +/* + * Fork the automounter + * + * TODO: Need a better strategy for handling errors + */ +static int dofork(P_void); +static int dofork() +{ + int pid; +top: + pid = fork(); + + if (pid < 0) { + sleep(1); + goto top; + } + + if (pid == 0) { + mypid = getpid(); + foreground = 0; + } + + return pid; +} + +int background(P_void); +int background() +{ + int pid = dofork(); + if (pid == 0) { +#ifdef DEBUG + dlog("backgrounded"); +#endif + foreground = 0; + } + + return pid; +} + +/* + * Make all the directories in the path. + */ +int mkdirs P((char *path, int mode)); +int mkdirs(path, mode) +char *path; +int mode; +{ + /* + * take a copy in case path is in readonly store + */ + char *p2 = strdup(path); + char *sp = p2; + struct stat stb; + int error_so_far = 0; + + /* + * Skip through the string make the directories. + * Mostly ignore errors - the result is tested at the end. + * + * This assumes we are root so that we can do mkdir in a + * mode 555 directory... + */ + while (sp = strchr(sp+1, '/')) { + *sp = '\0'; + if (mkdir(p2, mode) < 0) { + error_so_far = errno; + } else { +#ifdef DEBUG + dlog("mkdir(%s)", p2); +#endif + } + *sp = '/'; + } + + if (mkdir(p2, mode) < 0) { + error_so_far = errno; + } else { +#ifdef DEBUG + dlog("mkdir(%s)", p2); +#endif + } + +#ifdef SUNOS4_WORKAROUND + /* + * Do a sync - if we do rmdirs() immediately + * and then the system crashes it leaves + * the filesystem in a state that fsck -p + * can't fix. (Observed more than once on + * SunOS 4 ...) + * + * The problem was caused by a bug somewhere + * in the UFS code which has since been fixed + * (at least at Berkeley). + * + * Attempted workaround - XXX. + */ + sync(); +#endif /* SUNOS4_WORKAROUND */ + + free(p2); + + return stat(path, &stb) == 0 && + (stb.st_mode & S_IFMT) == S_IFDIR ? 0 : error_so_far; +} + +/* + * Remove as many directories in the path as possible. + * Give up if the directory doesn't appear to have + * been created by Amd (not mode dr-x) or an rmdir + * fails for any reason. + */ +void rmdirs P((char *dir)); +void rmdirs(dir) +char *dir; +{ + char *xdp = strdup(dir); + char *dp; + + do { + struct stat stb; + /* + * Try to find out whether this was + * created by amd. Do this by checking + * for owner write permission. + */ + if (stat(xdp, &stb) == 0 && (stb.st_mode & 0200) == 0) { + if (rmdir(xdp) < 0) { + if (errno != ENOTEMPTY && + errno != EBUSY && + errno != EEXIST && + errno != EINVAL) + plog(XLOG_ERROR, "rmdir(%s): %m", xdp); + break; + } else { +#ifdef DEBUG + dlog("rmdir(%s)", xdp); +#endif + } + } else { + break; + } + dp = strrchr(xdp, '/'); + if (dp) + *dp = '\0'; + } while (dp && dp > xdp); + free(xdp); +} diff --git a/usr.sbin/amd/amd/wire.c b/usr.sbin/amd/amd/wire.c new file mode 100644 index 0000000..ea6d3da --- /dev/null +++ b/usr.sbin/amd/amd/wire.c @@ -0,0 +1,281 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)wire.c 8.1 (Berkeley) 6/6/93 + * + * $Id: wire.c,v 5.2.2.1 1992/02/09 15:09:15 jsp beta $ + * + */ + +/* + * This function returns the subnet (address&netmask) for the primary network + * interface. If the resulting address has an entry in the hosts file, the + * corresponding name is retuned, otherwise the address is returned in + * standard internet format. + * As a side-effect, a list of local IP/net address is recorded for use + * by the islocalnet() function. + * + * Derived from original by Paul Anderson (23/4/90) + * Updates from Dirk Grunwald (11/11/91) + */ + +#include "am.h" + +#include + +#define NO_SUBNET "notknown" + +/* + * List of locally connected networks + */ +typedef struct addrlist addrlist; +struct addrlist { + addrlist *ip_next; + unsigned long ip_addr; + unsigned long ip_mask; +}; +static addrlist *localnets = 0; + +#ifdef SIOCGIFFLAGS +#ifdef STELLIX +#include +#endif /* STELLIX */ +#include +#include + +#if defined(IFF_LOCAL_LOOPBACK) && !defined(IFF_LOOPBACK) +#define IFF_LOOPBACK IFF_LOCAL_LOOPBACK +#endif + +#define GFBUFLEN 1024 +#define clist (ifc.ifc_ifcu.ifcu_req) +#define count (ifc.ifc_len/sizeof(struct ifreq)) + +char *getwire P((void)); +char *getwire() +{ + struct hostent *hp; + struct netent *np; + struct ifconf ifc; + struct ifreq *ifr; + caddr_t cp, cplim; + unsigned long address, netmask, subnet; + char buf[GFBUFLEN], *s; + int sk = -1; + char *netname = 0; + + /* + * Get suitable socket + */ + if ((sk = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + goto out; + + /* + * Fill in ifconf details + */ + ifc.ifc_len = sizeof buf; + ifc.ifc_buf = buf; + + /* + * Get network interface configurations + */ + if (ioctl(sk, SIOCGIFCONF, (caddr_t) &ifc) < 0) + goto out; + + /* + * Upper bound on array + */ + cplim = buf + ifc.ifc_len; + + /* + * This is some magic to cope with both "traditional" and the + * new 4.4BSD-style struct sockaddrs. The new structure has + * variable length and a size field to support longer addresses. + * AF_LINK is a new definition for 4.4BSD. + */ +#ifdef AF_LINK +#define max(a, b) ((a) > (b) ? (a) : (b)) +#define size(ifr) (max((ifr)->ifr_addr.sa_len, sizeof((ifr)->ifr_addr)) + sizeof(ifr->ifr_name)) +#else +#define size(ifr) sizeof(*ifr) +#endif + /* + * Scan the list looking for a suitable interface + */ + for (cp = buf; cp < cplim; cp += size(ifr)) { + addrlist *al; + ifr = (struct ifreq *) cp; + + if (ifr->ifr_addr.sa_family != AF_INET) + continue; + else + address = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; + + /* + * Get interface flags + */ + if (ioctl(sk, SIOCGIFFLAGS, (caddr_t) ifr) < 0) + continue; + + /* + * If the interface is a loopback, or its not running + * then ignore it. + */ + if ((ifr->ifr_flags & IFF_LOOPBACK) != 0) + continue; + if ((ifr->ifr_flags & IFF_RUNNING) == 0) + continue; + + /* + * Get the netmask of this interface + */ + if (ioctl(sk, SIOCGIFNETMASK, (caddr_t) ifr) < 0) + continue; + + netmask = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; + + /* + * Add interface to local network list + */ + al = ALLOC(addrlist); + al->ip_addr = address; + al->ip_mask = netmask; + al->ip_next = localnets; + localnets = al; + + if (netname == 0) { + unsigned long net; + unsigned long mask; + unsigned long subnetshift; + /* + * Figure out the subnet's network address + */ + subnet = address & netmask; + +#ifdef IN_CLASSA + subnet = ntohl(subnet); + + if (IN_CLASSA(subnet)) { + mask = IN_CLASSA_NET; + subnetshift = 8; + } else if (IN_CLASSB(subnet)) { + mask = IN_CLASSB_NET; + subnetshift = 8; + } else { + mask = IN_CLASSC_NET; + subnetshift = 4; + } + + /* + * If there are more bits than the standard mask + * would suggest, subnets must be in use. + * Guess at the subnet mask, assuming reasonable + * width subnet fields. + * XXX: Or-in at least 1 byte's worth of 1s to make + * sure the top bits remain set. + */ + while (subnet &~ mask) + mask = (mask >> subnetshift) | 0xff000000; + + net = subnet & mask; + while ((mask & 1) == 0) + mask >>= 1, net >>= 1; + + /* + * Now get a usable name. + * First use the network database, + * then the host database, + * and finally just make a dotted quad. + */ + + np = getnetbyaddr(net, AF_INET); +#else + /* This is probably very wrong. */ + np = getnetbyaddr(subnet, AF_INET); +#endif /* IN_CLASSA */ + if (np) + s = np->n_name; + else { + subnet = address & netmask; + hp = gethostbyaddr((char *) &subnet, 4, AF_INET); + if (hp) + s = hp->h_name; + else + s = inet_dquad(buf, subnet); + } + netname = strdup(s); + } + } + +out: + if (sk >= 0) + (void) close(sk); + if (netname) + return netname; + return strdup(NO_SUBNET); +} + +#else + +char *getwire P((void)); +char *getwire() +{ + return strdup(NO_SUBNET); +} +#endif /* SIOCGIFFLAGS */ + +/* + * Determine whether a network is on a local network + * (addr) is in network byte order. + */ +int islocalnet P((unsigned long addr)); +int islocalnet(addr) +unsigned long addr; +{ + addrlist *al; + + for (al = localnets; al; al = al->ip_next) + if (((addr ^ al->ip_addr) & al->ip_mask) == 0) + return TRUE; + +#ifdef DEBUG + { char buf[16]; + plog(XLOG_INFO, "%s is on a remote network", inet_dquad(buf, addr)); + } +#endif + return FALSE; +} diff --git a/usr.sbin/amd/amd/xutil.c b/usr.sbin/amd/amd/xutil.c new file mode 100644 index 0000000..8af6951 --- /dev/null +++ b/usr.sbin/amd/amd/xutil.c @@ -0,0 +1,491 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)xutil.c 8.1 (Berkeley) 6/6/93 + * + * $Id: xutil.c,v 5.2.2.3 1992/03/07 10:36:09 jsp Exp $ + * + */ + +#include "config.h" +#ifdef HAS_SYSLOG +#include +#endif /* HAS_SYSLOG */ +#ifdef HAS_STRERROR +#include +#endif + +FILE *logfp = stderr; /* Log errors to stderr initially */ +#ifdef HAS_SYSLOG +int syslogging; +#endif /* HAS_SYSLOG */ +int xlog_level = XLOG_ALL & ~XLOG_MAP & ~XLOG_STATS; +int xlog_level_init = ~0; + +/* + * List of log options + */ +struct opt_tab xlog_opt[] = { + { "all", XLOG_ALL }, /* All messages */ +#ifdef DEBUG + { "debug", XLOG_DEBUG }, /* Debug messages */ +#endif /* DEBUG */ + { "error", XLOG_ERROR }, /* Non-fatal system errors */ + { "fatal", XLOG_FATAL }, /* Fatal errors */ + { "info", XLOG_INFO }, /* Information */ + { "map", XLOG_MAP }, /* Map errors */ + { "stats", XLOG_STATS }, /* Additional statistical information */ + { "user", XLOG_USER }, /* Non-fatal user errors */ + { "warn", XLOG_WARNING }, /* Warnings */ + { "warning", XLOG_WARNING }, /* Warnings */ + { 0, 0 } +}; + +voidp xmalloc(len) +int len; +{ + voidp p; + int retries = 600; + + /* + * Avoid malloc's which return NULL for malloc(0) + */ + if (len == 0) + len = 1; + + do { + p = (voidp) malloc((unsigned) len); + if (p) { +#if defined(DEBUG) && defined(DEBUG_MEM) + Debug(D_MEM) plog(XLOG_DEBUG, "Allocated size %d; block %#x", len, p); +#endif /* defined(DEBUG) && defined(DEBUG_MEM) */ + return p; + } + if (retries > 0) { + plog(XLOG_ERROR, "Retrying memory allocation"); + sleep(1); + } + } while (--retries); + + plog(XLOG_FATAL, "Out of memory"); + going_down(1); + + abort(); + + return 0; +} + +voidp xrealloc(ptr, len) +voidp ptr; +int len; +{ +#if defined(DEBUG) && defined(DEBUG_MEM) + Debug(D_MEM) plog(XLOG_DEBUG, "Reallocated size %d; block %#x", len, ptr); +#endif /* defined(DEBUG) && defined(DEBUG_MEM) */ + + if (len == 0) + len = 1; + + if (ptr) + ptr = (voidp) realloc(ptr, (unsigned) len); + else + ptr = (voidp) xmalloc((unsigned) len); + + if (!ptr) { + plog(XLOG_FATAL, "Out of memory in realloc"); + going_down(1); + abort(); + } + return ptr; +} + +#if defined(DEBUG) && defined(DEBUG_MEM) +xfree(f, l, p) +char *f; +int l; +voidp p; +{ + Debug(D_MEM) plog(XLOG_DEBUG, "Free in %s:%d: block %#x", f, l, p); +#undef free + free(p); +} +#endif /* defined(DEBUG) && defined(DEBUG_MEM) */ +#ifdef DEBUG_MEM +static int mem_bytes; +static int orig_mem_bytes; +static void checkup_mem(P_void) +{ +extern struct mallinfo __mallinfo; + if (mem_bytes != __mallinfo.uordbytes) { + if (orig_mem_bytes == 0) + mem_bytes = orig_mem_bytes = __mallinfo.uordbytes; + else { + fprintf(logfp, "%s[%d]: ", progname, mypid); + if (mem_bytes < __mallinfo.uordbytes) { + fprintf(logfp, "ALLOC: %d bytes", + __mallinfo.uordbytes - mem_bytes); + } else { + fprintf(logfp, "FREE: %d bytes", + mem_bytes - __mallinfo.uordbytes); + } + mem_bytes = __mallinfo.uordbytes; + fprintf(logfp, ", making %d missing\n", + mem_bytes - orig_mem_bytes); + } + } + malloc_verify(); +} +#endif /* DEBUG_MEM */ + +/* + * Take a log format string and expand occurences of %m + * with the current error code take from errno. + */ +INLINE +static void expand_error(f, e) +char *f; +char *e; +{ +#ifndef HAS_STRERROR + extern int sys_nerr; + extern char *sys_errlist[]; +#endif + char *p; + int error = errno; + + for (p = f; *e = *p; e++, p++) { + if (p[0] == '%' && p[1] == 'm') { + char *errstr; +#ifdef HAS_STRERROR + errstr = strerror(error); +#else + if (error < 0 || error >= sys_nerr) + errstr = 0; + else + errstr = sys_errlist[error]; +#endif + if (errstr) + strcpy(e, errstr); + else + sprintf(e, "Error %d", error); + e += strlen(e) - 1; + p++; + } + } +} + +/* + * Output the time of day and hostname to the logfile + */ +static void show_time_host_and_name(lvl) +int lvl; +{ +static time_t last_t = 0; +static char *last_ctime = 0; + time_t t = clocktime(); + char *sev; + extern char *ctime(); + +#if defined(DEBUG) && defined(PARANOID) +extern char **gargv; +#endif /* defined(DEBUG) && defined(PARANOID) */ + + if (t != last_t) { + last_ctime = ctime(&t); + last_t = t; + } + + switch (lvl) { + case XLOG_FATAL: sev = "fatal:"; break; + case XLOG_ERROR: sev = "error:"; break; + case XLOG_USER: sev = "user: "; break; + case XLOG_WARNING: sev = "warn: "; break; + case XLOG_INFO: sev = "info: "; break; + case XLOG_DEBUG: sev = "debug:"; break; + case XLOG_MAP: sev = "map: "; break; + case XLOG_STATS: sev = "stats:"; break; + default: sev = "hmm: "; break; + } + fprintf(logfp, "%15.15s %s %s[%d]/%s ", + last_ctime+4, hostname, +#if defined(DEBUG) && defined(PARANOID) + gargv[0], +#else + progname, +#endif /* defined(DEBUG) && defined(PARANOID) */ + mypid, + sev); +} + +#ifdef DEBUG +/*VARARGS1*/ +void dplog(fmt, j,s,_,p,e,n,d,r,y) +char *fmt; +char *j, *s, *_, *p, *e, *n, *d, *r, *y; +{ + plog(XLOG_DEBUG, fmt, j,s,_,p,e,n,d,r,y); +} + +#endif /* DEBUG */ +/*VARARGS1*/ +void plog(lvl, fmt, j,s,_,p,e,n,d,r,y) +int lvl; +char *fmt; +char *j, *s, *_, *p, *e, *n, *d, *r, *y; +{ + char msg[1024]; + char efmt[1024]; + char *ptr = msg; + + if (!(xlog_level & lvl)) + return; + +#ifdef DEBUG_MEM + checkup_mem(); +#endif /* DEBUG_MEM */ + + expand_error(fmt, efmt); + sprintf(ptr, efmt, j,s,_,p,e,n,d,r,y); + ptr += strlen(ptr); + if (ptr[-1] == '\n') + *--ptr = '\0'; +#ifdef HAS_SYSLOG + if (syslogging) { + switch(lvl) { /* from mike */ + case XLOG_FATAL: lvl = LOG_CRIT; break; + case XLOG_ERROR: lvl = LOG_ERR; break; + case XLOG_USER: lvl = LOG_WARNING; break; + case XLOG_WARNING: lvl = LOG_WARNING; break; + case XLOG_INFO: lvl = LOG_INFO; break; + case XLOG_DEBUG: lvl = LOG_DEBUG; break; + case XLOG_MAP: lvl = LOG_DEBUG; break; + case XLOG_STATS: lvl = LOG_INFO; break; + default: lvl = LOG_ERR; break; + } + syslog(lvl, "%s", msg); + return; + } +#endif /* HAS_SYSLOG */ + + *ptr++ = '\n'; + *ptr = '\0'; + + /* + * Mimic syslog header + */ + show_time_host_and_name(lvl); + fwrite(msg, ptr - msg, 1, logfp); + fflush(logfp); +} + +void show_opts P((int ch, struct opt_tab *opts)); +void show_opts(ch, opts) +int ch; +struct opt_tab *opts; +{ + /* + * Display current debug options + */ + int i; + int s = '{'; + fprintf(stderr, "\t[-%c {no}", ch); + for (i = 0; opts[i].opt; i++) { + fprintf(stderr, "%c%s", s, opts[i].opt); + s = ','; + } + fputs("}]\n", stderr); +} + +int cmdoption P((char *s, struct opt_tab *optb, int *flags)); +int cmdoption(s, optb, flags) +char *s; +struct opt_tab *optb; +int *flags; +{ + char *p = s; + int errs = 0; + + while (p && *p) { + int neg; + char *opt; + struct opt_tab *dp, *dpn = 0; + + s = p; + p = strchr(p, ','); + if (p) + *p = '\0'; + + if (s[0] == 'n' && s[1] == 'o') { + opt = s + 2; + neg = 1; + } else { + opt = s; + neg = 0; + } + + /* + * Scan the array of debug options to find the + * corresponding flag value. If it is found + * then set (or clear) the flag (depending on + * whether the option was prefixed with "no"). + */ + for (dp = optb; dp->opt; dp++) { + if (strcmp(opt, dp->opt) == 0) + break; + if (opt != s && !dpn && strcmp(s, dp->opt) == 0) + dpn = dp; + } + + if (dp->opt || dpn) { + if (!dp->opt) { + dp = dpn; + neg = !neg; + } + if (neg) + *flags &= ~dp->flag; + else + *flags |= dp->flag; + } else { + /* + * This will log to stderr when parsing the command line + * since any -l option will not yet have taken effect. + */ + plog(XLOG_USER, "option \"%s\" not recognised", s); + errs++; + } + /* + * Put the comma back + */ + if (p) + *p++ = ','; + } + + return errs; +} + +/* + * Switch on/off logging options + */ +int switch_option(opt) +char *opt; +{ + int xl = xlog_level; + int rc = cmdoption(opt, xlog_opt, &xl); + if (rc) { + rc = EINVAL; + } else { + /* + * Keep track of initial log level, and + * don't allow options to be turned off. + */ + if (xlog_level_init == ~0) + xlog_level_init = xl; + else + xl |= xlog_level_init; + xlog_level = xl; + } + return rc; +} + +/* + * Change current logfile + */ +int switch_to_logfile P((char *logfile)); +int switch_to_logfile(logfile) +char *logfile; +{ + FILE *new_logfp = stderr; + + if (logfile) { +#ifdef HAS_SYSLOG + syslogging = 0; +#endif /* HAS_SYSLOG */ + if (strcmp(logfile, "/dev/stderr") == 0) + new_logfp = stderr; + else if (strcmp(logfile, "syslog") == 0) { +#ifdef HAS_SYSLOG + syslogging = 1; + new_logfp = stderr; +#if defined(LOG_CONS) && defined(LOG_NOWAIT) + openlog(progname, LOG_PID|LOG_CONS|LOG_NOWAIT, + LOG_DAEMON); +#else + /* 4.2 compat mode - XXX */ + openlog(progname, LOG_PID); +#endif /* LOG_CONS && LOG_NOWAIT */ +#else + plog(XLOG_WARNING, "syslog option not supported, logging unchanged"); +#endif /* HAS_SYSLOG */ + } else { + (void) umask(orig_umask); + new_logfp = fopen(logfile, "a"); + umask(0); + } + } + + /* + * If we couldn't open a new file, then continue using the old. + */ + if (!new_logfp && logfile) { + plog(XLOG_USER, "%s: Can't open logfile: %m", logfile); + return 1; + } + /* + * Close the previous file + */ + if (logfp && logfp != stderr) + (void) fclose(logfp); + logfp = new_logfp; + return 0; +} + +time_t clock_valid = 0; +time_t xclock_valid = 0; +#ifndef clocktime +time_t clocktime(P_void) +{ + time_t now = time(&clock_valid); + if (xclock_valid > now) { + /* + * Someone set the clock back! + */ + plog(XLOG_WARNING, "system clock reset"); + reschedule_timeouts(now, xclock_valid); + } + return xclock_valid = now; +} +#endif /* clocktime */ diff --git a/usr.sbin/amd/amq/Makefile b/usr.sbin/amd/amq/Makefile new file mode 100644 index 0000000..adbd5f4 --- /dev/null +++ b/usr.sbin/amd/amq/Makefile @@ -0,0 +1,15 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG = amq +SRCS = amq.c amq_clnt.c amq_xdr.c misc_rpc.c +LDADD+=-lrpc +CFLAGS+=-I${.CURDIR}/../include +CFLAGS+=-I${.CURDIR}/../rpcx +CFLAGS+=-I${.CURDIR}/../config +CFLAGS+=-DARCH_REP=\"${MACHINE}\" +CFLAGS+=-DOS_REP=\"bsd44\" +CFLAGS+=-DOS_HDR=\"os-bsd44.h\" +.PATH: ${.CURDIR}/../rpcx ${.CURDIR}/../amd + +.include "../../Makefile.inc" +.include diff --git a/usr.sbin/amd/amq/amq.8 b/usr.sbin/amd/amq/amq.8 new file mode 100644 index 0000000..5485925 --- /dev/null +++ b/usr.sbin/amd/amq/amq.8 @@ -0,0 +1,130 @@ +.\" +.\" Copyright (c) 1990 Jan-Simon Pendry +.\" Copyright (c) 1990 Imperial College of Science, Technology & Medicine +.\" Copyright (c) 1990, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Jan-Simon Pendry at Imperial College, London. +.\" +.\" 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. +.\" +.\" @(#)amq.8 8.3 (Berkeley) 4/18/94 +.\" +.\" $Id: amq.8,v 5.2.2.1 1992/02/09 15:11:41 jsp beta $ +.\" +.Dd March 16, 1991 +.Dt AMQ 8 +.Os +.Sh NAME +.Nm amq +.Nd automounter query tool +.Sh SYNOPSIS +.Nm amq +.Op Fl f +.Op Fl h Ar hostname +.Op Fl M Ar mountmap_entry +.Op Fl m +.Op Fl s +.Op Fl u +.Op Fl v +.Op Ar directory +.Ar ... +.Sh DESCRIPTION +.Nm Amq +provides a simple way of determining the current state of the +.Xr amd 8 +program. +Communication is by +.Tn RPC . +Three modes of operation are supported by the current protocol. +By default a list of mount points and auto-mounted filesystems +is output. +An alternative host can be specified using the +.Fl h +option. +.Pp +If directory names are given, as output by default, +then per-filesystem information is displayed. +.Sh OPTIONS +.Bl -tag -width Ds +.It Fl f +Request automounter to flush the internal caches. +.It Fl h Ar hostname +Query alternate host +.Ar hostname . +By default the local host is used. In an +.Tn HP-UX +cluster, the root server is queried by default, since +that is the system on which the automounter is normally run. +.It Fl m +Request the automounter to provide a list of mounted filesystems, +including the number of references to each filesystem and any error +which occurred while mounting. +.It Fl s +Request the automounter to provide system-wide mount statistics. +.It Fl u +Request the automounter to unmount the named filesystems +instead of providing information about them. Unmounts are requested, +not forced. They merely cause the mounted filesystem to timeout, +which will be picked up by +.Xr amd Ns \'s +main scheduler thus causing the normal timeout action to be taken. +.It Fl v +Request the automounter to provide version information. This is a subset +of the information provided by +.Xr amd Ns \'s Fl v +option. +.It Fl M +Request automounter to add the given map entry to the root map and then +trigger a mount request for it. +.El +.Sh FILES +.Bl -tag -width amq.xxxxx -compact +.Bl -tag -width Ds +.It Pa amq.x +.Tn RPC +protocol description. +.El +.Sh CAVEATS +.Nm Amq +uses a Sun registered +.Tn RPC +program number (300019 decimal) which may not +be in the +.Pa /etc/rpc +database. +.Sh SEE ALSO +.Xr amd 8 +.Sh AUTHOR +.An Jan-Simon Pendry +, Department of Computing, Imperial College, London, UK. +.Sh HISTORY +.Nm Amq +.At diff --git a/usr.sbin/amd/amq/amq.c b/usr.sbin/amd/amq/amq.c new file mode 100644 index 0000000..d3749bc --- /dev/null +++ b/usr.sbin/amd/amq/amq.c @@ -0,0 +1,666 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)amq.c 8.1 (Berkeley) 6/7/93 + * + * $Id: amq.c,v 5.2.2.1 1992/02/09 15:09:16 jsp beta $ + * + */ + +/* + * Automounter query tool + */ + +#ifndef lint +char copyright[] = "\ +@(#)Copyright (c) 1990 Jan-Simon Pendry\n\ +@(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\ +@(#)Copyright (c) 1990, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char rcsid[] = "$Id: amq.c,v 5.2.2.1 1992/02/09 15:09:16 jsp beta $"; +static char sccsid[] = "@(#)amq.c 8.1 (Berkeley) 6/7/93"; +#endif /* not lint */ + +#include "am.h" +#include "amq.h" +#include +#include +#include + +static int privsock(); + +char *progname; +static int flush_flag; +static int minfo_flag; +static int unmount_flag; +static int stats_flag; +static int getvers_flag; +static char *debug_opts; +static char *logfile; +static char *mount_map; +static char *xlog_optstr; +static char localhost[] = "localhost"; +static char *def_server = localhost; + +extern int optind; +extern char *optarg; + +static struct timeval tmo = { 10, 0 }; +#define TIMEOUT tmo + +enum show_opt { Full, Stats, Calc, Short, ShowDone }; + +/* + * If (e) is Calc then just calculate the sizes + * Otherwise display the mount node on stdout + */ +static void show_mti(mt, e, mwid, dwid, twid) +amq_mount_tree *mt; +enum show_opt e; +int *mwid; +int *dwid; +int *twid; +{ + switch (e) { + case Calc: { + int mw = strlen(mt->mt_mountinfo); + int dw = strlen(mt->mt_directory); + int tw = strlen(mt->mt_type); + if (mw > *mwid) *mwid = mw; + if (dw > *dwid) *dwid = dw; + if (tw > *twid) *twid = tw; + } break; + + case Full: { + struct tm *tp = localtime((time_t *) &mt->mt_mounttime); +printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n", + *dwid, *dwid, + *mt->mt_directory ? mt->mt_directory : "/", /* XXX */ + *twid, *twid, + mt->mt_type, + *mwid, *mwid, + mt->mt_mountinfo, + mt->mt_mountpoint, + + mt->mt_mountuid, + mt->mt_getattr, + mt->mt_lookup, + mt->mt_readdir, + mt->mt_readlink, + mt->mt_statfs, + + tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year, + tp->tm_mon+1, tp->tm_mday, + tp->tm_hour, tp->tm_min, tp->tm_sec); + } break; + + case Stats: { + struct tm *tp = localtime((time_t *) &mt->mt_mounttime); +printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n", + *dwid, *dwid, + *mt->mt_directory ? mt->mt_directory : "/", /* XXX */ + + mt->mt_mountuid, + mt->mt_getattr, + mt->mt_lookup, + mt->mt_readdir, + mt->mt_readlink, + mt->mt_statfs, + + tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year, + tp->tm_mon+1, tp->tm_mday, + tp->tm_hour, tp->tm_min, tp->tm_sec); + } break; + + case Short: { + printf("%-*.*s %-*.*s %-*.*s %s\n", + *dwid, *dwid, + *mt->mt_directory ? mt->mt_directory : "/", + *twid, *twid, + mt->mt_type, + *mwid, *mwid, + mt->mt_mountinfo, + mt->mt_mountpoint); + } break; + } +} + +/* + * Display a mount tree. + */ +static void show_mt(mt, e, mwid, dwid, pwid) +amq_mount_tree *mt; +enum show_opt e; +int *mwid; +int *dwid; +int *pwid; +{ + while (mt) { + show_mti(mt, e, mwid, dwid, pwid); + show_mt(mt->mt_next, e, mwid, dwid, pwid); + mt = mt->mt_child; + } +} + +static void show_mi(ml, e, mwid, dwid, twid) +amq_mount_info_list *ml; +enum show_opt e; +int *mwid; +int *dwid; +int *twid; +{ + int i; + switch (e) { + case Calc: { + for (i = 0; i < ml->amq_mount_info_list_len; i++) { + amq_mount_info *mi = &ml->amq_mount_info_list_val[i]; + int mw = strlen(mi->mi_mountinfo); + int dw = strlen(mi->mi_mountpt); + int tw = strlen(mi->mi_type); + if (mw > *mwid) *mwid = mw; + if (dw > *dwid) *dwid = dw; + if (tw > *twid) *twid = tw; + } + } break; + + case Full: { + for (i = 0; i < ml->amq_mount_info_list_len; i++) { + amq_mount_info *mi = &ml->amq_mount_info_list_val[i]; + printf("%-*.*s %-*.*s %-*.*s %-3d %s is %s", + *mwid, *mwid, mi->mi_mountinfo, + *dwid, *dwid, mi->mi_mountpt, + *twid, *twid, mi->mi_type, + mi->mi_refc, mi->mi_fserver, + mi->mi_up > 0 ? "up" : + mi->mi_up < 0 ? "starting" : "down"); + if (mi->mi_error > 0) { +#ifdef HAS_STRERROR + printf(" (%s)", strerror(mi->mi_error)); +#else + extern char *sys_errlist[]; + extern int sys_nerr; + if (mi->mi_error < sys_nerr) + printf(" (%s)", sys_errlist[mi->mi_error]); + else + printf(" (Error %d)", mi->mi_error); +#endif + } else if (mi->mi_error < 0) { + fputs(" (in progress)", stdout); + } + fputc('\n', stdout); + } + } break; + } +} + +/* + * Display general mount statistics + */ +static void show_ms(ms) +amq_mount_stats *ms; +{ + printf("\ +requests stale mount mount unmount\n\ +deferred fhandles ok failed failed\n\ +%-9d %-9d %-9d %-9d %-9d\n", + ms->as_drops, ms->as_stale, ms->as_mok, ms->as_merr, ms->as_uerr); +} + +static bool_t +xdr_pri_free(xdr_args, args_ptr) +xdrproc_t xdr_args; +caddr_t args_ptr; +{ + XDR xdr; + xdr.x_op = XDR_FREE; + return ((*xdr_args)(&xdr, args_ptr)); +} + +#ifdef hpux +#include +static char *cluster_server() +{ + struct cct_entry *cp; + + if (cnodeid() == 0) { + /* + * Not clustered + */ + return def_server; + } + + while (cp = getccent()) + if (cp->cnode_type == 'r') + return cp->cnode_name; + + + return def_server; +} +#endif /* hpux */ + +/* + * MAIN + */ +main(argc, argv) +int argc; +char *argv[]; +{ + int opt_ch; + int errs = 0; + char *server; + struct sockaddr_in server_addr; + + /* In order to pass the Amd security check, we must use a priv port. */ + int s; + + CLIENT *clnt; + struct hostent *hp; + int nodefault = 0; + + /* + * Compute program name + */ + if (argv[0]) { + progname = strrchr(argv[0], '/'); + if (progname && progname[1]) + progname++; + else + progname = argv[0]; + } + if (!progname) + progname = "amq"; + + /* + * Parse arguments + */ + while ((opt_ch = getopt(argc, argv, "fh:l:msuvx:D:M:")) != EOF) + switch (opt_ch) { + case 'f': + flush_flag = 1; + nodefault = 1; + break; + + case 'h': + def_server = optarg; + break; + + case 'l': + logfile = optarg; + nodefault = 1; + break; + + case 'm': + minfo_flag = 1; + nodefault = 1; + break; + + case 's': + stats_flag = 1; + nodefault = 1; + break; + + case 'u': + unmount_flag = 1; + nodefault = 1; + break; + + case 'v': + getvers_flag = 1; + nodefault = 1; + break; + + case 'x': + xlog_optstr = optarg; + nodefault = 1; + break; + + case 'D': + debug_opts = optarg; + nodefault = 1; + break; + + case 'M': + mount_map = optarg; + nodefault = 1; + break; + + default: + errs = 1; + break; + } + + if (optind == argc) { + if (unmount_flag) + errs = 1; + } + + if (errs) { +show_usage: + fprintf(stderr, "\ +Usage: %s [-h host] [[-f] [-m] [-v] [-s]] | [[-u] directory ...]] |\n\ +\t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts] [-M mapent]\n", progname); + exit(1); + } + +#ifdef hpux + /* + * Figure out root server of cluster + */ + if (def_server == localhost) + server = cluster_server(); + else +#endif /* hpux */ + server = def_server; + + /* + * Get address of server + */ + if ((hp = gethostbyname(server)) == 0 && strcmp(server, localhost) != 0) { + fprintf(stderr, "%s: Can't get address of %s\n", progname, server); + exit(1); + } + bzero(&server_addr, sizeof server_addr); + server_addr.sin_family = AF_INET; + if (hp) { + bcopy((voidp) hp->h_addr, (voidp) &server_addr.sin_addr, + sizeof(server_addr.sin_addr)); + } else { + /* fake "localhost" */ + server_addr.sin_addr.s_addr = htonl(0x7f000001); + } + + /* + * Create RPC endpoint + */ + s = privsock(SOCK_STREAM); + clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0); + if (clnt == 0) { + close(s); + s = privsock(SOCK_DGRAM); + clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s); + } + if (clnt == 0) { + fprintf(stderr, "%s: ", progname); + clnt_pcreateerror(server); + exit(1); + } + + /* + * Control debugging + */ + if (debug_opts) { + int *rc; + amq_setopt opt; + opt.as_opt = AMOPT_DEBUG; + opt.as_str = debug_opts; + rc = amqproc_setopt_1(&opt, clnt); + if (rc && *rc < 0) { + fprintf(stderr, "%s: daemon not compiled for debug", progname); + errs = 1; + } else if (!rc || *rc > 0) { + fprintf(stderr, "%s: debug setting for \"%s\" failed\n", progname, debug_opts); + errs = 1; + } + } + + /* + * Control logging + */ + if (xlog_optstr) { + int *rc; + amq_setopt opt; + opt.as_opt = AMOPT_XLOG; + opt.as_str = xlog_optstr; + rc = amqproc_setopt_1(&opt, clnt); + if (!rc || *rc) { + fprintf(stderr, "%s: setting log level to \"%s\" failed\n", progname, xlog_optstr); + errs = 1; + } + } + + /* + * Control log file + */ + if (logfile) { + int *rc; + amq_setopt opt; + opt.as_opt = AMOPT_LOGFILE; + opt.as_str = logfile; + rc = amqproc_setopt_1(&opt, clnt); + if (!rc || *rc) { + fprintf(stderr, "%s: setting logfile to \"%s\" failed\n", progname, logfile); + errs = 1; + } + } + + /* + * Flush map cache + */ + if (flush_flag) { + int *rc; + amq_setopt opt; + opt.as_opt = AMOPT_FLUSHMAPC; + opt.as_str = ""; + rc = amqproc_setopt_1(&opt, clnt); + if (!rc || *rc) { + fprintf(stderr, "%s: amd on %s cannot flush the map cache\n", progname, server); + errs = 1; + } + } + + /* + * Mount info + */ + if (minfo_flag) { + int dummy; + amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt); + if (ml) { + int mwid = 0, dwid = 0, twid = 0; + show_mi(ml, Calc, &mwid, &dwid, &twid); + mwid++; dwid++; twid++; + show_mi(ml, Full, &mwid, &dwid, &twid); + + } else { + fprintf(stderr, "%s: amd on %s cannot provide mount info\n", progname, server); + } + } + + /* + * Mount map + */ + if (mount_map) { + int *rc; + do { + rc = amqproc_mount_1(&mount_map, clnt); + } while (rc && *rc < 0); + if (!rc || *rc > 0) { + if (rc) + errno = *rc; + else + errno = ETIMEDOUT; + fprintf(stderr, "%s: could not start new ", progname); + perror("autmount point"); + } + } + + /* + * Get Version + */ + if (getvers_flag) { + amq_string *spp = amqproc_getvers_1((voidp) 0, clnt); + if (spp && *spp) { + printf("%s.\n", *spp); + free(*spp); + } else { + fprintf(stderr, "%s: failed to get version information\n", progname); + errs = 1; + } + } + + /* + * Apply required operation to all remaining arguments + */ + if (optind < argc) { + do { + char *fs = argv[optind++]; + if (unmount_flag) { + /* + * Unmount request + */ + amqproc_umnt_1(&fs, clnt); + } else { + /* + * Stats request + */ + amq_mount_tree_p *mtp = amqproc_mnttree_1(&fs, clnt); + if (mtp) { + amq_mount_tree *mt = *mtp; + if (mt) { + int mwid = 0, dwid = 0, twid = 0; + show_mt(mt, Calc, &mwid, &dwid, &twid); + mwid++; dwid++, twid++; + printf("%-*.*s Uid Getattr Lookup RdDir RdLnk Statfs Mounted@\n", + dwid, dwid, "What"); + show_mt(mt, Stats, &mwid, &dwid, &twid); + } else { + fprintf(stderr, "%s: %s not automounted\n", progname, fs); + } + xdr_pri_free(xdr_amq_mount_tree_p, (caddr_t) mtp); + } else { + fprintf(stderr, "%s: ", progname); + clnt_perror(clnt, server); + errs = 1; + } + } + } while (optind < argc); + } else if (unmount_flag) { + goto show_usage; + } else if (stats_flag) { + amq_mount_stats *ms = amqproc_stats_1((voidp) 0, clnt); + if (ms) { + show_ms(ms); + } else { + fprintf(stderr, "%s: ", progname); + clnt_perror(clnt, server); + errs = 1; + } + } else if (!nodefault) { + amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt); + if (mlp) { + enum show_opt e = Calc; + int mwid = 0, dwid = 0, pwid = 0; + while (e != ShowDone) { + int i; + for (i = 0; i < mlp->amq_mount_tree_list_len; i++) { + show_mt(mlp->amq_mount_tree_list_val[i], + e, &mwid, &dwid, &pwid); + } + mwid++; dwid++, pwid++; + if (e == Calc) e = Short; + else if (e == Short) e = ShowDone; + } + } else { + fprintf(stderr, "%s: ", progname); + clnt_perror(clnt, server); + errs = 1; + } + } + + exit(errs); +} + +/* + * udpresport creates a datagram socket and attempts to bind it to a + * secure port. + * returns: The bound socket, or -1 to indicate an error. + */ +static int inetresport(ty) +int ty; +{ + int alport; + struct sockaddr_in addr; + int sock; + + /* Use internet address family */ + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + if ((sock = socket(AF_INET, ty, 0)) < 0) + return -1; + for (alport = IPPORT_RESERVED-1; alport > IPPORT_RESERVED/2 + 1; alport--) { + addr.sin_port = htons((u_short)alport); + if (bind(sock, (struct sockaddr *)&addr, sizeof (addr)) >= 0) + return sock; + if (errno != EADDRINUSE) { + close(sock); + return -1; + } + } + close(sock); + errno = EAGAIN; + return -1; +} + +/* + * Privsock() calls inetresport() to attempt to bind a socket to a secure + * port. If inetresport() fails, privsock returns a magic socket number which + * indicates to RPC that it should make its own socket. + * returns: A privileged socket # or RPC_ANYSOCK. + */ +static int privsock(ty) +int ty; +{ + int sock = inetresport(ty); + + if (sock < 0) { + errno = 0; + /* Couldn't get a secure port, let RPC make an insecure one */ + sock = RPC_ANYSOCK; + } + return sock; +} + +#ifdef DEBUG +xfree(f, l, p) +char *f, *l; +voidp p; +{ + free(p); +} +#endif /* DEBUG */ diff --git a/usr.sbin/amd/config/Configure b/usr.sbin/amd/config/Configure new file mode 100644 index 0000000..2851786 --- /dev/null +++ b/usr.sbin/amd/config/Configure @@ -0,0 +1,60 @@ +#!/bin/sh - +# +# Copyright (c) 1989 Jan-Simon Pendry +# Copyright (c) 1989 Imperial College of Science, Technology & Medicine +# Copyright (c) 1989, 1993 +# The Regents of the University of California. All rights reserved. +# +# This code is derived from software contributed to Berkeley by +# Jan-Simon Pendry at Imperial College, London. +# +# 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. +# +# @(#)Configure 8.1 (Berkeley) 6/6/93 +# +# $Id: Configure,v 5.2.1.2 91/05/07 22:20:26 jsp Alpha $ +# +echo "Making ./arch and ./os-type executable ..." +until chmod +x ./arch ./os-type; do echo "Error: chmod command failed" >&2; exit 1; done +echo "Checking ./arch and ./os-type ..." +echo "" +arch="`sh ./arch 2>/dev/null`" +os="`sh ./os-type 2>/dev/null`" +case "$arch" in +"") echo "./arch doesn't produce an answer - please check it" >&2; exit 1;; +esac +case "$os" in +"") echo "./os-type doesn't produce an answer - please check it" >&2; exit 1;; +esac +cat << % +This machine appears to be a "$arch" running "$os". +If that is correct just run make. +If those are incorrect please edit ./arch and ./os-type +% +exit 0 diff --git a/usr.sbin/amd/config/Makefile.aix3 b/usr.sbin/amd/config/Makefile.aix3 new file mode 100644 index 0000000..c4bdd3a --- /dev/null +++ b/usr.sbin/amd/config/Makefile.aix3 @@ -0,0 +1,5 @@ +# @(#)Makefile.aix3 8.1 (Berkeley) 6/6/93 +# +# $Id: Makefile.aix3,v 5.2.2.1 1992/02/09 15:10:06 jsp beta $ +# +SYSLIB = -lbsd diff --git a/usr.sbin/amd/config/Makefile.bsd44 b/usr.sbin/amd/config/Makefile.bsd44 new file mode 100644 index 0000000..a41ff2d --- /dev/null +++ b/usr.sbin/amd/config/Makefile.bsd44 @@ -0,0 +1,8 @@ +# @(#)Makefile.bsd44 8.1 (Berkeley) 6/6/93 +# +# $Id: Makefile.bsd44,v 5.2.2.1 1992/02/09 15:10:12 jsp beta $ +# +# Extra Makefile definitions for 4.4 BSD +# + +RPCLIB = -lrpc diff --git a/usr.sbin/amd/config/Makefile.config b/usr.sbin/amd/config/Makefile.config new file mode 100644 index 0000000..0c4d7be --- /dev/null +++ b/usr.sbin/amd/config/Makefile.config @@ -0,0 +1,91 @@ +# @(#)Makefile.config 8.1 (Berkeley) 6/6/93 +# +# $Id: Makefile.config,v 5.2.2.1 1992/02/09 15:11:17 jsp beta $ +# + +# +# Comment/uncomment the following lines as required +# + +# +# Where local include files are stored +# +#XINCLUDE = -I/usr/local/athena/include + +# +# Define RESOLV if your C library does not include support +# for Hesiod and/or Named. +# +#RESOLV = -lhesiod -lresolv + +# +# Define XLIBDIR if you have libraries not on the standard +# search path. +# +#XLIBDIR = -L/usr/local/athena/lib + +# +# Define DBM if your C library does not include +# support for gdbm and/or ndbm. +# +#DBM = -lgdbm #-lndbm + +# +# Define RPCLIB if your C library does not include +# support for RPC +# +#RPCLIB = -lrpc + +# +# Include support for Network Information Service (NIS) +# Also define HAS_NIS_RELOAD to include map +# enumeration code implementing "cache:=all" +# +#HAS_NIS_MAPS = -DHAS_NIS_MAPS -DHAS_NIS_RELOAD + +# +# Include support for file maps +# +HAS_FILE_MAPS = -DHAS_FILE_MAPS + +# +# Include support for Hesiod +# Also define HAS_HESIOD_RELOAD to include zone +# transfer code implementing "cache:=all" +# +#HAS_HESIOD_MAPS = -DHAS_HESIOD_MAPS -DHAS_HESIOD_RELOAD + +# +# Include support for /etc/passwd +# +HAS_PASSWD_MAPS = -DHAS_PASSWD_MAPS + +# +# Include support for union maps +# +HAS_UNION_MAPS = -DHAS_UNION_MAPS + +# +# Include support for ndbm. +# This removes support for gdbm and is only supported +# if your operating system supports ndbm +# +#HAS_NDBM_MAPS = -DHAS_NDBM_MAPS + +# +# Include support for "regexp" maps +# +HAS_REGEXP = -DHAS_REGEXP + +# +# Make sure that the hostname passed in RPC authentication packets +# contains a fully qualified domain name. See nfs_ops.c +# +#HAS_NFS_QUALIFIED_NAMES = -DHAS_NFS_QUALIFIED_NAMES + +############################################################## +# Do NOT edit the following lines +# +CONFIG = ${XINCLUDE} ${HAS_NIS_MAPS} ${HAS_FILE_MAPS} ${HAS_HESIOD_MAPS} \ + ${HAS_NDBM_MAPS} ${HAS_MOUNTD_MAPS} ${HAS_PASSWD_MAPS} ${HAS_UNION_MAPS} \ + ${HAS_REGEXP} ${HAS_NFS_QUALIFIED_NAMES} diff --git a/usr.sbin/amd/config/Makefile.hpux b/usr.sbin/amd/config/Makefile.hpux new file mode 100644 index 0000000..dd92f9e --- /dev/null +++ b/usr.sbin/amd/config/Makefile.hpux @@ -0,0 +1,13 @@ +# @(#)Makefile.hpux 8.1 (Berkeley) 6/6/93 +# +# $Id: Makefile.hpux,v 5.2.2.1 1992/02/09 15:10:26 jsp beta $ +# +# Extra Makefile definitions for HP-UX +# + +#CC = gcc ${GCCOPTS} +# Works only on HP300 +CC = cc -Wc,-Nd2000 +SYSCC = $(CC) +# Works only Hp800 +# CC = cc diff --git a/usr.sbin/amd/config/Makefile.irix b/usr.sbin/amd/config/Makefile.irix new file mode 100644 index 0000000..e936b45 --- /dev/null +++ b/usr.sbin/amd/config/Makefile.irix @@ -0,0 +1,10 @@ +# @(#)Makefile.irix 8.1 (Berkeley) 6/6/93 +# +# $Id: Makefile.irix,v 5.2.2.1 1992/02/09 15:10:31 jsp beta $ +# +# Extra Makefile definitions for IRIX +# + +DEBUG = #-g -DDEBUG +CCOPTS = -I/usr/include/sun -I/usr/include/bsd -DIRIX +RESOLV = -lrpcsvc -lsun -lbsd diff --git a/usr.sbin/amd/config/Makefile.irix3 b/usr.sbin/amd/config/Makefile.irix3 new file mode 100644 index 0000000..165e0e4 --- /dev/null +++ b/usr.sbin/amd/config/Makefile.irix3 @@ -0,0 +1,13 @@ +# @(#)Makefile.irix3 8.1 (Berkeley) 6/6/93 +# +# $Id: Makefile.irix3,v 5.2 1992/05/31 16:40:22 jsp Exp $ +# +# Extra Makefile definitions for IRIX +# + +# For 3.3.x and earlier we might need to indicate the Sun and BSD include +# paths. + +DEBUG = #-g -DDEBUG +CCOPTS = -I/usr/include/sun -I/usr/include/bsd +RESOLV = -lrpcsvc -lsun -lbsd diff --git a/usr.sbin/amd/config/Makefile.irix4 b/usr.sbin/amd/config/Makefile.irix4 new file mode 100644 index 0000000..4480e93 --- /dev/null +++ b/usr.sbin/amd/config/Makefile.irix4 @@ -0,0 +1,14 @@ +# @(#)Makefile.irix4 8.1 (Berkeley) 6/6/93 +# +# $Id: Makefile.irix4,v 5.2 1992/05/31 16:40:22 jsp Exp $ +# +# Extra Makefile definitions for IRIX +# + +# For 4.0.X and later we need to specify the -cckr option - although amd +# has prototypes - some of the rpc prototypes clash. The special include +# paths are not required. -lsun always comes before -lbsd. + +DEBUG = -g +CCOPTS = -cckr +RESOLV = -lrpcsvc -lsun -lbsd diff --git a/usr.sbin/amd/config/Makefile.stellix b/usr.sbin/amd/config/Makefile.stellix new file mode 100644 index 0000000..0bcfff6 --- /dev/null +++ b/usr.sbin/amd/config/Makefile.stellix @@ -0,0 +1,10 @@ +# @(#)Makefile.stellix 8.1 (Berkeley) 6/6/93 +# +# $Id: Makefile.stellix,v 5.2.2.1 1992/02/09 15:10:45 jsp beta $ +# +# Extra Makefile definitions for STELLIX +# + +DEBUG = #-g -DDEBUG +CCOPTS = -DSTELLIX +RESOLV = -lrpcsvc diff --git a/usr.sbin/amd/config/RELEASE b/usr.sbin/amd/config/RELEASE new file mode 100644 index 0000000..36f8f1f --- /dev/null +++ b/usr.sbin/amd/config/RELEASE @@ -0,0 +1 @@ +$Revision: 5.2.3.1 $ of $Date: 1993/06/01 11:43:31 $ bsd44 diff --git a/usr.sbin/amd/config/arch b/usr.sbin/amd/config/arch new file mode 100644 index 0000000..71c9224 --- /dev/null +++ b/usr.sbin/amd/config/arch @@ -0,0 +1,126 @@ +#! /bin/sh +# +# Copyright (c) 1989 Jan-Simon Pendry +# Copyright (c) 1989 Imperial College of Science, Technology & Medicine +# Copyright (c) 1989, 1993 +# The Regents of the University of California. All rights reserved. +# +# This code is derived from software contributed to Berkeley by +# Jan-Simon Pendry at Imperial College, London. +# +# 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. +# +# @(#)arch 8.1 (Berkeley) 6/6/93 +# +# $Id: arch,v 5.2.2.2 1992/05/31 16:45:35 jsp Exp $ +# +# Figure out machine architecture +# + +PATH=/bin:/usr/bin:/usr/ucb:/etc:/usr/local/bin:${PATH} export PATH + +# +# First try to find a standard command +# +a=arch # Sun compat +m=machine # BSD compat +u=uname # Sys5 compat + +if [ -f /etc/$a -o -f /bin/$a -o -f /usr/bin/$a -o -f /usr/local/bin/$a ] +then + exec $a +elif [ -f /etc/$m -o -f /bin/$m -o -f /usr/bin/$m -o -f /usr/ucb/$m -o -f /usr/local/bin/$m ] +then + exec $m +elif [ -f /etc/$u -o -f /bin/$u -o -f /usr/bin/$u -o -f /usr/local/bin/$u ] +then + ARCH="`uname`" + case "$ARCH" in + "HP-UX") echo hp9000; exit 0;; + AIX*) MACH="`uname -m`" + case "$MACH" in + 00*) echo ibm6000; exit 0;; + 10*) echo ibm032; exit 0;; + 20*) echo ibm032; exit 0;; + esac + ;; + A/UX) echo macII ; exit 0 ;; + dgux) MACH="`uname -m`" + case "$MACH" in + AViiON) echo aviion; exit 0;; + esac + ;; + *) MACH="`uname -m`" + case "$MACH" in + IP6) echo mips; exit 0;; + IP7) echo mips; exit 0;; + *) ;; + esac + ;; + esac +fi + +# +# Take a pot-shot at your machine architecture +# +echo "# ... No ARCH= option specified; dynamically determining architecture" >&2 + +case "`exec 2>/dev/null; head -2 /etc/motd`" in +*"HP-UX"*) ARCH=hp9000;; +*"Iris"*) ARCH=iris4d;; +*"Ultrix"*) ARCH=vax;; +*"RISC iX"*) ARCH=arm;; +*"Umax 4.2"*) ARCH=encore;; +*"Alliant Concentrix"*) ARCH=alliant;; +*"FPS Model 500"*) ARCH=fps500;; +*"HCX/UX"*) ARCH=harris;; +*) ARCH=unknown; + if [ -d /usr/include/caif ]; then + ARCH=ibm032 + elif [ -f /bin/pyr ]; then + if /bin/pyr; then + ARCH=pyr + fi + elif [ -d /NextApps ]; then + ARCH=next + elif [ -f /etc/comply ]; then + # Tex 4300 is essentially a sun 3. + ARCH=sun3 + fi + ;; +esac + +echo "# ... architecture appears to be \"${ARCH}\"" >&2 +echo $ARCH + +case "$ARCH" in +unknown) exit 1 +esac + +exit 0 diff --git a/usr.sbin/amd/config/misc-aix3.h b/usr.sbin/amd/config/misc-aix3.h new file mode 100644 index 0000000..2c97d81 --- /dev/null +++ b/usr.sbin/amd/config/misc-aix3.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)misc-aix3.h 8.1 (Berkeley) 6/6/93 + * + * $Id: misc-aix3.h,v 5.2.2.1 1992/02/09 15:10:05 jsp beta $ + * + */ + +struct ufs_args { + char *fspec; /* Block device */ +}; + +struct nfs_args { + struct sockaddr_in addr; /* file server address */ + fhandle_t fh; /* File handle to be mounted */ + int flags; /* flags */ + int wsize; /* write size in bytes */ + int rsize; /* read size in bytes */ + int timeo; /* initial timeout in .1 secs */ + int retrans; /* times to retry send */ + char *hostname; /* server's hostname */ + int acregmin; /* attr cache file min secs */ + int acregmax; /* attr cache file max secs */ + int acdirmin; /* attr cache dir min secs */ + int acdirmax; /* attr cache dir max secs */ + char *netname; /* server's netname */ + int biods; /* number of BIODS */ +}; + +/* + * NFS mount option flags + */ +#define MNTOPT_RO "ro" /* read only */ +#define MNTOPT_RW "rw" /* read/write */ +#define MNTOPT_SOFT "soft" /* soft mount */ +#define MNTOPT_HARD "hard" /* hard mount */ +#define MNTOPT_NOSUID "nosuid"/* no set uid allowed */ +#define MNTOPT_NOAUTO "noauto"/* hide entry from mount -a */ +#define MNTOPT_INTR "intr" /* allow interrupts on hard mount */ +#define MNTOPT_SECURE "secure"/* use secure RPC for NFS */ +#define MNTOPT_GRPID "grpid" /* SysV-compatible group-id on create */ +#define MNTOPT_NOSUB "nosub" /* disallow mounts beneath this one */ +#define MNTOPT_MULTI "multi" /* Do multi-component lookup */ +#define MNTOPT_NOAC "noac" /* don't cache attributes */ + +#define NFSMNT_SOFT 0x001 /* soft mount (hard is default) */ +#define NFSMNT_WSIZE 0x002 /* set write size */ +#define NFSMNT_RSIZE 0x004 /* set read size */ +#define NFSMNT_TIMEO 0x008 /* set initial timeout */ +#define NFSMNT_RETRANS 0x010 /* set number of request retrys */ +#define NFSMNT_HOSTNAME 0x020 /* set hostname for error printf */ +#define NFSMNT_INT 0x040 /* allow interrupts on hard mount */ +#define NFSMNT_NOAC 0x080 /* don't cache attributes */ +#define NFSMNT_ACREGMIN 0x0100 /* set min secs for file attr cache */ +#define NFSMNT_ACREGMAX 0x0200 /* set max secs for file attr cache */ +#define NFSMNT_ACDIRMIN 0x0400 /* set min secs for dir attr cache */ +#define NFSMNT_ACDIRMAX 0x0800 /* set max secs for dir attr cache */ +#define NFSMNT_SECURE 0x1000 /* secure mount */ +#define NFSMNT_BIODS 0x10000 /* Number of biods for the file system */ + +#define DEF_BIODS 6 diff --git a/usr.sbin/amd/config/misc-hpux.h b/usr.sbin/amd/config/misc-hpux.h new file mode 100644 index 0000000..d808627 --- /dev/null +++ b/usr.sbin/amd/config/misc-hpux.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)misc-hpux.h 8.1 (Berkeley) 6/6/93 + * + * $Id: misc-hpux.h,v 5.2.2.1 1992/02/09 15:10:24 jsp beta $ + * + */ + +/* + * These definitions are from + * Unfortunately, that file cannot be included + * because it contains lots of structure definitions + * that are not wanted (they produce name clashes). + * Isn't HP-UX wonderful! + */ + +/* + * HP-UX specific definitions + */ +struct nfs_args { + struct sockaddr_in *addr; /* file server address */ + fhandle_t *fh; /* File handle to be mounted */ + int flags; /* flags */ + int wsize; /* write size in bytes */ + int rsize; /* read size in bytes */ + int timeo; /* initial timeout in .1 secs */ + int retrans; /* times to retry send */ + char *hostname; /* server's name */ +#ifdef __hp9000s700 /* XXX for HPUX 8.0 */ + char *fsname; /* server's filesystem name */ +#endif +}; + +/* + * NFS mount option flags + */ +#define NFSMNT_SOFT 0x001 /* soft mount (hard is default) */ +#define NFSMNT_WSIZE 0x002 /* set write size */ +#define NFSMNT_RSIZE 0x004 /* set read size */ +#define NFSMNT_TIMEO 0x008 /* set initial timeout */ +#define NFSMNT_RETRANS 0x010 /* set number of request retrys */ +#define NFSMNT_HOSTNAME 0x020 /* set hostname for error printf */ +#define NFSMNT_INT 0x040 /* set option to have interruptable mounts */ +#define NFSMNT_NODEVS 0x080 /* turn off device file access (default on) */ diff --git a/usr.sbin/amd/config/misc-irix.h b/usr.sbin/amd/config/misc-irix.h new file mode 100644 index 0000000..f7d6682 --- /dev/null +++ b/usr.sbin/amd/config/misc-irix.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)misc-irix.h 8.1 (Berkeley) 6/6/93 + * + * $Id: misc-irix.h,v 5.2.2.1 1992/02/09 15:10:30 jsp beta $ + * + */ + +#include +#include +#include + +struct ufs_args { + char *fspec; +}; diff --git a/usr.sbin/amd/config/misc-next.h b/usr.sbin/amd/config/misc-next.h new file mode 100644 index 0000000..46a498e --- /dev/null +++ b/usr.sbin/amd/config/misc-next.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)misc-next.h 8.1 (Berkeley) 6/6/93 + * + * $Id: misc-next.h,v 5.2.2.1 1992/02/09 15:10:34 jsp beta $ + * + */ + +#include diff --git a/usr.sbin/amd/config/misc-stellix.h b/usr.sbin/amd/config/misc-stellix.h new file mode 100644 index 0000000..275a853 --- /dev/null +++ b/usr.sbin/amd/config/misc-stellix.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)misc-stellix.h 8.1 (Berkeley) 6/6/93 + * + */ + +#include + +struct ufs_args { + char *fspec; +}; + +struct nfs_args { + struct sockaddr_in *addr; /* file server address */ + fhandle_t *fh; /* File handle to be mounted */ + int flags; /* flags */ + int wsize; /* write size in bytes */ + int rsize; /* read size in bytes */ + int timeo; /* initial timeout in .1 secs * +/ + int retrans; /* times to retry send */ + char *hostname; /* server's name */ +}; +#define NFSMNT_SOFT 0x001 /* soft mount (hard is default) */ +#define NFSMNT_WSIZE 0x002 /* set write size */ +#define NFSMNT_RSIZE 0x004 /* set read size */ +#define NFSMNT_TIMEO 0x008 /* set initial timeout (= 1.6 sec) */ +#define NFSMNT_RETRANS 0x010 /* set number of request retrys */ +#define NFSMNT_HOSTNAME 0x020 /* set hostname for error printf */ +#define NFSMNT_INT 0x040 /* allow interrupts on hard mount */ diff --git a/usr.sbin/amd/config/misc-ultrix.h b/usr.sbin/amd/config/misc-ultrix.h new file mode 100644 index 0000000..640c5a7 --- /dev/null +++ b/usr.sbin/amd/config/misc-ultrix.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)misc-ultrix.h 8.1 (Berkeley) 6/6/93 + * + * $Id: misc-ultrix.h,v 5.2.2.1 1992/02/09 15:10:49 jsp beta $ + * + */ + +#include +#define KERNEL +#include +#undef KERNEL + +#ifndef HOSTNAMESZ +#include +#endif + +#include + +#define ufs_args ufs_specific diff --git a/usr.sbin/amd/config/mount_aix.c b/usr.sbin/amd/config/mount_aix.c new file mode 100644 index 0000000..07d9e80 --- /dev/null +++ b/usr.sbin/amd/config/mount_aix.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)mount_aix.c 8.1 (Berkeley) 6/6/93 + * + * $Id: mount_aix.c,v 5.2.2.1 1992/02/09 15:10:08 jsp beta $ + * + */ + + +/* + * AIX 3 Mount helper + */ + +#include "misc-aix3.h" + +static int aix3_mkvp(p, gfstype, flags, object, stub, host, info, info_size, args) +char *p; +int gfstype; +int flags; +char *object; +char *stub; +char *host; +char *info; +int info_size; +char *args; +{ + struct vmount *vp = (struct vmount *) p; + bzero((voidp) vp, sizeof(*vp)); + /* + * Fill in standard fields + */ + vp->vmt_revision = VMT_REVISION; + vp->vmt_flags = flags; + vp->vmt_gfstype = gfstype; + +#define VMT_ROUNDUP(len) (4 * ((len + 3) / 4)) +#define VMT_ASSIGN(vp, idx, data, size) \ + vp->vmt_data[idx].vmt_off = p - (char *) vp; \ + vp->vmt_data[idx].vmt_size = size; \ + bcopy(data, p, size); \ + p += VMT_ROUNDUP(size); + + /* + * Fill in all variable length data + */ + p += sizeof(*vp); + + VMT_ASSIGN(vp, VMT_OBJECT, object, strlen(object) + 1); + VMT_ASSIGN(vp, VMT_STUB, stub, strlen(stub) + 1); + VMT_ASSIGN(vp, VMT_HOST, host, strlen(host) + 1); + VMT_ASSIGN(vp, VMT_HOSTNAME, host, strlen(host) + 1); + VMT_ASSIGN(vp, VMT_INFO, info, info_size); + VMT_ASSIGN(vp, VMT_ARGS, args, strlen(args) + 1); + +#undef VMT_ASSIGN +#undef VMT_ROUNDUP + + /* + * Return length + */ + return vp->vmt_length = p - (char *) vp; +} + +/* + * Map from conventional mount arguments + * to AIX 3-style arguments. + */ +aix3_mount(fsname, dir, flags, type, data, args) +char *fsname; +char *dir; +int flags; +int type; +void *data; +char *args; +{ + char buf[4096]; + int size; + +#ifdef DEBUG + dlog("aix3_mount: fsname %s, dir %s, type %d", fsname, dir, type); +#endif /* DEBUG */ + +/* aix3_mkvp(p, gfstype, flags, object, stub, host, info, info_size, args) */ + + switch (type) { + + case MOUNT_TYPE_NFS: { + char *host = strdup(fsname); + char *rfs = strchr(host, ':'); + int free_rfs = 0; + if (rfs) { + *rfs++ = '\0'; + } else { + rfs = host; + free_rfs = 1; + host = strdup(hostname); + } + + size = aix3_mkvp(buf, type, flags, rfs, dir, host, data, sizeof(struct nfs_args), args); + if (free_rfs) + free((voidp) rfs); + free(host); + + } break; + + case MOUNT_TYPE_UFS: + /* Need to open block device and extract log device info from sblk. */ + return EINVAL; + + default: + return EINVAL; + } +#ifdef DEBUG + /*dlog("aix3_mkvp: flags %#x, size %d, args %s", flags, size, args);*/ +#endif /* DEBUG */ + + return vmount(buf, size); +} diff --git a/usr.sbin/amd/config/mount_irix.c b/usr.sbin/amd/config/mount_irix.c new file mode 100644 index 0000000..9926960 --- /dev/null +++ b/usr.sbin/amd/config/mount_irix.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)mount_irix.c 8.1 (Berkeley) 6/6/93 + * + * $Id: mount_irix.c,v 5.2.2.1 1992/02/09 15:10:32 jsp beta $ + * + */ + + +/* + * IRIX Mount helper + */ + +#include "misc-irix.h" + +/* + * Map from conventional mount arguments + * to IRIX style arguments. + */ +irix_mount(fsname, dir, flags, type, data) +char *fsname; +char *dir; +int flags; +int type; +void *data; +{ + int size; + +#ifdef DEBUG + dlog("irix_mount: fsname %s, dir %s, type %d", fsname, dir, type); +#endif /* DEBUG */ + + if (type == MOUNT_TYPE_NFS) { + + size = sizeof (struct nfs_args); + + return mount(dir, dir, (MS_FSS|MS_DATA|flags), + type, (struct nfs_args *) data, size); + + } else if (type == MOUNT_TYPE_UFS) { + + return mount(fsname, dir, (MS_FSS|flags), type); + + } else { + return EINVAL; + } + +} diff --git a/usr.sbin/amd/config/mount_stellix.c b/usr.sbin/amd/config/mount_stellix.c new file mode 100644 index 0000000..45703db --- /dev/null +++ b/usr.sbin/amd/config/mount_stellix.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)mount_stellix.c 8.1 (Berkeley) 6/6/93 + */ + +/* + * IRIX Mount helper + */ + +#include "misc-stellix.h" + +/* + * Map from conventional mount arguments + * to IRIX style arguments. + */ +stellix_mount(fsname, dir, flags, type, data) +char *fsname; +char *dir; +int flags; +int type; +void *data; +{ + +#ifdef DEBUG + dlog("stellix_mount: fsname %s, dir %s, type %d", fsname, dir, type); +#endif /* DEBUG */ + + if (type == MOUNT_TYPE_NFS) { + + return mount(dir, dir, (MS_FSS|MS_NFS|flags), + type, (caddr_t) data ); + + } else if (type == MOUNT_TYPE_UFS) { + + return mount(fsname, dir, (MS_FSS|flags), type); + + } else { + return EINVAL; + } + +} diff --git a/usr.sbin/amd/config/mtab_aix.c b/usr.sbin/amd/config/mtab_aix.c new file mode 100644 index 0000000..78bf941 --- /dev/null +++ b/usr.sbin/amd/config/mtab_aix.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)mtab_aix.c 8.1 (Berkeley) 6/6/93 + * + * $Id: mtab_aix.c,v 5.2.2.1 1992/02/09 15:10:07 jsp beta $ + * + */ + +#include "am.h" + +#ifdef READ_MTAB_AIX3_STYLE + +#include +#include + +static struct mntent *mnt_dup(mp) +struct vmount *mp; +{ + struct mntent *new_mp = ALLOC(mntent); + + char *ty; + new_mp->mnt_fsname = strdup(vmt2dataptr(mp, VMT_OBJECT)); + new_mp->mnt_dir = strdup(vmt2dataptr(mp, VMT_STUB)); + new_mp->mnt_opts = strdup(vmt2dataptr(mp, VMT_ARGS)); + switch (mp->vmt_gfstype) { + case MNT_JFS: ty = MTAB_TYPE_UFS; break; + case MNT_NFS: + ty = MTAB_TYPE_NFS; + new_mp->mnt_fsname = str3cat(new_mp->mnt_fsname, + vmt2dataptr(mp, VMT_HOSTNAME), + ":", new_mp->mnt_fsname); + break; + default: ty = "unknown"; break; + } + new_mp->mnt_type = strdup(ty); + new_mp->mnt_passno = mp->vmt_vfsnumber; + new_mp->mnt_freq = 0; + + return new_mp; +} + +/* + * Read a mount table into memory + */ +mntlist *read_mtab(fs) +char *fs; +{ + mntlist **mpp, *mhp; + + int i; + char *mntinfo = 0, *cp; + struct vmount *vp; + int ret; + + /* + * First figure out size of mount table + * and allocate space for a copy... + * Then get mount table for real. + */ + ret = mntctl(MCTL_QUERY, sizeof(i), &i); + if (ret == 0) { + mntinfo = xmalloc(i); + ret = mntctl(MCTL_QUERY, i, mntinfo); + } + + if (ret <= 0) { + plog(XLOG_ERROR, "mntctl: %m"); + goto out; + } +#ifdef DEBUG + /*dlog("mntctl returns %d structures", ret);*/ +#endif /* DEBUG */ + + mpp = &mhp; + for (i = 0, cp = mntinfo; i < ret; i++, cp += vp->vmt_length) { + vp = (struct vmount *) cp; + + /* + * Allocate a new slot + */ + *mpp = ALLOC(mntlist); + + /* + * Copy the data returned by mntctl + */ + (*mpp)->mnt = mnt_dup(vp); + + /* + * Move to next pointer + */ + mpp = &(*mpp)->mnext; + } + + *mpp = 0; + +out: + if (mntinfo) + free(mntinfo); + return mhp; +} + +#endif /* READ_MTAB_AIX3_STYLE */ diff --git a/usr.sbin/amd/config/mtab_bsd.c b/usr.sbin/amd/config/mtab_bsd.c new file mode 100644 index 0000000..1d81127 --- /dev/null +++ b/usr.sbin/amd/config/mtab_bsd.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)mtab_bsd.c 8.1 (Berkeley) 6/6/93 + * + * $Id: mtab_bsd.c,v 5.2.2.1 1992/02/09 15:10:13 jsp beta $ + * + */ + +#include "am.h" + +#ifdef READ_MTAB_BSD_STYLE + +#include + +static struct mntent *mnt_dup(mp) +struct statfs *mp; +{ + struct mntent *new_mp = ALLOC(mntent); + char *ty; + + new_mp->mnt_fsname = strdup(mp->f_mntfromname); + new_mp->mnt_dir = strdup(mp->f_mntonname); + switch (mp->f_type) { + case MOUNT_UFS: ty = MTAB_TYPE_UFS; break; + case MOUNT_NFS: ty = MTAB_TYPE_NFS; break; + case MOUNT_MFS: ty = MTAB_TYPE_MFS; break; + default: ty = "unknown"; break; + } + new_mp->mnt_type = strdup(ty); + new_mp->mnt_opts = strdup("unset"); + new_mp->mnt_freq = 0; + new_mp->mnt_passno = 0; + + return new_mp; +} + +/* + * Read a mount table into memory + */ +mntlist *read_mtab(fs) +char *fs; +{ + mntlist **mpp, *mhp; + struct statfs *mntbufp, *mntp; + + int nloc = getmntinfo(&mntbufp, MNT_NOWAIT); + + if (nloc == 0) { + plog(XLOG_ERROR, "Can't read mount table"); + return 0; + } + + mpp = &mhp; + for (mntp = mntbufp; mntp < mntbufp + nloc; mntp++) { + /* + * Allocate a new slot + */ + *mpp = ALLOC(mntlist); + + /* + * Copy the data returned by getmntent + */ + (*mpp)->mnt = mnt_dup(mntp); + + /* + * Move to next pointer + */ + mpp = &(*mpp)->mnext; + } + + /* + * Terminate the list + */ + *mpp = 0; + + return mhp; +} + +#endif /* READ_MTAB_BSD_STYLE */ diff --git a/usr.sbin/amd/config/mtab_file.c b/usr.sbin/amd/config/mtab_file.c new file mode 100644 index 0000000..8101f71 --- /dev/null +++ b/usr.sbin/amd/config/mtab_file.c @@ -0,0 +1,472 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)mtab_file.c 8.1 (Berkeley) 6/6/93 + * + * $Id: mtab_file.c,v 5.2.2.1 1992/02/09 15:10:42 jsp beta $ + * + */ + +#include "am.h" + +#ifdef READ_MTAB_FROM_FILE + +#ifdef USE_FCNTL +#include +#else +#include +#endif /* USE_FCNTL */ + +#ifdef UPDATE_MTAB + +/* + * Do strict /etc/mtab locking + */ +#define MTAB_LOCKING + +/* + * Firewall mtab entries + */ +#define MTAB_STRIPNL + +#include +static FILE *mnt_file; + +/* + * If the system is being trashed by something, then + * opening mtab may fail with ENFILE. So, go to sleep + * for a second and try again. (Yes - this has happened to me.) + * + * Note that this *may* block the automounter, oh well. + * If we get to this state then things are badly wrong anyway... + * + * Give the system 10 seconds to recover but then give up. + * Hopefully something else will exit and free up some file + * table slots in that time. + */ +#define NFILE_RETRIES 10 /* seconds */ + +#ifdef MTAB_LOCKING +#ifdef LOCK_FCNTL +static int lock(fd) +{ + int rc; + struct flock lk; + + lk.l_type = F_WRLCK; + lk.l_whence = 0; + lk.l_start = 0; + lk.l_len = 0; + +again: + rc = fcntl(fd, F_SETLKW, (caddr_t) &lk); + if (rc < 0 && (errno == EACCES || errno == EAGAIN)) { +#ifdef DEBUG + dlog("Blocked, trying to obtain exclusive mtab lock"); +#endif /* DEBUG */ + sleep(1); + goto again; + } + return rc; +} +#else +#define lock(fd) (flock((fd), LOCK_EX)) +#endif /* LOCK_FCNTL */ +#endif /* MTAB_LOCKING */ + +static FILE *open_locked_mtab(mtab_file, mode, fs) +char *mtab_file; +char *mode; +char *fs; +{ + FILE *mfp = 0; + +#ifdef UPDATE_MTAB + /* + * There is a possible race condition if two processes enter + * this routine at the same time. One will be blocked by the + * exclusive lock below (or by the shared lock in setmntent) + * and by the time the second process has the exclusive lock + * it will be on the wrong underlying object. To check for this + * the mtab file is stat'ed before and after all the locking + * sequence, and if it is a different file then we assume that + * it may be the wrong file (only "may", since there is another + * race between the initial stat and the setmntent). + * + * Simpler solutions to this problem are invited... + */ + int racing = 2; +#ifdef MTAB_LOCKING + int rc; + int retries = 0; + struct stat st_before, st_after; +#endif /* MTAB_LOCKING */ + + if (mnt_file) { +#ifdef DEBUG + dlog("Forced close on %s in read_mtab", mtab_file); +#endif /* DEBUG */ + endmntent(mnt_file); + mnt_file = 0; + } + +#ifdef MTAB_LOCKING +again: + if (mfp) { + endmntent(mfp); + mfp = 0; + } + + clock_valid = 0; + if (stat(mtab_file, &st_before) < 0) { + plog(XLOG_ERROR, "%s: stat: %m", mtab_file); + if (errno == ESTALE) { + /* happens occasionally */ + sleep(1); + goto again; + } + return 0; + } +#endif /* MTAB_LOCKING */ +#endif /* UPDATE_MTAB */ + +eacces: + mfp = setmntent(mtab_file, mode); + if (!mfp) { + /* + * Since setmntent locks the descriptor, it + * is possible it can fail... so retry if + * needed. + */ + if (errno == EACCES || errno == EAGAIN) { +#ifdef DEBUG + dlog("Blocked, trying to obtain exclusive mtab lock"); +#endif /* DEBUG */ + goto eacces; + } else if (errno == ENFILE && retries++ < NFILE_RETRIES) { + sleep(1); + goto eacces; + } + + plog(XLOG_ERROR, "setmntent(\"%s\", \"%s\"): %m", mtab_file, mode); + return 0; + } + +#ifdef MTAB_LOCKING +#ifdef UPDATE_MTAB + /* + * At this point we have an exclusive lock on the mount list, + * but it may be the wrong one so... + */ + + /* + * Need to get an exclusive lock on the current + * mount table until we have a new copy written + * out, when the lock is released in free_mntlist. + * flock is good enough since the mount table is + * not shared between machines. + */ + do + rc = lock(fileno(mfp)); + while (rc < 0 && errno == EINTR); + if (rc < 0) { + plog(XLOG_ERROR, "Couldn't lock %s: %m", mtab_file); + endmntent(mfp); + return 0; + } + /* + * Now check whether the mtab file has changed under our feet + */ + if (stat(mtab_file, &st_after) < 0) { + plog(XLOG_ERROR, "%s: stat", mtab_file); + goto again; + } + + if (st_before.st_dev != st_after.st_dev || + st_before.st_ino != st_after.st_ino) { + struct timeval tv; + if (racing == 0) { + /* Sometimes print a warning */ + plog(XLOG_WARNING, + "Possible mount table race - retrying %s", fs); + } + racing = (racing+1) & 3; + /* + * Take a nap. From: Doug Kingston + */ + tv.tv_sec = 0; + tv.tv_usec = (mypid & 0x07) << 17; + if (tv.tv_usec) + if (select(0, (voidp) 0, (voidp) 0, (voidp) 0, &tv) < 0) + plog(XLOG_WARNING, "mtab nap failed: %m"); + + goto again; + } +#endif /* UPDATE_MTAB */ +#endif /* MTAB_LOCKING */ + + return mfp; +} + +/* + * Unlock the mount table + */ +void unlock_mntlist P((void)); +void unlock_mntlist() +{ + /* + * Release file lock, by closing the file + */ + if (mnt_file) { + endmntent(mnt_file); + mnt_file = 0; + } +} + +/* + * Write out a mount list + */ +void rewrite_mtab(mp) +mntlist *mp; +{ + FILE *mfp; + int error = 0; + + /* + * Concoct a temporary name in the same + * directory as the target mount table + * so that rename() will work. + */ + char tmpname[64]; + int retries; + int tmpfd; + char *cp; + char *mcp = mtab; + cp = strrchr(mcp, '/'); + if (cp) { + bcopy(mcp, tmpname, cp - mcp); + tmpname[cp-mcp] = '\0'; + } else { + plog(XLOG_WARNING, "No '/' in mtab (%s), using \".\" as tmp directory", mtab); + tmpname[0] = '.'; tmpname[1] = '\0'; + } + strcat(tmpname, "/mtabXXXXXX"); + mktemp(tmpname); + retries = 0; +enfile1: + if ((tmpfd = open(tmpname, O_RDWR|O_CREAT|O_TRUNC, 0644)) < 0) { + if (errno == ENFILE && retries++ < NFILE_RETRIES) { + sleep(1); + goto enfile1; + } + plog(XLOG_ERROR, "%s: open: %m", tmpname); + return; + } + if (close(tmpfd) < 0) + plog(XLOG_ERROR, "Couldn't close tmp file descriptor: %m"); + + retries = 0; +enfile2: + mfp = setmntent(tmpname, "w"); + if (!mfp) { + if (errno == ENFILE && retries++ < NFILE_RETRIES) { + sleep(1); + goto enfile2; + } + plog(XLOG_ERROR, "setmntent(\"%s\", \"w\"): %m", tmpname); + error = 1; + goto out; + } + + while (mp) { + if (mp->mnt) { + if (addmntent(mfp, mp->mnt)) { + plog(XLOG_ERROR, "Can't write entry to %s", tmpname); + error = 1; + goto out; + } + } + mp = mp->mnext; + } + + /* + * SunOS 4.1 manuals say that the return code from entmntent() + * is always 1 and to treat as a void. That means we need to + * call fflush() to make sure the new mtab file got written. + */ + if (fflush(mfp)) { + plog(XLOG_ERROR, "flush new mtab file: %m"); + error = 1; + goto out; + } + + (void) endmntent(mfp); + + /* + * Rename temporary mtab to real mtab + */ + if (rename(tmpname, mtab) < 0) { + plog(XLOG_ERROR, "rename %s to %s: %m", tmpname, mtab); + error = 1; + goto out; + } + +out: + if (error) + (void) unlink(tmpname); +} + +#ifdef MTAB_STRIPNL +static void mtab_stripnl(s) +char *s; +{ + do { + s = strchr(s, '\n'); + if (s) + *s++ = ' '; + } while (s); +} +#endif /* MTAB_STRIPNL */ + +/* + * Append a mntent structure to the + * current mount table. + */ +void write_mntent(mp) +struct mntent *mp; +{ + int retries = 0; + FILE *mfp; +enfile: + mfp = open_locked_mtab(mtab, "a", mp->mnt_dir); + if (mfp) { +#ifdef MTAB_STRIPNL + mtab_stripnl(mp->mnt_opts); +#endif /* MTAB_STRIPNL */ + if (addmntent(mfp, mp)) + plog(XLOG_ERROR, "Couldn't write %s: %m", mtab); + if (fflush(mfp)) + plog(XLOG_ERROR, "Couldn't flush %s: %m", mtab); + (void) endmntent(mfp); + } else { + if (errno == ENFILE && retries < NFILE_RETRIES) { + sleep(1); + goto enfile; + } + plog(XLOG_ERROR, "setmntent(\"%s\", \"a\"): %m", mtab); + } +} + +#endif /* UPDATE_MTAB */ + +static struct mntent *mnt_dup(mp) +struct mntent *mp; +{ + struct mntent *new_mp = ALLOC(mntent); + + new_mp->mnt_fsname = strdup(mp->mnt_fsname); + new_mp->mnt_dir = strdup(mp->mnt_dir); + new_mp->mnt_type = strdup(mp->mnt_type); + new_mp->mnt_opts = strdup(mp->mnt_opts); + + new_mp->mnt_freq = mp->mnt_freq; + new_mp->mnt_passno = mp->mnt_passno; + +#ifdef FIXUP_MNTENT_DUP + /* + * Additional fields get dup'ed here + */ + FIXUP_MNTENT_DUP(new_mp, mp); +#endif + + return new_mp; +} + +/* + * Read a mount table into memory + */ +mntlist *read_mtab(fs) +char *fs; +{ + mntlist **mpp, *mhp; + + struct mntent *mep; + FILE *mfp = open_locked_mtab(mtab, "r+", fs); + + if (!mfp) + return 0; + + mpp = &mhp; + +/* + * XXX - In SunOS 4 there is (yet another) memory leak + * which loses 1K the first time getmntent is called. + * (jsp) + */ + while (mep = getmntent(mfp)) { + /* + * Allocate a new slot + */ + *mpp = ALLOC(mntlist); + + /* + * Copy the data returned by getmntent + */ + (*mpp)->mnt = mnt_dup(mep); + + /* + * Move to next pointer + */ + mpp = &(*mpp)->mnext; + } + *mpp = 0; + +#ifdef UPDATE_MTAB + /* + * If we are not updating the mount table then we + * can free the resources held here, otherwise they + * must be held until the mount table update is complete + */ + mnt_file = mfp; +#else + endmntent(mfp); +#endif /* UPDATE_MTAB */ + + return mhp; +} + +#endif /* READ_MTAB_FROM_FILE */ diff --git a/usr.sbin/amd/config/mtab_ultrix.c b/usr.sbin/amd/config/mtab_ultrix.c new file mode 100644 index 0000000..241ea88 --- /dev/null +++ b/usr.sbin/amd/config/mtab_ultrix.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)mtab_ultrix.c 8.1 (Berkeley) 6/6/93 + * + * $Id: mtab_ultrix.c,v 5.2.2.1 1992/02/09 15:10:50 jsp beta $ + * + */ + +#include "am.h" + +#ifdef READ_MTAB_ULTRIX_STYLE + +#include +#include + +static struct mntent *mnt_dup(mp) +struct fs_data *mp; +{ + struct mntent *new_mp = ALLOC(mntent); + + new_mp->mnt_fsname = strdup(mp->fd_devname); + new_mp->mnt_dir = strdup(mp->fd_path); + if (mp->fd_fstype >= GT_NUMTYPES) + mp->fd_fstype = GT_UNKWN; + else if (gt_names[mp->fd_fstype] == 0) + mp->fd_fstype = GT_UNKWN; + new_mp->mnt_type = strdup(gt_names[mp->fd_fstype]); + new_mp->mnt_opts = strdup("unset"); + + new_mp->mnt_freq = 0; + new_mp->mnt_passno = mp->fd_dev; + + return new_mp; +} + +/* + * Read a mount table into memory + */ +mntlist *read_mtab(fs) +char *fs; +{ + mntlist **mpp, *mhp; + +/* From: Piete Brooks */ + + int loc=0; +#undef NMOUNT +#define NMOUNT 20 + struct fs_data mountbuffer[NMOUNT], *fs_data; + int ret; + + mpp = &mhp; + while ((ret = getmountent(&loc, mountbuffer, NMOUNT)) > 0) { + for (fs_data = mountbuffer; fs_data < &mountbuffer[ret]; fs_data++) { + /* + * Allocate a new slot + */ + *mpp = ALLOC(mntlist); + + /* + * Copy the data returned by getmntent + */ + (*mpp)->mnt = mnt_dup(fs_data); + + /* + * Move to next pointer + */ + mpp = &(*mpp)->mnext; + } + } + if (ret < 0) { + plog(XLOG_ERROR, "getmountent: %m"); + return 0; + } + *mpp = 0; + + return mhp; +} + +#endif /* READ_MTAB_ULTRIX_STYLE */ diff --git a/usr.sbin/amd/config/newvers.sh b/usr.sbin/amd/config/newvers.sh new file mode 100644 index 0000000..a510966 --- /dev/null +++ b/usr.sbin/amd/config/newvers.sh @@ -0,0 +1,88 @@ +#!/bin/sh - +# +# Copyright (c) 1989 Jan-Simon Pendry +# Copyright (c) 1989 Imperial College of Science, Technology & Medicine +# Copyright (c) 1989, 1993 +# The Regents of the University of California. All Rights Reserved. +# +# This code is derived from software contributed to Berkeley by +# Jan-Simon Pendry at Imperial College, London. +# +# 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. +# +# @(#)newvers.sh 8.1 (Berkeley) 6/6/93 +# +# $Id: newvers.sh,v 5.2.2.1 1992/02/09 15:11:19 jsp beta $ +# +PATH=/usr/ucb:/bin:/usr/bin:$PATH +if [ $# -ne 3 ]; then echo "Usage: newvers program arch os" >&2; exit 1; fi +version="version.$1" +if [ ! -r $version ]; then echo 0 > $version; chmod 444 $version; fi +v=`cat $version` +u=${USER-${LOGNAME-root}} +h=`hostname` +#h=`expr "$h" : '\([^.]*\)'` +t=`date` +if [ ! -s "$d../config/RELEASE" -o ! -s "$d../text/COPYRIGHT" ]; then + echo ERROR: config file missing >&2 + exit 1 +fi +rm -f vers.$1.c +( +cat << %% +char copyright[] = "\\ +%% +sed 's/$/\\n\\/' $d../text/COPYRIGHT +cat << %% +"; +char version[] = "\\ +%% +cat << %% +$1 \\ +%% +sed \ + -e 's/\$//g' \ + -e 's/[A-Z][a-z]*://g' \ + -e 's/ */ /g' \ + -e 's/^ //' \ + -e 's/$/\\/' \ + $d../config/RELEASE +cat << %% + #${v}: ${t}\\n\\ +Built by ${u}@${h} for \\ +%% +case "$2" in +[aeiou]*) echo "an \\" ;; +*) echo "a \\";; +esac +echo "$2 running $3\";" +) > vers.$1.c +rm -f $version +expr ${v} + 1 > $version +chmod 444 $version diff --git a/usr.sbin/amd/config/os-acis43.h b/usr.sbin/amd/config/os-acis43.h new file mode 100644 index 0000000..bcc44d5 --- /dev/null +++ b/usr.sbin/amd/config/os-acis43.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-acis43.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-acis43.h,v 5.2.2.1 1992/02/09 15:10:02 jsp beta $ + * + * IBM RT ACIS4.3 definitions for Amd (automounter) + */ + +/* + * Does the compiler grok void * + */ +#define VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Does this OS have NDBM support? + */ +#define OS_HAS_NDBM + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS MOUNT_NFS +#define MOUNT_TYPE_UFS MOUNT_UFS +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "ufs" + +#undef ARCH_ENDIAN +#define ARCH_ENDIAN "big" + +/* + * Need precise symlink lengths +#define PRECISE_SYMLINKS + */ diff --git a/usr.sbin/amd/config/os-aix3.h b/usr.sbin/amd/config/os-aix3.h new file mode 100644 index 0000000..c70b159 --- /dev/null +++ b/usr.sbin/amd/config/os-aix3.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-aix3.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-aix3.h,v 5.2.2.2 1992/05/31 16:38:49 jsp Exp $ + * + * AIX 3.1 definitions for Amd (automounter) + */ + +/* + * Does the compiler grok void * + */ +#define VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_4 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_AIX3 + +/* + * Does this OS have NDBM support? + */ +#define OS_HAS_NDBM + +/* + * The mount table is obtained from the kernel + */ +#undef UPDATE_MTAB + +/* + * Pick up BSD bits from include files + * Try for 4.4 compatibility if available (AIX 3.2 and later) + */ +#define _BSD 44 + +/* + * No mntent info on AIX 3 + */ +#undef MNTENT_HDR +#define MNTENT_HDR + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS MNT_NFS +#define MOUNT_TYPE_UFS MNT_JFS +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "jfs" + +/* + * How to unmount filesystems + */ +#undef MOUNT_TRAP +#define MOUNT_TRAP(type, mnt, flag, mnt_data) \ + aix3_mount(mnt->mnt_fsname, mnt->mnt_dir, flag, type, mnt_data, mnt->mnt_opts) +#undef UNMOUNT_TRAP +#define UNMOUNT_TRAP(mnt) uvmount(mnt->mnt_passno, 0) + + +/* + * Byte ordering + */ +#ifndef BYTE_ORDER +#include +#endif /* BYTE_ORDER */ + +#undef ARCH_ENDIAN +#if BYTE_ORDER == LITTLE_ENDIAN +#define ARCH_ENDIAN "little" +#else +#if BYTE_ORDER == BIG_ENDIAN +#define ARCH_ENDIAN "big" +#else +XXX - Probably no hope of running Amd on this machine! +#endif /* BIG */ +#endif /* LITTLE */ + +/* + * Miscellaneous AIX 3 bits + */ +#define NEED_MNTOPT_PARSER +#define SHORT_MOUNT_NAME + +#define MNTMAXSTR 128 + +#define MNTTYPE_UFS "jfs" /* Un*x file system */ +#define MNTTYPE_NFS "nfs" /* network file system */ +#define MNTTYPE_IGNORE "ignore" /* No type specified, ignore this entry */ + +struct mntent { + char *mnt_fsname; /* name of mounted file system */ + char *mnt_dir; /* file system path prefix */ + char *mnt_type; /* MNTTYPE_* */ + char *mnt_opts; /* MNTOPT* */ + int mnt_freq; /* dump frequency, in days */ + int mnt_passno; /* pass number on parallel fsck */ +}; + +#define NFS_HDR "misc-aix3.h" +#define UFS_HDR "misc-aix3.h" +#undef NFS_FH_DREF +#define NFS_FH_DREF(dst, src) { (dst) = *(src); } +#undef NFS_SA_DREF +#define NFS_SA_DREF(dst, src) { (dst).addr = *(src); } +#define M_RDONLY MNT_READONLY + +/* + * How to get a mount list + */ +#undef READ_MTAB_FROM_FILE +#define READ_MTAB_AIX3_STYLE + +/* + * The data for the mount syscall needs the path in addition to the + * host name since that is the only source of information about the + * mounted filesystem. +#define NFS_ARGS_NEEDS_PATH + */ + +#define NFS_LOMAP 34 +#define NFS_HIMAP 99 +#define NFS_ERROR_MAPPING \ +static nfs_errormap[] = { 0,75,77,99,99,99, \ + 99,99,99,99,99,78,99,99,99,79, \ + 99,99,70,99,35,36,37,38,39,40, \ + 41,42,43,44,45,46,47,48,49,50, \ + 51,52,53,54,55,56,57,58,60,61, \ + 64,65,99,67,68,62,63,66,69,68, \ + 99,99,99,71,99,99,99,99,99,99 \ + }; + +#define MOUNT_HELPER_SOURCE "mount_aix.c" + +/* + * Need this too + */ +#include diff --git a/usr.sbin/amd/config/os-aux.h b/usr.sbin/amd/config/os-aux.h new file mode 100644 index 0000000..edd85a4 --- /dev/null +++ b/usr.sbin/amd/config/os-aux.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-aux.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-aux.h,v 5.2.2.1 1992/02/09 15:10:10 jsp beta $ + * + * A/UX macII definitions for Amd (automounter) + * Contributed by Julian Onions + */ + +/* + * Does the compiler grok void * + */ +#define VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#define ARCH_ENDIAN "big" + +/* + * No support for ndbm + */ +#undef OS_HAS_NDBM + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_UFS MOUNT_UFS +#define MOUNT_TYPE_NFS MOUNT_NFS + +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "5.2" + +#define SIGCHLD SIGCLD +#define SYS5_SIGNALS + +/* + * Use rather than + */ +#define USE_FCNTL + +/* + * Use fcntl() rather than flock() + */ +#define LOCK_FCNTL + +#ifdef __GNUC__ +#define alloca(sz) __builtin_alloca(sz) +#endif + +#define bzero(ptr, len) memset(ptr, 0, len) +#define bcopy(from, to, len) memcpy(to, from, len) +#define getpagesize() (2048) +#undef MOUNT_TRAP +#define MOUNT_TRAP(type, mnt, flags, mnt_data) \ + fsmount(type, mnt->mnt_dir, flags, mnt_data) +#undef UNMOUNT_TRAP +#define UNMOUNT_TRAP(mnt) unmount(mnt->mnt_dir) +#define NFDS 30 /* conservative */ + +/* not included in sys/param.h */ +#include +/* not part of sys/time.h */ +#include +/* for NMOUNT */ +#include diff --git a/usr.sbin/amd/config/os-bsd44.h b/usr.sbin/amd/config/os-bsd44.h new file mode 100644 index 0000000..837d596 --- /dev/null +++ b/usr.sbin/amd/config/os-bsd44.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-bsd44.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-bsd44.h,v 5.2.2.1 1992/02/09 15:10:11 jsp beta $ + * + * 4.4 BSD definitions for Amd (automounter) + */ + +/* + * Does the compiler grok void * + */ +#define VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_4 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_44 +#define HAS_TCP_NFS + +/* + * Does this OS have NDBM support? + */ +#define OS_HAS_NDBM + +/* + * 4.4 doesn't provide NIS. + */ +#undef HAS_NIS_MAPS + +/* + * OS provides strerror() + */ +#define HAS_STRERROR + +/* + * The mount table is obtained from the kernel + */ +#undef UPDATE_MTAB + +/* + * No mntent info on 4.4 BSD + */ +#undef MNTENT_HDR + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS MOUNT_NFS +#define MOUNT_TYPE_UFS MOUNT_UFS +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "ufs" +#define MTAB_TYPE_MFS "mfs" + +/* + * How to unmount filesystems + */ +#undef UNMOUNT_TRAP +#undef NEED_UMOUNT_FS +#define NEED_UMOUNT_BSD + +/* + * How to copy an address into an NFS filehandle + */ +#undef NFS_SA_DREF +#define NFS_SA_DREF(dst, src) { \ + (dst).addr = (struct sockaddr *) (src); \ + (dst).addrlen = sizeof(*src); \ + (dst).sotype = SOCK_DGRAM; \ + (dst).proto = 0; \ + } + +/* + * Byte ordering + */ +#ifndef BYTE_ORDER +#include +#endif /* BYTE_ORDER */ + +#undef ARCH_ENDIAN +#if BYTE_ORDER == LITTLE_ENDIAN +#define ARCH_ENDIAN "little" +#else +#if BYTE_ORDER == BIG_ENDIAN +#define ARCH_ENDIAN "big" +#else +XXX - Probably no hope of running Amd on this machine! +#endif /* BIG */ +#endif /* LITTLE */ + +/* + * Miscellaneous 4.4 BSD bits + */ +#define NEED_MNTOPT_PARSER +#define SHORT_MOUNT_NAME + +#define MNTMAXSTR 128 + +#define MNTTYPE_UFS "ufs" /* Un*x file system */ +#define MNTTYPE_NFS "nfs" /* network file system */ +#define MNTTYPE_MFS "mfs" /* memory file system */ +#define MNTTYPE_IGNORE "ignore" /* No type specified, ignore this entry */ + +#define M_RDONLY MNT_RDONLY +#define M_SYNC MNT_SYNCHRONOUS +#define M_NOEXEC MNT_NOEXEC +#define M_NOSUID MNT_NOSUID +#define M_NODEV MNT_NODEV + +#define MNTOPT_SOFT "soft" /* soft mount */ +#define MNTOPT_INTR "intr" /* interrupts allowed */ + +#define NFSMNT_HOSTNAME 0 /* hostname on 4.4 is not optional */ + +struct mntent { + char *mnt_fsname; /* name of mounted file system */ + char *mnt_dir; /* file system path prefix */ + char *mnt_type; /* MNTTYPE_* */ + char *mnt_opts; /* MNTOPT* */ + int mnt_freq; /* dump frequency, in days */ + int mnt_passno; /* pass number on parallel fsck */ +}; + +/* + * Type of a file handle + */ +#undef NFS_FH_TYPE +#define NFS_FH_TYPE nfsv2fh_t * + +/* + * How to get a mount list + */ +#undef READ_MTAB_FROM_FILE +#define READ_MTAB_BSD_STYLE + +/* + * The data for the mount syscall needs the path in addition to the + * host name since that is the only source of information about the + * mounted filesystem. + */ +#define NFS_ARGS_NEEDS_PATH + +/* + * 4.4 has RE support built in + */ +#undef RE_HDR +#define RE_HDR diff --git a/usr.sbin/amd/config/os-concentrix.h b/usr.sbin/amd/config/os-concentrix.h new file mode 100644 index 0000000..4a130e0 --- /dev/null +++ b/usr.sbin/amd/config/os-concentrix.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-concentrix.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-concentrix.h,v 5.2.2.1 1992/02/09 15:10:14 jsp beta $ + * + * Alliant Concentrix 5.0.0 definitions for Amd (automounter) + */ + +/* + * Does the compiler grok void * + */ +#undef VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Does this OS have NDBM support? + */ +#define OS_HAS_NDBM + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#define ARCH_ENDIAN "big" + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS MOUNT_NFS +#define MOUNT_TYPE_UFS MOUNT_UFS diff --git a/usr.sbin/amd/config/os-convex.h b/usr.sbin/amd/config/os-convex.h new file mode 100644 index 0000000..ade6c4c --- /dev/null +++ b/usr.sbin/amd/config/os-convex.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-convex.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-convex.h,v 5.2.2.1 1992/02/09 15:10:16 jsp beta $ + * + * Convex C220, version 7.1 definitions for Amd (automounter) + * from Eitan Mizrotsky + */ + + +/* + * Does the compiler grok void * + */ +#undef VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#define ARCH_ENDIAN "big" + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_UFS MOUNT_UFS +#define MOUNT_TYPE_NFS MOUNT_NFS + + +#define strrchr rindex +#define strchr index diff --git a/usr.sbin/amd/config/os-defaults.h b/usr.sbin/amd/config/os-defaults.h new file mode 100644 index 0000000..ce10ae2 --- /dev/null +++ b/usr.sbin/amd/config/os-defaults.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-defaults.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-defaults.h,v 5.2.2.1 1992/02/09 15:10:17 jsp beta $ + * + * Common OS definitions. These may be overridden in + * the OS specific files ("os-foo.h"). + */ + +/* + * What level of AMD are we backward compatible with? + * This only applies to externally visible characteristics. + * Rev.Minor.Branch.Patch (2 digits each) + */ +#define AMD_COMPAT 5000000 /* 5.0 */ + +/* + * What type is free(void*) returning? + */ +#define FREE_RETURN_TYPE void + +/* + * Is the mount table mirrored in software + */ +#define UPDATE_MTAB + +/* + * Where to get union wait + */ +#define WAIT + +/* + * Where to get mount entry info + */ +#define MNTENT_HDR + +/* + * Include support for syslog() + */ +#define HAS_SYSLOG + +/* + * Byte ordering + */ +#define ARCH_ENDIAN "unknown" + +/* + * Name of filesystem types + */ +#define MTAB_TYPE_NFS "nfs" +#define MTAB_TYPE_UFS "4.2" + +/* + * Name of mount & unmount system calls + * + * NOTE: + * UNMOUNT_TRAP takes a struct mntent * + */ +#define MOUNT_TRAP(type, mnt, flags, mnt_data) \ + mount(type, mnt->mnt_dir, flags, mnt_data) +#define UNMOUNT_TRAP(mnt) unmount(mnt->mnt_dir) + +/* + * How to unmount filesystems. + * NEED_UMOUNT_FS includes code to scan the mount table + * to find the correct information for the unmount system + * call. Some systems, such as 4.4bsd, do not require + * this - they can just do an unmount system call directly. + */ +#define NEED_UMOUNT_FS +#define UMOUNT_FS(dir) umount_fs(dir) + +/* + * Type of a file handle + */ +#define NFS_FH_TYPE fhandle_t * +#define NFS_FH_DREF(dst, src) { (dst) = (src); } + +/* + * How to copy an address into an NFS filehandle + */ +#define NFS_SA_DREF(dst, src) { (dst).addr = (src); } + +/* + * Type of filesystem type + */ +#define MTYPE_TYPE int + +/* + * How to get a mount list + */ +#define READ_MTAB_FROM_FILE + +/* + * Make Amd automount points appear + * to be zero sized. undef this + * if the O/S has a divide by zero + * problem in df et al. + */ +#define HAS_EMPTY_AUTOMOUNTS + +/* + * For the RE matcher + */ +#define CHARBITS 0377 +#define STRCSPN +#define RE_HDR "re.h" diff --git a/usr.sbin/amd/config/os-dgux.h b/usr.sbin/amd/config/os-dgux.h new file mode 100644 index 0000000..98c81bf --- /dev/null +++ b/usr.sbin/amd/config/os-dgux.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-dgux.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-dgux.h,v 5.2.2.1 1992/02/09 15:10:18 jsp beta $ + * + * dg/ux definitions for Amd (automounter) + */ + +/* + * Does the compiler grok void * + */ +#define VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_4 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_4 + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS "nfs" +#define MOUNT_TYPE_UFS "dg/ux" +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "dg/ux" + +/* + * Need the following in more places than just NFS_HDR + */ +#include +/* + * This is braindead + * dg/ux has nfs 4.0 but doesn't have the following options + */ +#define NFSMNT_HOSTNAME 0x0 +#define NFSMNT_INT 0x0 +#define M_NEWTYPE 0 + +/* + * DG have their own filesystem. + */ +#define ufs_args dgux_args + +/* + * Byte ordering + */ + +#undef ARCH_ENDIAN +#define ARCH_ENDIAN "big" + +#define _BSD_WAIT_FLAVOR +#define _BSD_TTY_FLAVOR +#define _BSD_SIGNAL_FLAVOR +#define _DGUX_SOURCE + +/* + * Use fcntl() rather than flock() + */ +#define LOCK_FCNTL + +#define bzero(ptr, len) memset(ptr, 0, len) +#define bcopy(from, to, len) memcpy(to, from, len) +#undef MOUNT_TRAP +#define MOUNT_TRAP(type, mnt, flags, mnt_data) \ + ((struct nfs_args *)mnt_data)->version = !strcmp(type, MOUNT_TYPE_UFS)?\ + DG_MOUNT_DGUX_VERSION:DG_MOUNT_NFS_VERSION, \ + dg_mount(type, mnt->mnt_dir, flags, mnt_data) +#undef UNMOUNT_TRAP +#define UNMOUNT_TRAP(mnt) umount(mnt->mnt_dir) diff --git a/usr.sbin/amd/config/os-fpx4.h b/usr.sbin/amd/config/os-fpx4.h new file mode 100644 index 0000000..8c69421 --- /dev/null +++ b/usr.sbin/amd/config/os-fpx4.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-fpx4.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-fpx4.h,v 5.2.2.2 1992/05/31 16:39:34 jsp Exp $ + * + * Celerity FPX 4.1/2 definitions for Amd (automounter) + * from Stephen Pope + */ + +/* + * FPX wants to include sys headers multiple times + */ +#define INCLUDE_HEADERS + +/* + * FPX sys/mount.h includes sys/nfs.h; prevent this + */ +#define INCLUDED_nfs + +/* + * FPX doesn't define NMOUNT anywhere + */ +#define NMOUNT 40 + +/* + * Does the compiler grok void * + */ +/* #define VOIDP */ + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_4 +#define svc_fdset svc_fds +#define svc_getreqset(p) svc_getreq((*p).fds_bits[0]) + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#define ARCH_ENDIAN "big" + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS MOUNT_NFS +#define MOUNT_TYPE_UFS MOUNT_UFS diff --git a/usr.sbin/amd/config/os-hcx.h b/usr.sbin/amd/config/os-hcx.h new file mode 100644 index 0000000..5b3fb30 --- /dev/null +++ b/usr.sbin/amd/config/os-hcx.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-hcx.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-hcx.h,v 5.2.2.1 1992/02/09 15:10:20 jsp beta $ + * + * Harris HCX/UX Release 3.0 definitions for Amd (automounter) + */ + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Deviant call necessary. The mount() routine in libc only works for UFS + * (it's a backward-compatible piece of C code which traps to mountsyscall). + */ +#undef MOUNT_TRAP +#define MOUNT_TRAP(type, mnt, flags, mnt_data) \ + mountsyscall(type, mnt->mnt_dir, flags, mnt_data) + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS MOUNT_NFS +#define MOUNT_TYPE_UFS MOUNT_UFS + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#ifdef _hcx +#define ARCH_ENDIAN "big" +#else +XXX - bizarre! +#endif diff --git a/usr.sbin/amd/config/os-hlh42.h b/usr.sbin/amd/config/os-hlh42.h new file mode 100644 index 0000000..43d2d0b --- /dev/null +++ b/usr.sbin/amd/config/os-hlh42.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-hlh42.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-hlh42.h,v 5.2.2.1 1992/02/09 15:10:22 jsp beta $ + * + * HLH OTS definitions for Amd (automounter) + */ + +/* + * Does the compiler grok void * + */ +#undef VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#if defined(hlh) +#define ARCH_ENDIAN "little" +#endif + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS MOUNT_NFS +#define MOUNT_TYPE_UFS MOUNT_UFS + +/* + * Miscellaneous HLH 4.2 incantations + */ +#define strchr index +#define strrchr rindex +#define sigmask(x) (1 << ((x)-1)) + +/* + * HLH's 4.2 needs the extra RPC definitions. + */ +#define NEED_XDR_POINTER +#define NEED_CLNT_SPERRNO diff --git a/usr.sbin/amd/config/os-hpux.h b/usr.sbin/amd/config/os-hpux.h new file mode 100644 index 0000000..42b6b8b --- /dev/null +++ b/usr.sbin/amd/config/os-hpux.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-hpux.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-hpux.h,v 5.2.2.1 1992/02/09 15:10:23 jsp beta $ + * + * HP/9000 HP-UX definitions for Amd (automounter) + */ + +/* + * Does the compiler grok void * + */ +#ifdef __GNUC__ +#define VOIDP +#endif + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#if defined(hp9000s200) || defined(hp9000s300) || defined(hp9000s800) +#define ARCH_ENDIAN "big" +#endif + +#ifndef __hpux +#define HPUX_VERSION_6 +#endif + +/* + * No support for syslog() prior to 7.0 + */ +#ifdef HPUX_VERSION_6 +#undef HAS_SYSLOG +#endif + +/* + * No support for ndbm + */ +#undef OS_HAS_NDBM + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_UFS MOUNT_UFS +#define MOUNT_TYPE_NFS MOUNT_NFS +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "hfs" + +/* + * Where to get NFS definitions + */ +#define NFS_HDR "misc-hpux.h" + +/* + * Where to get union wait + */ +#undef WAIT +#define WAIT "uwait.h" +#ifdef HPUX_VERSION_6 +#define SIGCHLD SIGCLD +#endif +#define SYS5_SIGNALS + +/* + * Miscellaneous HP-UX definitions + */ + +#define NEED_XDR_POINTER +#define NEED_CLNT_SPERRNO + +/* + * Use rather than + */ +#define USE_FCNTL + +/* + * Use fcntl() rather than flock() + */ +#define LOCK_FCNTL + +/* + * Additional fields in struct mntent + * are fixed up here + */ +#define FIXUP_MNTENT(mntp) { \ + (mntp)->mnt_time = clocktime(); \ +} +#define FIXUP_MNTENT_DUP(mntp, mp) { \ + (mntp)->mnt_time = (mp)->mnt_time; \ +} + +#define bzero(ptr, len) memset(ptr, 0, len) +#define bcopy(from, to, len) memcpy(to, from, len) +#define getpagesize() (2048) +#undef MOUNT_TRAP +#define MOUNT_TRAP(type, mnt, flags, mnt_data) \ + vfsmount(type, mnt->mnt_dir, flags, mnt_data) +#undef UNMOUNT_TRAP +#define UNMOUNT_TRAP(mnt) umount(mnt->mnt_dir) +#define NFDS 30 /* conservative */ +#define MOUNTED MNT_MNTTAB diff --git a/usr.sbin/amd/config/os-irix.h b/usr.sbin/amd/config/os-irix.h new file mode 100644 index 0000000..1d854f7 --- /dev/null +++ b/usr.sbin/amd/config/os-irix.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-irix.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-irix.h,v 5.2.2.1 1992/02/09 15:10:28 jsp beta $ + * + * IRIX 3.3 definitions for Amd (automounter) + * Contributed by Scott R. Presnell + */ + +/* + * Does the compiler grok void * + */ +#define VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#define ARCH_ENDIAN "big" + +/* + * Has support for syslog() + */ +#define HAS_SYSLOG + +#define M_GRPID MS_GRPID +#define M_RDONLY MS_RDONLY +/* + * Support for ndbm + */ +#define OS_HAS_NDBM + +#define UPDATE_MTAB + +#undef MTAB_TYPE_NFS +#define MTAB_TYPE_NFS "nfs" + +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "efs" + +#define NMOUNT 40 /* The std sun value */ +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_UFS sysfs(GETFSIND, FSID_EFS) +#define MOUNT_TYPE_NFS sysfs(GETFSIND, FSID_NFS) + +#define SYS5_SIGNALS + +/* + * Use rather than + */ +/*#define USE_FCNTL*/ + +/* + * Use fcntl() rather than flock() + */ +/*#define LOCK_FCNTL*/ + +#ifdef __GNUC__ +#define alloca(sz) __builtin_alloca(sz) +#endif + +#define bzero(ptr, len) memset(ptr, 0, len) +#define bcopy(from, to, len) memcpy(to, from, len) + +#undef MOUNT_TRAP +#define MOUNT_TRAP(type, mnt, flags, mnt_data) \ + irix_mount(mnt->mnt_fsname, mnt->mnt_dir,flags, type, mnt_data) +#undef UNMOUNT_TRAP +#define UNMOUNT_TRAP(mnt) umount(mnt->mnt_dir) +#define NFDS 30 /* conservative */ + +#define NFS_HDR "misc-irix.h" +#define UFS_HDR "misc-irix.h" + +/* not included in sys/param.h */ +#include + +#define MOUNT_HELPER_SOURCE "mount_irix.c" + +#define MNTINFO_DEV "fsid" +#define MNTINFO_PREF "0x" diff --git a/usr.sbin/amd/config/os-irix3.h b/usr.sbin/amd/config/os-irix3.h new file mode 100644 index 0000000..867097d --- /dev/null +++ b/usr.sbin/amd/config/os-irix3.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-irix3.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-irix3.h,v 5.2 1992/05/31 16:40:22 jsp Exp $ + * + * IRIX 3.3 definitions for Amd (automounter) + * Contributed by Scott R. Presnell + */ + +/* + * Does the compiler grok void * + */ +#define VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#define ARCH_ENDIAN "big" + +/* + * Has support for syslog() + */ +#define HAS_SYSLOG + +#define M_GRPID MS_GRPID +#define M_RDONLY MS_RDONLY +/* + * Support for ndbm + */ +#define OS_HAS_NDBM + +#define UPDATE_MTAB + +#undef MTAB_TYPE_NFS +#define MTAB_TYPE_NFS "nfs" + +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "efs" + +#define NMOUNT 40 /* The std sun value */ +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_UFS sysfs(GETFSIND, FSID_EFS) +#define MOUNT_TYPE_NFS sysfs(GETFSIND, FSID_NFS) + +#define SYS5_SIGNALS + +/* + * Use rather than + */ +/*#define USE_FCNTL*/ + +/* + * Use fcntl() rather than flock() + */ +/*#define LOCK_FCNTL*/ + +#ifdef __GNUC__ +#define alloca(sz) __builtin_alloca(sz) +#endif + +#define bzero(ptr, len) memset(ptr, 0, len) +#define bcopy(from, to, len) memcpy(to, from, len) + +#undef MOUNT_TRAP +#define MOUNT_TRAP(type, mnt, flags, mnt_data) \ + irix_mount(mnt->mnt_fsname, mnt->mnt_dir,flags, type, mnt_data) +#undef UNMOUNT_TRAP +#define UNMOUNT_TRAP(mnt) umount(mnt->mnt_dir) +#define NFDS 30 /* conservative */ + +#define NFS_HDR "misc-irix.h" +#define UFS_HDR "misc-irix.h" + +/* not included in sys/param.h */ +#include + +#define MOUNT_HELPER_SOURCE "mount_irix.c" + +#define MNTINFO_DEV "fsid" +#define MNTINFO_PREF "0x" diff --git a/usr.sbin/amd/config/os-irix4.h b/usr.sbin/amd/config/os-irix4.h new file mode 100644 index 0000000..ee2f8cb --- /dev/null +++ b/usr.sbin/amd/config/os-irix4.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-irix4.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-irix4.h,v 5.2 1992/05/31 16:40:22 jsp Exp $ + * + * IRIX 4.0.X definitions for Amd (automounter) + * Contributed by Scott R. Presnell + */ + +/* + * Does the compiler grok void * + */ +#define VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#define ARCH_ENDIAN "big" + +/* + * Has support for syslog() + */ +#define HAS_SYSLOG + +#define M_RDONLY MS_RDONLY +#define M_GRPID MS_GRPID +#define M_NOSUID MS_NOSUID +#define M_NONDEV MS_NODEV + +/* + * Support for ndbm + */ +#define OS_HAS_NDBM + +#define UPDATE_MTAB + +#undef MTAB_TYPE_NFS +#define MTAB_TYPE_NFS "nfs" + +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "efs" + +#define NMOUNT 40 /* The std sun value */ +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_UFS sysfs(GETFSIND, FSID_EFS) +#define MOUNT_TYPE_NFS sysfs(GETFSIND, FSID_NFS) + +#define SYS5_SIGNALS + +/* + * Use rather than + */ +/*#define USE_FCNTL*/ + +/* + * Use fcntl() rather than flock() + */ +/*#define LOCK_FCNTL*/ + +#ifdef __GNUC__ +#define alloca(sz) __builtin_alloca(sz) +#endif + +#define bzero(ptr, len) memset(ptr, 0, len) +#define bcopy(from, to, len) memcpy(to, from, len) + +#undef MOUNT_TRAP +#define MOUNT_TRAP(type, mnt, flags, mnt_data) \ + irix_mount(mnt->mnt_fsname, mnt->mnt_dir,flags, type, mnt_data) +#undef UNMOUNT_TRAP +#define UNMOUNT_TRAP(mnt) umount(mnt->mnt_dir) +#define NFDS 30 /* conservative */ + +#define NFS_HDR "misc-irix.h" +#define UFS_HDR "misc-irix.h" + +/* not included in sys/param.h */ +#include + +#define MOUNT_HELPER_SOURCE "mount_irix.c" + +/* + * Under 4.0.X this information is in /usr/include/mntent.h + * Below is what is used to be for Irix 3.3.X. + */ +/*#define MNTINFO_DEV "fsid"*/ +/*#define MNTINFO_PREF "0x"*/ + +#define MNTINFO_PREF "" + +/* + * Under Irix, mount type "auto" is probed by statfs() in df. A statfs() of + * a direct mount causes that mount to fire. So change the mount type in + * /etc/mtab to "ignore" to stop that (this is what SGI does for their + * automounter. Use the old FASCIST define for this. + */ +#define FASCIST_DF_COMMAND MNTTYPE_IGNORE diff --git a/usr.sbin/amd/config/os-next.h b/usr.sbin/amd/config/os-next.h new file mode 100644 index 0000000..c9b1cc2 --- /dev/null +++ b/usr.sbin/amd/config/os-next.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-next.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-next.h,v 5.2.2.1 1992/02/09 15:10:33 jsp beta $ + * + * NeXT OS definitions for Amd (automounter) + * By Bill Trost, Reed College + * trost%reed@cse.ogi.edu, + * + * Derived from the Sun 3.2 definitions for Amd (os-sos3.h). + */ + +/* + * Does the compiler grok void * (NeXT uses gcc) + */ +#define VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_UFS MOUNT_UFS +#define MOUNT_TYPE_NFS MOUNT_NFS +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "4.3" + +/* + * Where to get NFS definitions + */ +#define NFS_HDR "misc-next.h" diff --git a/usr.sbin/amd/config/os-pyrOSx.h b/usr.sbin/amd/config/os-pyrOSx.h new file mode 100644 index 0000000..21b5fdd --- /dev/null +++ b/usr.sbin/amd/config/os-pyrOSx.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-pyrOSx.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-pyrOSx.h,v 5.2.2.1 1992/02/09 15:10:37 jsp beta $ + * + * Pyramid OSx definitions for Amd (automounter) + * from Stefan Petri + */ + +/* + * Does the compiler grok void * + */ +#define VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#define ARCH_ENDIAN "big" + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_UFS MOUNT_UFS +#define MOUNT_TYPE_NFS MOUNT_NFS + +#define strchr index +#define strrchr rindex + +#define hostname mnthostname diff --git a/usr.sbin/amd/config/os-riscix.h b/usr.sbin/amd/config/os-riscix.h new file mode 100644 index 0000000..cff7951 --- /dev/null +++ b/usr.sbin/amd/config/os-riscix.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-riscix.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-riscix.h,v 5.2.2.1 1992/02/09 15:10:38 jsp beta $ + * + * Acorn Archimedes RISC iX definitions for Amd (automounter) + * Contributed by Piete Brooks. + */ + +/* + * Does the compiler grok void * + */ +#define VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Does this OS have NDBM support? + */ +#define OS_HAS_NDBM + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#define ARCH_ENDIAN "little" + +/* + * Is the mount table mirrored in software + */ +#define UPDATE_MTAB + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS MOUNT_NFS +#define MOUNT_TYPE_UFS MOUNT_UFS + +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS MNTTYPE_43 diff --git a/usr.sbin/amd/config/os-sos3.h b/usr.sbin/amd/config/os-sos3.h new file mode 100644 index 0000000..15c632c --- /dev/null +++ b/usr.sbin/amd/config/os-sos3.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-sos3.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-sos3.h,v 5.2.2.1 1992/02/09 15:10:39 jsp beta $ + * + * SunOS 3.2 definitions for Amd (automounter) + */ + +/* + * Does the compiler grok void * + */ +#define VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#if defined(mc68010) || defined(mc68020) || defined(sparc) +#define ARCH_ENDIAN "big" +#endif +#if defined(i386) +#define ARCH_ENDIAN "little" +#endif + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_UFS MOUNT_UFS +#define MOUNT_TYPE_NFS MOUNT_NFS diff --git a/usr.sbin/amd/config/os-sos4.h b/usr.sbin/amd/config/os-sos4.h new file mode 100644 index 0000000..3853a6c --- /dev/null +++ b/usr.sbin/amd/config/os-sos4.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-sos4.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-sos4.h,v 5.2.2.1 1992/02/09 15:10:41 jsp beta $ + * + * SunOS 4.0 definitions for Amd (automounter) + */ + +/* + * Does the compiler grok void * + */ +#define VOIDP + +/* + * What type is free(void*) returning? + */ +#undef FREE_RETURN_TYPE +#define FREE_RETURN_TYPE int + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_4 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_4 + +/* + * Does this OS have NDBM support? + */ +#define OS_HAS_NDBM + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#if defined(mc68010) || defined(mc68020) || defined(sparc) +#define ARCH_ENDIAN "big" +#endif +#if defined(i386) +#define ARCH_ENDIAN "little" +#endif + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS "nfs" +#define MOUNT_TYPE_UFS "4.2" + +/* + * Type of a file handle + */ +#undef NFS_FH_TYPE +#define NFS_FH_TYPE caddr_t + +/* + * Type of filesystem type + */ +#undef MTYPE_TYPE +#define MTYPE_TYPE char * + +/* + * Add support for SunOS 4 automounter files + */ +#define SUNOS4_COMPAT + +/* + * System Vr4 / SunOS 4.1 compatibility + * - put dev= in the options list + * + * From: Brent Callaghan + */ +#define MNTINFO_DEV "dev" +#define MNTINFO_PREF "" diff --git a/usr.sbin/amd/config/os-stellix.h b/usr.sbin/amd/config/os-stellix.h new file mode 100644 index 0000000..8c6290a --- /dev/null +++ b/usr.sbin/amd/config/os-stellix.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-stellix.h 8.1 (Berkeley) 6/6/93 + * + * Amd (automounter) definitions for Stellix. + * From Stephen C. Pope + * + * $Id: os-stellix.h,v 5.2.2.1 1992/02/09 15:10:43 jsp beta $ + */ + +#define RPC_3 + +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#define ARCH_ENDIAN "big" + +#define HAS_SYSLOG + +#define OS_HAS_NDBM + +#define UPDATE_MTAB + +#define USE_FCNTL + +#define LOCK_FCNTL + +/* + * Name of filesystem types + */ +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "sfs" + +#define MOUNT_TYPE_UFS sysfs(GETFSIND, "SFS1") +#define MOUNT_TYPE_NFS sysfs(GETFSIND, "NFS") + +#define SYS5_SIGNALS +#define HAS_SVR3_SIGNALS + +#define MOUNT_HELPER_SOURCE "mount_stellix.c" + +/* + * Name of mount & unmount system calls + * + * NOTE: + * UNMOUNT_TRAP takes a struct mntent * + */ +#undef MOUNT_TRAP +#define MOUNT_TRAP(type, mnt, flags, mnt_data) \ + stellix_mount(mnt->mnt_fsname, mnt->mnt_dir, flags, type, mnt_data) +#undef UNMOUNT_TRAP +#define UNMOUNT_TRAP(mnt) umount(mnt->mnt_dir) + +/* + * How to unmount filesystems. + * NEED_UMOUNT_FS includes code to scan the mount table + * to find the correct information for the unmount system + * call. Some systems, such as 4.4bsd, do not require + * this - they can just do an unmount system call directly. + */ +/* #define NEED_UMOUNT_FS */ +/* #define UMOUNT_FS(dir) umount_fs(dir) */ + +#define NFS_HDR "misc-stellix.h" +#define UFS_HDR "misc-stellix.h" + +#define M_RDONLY 0x01 /* mount fs read only */ + +#define bzero(ptr, len) memset(ptr, 0, len) +#define bcopy(from, to, len) memcpy(to, from, len) diff --git a/usr.sbin/amd/config/os-type b/usr.sbin/amd/config/os-type new file mode 100644 index 0000000..4871d79 --- /dev/null +++ b/usr.sbin/amd/config/os-type @@ -0,0 +1,128 @@ +#!/bin/sh +# +# Copyright (c) 1989 Jan-Simon Pendry +# Copyright (c) 1989 Imperial College of Science, Technology & Medicine +# Copyright (c) 1989, 1993 +# The Regents of the University of California. All rights reserved. +# +# This code is derived from software contributed to Berkeley by +# Jan-Simon Pendry at Imperial College, London. +# +# 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. +# +# @(#)os-type 8.1 (Berkeley) 6/6/93 +# +# $Id: os-type,v 5.2.2.2 1992/05/31 16:45:46 jsp Exp $ +# + +# +# Take a pot-shot at your os type +# +echo "# ... No OS= option specified; dynamically determining OS type" >&2 + +# +# First try poking around in /etc/motd +# + +case "`exec 2>/dev/null; head -2 /etc/motd`" in +*"Sun UNIX 4.2 Release 3."*) OS=sos3;; +*"SunOS Release 4."*) OS=sos4;; +*"HP-UX on the HP"*) OS=hpux;; +*"Ultrix V2."*) OS=u2_2;; +*"Ultrix V3."*) OS=u3_0;; +*"Ultrix-32 V3."*) OS=u3_0;; +*"Ultrix Worksystem V2."*) OS=u3_0;; +*"ULTRIX V4.2"*) OS=u4_2;; +*"ULTRIX V4."*) OS=u4_0;; +*"HLH OTS Version 1."*) OS=hlh42;; +*"RISC iX release 1."*) OS=riscix;; +*"FPX 4."*) OS=fpx4;; +*"HCX/UX"*) OS=hcx;; +*"4.4 BSD UNIX"*) OS=bsd44;; +*"4.3 BSD Reno UNIX"*) OS=bsd44;; +*"4.3 BSD UNIX"*) if [ -f /etc/minidisk ]; then + OS=acis43 + elif [ -f /sbin/nfsiod ]; then + OS=bsd44 # prototype + else + OS=xinu43 + fi;; +*"Alliant Concentrix"*) OS=concentrix;; +*"Umax 4.3"*) OS=umax43;; +*) +# +# Well, that didn't work so apply some heuristics +# to the filesystem name space... +# + echo "# ... inspecting File system ..." >&2 + if [ -f /etc/comply ]; then + OS=utek + elif [ -d /usr/lib/methods -o -d /etc/methods ]; then + OS=aix3 + elif [ -f /usr/bin/cat ]; then + OS=sos4 + elif [ -f /etc/nd ]; then + OS=sos3 + elif [ -f /etc/elcsd ]; then + echo "# ... Ultrix - assuming U4.0 ..." >&2 + OS=u4_0 + elif [ -f /hp-ux ]; then + OS=hpux + elif [ -f /etc/ttylocal ]; then + OS=xinu43 + elif [ -f /etc/minidisk ]; then + OS=acis43 + elif [ -f /etc/toolboxdaemon ]; then + OS=aux + elif [ -f /sbin/nfsiod ]; then + OS=bsd44 + elif [ -d /vrm ]; then + OS=aix2 + elif [ -f /bin/pyr ] && /bin/pyr; then + OS=pyrOSx + elif [ -d /NextApps ]; then + OS=next + elif [ -f /etc/gl/ucode ]; then + OS=irix3 + elif [ -f /usr/gfx/ucode ]; then + OS=irix4 + elif [ -f /stellix ]; then + OS=stellix + else + case "`(sh ../config/arch)2>/dev/null`" in + ibm032) OS=acis43;; + aviion) OS=dgux;; + *) OS=unknown;; + esac + fi;; +esac + +echo "# ... OS appears to be \"${OS}\"" >&2 +echo "${OS}" +exit 0 diff --git a/usr.sbin/amd/config/os-u2_2.h b/usr.sbin/amd/config/os-u2_2.h new file mode 100644 index 0000000..aece171 --- /dev/null +++ b/usr.sbin/amd/config/os-u2_2.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-u2_2.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-u2_2.h,v 5.2.2.1 1992/02/09 15:10:48 jsp beta $ + * + * Ultrix 2.2 definitions for Amd (automounter) + */ + +/* + * Does the compiler grok void * + */ +#undef VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#if defined(vax) +#define ARCH_ENDIAN "little" +#endif + +/* + * The mount table is obtained from the kernel + */ +#undef UPDATE_MTAB + +/* + * No mntent info on Ultrix + */ +#undef MNTENT_HDR + +/* + * No support for syslog() + */ +#undef HAS_SYSLOG + +/* + * No support for ndbm + */ +#undef HAS_NDBM_MAPS + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS GT_NFS +#define MOUNT_TYPE_UFS GT_ULTRIX +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "ufs" + +/* + * Name of mount & unmount system calls + */ +#undef MOUNT_TRAP +#define MOUNT_TRAP(type, mnt, flag, mnt_data) \ + mount(mnt->mnt_fsname, mnt->mnt_dir, flag, type, mnt_data) +#undef UNMOUNT_TRAP +#define UNMOUNT_TRAP(mnt) umount(mnt->mnt_passno) + +/* + * Miscellaneous Ultrix bits + */ +#define M_RDONLY M_RONLY + +#ifndef MNTMAXSTR +#define MNTMAXSTR 128 +#endif + +#define MNTTYPE_UFS "ufs" /* Un*x file system */ +#define MNTTYPE_NFS "nfs" /* network file system */ +#define MNTTYPE_IGNORE "ignore" /* No type specified, ignore this entry */ + +#define MNTOPT_RO "ro" /* read only */ +#define MNTOPT_RW "rw" /* read/write */ +#define MNTOPT_QUOTA "quota" /* quotas */ +#define MNTOPT_NOQUOTA "noquota" /* no quotas */ +#define MNTOPT_HARD "hard" /* hard mount */ +#define MNTOPT_SOFT "soft" /* soft mount */ +#define MNTOPT_INTR "intr" /* interrupts allowed */ + +#define MNTOPT_NOSUID "nosuid" /* no set uid allowed */ + +struct mntent { + char *mnt_fsname; /* name of mounted file system */ + char *mnt_dir; /* file system path prefix */ + char *mnt_type; /* MNTTYPE_* */ + char *mnt_opts; /* MNTOPT* */ + int mnt_freq; /* dump frequency, in days */ + int mnt_passno; /* pass number on parallel fsck */ +}; +#define MOUNTED "/etc/mtab" + +#define NFS_HDR "misc-ultrix.h" +#define UFS_HDR "misc-ultrix.h" + +#define NEED_XDR_POINTER +#define NEED_CLNT_SPERRNO + +#define nfs_args nfs_gfs_mount +#define ULTRIX_HACK /* Should be handled better than this !! */ +#define NEED_MNTOPT_PARSER + +/* + * How to get a mount list + */ +#undef READ_MTAB_FROM_FILE +#define READ_MTAB_ULTRIX_STYLE + +/* + * Need precise length links + */ +#define PRECISE_SYMLINKS diff --git a/usr.sbin/amd/config/os-u3_0.h b/usr.sbin/amd/config/os-u3_0.h new file mode 100644 index 0000000..08a4f36 --- /dev/null +++ b/usr.sbin/amd/config/os-u3_0.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-u3_0.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-u3_0.h,v 5.2.2.1 1992/02/09 15:10:52 jsp beta $ + * + * Ultrix 3.0 definitions for Amd (automounter) + */ + +/* + * Does the compiler grok void * + */ +#undef VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#if defined(vax) || defined(mips) +#define ARCH_ENDIAN "little" +#endif + +/* + * The mount table is obtained from the kernel + */ +#undef UPDATE_MTAB + +/* + * No mntent info on Ultrix + */ +#undef MNTENT_HDR + +/* + * No support for syslog() + */ +#undef HAS_SYSLOG + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS GT_NFS +#define MOUNT_TYPE_UFS GT_ULTRIX +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "ufs" + +/* + * Name of mount & unmount system calls + */ +#undef MOUNT_TRAP +#define MOUNT_TRAP(type, mnt, flag, mnt_data) \ + mount(mnt->mnt_fsname, mnt->mnt_dir, flag, type, mnt_data) +#undef UNMOUNT_TRAP +#define UNMOUNT_TRAP(mnt) umount(mnt->mnt_passno) + +/* + * Miscellaneous Ultrix bits + */ +#define M_RDONLY M_RONLY + +#define MNTMAXSTR 128 + +#define MNTTYPE_UFS "ufs" /* Un*x file system */ +#define MNTTYPE_NFS "nfs" /* network file system */ +#define MNTTYPE_IGNORE "ignore" /* No type specified, ignore this entry */ + +#define MNTOPT_RO "ro" /* read only */ +#define MNTOPT_RW "rw" /* read/write */ +#define MNTOPT_QUOTA "quota" /* quotas */ +#define MNTOPT_NOQUOTA "noquota" /* no quotas */ +#define MNTOPT_HARD "hard" /* hard mount */ +#define MNTOPT_SOFT "soft" /* soft mount */ +#define MNTOPT_INTR "intr" /* interrupts allowed */ + +#define MNTOPT_NOSUID "nosuid" /* no set uid allowed */ + +struct mntent { + char *mnt_fsname; /* name of mounted file system */ + char *mnt_dir; /* file system path prefix */ + char *mnt_type; /* MNTTYPE_* */ + char *mnt_opts; /* MNTOPT* */ + int mnt_freq; /* dump frequency, in days */ + int mnt_passno; /* pass number on parallel fsck */ +}; +#define MOUNTED "/etc/mtab" + +#define NFS_HDR "misc-ultrix.h" +#define UFS_HDR "misc-ultrix.h" + +#define NEED_XDR_POINTER +#define NEED_CLNT_SPERRNO + +#define nfs_args nfs_gfs_mount +#define ULTRIX_HACK /* Should be handled better than this !! */ +#define NEED_MNTOPT_PARSER + +/* + * How to get a mount list + */ +#undef READ_MTAB_FROM_FILE +#define READ_MTAB_ULTRIX_STYLE + +/* + * Need precise length links + */ +#define PRECISE_SYMLINKS diff --git a/usr.sbin/amd/config/os-u4_0.h b/usr.sbin/amd/config/os-u4_0.h new file mode 100644 index 0000000..07c9833 --- /dev/null +++ b/usr.sbin/amd/config/os-u4_0.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-u4_0.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-u4_0.h,v 5.2.2.1 1992/02/09 15:10:53 jsp beta $ + * + * Ultrix 4.0 definitions for Amd (automounter) + * from Chris Lindblad + */ + +/* + * Does the compiler grok void * + */ +#ifdef __STDC__ +#define VOIDP +#else +#undef VOIDP +#endif + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#if defined(vax) || defined(mips) +#define ARCH_ENDIAN "little" +#endif + +/* + * The mount table is obtained from the kernel + */ +#undef UPDATE_MTAB + +/* + * No mntent info on Ultrix + */ +#undef MNTENT_HDR + +/* + * No support for syslog() + */ +#define HAS_SYSLOG + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS GT_NFS +#define MOUNT_TYPE_UFS GT_ULTRIX +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "ufs" + +/* + * Name of mount & unmount system calls + */ +#undef MOUNT_TRAP +#define MOUNT_TRAP(type, mnt, flag, mnt_data) \ + mount(mnt->mnt_fsname, mnt->mnt_dir, flag, type, mnt_data) +#undef UNMOUNT_TRAP +#define UNMOUNT_TRAP(mnt) umount(mnt->mnt_passno) + +/* + * Miscellaneous Ultrix bits + */ +#define M_RDONLY M_RONLY + +#define MNTMAXSTR 128 + +#define MNTTYPE_UFS "ufs" /* Un*x file system */ +#define MNTTYPE_NFS "nfs" /* network file system */ +#define MNTTYPE_IGNORE "ignore" /* No type specified, ignore this entry */ + +#define MNTOPT_RO "ro" /* read only */ +#define MNTOPT_RW "rw" /* read/write */ +#define MNTOPT_QUOTA "quota" /* quotas */ +#define MNTOPT_NOQUOTA "noquota" /* no quotas */ +#define MNTOPT_HARD "hard" /* hard mount */ +#define MNTOPT_SOFT "soft" /* soft mount */ +#define MNTOPT_INTR "intr" /* interrupts allowed */ + +#define MNTOPT_NOSUID "nosuid" /* no set uid allowed */ + +struct mntent { + char *mnt_fsname; /* name of mounted file system */ + char *mnt_dir; /* file system path prefix */ + char *mnt_type; /* MNTTYPE_* */ + char *mnt_opts; /* MNTOPT* */ + int mnt_freq; /* dump frequency, in days */ + int mnt_passno; /* pass number on parallel fsck */ +}; +#define MOUNTED "/etc/mtab" + +#define NFS_HDR "misc-ultrix.h" +#define UFS_HDR "misc-ultrix.h" + +#define NEED_CLNT_SPERRNO + +#define nfs_args nfs_gfs_mount +#define ULTRIX_HACK /* Should be handled better than this !! */ +#define NEED_MNTOPT_PARSER + +/* + * How to get a mount list + */ +#undef READ_MTAB_FROM_FILE +#define READ_MTAB_ULTRIX_STYLE + +/* + * Need precise length links + */ +#define PRECISE_SYMLINKS diff --git a/usr.sbin/amd/config/os-u4_2.h b/usr.sbin/amd/config/os-u4_2.h new file mode 100644 index 0000000..f8f039c --- /dev/null +++ b/usr.sbin/amd/config/os-u4_2.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-u4_2.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-u4_2.h,v 5.2.2.1 1992/02/09 15:10:54 jsp beta $ + * + * Ultrix 4.2 definitions for Amd (automounter) + * from Chris Lindblad + * and Chris Metcalf + */ + +/* + * Does the compiler grok void * + */ +#define VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_4 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#if defined(vax) || defined(mips) +#define ARCH_ENDIAN "little" +#endif + +/* + * The mount table is obtained from the kernel + */ +#undef UPDATE_MTAB + +/* + * No mntent info on Ultrix + */ +#undef MNTENT_HDR + +/* + * No support for syslog() + */ +#define HAS_SYSLOG + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS GT_NFS +#define MOUNT_TYPE_UFS GT_ULTRIX +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "ufs" + +/* + * Name of mount & unmount system calls + */ +#undef MOUNT_TRAP +#define MOUNT_TRAP(type, mnt, flag, mnt_data) \ + mount(mnt->mnt_fsname, mnt->mnt_dir, flag, type, mnt_data) +#undef UNMOUNT_TRAP +#define UNMOUNT_TRAP(mnt) umount(mnt->mnt_passno) + +/* + * Miscellaneous Ultrix bits + */ +#define M_RDONLY M_RONLY + +#define MNTMAXSTR 128 + +#define MNTTYPE_UFS "ufs" /* Un*x file system */ +#define MNTTYPE_NFS "nfs" /* network file system */ +#define MNTTYPE_IGNORE "ignore" /* No type specified, ignore this entry */ + +#define MNTOPT_RO "ro" /* read only */ +#define MNTOPT_RW "rw" /* read/write */ +#define MNTOPT_QUOTA "quota" /* quotas */ +#define MNTOPT_NOQUOTA "noquota" /* no quotas */ +#define MNTOPT_HARD "hard" /* hard mount */ +#define MNTOPT_SOFT "soft" /* soft mount */ +#define MNTOPT_INTR "intr" /* interrupts allowed */ + +#define MNTOPT_NOSUID "nosuid" /* no set uid allowed */ + +struct mntent { + char *mnt_fsname; /* name of mounted file system */ + char *mnt_dir; /* file system path prefix */ + char *mnt_type; /* MNTTYPE_* */ + char *mnt_opts; /* MNTOPT* */ + int mnt_freq; /* dump frequency, in days */ + int mnt_passno; /* pass number on parallel fsck */ +}; +#define MOUNTED "/etc/mtab" + +#define NFS_HDR "misc-ultrix.h" +#define UFS_HDR "misc-ultrix.h" + +#define nfs_args nfs_gfs_mount +#define ULTRIX_HACK /* Should be handled better than this !! */ +#define NEED_MNTOPT_PARSER + +/* + * How to get a mount list + */ +#undef READ_MTAB_FROM_FILE +#define READ_MTAB_ULTRIX_STYLE + +/* + * Need precise length links + */ +#define PRECISE_SYMLINKS diff --git a/usr.sbin/amd/config/os-umax43.h b/usr.sbin/amd/config/os-umax43.h new file mode 100644 index 0000000..3e80872 --- /dev/null +++ b/usr.sbin/amd/config/os-umax43.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-umax43.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-umax43.h,v 5.2.2.1 1992/02/09 15:10:55 jsp beta $ + * + * UMAX 4.3 definitions for Amd (automounter) + */ + +/* + * Does the compiler grok void * + */ +#define VOIDP + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_4 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Does this OS have NDBM support? + */ +#define OS_HAS_NDBM + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#define ARCH_ENDIAN "little" + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS MOUNT_NFS +#define MOUNT_TYPE_UFS MOUNT_UFS diff --git a/usr.sbin/amd/config/os-utek.h b/usr.sbin/amd/config/os-utek.h new file mode 100644 index 0000000..eb1be04 --- /dev/null +++ b/usr.sbin/amd/config/os-utek.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-utek.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-utek.h,v 5.2.2.1 1992/02/09 15:10:56 jsp beta $ + * + * Utek 4.0 definitions for Amd (automounter) + * from Bill Trost + */ + +#define UTEK +#define __NFS_HEADER__ /* prevent re-inclusion of */ +/* ... and fake the rest */ +#include "os-sos3.h" diff --git a/usr.sbin/amd/config/os-utx32.h b/usr.sbin/amd/config/os-utx32.h new file mode 100644 index 0000000..29612c4 --- /dev/null +++ b/usr.sbin/amd/config/os-utx32.h @@ -0,0 +1,85 @@ +/* $Id: os-utx32.h,v 5.2.1.1 90/10/21 22:31:11 jsp Exp $ */ + +/* + * Gould UTX/32 definitions for Amd (automounter) + * + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-utx32.h 8.1 (Berkeley) 6/6/93 + */ + +/* + * Does the compiler grok void * + */ +#ifdef __GNUC__ +#define VOIDP +#endif + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_3 + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_3 + +/* + * Does this OS have NDBM support? + */ +#define OS_HAS_NDBM + +/* + * Byte ordering + */ +#undef ARCH_ENDIAN +#if defined(gould) || defined(GOULD_PN) +#define ARCH_ENDIAN "big" +#endif + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS MOUNT_NFS +#define MOUNT_TYPE_UFS MOUNT_UFS +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "4.3" diff --git a/usr.sbin/amd/config/os-xinu43.h b/usr.sbin/amd/config/os-xinu43.h new file mode 100644 index 0000000..e85cea2 --- /dev/null +++ b/usr.sbin/amd/config/os-xinu43.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)os-xinu43.h 8.1 (Berkeley) 6/6/93 + * + * $Id: os-xinu43.h,v 5.2.2.1 1992/02/09 15:10:58 jsp beta $ + * + * mt Xinu 4.3 (MORE/bsd) definitions for Amd (automounter) + * Should work on both Vax and HP ... + */ + +/* + * Does the compiler grok void * + */ +#ifdef __GNUC__ +#define VOIDP +#endif + +/* + * Which version of the Sun RPC library we are using + * This is the implementation release number, not + * the protocol revision number. + */ +#define RPC_4 + +/* + * mt Xinu have a compatibility problem + * with getreq vs. getreqset. On SunOS + * getreqset takes a pointer to an fd_set, + * whereas on MORE/bsd, getreq takes a + * fd_set directly (cf. an integer on SunOS). + */ +#define svc_getreqset(p) svc_getreq(*p) + +/* + * Which version of the NFS interface are we using. + * This is the implementation release number, not + * the protocol revision number. + */ +#define NFS_4 + +/* + * Name of filesystem types + */ +#define MOUNT_TYPE_NFS "nfs" +#define MOUNT_TYPE_UFS "ufs" +#undef MTAB_TYPE_UFS +#define MTAB_TYPE_UFS "ufs" + +/* + * Byte ordering + */ +#ifndef BYTE_ORDER +#include +#endif /* BYTE_ORDER */ + +#undef ARCH_ENDIAN +#if BYTE_ORDER == LITTLE_ENDIAN +#define ARCH_ENDIAN "little" +#else +#if BYTE_ORDER == BIG_ENDIAN +#define ARCH_ENDIAN "big" +#else +XXX - Probably no hope of running Amd on this machine! +#endif /* BIG */ +#endif /* LITTLE */ + +/* + * Type of a file handle + */ +#undef NFS_FH_TYPE +#define NFS_FH_TYPE caddr_t + +/* + * Type of filesystem type + */ +#undef MTYPE_TYPE +#define MTYPE_TYPE char * diff --git a/usr.sbin/amd/doc/Makefile b/usr.sbin/amd/doc/Makefile new file mode 100644 index 0000000..297de2b --- /dev/null +++ b/usr.sbin/amd/doc/Makefile @@ -0,0 +1,53 @@ +# +# $Id: Makefile,v 5.2 90/06/23 22:21:25 jsp Rel $ +# +# Copyright (c) 1990 Jan-Simon Pendry +# Copyright (c) 1990 Imperial College of Science, Technology & Medicine +# Copyright (c) 1990 The Regents of the University of California. +# All rights reserved. +# +# This code is derived from software contributed to Berkeley by +# Jan-Simon Pendry at Imperial College, London. +# +# 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. +# +# @(#)Makefile 8.1 (Berkeley) 6/6/93 +# + +PROG = amdref +SRCS = amdref.texinfo + +${PROG}: amdref.dvi + +amdref.dvi: ${SRCS} + -tex amdref; tex amdref + +clean: + -rm -f amdref.aux amdref.cp amdref.dvi amdref.fn amdref.ky \ + amdref.log amdref.pg amdref.toc amdref.tp amdref.vr diff --git a/usr.sbin/amd/doc/amdref.cps b/usr.sbin/amd/doc/amdref.cps new file mode 100644 index 0000000..a146372 --- /dev/null +++ b/usr.sbin/amd/doc/amdref.cps @@ -0,0 +1,381 @@ +\initial {/} +\entry {/etc/amd.start}{40} +\entry {/etc/passwd maps}{15} +\entry {/etc/rc.local additions}{40} +\entry {/vol}{70} +\initial {A} +\entry {Additions to /etc/rc.local}{40} +\entry {Aliased hostnames}{27} +\entry {Alternate locations}{7} +\entry {Amd command line options}{25} +\entry {Amq command}{40} +\entry {arch, FSinfo host attribute}{50} +\entry {arch, mount selector}{20} +\entry {Architecture dependent volumes}{68} +\entry {Architecture sharing}{68} +\entry {Architecture specific mounts}{69} +\entry {Atomic NFS mounts}{33} +\entry {auto, filesystem type}{36} +\entry {autodir, mount selector}{20} +\entry {Automatic generation of user maps}{15} +\entry {Automount directory}{25} +\entry {Automount filesystem}{36} +\entry {Automounter configuration maps}{12} +\entry {Automounter fundamentals}{5} +\initial {B} +\entry {Background mounts}{7} +\entry {Binding names to filesystems}{6} +\entry {bootparams, FSinfo prefix}{59} +\entry {Bug reports}{3} +\entry {byte, mount selector}{20} +\initial {C} +\entry {Cache interval}{26} +\entry {cache, mount option}{36} +\entry {Catch-all mount point}{70} +\entry {Changing the interval before a filesystem times out}{26} +\entry {Cluster names}{30} +\entry {cluster, FSinfo host attribute}{50} +\entry {cluster, mount selector}{20} +\entry {Command line options, Amd}{25} +\entry {Command line options, FSinfo}{58} +\entry {config, FSinfo host attribute}{49} +\entry {Configuration map types}{12} +\entry {Controlling Amd}{41} +\entry {Creating a pid file}{27} +\initial {D} +\entry {Debug options}{30} +\entry {Defining a host, FSinfo}{48} +\entry {Defining an Amd mount map, FSinfo}{56} +\entry {Defining host attributes, FSinfo}{48} +\entry {delay, mount option}{21} +\entry {Delaying mounts from specific locations}{21} +\entry {Determining the map type}{12} +\entry {dev, mount option}{34} +\entry {Direct automount filesystem}{37} +\entry {direct, filesystem type}{37} +\entry {Discovering version information}{28} +\entry {Discovering what is going on at run-time}{41} +\entry {Disk filesystems}{34} +\entry {Displaying the process id}{27} +\entry {Domain name}{26} +\entry {Domain stripping}{18} +\entry {domain, mount selector}{20} +\entry {Domainname operators}{18} +\entry {dumpset, FSinfo filesystems option}{55} +\entry {dumpset, FSinfo prefix}{59} +\entry {Duplicated volumes}{6} +\initial {E} +\entry {Environment variables}{18} +\entry {Error filesystem}{38} +\entry {error, filesystem type}{38} +\entry {Example of architecture specific mounts}{69} +\entry {Example of mounting home directories}{66} +\entry {export, FSinfo special fstype}{52} +\entry {exportfs, FSinfo mount option}{54} +\entry {exports, FSinfo prefix}{59} +\initial {F} +\entry {File map syntactic conventions}{12} +\entry {File maps}{12} +\entry {Fileserver}{5} +\entry {Filesystem}{5} +\entry {Filesystem info package}{46} +\entry {Filesystem type; auto}{36} +\entry {Filesystem type; direct}{37} +\entry {Filesystem type; error}{38} +\entry {Filesystem type; host}{32} +\entry {Filesystem type; inherit}{39} +\entry {Filesystem type; link}{35} +\entry {Filesystem type; nfs}{31} +\entry {Filesystem type; nfsx}{33} +\entry {Filesystem type; program}{34} +\entry {Filesystem type; root}{39} +\entry {Filesystem type; toplvl}{38} +\entry {Filesystem type; ufs}{34} +\entry {Filesystem type; union}{38} +\entry {Filesystem types}{31} +\entry {Flat file maps}{12} +\entry {Flushing the map cache}{43} +\entry {Forcing filesystem to time out}{45} +\entry {freq, FSinfo filesystems option}{53} +\entry {fs, mount option}{21} +\entry {FSinfo}{46} +\entry {FSinfo arch host attribute}{50} +\entry {FSinfo automount definitions}{56} +\entry {FSinfo cluster host attribute}{50} +\entry {FSinfo command line options}{58} +\entry {FSinfo config host attribute}{49} +\entry {FSinfo dumpset filesystems option}{55} +\entry {FSinfo error messages}{61} +\entry {FSinfo filesystems}{51} +\entry {FSinfo freq filesystems option}{53} +\entry {FSinfo fstype filesystems option}{52} +\entry {FSinfo grammar}{47} +\entry {FSinfo host attributes}{48} +\entry {FSinfo host definitions}{48} +\entry {FSinfo log filesystems option}{55} +\entry {FSinfo mount filesystems option}{54} +\entry {FSinfo opts filesystems option}{53} +\entry {FSinfo os host attribute}{50} +\entry {FSinfo overview}{46} +\entry {FSinfo passno filesystems option}{53} +\entry {FSinfo static mounts}{55} +\entry {fstab, FSinfo prefix}{60} +\entry {fstype, FSinfo filesystems option}{52} +\initial {G} +\entry {Generic volume name}{70} +\entry {Global statistics}{44} +\entry {Grammar, FSinfo}{47} +\initial {H} +\entry {Hesiod maps}{15} +\entry {Home directories}{66} +\entry {host, filesystem type}{32} +\entry {host, mount selector}{20} +\entry {hostd, mount selector}{20} +\entry {Hostname normalisation}{27} +\entry {hostname, FSinfo command line option}{60} +\entry {How keys are looked up}{16} +\entry {How locations are parsed}{17} +\entry {How to access environment variables in maps}{18} +\entry {How to discover your version of Amd}{28} +\entry {How to mount a local disk}{34} +\entry {How to mount a UFS filesystems}{34} +\entry {How to mount all NFS exported filesystems}{32} +\entry {How to mount an atomic group of NFS filesystems}{33} +\entry {How to mount and NFS filesystem}{31} +\entry {How to reference part of the local name space}{35} +\entry {How to select log messages}{29} +\entry {How to set default map parameters}{18} +\entry {How to set map cache parameters}{36} +\entry {How to start a direct automount point}{37} +\entry {How to start an indirect automount point}{36} +\entry {How variables are expanded}{18} +\initial {I} +\entry {inherit, filesystem type}{39} +\entry {Inheritance filesystem}{39} +\entry {Interval before a filesystem times out}{26} +\entry {Introduction}{4} +\initial {K} +\entry {karch, mount selector}{20} +\entry {Keep-alives}{8} +\entry {Key lookup}{16} +\entry {key, mount selector}{20} +\initial {L} +\entry {License Information}{2} +\entry {link, filesystem type}{35} +\entry {Listing currently mounted filesystems}{41} +\entry {Location format}{17} +\entry {Location lists}{7} +\entry {Log filename}{27} +\entry {Log message selection}{29} +\entry {log, FSinfo filesystems option}{55} +\entry {Looking up keys}{16} +\initial {M} +\entry {Machine architecture names}{11} +\entry {Machine architectures supported by Amd}{11} +\entry {Mailing list}{3} +\entry {Map cache options}{36} +\entry {Map cache synchronising}{36} +\entry {Map cache types}{36} +\entry {Map cache, flushing}{43} +\entry {Map defaults}{18} +\entry {Map entry format}{17} +\entry {Map lookup}{16} +\entry {Map options}{21} +\entry {Map types}{12} +\entry {map, mount selector}{20} +\entry {maps, FSinfo command line option}{60} +\entry {Mount a filesystem under program control}{34} +\entry {Mount home directories}{66} +\entry {Mount information}{12} +\entry {Mount map types}{12} +\entry {Mount maps}{12} +\entry {Mount option; cache}{36} +\entry {Mount option; delay}{21} +\entry {Mount option; dev}{34} +\entry {Mount option; fs}{21} +\entry {Mount option; mount}{34} +\entry {Mount option; opts}{22} +\entry {Mount option; rfs}{31} +\entry {Mount option; rhost}{31} +\entry {Mount option; sublink}{23} +\entry {Mount option; type}{24} +\entry {Mount option; unmount}{34} +\entry {Mount retries}{7} +\entry {Mount selector; arch}{20} +\entry {Mount selector; autodir}{20} +\entry {Mount selector; byte}{20} +\entry {Mount selector; cluster}{20} +\entry {Mount selector; domain}{20} +\entry {Mount selector; host}{20} +\entry {Mount selector; hostd}{20} +\entry {Mount selector; karch}{20} +\entry {Mount selector; key}{20} +\entry {Mount selector; map}{20} +\entry {Mount selector; os}{20} +\entry {Mount selector; path}{20} +\entry {Mount selector; wire}{21} +\entry {mount system call}{22} +\entry {mount system call flags}{22} +\entry {Mount types}{31} +\entry {mount, FSinfo filesystems option}{54} +\entry {mount, mount option}{34} +\entry {Mounting a local disk}{34} +\entry {Mounting a UFS filesystem}{34} +\entry {Mounting a volume}{7} +\entry {Mounting an atomic group of NFS filesystems}{33} +\entry {Mounting an NFS filesystem}{31} +\entry {Mounting entire export trees}{32} +\entry {Mounting part of the local name space}{35} +\entry {Mounting user filesystems}{65} +\entry {Multiple-threaded server}{9} +\initial {N} +\entry {Namespace}{6} +\entry {ndbm maps}{13} +\entry {Network filesystem group}{33} +\entry {Network host filesystem}{32} +\entry {Network-wide naming}{6} +\entry {NFS}{31} +\entry {NFS ping}{8} +\entry {nfs, filesystem type}{31} +\entry {nfsx, filesystem type}{33} +\entry {NIS (YP) domain name}{30} +\entry {NIS (YP) maps}{14} +\entry {Nodes generated on a restart}{39} +\entry {Non-blocking operation}{9} +\entry {Normalising hostnames}{27} +\initial {O} +\entry {Obtaining the source code}{3} +\entry {Operating system names}{10} +\entry {Operating systems supported by Amd}{10} +\entry {Operational principles}{7} +\entry {opts, FSinfo filesystems option}{53} +\entry {opts, mount option}{22} +\entry {os, FSinfo host attribute}{50} +\entry {os, mount selector}{20} +\entry {Overriding defaults on the command line}{25} +\entry {Overriding the default mount point}{21} +\entry {Overriding the local domain name}{26} +\entry {Overriding the NIS (YP) domain name}{30} +\initial {P} +\entry {Passing parameters to the mount system call}{22} +\entry {passno, FSinfo filesystems option}{53} +\entry {Password file maps}{15} +\entry {path, mount selector}{20} +\entry {Pathname operators}{18} +\entry {Picking up existing mounts}{28} +\entry {pid file, creating with -p option}{27} +\entry {Primary server}{21} +\entry {Process id}{27} +\entry {process id of Amd daemon}{27} +\entry {Program filesystem}{34} +\entry {program, filesystem type}{34} +\initial {Q} +\entry {Querying an alternate host}{43} +\entry {quiet, FSinfo command line option}{61} +\initial {R} +\entry {Referencing part of the local name space}{35} +\entry {Regular expressions in maps}{36} +\entry {Replacement volumes}{6} +\entry {Replicated volumes}{6} +\entry {Resolving aliased hostnames}{27} +\entry {Restarting existing mounts}{28} +\entry {rfs, mount option}{31} +\entry {rhost, mount option}{31} +\entry {Root filesystem}{39} +\entry {root, filesystem type}{39} +\entry {RPC retries}{9} +\entry {Run-time administration}{40} +\entry {rwho servers}{69} +\initial {S} +\entry {Secondary server}{21} +\entry {sel, FSinfo mount option}{54} +\entry {Selecting specific log messages}{29} +\entry {Selector; arch}{20} +\entry {Selector; autodir}{20} +\entry {Selector; byte}{20} +\entry {Selector; cluster}{20} +\entry {Selector; domain}{20} +\entry {Selector; host}{20} +\entry {Selector; hostd}{20} +\entry {Selector; karch}{20} +\entry {Selector; key}{20} +\entry {Selector; map}{20} +\entry {Selector; os}{20} +\entry {Selector; path}{20} +\entry {Selector; wire}{21} +\entry {Selectors}{19} +\entry {Server crashes}{8} +\entry {Setting a delay on a mount location}{21} +\entry {Setting Amd's RPC parameters}{28} +\entry {Setting debug flags}{30} +\entry {Setting default map parameters}{18} +\entry {Setting map cache parameters}{36} +\entry {Setting map options}{21} +\entry {Setting system mount options}{22} +\entry {Setting the cluster name}{30} +\entry {Setting the default mount directory}{25} +\entry {Setting the filesystem type option}{24} +\entry {Setting the interval before a filesystem times out}{26} +\entry {Setting the interval between unmount attempts}{28} +\entry {Setting the Kernel architecture}{26} +\entry {Setting the local domain name}{26} +\entry {Setting the local mount point}{21} +\entry {Setting the log file}{27} +\entry {Setting the NIS (YP) domain name}{30} +\entry {Setting the sublink option}{23} +\entry {Sharing a fileserver between architectures}{68} +\entry {SIGHUP signal}{36} +\entry {SIGINT signal}{41} +\entry {SIGTERM signal}{41} +\entry {Source code distribution}{3} +\entry {Starting Amd}{40} +\entry {Statically mounts filesystems, FSinfo}{55} +\entry {Statistics}{44} +\entry {Stopping Amd}{41} +\entry {Stripping the local domain name}{18} +\entry {sublink}{5} +\entry {sublink, mount option}{23} +\entry {Supported machine architectures}{11} +\entry {Supported operating systems}{10} +\entry {Symbolic link filesystem}{35} +\entry {symlink, link filesystem type}{35} +\entry {Synchronising the map cache}{36} +\entry {syslog}{27} +\entry {syslog priorities}{29} +\initial {T} +\entry {The mount system call}{22} +\entry {Top level filesystem}{38} +\entry {toplvl, filesystem type}{38} +\entry {type, mount option}{24} +\entry {Types of configuration map}{12} +\entry {Types of filesystem}{31} +\entry {Types of mount map}{12} +\initial {U} +\entry {UFS}{34} +\entry {ufs, filesystem type}{34} +\entry {Union file maps}{16} +\entry {Union filesystem}{38} +\entry {union, filesystem type}{38} +\entry {Unix filesystem}{34} +\entry {Unix namespace}{6} +\entry {unmount attempt backoff interval}{28} +\entry {unmount, mount option}{34} +\entry {Unmounting a filesystem}{45} +\entry {User filesystems}{65} +\entry {User maps, automatic generation}{15} +\entry {Using FSinfo}{46} +\entry {Using syslog to log errors}{27} +\entry {Using the password file as a map}{15} +\initial {V} +\entry {Variable expansion}{18} +\entry {verbose, FSinfo command line option}{61} +\entry {Version information}{28} +\entry {volname, FSinfo mount option}{54} +\entry {Volume}{5} +\entry {Volume binding}{6} +\entry {Volume names}{6} +\initial {W} +\entry {Wildcards in maps}{16} +\entry {wire, mount selector}{21} +\initial {Y} +\entry {YP domain name}{30} diff --git a/usr.sbin/amd/doc/amdref.ps b/usr.sbin/amd/doc/amdref.ps new file mode 100644 index 0000000..17e10f5 --- /dev/null +++ b/usr.sbin/amd/doc/amdref.ps @@ -0,0 +1,6429 @@ +%!PS-Adobe-2.0 +%%Creator: dvipsk 5.512a Copyright 1986, 1993 Radical Eye Software +%%Title: amdref.dvi +%%Pages: 62 +%%PageOrder: Ascend +%%BoundingBox: 0 0 612 792 +%%EndComments +%DVIPSCommandLine: dvips amdref.dvi -o +%DVIPSSource: TeX output 1993.06.10:1525 +%%BeginProcSet: tex.pro +/TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N} +B /TR{translate}N /isls false N /vsize 11 72 mul N /@rigin{isls{[0 -1 1 0 0 0] +concat}if 72 Resolution div 72 VResolution div neg scale isls{Resolution hsize +-72 div mul 0 TR}if Resolution VResolution vsize -72 div 1 add mul TR matrix +currentmatrix dup dup 4 get round 4 exch put dup dup 5 get round 5 exch put +setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed +true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N +/IE 0 N /ctr 0 N /df-tail{/nn 8 dict N nn begin /FontType 3 N /FontMatrix +fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{ +CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn +put /ctr 0 N[}B /df{/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 +0 sf neg 0 0]N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data +dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{128 +ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 +sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type +/stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N +/cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get +S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height +sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 +-1 -.1 ch-xoff sub ch-yoff .1 add]{ch-image}imagemask restore}B /D{/cc X dup +type /stringtype ne{]}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 +ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N} +B /I{cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin +0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add +.99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore showpage userdict +/eop-hook known{eop-hook}if}N /@start{userdict /start-hook known{start-hook} +if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255 +{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 +div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N +/ruley 0 N /v{/ruley X /rulex X V}B /V{}B /RV statusdict begin /product where{ +pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 +getinterval(NeXT)eq or}{pop false}ifelse}{false}ifelse end{{gsave TR -.1 -.1 +TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 +-.1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{ +gsave transform round exch round exch itransform moveto rulex 0 rlineto 0 +ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N +/tail{dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} +B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{4 M}B +/w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{p 1 w}B /r{ +p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save +N}B /eos{SS restore}B end +%%EndProcSet +TeXDict begin 40258431 52099146 1000 300 300 (amdref.dvi) @start +/Fa 1 59 df<78FCFCFCFC7806067B8510>58 D E /Fb 1 59 df<60F0F06004047D830B>58 +D E /Fc 68 122 df<00FE7C0381C60603CE0E03841C03801C03801C03801C03801C03801C0380 +FFFFF01C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C0380 +1C03801C0380FF8FF0171A809916>11 D<00FE000381000601800E03801C01001C00001C00001C +00001C00001C0000FFFF801C03801C03801C03801C03801C03801C03801C03801C03801C03801C +03801C03801C03801C03801C0380FF8FF0141A809915>I<00FF800383800603800E03801C0380 +1C03801C03801C03801C03801C0380FFFF801C03801C03801C03801C03801C03801C03801C0380 +1C03801C03801C03801C03801C03801C03801C0380FF9FF0141A809915>I<60F0F86808080810 +102040050B7D990B>39 D<00800100020004000C00080018003000300030006000600060006000 +E000E000E000E000E000E000E000E000E000E0006000600060006000300030003000180008000C +00040002000100008009267D9B0F>I<8000400020001000180008000C00060006000600030003 +000300030003800380038003800380038003800380038003800300030003000300060006000600 +0C0008001800100020004000800009267E9B0F>I<60F0F07010101020204040040B7D830B>44 +DI<60F0F06004047D830B>I<0004000C00180018001800300030003000 +600060006000C000C000C00180018001800300030003000600060006000C000C000C0018001800 +1800300030003000600060006000C000C0000E257E9B13>I<07E01C38381C300C700E60066006 +E007E007E007E007E007E007E007E007E007E00760066006700E300C381C1C3807E010187F9713 +>I<03000700FF0007000700070007000700070007000700070007000700070007000700070007 +0007000700070007007FF80D187D9713>I<0F80106020304038803CC01CE01C401C003C003800 +380070006000C001800100020004040804100430083FF87FF8FFF80E187E9713>I<07E0183820 +1C601E700E201E001E001C001C0038007007E00038001C000E000F000FE00FE00FC00F400E601C +183807E010187F9713>I<001800180038007800F800B801380238023804380838183810382038 +4038C038FFFF00380038003800380038003803FF10187F9713>I<30183FF03FE03F8020002000 +2000200020002FC03060203000380018001C001C401CE01CE01C80184038403030E00F800E187E +9713>I<01F807040C06180E300E300070006000E000E3E0E418E80CF00EE006E007E007E00760 +0760077006300E180C0C3807E010187F9713>I<40007FFF7FFE7FFE4004800880108010002000 +400040008001800100030003000700060006000E000E000E000E000E00040010197E9813>I<07 +E01818300C2006600660067006780C3E181F3007C003E00CF8307C601E600FC007C003C003C003 +60022004181807E010187F9713>I<07E01C303018700C600EE006E006E007E007E0076007700F +3017182707C700070006000E000C700C7018603030600F8010187F9713>I<60F0F06000000000 +0000000060F0F0701010102020404004177D8F0B>59 D<000C0000000C0000000C0000001E0000 +001E0000002F000000270000002700000043800000438000004380000081C0000081C0000181E0 +000100E0000100E00003FFF000020070000200700004003800040038000400380008001C000800 +1C003C001E00FF00FFC01A1A7F991D>65 DI<003F0201C0C603002E0E001E1C00 +0E1C0006380006780002700002700002F00000F00000F00000F00000F00000F000007000027000 +027800023800041C00041C00080E000803003001C0C0003F00171A7E991C>III +I<003F020001C0C60003002E000E001E001C000E001C0006003800060078000200700002007000 +0200F0000000F0000000F0000000F0000000F0000000F001FFC070000E0070000E0078000E0038 +000E001C000E001C000E000E000E000300160001C06600003F82001A1A7E991E>III75 DIII<00 +7F000001C1C000070070000E0038001C001C003C001E0038000E0078000F0070000700F0000780 +F0000780F0000780F0000780F0000780F0000780F0000780F000078078000F0078000F0038000E +003C001E001C001C000E0038000700700001C1C000007F0000191A7E991E>II< +007F000001C1C000070070000E0038001C001C003C001E0038000E0078000F0070000700F00007 +80F0000780F0000780F0000780F0000780F0000780F0000780F00007807000070078000F003800 +0E003C1C1E001C221C000E4138000741F00001E1C000007F80800000C0800000C0800000E18000 +007F0000007F0000003E0000001C0019217E991E>II<0FC21836200E6006C006C002C002C002E00070007E003F +E01FF803FC007E000E00070003800380038003C002C006E004D81887E0101A7E9915>I<7FFFFF +00701C0700401C0100401C0100C01C0180801C0080801C0080801C0080001C0000001C0000001C +0000001C0000001C0000001C0000001C0000001C0000001C0000001C0000001C0000001C000000 +1C0000001C0000001C0000001C0000001C000003FFE000191A7F991C>IIII89 +D<1FC000387000383800101C00001C00001C0003FC001E1C00381C00701C00E01C00E01C80E01C +80E03C80705F801F8F0011107F8F13>97 DI<07F81C1C381C70087000E000E000 +E000E000E000E0007000700438081C1807E00E107F8F11>I<003F000007000007000007000007 +0000070000070000070000070000070003E7000C1700180F00300700700700E00700E00700E007 +00E00700E00700E00700600700700700380F001C370007C7E0131A7F9915>I<07C01C30301870 +18600CE00CFFFCE000E000E000E0006000700438081C1807E00E107F8F11>I<01F007180E381C +101C001C001C001C001C001C00FFC01C001C001C001C001C001C001C001C001C001C001C001C00 +1C001C00FF800D1A80990C>I<0FCF001871803030007038007038007038007038003030001860 +002FC0006000006000007000003FF0003FFC001FFE00600F00C00300C00300C00300C003006006 +00381C0007E00011187F8F13>II<183C3C18000000000000FC1C1C1C1C1C1C1C +1C1C1C1C1C1C1CFF081A80990A>I107 DIII<07E01C38300C700E6006E007E007E007E007E007E007600670 +0E381C1C3807E010107F8F13>II<03E1000C1300180B00300F00700700E00700E00700E00700E00700 +E00700E00700700700700700380F001C370007C700000700000700000700000700000700000700 +003FE013177F8F14>II<1F2060E04020C020C020F0007F003FC01FE000F080708030C030C020F0 +408F800C107F8F0F>I<0800080008000800180018003800FFC038003800380038003800380038 +003800382038203820382018201C4007800B177F960F>I +IIIII E /Fd 13 119 +df<7FFFF0FFFFF8FFFFF87FFFF015047D921C>45 D68 D +73 D<7FE0FFC0FFF1FFE07FE0FFC00F001E000F001E000F001E000F001E000F001E000F001E00 +0F001E000F001E000F001E000F001E000F001E000F001E000F001E000F001E000F001E000F001E +000F001E000F001E000F001E000F001E000F001E000F001E0007001C0007803C0007803C0003C0 +780001E0F00000FFE000007FC000001F00001B2180A01C>85 D<0FF8001FFE003FFF803C0F8018 +03C00001E00001E00001E0003FE003FFE00FFFE03FC1E07E01E07801E0F001E0F001E0F001E0F0 +01E07803E07C0FE03FFFFF1FFEFF03F03F18177D961C>97 DI<000FF0000FF0000FF00000F00000F00000F00000F00000F000 +00F00000F000F8F003FEF00FFFF01F07F03E03F03C01F07800F07800F0F000F0F000F0F000F0F0 +00F0F000F0F000F0F000F07800F07801F03C01F03E03F01F07F00FFFFF07FEFF01F8FF18217EA0 +1C>100 D<00FC0003FF000FFFC01F03E03E01E03C00F07800F0780070F00078F00078FFFFF8FF +FFF8FFFFF8F00000F000007800007800783C00783E00F81F81F00FFFE003FFC000FE0015177D96 +1C>I<0003F8001FFC003FFE007C1E00780C00F00000F00000F00000F00000F0007FFFFCFFFFFC +FFFFFC00F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F000 +00F00000F00000F00000F00000F0007FFFE07FFFE07FFFE017217FA01C>I104 D<7E783C00FEFE7F007FFFFF001FCFE7801F0F87801F0F87 +801E0F07801E0F07801E0F07801E0F07801E0F07801E0F07801E0F07801E0F07801E0F07801E0F +07801E0F07801E0F07801E0F07801E0F07807F8FC7E0FFCFE7F07F8FC7E01C1780961C>109 +D<00FC780003FF78000FFFF8001F03F8003E01F8003C00F8007800F80078007800F0007800F000 +7800F0007800F0007800F0007800F0007800F0007800780078007800F8003C01F8003E01F8001F +07F8000FFFF80003FE780000F87800000078000000780000007800000078000000780000007800 +0000780000007800000078000007FF800007FF800007FF8019237E961C>113 +D<7FE3FF00FFE3FF807FE3FF000F0078000F0078000F80F8000780F0000780F00007C1F00003C1 +E00003C1E00003C1E00001E3C00001E3C00001E3C00000E3800000F7800000F7800000F7800000 +7F0000007F0000007F0000003E000019177F961C>118 D E /Fe 24 122 +df45 D<1FFFFFFFE07FFFFFFFF07FFFFFFFF00000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000FFFF +FFFFC0FFFFFFFFC07FFFFFFF80240F7B942A>61 D<000001000000000180000000038000000007 +8000000007800000000F800000000FC000000013C000000013C000000023C000000023C0000000 +43E000000041E000000081E000000081E000000101E000000101F000000200F000000200F00000 +0400F000000400F000000800F00000080078000010007800003FFFF800003FFFF8000040007800 +0040007C000080003C000080003C000100003C000100003C000200003E000200001E000600001E +001F00003E00FFC001FFF0FFC003FFE024267EA528>65 D<007F80007F8000FF0000E00000E000 +00E00000E00000E00001C00001C00001C00001C00001C00001C000038000038000038000038000 +0380000380000700000700000700000700000700000700000E00000E00000E00000E00000E0000 +0E00001C00001C00001C00001C00001C00001C0000380000380000380000380000380000380000 +700000700000700000700000700000700000E00000E00000FF0000FF0000FF000011377DA80F> +91 D<007F80007F8000FF00000700000700000700000700000700000E00000E00000E00000E00 +000E00000E00001C00001C00001C00001C00001C00001C00003800003800003800003800003800 +00380000700000700000700000700000700000700000E00000E00000E00000E00000E00000E000 +01C00001C00001C00001C00001C00001C000038000038000038000038000038000038000070000 +070000FF0000FF0000FF0000113781A80F>93 D<01FF000701C00780E00F80F00F807807007800 +00780000780000F0003FF001F0F00780F01E00F03C00F07801E07801E1F001E1F001E1F003E1F0 +05E2700DE23C11FC0FE07818177D961B>97 D<03C0003FC0003FC00007C00007C0000780000780 +000780000780000780000780000F00000F00000F00000F00000F0FC00F30701EC0181F001C1E00 +0E1E000E1E000F1E000F3C000F3C000F3C000F3C000F3C000F3C000E78001E78001C78003C7800 +387800707800E0E401C0C3070080FC0018267BA51E>I<007FC001C0700300F00E01F01E01F01C +00E0380000780000780000F00000F00000F00000F00000F00000F00000F00000F0000070002070 +00403800C01801000E060003F80014177C9618>I<000003C000003FC000003FC0000007C00000 +07C000000780000007800000078000000780000007800000078000000F0000000F0000000F0000 +000F00003F0F0000E0CF0003803E0006003E000E001E001C001E0038001E0078001E0078003C00 +F0003C00F0003C00F0003C00F0003C00F0003C00F0007800F0007800F0007800700078007000F8 +003801F8001802F8000E0CFF0003F0FF001A267CA51E>I<007E0001C1800700E00E00601C0070 +3C0070380070780070780070FFFFF0F00000F00000F00000F00000F00000F00000F00000700020 +7000403800801801000E060003F80014177C9618>I<0000F800038C000E1E001E3E003C3E003C +3C00780000780000780000780000780000F00000F00000F00000F0001FFF801FFF8001E00001E0 +0001E00001E00001E00001E00003C00003C00003C00003C00003C00003C0000780000780000780 +000780000780000780000F8000FFF800FFF80017267FA510>I<003C000003FC000003FC000000 +7C0000007C000000780000007800000078000000780000007800000078000000F0000000F00000 +00F0000000F0000000F0FE0000F3070001E4038001E803C001F003C001F003C001E003C001E003 +C003C0078003C0078003C0078003C0078003C0078003C0078007800F0007800F0007800F000780 +0F0007800F0007800F000F801F00FFF1FFE0FFF1FFE01B267FA51E>104 +D<0038007C007C0078003000000000000000000000000000000000000000F00FF00FE001E001E0 +01E001E001E003C003C003C003C003C003C00780078007800780078007800F80FFF0FFF00E257F +A40F>I<00F0FE01FC001FF307060E001FE40388070001E803D0078001F003E0078001F003E007 +8001E003C0078001E003C0078003C007800F0003C007800F0003C007800F0003C007800F0003C0 +07800F0003C007800F0007800F001E0007800F001E0007800F001E0007800F001E0007800F001E +0007800F001E000F801F003E00FFF1FFE3FFC0FFF1FFE3FFC02A177F962D>109 +D<00F0FE000FF307001FE4038001E803C001F003C001F003C001E003C001E003C003C0078003C0 +078003C0078003C0078003C0078003C0078007800F0007800F0007800F0007800F0007800F0007 +800F000F801F00FFF1FFE0FFF1FFE01B177F961E>I<003F0001C1C00300600E00701C00381C00 +3838003C78003C78003CF0003CF0003CF0003CF0003CF00038F00078F00078F00070F000E07001 +E03801C01807000E0E0003F00016177C961B>I<003C3F0003FCC1C007FB00E0007C0070007800 +78007800380078003C0078003C00F0003C00F0003C00F0003C00F0003C00F0003C00F0007801E0 +007801E0007001E000F001E000E001E001C001E0038003D0070003CC1C0003C3F00003C0000003 +C0000003C0000007800000078000000780000007800000078000000F800000FFF00000FFF00000 +1E2281961E>I<003E0601E18603808C07005C0E007C1C003C3C003C78003C780078F00078F000 +78F00078F00078F00078F000F0F000F0F000F07000F07001F03802F01805E00E19E003E1E00001 +E00001E00001E00003C00003C00003C00003C00003C00007C0007FF8007FF817227C961C>I<00 +F1F00FF2381FE47801E87801F03001F00001E00001E00003E00003C00003C00003C00003C00003 +C0000780000780000780000780000780000780000F8000FFF800FFF80015177F9615>I<00FE20 +0381E00600C00C00401C00401C00401C00401E00001FC0001FFC000FFE0007FF0000FF80000F80 +400780400380600380600380600300600700F00600C81C0087F00013177E9615>I<0040008000 +8000800080018001800300030007000F003FFEFFFE1E001E001E001E001E001E003C003C003C00 +3C003C003C0478087808780878087808781038201C600F800F227BA115>I<07800F7F80FFFF01 +FE0F001E0F001E0F001E0F001E0F001E1E003C1E003C1E003C1E003C1E003C1E003C3C00783C00 +783C00783C00F83C00F83C01781C02F80E0CFF03F0FF18177C961E>I<0FFE1FF01FFC1FF001F8 +0F8000F00C000078080000781000003C2000003E4000001E8000001F0000000F0000000F800000 +0F8000001BC0000013C0000021E0000041E0000080F0000100F800030078001F00FC00FF81FFC0 +FF81FFC01C177F961C>120 D<07FF03FC07FF03FC00F801E000F8008000780180007801000078 +020000780200003C0400003C0400003C0800003C0800003E1000001E2000001E2000001E400000 +1F4000000F8000000F8000000F0000000E00000006000000040000000400000008000000080000 +0010000030200000F8200000F8400000F8C00000F1800000C30000003C0000001E2280961C>I +E /Ff 28 122 df45 D<387C7EFC7C3807067B8510>I<00000020 +0000000060000000007000000000F000000000F000000001F000000001F000000003F000000003 +F800000004F80000000CF800000008F800000010F800000010FC000000207C000000207C000000 +407C000000407C000000807E000000803E000001003E000001003E000002003E000002003F0000 +04001F000004001F000008001F00000FFFFF00001FFFFF000010001F800020000F800060000F80 +0040000F800080000F800080000FC001000007C001000007C003000007C007000007C01F80000F +E0FFE000FFFEFFE000FFFE272A7EA92C>65 D<03FFFFFFF803FFFFFFF8001F8001F8001F000078 +001F000038001F000018001F000018001F000018003E000018003E000018003E000008003E0000 +08003E002008003E002008007C004000007C004000007C004000007C00C000007C03C000007FFF +C00000FFFF800000F803800000F801800000F801800000F800800000F800800001F001000001F0 +01000001F000000001F000000001F000000001F000000003E000000003E000000003E000000003 +E000000003E000000003E000000007E0000000FFFF800000FFFF80000025297DA826>70 +D<03FFFC03FFFC001F80001F00001F00001F00001F00001F00003E00003E00003E00003E00003E +00003E00007C00007C00007C00007C00007C00007C0000F80000F80000F80000F80000F80000F8 +0001F00001F00001F00001F00001F00001F00003E00003E00003E00003E00003E00003E00007E0 +00FFFF00FFFF0016297DA815>73 D<03FF8000FFF003FFC000FFF0001FC0001F800017C0000600 +0013E00004000013E00004000011F00004000011F00004000020F80008000020F800080000207C +00080000207C00080000203E00080000203E00080000401F00100000401F00100000401F801000 +00400F80100000400FC01000004007C01000008007E02000008003E02000008003F02000008001 +F02000008001F82000008000F82000010000FC40000100007C40000100007E40000100003E4000 +0100003F40000100001F40000200001F80000200000F80000200000F8000020000078000020000 +0780000600000380001F8000030000FFF000010000FFF0000100002C297DA82C>78 +D<0001FC020007FF06001E038E003800DC0070007C00E0003C01E0001C03C0001C03C0001C0380 +000807800008078000080780000807C0000807C0000007E0000003F0000003FE000001FFE00001 +FFFC0000FFFF00003FFF800007FFC00000FFE000000FE0000003F0000001F0000001F0000001F0 +200000F0200000F0200000F0200000E0600001E0600001E0700001C0700003C0780007807C0007 +00E6001E00E3C07C00C1FFF000803FC0001F2B7DA921>83 D<003F800001C0E000020070000780 +380007C03C000F803C0007803C0002003C0000003C0000003C0000003C00003FF80001F0780007 +C078000F0078001E0078003C0078007C00F040F800F040F800F040F800F040F801F040F802F080 +7C04F0803E187F0007E03C001A1A7D991D>97 D<001FE000701801C00403803C07003E0F007C1E +003C3E00103C00007C00007C0000F80000F80000F80000F80000F80000F80000F80000F8000078 +00107800103C00201C00400E008007070001F800171A7C991A>99 D<0000007800000FF800000F +F8000000F0000000F0000000F0000000F0000000F0000000F0000001E0000001E0000001E00000 +01E0000001E0000001E0000003C0000FC3C0007833C001E00BC003800BC0070007C00F0007801E +0007803E0007803C0007807C0007807C00078078000F00F8000F00F8000F00F8000F00F8000F00 +F8000F00F8001E00F8001E0078001E0078001E0038003E001C005E000E00BE0007073FE001F83F +E01D2A7CA921>I<003F8000E0E001C0700780700F00780E00381E003C3C003C3C003C7C003C7C +007CFFFFF8F80000F80000F80000F80000F80000F80000F800007800107800103800201C00400C +018007060001F800161A7C991A>I<00007C0001C200070F000F1F001E1F001C0F003C04003C00 +003C0000780000780000780000780000780000780000F0001FFFC01FFFC000F00000F00000F000 +01E00001E00001E00001E00001E00001E00003C00003C00003C00003C00003C00003C000078000 +0780000780000780000780000780000F8000FFFC00FFFC00182A7EA912>I<000000780007E084 +003C3B1C00701C1C00E01E0801E01E0003E01F0003C01F0007C01F0007C01F0007C01F0007C01E +0007C03E0007C03C0003C0780001C0700002E1E000063F000004000000040000000C0000000C00 +00000E00000007FFE00007FFF80003FFFC000E003E0018000F00380007007000070070000700E0 +000700E0000700E0000700E0000E0070001C0030003800180070000F03C00001FE00001E287F9A +1D>I<001E000003FE000003FE0000003C0000003C0000003C0000003C0000003C0000003C0000 +00780000007800000078000000780000007800000078000000F0000000F07F0000F1838000F201 +C000F401E000F801E001F001E001F001E001E001E001E001E001E001E001E001E003C003C003C0 +03C003C003C003C003C003C003C003C003C0078007800780078007800780078007800780078007 +8007800F800F80FFF8FFF8FFF8FFF81D2A7EA921>I<0038007C00FC00FC007C00780000000000 +0000000000000000000000000000F00FF00FF001F001F001E001E001E001E001E001E003C003C0 +03C003C003C003C00780078007800780078007800F80FFF0FFF00E297EA811>I<001E000003FE +000003FE0000003C0000003C0000003C0000003C0000003C0000003C0000007800000078000000 +78000000780000007800000078000000F0000000F00FFC00F00FFC00F007C000F0070000F00400 +01E0080001E0100001E0200001E0800001E1800001E3800003C7C00003D3C00003E3E00003C3E0 +0003C1E00003C1F0000780F0000780F8000780780007807C0007803C0007803E000F807F00FFF9 +FFE0FFF9FFE01E2A7EA91F>107 D<001E01FE03FE003C003C003C003C003C003C007800780078 +00780078007800F000F000F000F000F000F001E001E001E001E001E001E003C003C003C003C003 +C003C00780078007800780078007800F80FFF0FFF00F2A7EA911>I<00F07F007F000FF1838183 +801FF201C201C001F401E401E001F801E801E001F001F001E001F001F001E001E001E001E001E0 +01E001E001E001E001E001E001E001E003C003C003C003C003C003C003C003C003C003C003C003 +C003C003C003C003C003C003C00780078007800780078007800780078007800780078007800780 +078007800780078007800F800F800F80FFF8FFF8FFF8FFF8FFF8FFF82D1A7E9931>I<00F07F00 +0FF183801FF201C001F401E001F801E001F001E001F001E001E001E001E001E001E001E001E001 +E003C003C003C003C003C003C003C003C003C003C003C003C00780078007800780078007800780 +078007800780078007800F800F80FFF8FFF8FFF8FFF81D1A7E9921>I<001FC00070F001C03803 +801C07001E0E000E1E000F3C000F3C000F7C000F7C000F78001FF8001FF8001FF8001FF8001FF8 +003EF8003EF8003C78007C7800783800F03C01E01E03C007070001F800181A7C991D>I<003C1F +8003FC60E007FD8078007E003C003C003C007C001E0078001F0078001F0078001F0078001F0078 +001F00F0001F00F0001F00F0001F00F0001F00F0001E00F0003E01E0003E01E0007C01E0007801 +E000F001E001E001F001C003C8078003C40E0003C3F80003C0000003C0000003C0000007800000 +07800000078000000780000007800000078000000F800000FFF80000FFF800002026809921>I< +00F0F80FF11C0FF63E01F43E01F83C01F03C01F00001F00001E00001E00001E00003C00003C000 +03C00003C00003C00003C0000780000780000780000780000780000780000F8000FFFC00FFFC00 +171A7E9917>114 D<007F0801C0D80300380600180E00180C00101C00101E00101E00001F8000 +0FFC0007FF0003FF8000FFC0000FE00003E02001E06000E06000E06000E06000E06000C0700180 +E80300C40E0083F800151A7E9917>I<00200000200000200000600000400000C00000C00001C0 +0001C00003C0000780001FFF80FFFF800780000780000780000F00000F00000F00000F00000F00 +000F00001E00001E00001E00001E00001E01001E01003C02003C02003C02003C02003C04001C04 +001C08000E100003E00011257BA417>I<078007807F807F80FF80FF800F800F800F800F800F00 +0F000F000F000F000F000F000F000F000F000F000F001E001E001E001E001E001E001E001E001E +001E001E001E003C003C003C003C003C003C003C007C003C007C003C00BC001C017C000E067FC0 +03F87FC01A1A7B9921>III<07FF80FF8007FF80FF80007C003C +000078003800007C003000003C002000003C006000003C004000003E008000001E008000001E01 +0000001E010000001E020000000F020000000F040000000F080000000F080000000F9000000007 +9000000007A000000007A000000007C000000003C0000000038000000003000000000300000000 +0200000000020000000004000000000C00000000080000007010000000F810000000F820000000 +F040000000F080000000C1000000003E00000000212680991F>121 D E +/Fg 28 122 df<7FFFFEFFFFFFFFFFFF7FFFFE18047D931F>45 D<00000600000F00000F00001F +00001E00003E00003C00007C0000780000F80000F00001F00001E00003E00003C00007C0000780 +000780000F80000F00001F00001E00003E00003C00007C0000780000F80000F00001F00001E000 +01E00003E00003C00007C0000780000F80000F00001F00001E00003E00003C00007C0000780000 +F80000F00000F00000600000182F7DA91F>47 D<387CFEFEFE7C38000000000000000000000000 +387CFEFEFE7C38071A74991F>58 D<7FFFFF80FFFFFFC0FFFFFFC07FFFFF800000000000000000 +000000000000000000000000000000007FFFFF80FFFFFFC0FFFFFFC07FFFFF801A0E7E981F>61 +D<001F81C0007FF1C001FFFBC003E07FC007C01FC00F800FC01F0007C01E0007C03C0003C03C00 +03C0780003C0780003C07800000070000000F0000000F0000000F0000000F0000000F0000000F0 +000000F0000000F0000000F0000000700000007800000078000000780003C03C0003C03C0003C0 +1E0003C01F0007800F800F8007C01F0003E07E0001FFFC00007FF000001FC0001A257EA41F>67 +D<7FFF8000FFFFE0007FFFF8000F00FC000F003E000F001E000F001F000F000F800F0007800F00 +07800F0003C00F0003C00F0003C00F0003E00F0001E00F0001E00F0001E00F0001E00F0001E00F +0001E00F0001E00F0001E00F0001E00F0001E00F0003C00F0003C00F0003C00F0007C00F000780 +0F000F800F000F000F001E000F003E000F00FC007FFFF800FFFFE0007FFF80001B257FA41F>I< +07FC00001FFF00003FFFC0003E03E0003E01F0001C00F000000078000000780000007800000078 +00003FF80001FFF80007FFF8001FE078003E0078007C00780078007800F0007800F0007800F000 +7800F00078007800F8007E03F8003FFFFFE00FFF3FE003FC0FE01B1A7D991F>97 +D<007FE001FFF807FFFC0FC07C1F007C3E00383C0000780000780000700000F00000F00000F000 +00F00000F00000F000007000007800007800003C003C3E003C1F007C0FC0F807FFF001FFE0007F +80161A7C991F>99 D<0001FE000003FE000001FE0000001E0000001E0000001E0000001E000000 +1E0000001E0000001E0000001E00007E1E0001FF9E0007FFDE000F81FE001F00FE003E007E003C +003E0078001E0078001E00F0001E00F0001E00F0001E00F0001E00F0001E00F0001E00F0001E00 +F0001E0078001E0078003E003C003E003C007E001E00FE000F83FE0007FFDFE003FF1FF0007C1F +E01C257EA41F>I<007F0001FFC007FFE00F81F01F00783E00783C003C78003C78001E70001EF0 +001EFFFFFEFFFFFEFFFFFEF00000F000007800007800007800003C001E1E001E1F003E0FC0FC03 +FFF801FFF0003F80171A7D991F>I<0001FC000007FF00001FFF80003F0F80003C0F8000780700 +00780000007800000078000000780000007800007FFFFE00FFFFFE00FFFFFE0000780000007800 +000078000000780000007800000078000000780000007800000078000000780000007800000078 +000000780000007800000078000000780000007800000078000000780000007800003FFFF0007F +FFF8003FFFF00019257FA41F>I<007C0F8001FF3FC007FFFFE00F83F1E01F01F1C01E00F0003C +0078003C0078003C0078003C0078003C0078003C0078001E00F0001F01F0000F83E0001FFFC000 +1DFF00001C7C00003C0000003C0000003C0000001E0000001FFFE0000FFFF8000FFFFE001FFFFF +003C003F8078000F80780007C0F00003C0F00003C0F00003C0F00003C078000780780007803E00 +1F001F807E000FFFFC0003FFF000007F80001B287E991F>I<7F800000FF8000007F8000000780 +0000078000000780000007800000078000000780000007800000078000000783F000078FFC0007 +BFFE0007FC1F0007F00F0007E0078007C0078007C0078007800780078007800780078007800780 +078007800780078007800780078007800780078007800780078007800780078007800780078007 +80078007807FF87FF8FFFCFFFC7FF87FF81E2580A41F>I<00700000F80000F80000F800007000 +0000000000000000000000000000000000000000007FF800FFF8007FF800007800007800007800 +007800007800007800007800007800007800007800007800007800007800007800007800007800 +007800007800007800007800FFFFF8FFFFF8FFFFF815267BA51F>I<7F800000FF8000007F8000 +0007800000078000000780000007800000078000000780000007800000078000000787FFC00787 +FFE00787FFC007807E000780FC000781F8000783F0000787E000078FC000079F800007BF000007 +FF000007FF800007FFC00007F3C00007E3E00007C1F0000780F0000780F80007807C0007803C00 +07801E0007801F007FF87FE0FFFCFFF07FF87FE01C257FA41F>107 DII<7F83F000FF8FFC007FBFFE0007FC1F +0007F00F0007E0078007C0078007C0078007800780078007800780078007800780078007800780 +07800780078007800780078007800780078007800780078007800780078007800780078007807F +F87FF8FFFCFFFC7FF87FF81E1A80991F>I<00FC0003FF0007FF801F87E01E01E03C00F07C00F8 +780078780078F0003CF0003CF0003CF0003CF0003CF0003CF0003CF8007C7800787800787C00F8 +3C00F01E01E01F87E007FF8003FF0000FC00161A7C991F>I<7F83E000FF9FFC007FBFFE0007FC +1F0007F0078007E003C007C003C0078001E0078001E0078000F0078000F0078000F0078000F007 +8000F0078000F0078000F0078000F0078001E007C001E007C003C007E007C007F00F8007F81F00 +07BFFE00079FF8000787E000078000000780000007800000078000000780000007800000078000 +000780000007800000078000007FF80000FFFC00007FF800001C2780991F>I<7FE07E00FFE1FF +807FE3FFC001EF87C001FF07C001FC038001F8000001F8000001F0000001F0000001F0000001E0 +000001E0000001E0000001E0000001E0000001E0000001E0000001E0000001E0000001E0000001 +E0000001E000007FFFE000FFFFE0007FFFE0001A1A7E991F>114 D<03FC700FFFF03FFFF07C03 +F07001F0E000F0E000F0E000F0F000F07C00003FE0001FFF0007FFC000FFF00003F80000787000 +3CF0001CF0001CF8001CF8001CFC0038FF00F0FFFFF0E7FFC0E1FE00161A7C991F>I<00700000 +00F0000000F0000000F0000000F0000000F0000000F000007FFFFE00FFFFFE00FFFFFE0000F000 +0000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0 +000000F0000000F0000000F0078000F0078000F0078000F0078000F0078000F00F00007C1F0000 +3FFE00001FFC000007F00019217FA01F>I<7F807F80FF80FF807F807F80078007800780078007 +800780078007800780078007800780078007800780078007800780078007800780078007800780 +078007800780078007800780078007800780078007800F8007801F8003C07F8001FFFFF800FFE7 +FC003F87F81E1A80991F>I<7FF0FFE0FFF0FFF07FF0FFE00F000F0007801E0007801E0007801E +0003C03C0003C03C0003C03C0003E07C0001E0780001E0780001E0780000F0F00000F0F00000F0 +F0000079E0000079E0000079E0000039C0000039C000003FC000003FC000001F8000001F80001C +1A7F991F>II< +7FF1FFC07FF1FFE07FF1FFC007C07C0003E0780001E0F80000F1F00000F9E000007FE000003FC0 +00003F8000001F8000000F0000001F0000001F8000003FC0000079E00000F9E00000F0F00001E0 +F80003E07C0003C03C0007803E007FF0FFE0FFF9FFF07FF0FFE01C1A7F991F>I<7FF0FFE0FFF8 +FFF07FF0FFE00F800F0007801E0007801E0003C01E0003C03C0003C03C0001E03C0001E07C0001 +E0780000F0780000F0780000F0F0000078F0000078F0000038E0000039E000003DE000001DC000 +001DC000001FC000000FC000000F8000000F8000000F8000000F0000000F0000001F0000001E00 +00001E0000383E00007C3C00007C7C00007CF800007FF000003FE000000F8000001C277F991F> +I E /Fh 3 110 df<00000001800000000003C00000000003C00000000007C00000000007C000 +0000000FC0000000000FE0000000001FE0000000001FE00000000037E00000000037E000000000 +67F00000000063F000000000C3F000000000C3F00000000183F00000000183F00000000303F800 +00000301F80000000601F80000000601F80000000C01F80000000C01FC0000001800FC00000018 +00FC0000003000FC0000003000FC0000006000FE000000E0007E000000C0007E000001C0007E00 +000180007E000003FFFFFE000003FFFFFF00000600003F00000600003F00000C00003F00000C00 +003F00001800003F80001800001F80003000001F80003000001F80006000001F80006000001F80 +00C000001FC001C000000FC003E000000FC00FF000003FE0FFFE0003FFFFFFFC0003FFFF30327E +B135>65 D<00000007C0000000FFC0000000FFC00000000FC00000000FC00000000F800000000F +800000000F800000000F800000000F800000000F800000001F000000001F000000001F00000000 +1F000000001F000000001F000000003E000000003E000003F83E00001E063E000038013E0000E0 +00BE0001C000FC000380007C000780007C000F00007C001F00007C001E00007C003E0000F8003C +0000F8007C0000F8007C0000F8007C0000F8007C0000F800F80001F000F80001F000F80001F000 +F80001F000780001F000780001F000780003E000780003E0003C0003E0003C0007E0001C000FE0 +000E001BE000070037F00001C1C7FF00007F07FE0022327BB127>100 D<003E03F8003F800FFE +0C1E00C1E00FFE300F0300F000FE4007840078007C8007C8007C007D0007D0007C007E0007E000 +7C007E0007E0007C007C0007C0007C007C0007C0007C00FC000FC000F800F8000F8000F800F800 +0F8000F800F8000F8000F800F8000F8000F800F8000F8000F801F0001F0001F001F0001F0001F0 +01F0001F0001F001F0001F0001F001F0001F0001F001F0001F0001F003E0003E0003E003E0003E +0003E003E0003E0003E003E0003E0003E003E0003E0003E007E0007E0007E007E0007E0007E0FF +FF0FFFF0FFFFFFFF0FFFF0FFFF381F7E9E3C>109 D E /Fi 49 122 df<0007FC00003FFF0000 +FE078003F007C007E00FC007E00FC00FC00FC00FC00FC00FC00FC00FC003000FC000000FC00000 +0FC000000FC07FE0FFFFFFE0FFFFFFE00FC007E00FC007E00FC007E00FC007E00FC007E00FC007 +E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC007E00FC0 +07E00FC007E00FC007E00FC007E00FC007E0FFFC7FFEFFFC7FFE1F267FA522>12 +D45 D<3C7EFFFFFFFF7E3C08087C8711>I<007F800003 +FFF00007E1F8000F807C001F003E003F003F003E001F007E001F807E001F807E001F807E001F80 +FE001FC0FE001FC0FE001FC0FE001FC0FE001FC0FE001FC0FE001FC0FE001FC0FE001FC0FE001F +C0FE001FC0FE001FC0FE001FC07E001F807E001F807E001F807E001F803F003F003F003F001F00 +3E000F807C0007E1F80003FFF000007F80001A237EA21F>48 D<001C00003C0000FC00FFFC00FF +FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000 +FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000 +FC0000FC0000FC007FFFFC7FFFFC16237CA21F>I<01FF0007FFC01E07F03803F86001FC7C00FE +FE00FEFE00FFFE007FFE007F7C007F3800FF0000FF0000FE0000FE0001FC0001F80003F00007E0 +000780000F00001E00003C0000700000E00301C0030380070700060600060FFFFE1FFFFE3FFFFE +7FFFFCFFFFFCFFFFFC18237DA21F>I<01FF0007FFE01E03F03801F83C01FC7E00FE7E00FE7E00 +FE3E00FE1C01FE0001FC0001FC0003F80007F0000FC001FF0001FF000007E00001F00001F80000 +FC0000FE0000FF0000FF1000FF7C00FFFE00FFFE00FFFE00FEFE00FE7C01FC7001F83E07F00FFF +C001FF0018237DA21F>I<0000380000007800000078000000F8000001F8000003F8000007F800 +0006F800000CF800001CF8000038F8000030F8000060F80000E0F80001C0F8000180F8000300F8 +000700F8000E00F8001C00F8001800F8003000F8007000F800E000F800FFFFFFC0FFFFFFC00001 +F8000001F8000001F8000001F8000001F8000001F8000001F800007FFFC0007FFFC01A237EA21F +>I<18000C1F007C1FFFF81FFFF01FFFE01FFFC01FFF801FFC0018000018000018000018000018 +000018FF001BFFE01F03F01C00F80800FC00007E00007E00007E00007F00007F78007FFC007FFC +007FFC007FFC007EF8007E6000FC7000FC3801F81E07E007FFC001FE0018237DA21F>I<001FC0 +007FF001F03803E00C07803E0F807E1F007E3F007E3F007E7E003C7E00007E00007E0000FE3FC0 +FE7FF0FE80F8FF80FCFF007CFF007EFE007EFE007FFE007FFE007FFE007F7E007F7E007F7E007F +7E007F3E007E3F007E1F007C0F80F807C1F003FFC0007F0018237DA21F>I<300000003C000000 +3FFFFFC03FFFFFC03FFFFF807FFFFF007FFFFE007FFFFC006000180060001800E0003000C00060 +00C000C00000018000000180000003000000060000000E0000000E0000001C0000001C0000003C +0000003C0000007800000078000000F8000000F8000000F8000000F8000001F8000001F8000001 +F8000001F8000001F8000001F8000000F00000006000001A257DA41F>I<00FF8003FFE00F01F8 +1C007C38003C38001E78001E78001E7C001E7E001E7F803C7FE03C3FF8781FFDF01FFFC00FFFC0 +03FFE003FFF80FFFFC1E1FFC3C07FE7803FE7800FFF0003FF0001FF0000FF0000FF0000FF0000E +78000E78001C3C00381F80F007FFE001FF0018237DA21F>I<00FF0003FFC00F83E01F00F03F00 +F87E007C7E007C7E007EFE007EFE007EFE007EFE007FFE007FFE007FFE007F7E007F7E00FF3E00 +FF3F01FF1F017F0FFE7F03FC7F00007F00007E00007E3C007E7E00FC7E00FC7E00F87E00F07C01 +F03003E01C0F800FFF0003F80018237DA21F>I68 DII72 DI77 +DI<0003FF80 +00001FFFF000007F01FC0001FC007F0003F0001F8007E0000FC00FE0000FE01FC00007F01F8000 +03F03F800003F83F800003F87F800003FC7F000001FC7F000001FCFF000001FEFF000001FEFF00 +0001FEFF000001FEFF000001FEFF000001FEFF000001FEFF000001FEFF000001FE7F000001FC7F +000001FC7F800003FC3F800003F83F800003F81FC00007F01FC00007F00FE0000FE007F0001FC0 +03F8003F8001FC007F00007F01FC00001FFFF0000003FF800027257DA42E>II<00FF008007FFE3800F80 +F7801E001F803C000F807800078078000380F8000380F8000180F8000180FC000180FC000000FF +0000007FE000007FFE00003FFFE0003FFFF8001FFFFE0007FFFF0003FFFF80007FFF800003FFC0 +00003FC000000FE0000007E0000007E0C00003E0C00003E0C00003E0C00003C0E00003C0F00007 +C0F8000780FC000F00FFC03E00E3FFF800803FE0001B257DA422>83 D85 DI<07FF00001FFFE0003E03F0003F00F8003F00FC +003F007E001E007E0000007E0000007E0000007E00001FFE0003FE7E000FC07E001F007E003E00 +7E007E007E00FC007E00FC007E00FC007E00FC00BE007E01BE003F073E001FFE1FE007F00FE01B +187E971E>97 DI<007FE003FFF807C07C1F80FC1F00FC3F00FC7E00787E0000FE0000FE00 +00FE0000FE0000FE0000FE0000FE0000FE00007E00007F00003F000C1F800C1FC01807E07003FF +E0007F0016187E971B>I<0000FFC00000FFC000000FC000000FC000000FC000000FC000000FC0 +00000FC000000FC000000FC000000FC000000FC000000FC000000FC0007F0FC003FFCFC00FE0FF +C01F803FC03F000FC03F000FC07E000FC07E000FC0FE000FC0FE000FC0FE000FC0FE000FC0FE00 +0FC0FE000FC0FE000FC0FE000FC07E000FC07E000FC03F000FC03F001FC01F803FC00FC0EFC003 +FFCFFC00FE0FFC1E267EA522>I<007F0003FFC007C1F00F80F81F00F83F007C7E007C7E007EFE +007EFE007EFFFFFEFFFFFEFE0000FE0000FE00007E00007E00007E00063F00061F000C0F801807 +E07003FFE0007F8017187E971C>I<001FC0007FF001F8F003E1F807E1F807C1F80FC0F00FC000 +0FC0000FC0000FC0000FC0000FC0000FC000FFFF00FFFF000FC0000FC0000FC0000FC0000FC000 +0FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC000 +0FC0000FC000FFFE00FFFE0015267EA513>I<01FF07C007FFDFE00F83F1E01F01F1E03E00F800 +7E00FC007E00FC007E00FC007E00FC007E00FC007E00FC003E00F8001F01F0000F83E0000FFFC0 +0011FF00003000000030000000380000003C0000003FFFE0001FFFFC001FFFFE000FFFFF001FFF +FF803C003F8078000FC0F80007C0F80007C0F80007C0F80007C07C000F803E001F001F807E0007 +FFF80000FFC0001B247E971F>II<0F001F803FC03FC03FC03FC01F800F00000000000000 +00000000000000007FC07FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00F +C00FC00FC00FC00FC00FC00FC0FFF8FFF80D277EA611>I107 DIII<007F800003FFF00007C0F8001F807E003F003F003F003F00 +7E001F807E001F80FE001FC0FE001FC0FE001FC0FE001FC0FE001FC0FE001FC0FE001FC0FE001F +C07E001F807E001F803F003F003F003F001F807E000FC0FC0003FFF000007F80001A187E971F> +II<007F00C003FFC1C0 +07E0E3C01FC033C01F801FC03F001FC07F000FC07F000FC0FE000FC0FE000FC0FE000FC0FE000F +C0FE000FC0FE000FC0FE000FC0FE000FC07E000FC07F000FC03F000FC03F801FC01F803FC00FE0 +EFC003FF8FC000FE0FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000 +000FC000000FC00000FFFC0000FFFC1E237E9720>II<07F8C01FFFC03C07C07001C0F000C0F0 +00C0F000C0FC0000FF80007FFC007FFE003FFF800FFFC003FFC0001FE00003E0C001E0C001E0E0 +01E0E001C0F003C0FC0780EFFF00C3FC0013187E9718>I<00C00000C00000C00000C00001C000 +01C00001C00003C00007C0000FC0001FC000FFFFC0FFFFC00FC0000FC0000FC0000FC0000FC000 +0FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0600FC0600FC0600FC0600FC0600FC060 +07E0C007E1C001FF80007E0013237FA218>IIIIII E /Fj 1 59 df<70F8F8F87005057C840D>58 D E /Fk 34 122 df<000700000007000000 +070000000F8000000F8000001FC000001FC000001FC000003FE0000037E0000037E0000063F000 +0063F0000063F00000C1F80000C1F80000C1F8000180FC000180FC000180FC0003007E0003FFFE +0007FFFF0006003F0006003F000E001F800C001F800C001F801C000FC0FF80FFF8FF80FFF81D1F +7E9E22>65 DI<000FF010007FFC7001FC0EF003E003F00FC001 +F01F8000F01F8000F03F0000703F0000707E0000307E000030FE000030FE000000FE000000FE00 +0000FE000000FE000000FE000000FE000000FE0000007E0000307E0000303F0000303F0000701F +8000601F8000E00FC000C003E0038001FC0F00007FFC00000FF0001C1F7E9E21>IIII73 +D77 DI<003FE00000FFF80003F07E0007C01F000F +800F801F800FC03F0007E03F0007E07F0007F07E0003F07E0003F0FE0003F8FE0003F8FE0003F8 +FE0003F8FE0003F8FE0003F8FE0003F8FE0003F8FE0003F87E0003F07E0003F07F0007F03F0007 +E03F0007E01F800FC00FC01F8007E03F0003F07E0000FFF800003FE0001D1F7E9E22>I<03F040 +0FFDC01C0FC03803C07001C07001C0F000C0F000C0F000C0F80000FC0000FF80007FF8003FFE00 +3FFF801FFFC007FFC000FFE0000FE00003F00001F00000F0C000F0C000F0C000F0E000E0E001E0 +F801C0FE0380EFFF0081FC00141F7E9E19>83 D85 +DI<7FFC3FF87FFC3FF807E0070007F0060003F00E0001F80C00 +01FC1C0000FC180000FE3000007E7000003F6000003FC000001FC000001FC000000FC0000007E0 +000007F000000FF000000FF8000019F8000038FC000030FE0000607E0000E07F0000C03F000180 +1F8003801FC003000FC007000FE0FFE07FFEFFE07FFE1F1F7F9E22>88 D<0FF0003FFC007E1E00 +7E1F007E0F807E0F80180F80000F8000FF800FFF801F0F807C0F807C0F80F80F80F80F80F80F80 +F817807C37803FE3F00F81F014147F9316>97 D<03F8000FFE001F3F003E3F007E3F007C3F007C +0C00FC0000FC0000FC0000FC0000FC0000FC00007C00007C00007E01803E03801F87000FFE0003 +F80011147F9314>99 D<001FE0001FE00003E00003E00003E00003E00003E00003E00003E00003 +E00003E00003E003F3E00FFFE01F0FE03E03E07C03E07C03E07C03E0FC03E0FC03E0FC03E0FC03 +E0FC03E0FC03E0FC03E07C03E07C03E03E07E01F0FE00FFBFC03F3FC16207F9F19>I<03F8000F +FE001F0F003E07803C07807C07C07C07C0FC07C0FFFFC0FFFFC0FC0000FC0000FC00007C00007C +00003E00C03E00C01F038007FF0001FC0012147F9315>I<007F0001FF8007C7C00F8FC00F0FC0 +1F0FC01F07801F00001F00001F00001F00001F0000FFF000FFF0001F00001F00001F00001F0000 +1F00001F00001F00001F00001F00001F00001F00001F00001F00001F00001F00001F0000FFF000 +FFF00012207F9F0E>I<03F0E00FFDF01E1EF03C0FF07C0F807C0F807C0F807C0F807C0F803C0F +001E1E001FFC0033F0003000003000003800003FFE003FFF801FFFC03FFFE07803F07000F0F000 +F0F000F0F000F0F000F07801E03E07C01FFF8003FC00141E7F9317>II<1C003E007F007F007F003E001C0000000000000000000000 +0000FF00FF001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F00FF +E0FFE00B217FA00C>I107 +DIII<01F8000FFF001F0F803E07C07C03E07C03E07C03E0FC03F0FC03F0 +FC03F0FC03F0FC03F0FC03F0FC03F07C03E07C03E03E07C01F0F800FFF0003FC0014147F9317> +I114 +D<0FD83FF87038E018E018E018F800FF807FF03FF81FFC03FE003EC00EC00EE00EE00CF81CFFF8 +C7E00F147F9312>I<0300030003000300070007000F000F003F00FFF8FFF81F001F001F001F00 +1F001F001F001F001F001F001F0C1F0C1F0C1F0C1F0C0F9807F003E00E1D7F9C12>II119 +DII E /Fl 92 126 df<70F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F870000000000070F8 +F8F870051C779B18>33 D<4010E038F078E038E038E038E038E038E038E038E038E038E0386030 +0D0E7B9C18>I<030600078F00078F00078F00078F00078F00078F007FFFC0FFFFE0FFFFE07FFF +C00F1E000F1E000F1E000F1E000F1E000F1E007FFFC0FFFFE0FFFFE07FFFC01E3C001E3C001E3C +001E3C001E3C001E3C000C1800131C7E9B18>I<00C00001C00001C00001C00003F0000FFC003F +FE007DCF0071C700E1C380E1C780E1C780E1C780F1C00079C0003FC0001FE0000FF80001FC0001 +DE0001CF0001C70061C380F1C380F1C380E1C380E1C70071C70079DE003FFE001FF80007E00001 +C00001C00001C00000C00011247D9F18>I<3803007C07807C0780EE0F80EE0F00EE0F00EE1F00 +EE1E00EE1E00EE3E007C3C007C3C00387C0000780000780000F80000F00001F00001E00001E000 +03E00003C00003C00007C0000783800787C00F87C00F0EE00F0EE01F0EE01E0EE01E0EE03E0EE0 +3C07C03C07C018038013247E9F18>I<01C00007E0000FF0000E70001C38001C38001C38001C38 +001C73F81CF3F81CE3F80FC1C00FC3800F83800F03801F07003F87007B8E0071CE00E1FC00E0FC +00E07C00E07870E0787070FE707FFFE03FC7E00F03C0151C7F9B18>I<387C7C7E3E0E0E0E1C1C +38F8F0C0070E789B18>I<007000F001E003C007800F001E001C00380038007000700070007000 +E000E000E000E000E000E000E000E0007000700070007000380038001C001E000F00078003C001 +F000F000700C24799F18>I<6000F00078003C001E000F000780038001C001C000E000E000E000 +E00070007000700070007000700070007000E000E000E000E001C001C0038007800F001E003C00 +7800F00060000C247C9F18>I<01C00001C00001C00001C00041C100F1C780FDDF807FFF001FFC +0007F00007F0001FFC007FFF00FDDF80F1C78041C10001C00001C00001C00001C00011147D9718 +>I<00600000F00000F00000F00000F00000F00000F00000F0007FFFC0FFFFE0FFFFE07FFFC000 +F00000F00000F00000F00000F00000F00000F00000600013147E9718>I<1C3E7E7F3F1F070E1E +7CF860080C788518>I<7FFFC0FFFFE0FFFFE07FFFC013047E8F18>I<3078FCFC78300606778518 +>I<000300000780000780000F80000F00001F00001E00001E00003E00003C00007C0000780000 +780000F80000F00001F00001E00003E00003C00003C00007C0000780000F80000F00000F00001F +00001E00003E00003C00003C00007C0000780000F80000F00000F0000060000011247D9F18>I< +01F00007FC000FFE001F1F001C07003803807803C07001C07001C0E000E0E000E0E000E0E000E0 +E000E0E000E0E000E0E000E0E000E0F001E07001C07001C07803C03803801C07001F1F000FFE00 +07FC0001F000131C7E9B18>I<01800380038007800F803F80FF80FB8043800380038003800380 +0380038003800380038003800380038003800380038003807FFCFFFE7FFC0F1C7B9B18>I<03F0 +000FFE003FFF007C0F807003C0E001C0F000E0F000E06000E00000E00000E00001C00001C00003 +C0000780000F00001E00003C0000780000F00001E00007C0000F80001E00E03C00E07FFFE0FFFF +E07FFFE0131C7E9B18>I<07F8001FFE003FFF007807807803C07801C03001C00001C000038000 +0380000F0003FF0003FE0003FF000007800003C00001C00000E00000E00000E0F000E0F000E0F0 +01C0F003C07C07803FFF001FFE0003F800131C7E9B18>I<001F00003F0000770000770000E700 +01E70001C7000387000787000707000E07001E07003C0700380700780700F00700FFFFF8FFFFF8 +FFFFF8000700000700000700000700000700000700007FF0007FF0007FF0151C7F9B18>I<3FFF +803FFF803FFF803800003800003800003800003800003800003800003800003BF8003FFE003FFF +003C07803003C00001C00000E00000E06000E0F000E0F000E0E001C07003C07C0F803FFF001FFC +0003F000131C7E9B18>I<007E0001FF0007FF800F83C01E03C01C03C038018038000070000070 +0000E1F800E7FE00FFFF00FE0780F803C0F001C0F000E0E000E0F000E07000E07000E07000E038 +01C03C03C01E07800FFF0007FE0001F800131C7E9B18>I +I<03F8000FFE001FFF003E0F803803807001C07001C07001C07001C03803803C07801FFF0007FC +000FFE001F1F003C07807001C0F001E0E000E0E000E0E000E0E000E07001C07803C03E0F801FFF +000FFE0003F800131C7E9B18>I<03F0000FFC001FFE003C0F00780780700380E001C0E001C0E0 +01C0E001E0E001E07001E07803E03C0FE01FFFE00FFEE003F0E00000E00001C00001C00001C030 +0380780780780F00783E003FFC001FF00007C000131C7E9B18>I<3078FCFC7830000000000000 +00003078FCFC78300614779318>I<183C7E7E3C180000000000000000183C7E7E3E1E0E1C3C78 +F060071A789318>I<0000C00003E00007E0001FC0003F8000FE0001FC0007F0000FE0003F8000 +7F0000FC0000FC00007F00003F80000FE00007F00001FC0000FE00003F80001FC00007E00003E0 +0000C013187E9918>I<7FFFC0FFFFE0FFFFE0FFFFE0000000000000000000000000FFFFE0FFFF +E0FFFFE07FFFC0130C7E9318>I<600000F80000FC00007F00003F80000FE00007F00001FC0000 +FE00003F80001FC00007E00007E0001FC0003F8000FE0001FC0007F0000FE0003F80007F0000FC +0000F8000060000013187E9918>I<007C0001FE0007FF000F87801E03C03C1DC0387FC070FFE0 +71E3E071C1E0E1C1E0E380E0E380E0E380E0E380E0E380E0E380E0E1C1C071C1C071E3C070FF80 +387F003C1C001E00E00F83E007FFC001FF80007E00131C7E9B18>64 D<00700000F80000F80000 +D80000D80001DC0001DC0001DC00018C00038E00038E00038E00038E0007070007070007070007 +07000707000FFF800FFF800FFF800E03801C01C01C01C01C01C07F07F0FF07F87F07F0151C7F9B +18>I<7FFC00FFFF007FFF801C03C01C01C01C00E01C00E01C00E01C00E01C01E01C01C01C07C0 +1FFF801FFF001FFFC01C03C01C00E01C00F01C00701C00701C00701C00701C00F01C00E01C03E0 +7FFFC0FFFF807FFE00141C7F9B18>I<00F8E003FEE007FFE00F07E01E03E03C01E03800E07000 +E07000E0700000E00000E00000E00000E00000E00000E00000E00000E000007000007000E07000 +E03800E03C00E01E01C00F07C007FF8003FE0000F800131C7E9B18>I<7FF800FFFE007FFF001C +0F801C03C01C03C01C01E01C00E01C00E01C00F01C00701C00701C00701C00701C00701C00701C +00701C00701C00F01C00E01C00E01C01E01C01C01C03C01C0F807FFF00FFFE007FF800141C7F9B +18>III<01F1C003FDC00FFFC01F +0FC01C03C03803C03801C07001C07001C0700000E00000E00000E00000E00000E00000E00FF0E0 +1FF0E00FF07001C07001C07003C03803C03803C01C07C01F0FC00FFFC003FDC001F1C0141C7E9B +18>I<7F07F0FF8FF87F07F01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C0 +1FFFC01FFFC01FFFC01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C0 +7F07F0FF8FF87F07F0151C7F9B18>I<7FFF00FFFF807FFF0001C00001C00001C00001C00001C0 +0001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C0 +0001C00001C00001C00001C0007FFF00FFFF807FFF00111C7D9B18>I<01FFC001FFC001FFC000 +0E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E0000 +0E00000E00000E00000E00000E00000E00F00E00F00E00F03C007FFC003FF0000FC000121C7D9B +18>I<7F07F0FF87F87F07F01C03C01C07801C07001C0E001C1E001C3C001C38001C70001CF000 +1DF0001DF0001FB8001FB8001F1C001E1C001C0E001C0E001C07001C07001C03801C03801C01C0 +7F03F0FF87F87F03F0151C7F9B18>III<7E07F0FF0FF87F07F01D81C01D81C01D81C01DC1C01CC1C01CC1C01CE1C01CE1C01CE1C0 +1C61C01C71C01C71C01C31C01C39C01C39C01C39C01C19C01C19C01C1DC01C0DC01C0DC01C0DC0 +7F07C0FF87C07F03C0151C7F9B18>I<0FFE003FFF807FFFC07803C07001C0F001E0E000E0E000 +E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000 +E0E000E0F001E07001C07C07C07FFFC03FFF800FFE00131C7E9B18>II<0FFE003FFF807FFFC07803C07001C0F001E0E000E0E000E0E000E0E000E0E000E0E000E0 +E000E0E000E0E000E0E000E0E000E0E000E0E000E0E000E0E070E0E070E0F079E07039C0783FC0 +7FFFC03FFF800FFE00000F000007800007800003C00001C00001C013227E9B18>I<7FF800FFFE +007FFF001C0F801C03801C03C01C01C01C01C01C01C01C03C01C03801C0F801FFF001FFE001FFE +001C0F001C07001C03801C03801C03801C03801C03801C039C1C039C1C039C7F01F8FF81F87F00 +F0161C7F9B18>I<03F1C01FFFC03FFFC07C0FC07003C0E001C0E001C0E001C0E0000070000078 +00003F00001FF00007FE0000FF00000F800003C00001C00000E00000E06000E0E000E0E001E0F0 +01C0F80780FFFF80FFFE00E7F800131C7E9B18>I<7FFFF8FFFFF8FFFFF8E07038E07038E07038 +E07038007000007000007000007000007000007000007000007000007000007000007000007000 +00700000700000700000700000700000700007FF0007FF0007FF00151C7F9B18>IIII<7F0FE07F9F +E07F0FE00E07000F0700070E00078E00039C0003DC0001F80001F80000F80000F00000700000F0 +0000F80001FC0001DC00039E00038E00070F000707000E07800E03801E03C07F07F0FF07F87F07 +F0151C7F9B18>II<3FFFE07FFFE07FFFE07001C07003C0700780 +700700000F00001E00001C00003C0000780000700000F00001E00001C00003C000078000070000 +0F00001E00E01C00E03C00E07800E07000E0FFFFE0FFFFE0FFFFE0131C7E9B18>II<600000F0 +0000F00000F800007800007C00003C00003C00003E00001E00001F00000F00000F00000F800007 +800007C00003C00003C00003E00001E00001F00000F00000F800007800007800007C00003C0000 +3E00001E00001E00001F00000F00000F8000078000078000030011247D9F18>II<018007C01F +F07EFCF83EE00E0F067C9B18>I<7FFFC0FFFFE0FFFFE07FFFC013047E7F18>I<061E3E387070E0 +E0E0F8FC7C7C38070E789E18>I<0FF0001FFC003FFE003C0F0018070000038000038000FF8007 +FF801FFF807F0380780380E00380E00380E00380F00780780F803FFFF81FFDF807F0F815147E93 +18>I<7E0000FE00007E00000E00000E00000E00000E00000E00000E3E000EFF800FFFC00FC1E0 +0F80E00F00700E00700E00380E00380E00380E00380E00380E00380F00700F00700F80E00FC1E0 +0FFFC00EFF80063E00151C809B18>I<01FE0007FF001FFF803E0780380300700000700000E000 +00E00000E00000E00000E00000E000007000007001C03801C03E03C01FFF8007FF0001FC001214 +7D9318>I<001F80003F80001F8000038000038000038000038000038003E3800FFB801FFF803C +1F80380F80700780700380E00380E00380E00380E00380E00380E00380700780700780380F803C +1F801FFFF00FFBF803E3F0151C7E9B18>I<01F00007FC001FFE003E0F00380780700380700380 +E001C0E001C0FFFFC0FFFFC0FFFFC0E000007000007001C03801C03E07C01FFF8007FF0001F800 +12147D9318>I<001F80007FC000FFE000E1E001C0C001C00001C00001C0007FFFC0FFFFC0FFFF +C001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C0 +0001C0007FFF007FFF007FFF00131C7F9B18>I<01E1F007FFF80FFFF81E1E301C0E0038070038 +07003807003807003807001C0E001E1E001FFC001FF80039E0003800001C00001FFE001FFFC03F +FFE07801F0700070E00038E00038E00038E000387800F07E03F01FFFC00FFF8001FC00151F7F93 +18>I<7E0000FE00007E00000E00000E00000E00000E00000E00000E3E000EFF800FFFC00FC1C0 +0F80E00F00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E0 +7FC7FCFFE7FE7FC7FC171C809B18>I<038007C007C007C0038000000000000000007FC0FFC07F +C001C001C001C001C001C001C001C001C001C001C001C001C001C001C0FFFFFFFFFFFF101D7C9C +18>I<0038007C007C007C003800000000000000000FFC0FFC0FFC001C001C001C001C001C001C +001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C6038F078FFF07F +E03F800E277E9C18>I<7E0000FE00007E00000E00000E00000E00000E00000E00000E3FF00E3F +F00E3FF00E07800E0F000E1E000E3C000E78000EF0000FF8000FFC000F9C000F0E000E0F000E07 +000E03800E03C07FC7F8FFC7F87FC7F8151C7F9B18>III<7E3E00FEFF807FFFC00FC1C00F80 +E00F00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E07FC7 +FCFFE7FE7FC7FC1714809318>I<01F0000FFE001FFF003E0F803803807001C07001C0E000E0E0 +00E0E000E0E000E0E000E0F001E07001C07803C03C07803E0F801FFF000FFE0001F00013147E93 +18>I<7E3E00FEFF807FFFC00FC1E00F80E00F00700E00700E00380E00380E00380E00380E0038 +0E00380F00700F00700F80E00FC1E00FFFC00EFF800E3E000E00000E00000E00000E00000E0000 +0E00000E00007FC000FFE0007FC000151E809318>I<01F38007FB801FFF803E1F80380F807007 +80700780E00380E00380E00380E00380E00380E00380700780700780380F803C1F801FFF800FFB +8003E380000380000380000380000380000380000380000380001FF0003FF8001FF0151E7E9318 +>II<07F7003FFF007FFF00 +780F00E00700E00700E007007C00007FE0001FFC0003FE00001F00600780E00380E00380F00380 +F80F00FFFF00FFFC00E7F00011147D9318>I<0180000380000380000380000380007FFFC0FFFF +C0FFFFC00380000380000380000380000380000380000380000380000380000380400380E00380 +E00380E001C1C001FFC000FF80003E0013197F9818>I<7E07E0FE0FE07E07E00E00E00E00E00E +00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E00E01E00F03E007FFFC03 +FFFE01FCFC1714809318>I<7F8FF0FF8FF87F8FF01C01C00E03800E03800E0380070700070700 +070700078F00038E00038E00038E0001DC0001DC0001DC0000F80000F80000700015147F9318> +II<7F8FF07F9FF07F8FF00F +0700078E00039E0001DC0001F80000F80000700000F00000F80001DC00039E00038E000707000E +07807F8FF0FF8FF87F8FF015147F9318>I<7F8FF0FF8FF87F8FF00E01C00E03800E0380070380 +070700070700038700038700038E0001CE0001CE0001CC0000CC0000DC00007800007800007800 +00700000700000700000F00000E00079E0007BC0007F80003F00001E0000151E7F9318>I<3FFF +F07FFFF07FFFF07001E07003C0700780000F00001E00003C0000F80001F00003C0000780000F00 +701E00703C0070780070FFFFF0FFFFF0FFFFF014147F9318>I<0007E0001FE0007FE000780000 +E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00001E0007FC000FF +8000FF80007FC00001E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000 +E00000E000007800007FE0001FE00007E013247E9F18>I<60F0F0F0F0F0F0F0F0F0F0F0F0F0F0 +F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0600424769F18>I<7C0000FF0000FFC00003C0 +0000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000F000007F +C0003FE0003FE0007FC000F00000E00000E00000E00000E00000E00000E00000E00000E00000E0 +0000E00000E00003C000FFC000FF00007C000013247E9F18>I E /Fm 46 +122 df<00003F000000000000FF800000000003E0C00000000007C060000000000F8070000000 +001F8030000000003F0038000000003F0038000000003F0038000000007F0038000000007F0038 +000000007F0070000000007F0060000000007F80E0000000007F80C0000000007F818000000000 +7F8300000000003F8600000000003FCC0000FFFE003FD80000FFFE003FF00000FFFE001FE00000 +0780001FE000000700001FF000000E00000FF000001C00000FF800001C00000FF800003800001F +FC000038000033FE000070000063FE0000E00001C1FF0000E00003C1FF8001C00007C0FF800380 +000F807FC00700001F807FE00700003F803FF00E00007F801FF81C00007F800FFC380000FF8007 +FC700000FF8003FEE00000FF8001FFC00000FFC000FF800000FFC0007FC0000E7FC0003FF0000E +7FE0007FF8001C3FF001F7FE003C1FF80FE1FF81F807FFFF807FFFF001FFFE001FFFC0003FE000 +01FE0037327DB13F>38 D45 +D<0001C0000003C000000FC000007FC0001FFFC000FFFFC000FFBFC000E03FC000003FC000003F +C000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC00000 +3FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000 +003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC0 +00003FC000003FC000003FC000003FC0007FFFFFF07FFFFFF07FFFFFF01C2E7AAD28>49 +D<003FE00001FFFE0007FFFF800F80FFC01E003FE038001FF07C000FF87E0007FCFF0007FCFF80 +07FEFF8007FEFF8003FEFF8003FE7F0003FE3E0007FE000007FE000007FC000007FC00000FF800 +000FF800000FF000001FE000001FC000003F8000007F0000007E000000F8000001F0000003E000 +0007C000000F0000001E000E003C000E0038000E0070001E00E0001C01C0001C0300003C07FFFF +FC0FFFFFFC1FFFFFFC3FFFFFFC7FFFFFF8FFFFFFF8FFFFFFF8FFFFFFF81F2E7CAD28>I<001FF8 +000000FFFF000003FFFFC00007E01FF0000F0007F8001F8007FC003FC007FC003FC003FE003FC0 +03FE003FC003FE003FC003FE001F8003FE000F0007FE00000007FC00000007FC00000007F80000 +000FF00000001FE00000003F80000000FF0000003FF80000003FFF800000001FE00000000FF000 +000007F800000003FC00000003FE00000001FF00000001FF00000001FF80000001FF80000001FF +801C0001FF803E0001FF807F0001FF80FF8001FF80FF8001FF00FF8001FF00FF8003FE007F0003 +FE007E0007FC003C0007F8001FC01FF0000FFFFFC00003FFFF0000003FF80000212E7DAD28>I< +0000007000000000F000000001F000000003F000000007F00000000FF00000000FF00000001FF0 +0000003FF000000077F0000000F7F0000000E7F0000001C7F000000387F000000707F000000F07 +F000000E07F000001C07F000003807F000007007F00000F007F00000E007F00001C007F0000380 +07F000070007F0000F0007F0000E0007F0001C0007F000380007F000700007F000E00007F000FF +FFFFFFE0FFFFFFFFE0FFFFFFFFE000000FF00000000FF00000000FF00000000FF00000000FF000 +00000FF00000000FF00000000FF00000000FF000000FFFFFE0000FFFFFE0000FFFFFE0232E7EAD +28>I<0C0000300FC007F00FFFFFE00FFFFFC00FFFFF800FFFFF000FFFFE000FFFF8000FFFF000 +0FFF80000E0000000E0000000E0000000E0000000E0000000E0000000E0000000E0000000E1FF0 +000EFFFE000FE03F800F000FC00E0007E00C0007F0000007F8000003F8000003FC000003FC0000 +03FE000003FE180003FE3E0003FE7F0003FEFF0003FEFF0003FEFF0003FCFF0003FCFE0003FC78 +0007F8780007F03C000FE01E001FC00FC07F8007FFFF0001FFFC00003FE0001F2E7CAD28>I<00 +00FF00000007FFE000001FFFF000007F80F80000FE003C0001F8007C0003F000FE0007F001FE00 +0FE001FE000FE001FE001FC001FE003FC000FC003FC00078003FC00000007F800000007F800000 +007F80000000FF83FC0000FF8FFF8000FF9C0FC000FFB003F000FFB001F800FFE001FC00FFC001 +FE00FFC000FE00FFC000FF00FFC000FF00FF8000FF80FF8000FF80FF8000FF80FF8000FF807F80 +00FF807F8000FF807F8000FF807F8000FF803F8000FF003FC000FF001FC000FF001FC000FE000F +C001FC0007E001FC0003F003F80001FC0FE00000FFFFC000003FFF0000000FFC0000212E7DAD28 +>I<38000000003E000000003FFFFFFFC03FFFFFFFC03FFFFFFFC03FFFFFFF807FFFFFFF007FFF +FFFE007FFFFFFC007FFFFFF80078000038007000007000700000E000F00001C000E000038000E0 +00070000E00007000000000E000000001C00000000380000000078000000007000000000F00000 +0001E000000001E000000003E000000003C000000007C000000007C00000000FC00000000FC000 +00001FC00000001F800000001F800000003F800000003F800000003F800000003F800000007F80 +0000007F800000007F800000007F800000007F800000007F800000007F800000007F800000003F +000000001E00000022307CAF28>I<000FFC0000007FFF800001FFFFE00003F00FF00007C003F8 +000F8000FC001F0000FC001F00007E003F00007E003F00007E003F00007E003F80007E003FC000 +7E003FF000FC003FFC00F8001FFE01F8001FFF81F0000FFFE3C00007FFFF800003FFFE000001FF +FF000000FFFFC000003FFFE00000FFFFF00003E3FFF80007C1FFFC000F807FFE001F001FFF003E +000FFF007E0003FF807E0000FF80FC00007F80FC00003F80FC00001F80FC00001F80FC00001F80 +FC00001F00FE00001F007E00001F007E00003E003F00007C001FC000F8000FF007F00003FFFFE0 +0000FFFF8000001FF80000212E7DAD28>I<000FF80000007FFF000001FFFF800003F80FC00007 +E007E0000FC003F0001FC001F8003FC001FC007F8001FC007F8001FE007F8000FE00FF8000FF00 +FF8000FF00FF8000FF00FF8000FF00FF8000FF80FF8000FF80FF8000FF80FF8000FF807F8001FF +807F8001FF803F8001FF803FC001FF801FC003FF800FC006FF8007E006FF8001F81CFF8000FFF8 +FF80001FE0FF80000000FF00000000FF00000000FF00000000FF000F0001FE001F8001FE003FC0 +01FC003FC001FC003FC003F8003FC003F0003F8007E0001F000FC0001E001F80000F807F000007 +FFFE000001FFF80000007FC00000212E7DAD28>I<0000007800000000000078000000000000FC +000000000000FC000000000000FC000000000001FE000000000001FE000000000003FF00000000 +0003FF000000000007FF800000000007FF800000000007FF80000000000FFFC0000000000E7FC0 +000000001E7FE0000000001C3FE0000000001C3FE000000000383FF000000000381FF000000000 +781FF800000000700FF800000000700FF800000000E00FFC00000000E007FC00000001E007FE00 +000001C003FE00000001C003FE000000038001FF000000038001FF000000078001FF8000000700 +00FF8000000F0000FFC000000FFFFFFFC000000FFFFFFFC000001FFFFFFFE000001C00003FE000 +003C00003FF000003800001FF000003800001FF000007000001FF800007000000FF80000F00000 +0FFC0000E0000007FC0000E0000007FC0001C0000007FE0003E0000003FE00FFFF0001FFFFFCFF +FF0001FFFFFCFFFF0001FFFFFC36317DB03D>65 D<000003FF80018000003FFFF003800001FFFF +FC07800007FF003F0F80001FF800079F80003FC00001FF8000FF800000FF8001FE0000007F8003 +FC0000003F8007FC0000001F8007F80000000F800FF00000000F801FF000000007801FF0000000 +07803FE000000007803FE000000003807FE000000003807FE000000003807FC000000000007FC0 +0000000000FFC00000000000FFC00000000000FFC00000000000FFC00000000000FFC000000000 +00FFC00000000000FFC00000000000FFC00000000000FFC000000000007FC000000000007FC000 +000000007FE000000000007FE000000003803FE000000003803FE000000003801FF00000000380 +1FF000000007800FF0000000070007F8000000070007FC0000000E0003FC0000001E0001FE0000 +001C0000FF8000007800003FC00000F000001FF80003E0000007FF003F80000001FFFFFE000000 +003FFFF80000000003FF80000031317CB03A>67 DIII73 D76 +DI<00000FFF0000000000FFFFF000000007FC03FE +0000001FE0007F8000003F80001FC000007F00000FE00001FE000007F80003FC000003FC0007F8 +000001FE0007F8000001FE000FF0000000FF001FF0000000FF801FE00000007F803FE00000007F +C03FE00000007FC03FE00000007FC07FC00000003FE07FC00000003FE07FC00000003FE0FFC000 +00003FF0FFC00000003FF0FFC00000003FF0FFC00000003FF0FFC00000003FF0FFC00000003FF0 +FFC00000003FF0FFC00000003FF0FFC00000003FF0FFC00000003FF0FFC00000003FF07FC00000 +003FE07FE00000007FE07FE00000007FE07FE00000007FE03FE00000007FC03FE00000007FC01F +F0000000FF801FF0000000FF800FF8000001FF0007F8000001FE0007FC000003FE0003FC000003 +FC0001FE000007F80000FF00000FF000003FC0003FC000001FE0007F80000007FC03FE00000000 +FFFFF0000000000FFF00000034317CB03D>79 DI82 D<001FF8018000FFFF038003FFFFC78007F007EF80 +0F8000FF801F00007F803E00001F803E00000F807C00000F807C00000780FC00000780FC000007 +80FC00000380FE00000380FE00000380FF00000000FFC00000007FF00000007FFF8000003FFFF8 +00003FFFFF80001FFFFFF0000FFFFFF80007FFFFFC0003FFFFFF0000FFFFFF00003FFFFF800001 +FFFFC000001FFFE0000001FFE00000003FE00000001FF00000000FF000000007F060000007F0E0 +000003F0E0000003F0E0000003F0E0000003E0F0000003E0F0000003E0F8000007C0FC000007C0 +FF00000F80FFC0001F00FBFC00FE00F1FFFFF800E03FFFF000C003FF800024317CB02D>I<7FFF +FFFFFFFF007FFFFFFFFFFF007FFFFFFFFFFF007FC00FF801FF007E000FF8003F007C000FF8001F +0078000FF8000F0078000FF8000F0070000FF8000700F0000FF8000780F0000FF8000780F0000F +F8000780E0000FF8000380E0000FF8000380E0000FF8000380E0000FF8000380E0000FF8000380 +00000FF800000000000FF800000000000FF800000000000FF800000000000FF800000000000FF8 +00000000000FF800000000000FF800000000000FF800000000000FF800000000000FF800000000 +000FF800000000000FF800000000000FF800000000000FF800000000000FF800000000000FF800 +000000000FF800000000000FF800000000000FF800000000000FF800000000000FF80000000000 +0FF800000000000FF800000000000FF800000000000FF800000000000FF800000000000FF80000 +00007FFFFFFF0000007FFFFFFF0000007FFFFFFF000031307DAF38>I<00FFF0000003FFFF0000 +0F803F80000FC00FE0001FE007F0001FE007F0001FE003F8000FC003FC00078003FC00000003FC +00000003FC00000003FC00000003FC000000FFFC00001FFFFC0000FFE3FC0003FC03FC000FF003 +FC001FC003FC003FC003FC007F8003FC007F8003FC00FF0003FC00FF0003FC00FF0003FC00FF00 +07FC00FF0007FC007F800DFC003FC01DFE001FE078FFF007FFE07FF000FF803FF024207E9F27> +97 D<01F8000000FFF8000000FFF8000000FFF80000000FF800000007F800000007F800000007 +F800000007F800000007F800000007F800000007F800000007F800000007F800000007F8000000 +07F800000007F800000007F800000007F83FE00007F8FFFC0007FBE07F0007FF001F8007FE000F +C007FC000FE007F80007F007F80007F807F80007F807F80003FC07F80003FC07F80003FC07F800 +03FE07F80003FE07F80003FE07F80003FE07F80003FE07F80003FE07F80003FE07F80003FE07F8 +0003FC07F80003FC07F80003FC07F80007F807F80007F807F80007F007FC000FE007FE000FC007 +E7003F8007C3C0FE000780FFF80007003FC00027327EB12D>I<000FFF00007FFFC001FC01F003 +F003F007E007F80FE007F81FC007F83FC003F03FC001E07F8000007F8000007F800000FF800000 +FF800000FF800000FF800000FF800000FF800000FF800000FF8000007F8000007F8000007F8000 +003FC0001C3FC0001C1FC000380FE0003807E0007003F001E001FC07C0007FFF00000FF8001E20 +7D9F24>I<0000000FC0000007FFC0000007FFC0000007FFC00000007FC00000003FC00000003F +C00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC0000000 +3FC00000003FC00000003FC00000003FC00007F83FC0003FFF3FC000FE07BFC003F801FFC007E0 +007FC00FE0007FC01FC0003FC03FC0003FC03FC0003FC07F80003FC07F80003FC07F80003FC0FF +80003FC0FF80003FC0FF80003FC0FF80003FC0FF80003FC0FF80003FC0FF80003FC0FF80003FC0 +7F80003FC07F80003FC07F80003FC03FC0003FC03FC0003FC01FC0003FC00FE0007FC007E000FF +C003F003FFE001FC0F3FFE007FFE3FFE000FF03FFE27327DB12D>I<000FFC00007FFF8001FC0F +C003F003E007E001F00FE001F81FC000FC3FC000FE3FC000FE7F80007E7F80007F7F80007FFF80 +007FFF80007FFFFFFFFFFFFFFFFFFF800000FF800000FF800000FF8000007F8000007F8000007F +8000003FC000071FC000071FC0000E0FE0000E07F0001C03F8007800FE03E0003FFFC00007FE00 +20207E9F25>I<0001FE00000FFF80001FC3C0007F07E000FE0FF001FE0FF001FC0FF003FC0FF0 +03FC07E003FC018003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC00 +00FFFFFC00FFFFFC00FFFFFC0003FC000003FC000003FC000003FC000003FC000003FC000003FC +000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003 +FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC0000 +7FFFF0007FFFF0007FFFF0001C327EB119>I<001FF007C000FFFE3FE001F83F79F007E00FC3F0 +0FE00FE1F00FC007E0E01FC007F0001FC007F0003FC007F8003FC007F8003FC007F8003FC007F8 +003FC007F8001FC007F0001FC007F0000FC007E0000FE00FE00007E00FC00003F83F000006FFFE +00000E1FF000000E000000001E000000001E000000001F000000001F800000001FFFFF80000FFF +FFF0000FFFFFFC0007FFFFFE0003FFFFFF0003FFFFFF800FFFFFFFC03F00007FC07E00001FE07C +00000FE0FC000007E0FC000007E0FC000007E0FC000007E07E00000FC03E00000F803F00001F80 +0FC0007E0007F803FC0001FFFFF000001FFF0000242F7E9F28>I<03C00007E0000FF0001FF800 +1FF8001FF8001FF8000FF00007E00003C000000000000000000000000000000000000000000000 +00000000000001F8007FF8007FF8007FF80007F80007F80007F80007F80007F80007F80007F800 +07F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F800 +07F80007F80007F80007F80007F800FFFF80FFFF80FFFF8011337DB217>105 +D<01F8000000FFF8000000FFF8000000FFF80000000FF800000007F800000007F800000007F800 +000007F800000007F800000007F800000007F800000007F800000007F800000007F800000007F8 +00000007F800000007F800000007F800FFF807F800FFF807F800FFF807F8003F0007F8003C0007 +F800780007F800F00007F803C00007F807800007F80F000007F81E000007F878000007F8FC0000 +07F9FE000007FBFE000007FFFF000007FE7F800007FC7FC00007F83FC00007F01FE00007F00FF0 +0007F00FF80007F007FC0007F003FC0007F001FE0007F000FF0007F000FF8007F0007F8007F000 +7FC0FFFF81FFFEFFFF81FFFEFFFF81FFFE27327EB12B>107 D<01F800FFF800FFF800FFF8000F +F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007 +F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007 +F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007 +F80007F80007F80007F800FFFFC0FFFFC0FFFFC012327DB117>I<03F007F8001FE000FFF03FFE +00FFF800FFF0783F01E0FC00FFF0C03F8300FE000FF1801FC6007F0007F3001FCC007F0007F600 +1FF8007F8007FC001FF0007F8007FC001FF0007F8007FC001FF0007F8007F8001FE0007F8007F8 +001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007 +F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F80 +07F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F +8007F8001FE0007F8007F8001FE0007F8007F8001FE0007F80FFFFC3FFFF0FFFFCFFFFC3FFFF0F +FFFCFFFFC3FFFF0FFFFC3E207D9F43>I<03F007F800FFF03FFE00FFF0783F00FFF0C03F800FF1 +801FC007F3001FC007F6001FE007FC001FE007FC001FE007FC001FE007F8001FE007F8001FE007 +F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE0 +07F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001F +E007F8001FE0FFFFC3FFFFFFFFC3FFFFFFFFC3FFFF28207D9F2D>I<0007FC0000007FFFC00001 +FC07F00003F001F80007E000FC000FC0007E001FC0007F003FC0007F803F80003F807F80003FC0 +7F80003FC07F80003FC0FF80003FE0FF80003FE0FF80003FE0FF80003FE0FF80003FE0FF80003F +E0FF80003FE0FF80003FE07F80003FC07F80003FC07F80003FC03FC0007F803FC0007F801FC000 +7F000FE000FE0007E000FC0003F803F80001FE0FF000007FFFC0000007FC000023207E9F28>I< +01F83FE000FFF8FFFC00FFFBE07F00FFFF003F8007FE001FC007FC000FE007F8000FF007F80007 +F807F80007F807F80007FC07F80003FC07F80003FC07F80003FE07F80003FE07F80003FE07F800 +03FE07F80003FE07F80003FE07F80003FE07F80003FE07F80003FC07F80007FC07F80007FC07F8 +0007F807F80007F807F8000FF007FC000FE007FE001FC007FF003F8007FBC0FE0007F8FFF80007 +F83FC00007F800000007F800000007F800000007F800000007F800000007F800000007F8000000 +07F800000007F800000007F800000007F8000000FFFFC00000FFFFC00000FFFFC00000272E7E9F +2D>I<03F03F00FFF07FC0FFF1C3E0FFF187E00FF30FF007F60FF007F60FF007FC07E007FC03C0 +07FC000007FC000007F8000007F8000007F8000007F8000007F8000007F8000007F8000007F800 +0007F8000007F8000007F8000007F8000007F8000007F8000007F8000007F8000007F8000007F8 +0000FFFFE000FFFFE000FFFFE0001C207E9F21>114 D<01FF860007FFFE001F00FE003C003E00 +78001E0078000E00F8000E00F8000E00F8000E00FC000000FF800000FFFC00007FFFC0003FFFF0 +003FFFF8001FFFFC0007FFFE0001FFFF00003FFF000000FF8000003F8060001F80E0000F80E000 +0F80F0000F80F0000F00F8000F00FC001E00FE001C00FF807800F3FFF000C07F800019207D9F20 +>I<001C0000001C0000001C0000001C0000001C0000003C0000003C0000003C0000007C000000 +7C000000FC000001FC000003FC000007FC00001FFFFE00FFFFFE00FFFFFE0003FC000003FC0000 +03FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC00 +0003FC000003FC000003FC000003FC000003FC038003FC038003FC038003FC038003FC038003FC +038003FC038001FC038001FC070000FE0700007F0E00003FFC000007F000192E7FAD1F>I<01F8 +0007E0FFF803FFE0FFF803FFE0FFF803FFE00FF8003FE007F8001FE007F8001FE007F8001FE007 +F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE0 +07F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001FE007F8001F +E007F8003FE007F8003FE003F8007FE003F8007FE001FC00DFF000FE039FFF007FFF1FFF000FFC +1FFF28207D9F2D>III<7FFF807FFC7FFF807FFC7FFF807FFC03FC000F0001FE +001E0000FF003C0000FF803800007FC07800003FC0F000001FE1E000000FF3C000000FFF800000 +07FF00000003FE00000001FE00000000FF00000000FF80000000FFC0000001FFC0000003DFE000 +00078FF00000078FF800000F07FC00001E03FE00003C01FE00007800FF0000F000FF8001E0007F +C003E0003FE0FFFC01FFFFFFFC01FFFFFFFC01FFFF28207F9F2B>II +E /Fn 2 16 df<0000FF00000007FFE000001F00F8000078001E0000E000070001800001800300 +0000C006000000600C000000300C000000301800000018300000000C300000000C600000000660 +0000000660000000066000000006C000000003C000000003C000000003C000000003C000000003 +C000000003C000000003C000000003C00000000360000000066000000006600000000660000000 +06300000000C300000000C18000000180C000000300C00000030060000006003000000C0018000 +018000E00007000078001E00001F00F8000007FFE0000000FF0000282B7EA02D>13 +D<03F0000FFC001FFE003FFF007FFF807FFF80FFFFC0FFFFC0FFFFC0FFFFC0FFFFC0FFFFC07FFF +807FFF803FFF001FFE000FFC0003F00012127E9317>15 D E /Fo 82 125 +df<001F83E000F06E3001C078780380F8780300F0300700700007007000070070000700700007 +0070000700700007007000FFFFFF80070070000700700007007000070070000700700007007000 +070070000700700007007000070070000700700007007000070070000700700007007000070070 +0007007000070070003FE3FF001D20809F1B>11 D<003F0000E0C001C0C00381E00701E00701E0 +070000070000070000070000070000070000FFFFE00700E00700E00700E00700E00700E00700E0 +0700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E03FC3FC +1620809F19>I<003FE000E0E001C1E00381E00700E00700E00700E00700E00700E00700E00700 +E00700E0FFFFE00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700 +E00700E00700E00700E00700E00700E00700E00700E03FE7FC1620809F19>I<001F81F80000F0 +4F040001C07C06000380F80F000300F00F000700F00F0007007000000700700000070070000007 +0070000007007000000700700000FFFFFFFF000700700700070070070007007007000700700700 +070070070007007007000700700700070070070007007007000700700700070070070007007007 +000700700700070070070007007007000700700700070070070007007007003FE3FE3FE0232080 +9F26>I<7038F87CFC7EFC7E743A0402040204020804080410081008201040200F0E7F9F17>34 +D<0078000000840000018400000302000007020000070200000702000007020000070400000704 +000007080000070800000390000003A00FFC03C001E003C000C001C0008001C0010002E0010004 +E00200087002001878040030380800703C0800701C1000F00E1000F00F2000F007C000F0038004 +7001C0047802E008380470181C183C3007E00FC01E227EA023>38 D<70F8FCFC74040404080810 +102040060E7C9F0D>I<0040008001000300060004000C00180018003800300030007000600060 +0060006000E000E000E000E000E000E000E000E000E000E000E000E00060006000600060007000 +300030003800180018000C000400060003000100008000400A2E7BA112>I<8000400020003000 +180008000C00060006000700030003000380018001800180018001C001C001C001C001C001C001 +C001C001C001C001C001C001800180018001800380030003000700060006000C00080018003000 +2000400080000A2E7EA112>I<70F0F8F878080808101010202040050E7C840D>44 +DI<70F8F8F87005057C840D>I<0000400000C000018000018000018000 +0300000300000300000600000600000C00000C00000C0000180000180000180000300000300000 +600000600000600000C00000C00000C00001800001800001800003000003000006000006000006 +00000C00000C00000C0000180000180000300000300000300000600000600000600000C00000C0 +0000122D7EA117>I<03F0000E1C001C0E00180600380700700380700380700380700380F003C0 +F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0700380 +7003807003807807803807001806001C0E000E1C0003F000121F7E9D17>I<008003800F80F380 +038003800380038003800380038003800380038003800380038003800380038003800380038003 +80038003800380038007C0FFFE0F1E7C9D17>I<03F0000C1C00100E00200700400780800780F0 +07C0F803C0F803C0F803C02007C00007C0000780000780000F00000E00001C0000380000700000 +600000C0000180000300000600400C00401800401000803FFF807FFF80FFFF80121E7E9D17>I< +03F0000C1C00100E00200F00780F80780780780780380F80000F80000F00000F00001E00001C00 +00700007F000003C00000E00000F000007800007800007C02007C0F807C0F807C0F807C0F00780 +400780400F00200E00183C0007F000121F7E9D17>I<000600000600000E00000E00001E00002E +00002E00004E00008E00008E00010E00020E00020E00040E00080E00080E00100E00200E00200E +00400E00C00E00FFFFF0000E00000E00000E00000E00000E00000E00000E0000FFE0141E7F9D17 +>I<1803001FFE001FFC001FF8001FE00010000010000010000010000010000010000011F00016 +1C00180E001007001007800003800003800003C00003C00003C07003C0F003C0F003C0E0038040 +0380400700200600100C0008380007E000121F7E9D17>I<007C000182000701000E03800C0780 +180780380300380000780000700000700000F1F000F21C00F40600F80700F80380F80380F003C0 +F003C0F003C0F003C0F003C07003C07003C07003803803803807001807000C0E00061C0001F000 +121F7E9D17>I<4000007FFFE07FFFC07FFFC04000808001008001008002000004000004000008 +0000100000100000200000200000600000600000E00000C00001C00001C00001C00001C00003C0 +0003C00003C00003C00003C00003C00003C000018000131F7E9D17>I<03F0000C0C0010060030 +03002001806001806001806001807001807803003E03003F06001FC8000FF00003F80007FC000C +7E00103F00300F806007806001C0C001C0C000C0C000C0C000C0C000806001802001001002000C +0C0003F000121F7E9D17>I<03F0000E18001C0C00380600380700700700700380F00380F00380 +F003C0F003C0F003C0F003C0F003C07007C07007C03807C0180BC00E13C003E3C0000380000380 +000380000700300700780600780E00700C002018001070000FC000121F7E9D17>I<70F8F8F870 +0000000000000000000070F8F8F87005147C930D>I<70F8F8F8700000000000000000000070F0 +F8F878080808101010202040051D7C930D>I<000100000003800000038000000380000007C000 +0007C0000007C0000009E0000009E0000009E0000010F0000010F0000010F00000207800002078 +000020780000403C0000403C0000C03E0000801E0000801E0001FFFF0001000F0001000F000200 +07800200078002000780040003C0040003C00C0003C01E0003E0FF801FFE1F207F9F22>65 +DI<000FE01000381C3000E0027003C00170078000F00F000070 +1E0000701E0000303C0000303C0000107C00001078000010F8000000F8000000F8000000F80000 +00F8000000F8000000F8000000F8000000F8000000780000007C0000103C0000103C0000101E00 +00201E0000200F0000200780004003C0008000E0030000380C00000FF0001C217E9F21>III +I<000FE01000381C3000E0027003C00170078000F00F0000701E0000701E0000303C0000303C00 +00107C00001078000010F8000000F8000000F8000000F8000000F8000000F8000000F8000000F8 +003FFEF80001F0780000F07C0000F03C0000F03C0000F01E0000F01E0000F00F0000F0078000F0 +03C0017000E0023000380C10000FF0001F217E9F24>III<07FFC0003E00001E00001E +00001E00001E00001E00001E00001E00001E00001E00001E00001E00001E00001E00001E00001E +00001E00001E00001E00001E00001E00001E00201E00F81E00F81E00F81E00F01C00403C006038 +001070000FC00012207F9E17>IIIII<001FE00000703800 +01C00E0003800700070003800F0003C01E0001E03C0000F03C0000F07C0000F87C0000F8780000 +78F800007CF800007CF800007CF800007CF800007CF800007CF800007CF800007CF800007C7800 +00787C0000F87C0000F83C0000F03E0001F01E0001E00F0003C0070003800380070001E01E0000 +703800001FE0001E217E9F23>II<001FE0000070380001C00E +0003800700070003800F0003C01E0001E03E0001F03C0000F07C0000F87C0000F878000078F800 +007CF800007CF800007CF800007CF800007CF800007CF800007CF800007CF800007C780000787C +0000F87C0000F83C0000F03E0781F01E0841E00F1023C0071023800390170001D01E0000783804 +001FF80400001C0400000C0C00000E1C00000FF800000FF8000007F8000007F0000001E01E297E +9F23>II<03F0400C0CC01803C03001C06000C06000 +C0E000C0E00040E00040E00040F00000F800007C00007F80003FF8001FFF0007FF8000FFC0001F +E00003E00001E00000F0000070800070800070800070800070C00060C000E0E000C0F80180C603 +0081FC0014217E9F19>I<7FFFFFE0780F01E0600F0060400F0020400F0020C00F0030800F0010 +800F0010800F0010800F0010000F0000000F0000000F0000000F0000000F0000000F0000000F00 +00000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F +0000000F0000000F0000001F800003FFFC001C1F7E9E21>IIII<7FF81FF80FE007C007C0030003 +C0020003E0060001F0040000F0080000F8180000781000003C2000003E6000001E4000000F8000 +000F8000000780000003C0000007E0000005E0000008F0000018F8000010780000207C0000603E +0000401E0000801F0001000F8001000780020007C0060003C01F0007E0FFC01FFE1F1F7F9E22> +II91 D<08041008201020104020 +4020804080408040B85CFC7EFC7E7C3E381C0F0E7A9F17>II<08 +1020204040808080B8FCFC7C38060E7D9F0D>96 D<1FE000303000781800781C00300E00000E00 +000E00000E0000FE00078E001E0E00380E00780E00F00E10F00E10F00E10F01E10781E10386720 +0F83C014147E9317>I<1C0000FC00001C00001C00001C00001C00001C00001C00001C00001C00 +001C00001C00001C7C001D87001E01801E00C01C00E01C00701C00701C00781C00781C00781C00 +781C00781C00781C00701C00F01C00E01E00C01A0180198700107C0015207E9F19>I<01FC0007 +06001C0F00380F00380600780000700000F00000F00000F00000F00000F00000F0000070000078 +00003800803800801C010007060001F80011147F9314>I<0001C0000FC00001C00001C00001C0 +0001C00001C00001C00001C00001C00001C00001C001F1C0070DC00C03C01801C03801C07801C0 +7001C0F001C0F001C0F001C0F001C0F001C0F001C07001C07001C03801C01803C00C03C0070DC0 +01F1F815207F9F19>I<03F0000E1C001C0E00380700380700700700700380F00380F00380FFFF +80F00000F00000F000007000007000003800803800801C010007060001F80011147F9314>I<00 +7C01C6030F070F0E060E000E000E000E000E000E000E00FFF00E000E000E000E000E000E000E00 +0E000E000E000E000E000E000E000E000E000E000E007FE01020809F0E>I<0000E003E3300E3C +301C1C30380E00780F00780F00780F00780F00780F00380E001C1C001E380033E0002000002000 +003000003000003FFE001FFF801FFFC03001E0600070C00030C00030C00030C000306000603000 +C01C038003FC00141F7F9417>I<1C0000FC00001C00001C00001C00001C00001C00001C00001C +00001C00001C00001C00001C7C001C86001D03001E03801E03801C03801C03801C03801C03801C +03801C03801C03801C03801C03801C03801C03801C03801C03801C0380FF8FF014207E9F19>I< +38007C007C007C0038000000000000000000000000001C00FC001C001C001C001C001C001C001C +001C001C001C001C001C001C001C001C001C001C00FF80091F7F9E0C>I<00E001F001F001F000 +E0000000000000000000000000007007F000F00070007000700070007000700070007000700070 +007000700070007000700070007000700070007000706070F060F0C061803F000C28829E0E>I< +1C0000FC00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C1FE0 +1C07801C06001C04001C08001C10001C20001C60001CE0001DF0001E70001C38001C3C001C1C00 +1C0E001C0F001C07001C07801C07C0FF9FF014207E9F18>I<1C00FC001C001C001C001C001C00 +1C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C +001C001C001C001C00FF8009207F9F0C>I<1C3E03E000FCC30C30001D039038001E01E01C001E +01E01C001C01C01C001C01C01C001C01C01C001C01C01C001C01C01C001C01C01C001C01C01C00 +1C01C01C001C01C01C001C01C01C001C01C01C001C01C01C001C01C01C001C01C01C00FF8FF8FF +8021147E9326>I<1C7C00FC86001D03001E03801E03801C03801C03801C03801C03801C03801C +03801C03801C03801C03801C03801C03801C03801C03801C0380FF8FF014147E9319>I<01F800 +070E001C03803801C03801C07000E07000E0F000F0F000F0F000F0F000F0F000F0F000F07000E0 +7000E03801C03801C01C0380070E0001F80014147F9317>I<1C7C00FD87001E01801E01C01C00 +E01C00F01C00701C00781C00781C00781C00781C00781C00781C00701C00F01C00E01E01C01E03 +801D87001C7C001C00001C00001C00001C00001C00001C00001C00001C0000FF8000151D7E9319 +>I<01F040070CC00E02C01C03C03801C07801C07001C0F001C0F001C0F001C0F001C0F001C0F0 +01C07001C07801C03801C01C03C00C05C00709C001F1C00001C00001C00001C00001C00001C000 +01C00001C00001C0000FF8151D7F9318>I<1CF0FD181E3C1E3C1E181C001C001C001C001C001C +001C001C001C001C001C001C001C001C00FFC00E147E9312>I<0FC830386018C008C008C008E0 +007C003FE01FF007F8003C800E8006C006C006C004E00CD81887E00F147F9312>I<0200020002 +00060006000E000E003E00FFF80E000E000E000E000E000E000E000E000E000E000E000E040E04 +0E040E040E040708030801F00E1C7F9B12>I<1C0380FC1F801C03801C03801C03801C03801C03 +801C03801C03801C03801C03801C03801C03801C03801C03801C03801C07800C0780061B8003E3 +F014147E9319>IIIII<7FFF700E600E401C40384078407000E001E001C00380078007010E01 +1E011C0338027006700EFFFE10147F9314>III E /Fp 41 123 df<0003F07C001E0DC600380F0F00701E0F00E01E0E00E00C0001C01C0001 +C01C0001C01C0001C01C0001C01C00038038007FFFFFC003803800038038000380380003803800 +0700700007007000070070000700700007007000070070000E00E0000E00E0000E00E0000E00E0 +000E00E0000E00E0001C01C0001E01E000FF8FFC0020207E9F1B>11 D<0003E0001C1800381800 +703C00E03C00E03801C00001C00001C00001C00001C0000380007FFFF003807003807003807003 +80700700E00700E00700E00700E00700E00700E00E01C00E01C00E01C00E01C00E01C00E01C01C +03801E03C0FF0FF016207E9F19>I<0006000C00100030006000C0008001800300030006000E00 +0C000C0018001800380038003000300070007000600060006000E000E000E000E000E000E000E0 +00E00060006000600060006000300030001000180008000C00040002000F2E7AA112>40 +D<008000C00040002000300030001800180018000C000C000C000C000C000C000C000C000C000C +000C000C000C001C001C001C0018001800380038003000300070006000E000C000C00180010003 +0006000400080018003000400080000E2E80A112>I45 +D<3078F8787005057C840D>I<0018003801F80E700070007000700070007000E000E000E000E0 +00E000E001C001C001C001C001C001C003800380038003800380038007000780FFFC0E1E7B9D17 +>49 D<1FFFFFFE3FFFFFFF00000000000000000000000000000000000000000000000000000000 +00000000FFFFFFFC7FFFFFF8200C7D9023>61 D<0000080000000C0000001C0000003C0000003C +0000007C0000007E0000009E0000009E0000011E0000011E0000021E0000020F0000040F000004 +0F0000080F0000080F0000100F80001007800020078000200780007FFF80004007C0008003C000 +8003C0010003C0010003C0020003C0020001E0060001E01F0003E0FF801FFE1F207F9F22>65 +D<07FFFFF800F80078007800380078001800F0001800F0000800F0000800F0000800F0000800F0 +000801E0080001E0080001E0080001E0180001E0380001FFF80003C0300003C0100003C0100003 +C0100003C0100003C000000780000007800000078000000780000007800000078000000F000000 +0F800000FFFC00001D1F7E9E1E>70 D<07FF83FFC000F8007C000078003C000078003C0000F000 +780000F000780000F000780000F000780000F000780000F000780001E000F00001E000F00001E0 +00F00001E000F00001FFFFF00001E000F00003C001E00003C001E00003C001E00003C001E00003 +C001E00003C001E000078003C000078003C000078003C000078003C000078003C000078003C000 +0F000780000F8007C000FFF07FF800221F7E9E22>72 D<07FF8000F80000780000780000F00000 +F00000F00000F00000F00000F00001E00001E00001E00001E00001E00001E00003C00003C00003 +C00003C00003C00003C0000780000780000780000780000780000780000F00000F8000FFF00011 +1F7E9E10>I<07F8007FC0007C001F00007C000C00005E000400009E000800008F000800008F00 +0800008780080000878008000083C008000103C010000101E010000101E010000100F010000100 +F010000100781000020078200002003C200002003C200002001E200002001E200002000F200004 +000F4000040007C000040007C000040003C000040003C000040001C0000C000180001E00008000 +FF80008000221F7E9E22>78 D<001F8200706600C01E01800E03000E07000C0600040E00040E00 +040E00040F00000F00000F800007F00007FF0003FFC001FFE0003FF00003F80000F80000780000 +3C00003C400038400038400038400030600070600060F000C0E80180C6030081FC0017217E9F19 +>83 D<00FF01FE0180018001800180018003000300030003000300030006000600060006000600 +06000C000C000C000C000C000C0018001800180018001800180030003000300030003000300060 +0060006000600060006000FF00FF00102D7EA10D>91 D<00FF01FE00060006000600060006000C +000C000C000C000C000C0018001800180018001800180030003000300030003000300060006000 +6000600060006000C000C000C000C000C000C0018001800180018001800180FF00FF00102D82A1 +0D>93 D<07F8000C0C001E06001E07001C070000070000070000070000FF0007C7001E07003C0E +00780E00F00E10F00E10F00E10F01E10F02E20784F401F878014147D9317>97 +D<0700003F00000F00000700000700000E00000E00000E00000E00000E00000E00001C00001C7C +001D83001E01801C01C01C00E03800E03800F03800F03800F03800F03800F07001E07001E07001 +C07003C0700380700700E80E00CC380083E00014207B9F19>I<00FE000383000E07801C078038 +0700380000780000F00000F00000F00000F00000E00000E00000E00000F00000F0010070020038 +04001C180007E00011147D9314>I<0000380001F8000078000038000038000070000070000070 +0000700000700000700000E000FCE00382E00601E01C01E03C00E03801C07801C0F001C0F001C0 +F001C0F001C0E00380E00380E00380E00380F00380700780380F001C378007C7E015207D9F19> +I<00F800070E000E07001C0700380380780380700380F00380F00380FFFF80F00000E00000E000 +00E00000E00000F001007002003004001C180007E00011147D9314>I<0007C0001C600030F000 +60F000E0E000C00001C00001C00001C00001C00001C0000380003FFC0003800003800003800003 +80000700000700000700000700000700000700000E00000E00000E00000E00000E00000E00001C +00001E0000FFC00014207F9F0E>I<00000E003E1100E1A301C1C20381E00780E00701E00F01E0 +0F01E00F01E00703C007038007870004FC000800000800001800001C00000FFF000FFFC00FFFE0 +1800F0300030600030C00030C00030C000306000603000C01C070007FC00181F809417>I<00E0 +0007E00001E00000E00000E00001C00001C00001C00001C00001C00001C000038000038F800390 +E003A0E003C0600380600780E00700E00700E00700E00700E00700E00E01C00E01C00E01C00E01 +C00E01C00E01C01C03801E03C0FF8FF014207E9F19>I<01C003E003E003C00180000000000000 +00000000000003801F800780038003800700070007000700070007000E000E000E000E000E000E +001C001E00FF800B1F7F9E0C>I<00E00007E00001E00000E00000E00001C00001C00001C00001 +C00001C00001C0000380000381FC0380F00380C003818003810007040007080007180007380007 +7C00071C000E1C000E0E000E0E000E0F000E07000E07801C03801E07C0FF8FF016207E9F18> +107 D<00E007E001E000E000E001C001C001C001C001C001C00380038003800380038003800700 +070007000700070007000E000E000E000E000E000E001C001E00FF800B207F9F0C>I<0387C07C +001F9861860007A072070003C03403000380380300078078070007007007000700700700070070 +0700070070070007007007000E00E00E000E00E00E000E00E00E000E00E00E000E00E00E000E00 +E00E001C01C01C001E01E01E00FFCFFCFFC022147E9326>I<038F801F90E007A0E003C0600380 +600780E00700E00700E00700E00700E00700E00E01C00E01C00E01C00E01C00E01C00E01C01C03 +801E03C0FF8FF014147E9319>I<00FC000387000E01801C00C03800E03800E07000F0F000F0F0 +00F0F000F0F000F0E001E0E001E0E001C0E003C0F00380700700380E001C1C0007E00014147D93 +17>I<00E3E00007EC380000F01C0000E00E0000E00F0001C0070001C0078001C0078001C00780 +01C0078001C0078003800F0003800F0003800E0003801E0003801C0003803800074070000761C0 +00071F00000700000007000000070000000E0000000E0000000E0000000E0000001E000000FFC0 +0000191D809319>I<00FC200382600702601E01E03C01E03801C07801C0F001C0F001C0F001C0 +F001C0E00380E00380F00380F00380F00780700780380F001C370007C700000700000700000700 +000E00000E00000E00000E00001E0000FFC0131D7D9318>I<038E001FB38007C78003C7800383 +000780000700000700000700000700000700000E00000E00000E00000E00000E00000E00001C00 +001E0000FFC00011147E9312>I<01F9060708031803180138023C001F001FF007FC01FE001F40 +074003400360036006F004C81887E010147F9312>I<0080010001000100030007000F001E00FF +F80E000E000E000E001C001C001C001C001C001C00380038103810381038103820382018400F80 +0D1C7C9B12>I<1C0380FC1F803C07801C03801C03803807003807003807003807003807003807 +00700E00700E00700E00700E00701E00701E00703C00305E001F9F8011147B9319>III<1FF0FF03C078 +01C07001C04000E0C000E180007300007600003C00003C00001C00002E00004E00008700010700 +0203800403800C01C03C03E0FE07FC18147F9318>I<0FF83F8001E00E0001C00C0001C0080001 +E0080000E0100000E0300000E0200000E040000070400000708000007080000071000000390000 +003A0000003E0000003C0000003800000018000000100000001000000020000000200000004000 +0070C00000F0800000F1000000E600000078000000191D809318>I<0FFFE00E01E00C01C00803 +80080700100E00101C0000380000700000700000E00001C0000380800700800E00801C01001C01 +00380300700E00FFFE0013147F9314>I E /Fq 63 122 df<0001FF0000001FFFC000007F81E0 +0000FC01E00001F807F00003F807F00007F007F00007F007F00007F007F00007F007F00007F001 +C00007F000000007F000000007F000000007F03FF800FFFFFFF800FFFFFFF800FFFFFFF80007F0 +03F80007F003F80007F003F80007F003F80007F003F80007F003F80007F003F80007F003F80007 +F003F80007F003F80007F003F80007F003F80007F003F80007F003F80007F003F80007F003F800 +07F003F80007F003F80007F003F80007F003F80007F003F8007FFF3FFF807FFF3FFF807FFF3FFF +80212A7FA925>12 D<0003F0000000000FF8000000001F1C000000003C0E000000007C06000000 +00FC0700000000F80700000001F80700000001F80700000001F80600000001F80E00000001FC0C +00000001FC1800000001FC3800000001FC3000000000FE6000FFF800FEC000FFF800FF8000FFF8 +00FF00000E00007F00000E00007F00001C00007F80003800007FC000380000FFC0007000019FE0 +00E000038FE000E000070FF001C0000F07F80380001E07FC0380003E03FE0700007E01FE0E0000 +FE00FF1C0000FE007FB80000FE003FF00000FE001FE00000FF000FF000707F0007F800707F801F +FE00E03FC0FEFF83E01FFFF87FFFC007FFE00FFF8000FF0001FE002D2A7DA934>38 +D<3C007F00FF80FF80FFC0FFC0FFC07FC03EC000C000C00180018001800300030006000E001C00 +380010000A157BA913>I<0006000C00180038007000E001E003C003C0078007800F800F001F00 +1F003E003E003E007E007E007E007C007C00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC00FC +00FC00FC00FC007C007C007E007E007E003E003E003E001F001F000F000F800780078003C003C0 +01E000E0007000380018000C00060F3C7AAC1A>II45 D<1C007F007F00FF80FF80FF807F007F001C0009097B +8813>I<003F800001FFF00007E0FC000FC07E001F803F001F001F003F001F803E000F807E000F +C07E000FC07E000FC07E000FC0FE000FE0FE000FE0FE000FE0FE000FE0FE000FE0FE000FE0FE00 +0FE0FE000FE0FE000FE0FE000FE0FE000FE0FE000FE0FE000FE0FE000FE0FE000FE07E000FC07E +000FC07E000FC07E000FC03F001F803F001F801F001F001F803F000FC07E0007E0FC0001FFF000 +003F80001B277DA622>48 D<000E00001E00007E0007FE00FFFE00FFFE00F8FE0000FE0000FE00 +00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE00 +00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE00 +00FE00FFFFFEFFFFFEFFFFFE17277BA622>I<00FF800007FFF0000FFFFC001E03FE003800FF80 +7C003F80FE003FC0FF001FC0FF001FE0FF000FE0FF000FE07E000FE03C001FE000001FE000001F +C000001FC000003F8000003F0000007E000000FC000000F8000001F0000003E00000078000000F +0000001E0000003C00E0007000E000E000E001C001C0038001C0060001C00FFFFFC01FFFFFC03F +FFFFC07FFFFFC0FFFFFF80FFFFFF80FFFFFF801B277DA622>I<007F800003FFF00007FFFC000F +81FE001F007F003F807F003F803F803F803F803F803F801F803F801F003F8000007F0000007F00 +00007E000000FC000001F8000007F00000FFC00000FFC0000001F80000007E0000003F0000003F +8000001FC000001FC000001FE000001FE03C001FE07E001FE0FF001FE0FF001FE0FF001FC0FF00 +3FC0FE003F807C007F003F01FE001FFFFC0007FFF00000FF80001B277DA622>I<00000F000000 +0F0000001F0000003F0000007F000000FF000001FF000001FF000003BF0000073F00000E3F0000 +1C3F00003C3F0000383F0000703F0000E03F0001C03F0003803F0007803F0007003F000E003F00 +1C003F0038003F0070003F00F0003F00FFFFFFF8FFFFFFF8FFFFFFF800007F0000007F0000007F +0000007F0000007F0000007F0000007F0000007F00001FFFF8001FFFF8001FFFF81D277EA622> +I<180003001F801F001FFFFE001FFFFC001FFFF8001FFFF0001FFFC0001FFF00001C0000001C00 +00001C0000001C0000001C0000001C0000001C0000001C7FC0001DFFF8001F80FC001E003F0008 +003F0000001F8000001FC000001FC000001FE000001FE018001FE07C001FE0FE001FE0FE001FE0 +FE001FE0FE001FC0FC001FC078003F8078003F803C007F001F01FE000FFFFC0003FFF00000FF80 +001B277DA622>I<0007F800003FFE0000FFFF0001FC078003F00FC007C01FC00F801FC01F801F +C01F001FC03F000F803F0000007E0000007E0000007E000000FE020000FE1FF000FE3FFC00FE60 +3E00FE801F00FF801F80FF000FC0FF000FC0FE000FE0FE000FE0FE000FE0FE000FE07E000FE07E +000FE07E000FE07E000FE03E000FE03F000FC01F000FC01F001F800F801F0007E07E0003FFFC00 +01FFF800003FC0001B277DA622>I<380000003E0000003FFFFFF03FFFFFF03FFFFFF07FFFFFE0 +7FFFFFC07FFFFF807FFFFF0070000E0070000E0070001C00E0003800E0007000E000E0000001C0 +000001C000000380000007800000070000000F0000001F0000001E0000003E0000003E0000007E +0000007C0000007C000000FC000000FC000000FC000000FC000001FC000001FC000001FC000001 +FC000001FC000001FC000001FC000000F80000007000001C297CA822>I<003FC00001FFF00003 +FFFC0007C07E000F003F001E001F001E000F803E000F803E000F803F000F803F800F803FC00F00 +3FF01F001FFC1E001FFE3C000FFFF80007FFE00003FFF00001FFFC0001FFFE0007FFFF000F0FFF +801E07FFC03E01FFC07C007FE07C001FE0F8000FE0F80007E0F80003E0F80003E0F80003E0F800 +03C07C0003C07E0007803F000F001FC03F000FFFFC0003FFF800007FC0001B277DA622>I<007F +800001FFF00007FFF8000FC0FC001F803E003F001F007E001F807E001F807E000F80FE000FC0FE +000FC0FE000FC0FE000FE0FE000FE0FE000FE0FE000FE0FE000FE07E001FE07E001FE03F003FE0 +1F002FE00F80CFE007FF8FE001FF0FE000080FE000000FC000000FC000000FC000001F803E001F +807F001F807F003F007F003E007F007E007E00FC003E03F8001FFFE0000FFF800001FE00001B27 +7DA622>I<00000780000000000780000000000FC0000000000FC0000000000FC0000000001FE0 +000000001FE0000000003FF0000000003FF0000000003FF00000000077F80000000077F8000000 +00F7FC00000000E3FC00000000E3FC00000001C1FE00000001C1FE00000003C1FF0000000380FF +0000000380FF00000007007F80000007007F8000000F007FC000000E003FC000000E003FC00000 +1C001FE000001C001FE000003FFFFFF000003FFFFFF000003FFFFFF00000700007F80000700007 +F80000F00007FC0000E00003FC0001E00003FE0001C00001FE0001C00001FE0003C00001FF00FF +FE003FFFFCFFFE003FFFFCFFFE003FFFFC2E297EA833>65 DI<00007FE0030007FFFC07001FFFFF0F007FF00F9F00FF0001FF01FC0000FF03F800007F07 +F000003F0FE000001F1FC000001F1FC000000F3F8000000F3F800000077F800000077F80000007 +7F00000000FF00000000FF00000000FF00000000FF00000000FF00000000FF00000000FF000000 +00FF00000000FF000000007F000000007F800000007F800000073F800000073F800000071FC000 +00071FC000000E0FE000000E07F000001C03F800003C01FC00007800FF0001F0007FF007C0001F +FFFF800007FFFE0000007FF00028297CA831>II< +FFFFFFFFE0FFFFFFFFE0FFFFFFFFE003FC001FE003FC0007F003FC0001F003FC0001F003FC0000 +F003FC00007003FC00007003FC00007003FC01C07803FC01C03803FC01C03803FC01C03803FC03 +C00003FC03C00003FC0FC00003FFFFC00003FFFFC00003FFFFC00003FC0FC00003FC03C00003FC +03C00003FC01C00E03FC01C00E03FC01C00E03FC01C01C03FC00001C03FC00001C03FC00001C03 +FC00003C03FC00003803FC00007803FC0000F803FC0001F803FC0003F803FC001FF8FFFFFFFFF0 +FFFFFFFFF0FFFFFFFFF027297EA82C>II<00007FE003 +000007FFFC0700001FFFFF0F00007FF00F9F0000FF0001FF0001FC0000FF0003F800007F0007F0 +00003F000FE000001F001FC000001F001FC000000F003F8000000F003F80000007007F80000007 +007F80000007007F0000000000FF0000000000FF0000000000FF0000000000FF0000000000FF00 +00000000FF0000000000FF0000000000FF0000000000FF0000FFFFF87F0000FFFFF87F8000FFFF +F87F800000FF003F800000FF003F800000FF001FC00000FF001FC00000FF000FE00000FF0007F0 +0000FF0003F80000FF0001FC0000FF0000FF0001FF00007FF007FF00001FFFFF9F000007FFFE0F +0000007FF003002D297CA835>III<00FFFFF800FFFFF800FFFFF80000FF000000FF000000FF000000FF000000FF00 +0000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF +000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000 +FF000000FF000000FF001800FF007E00FF00FF00FF00FF00FF00FF00FF00FF00FE007E01FC007C +01F8003E07F0000FFFE00003FF00001D297EA823>IIIII<0000FFC00000000FFFFC0000003F807F00 +0000FE001FC00001F80007E00003F00003F00007E00001F8000FE00001FC001FC00000FE001FC0 +0000FE003F8000007F003F8000007F007F8000007F807F0000003F807F0000003F807F0000003F +80FF0000003FC0FF0000003FC0FF0000003FC0FF0000003FC0FF0000003FC0FF0000003FC0FF00 +00003FC0FF0000003FC0FF0000003FC0FF0000003FC07F0000003F807F8000007F807F8000007F +803F8000007F003F8000007F001FC00000FE001FC00000FE000FE00001FC0007F00003F80003F8 +0007F00001FC000FE00000FE001FC000003FC0FF0000000FFFFC00000000FFC000002A297CA833 +>II82 +D<00FF806003FFF0E00FFFF8E01F80FDE03F001FE03E0007E07C0003E07C0003E0FC0001E0FC00 +01E0FC0000E0FE0000E0FE0000E0FF000000FFC000007FFC00007FFFE0003FFFF8001FFFFE001F +FFFF0007FFFF8003FFFFC000FFFFC0000FFFE000007FE000001FF000000FF0000007F0E00003F0 +E00003F0E00003F0E00003F0F00003E0F00003E0F80007E0FC0007C0FF000F80FFE03F80E3FFFE +00E1FFFC00C01FF0001C297CA825>I<7FFFFFFFFF807FFFFFFFFF807FFFFFFFFF807F807F807F +807C007F800F8078007F80078078007F80078070007F800380F0007F8003C0F0007F8003C0E000 +7F8001C0E0007F8001C0E0007F8001C0E0007F8001C0E0007F8001C000007F80000000007F8000 +0000007F80000000007F80000000007F80000000007F80000000007F80000000007F8000000000 +7F80000000007F80000000007F80000000007F80000000007F80000000007F80000000007F8000 +0000007F80000000007F80000000007F80000000007F80000000007F80000000007F8000000000 +7F80000000FFFFFFC00000FFFFFFC00000FFFFFFC0002A287EA72F>IIII<020007000E001C00180030003000600060006000C000C000DF +00FF80FFC0FFC0FFC07FC07FC03F800F000A157CA913>96 D<03FF80000FFFF0001F01FC003F80 +FE003F807F003F803F003F803F801F003F8000003F8000003F8000003F8000003F80003FFF8001 +FC3F800FE03F801F803F803F003F807E003F80FC003F80FC003F80FC003F80FC003F80FC005F80 +7E00DF803F839FFC1FFE0FFC03FC03FC1E1B7E9A21>II<003FF00001FFFC0003F03E000FC07F001F807F003F007F003F007F007F003E007E000000 +7E000000FE000000FE000000FE000000FE000000FE000000FE000000FE0000007E0000007E0000 +007F0000003F0003803F8003801F8007000FE00E0003F83C0001FFF800003FC000191B7E9A1E> +I<00007FF000007FF000007FF0000007F0000007F0000007F0000007F0000007F0000007F00000 +07F0000007F0000007F0000007F0000007F0000007F0003F87F001FFF7F007F03FF00FC00FF01F +8007F03F0007F03F0007F07E0007F07E0007F07E0007F0FE0007F0FE0007F0FE0007F0FE0007F0 +FE0007F0FE0007F0FE0007F0FE0007F07E0007F07E0007F03F0007F03F0007F01F800FF00FC01F +F007E07FFF01FFE7FF007F87FF202A7EA925>I<003FC00001FFF00003E07C000F803E001F801F +001F001F003F000F807E000F807E000FC07E000FC0FE0007C0FE0007C0FFFFFFC0FFFFFFC0FE00 +0000FE000000FE0000007E0000007E0000007F0000003F0001C01F0001C00F80038007C0070003 +F01E0000FFFC00003FE0001A1B7E9A1F>I<0007F8003FFC007E3E01FC7F03F87F03F07F07F07F +07F03E07F00007F00007F00007F00007F00007F00007F000FFFFC0FFFFC0FFFFC007F00007F000 +07F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F000 +07F00007F00007F00007F00007F00007F0007FFF807FFF807FFF80182A7EA915>I<00FF80F003 +FFE3F80FC1FE1C1F007C7C3F007E7C3E003E107E003F007E003F007E003F007E003F007E003F00 +7E003F003E003E003F007E001F007C000FC1F8000BFFE00018FF80001800000038000000380000 +003C0000003FFFF8003FFFFF001FFFFFC00FFFFFE007FFFFF01FFFFFF03C0007F07C0001F8F800 +00F8F80000F8F80000F8F80000F87C0001F07C0001F03F0007E00FC01F8007FFFF00007FF0001E +287E9A22>II<07000F801FC03FE03FE03FE01FC0 +0F8007000000000000000000000000000000FFE0FFE0FFE00FE00FE00FE00FE00FE00FE00FE00F +E00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE0FFFEFFFEFFFE0F2B7EAA12> +I107 DIII<003FE00001 +FFFC0003F07E000FC01F801F800FC03F0007E03F0007E07E0003F07E0003F07E0003F0FE0003F8 +FE0003F8FE0003F8FE0003F8FE0003F8FE0003F8FE0003F8FE0003F87E0003F07E0003F03F0007 +E03F0007E01F800FC00FC01F8007F07F0001FFFC00003FE0001D1B7E9A22>II< +FFC1F0FFC7FCFFC63E0FCC7F0FD87F0FD07F0FD07F0FF03E0FE0000FE0000FE0000FE0000FE000 +0FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE000FFFF00FFFF00 +FFFF00181B7F9A1B>114 D<03FE300FFFF03E03F07800F07000F0F00070F00070F80070FE0000 +FFE0007FFF007FFFC03FFFE01FFFF007FFF800FFF80007FC0000FCE0007CE0003CF0003CF00038 +F80038FC0070FF01E0E7FFC0C1FF00161B7E9A1B>I<00E00000E00000E00000E00001E00001E0 +0001E00003E00003E00007E0000FE0001FFFE0FFFFE0FFFFE00FE0000FE0000FE0000FE0000FE0 +000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0700FE0700FE0700FE0700FE0 +700FE0700FE07007F0E003F0C001FF80007F0014267FA51A>IIIII +I E /Fr 22 118 df<0F003FC07FE07FE0FFF0FFF0FFF0FFF07FE07FE03FC00F000C0C798B1B> +46 D<0000000F80000000000F80000000001F80000000003F80000000007F8000000000FF8000 +000000FF8000000001FF8000000003FF8000000007FF8000000007FF800000000FFF800000001E +FF800000003EFF800000007CFF8000000078FF80000000F0FF80000001E0FF80000003E0FF8000 +0003C0FF8000000780FF8000000F00FF8000001F00FF8000003E00FF8000003C00FF8000007800 +FF800000F000FF800001F000FF800001E000FF800003C000FF8000078000FF80000F8000FF8000 +1F0000FF80001E0000FF80003C0000FF8000780000FF8000F80000FF8000FFFFFFFFFF80FFFFFF +FFFF80FFFFFFFFFF80FFFFFFFFFF80000001FF8000000001FF8000000001FF8000000001FF8000 +000001FF8000000001FF8000000001FF8000000001FF8000000001FF8000000001FF80000003FF +FFFF800003FFFFFF800003FFFFFF800003FFFFFF8029377DB630>52 D<00000001E00000000000 +000003F00000000000000003F00000000000000007F80000000000000007F80000000000000007 +F8000000000000000FFC000000000000000FFC000000000000001FFE000000000000001FFE0000 +00000000001FFE000000000000003FFF000000000000003FFF000000000000007FFF8000000000 +00007BFF800000000000007BFF80000000000000F3FFC0000000000000F1FFC0000000000001F1 +FFE0000000000001E0FFE0000000000003E0FFF0000000000003C0FFF0000000000003C07FF000 +0000000007C07FF8000000000007803FF800000000000F803FFC00000000000F001FFC00000000 +000F001FFC00000000001F001FFE00000000001E000FFE00000000003E000FFF00000000003C00 +07FF00000000003C0007FF0000000000780007FF8000000000780003FF8000000000F80003FFC0 +00000000F00001FFC000000000F00001FFC000000001FFFFFFFFE000000001FFFFFFFFE0000000 +03FFFFFFFFF000000003FFFFFFFFF000000007C000007FF8000000078000007FF8000000078000 +003FF80000000F8000003FFC0000000F0000001FFC0000001F0000001FFE0000001E0000000FFE +0000001E0000000FFE0000003E0000000FFF0000003C00000007FF0000007C00000007FF800000 +7800000003FF800000FC00000003FF8000FFFFF00003FFFFFFC0FFFFF00003FFFFFFC0FFFFF000 +03FFFFFFC0FFFFF00003FFFFFFC0423B7DBA49>65 DI68 D77 +D82 D<0003FF000300001FFFE0070000FFFFFC0F0001FFFFFE1F0003FE00FF3F0007F0001FFF00 +0FE00007FF001FC00001FF003F800000FF003F800000FF007F0000007F007F0000003F007F0000 +003F00FF0000001F00FF0000001F00FF0000001F00FF8000000F00FF8000000F00FFC000000F00 +FFC000000F00FFF0000000007FFC000000007FFF800000003FFFF80000003FFFFFC000001FFFFF +FC00001FFFFFFF00000FFFFFFFC00007FFFFFFF00003FFFFFFF80000FFFFFFFC00007FFFFFFE00 +001FFFFFFE000003FFFFFF0000001FFFFF80000001FFFF800000000FFFC000000003FFC0000000 +00FFC0000000007FE0000000007FE0700000003FE0F00000003FE0F00000001FE0F00000001FE0 +F00000001FE0F80000001FE0F80000001FC0F80000001FC0FC0000001FC0FC0000003F80FE0000 +003F80FF0000003F00FFC000007F00FFE00000FE00FFFC0001FC00FDFFC00FF800F87FFFFFF000 +F01FFFFFC000E003FFFF0000C0003FF800002B3D7BBB36>I<3FFFFFFFFFFFFFC03FFFFFFFFFFF +FFC03FFFFFFFFFFFFFC03FFFFFFFFFFFFFC03FF8007FF001FFC07FC0007FF0003FE07F80007FF0 +001FE07F00007FF0000FE07E00007FF00007E07C00007FF00003E07C00007FF00003E07C00007F +F00003E07800007FF00001E07800007FF00001E07800007FF00001E07800007FF00001E0F00000 +7FF00000F0F000007FF00000F0F000007FF00000F0F000007FF00000F0F000007FF00000F00000 +007FF00000000000007FF00000000000007FF00000000000007FF00000000000007FF000000000 +00007FF00000000000007FF00000000000007FF00000000000007FF00000000000007FF0000000 +0000007FF00000000000007FF00000000000007FF00000000000007FF00000000000007FF00000 +000000007FF00000000000007FF00000000000007FF00000000000007FF00000000000007FF000 +00000000007FF00000000000007FF00000000000007FF00000000000007FF00000000000007FF0 +0000000000007FF00000000000007FF00000000000007FF00000000000007FF00000000000007F +F00000000000007FF00000000000007FF00000000000007FF0000000000FFFFFFFFF8000000FFF +FFFFFF8000000FFFFFFFFF8000000FFFFFFFFF80003C3A7DB943>I<003FFE00000001FFFFE000 +0007FFFFF800000FE007FC00000FF001FE00001FF800FF00001FF8007F80001FF8007FC0001FF8 +003FC0000FF0003FE00007E0003FE00003C0003FE0000000003FE0000000003FE0000000003FE0 +000000003FE0000000FFFFE000001FFFFFE000007FF83FE00003FF803FE00007FC003FE0000FF0 +003FE0001FE0003FE0003FE0003FE0007FC0003FE0007FC0003FE000FF80003FE000FF80003FE0 +00FF80003FE000FF80003FE000FF80007FE0007FC0007FE0007FC000DFE0003FE0039FF0001FF8 +0F0FFFE007FFFE0FFFE001FFFC07FFE0003FE000FFE02B267DA52F>97 D<0001FFF000000FFFFE +00003FFFFF8000FF801FC001FE003FC003FC007FE007F8007FE00FF0007FE01FF0007FE03FE000 +3FC03FE0001F807FE0000F007FC00000007FC0000000FFC0000000FFC0000000FFC0000000FFC0 +000000FFC0000000FFC0000000FFC0000000FFC0000000FFC0000000FFC00000007FC00000007F +E00000007FE00000003FE00000003FF00000F01FF00000F00FF80001E007F80001E003FC0003C0 +01FF000F8000FFC03F00003FFFFE00000FFFF8000001FFC00024267DA52B>99 +D<000000003F800000003FFF800000003FFF800000003FFF800000003FFF8000000001FF800000 +0000FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF +8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF800000 +0000FF8000000000FF8000000000FF800000FF80FF80000FFFF0FF80003FFFFCFF8000FFC03FFF +8001FE000FFF8003FC0003FF8007F80001FF800FF00000FF801FF00000FF803FE00000FF803FE0 +0000FF807FE00000FF807FC00000FF807FC00000FF807FC00000FF80FFC00000FF80FFC00000FF +80FFC00000FF80FFC00000FF80FFC00000FF80FFC00000FF80FFC00000FF80FFC00000FF80FFC0 +0000FF807FC00000FF807FC00000FF807FC00000FF803FE00000FF803FE00000FF801FE00000FF +800FF00001FF8007F80003FF8003F80007FF8001FE001FFFC000FF807EFFFE007FFFF8FFFE000F +FFE0FFFE0001FF00FFFE2F3C7DBB36>I<0001FF8000000FFFF000007FFFFC0000FF81FE0003FE +007F8007F8003F800FF0001FC00FF0000FE01FE0000FE03FE0000FF03FE00007F07FC00007F07F +C00007F87FC00007F8FFC00007F8FFC00007F8FFFFFFFFF8FFFFFFFFF8FFFFFFFFF8FFC0000000 +FFC0000000FFC0000000FFC00000007FC00000007FC00000007FC00000003FE00000003FE00000 +781FE00000781FF00000780FF00000F007F80001F003FC0003E001FE000FC000FFC07F80003FFF +FE00000FFFF8000000FFC00025267DA52C>I<00001FF0000000FFFC000003FFFF00000FF83F80 +001FE07F80003FC0FFC0007F80FFC000FF80FFC000FF80FFC001FF007F8001FF003F0001FF001E +0001FF00000001FF00000001FF00000001FF00000001FF00000001FF00000001FF00000001FF00 +000001FF00000001FF000000FFFFFF8000FFFFFF8000FFFFFF8000FFFFFF800001FF00000001FF +00000001FF00000001FF00000001FF00000001FF00000001FF00000001FF00000001FF00000001 +FF00000001FF00000001FF00000001FF00000001FF00000001FF00000001FF00000001FF000000 +01FF00000001FF00000001FF00000001FF00000001FF00000001FF00000001FF00000001FF0000 +0001FF00000001FF00000001FF00000001FF00000001FF0000007FFFFE00007FFFFE00007FFFFE +00007FFFFE0000223C7DBB1E>I<00FE00000000FFFE00000000FFFE00000000FFFE00000000FF +FE0000000007FE0000000003FE0000000003FE0000000003FE0000000003FE0000000003FE0000 +000003FE0000000003FE0000000003FE0000000003FE0000000003FE0000000003FE0000000003 +FE0000000003FE0000000003FE0000000003FE0000000003FE0000000003FE00FF800003FE03FF +F00003FE0FFFF80003FE1E03FC0003FE3801FE0003FE6001FF0003FEC000FF0003FFC000FF8003 +FF8000FF8003FF0000FF8003FF0000FF8003FF0000FF8003FE0000FF8003FE0000FF8003FE0000 +FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003 +FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000 +FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF80FF +FFF83FFFFEFFFFF83FFFFEFFFFF83FFFFEFFFFF83FFFFE2F3C7CBB36>104 +D<00FE00FFFE00FFFE00FFFE00FFFE0007FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE +0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE +0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE +0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE0003FE +0003FE0003FE0003FE0003FE00FFFFF8FFFFF8FFFFF8FFFFF8153C7DBB1A>108 +D<01FC007FC0000FF80000FFFC03FFF8007FFF0000FFFC0FFFFC01FFFF8000FFFC1F03FE03E07F +C000FFFC3800FF07001FE00007FC7000FF8E001FF00003FCC0007F98000FF00003FDC0007FF800 +0FF80003FD80007FF0000FF80003FF00007FE0000FF80003FF00007FE0000FF80003FF00007FE0 +000FF80003FE00007FC0000FF80003FE00007FC0000FF80003FE00007FC0000FF80003FE00007F +C0000FF80003FE00007FC0000FF80003FE00007FC0000FF80003FE00007FC0000FF80003FE0000 +7FC0000FF80003FE00007FC0000FF80003FE00007FC0000FF80003FE00007FC0000FF80003FE00 +007FC0000FF80003FE00007FC0000FF80003FE00007FC0000FF80003FE00007FC0000FF80003FE +00007FC0000FF80003FE00007FC0000FF80003FE00007FC0000FF80003FE00007FC0000FF80003 +FE00007FC0000FF80003FE00007FC0000FF80003FE00007FC0000FF800FFFFF81FFFFF03FFFFE0 +FFFFF81FFFFF03FFFFE0FFFFF81FFFFF03FFFFE0FFFFF81FFFFF03FFFFE04B267CA552>I<01FC +00FF8000FFFC03FFF000FFFC0FFFF800FFFC1E03FC00FFFC3801FE0007FC6001FF0003FCC000FF +0003FDC000FF8003FD8000FF8003FF0000FF8003FF0000FF8003FF0000FF8003FE0000FF8003FE +0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF +8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE +0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF +8003FE0000FF80FFFFF83FFFFEFFFFF83FFFFEFFFFF83FFFFEFFFFF83FFFFE2F267CA536>I<00 +01FFC00000000FFFF80000007FFFFF000000FF80FF800003FE003FE00007F8000FF0000FF00007 +F8000FF00007F8001FE00003FC003FE00003FE003FE00003FE007FC00001FF007FC00001FF007F +C00001FF007FC00001FF00FFC00001FF80FFC00001FF80FFC00001FF80FFC00001FF80FFC00001 +FF80FFC00001FF80FFC00001FF80FFC00001FF80FFC00001FF807FC00001FF007FC00001FF007F +C00001FF003FE00003FE003FE00003FE001FE00003FC001FF00007FC000FF00007F80007F8000F +F00003FE003FE00000FF80FF8000007FFFFF0000000FFFF800000001FFC0000029267DA530>I< +01FC03F000FFFC0FFC00FFFC1FFF00FFFC3C3F80FFFC707F8007FCE0FFC003FCC0FFC003FD80FF +C003FD80FFC003FF807F8003FF003F0003FF001E0003FF00000003FE00000003FE00000003FE00 +000003FE00000003FE00000003FE00000003FE00000003FE00000003FE00000003FE00000003FE +00000003FE00000003FE00000003FE00000003FE00000003FE00000003FE00000003FE00000003 +FE00000003FE00000003FE000000FFFFFC0000FFFFFC0000FFFFFC0000FFFFFC000022267DA528 +>114 D<000F0000000F0000000F0000000F0000000F0000001F0000001F0000001F0000001F00 +00003F0000003F0000007F0000007F000000FF000001FF000003FF000007FF00001FFFFFF0FFFF +FFF0FFFFFFF0FFFFFFF001FF000001FF000001FF000001FF000001FF000001FF000001FF000001 +FF000001FF000001FF000001FF000001FF000001FF000001FF000001FF000001FF000001FF0000 +01FF000001FF000001FF003C01FF003C01FF003C01FF003C01FF003C01FF003C01FF003C01FF00 +3C00FF007800FF8078007F80F0003FC1E0001FFFC0000FFF800001FE001E377EB626>116 +D<00FE00003F80FFFE003FFF80FFFE003FFF80FFFE003FFF80FFFE003FFF8007FE0001FF8003FE +0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF +8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE +0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF8003FE0000FF +8003FE0000FF8003FE0000FF8003FE0001FF8003FE0001FF8003FE0003FF8001FE0003FF8001FE +0006FF8000FF000CFFC0007F8078FFFE003FFFF0FFFE001FFFE0FFFE0003FF80FFFE2F267CA536 +>I E end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 300dpi +TeXDict begin + +%%EndSetup +%%Page: 1 1 +1 0 bop 871 1042 a Fr(Amd)399 1229 y(The)33 b(4.4)g(BSD)f(Automoun)m(ter)592 +1415 y(Reference)h(Man)m(ual)702 1602 y Fq(Jan-Simon)24 b(P)n(endry)937 +1727 y Fp(and)767 1851 y Fq(Nic)n(k)f(Williams)719 2163 y Fo(Last)15 +b(up)q(dated)h(Marc)o(h)e(1991)510 2225 y(Do)q(cumen)o(tation)h(for)g(soft)o +(w)o(are)e(revision)k(5.3)d(Alpha)p eop +%%Page: 2 2 +2 1 bop 0 295 a Fo(Cop)o(yrigh)o(t)226 294 y(c)214 295 y Fn(\015)15 +b Fo(1989)f(Jan-Simon)j(P)o(endry)0 370 y(Cop)o(yrigh)o(t)226 +369 y(c)214 370 y Fn(\015)e Fo(1989)f(Imp)q(erial)j(College)f(of)f(Science,)i +(T)l(ec)o(hnology)e(&)h(Medicine)0 445 y(Cop)o(yrigh)o(t)226 +444 y(c)214 445 y Fn(\015)f Fo(1989)f(The)i(Regen)o(ts)f(of)g(the)g(Univ)o +(ersit)o(y)h(of)f(California.)0 582 y(All)h(Righ)o(ts)g(Reserv)o(ed.)0 +738 y(P)o(ermission)k(to)g(cop)o(y)f(this)i(do)q(cumen)o(t,)g(or)e(an)o(y)g +(p)q(ortion)i(of)e(it,)i(as)e(necessary)h(for)g(use)g(of)f(this)h(soft)o(w)o +(are)e(is)0 801 y(gran)o(ted)d(pro)o(vided)h(this)f(cop)o(yrigh)o(t)g(notice) +h(and)f(statemen)o(t)f(of)h(p)q(ermission)i(are)e(included.)p +eop +%%Page: 1 3 +1 2 bop 0 -83 a Fo(Source)16 b(Distribution)1357 b(SMM:13-1)0 +158 y Fm(Preface)62 299 y Fo(This)11 b(man)o(ual)g(do)q(cumen)o(ts)g(the)f +(use)h(of)f(the)h(4.4)f(BSD)g(automoun)o(ter|)p Fp(Amd)p Fo(.)18 +b(This)11 b(is)g(primarily)h(a)e(reference)0 349 y(man)o(ual.)20 +b(Unfortunately)l(,)15 b(no)g(tutorial)h(exists.)62 419 y(This)22 +b(man)o(ual)f(comes)f(in)i(t)o(w)o(o)e(forms:)30 b(the)21 b(published)i(form) +d(and)h(the)g(Info)g(form.)36 b(The)21 b(Info)g(form)f(is)0 +469 y(for)f(on-line)i(p)q(erusal)f(with)g(the)g(INF)o(O)f(program)g(whic)o(h) +h(is)g(distributed)h(along)e(with)h(GNU)f(Emacs.)32 b(Both)0 +519 y(forms)16 b(con)o(tain)h(substan)o(tially)h(the)f(same)f(text)h(and)g +(are)f(generated)h(from)f(a)h(common)f(source)h(\014le,)h(whic)o(h)f(is)0 +569 y(distributed)g(with)e(the)h Fp(Amd)h Fo(source.)0 783 +y Fm(License)62 924 y Fp(Amd)f Fo(is)f(not)e(in)i(the)f(public)i(domain;)e +(it)g(is)h(cop)o(yrigh)o(ted)f(and)g(there)g(are)f(restrictions)i(on)f(its)g +(distribution.)62 994 y(Redistribution)k(and)d(use)g(in)h(source)f(and)g +(binary)h(forms)e(are)g(p)q(ermitted)i(pro)o(vided)g(that:)j(\(1\))14 +b(source)h(dis-)0 1044 y(tributions)f(retain)g(this)g(en)o(tire)h(cop)o +(yrigh)o(t)e(notice)h(and)g(commen)o(t,)f(and)h(\(2\))f(distributions)i +(including)i(binaries)0 1094 y(displa)o(y)e(the)e(follo)o(wing)h(ac)o(kno)o +(wledgemen)o(t:)19 b(\\This)14 b(pro)q(duct)g(includes)h(soft)o(w)o(are)d +(dev)o(elop)q(ed)j(b)o(y)e(The)h(Univ)o(er-)0 1144 y(sit)o(y)f(of)g +(California,)h(Berk)o(eley)g(and)f(its)h(Con)o(tributors")e(in)i(the)f(do)q +(cumen)o(tation)g(or)g(other)g(materials)g(pro)o(vided)0 1193 +y(with)18 b(the)f(distribution)i(and)e(in)h(all)g(adv)o(ertising)g(materials) +f(men)o(tioning)i(features)d(or)h(use)h(of)e(this)i(soft)o(w)o(are.)0 +1243 y(neither)h(the)e(name)h(of)f(the)g(Univ)o(ersit)o(y)i(nor)e(the)g +(names)h(of)f(its)h(Con)o(tributors)f(ma)o(y)f(b)q(e)j(used)f(to)f(endorse)g +(or)0 1293 y(promote)d(pro)q(ducts)i(deriv)o(ed)g(from)f(this)g(soft)o(w)o +(are)f(without)h(sp)q(eci\014c)i(prior)e(written)g(p)q(ermission.)62 +1364 y(THIS)h(SOFTW)-5 b(ARE)15 b(IS)g(PR)o(O)o(VIDED)g(\\AS)g(IS")g(AND)g +(WITHOUT)g(ANY)g(EXPRESS)h(OR)g(IMPLIED)0 1413 y(W)-5 b(ARRANTIES,)21 +b(INCLUDING,)e(WITHOUT)h(LIMIT)l(A)l(TION,)i(THE)d(IMPLIED)h(W)-5 +b(ARRANTIES)21 b(OF)0 1463 y(MER)o(CHANT)l(ABILITY)c(AND)e(FITNESS)g(F)o(OR)h +(A)f(P)l(AR)l(TICULAR)i(PURPOSE.)0 1678 y Fm(Source)e(Distribution)62 +1818 y Fo(If)g(y)o(ou)f(ha)o(v)o(e)h(access)f(to)g(the)h(In)o(ternet,)g(y)o +(ou)f(can)h(get)f(the)g(latest)h(distribution)h(v)o(ersion)f(of)f +Fp(Amd)j Fo(from)c(host)0 1868 y(`)p Fl(usc.edu)p Fo(')g(using)i(anon)o +(ymous)g(FTP)l(.)e(Mo)o(v)o(e)h(to)g(the)h(directory)g(`)p +Fl(/pub/amd)p Fo(')e(on)h(that)g(host)h(and)g(fetc)o(h)f(the)h(\014le)0 +1918 y(`)p Fl(amd.tar.Z)p Fo('.)62 1988 y(If)23 b(y)o(ou)e(are)h(in)h(the)g +(UK,)f(y)o(ou)g(can)g(get)g(the)g(latest)g(distribution)i(v)o(ersion)e(of)g +Fp(Amd)i Fo(from)d(the)h(UKnet)0 2038 y(info-serv)o(er.)e(Start)14 +b(b)o(y)i(sending)g(email)g(to)f(`)p Fl(info-server@doc.ic.ac)o(.uk)p +Fo('.)62 2109 y(Sites)g(on)f(the)g(UK)g(JANET)g(net)o(w)o(ork)f(can)h(get)g +(the)g(latest)f(distribution)j(b)o(y)e(using)g(anon)o(ymous)g(NIFTP)g(to)0 +2159 y(fetc)o(h)h(the)g(\014le)i(`)p Fl(amd.tar.Z)p Fo(')12 +b(from)j(host)f(`)p Fl(uk.ac.imperial.doc.src)p Fo('.)62 2229 +y(Revision)j(5.2)d(w)o(as)h(part)f(of)h(the)g(4.3)g(BSD)g(Reno)h +(distribution.)62 2300 y(Revision)c(5.3bsdnet,)f(a)f(late)g(alpha)h(v)o +(ersion)f(of)g(5.3,)g(w)o(as)g(part)f(of)h(the)g(BSD)h(net)o(w)o(ork)e(v)o +(ersion)h(2)g(distribution)0 2504 y Fq(Bug)15 b(Rep)r(orts)62 +2595 y Fo(Send)i(all)f(bug)g(rep)q(orts)f(to)f(`)p Fl(jsp@doc.ic.ac.uk)p +Fo(')f(quoting)j(the)f(details)i(of)e(the)g(release)h(and)g(y)o(our)f +(con\014g-)0 2645 y(uration.)20 b(These)15 b(can)h(b)q(e)g(obtained)g(b)o(y)f +(running)h(the)f(command)g(`)p Fl(amd)g(-v)p Fo('.)p eop +%%Page: 2 4 +2 3 bop 15 -83 a Fo(SMM:13-2)912 b(4.4)15 b(BSD)g(Automoun)o(ter)f(Reference) +j(Man)o(ual)0 158 y Fq(Mailing)g(List)62 250 y Fo(There)11 +b(is)g(a)f(mailing)i(list)f(for)f(p)q(eople)i(in)o(terested)f(in)h(k)o +(eeping)f(upto)q(date)g(with)f(dev)o(elopmen)o(ts.)19 b(T)l(o)11 +b(subscrib)q(e,)0 299 y(send)16 b(a)f(note)g(to)f(`)p Fl +(amd-workers-request@acl.l)o(anl.gov)o Fo('.)0 533 y Fm(In)n(tro)r(duction)62 +674 y Fo(An)e Fp(automoun)o(ter)i Fo(main)o(tains)e(a)f(cac)o(he)h(of)g(moun) +o(ted)f(\014lesystems.)20 b(Filesystems)12 b(are)f(moun)o(ted)h(on)f(demand)0 +724 y(when)16 b(they)f(are)g(\014rst)g(referenced,)g(and)h(unmoun)o(ted)f +(after)g(a)g(p)q(erio)q(d)h(of)f(inactivit)o(y)l(.)62 795 y +Fp(Amd)k Fo(ma)o(y)d(b)q(e)h(used)g(as)g(a)f(replacemen)o(t)h(for)f(Sun's)h +(automoun)o(ter.)23 b(The)17 b(c)o(hoice)h(of)e(whic)o(h)h(\014lesystem)h(to) +0 844 y(moun)o(t)10 b(can)h(b)q(e)h(con)o(trolled)f(dynamically)i(with)e +Fp(selectors)p Fo(.)19 b(Selectors)11 b(allo)o(w)g(decisions)h(of)f(the)g +(form)f(\\hostname)0 894 y(is)15 b Fp(this)p Fo(,")f(or)f(\\arc)o(hitecture)h +(is)h(not)e Fp(that)p Fo(.")19 b(Selectors)c(ma)o(y)e(b)q(e)i(com)o(bined)g +(arbitrarily)l(.)20 b Fp(Amd)c Fo(also)e(supp)q(orts)g(a)0 +944 y(v)m(ariet)o(y)e(of)f(\014lesystem)i(t)o(yp)q(es,)f(including)i(NFS,)e +(UFS)f(and)h(the)g(no)o(v)o(el)g Fp(program)f Fo(\014lesystem.)19 +b(The)12 b(com)o(bination)0 994 y(of)22 b(selectors)h(and)g(m)o(ultiple)h +(\014lesystem)f(t)o(yp)q(es)g(allo)o(ws)g(iden)o(tical)h(con\014guration)f +(\014les)g(to)f(b)q(e)h(used)h(on)e(all)0 1044 y(mac)o(hines)16 +b(so)f(reducing)h(the)g(administrativ)o(e)f(o)o(v)o(erhead.)62 +1114 y Fp(Amd)h Fo(ensures)f(that)f(it)g(will)i(not)e(hang)g(if)g(a)g(remote) +g(serv)o(er)g(go)q(es)g(do)o(wn.)19 b(Moreo)o(v)o(er,)12 b +Fp(Amd)17 b Fo(can)d(determine)0 1164 y(when)f(a)f(remote)g(serv)o(er)g(has)g +(b)q(ecome)h(inaccessible)i(and)d(then)h(moun)o(t)f(replacemen)o(t)h +(\014lesystems)g(as)f(and)g(when)0 1214 y(they)j(b)q(ecome)h(a)o(v)m +(ailable.)62 1284 y Fp(Amd)h Fo(con)o(tains)f(no)f(proprietary)g(source)g(co) +q(de)h(and)f(has)g(b)q(een)i(p)q(orted)e(to)g(n)o(umerous)g(\015a)o(v)o(ours) +f(of)h(Unix.)0 1516 y Fm(1)41 b(Ov)n(erview)62 1658 y Fp(Amd)20 +b Fo(main)o(tains)e(a)g(cac)o(he)g(of)f(moun)o(ted)h(\014lesystems.)28 +b(Filesystems)18 b(are)f Fp(demand-moun)o(ted)k Fo(when)d(they)0 +1708 y(are)12 b(\014rst)g(referenced,)i(and)e(unmoun)o(ted)h(after)f(a)g(p)q +(erio)q(d)i(of)e(inactivit)o(y)l(.)20 b Fp(Amd)14 b Fo(ma)o(y)e(b)q(e)h(used) +g(as)f(a)g(replacemen)o(t)0 1757 y(for)17 b(Sun's)g Fk(automoun)o(t)p +Fo(\(8\))f(program.)25 b(It)18 b(con)o(tains)f(no)g(proprietary)h(source)f +(co)q(de)h(and)f(has)h(b)q(een)g(p)q(orted)g(to)0 1807 y(n)o(umerous)d(\015a) +o(v)o(ours)f(of)h(Unix.)21 b(See)16 b(Section)g(2.1)e([Supp)q(orted)i(Op)q +(erating)g(Systems],)e(page)30 b(SMM:13-6.)62 1878 y Fp(Amd)25 +b Fo(w)o(as)c(designed)j(as)e(the)h(basis)g(for)f(exp)q(erimen)o(ting)i(with) +e(\014lesystem)i(la)o(y)o(out)d(and)i(managemen)o(t.)0 1928 +y(Although)15 b Fp(Amd)i Fo(has)e(man)o(y)g(direct)g(applications)i(it)e(is)g +(loaded)h(with)f(additional)i(features)d(whic)o(h)i(ha)o(v)o(e)f(little)0 +1977 y(practical)h(use.)21 b(A)o(t)15 b(some)g(p)q(oin)o(t)h(the)g(infrequen) +o(tly)h(used)f(comp)q(onen)o(ts)f(ma)o(y)g(b)q(e)h(remo)o(v)o(ed)f(to)g +(streamline)h(the)0 2027 y(pro)q(duction)g(system.)0 2234 y +Fq(1.1)33 b(F)-6 b(undamen)n(tals)62 2325 y Fo(The)15 b(fundamen)o(tal)g +(concept)f(b)q(ehind)j Fp(Amd)f Fo(is)f(the)f(abilit)o(y)i(to)d(separate)h +(the)g(name)h(used)g(to)e(refer)h(to)g(a)g(\014le)0 2375 y(from)d(the)g(name) +g(used)h(to)f(refer)g(to)g(its)g(ph)o(ysical)i(storage)d(lo)q(cation.)19 +b(This)12 b(allo)o(ws)g(the)f(same)g(\014les)i(to)d(b)q(e)i(accessed)0 +2425 y(with)g(the)h(same)f(name)g(regardless)g(of)g(where)g(in)h(the)f(net)o +(w)o(ork)g(the)g(name)g(is)h(used.)19 b(This)13 b(is)f(v)o(ery)g(di\013eren)o +(t)h(from)0 2475 y(placing)i(`)p Fl(/n/hostname)p Fo(')10 b(in)k(fron)o(t)f +(of)f(the)i(pathname)f(since)h(that)f(includes)i(lo)q(cation)f(dep)q(enden)o +(t)h(information)0 2525 y(whic)o(h)h(ma)o(y)f(c)o(hange)g(if)g(\014les)i(are) +e(mo)o(v)o(ed)f(to)h(another)g(mac)o(hine.)62 2595 y(By)i(placing)i(the)e +(required)h(mappings)f(in)h(a)e(cen)o(trally)i(administered)g(database,)f +(\014lesystems)g(can)g(b)q(e)h(re-)0 2645 y(organised)d(without)h(requiring)g +(c)o(hanges)f(to)g(con\014guration)g(\014les,)h(shell)h(scripts)e(and)h(so)e +(on.)p eop +%%Page: 3 5 +3 4 bop 0 -83 a Fo(Chapter)15 b(1:)k(Ov)o(erview)1328 b(SMM:13-3)0 +158 y Fq(1.2)33 b(Filesystems)15 b(and)h(V)-6 b(olumes)62 250 +y Fp(Amd)19 b Fo(views)e(the)g(w)o(orld)g(as)g(a)f(set)h(of)f(\014leserv)o +(ers,)i(eac)o(h)f(con)o(taing)g(one)g(or)f(more)g(\014lesystems)i(where)f +(eac)o(h)0 299 y(\014lesystem)g(con)o(tains)f(one)h(or)f(more)g +Fp(v)o(olumes)p Fo(.)23 b(Here)17 b(the)f(term)g Fp(v)o(olume)j +Fo(is)e(used)g(to)f(refer)g(to)g(a)g(coheren)o(t)g(set)0 349 +y(of)f(\014les)h(suc)o(h)f(as)g(a)g(user's)g(home)g(directory)h(or)e(a)h(T) +899 359 y(E)925 349 y(X)g(distribution.)62 420 y(In)i(order)e(to)h(access)g +(the)g(con)o(ten)o(ts)f(of)g(a)h(v)o(olume,)g Fp(Amd)i Fo(m)o(ust)d(b)q(e)i +(told)f(in)g(whic)o(h)h(\014lesystem)g(the)f(v)o(olume)0 470 +y(resides)j(and)g(whic)o(h)g(host)g(o)o(wns)e(the)i(\014lesystem.)30 +b(By)19 b(default)g(the)g(host)f(is)h(assumed)f(to)g(b)q(e)i(lo)q(cal)f(and)g +(the)0 519 y(v)o(olume)c(is)f(assumed)g(to)g(b)q(e)h(the)f(en)o(tire)h +(\014lesystem.)20 b(If)14 b(a)g(\014lesystem)h(con)o(tains)f(more)g(than)g +(one)g(v)o(olume,)h(then)0 569 y(a)e Fp(sublink)18 b Fo(is)13 +b(used)h(to)f(refer)g(to)f(the)h(sub-directory)h(within)h(the)e(\014lesystem) +h(where)f(the)g(v)o(olume)h(can)f(b)q(e)h(found.)0 722 y Fq(1.3)33 +b(V)-6 b(olume)15 b(Naming)62 814 y Fo(V)l(olume)23 b(names)g(are)f +(de\014ned)h(to)f(b)q(e)h(unique)g(across)f(the)g(en)o(tire)h(net)o(w)o(ork.) +40 b(A)22 b(v)o(olume)h(name)f(is)h(the)0 864 y(pathname)17 +b(to)g(the)h(v)o(olume's)f(ro)q(ot)g(as)g(kno)o(wn)g(b)o(y)h(the)g(users)f +(of)g(that)g(v)o(olume.)27 b(Since)19 b(this)f(name)g(uniquely)0 +913 y(iden)o(ti\014es)g(the)e(v)o(olume)h(con)o(ten)o(ts,)e(all)i(v)o(olumes) +g(can)f(b)q(e)h(named)f(and)h(accessed)f(from)g(eac)o(h)g(host,)g(sub)s(ject) +g(to)0 963 y(administrativ)o(e)g(con)o(trols.)62 1034 y(V)l(olumes)k(ma)o(y)e +(b)q(e)h(replicated)h(or)e(duplicated.)32 b(Replicated)21 b(v)o(olumes)e(con) +o(tain)g(iden)o(tical)h(copies)g(of)e(the)0 1084 y(same)11 +b(data)g(and)g(reside)i(at)d(t)o(w)o(o)g(or)h(more)g(lo)q(cations)h(in)h(the) +e(net)o(w)o(ork.)18 b(Eac)o(h)11 b(of)g(the)g(replicated)i(v)o(olumes)f(can)f +(b)q(e)0 1133 y(used)16 b(in)o(terc)o(hangeably)l(.)22 b(Duplicated)17 +b(v)o(olumes)f(eac)o(h)f(ha)o(v)o(e)g(the)h(same)f(name)g(but)h(con)o(tain)g +(di\013eren)o(t,)f(though)0 1183 y(functionally)21 b(iden)o(tical,)h(data.)32 +b(F)l(or)19 b(example,)i(`)p Fl(/vol/tex)p Fo(')d(migh)o(t)h(b)q(e)h(the)g +(name)f(of)g(a)g(T)1638 1193 y(E)1664 1183 y(X)g(distribution)0 +1233 y(whic)o(h)d(v)m(aried)g(for)f(eac)o(h)g(mac)o(hine)h(arc)o(hitecture.) +62 1304 y Fp(Amd)k Fo(pro)o(vides)e(facilities)h(to)e(tak)o(e)g(adv)m(an)o +(tage)g(of)g(b)q(oth)g(replicated)i(and)f(duplicated)h(v)o(olumes.)27 +b(Con\014g-)0 1353 y(uration)18 b(options)g(allo)o(w)f(a)h(single)h(set)e(of) +h(con\014guration)f(data)g(to)h(b)q(e)g(shared)g(across)f(an)g(en)o(tire)h +(net)o(w)o(ork)f(b)o(y)0 1403 y(taking)e(adv)m(an)o(tage)g(of)g(replicated)h +(and)g(duplicated)h(v)o(olumes.)62 1474 y Fp(Amd)d Fo(can)f(tak)o(e)e(adv)m +(an)o(tage)h(of)f(replacemen)o(t)i(v)o(olumes)f(b)o(y)h(moun)o(ting)f(them)g +(as)f(required)j(should)f(an)f(activ)o(e)0 1524 y(\014leserv)o(er)k(b)q +(ecome)g(una)o(v)m(ailable.)0 1670 y Fq(1.4)33 b(V)-6 b(olume)15 +b(Binding)62 1761 y Fo(Unix)22 b(implemen)o(ts)h(a)d(namespace)i(of)e +(hierarc)o(hically)k(moun)o(ted)d(\014lesystems.)38 b(Tw)o(o)20 +b(forms)g(of)h(binding)0 1811 y(b)q(et)o(w)o(een)15 b(names)g(and)g(\014les)g +(are)g(pro)o(vided.)20 b(A)15 b Fp(hard)g(link)k Fo(completes)c(the)g +(binding)h(when)g(the)e(name)h(is)g(added)0 1861 y(to)f(the)h(\014lesystem.) +20 b(A)15 b Fp(soft)f(link)19 b Fo(dela)o(ys)c(the)g(binding)i(un)o(til)f +(the)f(name)f(is)i(accessed.)k(An)15 b Fp(automoun)o(ter)i +Fo(adds)0 1911 y(a)e(further)g(form)f(in)i(whic)o(h)g(the)g(binding)h(of)e +(name)g(to)f(\014lesystem)i(is)g(dela)o(y)o(ed)g(un)o(til)g(the)f(name)h(is)f +(accessed.)62 1981 y(The)h(target)f(v)o(olume,)g(in)i(its)f(general)g(form,)f +(is)h(a)f(tuple)i(\(host,)d(\014lesystem,)i(sublink\))i(whic)o(h)e(can)g(b)q +(e)g(used)0 2031 y(to)f(name)g(the)g(ph)o(ysical)i(lo)q(cation)f(of)e(an)o(y) +h(v)o(olume)h(in)g(the)f(net)o(w)o(ork.)62 2102 y(When)22 b(a)f(target)f(is)i +(referenced,)h Fp(Amd)g Fo(ignores)e(the)h(sublink)h(elemen)o(t)f(and)f +(determines)h(whether)g(the)0 2152 y(required)c(\014lesystem)f(is)g(already)g +(moun)o(ted.)25 b(This)17 b(is)g(done)g(b)o(y)g(computing)g(the)g(lo)q(cal)g +(moun)o(t)g(p)q(oin)o(t)g(for)f(the)0 2201 y(\014lesystem)g(and)g(c)o(hec)o +(king)h(for)e(an)h(existing)h(\014lesystem)f(moun)o(ted)g(at)f(the)h(same)g +(place.)23 b(If)16 b(suc)o(h)g(a)f(\014lesystem)0 2251 y(already)i(exists)h +(then)f(it)h(is)f(assumed)h(to)e(b)q(e)i(functionally)h(iden)o(tical)g(to)e +(the)g(target)f(\014lesystem.)26 b(By)17 b(default)0 2301 y(there)d(is)g(a)f +(one-to-one)g(mapping)i(b)q(et)o(w)o(een)e(the)h(pair)g(\(host,)f +(\014lesystem\))g(and)h(the)g(lo)q(cal)g(moun)o(t)f(p)q(oin)o(t)h(so)g(this)0 +2351 y(assumption)h(is)h(v)m(alid.)0 2504 y Fq(1.5)33 b(Op)r(erational)15 +b(Principl)q(es)62 2595 y Fp(Amd)e Fo(op)q(erates)e(b)o(y)f(in)o(tro)q +(ducing)j(new)e(moun)o(t)f(p)q(oin)o(ts)h(in)o(to)g(the)g(namespace.)19 +b(These)11 b(are)g(called)h Fp(automoun)o(t)0 2645 y Fo(p)q(oin)o(ts.)22 +b(The)16 b(k)o(ernel)h(sees)f(these)g(automoun)o(t)e(p)q(oin)o(ts)j(as)e(NFS) +h(\014lesystems)g(b)q(eing)h(serv)o(ed)f(b)o(y)g Fp(Amd)p Fo(.)22 +b(Ha)o(ving)p eop +%%Page: 4 6 +4 5 bop 15 -83 a Fo(SMM:13-4)912 b(4.4)15 b(BSD)g(Automoun)o(ter)f(Reference) +j(Man)o(ual)0 158 y(attac)o(hed)f(itself)h(to)f(the)h(namespace,)g +Fp(Amd)h Fo(is)f(no)o(w)f(able)i(to)e(con)o(trol)g(the)g(view)i(the)e(rest)g +(of)g(the)h(system)f(has)0 208 y(of)f(those)g(moun)o(t)f(p)q(oin)o(ts.)21 +b(RPC)15 b(calls)h(are)f(receiv)o(ed)i(from)d(the)h(k)o(ernel)h(one)g(at)e(a) +h(time.)62 279 y(When)k(a)e Fp(lo)q(okup)j Fo(call)f(is)g(receiv)o(ed)g +Fp(Amd)h Fo(c)o(hec)o(ks)e(whether)g(the)g(name)g(is)h(already)f(kno)o(wn.)28 +b(If)18 b(it)g(is)h(not,)0 329 y(the)g(required)h(v)o(olume)f(is)g(moun)o +(ted.)30 b(A)19 b(sym)o(b)q(olic)h(link)g(p)q(oin)o(ting)g(to)e(the)h(v)o +(olume)g(ro)q(ot)f(is)h(then)g(returned.)0 378 y(Once)g(the)e(sym)o(b)q(olic) +i(link)g(is)f(returned,)g(the)g(k)o(ernel)g(will)i(send)e(all)g(other)g +(requests)f(direct)h(to)f(the)h(moun)o(ted)0 428 y(\014lesystem.)62 +499 y(If)d(a)f(v)o(olume)g(is)h(not)f(y)o(et)g(moun)o(ted,)g +Fp(Amd)i Fo(consults)f(a)f(con\014guration)g Fp(moun)o(t-map)h +Fo(corresp)q(onding)g(to)f(the)0 549 y(automoun)o(t)h(p)q(oin)o(t.)24 +b Fp(Amd)19 b Fo(then)e(mak)o(es)f(a)g(run)o(time)h(decision)h(on)e(what)g +(and)h(where)f(to)g(moun)o(t)g(a)g(\014lesystem)0 598 y(based)g(on)f(the)g +(information)g(obtained)h(from)f(the)g(map.)62 669 y Fp(Amd)21 +b Fo(do)q(es)e(not)g(implemen)o(t)h(all)g(the)f(NFS)g(requests;)h(only)g +(those)e(relev)m(an)o(t)i(to)e(name)h(binding)i(suc)o(h)e(as)0 +719 y Fp(lo)q(okup)p Fo(,)g Fp(readlink)j Fo(and)c Fp(readdir)p +Fo(.)28 b(Some)18 b(other)g(calls)g(are)g(also)g(implemen)o(ted)h(but)f(most) +f(simply)i(return)f(an)0 769 y(error)c(co)q(de;)i(for)e(example)j +Fp(mkdir)h Fo(alw)o(a)o(ys)d(returns)g(\\read-only)h(\014lesystem".)0 +933 y Fq(1.6)33 b(Moun)n(ting)16 b(a)f(V)-6 b(olume)62 1024 +y Fo(Eac)o(h)21 b(automoun)o(t)e(p)q(oin)o(t)i(has)g(a)f(corresp)q(onding)i +(moun)o(t)e(map.)36 b(The)20 b(moun)o(t)h(map)f(con)o(tains)h(a)f(list)h(of)0 +1074 y(k)o(ey{v)m(alue)15 b(pairs.)20 b(The)15 b(k)o(ey)f(is)h(the)f(name)h +(of)f(the)g(v)o(olume)h(to)e(b)q(e)j(moun)o(ted.)j(The)c(v)m(alue)g(is)g(a)f +(list)h(of)f(lo)q(cations)0 1124 y(describing)i(where)d(the)h(\014lesystem)h +(is)f(stored)f(in)i(the)e(net)o(w)o(ork.)19 b(In)14 b(the)g(source)g(for)f +(the)g(map)h(the)g(v)m(alue)h(w)o(ould)0 1173 y(lo)q(ok)g(lik)o(e)120 +1244 y(lo)q(cation1)31 b(lo)q(cation2)g Fj(:)8 b(:)g(:)28 b +Fo(lo)q(cationN)62 1335 y Fp(Amd)14 b Fo(examines)f(eac)o(h)f(lo)q(cation)g +(in)h(turn.)19 b(Eac)o(h)12 b(lo)q(cation)g(ma)o(y)f(con)o(tain)h +Fp(selectors)i Fo(whic)o(h)f(con)o(trol)f(whether)0 1385 y +Fp(Amd)19 b Fo(can)e(use)h(that)e(lo)q(cation.)27 b(F)l(or)16 +b(example,)i(the)g(lo)q(cation)g(ma)o(y)e(b)q(e)i(restricted)f(to)g(use)g(b)o +(y)g(certain)h(hosts.)0 1435 y(Those)d(lo)q(cations)h(whic)o(h)g(cannot)f(b)q +(e)h(used)g(are)f(ignored.)62 1506 y Fp(Amd)23 b Fo(attempts)d(to)g(moun)o(t) +g(the)h(\014lesystem)g(describ)q(ed)i(b)o(y)d(eac)o(h)h(remaining)h(lo)q +(cation)f(un)o(til)h(a)e(moun)o(t)0 1555 y(succeeds)c(or)f +Fp(Amd)i Fo(can)f(no)f(longer)g(pro)q(ceed.)21 b(The)15 b(latter)g(can)g(o)q +(ccur)h(in)g(three)f(w)o(a)o(ys:)37 1626 y Fn(\017)30 b Fo(If)16 +b(none)h(of)e(the)i(lo)q(cations)f(could)i(b)q(e)e(used,)h(or)e(if)i(all)g +(of)f(the)g(lo)q(cations)h(caused)f(an)g(error,)f(then)i(the)f(last)90 +1676 y(error)e(is)i(returned.)37 1738 y Fn(\017)30 b Fo(If)17 +b(a)f(lo)q(cation)i(could)f(b)q(e)g(used)h(but)e(w)o(as)g(b)q(eing)i(moun)o +(ted)f(in)g(the)g(bac)o(kground)f(then)h Fp(Amd)i Fo(marks)d(that)90 +1788 y(moun)o(t)k(as)f(b)q(eing)j(\\in)f(progress")e(and)h(con)o(tin)o(ues)h +(with)g(the)f(next)g(request;)j(no)d(reply)h(is)f(sen)o(t)g(to)g(the)90 +1838 y(k)o(ernel.)37 1900 y Fn(\017)30 b Fo(Lastly)l(,)23 b(one)e(or)g(more)f +(of)h(the)g(moun)o(ts)g(ma)o(y)f(ha)o(v)o(e)h(b)q(een)h Fp(deferred)p +Fo(.)38 b(A)21 b(moun)o(t)g(is)g(deferred)h(if)g(extra)90 1950 +y(information)11 b(is)h(required)g(b)q(efore)f(the)h(moun)o(t)e(can)h(pro)q +(ceed.)20 b(When)11 b(the)g(information)h(b)q(ecomes)f(a)o(v)m(ailable)90 +1999 y(the)k(moun)o(t)e(will)k(tak)o(e)c(place,)i(but)g(in)g(the)g(mean)f +(time)h(no)f(reply)i(is)e(sen)o(t)h(to)e(the)i(k)o(ernel.)20 +b(If)15 b(the)g(moun)o(t)e(is)90 2049 y(deferred,)i Fp(Amd)j +Fo(con)o(tin)o(ues)d(to)g(try)f(an)o(y)h(remaining)i(lo)q(cations.)62 +2141 y(Once)g(a)d(v)o(olume)i(has)f(b)q(een)i(moun)o(ted,)e +Fp(Amd)i Fo(establishes)f(a)f Fp(v)o(olume)h(mapping)k Fo(whic)o(h)c(is)g +(used)g(to)e(satisfy)0 2190 y(subsequen)o(t)i(requests.)0 2355 +y Fq(1.7)33 b(Automatic)15 b(Unmoun)n(ting)62 2446 y Fo(T)l(o)e(a)o(v)o(oid)f +(an)g(ev)o(er)h(increasing)h(n)o(um)o(b)q(er)e(of)h(\014lesystem)g(moun)o +(ts,)f Fp(Amd)i Fo(remo)o(v)o(es)e(v)o(olume)h(mappings)g(whic)o(h)0 +2496 y(ha)o(v)o(e)19 b(not)g(b)q(een)h(used)g(recen)o(tly)l(.)33 +b(A)19 b(time-to-liv)o(e)i(in)o(terv)m(al)f(is)g(asso)q(ciated)f(with)h(eac)o +(h)f(mapping)h(and)f(when)0 2545 y(that)g(expires)i(the)e(mapping)i(is)f +(remo)o(v)o(ed.)32 b(When)20 b(the)g(last)g(reference)g(to)f(a)g +(\014lesystem)i(is)f(remo)o(v)o(ed,)g(that)0 2595 y(\014lesystem)14 +b(is)h(unmoun)o(ted.)k(If)14 b(the)g(unmoun)o(t)g(fails,)g(for)f(example)i +(the)f(\014lesystem)g(is)g(still)h(busy)l(,)f(the)g(mapping)0 +2645 y(is)k(re-instated)f(and)g(its)h(time-to-liv)o(e)g(in)o(terv)m(al)g(is)g +(extended.)26 b(The)18 b(global)g(default)f(for)g(this)g(grace)g(p)q(erio)q +(d)h(is)p eop +%%Page: 5 7 +5 6 bop 0 -83 a Fo(Chapter)15 b(1:)k(Ov)o(erview)1328 b(SMM:13-5)0 +158 y(con)o(trolled)14 b(b)o(y)g(the)f(\\-w")g(command-line)i(option)f(\(see) +f(Section)h(4.11)e([-w)h(Option],)h(page)27 b(SMM:13-19\).)17 +b(It)c(is)0 208 y(also)i(p)q(ossible)i(to)e(set)g(this)g(v)m(alue)i(on)e(a)g +(p)q(er-moun)o(t)g(basis)h(\(see)f(Section)h(3.3.4.3)d([opts],)g(page)31 +b(SMM:13-15\).)62 279 y(Filesystems)20 b(can)g(b)q(e)f(forcefully)i(timed)f +(out)f(using)h(the)f Fp(Amq)h Fo(command.)32 b(See)20 b(Chapter)f(6)g +([Run-time)0 329 y(Administration],)d(page)30 b(SMM:13-27.)0 +513 y Fq(1.8)j(Keep-aliv)n(es)62 604 y Fo(Use)14 b(of)g(some)g(\014lesystem)g +(t)o(yp)q(es)g(requires)h(the)f(presence)h(of)e(a)h(serv)o(er)g(on)f(another) +h(mac)o(hine.)20 b(If)14 b(a)g(mac)o(hine)0 654 y(crashes)19 +b(then)g(it)g(is)h(of)e(no)h(concern)g(to)f(pro)q(cesses)i(on)e(that)h(mac)o +(hine)g(that)f(the)h(\014lesystem)h(is)f(una)o(v)m(ailable.)0 +704 y(Ho)o(w)o(ev)o(er,)14 b(to)h(pro)q(cesses)h(on)f(a)h(remote)f(host)g +(using)h(that)f(mac)o(hine)h(as)f(a)g(\014leserv)o(er)i(this)e(ev)o(en)o(t)h +(is)g(imp)q(ortan)o(t.)0 753 y(This)h(situation)f(is)h(most)e(widely)i +(recognised)g(when)g(an)f(NFS)g(serv)o(er)g(crashes)g(and)g(the)g(b)q(eha)o +(viour)h(observ)o(ed)0 803 y(on)h(clien)o(t)i(mac)o(hines)f(is)g(that)f(more) +g(and)h(more)f(pro)q(cesses)h(hang.)29 b(In)19 b(order)f(to)g(pro)o(vide)h +(the)g(p)q(ossibilit)o(y)h(of)0 853 y(reco)o(v)o(ery)l(,)f +Fp(Amd)h Fo(implemen)o(ts)g(a)e Fp(k)o(eep-aliv)o(e)23 b Fo(in)o(terv)m(al)c +(timer)g(for)f(some)g(\014lesystem)i(t)o(yp)q(es.)30 b(Curren)o(tly)18 +b(only)0 903 y(NFS)d(mak)o(es)g(use)g(of)g(this)h(service.)62 +973 y(The)k(basis)h(of)e(the)h(NFS)g(k)o(eep-aliv)o(e)i(implemen)o(tation)f +(is)f(the)h(observ)m(ation)f(that)f(most)g(sites)h(main)o(tain)0 +1023 y(replicated)j(copies)e(of)g(common)g(system)f(data)h(suc)o(h)g(as)g +(man)o(ual)g(pages,)h(most)e(or)h(all)g(programs,)g(system)0 +1073 y(source)c(co)q(de)g(and)g(so)f(on.)24 b(If)17 b(one)g(of)f(those)h +(serv)o(ers)f(go)q(es)h(do)o(wn)f(it)h(w)o(ould)g(b)q(e)g(reasonable)g(to)f +(moun)o(t)h(one)f(of)0 1123 y(the)f(others)g(as)g(a)g(replacemen)o(t.)62 +1193 y(The)j(\014rst)g(part)f(of)h(the)g(pro)q(cess)g(is)h(to)e(k)o(eep)h +(trac)o(k)f(of)h(whic)o(h)g(\014leserv)o(ers)h(are)f(up)g(and)g(whic)o(h)h +(are)f(do)o(wn.)0 1243 y Fp(Amd)j Fo(do)q(es)e(this)g(b)o(y)g(sending)h(RPC)f +(requests)f(to)h(the)f(serv)o(ers')g(NFS)h Fl(NullProc)f Fo(and)h(c)o(hec)o +(king)g(whether)g(a)0 1293 y(reply)13 b(is)f(returned.)19 b(While)13 +b(the)f(serv)o(er)f(state)g(is)h(uncertain)h(the)f(requests)g(are)f +(re-transmitted)h(at)f(three)g(second)0 1343 y(in)o(terv)m(als)19 +b(and)g(if)f(no)h(reply)g(is)f(receiv)o(ed)i(after)d(four)h(attempts)f(the)i +(serv)o(er)f(is)g(mark)o(ed)g(do)o(wn.)29 b(If)18 b(a)g(reply)h(is)0 +1393 y(receiv)o(ed)f(the)g(\014leserv)o(er)f(is)h(mark)o(ed)f(up)g(and)h(sta) +o(ys)e(in)i(that)e(state)h(for)f(30)h(seconds)g(at)g(whic)o(h)h(time)f +(another)0 1442 y(NFS)e(ping)h(is)g(sen)o(t.)62 1513 y(Once)21 +b(a)f(\014leserv)o(er)g(is)h(mark)o(ed)e(do)o(wn,)h(requests)g(con)o(tin)o +(ue)h(to)e(b)q(e)h(sen)o(t)g(ev)o(ery)g(30)f(seconds)h(in)h(order)f(to)0 +1563 y(determine)c(when)g(the)f(\014leserv)o(er)h(comes)f(bac)o(k)g(up.)21 +b(During)15 b(this)h(time)f(an)o(y)g(reference)h(through)f +Fp(Amd)i Fo(to)e(the)0 1613 y(\014lesystems)h(on)f(that)g(serv)o(er)g(fail)h +(with)g(the)f(error)g(\\Op)q(eration)h(w)o(ould)g(blo)q(c)o(k".)21 +b(If)15 b(a)h(replacemen)o(t)g(v)o(olume)f(is)0 1662 y(a)o(v)m(ailable)i +(then)e(it)h(will)h(b)q(e)f(moun)o(ted,)e(otherwise)i(the)f(error)g(is)g +(returned)h(to)e(the)i(user.)62 1733 y(Although)g(this)g(action)g(do)q(es)g +(not)f(protect)g(user)g(\014les,)h(whic)o(h)h(are)e(unique)i(on)e(the)h(net)o +(w)o(ork,)e(or)h(pro)q(cesses)0 1783 y(whic)o(h)g(do)g(not)f(access)h +(\014les)g(via)g Fp(Amd)h Fo(or)e(already)h(ha)o(v)o(e)f(op)q(en)i(\014les)f +(on)f(the)h(h)o(ung)g(\014lesystem,)g(it)f(can)h(prev)o(en)o(t)0 +1833 y(most)f(new)i(pro)q(cesses)f(from)g(hanging.)62 1903 +y(By)k(default,)g(\014leserv)o(er)h(state)d(is)i(not)f(main)o(tained)i(for)e +(NFS/TCP)f(moun)o(ts.)30 b(The)18 b(remote)g(\014leserv)o(er)h(is)0 +1953 y(alw)o(a)o(ys)14 b(assumed)i(to)e(b)q(e)i(up.)0 2135 +y Fq(1.9)33 b(Non-blo)r(c)n(king)16 b(Op)r(eration)62 2226 +y Fo(Since)e(there)f(is)g(only)g(one)g(instance)g(of)f Fp(Amd)j +Fo(for)d(eac)o(h)g(automoun)o(t)g(p)q(oin)o(t,)h(and)f(usually)i(only)f(one)g +(instance)0 2276 y(on)18 b(eac)o(h)g(mac)o(hine,)h(it)g(is)f(imp)q(ortan)o(t) +g(that)f(it)h(is)h(alw)o(a)o(ys)e(a)o(v)m(ailable)j(to)d(service)i(k)o(ernel) +g(calls.)30 b Fp(Amd)20 b Fo(go)q(es)e(to)0 2325 y(great)12 +b(lengths)h(to)g(ensure)g(that)f(it)h(do)q(es)g(not)g(blo)q(c)o(k)g(in)h(a)f +(system)f(call.)20 b(As)13 b(a)g(last)f(resort)g Fp(Amd)j Fo(will)f(fork)f(b) +q(efore)0 2375 y(it)j(attempts)e(a)i(system)f(call)i(that)d(ma)o(y)h(blo)q(c) +o(k)i(inde\014nitely)l(,)h(suc)o(h)e(as)f(moun)o(ting)h(an)f(NFS)h +(\014lesystem.)22 b(Other)0 2425 y(tasks)12 b(suc)o(h)g(as)h(obtaining)g +(\014lehandle)i(information)d(for)g(an)g(NFS)h(\014lesystem,)g(are)f(done)h +(using)g(a)f(purp)q(ose)i(built)0 2475 y(non-blo)q(c)o(king)i(RPC)f(library)g +(whic)o(h)g(is)g(in)o(tegrated)f(with)h Fp(Amd)r Fo('s)f(task)g(sc)o +(heduler.)21 b(This)15 b(library)g(is)g(also)f(used)0 2525 +y(to)h(implemen)o(t)h(NFS)f(k)o(eep-aliv)o(es)i(\(see)e(Section)h(1.8)e +([Keep-aliv)o(es],)i(page)30 b(SMM:13-5\).)62 2595 y(Whenev)o(er)11 +b(a)f(moun)o(t)g(is)g(deferred)h(or)f(bac)o(kgrounded,)h Fp(Amd)i +Fo(m)o(ust)c(w)o(ait)h(for)g(it)g(to)g(complete)h(b)q(efore)g(replying)0 +2645 y(to)f(the)i(k)o(ernel.)19 b(Ho)o(w)o(ev)o(er,)10 b(this)i(w)o(ould)f +(cause)h Fp(Amd)h Fo(to)d(blo)q(c)o(k)i(w)o(aiting)f(for)f(a)h(reply)h(to)f +(b)q(e)g(constructed.)19 b(Rather)p eop +%%Page: 6 8 +6 7 bop 15 -83 a Fo(SMM:13-6)912 b(4.4)15 b(BSD)g(Automoun)o(ter)f(Reference) +j(Man)o(ual)0 158 y(than)h(do)g(this,)h Fp(Amd)h Fo(simply)f +Fp(drops)h Fo(the)e(call)h(under)g(the)f(assumption)g(that)f(the)h(k)o(ernel) +h(RPC)f(mec)o(hanism)0 208 y(will)f(automatically)e(retry)g(the)g(request.)0 +445 y Fm(2)41 b(Supp)r(orted)15 b(Platforms)62 590 y Fp(Amd)20 +b Fo(has)e(b)q(een)g(p)q(orted)g(to)f(a)h(wide)h(v)m(ariet)o(y)e(of)h(mac)o +(hines)g(and)g(op)q(erating)g(systems.)27 b(The)18 b(table)g(b)q(elo)o(w)0 +640 y(lists)e(those)f(platforms)g(supp)q(orted)g(b)o(y)g(the)h(curren)o(t)f +(release.)0 852 y Fq(2.1)33 b(Supp)r(orted)16 b(Op)r(erating)g(Systems)62 +943 y Fo(The)j(follo)o(wing)g(op)q(erating)f(systems)g(are)g(curren)o(tly)g +(supp)q(orted)h(b)o(y)f Fp(Amd)p Fo(.)30 b Fp(Amd)r Fo('s)17 +b(con)o(v)o(en)o(tional)i(name)0 993 y(for)c(eac)o(h)g(system)g(is)g(giv)o +(en.)0 1064 y Fl(acis43)96 b Fo(4.3)14 b(BSD)i(for)e(IBM)i(R)l(T.)f(Con)o +(tributed)g(b)o(y)g(Jan-Simon)i(P)o(endry)e Fl()0 +1132 y(aix3)144 b Fo(AIX)16 b(3.1.)j(Con)o(tributed)c(b)o(y)g(Jan-Simon)i(P)o +(endry)e Fl()0 1200 y(aux)168 b Fo(System)15 +b(V)g(for)g(Mac-I)q(I.)h(Con)o(tributed)f(b)o(y)g(Julian)i(Onions)f +Fl()0 1269 y(bsd44)120 b Fo(4.4)14 b(BSD.)h(Con)o +(tributed)h(b)o(y)f(Jan-Simon)h(P)o(endry)f Fl()0 +1337 y(concentrix)240 1405 y Fo(Concen)o(trix)g(5.0.)k(Con)o(tributed)d(b)o +(y)f(Sjo)q(erd)g(Mullender)j Fl()0 1473 y(convex)96 +b Fo(Con)o(v)o(ex)15 b(OS)g(7.1.)k(Con)o(tributed)d(b)o(y)f(Eitan)g +(Mizrotsky)g Fl()0 1542 y(dgux)144 b Fo(Data)14 +b(General)i(DG/UX.)e(Con)o(tributed)h(b)o(y)g(Mark)g(Da)o(vies)g +Fl()0 1610 y(fpx4)144 b Fo(Celerit)o(y)16 +b(FPX)f(4.1/2.)j(Con)o(tributed)d(b)o(y)h(Stephen)g(P)o(op)q(e)f +Fl()0 1678 y(hcx)168 b Fo(Harris)15 +b(HCX/UX.)g(Con)o(tributed)g(b)o(y)g(Chris)h(Metcalf)f Fl +()0 1746 y(hlh42)120 b Fo(HLH)16 +b(OTS)f(1.)p Fp(x)j Fo(\(4.2)c(BSD\).)g(Con)o(tributed)i(b)o(y)f(Jan-Simon)h +(P)o(endry)g Fl()0 1815 y(hpux)144 b Fo(HP-UX)16 +b(6.)p Fp(x)h Fo(or)e(7.0.)k(Con)o(tributed)c(b)o(y)g(Jan-Simon)i(P)o(endry)e +Fl()0 1883 y(irix)144 b Fo(SGI)15 b(Irix.)21 +b(Con)o(tributed)16 b(b)o(y)f(Scott)f(R.)i(Presnell)g Fl()0 +1951 y(next)144 b Fo(Mac)o(h)15 b(for)f(NeXT.)h(Con)o(tributed)h(b)o(y)f +(Bill)i(T)l(rost)d Fl()0 2019 y(pyrOSx)96 +b Fo(Pyramid)15 b(OSx.)21 b(Con)o(tributed)15 b(b)o(y)g(Stefan)h(P)o(etri)f +Fl()0 2088 y(riscix)96 b Fo(Acorn)15 b(RISC)h(iX.)g(Con)o +(tributed)f(b)o(y)g(Piete)h(Bro)q(oks)f Fl()0 +2156 y(sos3)144 b Fo(SunOS)17 b(3.4)d(&)h(3.5.)k(Con)o(tributed)d(b)o(y)f +(Jan-Simon)h(P)o(endry)f Fl()0 2224 y(sos4)144 +b Fo(SunOS)17 b(4.)p Fp(x)p Fo(.)i(Con)o(tributed)c(b)o(y)g(Jan-Simon)i(P)o +(endry)e Fl()0 2292 y(u2_2)144 b Fo(Ultrix)16 +b(2.2.)j(Con)o(tributed)c(b)o(y)g(Piete)h(Bro)q(oks)f Fl()0 +2361 y(u3_0)144 b Fo(Ultrix)16 b(3.)k(Con)o(tributed)15 b(b)o(y)g(Piete)h +(Bro)q(oks)f Fl()0 2429 y(u4_0)144 b Fo(Ultrix)16 +b(4.0.)j(Con)o(tributed)c(b)o(y)g(Chris)h(Lindblad)i Fl()0 +2497 y(umax43)96 b Fo(Umax)15 b(4.3)f(BSD.)h(Con)o(tributed)g(b)o(y)h(Sjo)q +(erd)f(Mullender)i Fl()0 2565 y(utek)144 b Fo(Utek)15 +b(4.0.)k(Con)o(tributed)c(b)o(y)h(Bill)h(T)l(rost)d Fl +()0 2634 y(xinu43)96 b Fo(m)o(t)14 +b(Xin)o(u)j(MORE/bsd.)j(Con)o(tributed)15 b(b)o(y)h(Jan-Simon)g(P)o(endry)f +Fl()p eop +%%Page: 7 9 +7 8 bop 0 -83 a Fo(Chapter)15 b(3:)k(Moun)o(t)c(Maps)1258 b(SMM:13-7)0 +158 y Fq(2.2)33 b(Supp)r(orted)16 b(Mac)n(hine)g(Arc)n(hitectures)0 +250 y Fl(alliant)72 b Fo(Allian)o(t)17 b(FX/4)0 313 y Fl(arm)168 +b Fo(Acorn)15 b(ARM)0 377 y Fl(aviion)96 b Fo(Data)14 b(General)i(A)-5 +b(ViiON)0 440 y Fl(encore)96 b Fo(Encore)0 504 y Fl(fps500)g +Fo(FPS)15 b(Mo)q(del)h(500)0 567 y Fl(hp9000)96 b Fo(HP)15 +b(9000/300)e(family)0 631 y Fl(hp9k8)120 b Fo(HP)15 b(9000/800)e(family)0 +694 y Fl(ibm032)96 b Fo(IBM)15 b(R)l(T)0 758 y Fl(ibm6000)72 +b Fo(IBM)15 b(RISC)i(System/6000)0 821 y Fl(iris4d)96 b Fo(SGI)15 +b(Iris)h(4D)0 885 y Fl(macII)120 b Fo(Apple)17 b(Mac)d(I)q(I)0 +948 y Fl(mips)144 b Fo(MIPS)15 b(RISC)0 1012 y Fl(multimax)48 +b Fo(Encore)15 b(Multimax)0 1075 y Fl(orion105)48 b Fo(HLH)16 +b(Orion)g(1/05)0 1139 y Fl(sun3)144 b Fo(Sun-3)16 b(family)0 +1202 y Fl(sun4)144 b Fo(Sun-4)16 b(family)0 1266 y Fl(tahoe)120 +b Fo(T)l(aho)q(e)15 b(family)0 1329 y Fl(vax)168 b Fo(DEC)15 +b(V)l(ax)0 1513 y Fm(3)41 b(Moun)n(t)15 b(Maps)62 1639 y Fp(Amd)k +Fo(has)f(no)f(built-in)i(kno)o(wledge)f(of)f(mac)o(hines)h(or)e +(\014lesystems.)27 b(External)17 b Fp(moun)o(t-maps)i Fo(are)e(used)h(to)0 +1688 y(pro)o(vide)12 b(the)g(required)h(information.)19 b(Sp)q(eci\014cally)l +(,)c Fp(Amd)f Fo(needs)e(to)f(kno)o(w)g(when)h(and)g(under)h(what)e +(conditions)0 1738 y(it)k(should)i(moun)o(t)d(\014lesystems.)62 +1809 y(The)k(map)e(en)o(try)h(corresp)q(onding)h(to)e(the)h(requested)h(name) +f(con)o(tains)g(a)g(list)h(of)e(p)q(ossible)j(lo)q(cations)f(from)0 +1859 y(whic)o(h)e(to)f(resolv)o(e)h(the)f(request.)21 b(Eac)o(h)15 +b(lo)q(cation)i(sp)q(eci\014es)g(\014lesystem)f(t)o(yp)q(e,)f(information)h +(required)g(b)o(y)g(that)0 1908 y(\014lesystem)11 b(\(for)f(example)h(the)g +(blo)q(c)o(k)g(sp)q(ecial)h(device)g(in)g(the)e(case)h(of)f(UFS\),)g(and)g +(some)g(information)h(describing)0 1958 y(where)k(to)f(moun)o(t)h(the)g +(\014lesystem)g(\(see)g(Section)h(3.3.4.2)c([fs)j(Option],)g(page)29 +b(SMM:13-14\).)18 b(A)d(lo)q(cation)h(ma)o(y)0 2008 y(also)f(con)o(tain)h +Fp(selectors)h Fo(\(see)e(Section)h(3.3.3)e([Selectors],)g(page)31 +b(SMM:13-13\).)0 2184 y Fq(3.1)i(Map)15 b(T)n(yp)r(es)62 2276 +y Fo(A)k(moun)o(t-map)f(pro)o(vides)i(the)f(run-time)g(con\014guration)g +(information)g(to)f Fp(Amd)p Fo(.)31 b(Maps)19 b(can)g(b)q(e)g(imple-)0 +2325 y(men)o(ted)f(in)h(man)o(y)f(w)o(a)o(ys.)27 b(Some)18 +b(of)g(the)g(forms)f(supp)q(orted)i(b)o(y)f Fp(Amd)i Fo(are)e(regular)g +(\014les,)h(ndbm)g(databases,)0 2375 y(NIS)d(maps)f(the)g Fp(Hesio)q(d)j +Fo(name)d(serv)o(er)g(and)h(ev)o(en)f(the)g(passw)o(ord)g(\014le.)62 +2446 y(A)g(moun)o(t-map)f Fp(name)k Fo(is)d(a)f(sequence)i(of)f(c)o +(haracters.)k(When)c(an)f(automoun)o(t)g(p)q(oin)o(t)h(is)g(created)g(a)g +(handle)0 2496 y(on)j(the)h(moun)o(t-map)f(is)g(obtained.)31 +b(F)l(or)17 b(eac)o(h)i(map)f(t)o(yp)q(e)g(con\014gured)h Fp(Amd)i +Fo(attempts)c(to)h(reference)h(the)f(a)0 2545 y(map)g(of)g(the)h(appropriate) +f(t)o(yp)q(e.)29 b(If)19 b(a)f(map)g(is)h(found,)g Fp(Amd)i +Fo(notes)d(the)g(t)o(yp)q(e)h(for)e(future)i(use)f(and)h(deletes)0 +2595 y(the)14 b(reference,)g(for)f(example)i(closing)g(an)o(y)e(op)q(en)h +(\014le)h(descriptors.)20 b(The)14 b(a)o(v)m(ailable)h(maps)f(are)f +(con\014gure)h(when)0 2645 y Fp(Amd)j Fo(is)f(built)g(and)g(can)f(b)q(e)h +(displa)o(y)o(ed)h(b)o(y)e(running)h(the)f(command)g(`)p Fl(amd)g(-v)p +Fo('.)p eop +%%Page: 8 10 +8 9 bop 15 -83 a Fo(SMM:13-8)912 b(4.4)15 b(BSD)g(Automoun)o(ter)f(Reference) +j(Man)o(ual)62 158 y(By)i(default,)g Fp(Amd)h Fo(cac)o(hes)f(data)f(in)h(a)f +(mo)q(de)g(dep)q(enden)o(t)i(on)e(the)h(t)o(yp)q(e)f(of)g(map.)29 +b(This)19 b(is)g(the)f(same)g(as)0 208 y(sp)q(ecifying)g(`)p +Fl(cache:=mapdefault)p Fo(')13 b(and)k(selects)f(a)g(suitable)i(default)e +(cac)o(he)h(mo)q(de)f(dep)q(ending)j(on)d(the)g(map)0 258 y(t)o(yp)q(e.)j +(The)12 b(individual)k(defaults)c(are)g(describ)q(ed)i(b)q(elo)o(w.)20 +b(The)12 b Fp(cac)o(he)j Fo(option)e(can)f(b)q(e)h(sp)q(eci\014ed)h(on)e +(automoun)o(t)0 308 y(p)q(oin)o(ts)j(to)f(alter)g(the)h(cac)o(hing)g(b)q(eha) +o(viour)g(\(see)g(Section)g(5.8)f([Automoun)o(t)f(Filesystem],)i(page)28 +b(SMM:13-24\).)62 378 y(The)13 b(follo)o(wing)f(map)g(t)o(yp)q(es)g(ha)o(v)o +(e)g(b)q(een)h(implemen)o(ted,)h(though)e(some)g(are)f(not)h(a)o(v)m(ailable) +i(on)e(all)h(mac)o(hines.)0 428 y(Run)j(the)f(command)g(`)p +Fl(amd)g(-v)p Fo(')f(to)h(obtain)g(a)g(list)h(of)f(map)g(t)o(yp)q(es)g +(con\014gured)h(on)f(y)o(our)g(mac)o(hine.)0 582 y Fi(3.1.1)30 +b(File)15 b(maps)62 673 y Fo(When)i Fp(Amd)i Fo(searc)o(hes)e(a)f(\014le)i +(for)e(a)g(map)g(en)o(try)h(it)g(do)q(es)f(a)h(simple)h(scan)f(of)f(the)h +(\014le)g(and)g(supp)q(orts)g(b)q(oth)0 723 y(commen)o(ts)e(and)g(con)o(tin)o +(uation)h(lines.)62 794 y(Con)o(tin)o(uation)g(lines)h(are)e(indicated)i(b)o +(y)e(a)g(bac)o(kslash)h(c)o(haracter)e(\(`)p Fl(\\)p Fo('\))g(as)h(the)g +(last)h(c)o(haracter)e(of)h(a)g(line)i(in)0 843 y(the)h(\014le.)30 +b(The)18 b(bac)o(kslash,)h(newline)h(c)o(haracter)e Fp(and)g(an)o(y)g +(leading)i(white)e(space)h(on)f(the)g(follo)o(wing)h(line)j +Fo(are)0 893 y(discarded.)g(A)16 b(maxim)o(um)g(line)h(length)f(of)g(2047)e +(c)o(haracters)h(is)h(enforced)g(after)f(con)o(tin)o(uation)h(lines)i(are)d +(read)0 943 y(but)h(b)q(efore)h(commen)o(ts)f(are)g(stripp)q(ed.)24 +b(Eac)o(h)16 b(line)i(m)o(ust)e(end)h(with)g(a)f(newline)i(c)o(haracter;)e +(that)f(is)i(newlines)0 993 y(are)e(terminators,)f(not)h(separators.)j(The)e +(follo)o(wing)g(examples)g(illustrate)g(this:)120 1063 y Fl(key)119 +b(valA)71 b(valB;)g(\\)359 1113 y(valC)62 1205 y Fo(sp)q(eci\014es)17 +b Fp(three)h Fo(lo)q(cations,)e(and)f(is)h(iden)o(tical)h(to)120 +1275 y Fl(key)119 b(valA)71 b(valB;)g(valC)62 1366 y Fo(Ho)o(w)o(ev)o(er,)120 +1437 y Fl(key)119 b(valA)71 b(valB;\\)359 1487 y(valC)62 1578 +y Fo(sp)q(eci\014es)17 b(only)f Fp(t)o(w)o(o)g Fo(lo)q(cations,)g(and)f(is)h +(iden)o(tical)h(to)120 1649 y Fl(key)119 b(valA)71 b(valB;valC)62 +1740 y Fo(After)20 b(a)h(complete)g(line)h(has)f(b)q(een)g(read)g(from)f(the) +h(\014le,)h(including)h(con)o(tin)o(uations,)f Fp(Amd)h Fo(determines)0 +1790 y(whether)d(there)g(is)h(a)e(commen)o(t)h(on)f(the)i(line.)35 +b(A)20 b(commen)o(t)g(b)q(egins)h(with)f(a)g(hash)g(\(\\`)p +Fl(#)p Fo('"\))e(c)o(haracter)h(and)0 1840 y(con)o(tin)o(ues)12 +b(to)g(the)f(end)i(of)e(the)h(line.)21 b(There)12 b(is)g(no)g(w)o(a)o(y)e(to) +i(escap)q(e)g(or)f(c)o(hange)h(the)g(commen)o(t)f(lead-in)j(c)o(haracter.)62 +1910 y(Note)f(that)g(con)o(tin)o(uation)h(lines)h(and)f(commen)o(t)f(supp)q +(ort)g Fp(only)18 b Fo(apply)d(to)e(\014le)h(maps,)f(or)g(ndbm)h(maps)g +(built)0 1960 y(with)i(the)f Fl(mk-amd-map)f Fo(program.)62 +2031 y(When)e(cac)o(hing)f(is)h(enabled,)h(\014le)f(maps)e(ha)o(v)o(e)h(a)f +(default)i(cac)o(he)f(mo)q(de)g(of)g Fl(all)f Fo(\(see)h(Section)h(5.8)e +([Automoun)o(t)0 2080 y(Filesystem],)15 b(page)30 b(SMM:13-24\).)0 +2234 y Fi(3.1.2)g(ndbm)15 b(maps)62 2325 y Fo(An)20 b(ndbm)f(map)g(ma)o(y)g +(b)q(e)h(used)f(as)g(a)g(fast)f(access)h(form)g(of)f(a)h(\014le)h(map.)32 +b(The)19 b(program,)g Fl(mk-amd-map)p Fo(,)0 2375 y(con)o(v)o(erts)c(a)g +(normal)g(map)g(\014le)h(in)o(to)g(an)f(ndbm)h(database.)k(This)c(program)e +(supp)q(orts)h(the)h(same)f(con)o(tin)o(uation)0 2425 y(and)f(commen)o(t)f +(con)o(v)o(en)o(tions)h(that)f(are)g(pro)o(vided)i(for)e(\014le)h(maps.)19 +b(Note)14 b(that)f(ndbm)h(format)e(\014les)j(ma)o(y)e Fp(not)h +Fo(b)q(e)0 2475 y(sharable)h(across)f(mac)o(hine)i(arc)o(hitectures.)j(The)c +(notion)g(of)f(sp)q(eed)i(generally)g(only)f(applies)h(to)e(large)h(maps;)f +(a)0 2525 y(small)i(map,)f(less)g(than)g(a)g(single)i(disk)f(blo)q(c)o(k,)f +(is)h(almost)f(certainly)h(b)q(etter)f(implemen)o(ted)i(as)e(a)g(\014le)h +(map.)62 2595 y(ndbm)e(maps)e(do)h(not)f(supp)q(ort)h(cac)o(he)g(mo)q(de)f(`) +p Fl(all)p Fo(')g(and,)h(when)g(cac)o(hing)g(is)h(enabled,)g(ha)o(v)o(e)e(a)g +(default)i(cac)o(he)0 2645 y(mo)q(de)h(of)g(`)p Fl(inc)p Fo(')f(\(see)h +(Section)h(5.8)f([Automoun)o(t)f(Filesystem],)h(page)30 b(SMM:13-24\).)p +eop +%%Page: 9 11 +9 10 bop 0 -83 a Fo(Chapter)15 b(3:)k(Moun)o(t)c(Maps)1258 +b(SMM:13-9)0 158 y Fi(3.1.3)30 b(NIS)15 b(maps)62 250 y Fo(When)j(using)h +(NIS)f(\(formerly)f(YP\),)g(an)g Fp(Amd)j Fo(map)d(is)h(implemen)o(ted)i +(directly)f(b)o(y)e(the)h(underlying)h(NIS)0 299 y(map.)f(Commen)o(ts)11 +b(and)h(con)o(tin)o(uation)g(lines)h(are)f Fp(not)g Fo(supp)q(orted)g(in)g +(the)g(automoun)o(ter)f(and)g(m)o(ust)g(b)q(e)i(stripp)q(ed)0 +349 y(when)j(constructing)f(the)g(NIS)h(serv)o(er's)f(database.)62 +420 y(NIS)j(maps)e(do)h(not)f(supp)q(ort)h(cac)o(he)f(mo)q(de)h +Fl(all)f Fo(and,)h(when)g(cac)o(hing)h(is)f(enabled,)h(ha)o(v)o(e)e(a)g +(default)i(cac)o(he)0 470 y(mo)q(de)d(of)g Fl(inc)g Fo(\(see)g(Section)h(5.8) +e([Automoun)o(t)h(Filesystem],)g(page)30 b(SMM:13-24\).)62 +540 y(The)15 b(follo)o(wing)h(rule)f(illustrates)h(what)e(could)h(b)q(e)h +(added)f(to)f(y)o(our)g(NIS)i(`)p Fl(Makefile)p Fo(',)c(in)k(this)f(case)f +(causing)0 590 y(the)h(`)p Fl(amd.home)p Fo(')f(map)h(to)f(b)q(e)i(rebuilt:) +120 661 y Fl($\(YPTSDIR\)/amd.home.time:)k($\(ETCDIR\)/amd.home)311 +710 y(-@sed)j(-e)h("s/#.*$$//")e(-e)i("/^$$/d")e($\(ETCDIR\)/amd.home)g(|)i +(\\)359 760 y(awk)f('{)48 b(\\)526 810 y(for)23 b(\(i)h(=)f(1;)h(i)g(<=)f +(NF;)h(i++\))f(\\)621 860 y(if)h(\(i)f(==)h(NF\))f({)h(\\)717 +910 y(if)f(\(substr\($$i,)f(length\($$i\),)h(1\))g(==)h("\\\\"\))f(\\)812 +959 y(printf\("\045s",)f(substr\($$i,)h(1,)g(length\($$i\))g(-)g(1\)\);)120 +1009 y(\\)717 1059 y(else)g(\\)812 1109 y(printf\("\045s\\n",)f($$i\);)h(\\) +621 1159 y(})h(\\)621 1209 y(else)f(\\)717 1258 y(printf\("\045s)f(",)i +($$i\);)f(\\)430 1308 y(}')h(|)g(\\)311 1358 y($\(MAKEDBM\))e(-)i +($\(YPDBDIR\)/amd.home;)d(\\)311 1408 y(touch)i($\(YPTSDIR\)/amd.home.time;)e +(\\)311 1458 y(echo)i("updated)g(amd.home";)f(\\)311 1507 y(if)h([)h(!)g +($\(NOPUSH\))f(];)g(then)g(\\)502 1557 y($\(YPPUSH\))f(amd.home;)h(\\)502 +1607 y(echo)g("pushed)g(amd.home";)g(\\)311 1657 y(else)g(\\)502 +1707 y(:)h(;)f(\\)311 1757 y(fi)62 1848 y Fo(Here)16 b Fl($\(YPTSDIR\))e +Fo(con)o(tains)h(the)g(time)h(stamp)e(\014les,)i(and)f Fl($\(YPDBDIR\))f +Fo(con)o(tains)i(the)f(dbm)g(format)f(NIS)0 1898 y(\014les.)0 +2083 y Fi(3.1.4)30 b(Hesio)r(d)15 b(maps)62 2174 y Fo(When)f(the)g(map)g +(name)f(b)q(egins)i(with)f(the)g(string)g(`)p Fl(hesiod.)p +Fo(')e(lo)q(okups)i(are)f(made)h(using)h(the)e Fp(Hesio)q(d)k +Fo(name)0 2224 y(serv)o(er.)i(The)13 b(string)g(follo)o(wing)g(the)g(dot)g +(is)g(used)h(as)e(a)h(name)g(quali\014er)h(and)f(is)h(prep)q(ended)h(with)e +(the)g(k)o(ey)g(b)q(eing)0 2274 y(lo)q(cated.)24 b(The)16 b(en)o(tire)h +(string)f(is)h(then)g(resolv)o(ed)g(in)g(the)f Fl(automount)f +Fo(con)o(text.)23 b(F)l(or)15 b(example,)j(if)e(the)h(the)f(k)o(ey)0 +2324 y(is)f(`)p Fl(jsp)p Fo(')e(and)h(map)h(name)f(is)h(`)p +Fl(hesiod.homes)p Fo(')d(then)i Fp(Hesio)q(d)k Fo(is)c(ask)o(ed)h(to)e +(resolv)o(e)i(`)p Fl(jsp.homes.automount)p Fo(')o(.)62 2394 +y(Hesio)q(d)21 b(maps)e(do)g(not)g(supp)q(ort)g(cac)o(he)g(mo)q(de)h(`)p +Fl(all)p Fo(')e(and,)i(when)g(cac)o(hing)g(is)f(enabled,)j(ha)o(v)o(e)c(a)h +(default)0 2444 y(cac)o(he)c(mo)q(de)h(of)f(`)p Fl(inc)p Fo(')f(\(see)h +(Section)h(5.8)e([Automoun)o(t)g(Filesystem],)h(page)31 b(SMM:13-24\).)62 +2515 y(The)16 b(follo)o(wing)g(is)f(an)g(example)h(of)f(a)g +Fp(Hesio)q(d)j Fo(map)d(en)o(try:)120 2585 y Fl(jsp.homes.automount)21 +b(HS)j(TXT)f("rfs:=/home/charm;rhost:=cha)o(rm;subli)o(nk:=jsp)o(")120 +2635 y(njw.homes.automount)e(HS)j(TXT)f("rfs:=/home/dylan/dk2;rhost:)o +(=dylan;s)o(ublink:)o(=njw")p eop +%%Page: 10 12 +10 11 bop 15 -83 a Fo(SMM:13-10)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 158 y Fi(3.1.5)30 b(P)n(assw)n(ord)16 +b(maps)62 250 y Fo(The)g(passw)o(ord)g(map)f(supp)q(ort)i(is)f(unlik)o(e)i +(the)e(four)f(previous)i(map)f(t)o(yp)q(es.)22 b(When)16 b(the)h(map)e(name)h +(is)h(the)0 299 y(string)g(`)p Fl(/etc/passwd)p Fo(')d Fp(Amd)19 +b Fo(can)e(lo)q(okup)h(a)e(user)h(name)g(in)h(the)f(passw)o(ord)f(\014le)i +(and)f(re-arrange)f(the)h(home)0 349 y(directory)e(\014eld)i(to)d(pro)q(duce) +j(a)d(usable)j(map)e(en)o(try)l(.)62 420 y Fp(Amd)20 b Fo(assumes)e(the)g +(home)g(directory)g(has)g(the)g(format)f(`)p Fl(/)p Fp(an)o(ydir)s +Fl(/)p Fp(dom1)t Fl(/../)p Fp(domN)5 b Fl(/)p Fp(login)p Fo('.)27 +b(It)18 b(breaks)0 470 y(this)d(string)g(in)o(to)g(a)f(map)g(en)o(try)h +(where)g Fl(${rfs})f Fo(has)g(the)h(v)m(alue)h(`)p Fl(/)p Fp(an)o(ydir)s +Fl(/)p Fp(domN)5 b Fo(',)14 b Fl(${rhost})f Fo(has)i(the)g(v)m(alue)0 +519 y(`)p Fp(domN)5 b Fl(.)p Fp(...)p Fl(.)p Fp(dom1)t Fo(',)12 +b(and)j Fl(${sublink})f Fo(has)h(the)g(v)m(alue)i(`)p Fl(login)p +Fo('.)62 590 y(Th)o(us)e(if)h(the)f(passw)o(ord)g(\014le)h(en)o(try)f(w)o(as) +120 661 y Fl(/home/achilles/jsp)62 752 y Fo(the)h(map)f(en)o(try)f(used)i(b)o +(y)f Fp(Amd)i Fo(w)o(ould)f(b)q(e)120 823 y Fl(rfs:=/home/achilles;rhost:)o +(=achill)o(es;subli)o(nk:=jsp)62 914 y Fo(Similarly)l(,)h(if)f(the)f(passw)o +(ord)g(\014le)h(en)o(try)f(w)o(as)120 984 y Fl(/home/cc/sugar/mjh)62 +1076 y Fo(the)h(map)f(en)o(try)f(used)i(b)o(y)f Fp(Amd)i Fo(w)o(ould)f(b)q(e) +120 1146 y Fl(rfs:=/home/sugar;rhost:=su)o(gar.cc;)o(sublink:)o(=jsp)0 +1279 y Fi(3.1.6)30 b(Union)15 b(maps)62 1371 y Fo(The)d(union)h(map)e(supp)q +(ort)g(is)h(pro)o(vided)h(sp)q(eci\014cally)h(for)d(use)h(with)f(the)h(union) +h(\014lesystem,)f(see)g(Section)g(5.10)0 1420 y([Union)k(Filesystem],)f(page) +30 b(SMM:13-25.)62 1491 y(It)17 b(is)g(iden)o(ti\014ed)h(b)o(y)e(the)h +(string)f(`)p Fl(union:)p Fo(')f(whic)o(h)i(is)g(follo)o(w)o(ed)g(b)o(y)f(a)g +(colon)h(separated)f(list)h(of)f(directories.)0 1541 y(The)e(directories)g +(are)f(read)g(in)i(order,)e(and)g(the)h(names)f(of)g(all)h(en)o(tries)g(are)f +(recorded)h(in)g(the)f(map)h(cac)o(he.)19 b(Later)0 1591 y(directories)f(tak) +o(e)e(precedence)j(o)o(v)o(er)d(earlier)i(ones.)25 b(The)18 +b(union)g(\014lesystem)f(t)o(yp)q(e)g(then)h(uses)f(the)g(map)g(cac)o(he)0 +1640 y(to)e(determine)h(the)f(union)h(of)f(the)g(names)h(in)g(all)g(the)f +(directories.)0 1790 y Fq(3.2)33 b(Ho)n(w)14 b(k)n(eys)h(are)g(lo)r(ok)n(ed)h +(up)62 1881 y Fo(The)g(k)o(ey)f(is)h(lo)q(cated)g(in)g(the)g(map)f(whose)g(t) +o(yp)q(e)g(w)o(as)g(determined)i(when)e(the)h(automoun)o(t)e(p)q(oin)o(t)i(w) +o(as)e(\014rst)0 1931 y(created.)19 b(In)14 b(general)g(the)f(k)o(ey)g(is)h +(a)f(pathname)g(comp)q(onen)o(t.)19 b(In)14 b(some)f(circumstances)h(this)f +(ma)o(y)g(b)q(e)h(mo)q(di\014ed)0 1981 y(b)o(y)h(v)m(ariable)i(expansion)f +(\(see)f(Section)h(3.3.2)e([V)l(ariable)i(Expansion],)f(page)31 +b(SMM:13-12\))13 b(and)j(pre\014xing.)21 b(If)0 2031 y(the)13 +b(automoun)o(t)e(p)q(oin)o(t)i(has)g(a)f(pre\014x,)h(sp)q(eci\014ed)i(b)o(y)e +(the)f Fp(pref)22 b Fo(option,)13 b(then)g(that)f(is)h(prep)q(ended)h(to)e +(the)h(searc)o(h)0 2081 y(k)o(ey)i(b)q(efore)h(the)f(map)g(is)h(searc)o(hed.) +62 2151 y(If)e(the)f(map)g(cac)o(he)h(is)g(a)e(`)p Fl(regexp)p +Fo(')g(cac)o(he)i(then)f(the)h(k)o(ey)f(is)h(treated)e(as)h(an)g(egrep-st)o +(yle)h(regular)f(expression,)0 2201 y(otherwise)i(a)g(normal)g(string)h +(comparison)f(is)h(made.)62 2271 y(If)k(the)f(k)o(ey)h(cannot)f(b)q(e)h +(found)g(then)f(a)g Fp(wildcard)k Fo(matc)o(h)c(is)h(attempted.)31 +b Fp(Amd)22 b Fo(rep)q(eatedly)e(strips)g(the)0 2321 y(basename)15 +b(from)f(the)h(k)o(ey)l(,)f(app)q(ends)i(`)p Fl(/*)p Fo(')e(and)h(attempts)e +(a)i(lo)q(okup.)20 b(Finally)l(,)c Fp(Amd)h Fo(attempts)d(to)g(lo)q(cate)h +(the)0 2371 y(sp)q(ecial)i(k)o(ey)e(`)p Fl(*)p Fo('.)62 2421 +y(F)l(or)g(example,)g(the)h(follo)o(wing)g(sequence)g(w)o(ould)g(b)q(e)g(c)o +(hec)o(k)o(ed)f(if)h(`)p Fl(home/dylan/dk2)p Fo(')c(w)o(as)j(b)q(eing)h(lo)q +(cated:)192 2492 y Fl(home/dylan/dk2)192 2541 y(home/dylan/*)192 +2591 y(home/*)192 2641 y(*)p eop +%%Page: 11 13 +11 12 bop 0 -83 a Fo(Chapter)15 b(3:)k(Moun)o(t)c(Maps)1236 +b(SMM:13-11)62 158 y(A)o(t)14 b(an)o(y)f(p)q(oin)o(t)h(when)h(a)e(wildcard)i +(is)g(found,)f Fp(Amd)i Fo(pro)q(ceeds)e(as)g(if)g(an)g(exact)f(matc)o(h)h +(had)g(b)q(een)h(found)f(and)0 208 y(the)19 b(v)m(alue)h(\014eld)g(is)f(then) +g(used)g(to)f(resolv)o(e)h(the)g(moun)o(t)f(request,)h(otherwise)g(an)f +(error)g(co)q(de)h(is)h(propagated)0 258 y(bac)o(k)15 b(to)g(the)g(k)o +(ernel.)21 b(\(see)15 b(Chapter)g(5)f([Filesystem)i(T)o(yp)q(es],)f(page)30 +b(SMM:13-20\).)0 437 y Fq(3.3)j(Lo)r(cation)15 b(F)-6 b(ormat)62 +528 y Fo(The)17 b(v)m(alue)h(\014eld)f(from)f(the)h(lo)q(okup)g(pro)o(vides)g +(the)f(information)h(required)h(to)d(moun)o(t)h(a)g(\014lesystem.)25 +b(The)0 578 y(information)15 b(is)h(parsed)f(according)h(to)f(the)g(syn)o +(tax)f(sho)o(wn)h(b)q(elo)o(w.)120 648 y Fp(lo)q(cation-list)q +Fo(:)393 698 y Fp(lo)q(cation-selection)393 748 y(lo)q(cation-list)j +(white-space)g Fl(||)d Fp(white-space)k(lo)q(cation-selection)120 +798 y(lo)q(cation-selection)p Fo(:)393 848 y Fp(lo)q(cation)393 +897 y(lo)q(cation-selection)e(white-space)i(lo)q(cation)120 +947 y(lo)q(cation)p Fo(:)393 997 y Fp(lo)q(cation-info)393 +1047 y Fl(-)p Fp(lo)q(cation-info)393 1097 y Fl(-)120 1147 +y Fp(lo)q(cation-info)r Fo(:)393 1196 y Fp(sel-or-opt)393 1246 +y(lo)q(cation-info)r Fl(;)p Fp(sel-or-opt)393 1296 y Fl(;)120 +1346 y Fp(sel-or-opt)q Fo(:)393 1396 y Fp(selection)393 1445 +y(opt-ass)120 1495 y(selection)p Fo(:)393 1545 y(selector)p +Fl(==)p Fp(v)m(alue)393 1595 y Fo(selector)p Fl(!=)p Fp(v)m(alue)120 +1645 y(opt-ass)r Fo(:)393 1694 y(option)p Fl(:=)p Fp(v)m(alue)120 +1744 y(white-space)s Fo(:)393 1794 y(space)393 1844 y(tab)62 +1935 y(Note)g(that)f(unquoted)h(whitespace)h(is)f(not)f(allo)o(w)o(ed)h(in)h +(a)e(lo)q(cation)i(description.)32 b(White)19 b(space)g(is)g(only)0 +1985 y(allo)o(w)o(ed,)c(and)h(is)f(mandatory)l(,)f(where)i(sho)o(wn)f(with)g +(non-terminal)i(`)p Fl(white-space)p Fo('.)62 2056 y(A)j Fp(lo)q +(cation-selection)h Fo(is)f(a)f(list)h(of)f(p)q(ossible)i(v)o(olumes)f(with)f +(whic)o(h)i(to)d(satisfy)h(the)h(request.)32 b Fp(lo)q(cation-)0 +2105 y(selection)p Fo(s)23 b(are)f(separated)f(b)o(y)h(the)g(`)p +Fl(||)p Fo(')f(op)q(erator.)39 b(The)22 b(e\013ect)f(of)h(this)g(op)q(erator) +f(is)h(to)g(prev)o(en)o(t)f(use)h(of)0 2155 y(lo)q(cation-selections)d(to)c +(its)i(righ)o(t)f(if)h(an)o(y)f(of)g(the)g(lo)q(cation-selections)j(on)d(its) +h(left)f(w)o(ere)g(selected)i(whether)e(or)0 2205 y(not)f(an)o(y)g(of)f(them) +i(w)o(ere)f(successfully)i(moun)o(ted)e(\(see)g(Section)h(3.3.3)e +([Selectors],)g(page)31 b(SMM:13-13\).)62 2276 y(The)17 b(lo)q +(cation-selection,)h(and)e(singleton)h Fp(lo)q(cation-list)p +Fo(,)h(`)p Fl(type:=ufs;dev:=/dev/)o(xd1g)p Fo(')12 b(w)o(ould)17 +b(inform)0 2325 y Fp(Amd)g Fo(to)e(moun)o(t)f(a)h(UFS)g(\014lesystem)h(from)f +(the)g(blo)q(c)o(k)h(sp)q(ecial)h(device)g(`)p Fl(/dev/xd1g)p +Fo('.)62 2396 y(The)h Fp(sel-or-opt)g Fo(comp)q(onen)o(t)f(is)h(either)f(the) +h(name)f(of)f(an)h(option)h(required)g(b)o(y)f(a)g(sp)q(eci\014c)i +(\014lesystem,)e(or)0 2446 y(it)h(is)g(the)g(name)f(of)h(a)f(built-in,)j +(prede\014ned)f(selector)f(suc)o(h)g(as)g(the)f(arc)o(hitecture)h(t)o(yp)q +(e.)28 b(The)17 b(v)m(alue)i(ma)o(y)e(b)q(e)0 2496 y(quoted)g(with)g(double)h +(quotes)f(`)p Fl(")p Fo(',)f(for)g(example)i(`)p Fl(type:="ufs";dev:="/dev/)o +(xd1g")p Fo(')o(.)k(These)c(quotes)e(are)0 2545 y(stripp)q(ed)k(when)g(the)g +(v)m(alue)g(is)g(parsed)f(and)h(there)f(is)h(no)f(w)o(a)o(y)f(to)h(get)g(a)g +(double)h(quote)f(in)o(to)h(a)f(v)m(alue)h(\014eld.)0 2595 +y(Double)h(quotes)g(are)f(used)h(to)f(get)h(white)g(space)g(in)o(to)f(a)h(v)m +(alue)h(\014eld,)h(whic)o(h)e(is)g(needed)h(for)e(the)h(program)0 +2645 y(\014lesystem)16 b(\(see)f(Section)h(5.5)e([Program)g(Filesystem],)h +(page)30 b(SMM:13-23\).)p eop +%%Page: 12 14 +12 13 bop 15 -83 a Fo(SMM:13-12)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 158 y Fi(3.3.1)30 b(Map)15 b(Defaults)62 +250 y Fo(A)h(lo)q(cation)h(b)q(eginning)h(with)e(a)g(dash)g(`)p +Fl(-)p Fo(')f(is)h(used)h(to)e(sp)q(ecify)i(default)g(v)m(alues)g(for)e +(subsequen)o(t)i(lo)q(cations.)0 299 y(An)o(y)12 b(previously)i(sp)q +(eci\014ed)g(defaults)f(in)g(the)f(lo)q(cation-list)i(are)e(discarded.)20 +b(The)13 b(default)g(string)f(can)g(b)q(e)h(empt)o(y)0 349 +y(in)j(whic)o(h)g(case)f(no)g(defaults)h(apply)l(.)62 420 y(The)c(lo)q +(cation)h(`)p Fl(-fs:=/mnt;opts:=ro)p Fo(')8 b(w)o(ould)k(set)g(the)f(lo)q +(cal)i(moun)o(t)e(p)q(oin)o(t)h(to)f(`)p Fl(/mnt)p Fo(')g(and)h(cause)g(moun) +o(ts)0 470 y(to)h(b)q(e)g(read-only)h(b)o(y)f(default.)20 b(Defaults)13 +b(sp)q(eci\014ed)i(this)f(w)o(a)o(y)e(are)h(app)q(ended)i(to,)d(and)i(so)e(o) +o(v)o(erride,)i(an)o(y)e(global)0 519 y(map)j(defaults)h(giv)o(en)f(with)h(`) +p Fl(/defaults)p Fo('\).)0 805 y Fi(3.3.2)30 b(V)-5 b(ariable)15 +b(Expansion)62 896 y Fo(T)l(o)g(allo)o(w)g(generic)h(lo)q(cation)g(sp)q +(eci\014cations)h Fp(Amd)g Fo(do)q(es)e(v)m(ariable)i(expansion)f(on)f(eac)o +(h)g(lo)q(cation)h(and)f(also)0 946 y(on)f(some)f(of)g(the)h(option)g +(strings.)19 b(An)o(y)13 b(option)h(or)f(selector)h(app)q(earing)h(in)f(the)g +(form)f Fl($)p Fp(v)m(ar)j Fo(is)e(replaced)h(b)o(y)f(the)0 +996 y(curren)o(t)f(v)m(alue)i(of)e(that)g(option)h(or)f(selector.)19 +b(F)l(or)13 b(example,)h(if)g(the)g(v)m(alue)h(of)e Fl(${key})f +Fo(w)o(as)h(`)p Fl(bin)p Fo(',)f Fl(${autodir})0 1046 y Fo(w)o(as)k(`)p +Fl(/a)p Fo(')f(and)i Fl(${fs})f Fo(w)o(as)g(`)p Fl(${autodir}/local/${key})p +Fo(')d(then)k(after)f(expansion)i Fl(${fs})e Fo(w)o(ould)h(ha)o(v)o(e)f(the)0 +1095 y(v)m(alue)g(`)p Fl(/a/local/bin)p Fo('.)i(An)o(y)d(en)o(vironmen)o(t)h +(v)m(ariable)g(can)f(b)q(e)h(accessed)g(in)g(a)f(similar)h(w)o(a)o(y)l(.)62 +1166 y(Tw)o(o)f(pathname)g(op)q(erators)g(are)g(a)o(v)m(ailable)i(when)f +(expanding)h(a)e(v)m(ariable.)23 b(If)16 b(the)f(v)m(ariable)i(name)f(b)q +(egins)0 1216 y(with)h(`)p Fl(/)p Fo(')g(then)g(only)h(the)f(last)g(comp)q +(onen)o(t)g(of)g(then)g(pathname)g(is)h(substituted.)26 b(F)l(or)16 +b(example,)i(if)g Fl(${path})0 1266 y Fo(w)o(as)f(`)p Fl(/foo/bar)p +Fo(')e(then)j Fl(${/path})e Fo(w)o(ould)i(b)q(e)g(expanded)h(to)d(`)p +Fl(bar)p Fo('.)26 b(Similarly)l(,)20 b(if)e(the)f(v)m(ariable)i(name)e(ends)0 +1315 y(with)f(`)p Fl(/)p Fo(')e(then)h(all)i(but)e(the)g(last)g(comp)q(onen)o +(t)h(of)f(the)g(pathname)g(is)h(substituted.)k(In)c(the)g(previous)f +(example,)0 1365 y Fl(${path/})f Fo(w)o(ould)i(b)q(e)g(expanded)g(to)e(`)p +Fl(/foo)p Fo('.)62 1436 y(Tw)o(o)i(domain)g(name)h(op)q(erators)e(are)h(also) +g(pro)o(vided.)24 b(If)16 b(the)h(v)m(ariable)g(name)f(b)q(egins)i(with)f(`)p +Fl(.)p Fo(')e(then)h(only)0 1486 y(the)h(domain)g(part)f(of)g(the)g(name)h +(is)g(substituted.)25 b(F)l(or)16 b(example,)h(if)g Fl(${rhost})e +Fo(w)o(as)h(`)p Fl(swan.doc.ic.ac.uk)p Fo(')0 1535 y(then)g +Fl(${.rhost})f Fo(w)o(ould)i(b)q(e)f(expanded)h(to)f(`)p Fl(doc.ic.ac.uk)p +Fo('.)k(Similarly)l(,)e(if)e(the)h(v)m(ariable)g(name)f(ends)h(with)0 +1585 y(`)p Fl(.)p Fo(')h(then)h(only)g(the)g(host)f(comp)q(onen)o(t)h(is)g +(substituted.)31 b(In)19 b(the)g(previous)g(example,)h Fl(${rhost.})d +Fo(w)o(ould)i(b)q(e)0 1635 y(expanded)d(to)f(`)p Fl(swan)p +Fo('.)62 1706 y(V)l(ariable)k(expansion)f(is)g(a)f(t)o(w)o(o)f(phase)h(pro)q +(cess.)26 b(Before)18 b(a)f(lo)q(cation)h(is)f(parsed,)h(all)g(references)g +(to)f(selec-)0 1755 y(tors,)f Fp(eg)k Fl(${path})p Fo(,)c(are)g(expanded.)25 +b(The)17 b(lo)q(cation)g(is)g(then)g(parsed,)g(selections)h(are)e(ev)m +(aluated)i(and)f(option)0 1805 y(assignmen)o(ts)h(recorded.)31 +b(If)19 b(there)g(w)o(ere)f(no)h(selections)h(or)e(they)g(all)i(succeeded)g +(the)f(lo)q(cation)g(is)h(used)f(and)0 1855 y(the)c(v)m(alues)h(of)f(the)g +(follo)o(wing)h(options)f(are)g(expanded)h(in)g(the)f(order)g(giv)o(en:)20 +b Fp(sublink)p Fo(,)d Fp(rfs)p Fo(,)d Fp(fs)p Fo(,)h Fp(opts)p +Fo(,)f Fp(remopts)p Fo(,)0 1905 y Fp(moun)o(t)i Fo(and)f Fp(unmoun)o(t)p +Fo(.)62 1975 y(Note)f(that)f(expansion)h(of)g(option)f(v)m(alues)i(is)g(done) +f(after)f Fp(all)j Fo(assignmen)o(ts)e(ha)o(v)o(e)f(b)q(een)i(completed)f +(and)g(not)0 2025 y(in)20 b(a)f(purely)h(left)g(to)e(righ)o(t)h(order)g(as)g +(is)g(done)h(b)o(y)f(the)g(shell.)33 b(This)20 b(generally)g(has)f(the)h +(desired)g(e\013ect)f(but)0 2075 y(care)14 b(m)o(ust)g(b)q(e)h(tak)o(en)f(if) +g(one)h(of)f(the)g(options)h(references)g(another,)e(in)i(whic)o(h)h(case)e +(the)g(ordering)h(can)f(b)q(ecome)0 2125 y(signi\014can)o(t.)62 +2195 y(There)i(are)f(t)o(w)o(o)e(sp)q(ecial)k(cases)f(concerning)g(v)m +(ariable)h(expansion:)25 2266 y(1.)29 b(b)q(efore)12 b(a)f(map)h(is)g +(consulted,)h(an)o(y)e(selectors)h(in)g(the)g(name)g(receiv)o(ed)h(from)d +(the)i(k)o(ernel)h(are)e(expanded.)20 b(F)l(or)90 2316 y(example,)f(if)f(the) +f(request)h(from)e(the)i(k)o(ernel)g(w)o(as)f(for)g(`)p Fl(${arch}.bin)p +Fo(')e(and)j(the)f(mac)o(hine)i(arc)o(hitecture)90 2366 y(w)o(as)14 +b(`)p Fl(vax)p Fo(',)g(the)h(v)m(alue)i(giv)o(en)e(to)g Fl(${key})f +Fo(w)o(ould)i(b)q(e)g(`)p Fl(vax.bin)p Fo('.)25 2446 y(2.)29 +b(the)13 b(v)m(alue)h(of)e Fl(${rhost})g Fo(is)h(expanded)h(and)f(normalized) +i(b)q(efore)e(the)g(other)f(options)h(are)g(expanded.)20 b(The)90 +2496 y(normalization)g(pro)q(cess)g(strips)g(an)o(y)f(lo)q(cal)i(sub-domain)g +(comp)q(onen)o(ts.)33 b(F)l(or)19 b(example,)i(if)f Fl(${domain})90 +2545 y Fo(w)o(as)12 b(`)p Fl(Berkeley.EDU)p Fo(')e(and)j Fl(${rhost})f +Fo(w)o(as)g(initially)j(`)p Fl(snow.Berkeley.EDU)p Fo(',)10 +b(after)i(the)h(normalization)90 2595 y(it)21 b(w)o(ould)g(simply)h(b)q(e)g +(`)p Fl(snow)p Fo('.)35 b(Hostname)21 b(normalization)g(is)h(curren)o(tly)f +(done)g(in)h(a)e Fp(case-dep)q(enden)o(t)90 2645 y Fo(manner.)p +eop +%%Page: 13 15 +13 14 bop 0 -83 a Fo(Chapter)15 b(3:)k(Moun)o(t)c(Maps)1236 +b(SMM:13-13)0 158 y Fi(3.3.3)30 b(Selectors)62 250 y Fo(Selectors)15 +b(are)g(used)g(to)f(con)o(trol)g(the)h(use)g(of)f(a)h(lo)q(cation.)20 +b(It)15 b(is)g(p)q(ossible)h(to)e(share)h(a)f(moun)o(t)g(map)h(b)q(et)o(w)o +(een)0 299 y(man)o(y)c(mac)o(hines)h(in)g(suc)o(h)g(a)f(w)o(a)o(y)g(that)f +(\014lesystem)i(lo)q(cation,)h(arc)o(hitecture)f(and)f(op)q(erating)h(system) +f(di\013erences)0 349 y(are)18 b(hidden)j(from)d(the)h(users.)31 +b(A)18 b(selector)h(of)g(the)g(form)f(`)p Fl(arch==sun3;os==sos4)p +Fo(')d(w)o(ould)k(only)g(apply)h(on)0 399 y(Sun-3s)c(running)g(SunOS)h(4.x.) +62 470 y(Selectors)22 b(are)f(ev)m(aluated)h(left)g(to)e(righ)o(t.)38 +b(If)21 b(a)g(selector)g(fails)h(then)g(that)e(lo)q(cation)i(is)g(ignored.)38 +b(Th)o(us)0 519 y(the)21 b(selectors)h(form)f(a)g(conjunction)h(and)g(the)f +(lo)q(cations)h(form)f(a)g(disjunction.)40 b(If)21 b(all)i(the)e(lo)q +(cations)h(are)0 569 y(ignored)17 b(or)f(otherwise)h(fail)h(then)f +Fp(Amd)h Fo(uses)f(the)g Fp(error)i Fo(\014lesystem)e(\(see)g(Section)g(5.11) +f([Error)f(Filesystem],)0 619 y(page)43 b(SMM:13-26\).)38 b(This)22 +b(is)g(equiv)m(alen)o(t)i(to)d(ha)o(ving)h(a)f(lo)q(cation)i(`)p +Fl(type:=error)p Fo(')c(at)i(the)h(end)h(of)e(eac)o(h)0 669 +y(moun)o(t-map)15 b(en)o(try)l(.)62 739 y(The)h(selectors)f(curren)o(tly)h +(implemen)o(ted)h(are:)0 823 y(`)p Fl(arch)p Fo(')118 b(the)19 +b(mac)o(hine)g(arc)o(hitecture)g(whic)o(h)g(w)o(as)e(automatically)i +(determined)h(at)e(compile)i(time.)30 b(The)240 873 y(arc)o(hitecture)16 +b(t)o(yp)q(e)f(can)h(b)q(e)g(displa)o(y)o(ed)h(b)o(y)e(running)i(the)f +(command)f(`)p Fl(amd)f(-v)p Fo('.)20 b(See)d(Section)f(2.2)240 +923 y([Supp)q(orted)g(Mac)o(hine)g(Arc)o(hitectures],)f(page)30 +b(SMM:13-7.)0 985 y(`)p Fl(autodir)p Fo(')46 b(the)16 b(default)h(directory)g +(under)g(whic)o(h)g(to)f(moun)o(t)g(\014lesystems.)24 b(This)17 +b(ma)o(y)f(b)q(e)h(c)o(hanged)g(b)o(y)f(the)240 1035 y(\\-a")e(command)i +(line)g(option.)21 b(See)15 b(the)h Fp(fs)g Fo(option.)0 1098 +y(`)p Fl(byte)p Fo(')118 b(the)16 b(mac)o(hine's)g(b)o(yte)f(ordering.)21 +b(This)c(is)f(either)g(`)p Fl(little)p Fo(',)e(indicating)j(little-endian,)h +(or)e(`)p Fl(big)p Fo(',)240 1148 y(indicating)k(big-endian.)31 +b(One)18 b(p)q(ossible)i(use)f(is)f(to)g(share)g(`)p Fl(rwho)p +Fo(')e(databases)i(\(see)g(Section)h(8.5)240 1197 y([rwho)c(serv)o(ers],)h +(page)32 b(SMM:13-49\).)21 b(Another)16 b(is)g(to)g(share)g(ndbm)h +(databases,)e(ho)o(w)o(ev)o(er)h(this)240 1247 y(use)g(can)f(b)q(e)h +(considered)g(a)f(courageous)g(juggling)h(act.)0 1310 y(`)p +Fl(cluster)p Fo(')46 b(is)19 b(pro)o(vided)h(as)e(a)h(ho)q(ok)g(for)f(the)h +(name)g(of)f(the)h(lo)q(cal)h(cluster.)32 b(This)19 b(can)g(b)q(e)h(used)f +(to)f(decide)240 1360 y(whic)o(h)h(serv)o(ers)f(to)g(use)g(for)g(copies)h(of) +f(replicated)i(\014lesystems.)30 b Fl(${cluster})16 b Fo(defaults)j(to)f(the) +240 1410 y(v)m(alue)e(of)f Fl(${domain})f Fo(unless)i(a)f(di\013eren)o(t)h(v) +m(alue)g(is)g(set)f(with)g(the)h(\\-C")e(command)h(line)i(option.)0 +1472 y(`)p Fl(domain)p Fo(')70 b(the)15 b(lo)q(cal)i(domain)e(name)g(as)g(sp) +q(eci\014ed)j(b)o(y)d(the)g(\\-d")g(command)g(line)i(option.)j(See)c(`)p +Fl(host)p Fo('.)0 1535 y(`)p Fl(host)p Fo(')118 b(the)13 b(lo)q(cal)h +(hostname)e(as)h(determined)h(b)o(y)f Fk(gethostname)p Fo(\(2\).)18 +b(If)13 b(no)g(domain)g(name)g(w)o(as)f(sp)q(eci\014ed)240 +1585 y(on)19 b(the)g(command)f(line)j(and)e(the)f(hostname)h(con)o(tains)g(a) +f(p)q(erio)q(d)i(`)p Fl(.)p Fo(')e(then)h(the)g(string)g(b)q(efore)240 +1635 y(the)i(p)q(erio)q(d)g(is)g(used)g(as)f(the)h(host)f(name,)h(and)g(the)f +(string)h(after)e(the)i(p)q(erio)q(d)h(is)f(assigned)g(to)240 +1684 y Fl(${domain})p Fo(.)d(F)l(or)13 b(example,)h(if)f(the)h(hostname)f(is) +g(`)p Fl(styx.doc.ic.ac.uk)p Fo(')d(then)k Fl(host)f Fo(w)o(ould)g(b)q(e)240 +1734 y(`)p Fl(styx)p Fo(')h(and)h Fl(domain)g Fo(w)o(ould)g(b)q(e)h(`)p +Fl(doc.ic.ac.uk)p Fo('.)h Fl(hostd)e Fo(w)o(ould)h(b)q(e)f(`)p +Fl(styx.doc.ic.ac.uk)p Fo('.)0 1797 y(`)p Fl(hostd)p Fo(')94 +b(is)16 b Fl(${host})e Fo(and)i Fl(${domain})e Fo(concatenated)h(with)h(a)f +(`)p Fl(.)p Fo(')f(inserted)i(b)q(et)o(w)o(een)g(them)f(if)h(required.)240 +1847 y(If)f Fl(${domain})f Fo(is)i(an)f(empt)o(y)g(string)g(then)h +Fl(${host})e Fo(and)h Fl(${hostd})f Fo(will)j(b)q(e)f(iden)o(tical.)0 +1909 y(`)p Fl(karch)p Fo(')94 b(is)13 b(pro)o(vided)g(as)f(a)g(ho)q(ok)h(for) +e(the)i(k)o(ernel)g(arc)o(hitecture.)19 b(This)13 b(is)g(used)g(on)g(SunOS)g +(4,)g(for)e(example,)240 1959 y(to)i(distinguish)i(b)q(et)o(w)o(een)f +(di\013eren)o(t)f(`)p Fl(/usr/kvm)p Fo(')f(v)o(olumes.)20 b +Fl(${karch})12 b Fo(defaults)i(to)e(the)i(v)m(alue)g(of)240 +2009 y Fl(${arch})g Fo(unless)j(a)d(di\013eren)o(t)i(v)m(alue)g(is)g(set)f +(with)g(the)h(\\-k")e(command)i(line)g(option.)0 2072 y(`)p +Fl(os)p Fo(')166 b(the)15 b(op)q(erating)g(system.)k(Lik)o(e)d(the)f(mac)o +(hine)h(arc)o(hitecture,)f(this)g(is)g(automatically)h(determined)240 +2122 y(at)11 b(compile)h(time.)19 b(The)12 b(op)q(erating)f(system)g(name)g +(can)h(b)q(e)g(displa)o(y)o(ed)g(b)o(y)f(running)i(the)e(command)240 +2171 y(`)p Fl(amd)j(-v)p Fo('.)20 b(See)15 b(Section)h(2.1)f([Supp)q(orted)g +(Op)q(erating)h(Systems],)f(page)30 b(SMM:13-6.)62 2263 y(The)15 +b(follo)o(wing)g(selectors)g(are)f(also)h(pro)o(vided.)20 b(Unlik)o(e)c(the)f +(other)f(selectors,)h(they)f(v)m(ary)h(for)f(eac)o(h)h(lo)q(okup.)0 +2313 y(Note)h(that)h(when)g(the)g(name)g(from)f(the)h(k)o(ernel)g(is)g +(expanded)h(prior)f(to)f(a)h(map)g(lo)q(okup,)g(these)g(selectors)g(are)0 +2362 y(all)f(de\014ned)h(as)e(empt)o(y)f(strings.)0 2433 y(`)p +Fl(key)p Fo(')142 b(the)13 b(name)f(b)q(eing)i(resolv)o(ed.)19 +b(F)l(or)12 b(example,)i(if)e(`)p Fl(/home)p Fo(')f(is)i(an)g(automoun)o(t)e +(p)q(oin)o(t,)i(then)g(accessing)240 2483 y(`)p Fl(/home/foo)p +Fo(')c(w)o(ould)i(set)g Fl(${key})f Fo(to)g(the)h(string)f(`)p +Fl(foo)p Fo('.)18 b(The)11 b(k)o(ey)f(is)i(pre\014xed)f(b)o(y)g(the)g +Fp(pref)20 b Fo(option)240 2533 y(set)15 b(in)g(the)g(paren)o(t)f(moun)o(t)h +(p)q(oin)o(t.)20 b(The)15 b(default)g(pre\014x)g(is)h(an)e(empt)o(y)h +(string.)20 b(If)15 b(the)g(pre\014x)g(w)o(as)240 2582 y(`)p +Fl(blah/)p Fo(')f(then)h Fl(${key})g Fo(w)o(ould)g(b)q(e)h(set)f(to)g(`)p +Fl(blah/foo)p Fo('.)0 2645 y(`)p Fl(map)p Fo(')142 b(the)15 +b(name)g(of)g(the)h(moun)o(t)e(map)h(b)q(eing)i(used.)p eop +%%Page: 14 16 +14 15 bop 15 -83 a Fo(SMM:13-14)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 158 y(`)p Fl(path)p Fo(')118 b(the)12 +b(full)i(pathname)e(of)g(the)h(name)f(b)q(eing)i(resolv)o(ed.)19 +b(F)l(or)12 b(example)h(`)p Fl(/home/foo)p Fo(')d(in)k(the)e(example)240 +208 y(ab)q(o)o(v)o(e.)0 272 y(`)p Fl(wire)p Fo(')118 b(the)21 +b(name)g(of)g(the)g(net)o(w)o(ork)f(to)h(whic)o(h)h(the)f(primary)g(net)o(w)o +(ork)g(in)o(terface)g(is)h(attac)o(hed.)37 b(If)21 b(a)240 +322 y(sym)o(b)q(olic)i(name)e(cannot)h(b)q(e)g(found)g(in)g(the)g(net)o(w)o +(orks)e(or)h(hosts)g(database)g(then)h(dotted)g(IP)240 372 +y(address)15 b(format)f(is)i(used.)k(This)c(v)m(alue)g(is)g(also)f(output)g +(b)o(y)g(the)h(\\-v")f(option.)62 463 y(Selectors)j(can)f(b)q(e)h(negated)f +(b)o(y)h(using)f(`)p Fl(!=)p Fo(')g(instead)g(of)g(`)p Fl(==)p +Fo('.)25 b(F)l(or)16 b(example)j(to)d(select)i(a)f(lo)q(cation)h(on)f(all)0 +513 y(non-V)l(ax)f(mac)o(hines)g(the)f(selector)g(`)p Fl(arch!=vax)p +Fo(')e(w)o(ould)j(b)q(e)g(used.)0 669 y Fi(3.3.4)30 b(Map)15 +b(Options)62 760 y Fo(Options)e(are)f(parsed)g(concurren)o(tly)h(with)g +(selectors.)19 b(The)12 b(di\013erence)i(is)f(that)e(when)i(an)f(option)g(is) +h(seen)g(the)0 810 y(string)g(follo)o(wing)i(the)e(`)p Fl(:=)p +Fo(')g(is)h(recorded)g(for)e(later)i(use.)20 b(As)13 b(a)g(minim)o(um)i(the)e +Fp(t)o(yp)q(e)j Fo(option)e(m)o(ust)f(b)q(e)h(sp)q(eci\014ed.)0 +860 y(Eac)o(h)k(\014lesystem)h(t)o(yp)q(e)g(has)f(other)g(options)g(whic)o(h) +i(m)o(ust)e(also)g(b)q(e)h(sp)q(eci\014ed.)31 b(See)19 b(Chapter)g(5)f +([Filesystem)0 910 y(T)o(yp)q(es],)d(page)30 b(SMM:13-20,)13 +b(for)h(details)j(on)e(the)g(\014lesystem)h(sp)q(eci\014c)h(options.)62 +980 y(Sup)q(er\015uous)g(option)e(sp)q(eci\014cations)i(are)e(ignored)h(and)f +(are)g(not)g(rep)q(orted)g(as)g(errors.)62 1051 y(The)h(follo)o(wing)g +(options)f(apply)h(to)f(more)f(than)h(one)h(\014lesystem)g(t)o(yp)q(e.)0 +1207 y Fi(3.3.4.1)30 b(dela)n(y)15 b(Option)62 1298 y Fo(The)21 +b(dela)o(y)l(,)h(in)f(seconds,)h(b)q(efore)f(an)f(attempt)g(will)i(b)q(e)f +(made)f(to)g(moun)o(t)g(from)g(the)g(curren)o(t)h(lo)q(cation.)0 +1348 y(Auxilliary)g(data,)d(suc)o(h)g(as)g(net)o(w)o(ork)f(address,)i(\014le) +g(handles)h(and)e(so)g(on)h(are)f(computed)g(regardless)h(of)f(this)0 +1398 y(v)m(alue.)62 1468 y(A)23 b(dela)o(y)g(can)g(b)q(e)h(used)f(to)f +(implemen)o(t)i(the)f(notion)g(of)f(primary)h(and)g(secondary)g(\014le)h +(serv)o(ers.)42 b(The)0 1518 y(secondary)14 b(serv)o(ers)g(w)o(ould)h(ha)o(v) +o(e)e(a)h(dela)o(y)h(of)f(a)g(few)g(seconds,)g(th)o(us)g(giving)i(the)e +(primary)g(serv)o(ers)g(a)g(c)o(hance)h(to)0 1568 y(resp)q(ond)h(\014rst.)0 +1724 y Fi(3.3.4.2)30 b(fs)15 b(Option)62 1815 y Fo(The)h(lo)q(cal)g(moun)o(t) +f(p)q(oin)o(t.)20 b(The)15 b(seman)o(tics)h(of)f(this)g(option)h(v)m(ary)f(b) +q(et)o(w)o(een)g(\014lesystems.)62 1885 y(F)l(or)i(NFS)h(and)g(UFS)f +(\014lesystems)h(the)g(v)m(alue)h(of)e Fl(${fs})g Fo(is)h(used)g(as)f(the)h +(lo)q(cal)h(moun)o(t)e(p)q(oin)o(t.)27 b(F)l(or)17 b(other)0 +1935 y(\014lesystem)f(t)o(yp)q(es)f(it)g(has)g(other)f(meanings)i(whic)o(h)f +(are)g(describ)q(ed)i(in)f(the)f(section)g(describing)i(the)e(resp)q(ectiv)o +(e)0 1985 y(\014lesystem)d(t)o(yp)q(e.)19 b(It)11 b(is)h(imp)q(ortan)o(t)f +(that)g(this)h(string)f(uniquely)j(iden)o(ti\014es)f(the)f(\014lesystem)g(b)q +(eing)h(moun)o(ted.)18 b(T)l(o)0 2035 y(satisfy)d(this)g(requiremen)o(t,)g +(it)g(should)h(con)o(tain)f(the)g(name)g(of)f(the)h(host)f(on)h(whic)o(h)h +(the)f(\014lesystem)g(is)g(residen)o(t)0 2085 y(and)g(the)h(pathname)f(of)g +(the)g(\014lesystem)h(on)f(the)g(lo)q(cal)h(or)f(remote)g(host.)62 +2155 y(The)21 b(reason)g(for)f(requiring)i(the)f(hostname)f(is)h(clear)h(if)f +(replicated)h(\014lesystems)g(are)e(considered.)38 b(If)21 +b(a)0 2205 y(\014leserv)o(er)g(go)q(es)f(do)o(wn)f(and)i(a)e(replacemen)o(t)i +(\014lesystem)g(is)f(moun)o(ted)g(then)g(the)h Fp(lo)q(cal)i +Fo(moun)o(t)c(p)q(oin)o(t)i Fp(m)o(ust)0 2255 y Fo(b)q(e)e(di\013eren)o(t)f +(from)g(that)g(of)f(the)i(\014lesystem)g(whic)o(h)g(is)g(h)o(ung.)29 +b(Some)18 b(enco)q(ding)i(of)e(the)g(\014lesystem)h(name)f(is)0 +2305 y(required)e(if)g(more)f(than)g(one)g(\014lesystem)h(is)g(to)e(b)q(e)i +(moun)o(ted)f(from)g(an)o(y)g(giv)o(en)g(host.)62 2375 y(If)21 +b(the)f(hostname)f(is)i(\014rst)e(in)i(the)f(path)g(then)g(all)h(moun)o(ts)f +(from)f(a)h(particular)g(host)g(will)h(b)q(e)g(gathered)0 2425 +y(b)q(elo)o(w)16 b(a)e(single)j(directory)l(.)j(If)c(that)e(serv)o(er)h(go)q +(es)g(do)o(wn)f(then)i(the)f(h)o(ung)g(moun)o(t)g(p)q(oin)o(ts)g(are)g(less)h +(lik)o(ely)h(to)d(b)q(e)0 2475 y(acciden)o(tally)j(referenced,)e(for)g +(example)g(when)h Fk(get)o(wd)p Fo(\(3\))d(tra)o(v)o(erses)h(the)h(namespace) +g(to)f(\014nd)i(the)f(pathname)0 2525 y(of)g(the)g(curren)o(t)g(directory)l +(.)62 2595 y(The)i(`)p Fl(fs)p Fo(')e(option)h(defaults)g(to)g +Fl(${autodir}/${rhost}${rfs)o(})p Fo(.)k(In)c(addition,)h(`)p +Fl(rhost)p Fo(')e(defaults)h(to)g(the)0 2645 y(lo)q(cal)k(host)e(name)h(\()p +Fl(${host})p Fo(\))e(and)i(`)p Fl(rfs)p Fo(')e(defaults)i(to)f(the)h(v)m +(alue)h(of)e Fl(${path})p Fo(,)g(whic)o(h)i(is)f(the)g(full)h(path)e(of)p +eop +%%Page: 15 17 +15 16 bop 0 -83 a Fo(Chapter)15 b(3:)k(Moun)o(t)c(Maps)1236 +b(SMM:13-15)0 158 y(the)15 b(requested)h(\014le;)g(`)p Fl(/home/foo)p +Fo(')d(in)j(the)f(example)h(ab)q(o)o(v)o(e)f(\(see)g(Section)h(3.3.3)d +([Selectors],)i(page)30 b(SMM:13-)0 208 y(13\).)23 b Fl(${autodir})16 +b Fo(defaults)h(to)f(`)p Fl(/a)p Fo(')f(but)i(ma)o(y)f(b)q(e)i(c)o(hanged)f +(with)g(the)f(\\-a")g(command)h(line)h(option.)25 b(Sun's)0 +258 y(automoun)o(ter)15 b(defaults)i(to)e(`)p Fl(/tmp_mnt)p +Fo('.)22 b(Note)15 b(that)h(there)g(is)h(no)f(`)p Fl(/)p Fo(')f(b)q(et)o(w)o +(een)i(the)f Fl(${rhost})f Fo(and)i Fl(${rfs})0 308 y Fo(since)f +Fl(${rfs})f Fo(b)q(egins)h(with)g(a)f(`)p Fl(/)p Fo('.)0 437 +y Fi(3.3.4.3)30 b(opts)15 b(Option)62 528 y Fo(The)20 b(options)f(to)f(pass)h +(to)g(the)g(moun)o(t)g(system)g(call.)32 b(A)20 b(leading)g(`)p +Fl(-)p Fo(')e(is)i(silen)o(tly)h(ignored.)32 b(The)19 b(moun)o(t)0 +578 y(options)h(supp)q(orted)h(generally)g(corresp)q(ond)f(to)f(those)h(used) +h(b)o(y)f Fk(moun)o(t)p Fo(\(8\))e(and)i(are)g(listed)h(b)q(elo)o(w.)35 +b(Some)0 628 y(additional)17 b(pseudo-options)f(are)f(in)o(terpreted)g(b)o(y) +h Fp(Amd)h Fo(and)e(are)g(also)g(listed.)62 698 y(Unless)k(sp)q(eci\014cally) +h(o)o(v)o(erridden,)e(eac)o(h)f(of)g(the)g(system)g(default)h(moun)o(t)e +(options)i(applies.)28 b(An)o(y)17 b(options)0 748 y(not)12 +b(recognised)h(are)f(ignored.)19 b(If)12 b(no)g(options)h(list)g(is)f +(supplied)j(the)d(string)g(`)p Fl(rw,defaults)p Fo(')e(is)j(used)f(and)h(all) +g(the)0 798 y(system)k(default)g(moun)o(t)g(options)g(apply)l(.)26 +b(Options)18 b(whic)o(h)f(are)g(not)g(applicable)i(for)d(a)h(particular)h(op) +q(erating)0 848 y(system)d(are)h(silen)o(tly)h(ignored.)22 +b(F)l(or)15 b(example,)h(only)g(4.4)f(BSD)h(is)g(kno)o(wn)f(to)g(implemen)o +(t)i(the)f Fl(compress)f Fo(and)0 898 y Fl(spongy)f Fo(options.)0 +968 y Fl(compress)48 b Fo(Use)15 b(NFS)h(compression)f(proto)q(col.)0 +1027 y Fl(grpid)120 b Fo(Use)15 b(BSD)h(directory)f(group-id)h(seman)o(tics.) +0 1087 y Fl(intr)144 b Fo(Allo)o(w)16 b(k)o(eyb)q(oard)f(in)o(terrupts)g(on)g +(hard)h(moun)o(ts.)0 1146 y Fl(noconn)96 b Fo(Don't)14 b(mak)o(e)h(a)g +(connection)h(on)f(datagram)f(transp)q(orts.)0 1205 y Fl(nocto)120 +b Fo(No)15 b(close-to-op)q(en)h(consistency)l(.)0 1265 y Fl(nodevs)96 +b Fo(Don't)14 b(allo)o(w)i(lo)q(cal)g(sp)q(ecial)h(devices)f(on)g(this)f +(\014lesystem.)0 1324 y Fl(nosuid)96 b Fo(Don't)14 b(allo)o(w)i(set-uid)g(or) +f(set-gid)g(executables)i(on)e(this)g(\014lesystem.)0 1383 +y Fl(quota)120 b Fo(Enable)16 b(quota)f(c)o(hec)o(king)h(on)f(this)h(moun)o +(t.)0 1442 y Fl(retrans=)p Fp(n)240 1502 y Fo(The)21 b(n)o(um)o(b)q(er)g(of)f +(NFS)h(retransmits)f(made)h(b)q(efore)f(a)h(user)g(error)f(is)h(generated)f +(b)o(y)h(a)f(`)p Fl(soft)p Fo(')240 1551 y(moun)o(ted)15 b(\014lesystem,)h +(and)g(b)q(efore)f(a)g(`)p Fl(hard)p Fo(')f(moun)o(ted)i(\014lesystem)g(rep)q +(orts)f(`)p Fl(NFS)f(server)g Fp(y)o(o)o(y)o(o)240 1601 y Fl(not)h +(responding)f(still)g(trying)p Fo('.)0 1660 y Fl(ro)192 b Fo(Moun)o(t)14 +b(this)i(\014lesystem)g(readonly)l(.)0 1720 y Fl(rsize=)p Fp(n)71 +b Fo(The)12 b(NFS)g(read)f(pac)o(k)o(et)g(size.)20 b(Y)l(ou)12 +b(ma)o(y)f(need)h(to)f(set)h(this)g(if)g(y)o(ou)f(are)h(using)g(NFS/UDP)f +(through)240 1770 y(a)k(gatew)o(a)o(y)l(.)0 1829 y Fl(soft)144 +b Fo(Giv)o(e)15 b(up)h(after)e Fp(retrans)j Fo(retransmissions.)0 +1888 y Fl(spongy)96 b Fo(Lik)o(e)16 b(`)p Fl(soft)p Fo(')e(for)h(status)f +(requests,)h(and)g(`)p Fl(hard)p Fo(')f(for)g(data)h(transfers.)0 +1947 y Fl(tcp)168 b Fo(Use)15 b(TCP/IP)f(instead)h(of)f(UDP/IP)l(,)g(ignored) +h(if)g(the)g(NFS)f(implemen)o(tation)i(do)q(es)f(not)f(supp)q(ort)240 +1997 y(TCP/IP)h(moun)o(ts.)0 2056 y Fl(timeo=)p Fp(n)71 b Fo(The)15 +b(NFS)h(timeout,)e(in)i(ten)o(th-seconds,)g(b)q(efore)f(a)g(request)g(is)h +(retransmitted.)0 2116 y Fl(wsize=)p Fp(n)71 b Fo(The)21 b(NFS)h(write)f(pac) +o(k)o(et)g(size.)39 b(Y)l(ou)21 b(ma)o(y)g(need)h(to)e(set)h(this)h(if)g(y)o +(ou)f(are)g(using)h(NFS/UDP)240 2165 y(through)15 b(a)g(gatew)o(a)o(y)l(.)62 +2257 y(The)h(follo)o(wing)g(options)f(are)g(implemen)o(ted)i(b)o(y)e +Fp(Amd)p Fo(,)g(rather)g(than)g(b)q(eing)h(passed)g(to)e(the)h(k)o(ernel.)0 +2327 y Fl(nounmount)240 2387 y Fo(Con\014gures)f(the)g(moun)o(t)g(so)g(that)g +(its)g(time-to-liv)o(e)h(will)h(nev)o(er)f(expire.)20 b(This)15 +b(is)g(also)f(the)g(default)240 2436 y(for)h(some)f(\014lesystem)i(t)o(yp)q +(es.)0 2496 y Fl(ping=)p Fp(n)95 b Fo(The)16 b(in)o(terv)m(al,)h(in)g +(seconds,)f(b)q(et)o(w)o(een)h(k)o(eep-aliv)o(e)g(pings.)23 +b(When)17 b(four)f(consecutiv)o(e)h(pings)f(ha)o(v)o(e)240 +2545 y(failed)h(the)f(moun)o(t)f(p)q(oin)o(t)h(is)g(mark)o(ed)f(as)h(h)o +(ung.)21 b(This)16 b(in)o(terv)m(al)h(defaults)f(to)f(30)g(seconds.)22 +b(If)16 b(the)240 2595 y(ping)g(in)o(terv)m(al)h(is)f(less)g(than)g(zero,)f +(no)g(pings)i(are)e(sen)o(t)g(and)h(the)g(host)f(is)h(assumed)g(to)e(b)q(e)j +(alw)o(a)o(ys)240 2645 y(up.)j(By)c(default,)f(pings)h(are)f(not)g(sen)o(t)g +(for)f(an)h(NFS/TCP)g(moun)o(t.)p eop +%%Page: 16 18 +16 17 bop 15 -83 a Fo(SMM:13-16)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 158 y Fl(retry=)p Fp(n)71 b Fo(The)15 +b(n)o(um)o(b)q(er)h(of)f(times)g(to)g(retry)f(the)i(moun)o(t)e(system)h +(call.)0 220 y Fl(utimeout=)p Fp(n)240 282 y Fo(The)k(in)o(terv)m(al,)h(in)g +(seconds,)f(b)o(y)g(whic)o(h)h(the)e(moun)o(t's)g(time-to-liv)o(e)i(is)f +(extended)h(after)e(an)g(un-)240 332 y(moun)o(t)k(attempt)f(has)h(failed.)42 +b(In)23 b(fact)f(the)g(in)o(terv)m(al)h(is)g(extended)g(b)q(efore)g(the)f +(unmoun)o(t)g(is)240 382 y(attempted)13 b(to)g(a)o(v)o(oid)g(thrashing.)20 +b(The)14 b(default)g(v)m(alue)h(is)f(120)e(seconds)i(\(t)o(w)o(o)e(min)o +(utes\))i(or)f(as)g(set)240 432 y(b)o(y)i(the)g(\\-w")g(command)g(line)i +(option.)0 572 y Fi(3.3.4.4)30 b(remopts)15 b(Option)62 663 +y Fo(This)j(option)f(has)g(the)h(same)f(use)g(as)g Fl(${opts})f +Fo(but)h(applies)i(only)f(when)f(the)h(remote)e(host)h(is)h(on)f(a)g(non-)0 +713 y(lo)q(cal)g(net)o(w)o(ork.)j(F)l(or)15 b(example,)h(when)g(using)g(NFS)g +(across)e(a)i(gatew)o(a)o(y)d(it)j(is)g(often)g(necessary)f(to)g(use)h +(smaller)0 763 y(v)m(alues)g(for)e(the)g(data)g(read)g(and)h(write)g(sizes.) +20 b(This)15 b(can)g(simply)h(b)q(e)f(done)g(b)o(y)f(sp)q(ecifying)j(the)d +(small)h(v)m(alues)h(in)0 812 y Fp(remopts)p Fo(.)j(When)d(a)f(non-lo)q(cal)h +(host)f(is)h(accessed,)f(the)h(smaller)g(sizes)g(will)g(automatically)g(b)q +(e)g(used.)62 883 y Fp(Amd)21 b Fo(determines)f(whether)f(a)f(host)g(is)i(lo) +q(cal)f(b)o(y)g(examining)h(the)f(net)o(w)o(ork)f(in)o(terface)h +(con\014guration)g(at)0 933 y(startup.)24 b(An)o(y)17 b(in)o(terface)h(c)o +(hanges)f(made)g(after)f Fp(Amd)j Fo(has)e(b)q(een)h(started)e(will)j(not)d +(b)q(e)i(noticed.)26 b(The)17 b(lik)o(ely)0 983 y(e\013ect)e(will)i(b)q(e)f +(that)e(a)h(host)g(ma)o(y)f(incorrectly)j(b)q(e)e(declared)i(non-lo)q(cal.)62 +1053 y(Unless)f(otherwise)g(set,)e(the)i(v)m(alue)g(of)f Fl(${rem})f +Fo(is)i(the)f(same)g(as)g(the)g(v)m(alue)i(of)d Fl(${opts})p +Fo(.)0 1193 y Fi(3.3.4.5)30 b(sublink)16 b(Option)62 1284 y +Fo(The)22 b(sub)q(directory)h(within)g(the)e(moun)o(ted)h(\014lesystem)g(to)f +(whic)o(h)i(the)f(reference)g(should)h(p)q(oin)o(t.)39 b(This)0 +1334 y(can)16 b(b)q(e)h(used)f(to)f(prev)o(en)o(t)h(duplicate)h(moun)o(ts)f +(in)g(cases)g(where)g(m)o(ultiple)i(directories)f(in)g(the)e(same)h(moun)o +(ted)0 1384 y(\014lesystem)g(are)f(used.)0 1524 y Fi(3.3.4.6)30 +b(t)n(yp)r(e)15 b(Option)62 1615 y Fo(The)h(\014lesystem)g(t)o(yp)q(e)f(to)g +(b)q(e)h(used.)k(See)c(Chapter)f(5)g([Filesystem)h(T)o(yp)q(es],)e(page)31 +b(SMM:13-20,)13 b(for)i(a)g(full)0 1665 y(description)i(of)d(eac)o(h)i(t)o +(yp)q(e.)0 1853 y Fm(4)41 b Fh(Amd)16 b Fm(Command)g(Line)f(Options)62 +1973 y Fo(Man)o(y)g(of)g Fp(Amd)r Fo('s)g(parameters)g(can)g(b)q(e)h(set)f +(from)g(the)h(command)f(line.)22 b(The)16 b(command)f(line)i(is)f(also)f +(used)0 2022 y(to)g(sp)q(ecify)h(automoun)o(t)e(p)q(oin)o(ts)i(and)f(maps.)62 +2093 y(The)h(general)f(format)f(of)h(a)g(command)g(line)i(is)120 +2164 y Fl(amd)23 b([)p Fp(options)r Fl(])h({)g Fp(directory)k(map-name)e +Fl([-)p Fp(map-options)r Fl(])e(})g(...)62 2255 y Fo(F)l(or)11 +b(eac)o(h)h(directory)g(and)f(map-name)h(giv)o(en,)g Fp(Amd)i +Fo(establishes)f(an)e(automoun)o(t)g(p)q(oin)o(t.)19 b(The)12 +b Fp(map-options)0 2305 y Fo(ma)o(y)h(b)q(e)i(an)o(y)e(sequence)j(of)d +(options)h(or)f(selectors|see)i(Section)g(3.3)e([Lo)q(cation)h(F)l(ormat],)e +(page)28 b(SMM:13-11.)0 2355 y(The)15 b Fp(map-options)j Fo(apply)e(only)f +(to)g Fp(Amd)r Fo('s)g(moun)o(t)f(p)q(oin)o(t.)62 2425 y(`)p +Fl(type:=toplvl;cache:=mapde)o(fault;fs)o(:=${map)o(})p Fo(')c(is)j(the)f +(default)i(v)m(alue)g(for)e(the)g(map)h(options.)19 b(De-)0 +2475 y(fault)12 b(options)f(for)g(a)h(map)f(are)g(read)h(from)f(a)g(sp)q +(ecial)i(en)o(try)f(in)g(the)g(map)f(whose)h(k)o(ey)f(is)h(the)g(string)f(`)p +Fl(/defaults)p Fo('.)0 2525 y(When)16 b(default)g(options)f(are)g(giv)o(en)h +(they)f(are)g(prep)q(ended)j(to)c(an)o(y)h(options)h(sp)q(eci\014ed)h(in)f +(the)g(moun)o(t-map)e(lo-)0 2575 y(cations)h(as)g(explained)i(in.)k(See)16 +b(Section)g(3.3.1)e([Map)g(Defaults],)g(page)31 b(SMM:13-12,)13 +b(for)h(more)h(details.)62 2645 y(The)h Fp(options)h Fo(are)e(an)o(y)g(com)o +(bination)g(of)g(those)g(listed)i(b)q(elo)o(w.)p eop +%%Page: 17 19 +17 18 bop 0 -83 a Fo(Chapter)15 b(4:)k Fp(Amd)f Fo(Command)c(Line)j(Options) +899 b(SMM:13-17)62 158 y(Once)14 b(the)f(command)g(line)h(has)f(b)q(een)h +(parsed,)f(the)g(automoun)o(t)f(p)q(oin)o(ts)h(are)g(moun)o(ted.)19 +b(The)13 b(moun)o(t)g(p)q(oin)o(ts)0 208 y(are)21 b(created)g(if)g(they)g(do) +g(not)f(already)h(exist,)i(in)e(whic)o(h)h(case)f(they)g(will)i(b)q(e)e(remo) +o(v)o(ed)g(when)g Fp(Amd)i Fo(exits.)0 258 y(Finally)l(,)17 +b Fp(Amd)g Fo(disasso)q(ciates)f(itself)g(from)e(its)i(con)o(trolling)g +(terminal)g(and)f(forks)f(in)o(to)i(the)f(bac)o(kground.)62 +329 y(Note:)k(Ev)o(en)c(if)f Fp(Amd)j Fo(has)d(b)q(een)h(built)h(with)f(`)p +Fl(-DDEBUG)p Fo(')d(it)j(will)h(still)f(bac)o(kground)g(itself)g(and)f +(disasso)q(ciate)0 378 y(itself)j(from)e(the)h(con)o(trolling)g(terminal.)23 +b(T)l(o)15 b(use)h(a)g(debugger)g(it)g(is)g(necessary)g(to)f(sp)q(ecify)i(`)p +Fl(-D)e(nodaemon)p Fo(')f(on)0 428 y(the)h(command)g(line.)0 +648 y Fq(4.1)33 b Fg(-a)14 b Ff(directory)62 739 y Fo(Sp)q(eci\014es)25 +b(the)d(default)h(moun)o(t)f(directory)l(.)41 b(This)23 b(option)g(c)o +(hanges)f(the)h(v)m(ariable)g Fl(${autodir})e Fo(whic)o(h)0 +789 y(otherwise)15 b(defaults)h(to)f(`)p Fl(/a)p Fo('.)j(F)l(or)d(example,)h +(some)f(sites)g(prefer)g(`)p Fl(/amd)p Fo('.)120 860 y Fl(amd)23 +b(-a)h(/amd)f(...)0 1080 y Fq(4.2)33 b Fg(-c)14 b Ff(cac)n(he-in)n(terv)m(al) +62 1171 y Fo(Selects)k(the)e(p)q(erio)q(d,)i(in)f(seconds,)g(for)e(whic)o(h)j +(a)e(name)g(is)h(cac)o(hed)g(b)o(y)f Fp(Amd)p Fo(.)23 b(If)17 +b(no)f(reference)h(is)g(made)g(to)0 1221 y(the)e(v)o(olume)h(in)g(this)g(p)q +(erio)q(d,)g Fp(Amd)h Fo(discards)f(the)f(v)o(olume)h(name)f(to)f +(\014lesystem)i(mapping.)62 1291 y(Once)e(the)f(last)g(reference)h(to)e(a)g +(\014lesystem)i(has)f(b)q(een)h(remo)o(v)o(ed,)e Fp(Amd)j Fo(attempts)d(to)g +(unmoun)o(t)h(the)g(\014lesys-)0 1341 y(tem.)35 b(If)21 b(the)f(unmoun)o(t)h +(fails)g(the)f(in)o(terv)m(al)i(is)f(extended)g(b)o(y)g(a)f(further)g(p)q +(erio)q(d)i(as)e(sp)q(eci\014ed)i(b)o(y)f(the)f(`)p Fl(-w)p +Fo(')0 1391 y(command)15 b(line)i(option)e(or)g(b)o(y)g(the)g(`)p +Fl(utimeout)p Fo(')f(moun)o(t)g(option.)62 1461 y(The)i(default)f +Fp(cac)o(he-in)o(terv)m(al)k Fo(is)d(300)e(seconds)i(\(\014v)o(e)f(min)o +(utes\).)0 1691 y Fq(4.3)33 b Fg(-d)14 b Ff(domain)62 1782 +y Fo(Sp)q(eci\014es)i(the)e(host's)e(domain.)20 b(This)14 b(sets)g(the)f(in)o +(ternal)i(v)m(ariable)g Fl(${domain})d Fo(and)i(a\013ects)e(the)i +Fl(${hostd})0 1832 y Fo(v)m(ariable.)62 1902 y(If)i(this)h(option)f(is)h(not) +e(sp)q(eci\014ed)j(and)e(the)g(hostname)g(already)g(con)o(tains)g(the)g(lo)q +(cal)h(domain)g(then)f(that)f(is)0 1952 y(used,)g(otherwise)h(the)f(default)h +(v)m(alue)g(of)f Fl(${domain})f Fo(is)i(`)p Fl(unknown.domain)p +Fo('.)62 2023 y(F)l(or)f(example,)g(if)h(the)f(lo)q(cal)i(domain)e(w)o(as)g +(`)p Fl(doc.ic.ac.uk)p Fo(',)d Fp(Amd)17 b Fo(could)g(b)q(e)e(started)g(as)g +(follo)o(ws:)120 2093 y Fl(amd)23 b(-d)h(doc.ic.ac.uk)e(...)0 +2313 y Fq(4.4)33 b Fg(-k)14 b Ff(k)n(ernel-arc)n(hitecture)62 +2404 y Fo(Sp)q(eci\014es)19 b(the)e(k)o(ernel)g(arc)o(hitecture)g(of)f(the)g +(system.)24 b(This)17 b(is)g(usually)h(the)f(output)f(of)g(`)p +Fl(arch)e(-k)p Fo(')i(and)h(its)0 2454 y(only)d(e\013ect)f(is)h(to)f(set)g +(the)h(v)m(ariable)h Fl(${karch})p Fo(.)j(If)c(this)g(option)f(is)h(not)f +(giv)o(en,)h Fl(${karch})f Fo(has)g(the)h(same)f(v)m(alue)0 +2504 y(as)i Fl(${arch})p Fo(.)62 2575 y(This)h(w)o(ould)g(b)q(e)f(used)h(as)f +(follo)o(ws:)120 2645 y Fl(amd)23 b(-k)h(`arch)f(-k`)h(...)p +eop +%%Page: 18 20 +18 19 bop 15 -83 a Fo(SMM:13-18)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 158 y Fq(4.5)33 b Fg(-l)14 b Ff(log-option)62 +250 y Fo(Selects)j(the)e(form)f(of)h(logging)h(to)e(b)q(e)i(made.)k(Tw)o(o)14 +b(sp)q(ecial)j Fp(log-options)h Fo(are)c(recognised.)25 320 +y(1.)29 b(If)15 b Fp(log-option)h Fo(is)g(the)f(string)g(`)p +Fl(syslog)p Fo(',)e Fp(Amd)18 b Fo(will)e(use)g(the)f Fk(syslog)p +Fo(\(3\))f(mec)o(hanism.)25 384 y(2.)29 b(If)12 b Fp(log-option)h +Fo(is)g(the)f(string)g(`)p Fl(/dev/stderr)p Fo(',)e Fp(Amd)k +Fo(will)g(use)f(standard)f(error,)f(whic)o(h)i(is)g(also)f(the)g(default)90 +434 y(target)i(for)h(log)g(messages.)k(T)l(o)c(implemen)o(t)i(this,)e +Fp(Amd)i Fo(sim)o(ulates)f(the)f(e\013ect)g(of)g(the)g(`)p +Fl(/dev/fd)p Fo(')e(driv)o(er.)62 525 y(An)o(y)18 b(other)f(string)g(is)h +(tak)o(en)e(as)h(a)g(\014lename)i(to)d(use)i(for)f(logging.)26 +b(Log)17 b(messages)g(are)g(app)q(ended)i(to)e(the)0 575 y(\014le)f(if)f(it)g +(already)g(exists,)g(otherwise)g(a)f(new)h(\014le)h(is)g(created.)j(The)c +(\014le)h(is)f(op)q(ened)h(once)g(and)e(then)i(held)g(op)q(en,)0 +625 y(rather)f(than)g(b)q(eing)h(re-op)q(ened)h(for)d(eac)o(h)h(message.)62 +695 y(If)j(the)f(`)p Fl(syslog)p Fo(')e(option)j(is)f(sp)q(eci\014ed)j(but)d +(the)g(system)g(do)q(es)g(not)g(supp)q(ort)g(syslog)g(or)g(if)g(the)h(named)f +(\014le)0 745 y(cannot)e(b)q(e)h(op)q(ened)h(or)e(created,)g +Fp(Amd)i Fo(will)g(use)f(standard)f(error.)k(Error)c(messages)g(generated)g +(b)q(efore)h Fp(Amd)0 795 y Fo(has)f(\014nished)i(parsing)e(the)h(command)f +(line)i(are)e(prin)o(ted)h(on)f(standard)f(error.)62 866 y(Using)i(`)p +Fl(syslog)p Fo(')e(is)h(usually)i(b)q(est,)e(in)h(whic)o(h)g(case)f +Fp(Amd)i Fo(w)o(ould)f(b)q(e)g(started)e(as)h(follo)o(ws:)120 +936 y Fl(amd)23 b(-l)h(syslog)f(...)0 1107 y Fq(4.6)33 b Fg(-n)62 +1199 y Fo(Normalises)17 b(the)f(remote)g(hostname)g(b)q(efore)g(using)h(it.) +24 b(Normalisation)16 b(is)h(done)g(b)o(y)f(replacing)h(the)g(v)m(alue)0 +1248 y(of)e Fl(${rhost})f Fo(with)h(the)h(primary)f(name)g(returned)h(b)o(y)f +(a)g(hostname)f(lo)q(okup.)62 1319 y(This)i(option)f(should)i(b)q(e)f(used)f +(if)h(sev)o(eral)f(names)g(are)g(used)h(to)f(refer)g(to)f(a)h(single)i(host)d +(in)i(a)f(moun)o(t)g(map.)0 1490 y Fq(4.7)33 b Fg(-p)62 1581 +y Fo(Causes)14 b Fp(Amd)r Fo('s)f(pro)q(cess)h(id)g(to)f(b)q(e)h(prin)o(ted)h +(on)e(standard)g(output.)20 b(This)14 b(can)f(b)q(e)i(redirected)f(to)f(a)h +(suitable)0 1631 y(\014le)i(for)f(use)g(with)h(kill:)120 1702 +y Fl(amd)23 b(-p)h(>)g(/var/run/amd.pid)d(...)62 1793 y Fo(This)c(option)f +(only)h(has)f(an)g(a\013ect)f(if)h Fp(Amd)i Fo(is)f(running)g(in)g(daemon)f +(mo)q(de.)22 b(If)17 b Fp(Amd)h Fo(is)e(started)g(with)g(the)0 +1843 y Fl(-D)f(nodaemon)f Fo(debug)i(\015ag,)e(this)i(option)f(is)h(ignored.) +0 2014 y Fq(4.8)33 b Fg(-r)62 2105 y Fo(T)l(ells)16 b Fp(Amd)f +Fo(to)f(restart)e(existing)j(moun)o(ts)e(\(see)h(Section)h(5.14)e +([Inheritance)i(Filesystem],)f(page)27 b(SMM:13-)0 2155 y(26\).)0 +2334 y Fq(4.9)33 b Fg(-t)14 b Ff(timeout.retransmit)62 2425 +y Fo(Sp)q(eci\014es)i(the)d(RPC)g Fp(timeout)i Fo(and)e Fp(retransmit)h +Fo(in)o(terv)m(als)g(used)g(b)o(y)f(the)g(k)o(ernel)h(to)f(comm)o(unicate)h +(to)e Fp(Amd)p Fo(.)0 2475 y(These)k(are)e(used)i(to)f(set)g(the)g(`)p +Fl(timeo)p Fo(')f(and)h(`)p Fl(retrans)p Fo(')f(moun)o(t)g(options.)62 +2545 y Fp(Amd)21 b Fo(relies)g(on)e(the)g(k)o(ernel)h(RPC)f(retransmit)g(mec) +o(hanism)h(to)e(trigger)h(moun)o(t)g(retries.)32 b(The)19 b(v)m(alue)h(of)0 +2595 y(this)14 b(parameter)g(c)o(hanges)g(the)g(retry)f(in)o(terv)m(al.)21 +b(T)l(o)q(o)13 b(long)i(an)f(in)o(terv)m(al)h(giv)o(es)f(p)q(o)q(or)g(in)o +(teractiv)o(e)g(resp)q(onse,)h(to)q(o)0 2645 y(short)g(an)g(in)o(terv)m(al)h +(causes)f(excessiv)o(e)h(retries.)p eop +%%Page: 19 21 +19 20 bop 0 -83 a Fo(Chapter)15 b(4:)k Fp(Amd)f Fo(Command)c(Line)j(Options) +899 b(SMM:13-19)0 158 y Fq(4.10)32 b Fg(-v)62 250 y Fo(Prin)o(t)15 +b(v)o(ersion)h(information)f(on)g(standard)g(error)g(and)g(then)h(exit.)k +(The)15 b(output)g(is)h(of)f(the)g(form:)120 320 y Fl(amd)23 +b(5.2.1.11)g(of)h(91/03/17)f(18:04:05)f(5.3Alpha11)h(#0:)g(Sun)h(Mar)f(17)h +(18:07:28)f(GMT)g(1991)120 370 y(Built)g(by)h(pendry@vangogh.Berkeley.)o(EDU) +d(for)i(a)h(hp300)f(running)g(bsd44)g(\(big-endian\).)120 420 +y(Map)g(support)g(for:)h(root,)f(passwd,)g(union,)g(file,)g(error.)120 +470 y(FS:)g(ufs,)h(nfs,)f(nfsx,)g(host,)g(link,)h(program,)e(union,)h(auto,)h +(direct,)f(toplvl,)f(error.)120 519 y(Primary)h(network)g(is)g(128.32.130.0.) +62 611 y Fo(The)12 b(information)f(includes)i(the)f(v)o(ersion)f(n)o(um)o(b)q +(er,)h(release)g(date)f(and)g(name)g(of)g(the)g(release.)19 +b(The)11 b(arc)o(hitec-)0 661 y(ture)16 b(\(see)f(Section)i(2.2)e([Supp)q +(orted)h(Mac)o(hine)h(Arc)o(hitectures],)e(page)32 b(SMM:13-7\),)14 +b(op)q(erating)i(system)f(\(see)0 710 y(Section)j(2.1)f([Supp)q(orted)h(Op)q +(erating)g(Systems],)f(page)35 b(SMM:13-6\))15 b(and)j(b)o(yte)f(ordering)h +(are)f(also)g(prin)o(ted)0 760 y(as)e(they)g(app)q(ear)g(in)h(the)g +Fl(${os})p Fo(,)e Fl(${arch})g Fo(and)h Fl(${byte})g Fo(v)m(ariables.)0 +918 y Fq(4.11)32 b Fg(-w)15 b Ff(w)n(ait-timeout)62 1009 y +Fo(Selects)j(the)e(in)o(terv)m(al)i(in)f(seconds)g(b)q(et)o(w)o(een)g(unmoun) +o(t)g(attempts)e(after)h(the)h(initial)h(time-to-liv)o(e)g(has)f(ex-)0 +1059 y(pired.)62 1129 y(This)f(defaults)g(to)e(120)h(seconds)g(\(t)o(w)o(o)f +(min)o(utes\).)0 1293 y Fq(4.12)32 b Fg(-x)15 b Ff(opts)62 +1384 y Fo(Sp)q(eci\014es)k(the)d(t)o(yp)q(e)h(and)f(v)o(erb)q(osit)o(y)h(of)f +(log)g(messages.)23 b Fp(opts)18 b Fo(is)f(a)f(comma)g(separated)g(list)h +(selected)h(from)0 1434 y(the)d(follo)o(wing)h(options:)0 1505 +y Fl(fatal)120 b Fo(F)l(atal)15 b(errors)0 1567 y Fl(error)120 +b Fo(Non-fatal)15 b(errors)0 1629 y Fl(user)144 b Fo(Non-fatal)15 +b(user)g(errors)0 1691 y Fl(warn)144 b Fo(Reco)o(v)o(erable)16 +b(errors)0 1753 y Fl(warning)72 b Fo(Alias)16 b(for)f Fl(warn)0 +1815 y(info)144 b Fo(Information)15 b(messages)0 1877 y Fl(map)168 +b Fo(Moun)o(t)14 b(map)h(usage)0 1940 y Fl(stats)120 b Fo(Additional)17 +b(statistics)0 2002 y Fl(all)168 b Fo(All)16 b(of)f(the)h(ab)q(o)o(v)o(e)62 +2093 y(Initially)g(a)d(set)h(of)f(default)h(logging)g(\015ags)f(is)h +(enabled.)21 b(This)14 b(is)g(as)f(if)h(`)p Fl(-x)g(all,nomap,nostats)p +Fo(')d(had)j(b)q(een)0 2143 y(selected.)23 b(The)16 b(command)g(line)h(is)g +(parsed)f(and)g(logging)g(is)g(con)o(trolled)h(b)o(y)e(the)h(\\-x")g(option.) +22 b(The)16 b(v)o(ery)f(\014rst)0 2193 y(set)h(of)g(logging)h(\015ags)g(is)g +(sa)o(v)o(ed)f(and)g(can)h(not)f(b)q(e)h(subsequen)o(tly)h(disabled)h(using)e +Fp(Amq)p Fo(.)24 b(This)17 b(default)g(set)f(of)0 2243 y(options)f(is)h +(useful)g(for)f(general)h(pro)q(duction)g(use.)62 2313 y(The)h(`)p +Fl(info)p Fo(')f(messages)g(include)j(details)f(of)e(what)g(is)h(moun)o(ted)g +(and)g(unmoun)o(ted)g(and)g(when)g(\014lesystems)0 2363 y(ha)o(v)o(e)e(timed) +h(out.)k(If)c(y)o(ou)f(w)o(an)o(t)f(to)h(ha)o(v)o(e)g(the)h(default)g(set)f +(of)g(messages)g(without)g(the)h(`)p Fl(info)p Fo(')e(messages)h(then)0 +2413 y(y)o(ou)f(simply)i(need)f(`)p Fl(-x)f(noinfo)p Fo('.)19 +b(The)14 b(messages)g(giv)o(en)h(b)o(y)f(`)p Fl(user)p Fo(')f(relate)i(to)e +(errors)h(in)h(the)g(moun)o(t)e(maps,)h(so)0 2463 y(these)g(are)f(useful)i +(when)g(new)f(maps)f(are)h(installed.)21 b(The)14 b(follo)o(wing)h(table)f +(lists)g(the)g(syslog)g(priorites)g(used)h(for)0 2512 y(eac)o(h)g(of)g(the)g +(message)g(t)o(yp)q(es.)0 2583 y Fl(fatal)120 b Fo(LOG)p 342 +2583 14 2 v 17 w(CRIT)0 2645 y Fl(error)g Fo(LOG)p 342 2645 +V 17 w(ERR)p eop +%%Page: 20 22 +20 21 bop 15 -83 a Fo(SMM:13-20)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 158 y Fl(user)144 b Fo(LOG)p 342 158 +14 2 v 17 w(W)-5 b(ARNING)0 220 y Fl(warning)72 b Fo(LOG)p +342 220 V 17 w(W)-5 b(ARNING)0 281 y Fl(info)144 b Fo(LOG)p +342 281 V 17 w(INF)o(O)0 343 y Fl(debug)120 b Fo(LOG)p 342 +343 V 17 w(DEBUG)0 404 y Fl(map)168 b Fo(LOG)p 342 404 V 17 +w(DEBUG)0 466 y Fl(stats)120 b Fo(LOG)p 342 466 V 17 w(INF)o(O)62 +557 y(The)15 b(options)g(can)f(b)q(e)h(pre\014xed)h(b)o(y)e(the)h(string)f(`) +p Fl(no)p Fo(')g(to)f(indicate)j(that)e(this)h(option)g(should)g(b)q(e)g +(turned)g(o\013.)0 607 y(F)l(or)g(example,)g(to)g(obtain)g(all)h(but)g(`)p +Fl(info)p Fo(')e(messages)g(the)h(option)h(`)p Fl(-x)e(all,noinfo)p +Fo(')g(w)o(ould)h(b)q(e)h(used.)62 678 y(If)f Fp(Amd)i Fo(w)o(as)d(built)j +(with)e(debugging)h(enabled)g(the)f Fl(debug)f Fo(option)i(is)f +(automatically)g(enabled)i(regardless)0 728 y(of)e(the)g(command)g(line)i +(options.)0 889 y Fq(4.13)32 b Fg(-y)15 b Ff(NIS-domain)62 +980 y Fo(Selects)d(an)e(alternate)g(NIS)h(domain.)19 b(This)11 +b(is)f(useful)i(for)e(debugging)h(and)f(cross-domain)h(shared)f(moun)o(ting.) +0 1030 y(If)15 b(this)h(\015ag)f(is)h(sp)q(eci\014ed,)h Fp(Amd)g +Fo(immediately)g(attempts)d(to)g(bind)j(to)d(a)h(serv)o(er)g(for)g(this)g +(domain.)0 1192 y Fq(4.14)32 b Fg(-C)15 b Ff(cluster-name)62 +1283 y Fo(Sp)q(eci\014es)f(the)e(name)g(of)f(the)h(cluster)g(of)g(whic)o(h)g +(the)g(lo)q(cal)h(mac)o(hine)f(is)h(a)e(mem)o(b)q(er.)19 b(The)12 +b(only)g(e\013ect)g(is)g(to)f(set)0 1333 y(the)k(v)m(ariable)i +Fl(${cluster})p Fo(.)h(The)e Fp(cluster-name)j Fo(is)c(will)i(usually)g +(obtained)f(b)o(y)f(running)h(another)f(command)0 1383 y(whic)o(h)k(uses)f(a) +f(database)g(to)g(map)h(the)g(lo)q(cal)h(hostname)e(in)o(to)h(a)f(cluster)h +(name.)28 b Fl(${cluster})16 b Fo(can)i(then)g(b)q(e)0 1433 +y(used)f(as)f(a)f(selector)i(to)e(restrict)h(moun)o(ting)h(of)e(replicated)j +(data.)k(If)16 b(this)h(option)f(is)h(not)f(giv)o(en,)g Fl(${cluster})0 +1482 y Fo(has)f(the)g(same)g(v)m(alue)i(as)d Fl(${domain})p +Fo(.)19 b(This)d(w)o(ould)f(b)q(e)h(used)g(as)f(follo)o(ws:)120 +1553 y Fl(amd)23 b(-C)h(`clustername`)e(...)0 1708 y Fq(4.15)32 +b Fg(-D)15 b Ff(opts)62 1799 y Fo(Con)o(trols)20 b(the)h(v)o(erb)q(osit)o(y)f +(and)h(co)o(v)o(erage)f(of)g(the)g(debugging)i(trace;)h Fp(opts)f +Fo(is)f(a)f(comma)g(separated)g(list)0 1849 y(of)g(debugging)h(options.)36 +b(The)20 b(\\-D")g(option)h(is)g(only)f(a)o(v)m(ailable)j(if)d +Fp(Amd)j Fo(w)o(as)c(compiled)j(with)f(`)p Fl(-DDEBUG)p Fo('.)0 +1899 y(The)c(memory)g(debugging)h(facilities)h(are)e(only)h(a)o(v)m(ailable)h +(if)f Fp(Amd)h Fo(w)o(as)d(compiled)j(with)f(`)p Fl(-DDEBUG_MEM)p +Fo(')c(\(in)0 1948 y(addition)i(to)f(`)p Fl(-DDEBUG)p Fo('\).)62 +2019 y(The)j(most)f(common)g(options)h(to)f(use)h(are)f(`)p +Fl(-D)d(trace)p Fo(')j(and)h(`)p Fl(-D)c(test)p Fo(')j(\(whic)o(h)h(turns)f +(on)h(all)g(the)g(useful)0 2069 y(debug)e(options\).)k(See)15 +b(the)h(program)e(source)h(for)g(a)f(more)h(detailed)i(explanation)f(of)f +(the)g(a)o(v)m(ailable)i(options.)0 2258 y Fm(5)41 b(Filesystem)13 +b(T)n(yp)r(es)62 2375 y Fo(T)l(o)i(moun)o(t)g(a)g(v)o(olume,)g +Fp(Amd)i Fo(m)o(ust)e(b)q(e)h(told)f(the)g(t)o(yp)q(e)h(of)e(\014lesystem)i +(to)f(b)q(e)h(used.)k(Eac)o(h)15 b(\014lesystem)h(t)o(yp)q(e)0 +2425 y(t)o(ypically)h(requires)f(additional)g(information)g(suc)o(h)f(as)g +(the)g(\014leserv)o(er)h(name)f(for)g(NFS.)62 2496 y(F)l(rom)j(the)i(p)q(oin) +o(t)f(of)g(view)g(of)g Fp(Amd)p Fo(,)g(a)g Fp(\014lesystem)h +Fo(is)f(an)o(ything)g(that)g(can)g(resolv)o(e)g(an)g(incoming)h(name)0 +2545 y(lo)q(okup.)g(An)12 b(imp)q(ortan)o(t)f(feature)g(is)h(supp)q(ort)g +(for)f(m)o(ultiple)j(\014lesystem)e(t)o(yp)q(es.)19 b(Some)12 +b(of)f(these)h(\014lesystems)g(are)0 2595 y(implemen)o(ted)k(in)g(the)f(lo)q +(cal)g(k)o(ernel)h(and)f(some)f(on)g(remote)g(\014leserv)o(ers,)h(whilst)h +(the)f(others)f(are)g(implemen)o(ted)0 2645 y(in)o(ternally)j(b)o(y)e +Fp(Amd)p Fo(.)p eop +%%Page: 21 23 +21 22 bop 0 -83 a Fo(Chapter)15 b(5:)k(Filesystem)d(T)o(yp)q(es)1145 +b(SMM:13-21)62 158 y(The)21 b(t)o(w)o(o)f(common)g(\014lesystem)i(t)o(yp)q +(es)f(are)f(UFS)h(and)g(NFS.)g(F)l(our)f(other)h(user)g(accessible)h +(\014lesystems)0 208 y(\(`)p Fl(link)p Fo(',)c(`)p Fl(program)p +Fo(',)g(`)p Fl(auto)p Fo(')g(and)i(`)p Fl(direct)p Fo('\))d(are)i(also)g +(implemen)o(ted)i(in)o(ternally)g(b)o(y)e Fp(Amd)i Fo(and)f(these)f(are)0 +258 y(describ)q(ed)d(b)q(elo)o(w.)21 b(There)14 b(are)h(t)o(w)o(o)e +(additional)j(\014lesystem)f(t)o(yp)q(es)f(in)o(ternal)i(to)e +Fp(Amd)i Fo(whic)o(h)f(are)g(not)f(directly)0 308 y(accessible)j(to)e(the)g +(user)h(\(`)p Fl(inherit)p Fo(')d(and)j(`)p Fl(error)p Fo('\).)j(Their)d(use) +f(is)h(describ)q(ed)i(since)e(they)g(ma)o(y)e(still)j(ha)o(v)o(e)e(an)0 +358 y(e\013ect)g(visible)i(to)e(the)g(user.)0 508 y Fq(5.1)33 +b(Net)n(w)n(ork)15 b(Filesystem)g(\(`)p Fg(type:=nfs)p Fq('\))62 +599 y Fo(The)h Fp(nfs)h Fo(\014lesystem)f(t)o(yp)q(e)f(pro)o(vides)h(access)f +(to)f(Sun's)i(NFS.)0 670 y(The)f(follo)o(wing)h(options)g(m)o(ust)e(b)q(e)i +(sp)q(eci\014ed:)0 751 y Fl(rhost)120 b Fo(the)17 b(remote)g(\014leserv)o +(er.)26 b(This)17 b(m)o(ust)g(b)q(e)h(an)f(en)o(try)f(in)i(the)f(hosts)g +(database.)25 b(IP)17 b(addresses)g(are)240 801 y(not)i(accepted.)34 +b(The)20 b(default)g(v)m(alue)h(is)f(tak)o(en)g(from)e(the)i(lo)q(cal)h(host) +e(name)h(\()p Fl(${host})p Fo(\))e(if)i(no)240 851 y(other)15 +b(v)m(alue)h(is)g(sp)q(eci\014ed.)0 911 y Fl(rfs)168 b Fo(the)19 +b(remote)g(\014lesystem.)33 b(If)19 b(no)g(v)m(alue)i(is)f(sp)q(eci\014ed)h +(for)e(this)g(option,)h(an)f(in)o(ternal)i(default)e(of)240 +961 y Fl(${path})14 b Fo(is)i(used.)62 1052 y(NFS)d(moun)o(ts)g(require)g(a)g +(t)o(w)o(o)f(stage)g(pro)q(cess.)19 b(First,)13 b(the)g Fp(\014le)h(handle)j +Fo(of)c(the)g(remote)f(\014le)i(system)f(m)o(ust)f(b)q(e)0 +1102 y(obtained)i(from)f(the)h(serv)o(er.)19 b(Then)14 b(a)f(moun)o(t)g +(system)g(call)i(m)o(ust)d(b)q(e)j(done)f(on)f(the)h(lo)q(cal)g(system.)19 +b Fp(Amd)d Fo(k)o(eeps)0 1152 y(a)f(cac)o(he)g(of)g(\014le)h(handles)h(for)d +(remote)h(\014le)h(systems.)k(The)15 b(cac)o(he)g(en)o(tries)h(ha)o(v)o(e)f +(a)g(lifetime)i(of)d(a)h(few)g(min)o(utes.)62 1223 y(If)g(a)f(required)h +(\014le)g(handle)h(is)f(not)f(in)h(the)f(cac)o(he,)g Fp(Amd)j +Fo(sends)d(a)g(request)h(to)e(the)i(remote)e(serv)o(er)h(to)g(obtain)0 +1272 y(it.)19 b Fp(Amd)14 b(do)q(es)d(not)i Fo(w)o(ait)e(for)g(a)g(resp)q +(onse;)i(it)f(notes)f(that)g(one)h(of)f(the)h(lo)q(cations)g(needs)h +(retrying,)f(but)f(con)o(tin)o(ues)0 1322 y(with)17 b(an)o(y)f(remaining)h +(lo)q(cations.)24 b(When)17 b(the)g(\014le)g(handle)h(b)q(ecomes)f(a)o(v)m +(ailable,)h(and)e(assuming)h(none)g(of)f(the)0 1372 y(other)11 +b(lo)q(cations)h(w)o(as)e(successfully)j(moun)o(ted,)e Fp(Amd)j +Fo(will)e(retry)f(the)g(moun)o(t.)18 b(This)12 b(mec)o(hanism)g(allo)o(ws)f +(sev)o(eral)0 1422 y(NFS)17 b(\014lesystems)h(to)e(b)q(e)i(moun)o(ted)f(in)h +(parallel.)28 b(The)17 b(\014rst)g(one)g(whic)o(h)h(resp)q(onds)g(with)g(a)f +(v)m(alid)h(\014le)h(handle)0 1472 y(will)e(b)q(e)f(used.)0 +1542 y(An)f(NFS)h(en)o(try)e(migh)o(t)i(b)q(e:)120 1613 y Fl(jsp)47 +b(host!=charm;type:=nfs;rhost:)o(=charm;r)o(fs:=/ho)o(me/char)o(m;sublin)o +(k:=jsp)62 1704 y Fo(The)16 b(moun)o(t)f(system)g(call)i(and)f(an)o(y)f +(unmoun)o(t)h(attempts)f(are)g(alw)o(a)o(ys)g(done)h(in)g(a)g(new)g(task)e +(to)h(a)o(v)o(oid)h(the)0 1754 y(p)q(ossibilt)o(y)h(of)e(blo)q(c)o(king)h +Fp(Amd)p Fo(.)0 1914 y Fq(5.2)33 b(Net)n(w)n(ork)15 b(Host)f(Filesystem)h +(\(`)p Fg(type:=host)p Fq('\))62 2006 y Fo(The)d Fp(host)g +Fo(\014lesystem)g(allo)o(ws)g(access)g(to)f(the)g(en)o(tire)h(exp)q(ort)g +(tree)f(of)g(an)h(NFS)g(serv)o(er.)18 b(The)12 b(implemen)o(tation)0 +2056 y(is)18 b(la)o(y)o(ered)g(ab)q(o)o(v)o(e)f(the)h(`)p Fl(nfs)p +Fo(')e(implemen)o(tation)j(so)e(k)o(eep-aliv)o(es)i(w)o(ork)d(in)j(the)e +(same)h(w)o(a)o(y)l(.)26 b(The)18 b(only)g(option)0 2105 y(whic)o(h)e(needs)g +(to)f(sp)q(eci\014ed)i(is)f(`)p Fl(rhost)p Fo(')d(whic)o(h)j(is)g(the)f(name) +h(of)e(the)i(\014leserv)o(er)g(to)e(moun)o(t.)62 2176 y(The)e(`)p +Fl(host)p Fo(')e(\014lesystem)j(t)o(yp)q(e)e(w)o(orks)g(b)o(y)g(querying)i +(the)e(moun)o(t)h(daemon)f(on)h(the)f(giv)o(en)h(\014leserv)o(er)h(to)e +(obtain)0 2226 y(its)i(exp)q(ort)f(list.)19 b Fp(Amd)c Fo(then)d(obtains)h +(\014lehandles)h(for)e(eac)o(h)h(of)e(the)i(exp)q(orted)f(\014lesystems.)20 +b(An)o(y)12 b(errors)g(at)g(this)0 2276 y(stage)17 b(cause)i(that)e +(particular)i(\014lesystem)g(to)f(b)q(e)g(ignored.)30 b(Finally)19 +b(eac)o(h)g(\014lesystem)f(is)h(moun)o(ted.)29 b(Again,)0 2325 +y(errors)14 b(are)g(logged)g(but)h(ignored.)20 b(One)15 b(common)f(reason)g +(for)g(moun)o(ts)g(to)g(fail)h(is)g(that)e(the)i(moun)o(t)f(p)q(oin)o(t)h(do) +q(es)0 2375 y(not)e(exist.)19 b(Although)13 b Fp(Amd)i Fo(attempts)d(to)g +(automatically)i(create)e(the)h(moun)o(t)g(p)q(oin)o(t,)g(it)g(ma)o(y)g(b)q +(e)g(on)g(a)g(remote)0 2425 y(\014lesystem)j(to)e(whic)o(h)i +Fp(Amd)i Fo(do)q(es)d(not)g(ha)o(v)o(e)g(write)g(p)q(ermission.)62 +2496 y(When)j(an)f(attempt)f(to)h(unmoun)o(t)g(a)g(`)p Fl(host)p +Fo(')e(\014lesystem)j(moun)o(t)f(fails,)h Fp(Amd)h Fo(remoun)o(ts)e(an)o(y)f +(\014lesystems)0 2545 y(whic)o(h)21 b(had)e(succesfully)j(b)q(een)f(unmoun)o +(ted.)34 b(T)l(o)19 b(do)h(this)g Fp(Amd)i Fo(queries)e(the)g(moun)o(t)f +(daemon)h(again)g(and)0 2595 y(obtains)d(a)g(fresh)g(cop)o(y)g(of)g(the)g +(exp)q(ort)g(list.)26 b Fp(Amd)19 b Fo(then)f(tries)f(to)g(moun)o(t)f(an)o(y) +h(exp)q(orted)g(\014lesystems)h(whic)o(h)0 2645 y(are)d(not)g(curren)o(tly)g +(moun)o(ted.)p eop +%%Page: 22 24 +22 23 bop 15 -83 a Fo(SMM:13-22)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)62 158 y(Sun's)22 b(automoun)o(ter)e(pro)o(vides)i(a)f +(sp)q(ecial)i(`)p Fl(-hosts)p Fo(')d(map.)38 b(T)l(o)21 b(ac)o(hiev)o(e)h +(the)f(same)g(e\013ect)g(with)h Fp(Amd)0 208 y Fo(requires)16 +b(t)o(w)o(o)e(steps.)20 b(First)14 b(a)h(moun)o(t)g(map)g(m)o(ust)g(b)q(e)h +(created)f(as)g(follo)o(ws:)120 279 y Fl(/defaults)46 b +(type:=host;fs:=${autodir}/${rh)o(ost}/ro)o(ot;rhos)o(t:=${key)o(})120 +329 y(*)238 b(opts:=rw,nosuid,grpid)0 420 y Fo(and)15 b(then)h(start)e +Fp(Amd)j Fo(with)f(the)f(follo)o(wing)h(command)120 490 y Fl(amd)23 +b(/n)h(net.map)0 582 y Fo(where)17 b(`)p Fl(net.map)p Fo(')d(is)j(the)g(name) +f(of)g(map)g(describ)q(ed)i(ab)q(o)o(v)o(e.)23 b(Note)16 b(that)g(the)g(v)m +(alue)i(of)e Fl(${fs})g Fo(is)g(o)o(v)o(erridden)0 632 y(in)f(the)f(map.)19 +b(This)c(is)f(done)h(to)e(a)o(v)o(oid)h(a)g(clash)h(b)q(et)o(w)o(een)f(the)g +(moun)o(t)g(tree)f(and)i(an)o(y)e(other)h(\014lesystem)h(already)0 +681 y(moun)o(ted)g(from)g(the)g(same)g(\014leserv)o(er.)62 +752 y(If)g(di\013eren)o(t)f(moun)o(t)g(options)g(are)g(needed)h(for)f +(di\013eren)o(t)g(hosts)g(then)g(additional)i(en)o(tries)f(can)f(b)q(e)h +(added)g(to)0 802 y(the)g(map,)g(for)f(example)120 872 y Fl(host2)166 +b(opts:=ro,nosuid,soft)0 964 y Fo(w)o(ould)16 b(soft)e(moun)o(t)h(`)p +Fl(host2)p Fo(')e(read-only)l(.)0 1130 y Fq(5.3)33 b(Net)n(w)n(ork)15 +b(Filesystem)g(Group)h(\(`)p Fg(type:=nfsx)p Fq('\))62 1221 +y Fo(The)f Fp(nfsx)k Fo(\014lesystem)c(allo)o(ws)g(a)g(group)g(of)f +(\014lesystems)i(to)e(b)q(e)h(moun)o(ted)g(from)g(a)f(single)i(NFS)f(serv)o +(er.)20 b(The)0 1271 y(implemen)o(tation)c(is)g(la)o(y)o(ered)g(ab)q(o)o(v)o +(e)e(the)i(`)p Fl(nfs)p Fo(')e(implemen)o(tation)i(so)f(k)o(eep-aliv)o(es)i +(w)o(ork)d(in)i(the)f(same)g(w)o(a)o(y)l(.)62 1342 y(The)h(options)f(are)g +(the)g(same)g(as)g(for)f(the)i(`)p Fl(nfs)p Fo(')e(\014lesystem)i(with)f(one) +g(di\013erence.)0 1412 y(The)g(follo)o(wing)h(options)g(m)o(ust)e(b)q(e)i(sp) +q(eci\014ed:)0 1483 y Fl(rhost)120 b Fo(the)17 b(remote)g(\014leserv)o(er.)26 +b(This)17 b(m)o(ust)g(b)q(e)h(an)f(en)o(try)f(in)i(the)f(hosts)g(database.)25 +b(IP)17 b(addresses)g(are)240 1533 y(not)i(accepted.)34 b(The)20 +b(default)g(v)m(alue)h(is)f(tak)o(en)g(from)e(the)i(lo)q(cal)h(host)e(name)h +(\()p Fl(${host})p Fo(\))e(if)i(no)240 1582 y(other)15 b(v)m(alue)h(is)g(sp)q +(eci\014ed.)0 1644 y Fl(rfs)168 b Fo(as)15 b(a)f(list)i(of)f(\014lesystems)g +(to)f(moun)o(t.)20 b(The)15 b(list)h(is)f(in)h(the)f(form)f(of)h(a)f(comma)h +(separated)f(strings.)0 1736 y(F)l(or)h(example:)120 1806 y +Fl(pub)143 b(type:=nfsx;rhost:=gould;)o(\\)120 1856 y +(rfs:=/public,/,graphics,us)o(enet;fs)o(:=${auto)o(dir}/${)o(rhost}/)o(root) +62 1947 y Fo(The)14 b(\014rst)g(string)f(de\014nes)i(the)f(ro)q(ot)f(of)g +(the)h(tree,)g(and)g(is)g(applied)i(as)d(a)h(pre\014x)g(to)f(the)h(remaining) +h(mem)o(b)q(ers)0 1997 y(of)e(the)h(list)h(whic)o(h)g(de\014ne)g(the)e +(individual)k(\014lesystems.)j(The)15 b(\014rst)e(string)h(is)g +Fp(not)g Fo(used)h(as)e(a)h(\014lesystem)g(name.)0 2047 y(A)h(parallel)h(op)q +(eration)f(is)h(used)f(to)g(determine)h(the)e(lo)q(cal)i(moun)o(t)f(p)q(oin)o +(ts)g(to)f(ensure)i(a)e(consisten)o(t)i(la)o(y)o(out)e(of)g(a)0 +2097 y(tree)h(of)g(moun)o(ts.)62 2167 y(Here,)20 b(the)e Fp(three)k +Fo(\014lesystems,)d(`)p Fl(/public)p Fo(',)f(`)p Fl(/public/graphics)p +Fo(')d(and)k(`)p Fl(/public/usenet)p Fo(',)d(w)o(ould)j(b)q(e)0 +2217 y(moun)o(ted.)62 2288 y(A)g(lo)q(cal)g(moun)o(t)f(p)q(oin)o(t,)h +Fl(${fs})p Fo(,)f Fp(m)o(ust)h Fo(b)q(e)g(sp)q(eci\014ed.)32 +b(The)19 b(default)g(lo)q(cal)g(moun)o(t)f(p)q(oin)o(t)h(will)h(not)e(w)o +(ork)0 2338 y(correctly)d(in)h(the)g(general)f(case.)20 b(A)c(suggestion)f +(is)g(to)g(use)h(`)p Fl(fs:=${autodir}/${rho)o(st}/roo)o(t)p +Fo('.)0 2504 y Fq(5.4)33 b(Unix)16 b(Filesystem)g(\(`)p Fg(type:=ufs)p +Fq('\))62 2595 y Fo(The)22 b Fp(ufs)i Fo(\014lesystem)e(t)o(yp)q(e)g(pro)o +(vides)g(access)g(to)f(the)h(system's)e(standard)i(disk)g +(\014lesystem|usually)i(a)0 2645 y(deriv)m(ativ)o(e)16 b(of)f(the)h(Berk)o +(eley)g(F)l(ast)e(Filesystem.)p eop +%%Page: 23 25 +23 24 bop 0 -83 a Fo(Chapter)15 b(5:)k(Filesystem)d(T)o(yp)q(es)1145 +b(SMM:13-23)0 158 y(The)15 b(follo)o(wing)h(option)g(m)o(ust)e(b)q(e)i(sp)q +(eci\014ed:)0 246 y Fl(dev)168 b Fo(the)15 b(blo)q(c)o(k)h(sp)q(ecial)h +(device)g(to)d(b)q(e)i(moun)o(ted.)62 338 y(A)g(UFS)f(en)o(try)f(migh)o(t)i +(b)q(e:)120 408 y Fl(jsp)71 b(host==charm;type:=ufs;dev:=)o(/dev/xd0)o +(g;subli)o(nk:=jsp)0 617 y Fq(5.5)33 b(Program)15 b(Filesystem)g(\(`)p +Fg(type:=program)p Fq('\))62 709 y Fo(The)21 b Fp(program)f +Fo(\014lesystem)i(t)o(yp)q(e)f(allo)o(ws)g(a)f(program)g(to)g(b)q(e)i(run)f +(whenev)o(er)g(a)g(moun)o(t)f(or)h(unmoun)o(t)f(is)0 758 y(required.)43 +b(This)24 b(allo)o(ws)f(easy)f(addition)i(of)e(supp)q(ort)h(for)f(other)g +(\014lesystem)i(t)o(yp)q(es,)g(suc)o(h)f(as)f(MIT's)g(Re-)0 +808 y(mote)16 b(Virtual)h(Disk)g(\(R)-5 b(VD\))16 b(whic)o(h)h(has)g(a)f +(programmatic)g(in)o(terface)g(via)h(the)g(commands)f(`)p Fl(rvdmount)p +Fo(')f(and)0 858 y(`)p Fl(rvdunmount)p Fo('.)0 929 y(The)g(follo)o(wing)h +(options)g(m)o(ust)e(b)q(e)i(sp)q(eci\014ed:)0 1017 y Fl(mount)120 +b Fo(the)15 b(program)f(whic)o(h)i(will)h(p)q(erform)e(the)h(moun)o(t.)0 +1084 y Fl(unmount)72 b Fo(the)15 b(program)f(whic)o(h)i(will)h(p)q(erform)e +(the)h(unmoun)o(t.)62 1175 y(The)f(exit)h(co)q(de)f(from)f(these)h(t)o(w)o(o) +f(programs)f(is)i(in)o(terpreted)h(as)e(a)h(Unix)h(error)e(co)q(de.)20 +b(As)15 b(usual,)g(exit)g(co)q(de)0 1225 y(zero)i(indicates)h(success.)26 +b(T)l(o)17 b(execute)g(the)g(program)f Fp(Amd)j Fo(splits)f(the)f(string)g +(on)g(whitespace)h(to)e(create)h(an)0 1275 y(arra)o(y)h(of)h(substrings.)33 +b(Single)21 b(quotes)e(`)p Fl(')p Fo(')g(can)g(b)q(e)h(used)g(to)f(quote)g +(whitespace)i(if)f(that)e(is)i(required)h(in)f(an)0 1325 y(argumen)o(t.)f +(There)d(is)f(no)g(w)o(a)o(y)g(to)f(escap)q(e)i(or)f(c)o(hange)g(the)g(quote) +g(c)o(haracter.)62 1395 y(T)l(o)d(run)g(the)f(program)g(`)p +Fl(rvdmount)p Fo(')f(with)i(a)f(host)g(name)h(and)g(\014lesystem)g(as)g +(argumen)o(ts)e(w)o(ould)i(b)q(e)h(sp)q(eci\014ed)0 1445 y(b)o(y)i(`)p +Fl(mount:="/etc/rvdmount)d(rvdmount)i(fserver)g(${path}")p +Fo('.)62 1516 y(The)j(\014rst)f(elemen)o(t)h(in)g(the)f(arra)o(y)f(is)i(tak)o +(en)f(as)g(the)g(pathname)h(of)f(the)g(program)f(to)h(execute.)24 +b(The)16 b(other)0 1566 y(mem)o(b)q(ers)g(of)f(the)h(arra)o(y)e(form)h(the)h +(argumen)o(t)f(v)o(ector)g(to)g(b)q(e)h(passed)g(to)f(the)h(program,)e +Fp(including)19 b(argumen)o(t)0 1615 y(zero)p Fo(.)27 b(This)18 +b(means)f(that)g(the)h(split)g(string)g(m)o(ust)e(ha)o(v)o(e)i(at)e(least)i +(t)o(w)o(o)e(elemen)o(ts.)28 b(The)17 b(program)g(is)h(directly)0 +1665 y(executed)23 b(b)o(y)f Fp(Amd)p Fo(,)h(not)f(via)g(a)f(shell.)42 +b(This)22 b(means)g(that)g(scripts)g(m)o(ust)f(b)q(egin)i(with)g(a)e +Fl(#!)h Fo(in)o(terpreter)0 1715 y(sp)q(eci\014cation.)62 1786 +y(If)c(a)g(\014lesystem)g(t)o(yp)q(e)g(is)g(to)f(b)q(e)i(hea)o(vily)g(used,)f +(it)g(ma)o(y)f(b)q(e)i(w)o(orth)o(while)f(adding)g(a)g(new)f(\014lesystem)i +(t)o(yp)q(e)0 1835 y(in)o(to)c Fp(Amd)p Fo(,)g(but)h(for)e(most)g(uses)i(the) +f(program)f(\014lesystem)i(should)g(su\016ce.)62 1906 y(When)k(the)f(program) +f(is)i(run,)g(standard)e(input)i(and)g(standard)e(error)h(are)g(inherited)i +(from)d(the)h(curren)o(t)0 1956 y(v)m(alues)f(used)g(b)o(y)f +Fp(Amd)p Fo(.)26 b(Standard)17 b(output)g(is)h(a)f(duplicate)i(of)e(standard) +f(error.)25 b(The)18 b(v)m(alue)g(sp)q(eci\014ed)i(with)0 2006 +y(the)15 b(\\-l")h(command)f(line)i(option)e(has)g(no)g(e\013ect)g(on)g +(standard)g(error.)0 2213 y Fq(5.6)33 b(Sym)n(b)r(olic)17 b(Link)g +(Filesystem)f(\(`)p Fg(type:=link)p Fq('\))62 2305 y Fo(Eac)o(h)k +(\014lesystem)g(t)o(yp)q(e)f(creates)h(a)f(sym)o(b)q(olic)h(link)h(to)e(p)q +(oin)o(t)h(from)f(the)h(v)o(olume)g(name)f(to)g(the)h(ph)o(ysical)0 +2355 y(moun)o(t)15 b(p)q(oin)o(t.)22 b(The)16 b(`)p Fl(link)p +Fo(')e(\014lesystem)i(do)q(es)g(the)g(same)f(without)h(an)o(y)f(other)g(side) +i(e\013ects.)j(This)d(allo)o(ws)e(an)o(y)0 2404 y(part)g(of)f(the)i(mac)o +(hines)g(name)f(space)g(to)g(b)q(e)h(accessed)g(via)f Fp(Amd)p +Fo(.)62 2475 y(One)h(common)f(use)g(for)f(the)h(symlink)i(\014lesystem)e(is)h +(`)p Fl(/homes)p Fo(')d(whic)o(h)j(can)f(b)q(e)h(made)f(to)f(con)o(tain)h(an) +g(en)o(try)0 2525 y(for)e(eac)o(h)g(user)g(whic)o(h)i(p)q(oin)o(ts)e(to)g +(their)h(\(auto-moun)o(ted\))e(home)h(directory)l(.)20 b(Although)14 +b(this)f(ma)o(y)g(seem)h(rather)0 2575 y(exp)q(ensiv)o(e,)i(it)g(pro)o(vides) +g(a)e(great)h(deal)h(of)e(administrativ)o(e)i(\015exibili)q(t)o(y)l(.)0 +2645 y(The)f(follo)o(wing)h(option)g(m)o(ust)e(b)q(e)i(de\014ned:)p +eop +%%Page: 24 26 +24 25 bop 15 -83 a Fo(SMM:13-24)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 158 y Fl(fs)192 b Fo(The)16 b(v)m(alue)h(of)f +Fp(fs)h Fo(option)f(sp)q(eci\014es)i(the)e(destination)g(of)g(the)g(link,)h +(as)e(mo)q(di\014ed)i(b)o(y)f(the)g Fp(sublink)240 208 y Fo(option.)k(If)14 +b Fp(sublink)k Fo(is)c(non-n)o(ull,)i(it)e(is)g(app)q(ended)i(to)d +Fl(${fs}/)g Fo(and)h(the)f(resulting)i(string)f(is)g(used)240 +258 y(as)h(the)g(target.)62 349 y(The)g(`)p Fl(link)p Fo(')f(\014lesystem)h +(can)g(b)q(e)h(though)f(of)f(as)g(iden)o(tical)j(to)d(the)h(`)p +Fl(ufs)p Fo(')f(\014lesystem)h(but)g(without)g(actually)0 399 +y(moun)o(ting)g(an)o(ything.)62 470 y(An)h(example)g(en)o(try)f(migh)o(t)g(b) +q(e:)120 540 y Fl(jsp)71 b(host==charm;type:=link;fs:=)o(/home/ch)o(arm;sub)o +(link:=j)o(sp)62 632 y Fo(whic)o(h)16 b(w)o(ould)g(return)f(a)g(sym)o(b)q +(olic)h(link)h(p)q(oin)o(ting)f(to)f(`)p Fl(/home/charm/jsp)p +Fo('.)0 792 y Fq(5.7)33 b(Sym)n(b)r(olic)17 b(Link)g(Filesystem)f(I)r(I)f +(\(`)p Fg(type:=link)p Fq('\))62 884 y Fo(The)h(`)p Fl(linkx)p +Fo(')e(\014lesystem)i(t)o(yp)q(e)f(is)h(iden)o(tical)h(to)e(`)p +Fl(link)p Fo(')f(with)i(the)f(exception)i(that)d(the)i(target)e(of)h(the)h +(link)0 933 y(m)o(ust)f(exist.)20 b(Existence)c(is)g(c)o(hec)o(k)o(ed)f(with) +h(the)f(`)p Fl(lstat)p Fo(')f(system)h(call.)62 1004 y(The)f(`)p +Fl(linkx)p Fo(')e(\014lesystem)j(t)o(yp)q(e)f(is)g(particularly)h(useful)g +(for)e(wildcard)i(map)e(en)o(tries.)20 b(In)15 b(this)f(case,)f(a)h(list)g +(of)0 1054 y(p)q(ossible)j(targets)d(can)h(b)q(e)h(giv)o(e)f(and)h +Fp(Amd)h Fo(will)g(c)o(ho)q(ose)e(the)g(\014rst)g(one)h(whic)o(h)g(exists)f +(on)g(the)g(lo)q(cal)i(mac)o(hine.)0 1213 y Fq(5.8)33 b(Automoun)n(t)15 +b(Filesystem)h(\(`)p Fg(type:=auto)p Fq('\))62 1305 y Fo(The)j +Fp(auto)g Fo(\014lesystem)g(t)o(yp)q(e)f(creates)g(a)g(new)g(automoun)o(t)f +(p)q(oin)o(t)h(b)q(elo)o(w)h(an)f(existing)h(automoun)o(t)e(p)q(oin)o(t.)0 +1354 y(T)l(op-lev)o(el)g(automoun)o(t)e(p)q(oin)o(ts)h(app)q(ear)f(as)h +(system)f(moun)o(t)g(p)q(oin)o(ts.)22 b(An)16 b(automoun)o(t)e(moun)o(t)h(p)q +(oin)o(t)h(can)g(also)0 1404 y(app)q(ear)h(as)g(a)g(sub-directory)h(of)f(an)g +(existing)i(automoun)o(t)d(p)q(oin)o(t.)26 b(This)18 b(allo)o(ws)g(some)e +(additional)j(structure)0 1454 y(to)c(b)q(e)g(added,)h(for)e(example)i(to)f +(mimic)h(the)g(moun)o(t)e(tree)h(of)g(another)g(mac)o(hine.)62 +1525 y(The)h(follo)o(wing)g(options)f(ma)o(y)f(b)q(e)i(sp)q(eci\014ed:)0 +1605 y Fl(cache)120 b Fo(sp)q(eci\014es)19 b(whether)e(the)g(data)f(in)i +(this)g(moun)o(t-map)e(should)i(b)q(e)g(cac)o(hed.)25 b(The)18 +b(default)f(v)m(alue)h(is)240 1655 y(`)p Fl(none)p Fo(',)13 +b(in)i(whic)o(h)g(case)f(no)g(cac)o(hing)h(is)g(done)f(in)h(order)f(to)g +(conserv)o(e)g(memory)l(.)19 b(Ho)o(w)o(ev)o(er,)13 b(b)q(etter)240 +1705 y(p)q(erformance)i(and)h(reliabilit)o(y)h(can)f(b)q(e)g(obtained)f(b)o +(y)h(cac)o(hing)f(some)g(or)g(all)h(of)f(a)g(moun)o(t-map.)240 +1765 y(If)f(the)g(cac)o(he)g(option)g(sp)q(eci\014es)h(`)p +Fl(all)p Fo(',)e(the)g(en)o(tire)i(map)e(is)h(en)o(umerated)g(when)g(the)g +(moun)o(t)f(p)q(oin)o(t)240 1815 y(is)j(created.)240 1875 y(If)h(the)g(cac)o +(he)g(option)h(sp)q(eci\014es)g(`)p Fl(inc)p Fo(',)e(cac)o(hing)i(is)f(done)g +(incremen)o(tally)i(as)e(and)g(when)g(data)f(is)240 1925 y(required.)k(Some) +13 b(map)f(t)o(yp)q(es)h(do)g(not)f(supp)q(ort)h(cac)o(he)g(mo)q(de)f(`)p +Fl(all)p Fo(',)g(in)i(whic)o(h)f(case)g(`)p Fl(inc)p Fo(')e(is)i(used)240 +1975 y(whenev)o(er)j(`)p Fl(all)p Fo(')e(is)h(requested.)240 +2035 y(Cac)o(hing)h(can)f(b)q(e)h(en)o(tirely)g(disabled)h(b)o(y)e(using)h +(cac)o(he)g(mo)q(de)f(`)p Fl(none)p Fo('.)240 2095 y(If)f(the)g(cac)o(he)h +(option)f(sp)q(eci\014es)h(`)p Fl(regexp)p Fo(')e(then)h(the)g(en)o(tire)h +(map)e(will)j(b)q(e)f(en)o(umerated)f(and)g(eac)o(h)240 2145 +y(k)o(ey)i(will)i(b)q(e)g(treated)d(as)i(an)f(egrep-st)o(yle)h(regular)f +(expression.)25 b(The)17 b(order)f(in)h(whic)o(h)g(a)f(cac)o(hed)240 +2195 y(map)f(is)i(searc)o(hed)f(do)q(es)f(not)h(corresp)q(ond)g(to)f(the)g +(ordering)h(in)h(the)f(source)f(map)h(so)f(the)h(regular)240 +2245 y(expressions)g(should)g(b)q(e)g(m)o(utually)g(exclusiv)o(e)h(to)d(a)o +(v)o(oid)h(confusion.)240 2305 y(Eac)o(h)i(moun)o(t)g(map)g(t)o(yp)q(e)h(has) +f(a)g(default)h(cac)o(he)g(t)o(yp)q(e,)g(usually)g(`)p Fl(inc)p +Fo(',)f(whic)o(h)h(can)g(b)q(e)g(selected)240 2355 y(b)o(y)d(sp)q(ecifying)i +(`)p Fl(mapdefault)p Fo('.)240 2415 y(The)e(cac)o(he)g(mo)q(de)g(for)f(a)g +(moun)o(t)g(map)h(can)g(only)g(b)q(e)g(selected)h(on)f(the)f(command)h(line.) +21 b(Starting)240 2465 y Fp(Amd)c Fo(with)f(the)f(command:)360 +2525 y Fl(amd)23 b(/homes)g(hesiod.homes)g(-cache:=inc)240 +2595 y Fo(will)17 b(cause)f(`)p Fl(/homes)p Fo(')d(to)i(b)q(e)h(automoun)o +(ted)f(using)h(the)f Fp(Hesio)q(d)j Fo(name)e(serv)o(er)f(with)g(lo)q(cal)i +(incre-)240 2645 y(men)o(tal)e(cac)o(hing)h(of)f(all)h(succesfully)h(resolv)o +(ed)f(names.)p eop +%%Page: 25 27 +25 26 bop 0 -83 a Fo(Chapter)15 b(5:)k(Filesystem)d(T)o(yp)q(es)1145 +b(SMM:13-25)240 158 y(All)21 b(cac)o(hed)f(data)g(is)g(forgotten)e(whenev)o +(er)j Fp(Amd)h Fo(receiv)o(es)e(a)g(`)p Fl(SIGHUP)p Fo(')e(signal)j(and,)f +(if)h(cac)o(he)240 208 y(`)p Fl(all)p Fo(')14 b(mo)q(de)i(w)o(as)f(selected,) +i(the)e(cac)o(he)h(will)i(b)q(e)e(reloaded.)22 b(This)16 b(can)g(b)q(e)g +(used)g(to)f(inform)h Fp(Amd)240 258 y Fo(that)i(a)g(map)g(has)g(b)q(een)h +(up)q(dated.)30 b(In)19 b(addition,)h(whenev)o(er)f(a)f(cac)o(he)g(lo)q(okup) +h(fails)g(and)g Fp(Amd)240 308 y Fo(needs)g(to)f(examine)h(a)f(map,)h(the)f +(map's)g(mo)q(dify)h(time)g(is)g(examined.)31 b(If)18 b(the)h(cac)o(he)f(is)h +(out)f(of)240 358 y(date)d(with)h(resp)q(ect)f(to)g(the)g(map)g(then)h(it)f +(is)h(\015ushed)g(as)f(if)h(a)e(`)p Fl(SIGHUP)p Fo(')g(had)h(b)q(een)i +(receiv)o(ed.)240 422 y(An)c(additional)g(option)g(\(`)p Fl(sync)p +Fo('\))d(ma)o(y)i(b)q(e)h(sp)q(eci\014ed)h(to)e(force)g Fp(Amd)i +Fo(to)e(c)o(hec)o(k)g(the)h(map's)e(mo)q(dify)240 472 y(time)h(whenev)o(er)h +(a)f(cac)o(hed)g(en)o(try)g(is)g(b)q(eing)i(used.)19 b(F)l(or)11 +b(example,)i(an)f(incremen)o(tal,)i(sync)o(hronised)240 522 +y(cac)o(he)h(w)o(ould)h(b)q(e)g(created)f(b)o(y)g(the)h(follo)o(wing)f +(command:)360 587 y Fl(amd)23 b(/homes)g(hesiod.homes)g(-cache:=inc,sync)0 +652 y(fs)192 b Fo(sp)q(eci\014es)17 b(the)e(name)h(of)e(the)i(moun)o(t)e(map) +h(to)g(use)g(for)g(the)g(new)h(moun)o(t)e(p)q(oin)o(t.)240 +716 y(Arguably)g(this)g(should)g(ha)o(v)o(e)f(b)q(een)i(sp)q(eci\014ed)h +(with)d(the)h Fl(${rfs})f Fo(option)g(but)h(w)o(e)f(are)g(no)o(w)g(stuc)o(k) +240 766 y(with)j(it)f(due)h(to)e(historical)j(acciden)o(t.)0 +831 y Fl(pref)144 b Fo(alters)13 b(the)h(name)f(that)g(is)h(lo)q(ok)o(ed)g +(up)g(in)g(the)g(moun)o(t)f(map.)19 b(If)13 b Fl(${pref})p +Fo(,)g(the)g Fp(pre\014x)p Fo(,)h(is)g(non-n)o(ull)240 881 +y(then)i(it)f(is)h(prep)q(ended)h(to)d(the)i(name)f(requested)g(b)o(y)h(the)f +(k)o(ernel)h Fp(b)q(efore)i Fo(the)d(map)g(is)h(searc)o(hed.)62 +972 y(The)22 b(serv)o(er)e(`)p Fl(dylan.doc.ic.ac.uk)p Fo(')e(has)j(t)o(w)o +(o)f(user)h(disks:)33 b(`)p Fl(/dev/dsk/2s0)p Fo(')18 b(and)k(`)p +Fl(/dev/dsk/5s0)p Fo('.)0 1022 y(These)e(are)f(accessed)h(as)f(`)p +Fl(/home/dylan/dk2)p Fo(')e(and)i(`)p Fl(/home/dylan/dk5)p +Fo(')e(resp)q(ectiv)o(ely)l(.)35 b(Since)20 b(`)p Fl(/home)p +Fo(')e(is)0 1072 y(already)d(an)h(automoun)o(t)e(p)q(oin)o(t,)h(this)h +(naming)f(is)h(ac)o(hiev)o(ed)g(with)g(the)f(follo)o(wing)h(map)f(en)o +(tries:)120 1142 y Fl(dylan)190 b(type:=auto;fs:=${map};pref:=)o(${key}/)120 +1192 y(dylan/dk2)94 b(type:=ufs;dev:=/dev/dsk/2s0)120 1242 +y(dylan/dk5)g(type:=ufs;dev:=/dev/dsk/5s0)0 1432 y Fq(5.9)33 +b(Direct)15 b(Automoun)n(t)h(Filesystem)g(\(`)p Fg(type:=direct)p +Fq(')o(\))62 1523 y Fo(The)h Fp(direct)i Fo(\014lesystem)e(is)h(almost)e +(iden)o(tical)j(to)d(the)h(automoun)o(t)f(\014lesystem.)25 +b(Instead)18 b(of)e(app)q(earing)i(to)0 1573 y(b)q(e)e(a)f(directory)g(of)g +(moun)o(t)f(p)q(oin)o(ts,)h(it)h(app)q(ears)f(as)g(a)f(sym)o(b)q(olic)j(link) +f(to)f(a)g(moun)o(ted)g(\014lesystem.)20 b(The)15 b(moun)o(t)0 +1622 y(is)f(done)h(at)e(the)h(time)g(the)g(link)h(is)f(accessed.)20 +b(See)15 b(Section)g(5.8)d([Automoun)o(t)h(Filesystem],)h(page)28 +b(SMM:13-24)0 1672 y(for)15 b(a)f(list)i(of)f(required)i(options.)62 +1743 y(Direct)c(automoun)o(t)e(p)q(oin)o(ts)i(are)g(created)f(b)o(y)h(sp)q +(ecifying)h(the)f(`)p Fl(direct)p Fo(')e(\014lesystem)i(t)o(yp)q(e)g(on)f +(the)h(command)0 1793 y(line:)120 1863 y Fl(amd)23 b(...)h(/usr/man)f +(auto.direct)f(-type:=direct)62 1955 y Fo(where)16 b(`)p Fl(auto.direct)p +Fo(')d(w)o(ould)i(con)o(tain)h(an)f(en)o(try)f(suc)o(h)i(as:)120 +2025 y Fl(usr/man)94 b(-type:=nfs;rfs:=/usr/man)21 b(\\)382 +2075 y(rhost:=man-server1)46 b(rhost:=man-server2)62 2166 y +Fo(In)19 b(this)f(example,)h(`)p Fl(man-server1)p Fo(')d(and)i(`)p +Fl(man-server2)p Fo(')d(are)j(\014le)h(serv)o(ers)e(whic)o(h)i(exp)q(ort)f +(copies)g(of)g(the)0 2216 y(man)o(ual)e(pages.)22 b(Note)16 +b(that)f(the)i(k)o(ey)f(whic)o(h)g(is)h(lo)q(ok)o(ed)f(up)h(is)g(the)f(name)g +(of)f(the)i(automoun)o(t)d(p)q(oin)o(t)j(without)0 2266 y(the)e(leading)i(`)p +Fl(/)p Fo('.)0 2454 y Fq(5.10)32 b(Union)16 b(Filesystem)g(\(`)p +Fg(type:=union)p Fq('\))62 2545 y Fo(The)21 b Fp(union)g Fo(\014lesystem)g(t) +o(yp)q(e)f(allo)o(ws)h(the)f(con)o(ten)o(ts)g(of)g(sev)o(eral)g(directories)i +(to)d(b)q(e)i(merged)f(and)h(made)0 2595 y(visible)16 b(in)f(a)f(single)h +(directory)l(.)20 b(This)14 b(can)g(b)q(e)h(used)g(to)e(o)o(v)o(ercome)g(one) +h(of)g(the)g(ma)s(jor)e(limitations)j(of)f(the)g(Unix)0 2645 +y(moun)o(t)h(mec)o(hanism)h(whic)o(h)g(only)f(allo)o(ws)h(complete)g +(directories)g(to)e(b)q(e)i(moun)o(ted.)p eop +%%Page: 26 28 +26 27 bop 15 -83 a Fo(SMM:13-26)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)62 158 y(F)l(or)g(example,)i(supp)q(osing)g(`)p +Fl(/tmp)p Fo(')e(and)h(`)p Fl(/var/tmp)p Fo(')d(w)o(ere)j(to)f(b)q(e)h +(merged)g(in)o(to)g(a)f(new)h(directory)g(called)0 208 y(`)p +Fl(/mtmp)p Fo(',)j(with)g(\014les)h(in)g(`)p Fl(/var/tmp)p +Fo(')e(taking)h(precedence.)39 b(The)22 b(follo)o(wing)g(command)f(could)h(b) +q(e)g(used)g(to)0 258 y(ac)o(hiev)o(e)16 b(this)f(e\013ect:)120 +329 y Fl(amd)23 b(...)h(/mtmp)f(union:/tmp:/var/tmp)e(-type:=union)62 +420 y Fo(Curren)o(tly)l(,)12 b(the)f(unioned)h(directories)g(m)o(ust)f +Fp(not)g Fo(b)q(e)h(automoun)o(ted.)18 b(That)10 b(w)o(ould)h(cause)g(a)g +(deadlo)q(c)o(k.)19 b(This)0 470 y(seriously)d(limits)h(the)e(curren)o(t)g +(usefulness)i(of)e(this)h(\014lesystem)f(t)o(yp)q(e)h(and)f(the)h(problem)g +(will)g(b)q(e)g(addressed)g(in)0 519 y(a)f(future)g(release)h(of)f +Fp(Amd)p Fo(.)62 590 y(Files)20 b(created)e(in)i(the)e(union)i(directory)e +(are)h(actually)g(created)f(in)i(the)e(last)g(named)h(directory)l(.)30 +b(This)19 b(is)0 640 y(done)h(b)o(y)g(creating)f(a)h(wildcard)h(en)o(try)e +(whic)o(h)i(p)q(oin)o(ts)f(to)f(the)g(correct)h(directory)l(.)33 +b(The)20 b(wildcard)h(en)o(try)e(is)0 690 y(visible)e(if)f(the)f(union)i +(directory)e(is)h(listed,)g(so)f(allo)o(wing)h(y)o(ou)f(to)f(see)i(whic)o(h)g +(directory)f(has)g(priorit)o(y)l(.)62 760 y(The)j(\014les)g(visible)h(in)f +(the)f(union)h(directory)f(are)g(computed)g(at)g(the)g(time)g +Fp(Amd)i Fo(is)f(started,)e(and)i(are)e(not)0 810 y(k)o(ept)c(upto)q(date)g +(with)g(resp)q(ect)h(to)e(the)h(underlying)i(directories.)20 +b(Similarly)l(,)15 b(if)d(a)g(link)h(is)g(remo)o(v)o(ed,)f(for)f(example)0 +860 y(with)16 b(the)f(`)p Fl(rm)p Fo(')f(command,)h(it)g(will)i(b)q(e)f(lost) +f(forev)o(er.)0 1019 y Fq(5.11)32 b(Error)16 b(Filesystem)g(\(`)p +Fg(type:=error)p Fq('\))62 1111 y Fo(The)i Fp(error)i Fo(\014lesystem)e(t)o +(yp)q(e)f(is)h(used)g(in)o(ternally)h(as)e(a)g(catc)o(h-all)h(in)g(the)f +(case)h(where)f(none)h(of)f(the)g(other)0 1160 y(\014lesystems)g(w)o(as)e +(selected,)i(or)e(some)h(other)g(error)f(o)q(ccurred.)23 b(Lo)q(okups)16 +b(and)h(moun)o(ts)e(alw)o(a)o(ys)g(fail)i(with)f(\\No)0 1210 +y(suc)o(h)g(\014le)g(or)e(directory".)20 b(All)d(other)e(op)q(erations)g +(trivially)i(succeed.)62 1281 y(The)f(error)e(\014lesystem)i(is)g(not)f +(directly)h(accessible.)0 1440 y Fq(5.12)32 b(T)-6 b(op-lev)n(el)17 +b(Filesystem)f(\(`)p Fg(type:=toplvl)p Fq('\))62 1532 y Fo(The)23 +b Fp(toplvl)i Fo(\014lesystems)d(is)h(deriv)o(ed)g(from)f(the)g(`)p +Fl(auto)p Fo(')f(\014lesystem)i(and)f(is)h(used)g(to)e(moun)o(t)h(the)g(top-) +0 1581 y(lev)o(el)17 b(automoun)o(t)d(no)q(des.)21 b(Requests)16 +b(of)f(this)g(t)o(yp)q(e)h(are)f(automatically)h(generated)f(from)g(the)g +(command)g(line)0 1631 y(argumen)o(ts)f(and)i(can)f(also)g(b)q(e)h(passed)g +(in)g(b)o(y)f(using)h(the)f(\\-M")f(option)i(of)f(the)g Fp(Amq)h +Fo(command.)0 1787 y Fq(5.13)32 b(Ro)r(ot)15 b(Filesystem)62 +1879 y Fo(The)j Fp(ro)q(ot)g Fo(\(`)p Fl(type:=root)p Fo('\))e(\014lesystem)i +(t)o(yp)q(e)g(acts)f(as)h(an)g(in)o(ternal)h(placeholder)g(on)o(to)e(whic)o +(h)i Fp(Amd)h Fo(can)0 1929 y(pin)c(`)p Fl(toplvl)p Fo(')e(moun)o(ts.)20 +b(Only)d(one)e(no)q(de)h(of)f(this)h(t)o(yp)q(e)g(need)g(ev)o(er)f(exist)h +(and)g(one)f(is)h(created)g(automatically)0 1978 y(during)g(startup.)j(The)d +(e\013ect)f(of)f(creating)i(a)f(second)g(ro)q(ot)g(no)q(de)h(is)f +(unde\014ned.)0 2135 y Fq(5.14)32 b(Inheritance)17 b(Filesystem)62 +2226 y Fo(The)c Fp(inheritance)k Fo(\(`)p Fl(type:=inherit)p +Fo('\))10 b(\014lesystem)k(is)f(not)f(directly)j(accessible.)20 +b(Instead,)14 b(in)o(ternal)f(moun)o(t)0 2276 y(no)q(des)j(of)f(this)h(t)o +(yp)q(e)f(are)g(automatically)h(generated)f(when)h Fp(Amd)i +Fo(is)e(started)e(with)i(the)f(\\-r")g(option.)21 b(A)o(t)15 +b(this)0 2325 y(time)j(the)g(system)f(moun)o(t)g(table)h(is)g(scanned)g(to)f +(lo)q(cate)h(an)o(y)f(\014lesystems)h(whic)o(h)h(are)e(already)h(moun)o(ted.) +27 b(If)0 2375 y(an)o(y)17 b(reference)h(to)f(these)h(\014lesystems)g(is)g +(made)f(through)g Fp(Amd)i Fo(then)f(instead)g(of)f(attempting)g(to)g(moun)o +(t)g(it,)0 2425 y Fp(Amd)k Fo(sim)o(ulates)e(the)g(moun)o(t)f(and)h +Fp(inherits)j Fo(the)d(\014lesystem.)31 b(This)19 b(allo)o(ws)g(a)f(new)h(v)o +(ersion)g(of)g Fp(Amd)h Fo(to)e(b)q(e)0 2475 y(installed)d(on)e(a)g(liv)o(e)i +(system)e(simply)h(b)o(y)f(killing)j(the)d(old)h(daemon)f(with)h +Fl(SIGTERM)e Fo(and)i(starting)e(the)i(new)f(one.)62 2545 y(This)18 +b(\014lesystem)g(t)o(yp)q(e)f(is)g(not)g(generally)h(visible)h(externally)l +(,)g(but)e(it)g(is)h(p)q(ossible)g(that)f(the)g(output)g(from)0 +2595 y(`)p Fl(amq)d(-m)p Fo(')g(ma)o(y)f(list)h(`)p Fl(inherit)p +Fo(')f(as)g(the)h(\014lesystem)h(t)o(yp)q(e.)k(This)c(happ)q(ens)g(when)f(an) +g(inherit)h(op)q(eration)f(cannot)0 2645 y(b)q(e)i(completed)g(for)f(some)g +(reason,)f(usually)i(b)q(ecause)h(a)e(\014leserv)o(er)g(is)h(do)o(wn.)p +eop +%%Page: 27 29 +27 28 bop 0 -83 a Fo(Chapter)15 b(6:)k(Run-time)e(Administration)987 +b(SMM:13-27)0 158 y Fm(6)41 b(Run-time)14 b(Administration)0 +379 y Fq(6.1)33 b(Starting)16 b Ff(Amd)62 470 y Fp(Amd)h Fo(is)f(b)q(est)g +(started)e(from)g(`)p Fl(/etc/rc.local)p Fo(':)120 540 y Fl(if)24 +b([)f(-f)h(/etc/amd.start)e(];)h(then)311 590 y(sh)g(/etc/amd.start;)f +(\(echo)h(-n)h(')g(amd'\))142 b(>/dev/console)120 640 y(fi)0 +731 y Fo(The)15 b(shell)i(script,)e(`)p Fl(amd.start)p Fo(',)e(con)o(tains:) +120 802 y Fl(#!/bin/sh)23 b(-)120 852 y(PATH=/etc:/bin:/usr/bin:/u)o(sr/ucb:) +o($PATH)e(export)i(PATH)120 951 y(#)120 1001 y(#)h(Either)f(name)g(of)h +(logfile)f(or)g("syslog")120 1051 y(#)120 1101 y(LOGFILE=syslog)120 +1151 y(#LOGFILE=/var/log/amd)120 1250 y(#)120 1300 y(#)h(Figure)f(out)g +(whether)g(domain)g(name)g(is)h(in)g(host)f(name)120 1350 y(#)h(If)f(the)h +(hostname)f(is)g(just)g(the)h(machine)f(name)g(then)120 1400 +y(#)h(pass)f(in)h(the)f(name)g(of)h(the)f(local)h(domain)f(so)g(that)h(the) +120 1450 y(#)g(hostnames)e(in)i(the)f(map)h(are)f(domain)g(stripped)g +(correctly.)120 1499 y(#)120 1549 y(case)g(`hostname`)g(in)120 +1599 y(*.*\))g(dmn=)h(;;)120 1649 y(*\))g(dmn='-d)e(doc.ic.ac.uk')120 +1699 y(esac)120 1798 y(#)120 1848 y(#)i(Zap)f(earlier)g(log)h(file)120 +1898 y(#)120 1948 y(case)f("$LOGFILE")g(in)120 1998 y(*/*\))311 +2047 y(mv)g("$LOGFILE")g("$LOGFILE"-)311 2097 y(>)h("$LOGFILE")311 +2147 y(;;)120 2197 y(syslog\))311 2247 y(:)g(nothing)311 2296 +y(;;)120 2346 y(esac)120 2446 y(cd)g(/usr/sbin)120 2496 y(#)120 +2545 y(#)g(-r)286 b(restart)120 2595 y(#)24 b(-d)f(dmn)191 +b(local)23 b(domain)120 2645 y(#)h(-w)f(wait)167 b(wait)23 +b(between)g(unmount)g(attempts)p eop +%%Page: 28 30 +28 29 bop 15 -83 a Fo(SMM:13-28)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)120 158 y Fl(#)24 b(-l)f(log)191 b(logfile)23 +b(or)g("syslog")120 208 y(#)120 258 y(eval)g(./amd)g(-r)h($dmn)f(-w)h(240)f +(-l)h("$LOGFILE")f(\\)311 308 y(/homes)g(amd.homes)g(-cache:=inc)f(\\)311 +358 y(/home)h(amd.home)g(-cache:=inc)f(\\)311 407 y(/vol)h(amd.vol)g +(-cache:=inc)f(\\)311 457 y(/n)h(amd.net)g(-cache:=inc)62 549 +y Fo(If)12 b(the)g(list)g(of)f(automoun)o(t)f(p)q(oin)o(ts)i(and)g(maps)f(is) +h(con)o(tained)g(in)h(a)e(\014le)i(or)e(NIS)h(map)f(it)h(is)g(easily)g +(incorp)q(orated)0 598 y(on)o(to)i(the)i(command)f(line:)120 +669 y Fl(...)120 719 y(eval)23 b(./amd)g(-r)h($dmn)f(-w)h(240)f(-l)h +("$LOGFILE")f(`ypcat)g(-k)g(auto.master`)0 904 y Fq(6.2)33 +b(Stopping)16 b Ff(Amd)62 995 y Fp(Amd)h Fo(stops)e(in)h(resp)q(onse)g(to)e +(t)o(w)o(o)g(signals.)0 1066 y(`)p Fl(SIGTERM)p Fo(')46 b(causes)18 +b(the)f(top-lev)o(el)i(automoun)o(t)d(p)q(oin)o(ts)i(to)f(b)q(e)h(unmoun)o +(ted)f(and)h(then)g Fp(Amd)h Fo(to)e(exit.)27 b(An)o(y)240 +1116 y(automoun)o(ted)16 b(\014lesystems)g(are)g(left)h(moun)o(ted.)23 +b(They)17 b(can)f(b)q(e)h(reco)o(v)o(ered)f(b)o(y)g(restarting)g +Fp(Amd)240 1166 y Fo(with)g(the)f(\\-r")f(command)h(line)i(option.)0 +1230 y(`)p Fl(SIGINT)p Fo(')70 b(causes)22 b Fp(Amd)i Fo(to)d(attempt)g(to)g +(unmoun)o(t)h(an)o(y)g(\014lesystems)g(whic)o(h)h(it)f(has)g(automoun)o(ted,) +g(in)240 1280 y(addition)16 b(to)f(the)g(actions)g(of)g(`)p +Fl(SIGTERM)p Fo('.)j(This)e(signal)g(is)g(primarly)g(used)g(for)e(debugging.) +62 1371 y(Actions)i(tak)o(en)f(for)f(other)h(signals)h(are)f(unde\014ned.)0 +1556 y Fq(6.3)33 b(Con)n(trolling)17 b Ff(Amd)62 1647 y Fo(It)f(is)h +(sometimes)f(desirable)i(or)d(necessary)i(to)e(exercise)i(external)g(con)o +(trol)f(o)o(v)o(er)f(some)h(of)f Fp(Amd)r Fo('s)h(in)o(ternal)0 +1697 y(state.)j(T)l(o)c(supp)q(ort)g(this)h(requiremen)o(t,)f +Fp(Amd)i Fo(implemen)o(ts)g(an)e(RPC)g(in)o(terface)g(whic)o(h)h(is)g(used)g +(b)o(y)f(the)g Fp(Amq)0 1746 y Fo(program.)k(A)c(v)m(ariet)o(y)g(of)g +(information)g(is)h(a)o(v)m(ailable.)62 1817 y Fp(Amq)e Fo(generally)h +(applies)f(an)f(op)q(eration,)h(sp)q(eci\014ed)h(b)o(y)e(a)g(single)h(letter) +f(option,)h(to)e(a)h(list)h(of)e(moun)o(t)h(p)q(oin)o(ts.)0 +1867 y(The)i(default)g(op)q(eration)g(is)g(to)f(obtain)g(statistics)h(ab)q +(out)f(eac)o(h)h(moun)o(t)f(p)q(oin)o(t.)20 b(This)15 b(is)g(similar)h(to)e +(the)g(output)0 1917 y(sho)o(wn)f(ab)q(o)o(v)o(e)g(but)h(includes)h +(information)f(ab)q(out)f(the)h(n)o(um)o(b)q(er)g(and)f(t)o(yp)q(e)h(of)f +(accesses)h(to)e(eac)o(h)i(moun)o(t)f(p)q(oin)o(t.)0 2077 y +Fi(6.3.1)30 b Fe(Amq)16 b Fi(default)f(information)62 2169 +y Fo(With)k(no)f(argumen)o(ts,)f Fp(Amq)i Fo(obtains)f(a)g(brief)h(list)g(of) +e(all)i(existing)h(moun)o(ts)d(created)h(b)o(y)g Fp(Amd)p Fo(.)29 +b(This)18 b(is)0 2218 y(di\013eren)o(t)d(from)g(the)g(list)h(displa)o(y)o(ed) +h(b)o(y)e Fk(df)p Fo(\(1\))f(since)j(the)e(latter)g(only)g(includes)j(system) +d(moun)o(t)f(p)q(oin)o(ts.)0 2289 y(The)h(output)g(from)g(this)h(option)f +(includes)i(the)f(follo)o(wing)g(information:)37 2360 y Fn(\017)30 +b Fo(the)15 b(automoun)o(t)f(p)q(oin)o(t,)37 2424 y Fn(\017)30 +b Fo(the)15 b(\014lesystem)h(t)o(yp)q(e,)37 2489 y Fn(\017)30 +b Fo(the)15 b(moun)o(t)g(map)g(or)g(moun)o(t)f(information,)37 +2554 y Fn(\017)30 b Fo(the)15 b(in)o(ternal,)h(or)f(system)f(moun)o(t)h(p)q +(oin)o(t.)0 2645 y(F)l(or)g(example:)p eop +%%Page: 29 31 +29 30 bop 0 -83 a Fo(Chapter)15 b(6:)k(Run-time)e(Administration)987 +b(SMM:13-29)120 158 y Fl(/)286 b(root)71 b("root")477 b(sky:\(pid75\))120 +208 y(/homes)166 b(toplvl)23 b(/usr/local/etc/amd.homes)45 +b(/homes)120 258 y(/home)190 b(toplvl)23 b(/usr/local/etc/amd.home)69 +b(/home)120 308 y(/homes/jsp)h(nfs)95 b(charm:/home/charm)213 +b(/a/charm/home/charm/jsp)120 358 y(/homes/phjk)46 b(nfs)95 +b(toytown:/home/toytown)117 b(/a/toytown/home/toytown/)o(ai/phjk)0 +449 y Fo(If)15 b(an)h(argumen)o(t)e(is)i(giv)o(en)f(then)h(statistics)f(for)g +(that)f(v)o(olume)i(name)f(will)i(b)q(e)f(output.)j(F)l(or)c(example:)120 +519 y Fl(What)286 b(Uid)71 b(Getattr)23 b(Lookup)g(RdDir)71 +b(RdLnk)g(Statfs)23 b(Mounted@)120 569 y(/homes)238 b(0)119 +b(1196)95 b(512)g(22)143 b(0)167 b(30)119 b(90/09/14)23 b(12:32:55)120 +619 y(/homes/jsp)142 b(0)119 b(0)167 b(0)143 b(0)167 b(1180)95 +b(0)143 b(90/10/13)23 b(12:56:58)0 690 y(What)144 b Fo(the)15 +b(v)o(olume)h(name.)0 752 y Fl(Uid)168 b Fo(ignored.)0 815 +y Fl(Getattr)72 b Fo(the)21 b(coun)o(t)g(of)f(NFS)h Fp(getattr)i +Fo(requests)e(on)g(this)g(no)q(de.)38 b(This)21 b(should)h(only)g(b)q(e)f +(non-zero)h(for)240 865 y(directory)15 b(no)q(des.)0 928 y +Fl(Lookup)96 b Fo(the)21 b(coun)o(t)g(of)g(NFS)g Fp(lo)q(okup)j +Fo(requests)d(on)g(this)h(no)q(de.)38 b(This)22 b(should)g(only)g(b)q(e)g +(non-zero)g(for)240 978 y(directory)15 b(no)q(des.)0 1040 y +Fl(RdDir)120 b Fo(the)21 b(coun)o(t)f(of)g(NFS)h Fp(readdir)j +Fo(requests)d(on)g(this)g(no)q(de.)36 b(This)22 b(should)f(only)g(b)q(e)h +(non-zero)f(for)240 1090 y(directory)15 b(no)q(des.)0 1153 +y Fl(RdLnk)120 b Fo(the)19 b(coun)o(t)g(of)g(NFS)g Fp(readlink)k +Fo(requests)c(on)h(this)f(no)q(de.)32 b(This)20 b(should)g(b)q(e)g(zero)f +(for)g(directory)240 1203 y(no)q(des.)0 1266 y Fl(Statfs)96 +b Fo(the)11 b(could)h(of)f(NFS)g Fp(statfs)h Fo(requests)f(on)g(this)h(no)q +(de.)19 b(This)11 b(should)h(only)g(b)q(e)g(non-zero)f(for)g(top-lev)o(el)240 +1315 y(automoun)o(t)j(p)q(oin)o(ts.)0 1378 y Fl(Mounted@)48 +b Fo(the)15 b(date)g(and)h(time)f(the)g(v)o(olume)h(name)f(w)o(as)g(\014rst)f +(referenced.)0 1523 y Fi(6.3.2)30 b Fe(Amq)16 b Fi(-f)f(option)62 +1615 y Fo(The)i(\\-f)t(")f(option)h(causes)g Fp(Amd)i Fo(to)d(\015ush)h(the)g +(in)o(ternal)h(moun)o(t)e(map)g(cac)o(he.)25 b(This)18 b(is)f(useful)h(for)e +(Hesio)q(d)0 1664 y(maps)f(since)i Fp(Amd)g Fo(will)g(not)e(automatically)h +(notice)g(when)g(they)g(ha)o(v)o(e)f(b)q(een)i(up)q(dated.)k(The)16 +b(map)f(cac)o(he)h(can)0 1714 y(also)g(b)q(e)g(sync)o(hronised)g(with)g(the)g +(map)f(source)h(b)o(y)g(using)g(the)f(`)p Fl(sync)p Fo(')g(option)h(\(see)f +(Section)h(5.8)f([Automoun)o(t)0 1764 y(Filesystem],)g(page)30 +b(SMM:13-24\).)0 1909 y Fi(6.3.3)g Fe(Amq)16 b Fi(-h)g(option)62 +2000 y Fo(By)g(default)g(the)g(lo)q(cal)g(host)f(is)h(used.)22 +b(In)16 b(an)f(HP-UX)h(cluster)g(the)g(ro)q(ot)e(serv)o(er)h(is)h(used)g +(since)h(that)e(is)h(the)0 2050 y(only)k(place)g(in)g(the)f(cluster)h(where)f +Fp(Amd)i Fo(will)g(b)q(e)f(running.)33 b(T)l(o)19 b(query)g +Fp(Amd)i Fo(on)e(another)g(host)g(the)g(\\-h")0 2100 y(option)c(should)i(b)q +(e)e(used.)0 2245 y Fi(6.3.4)30 b Fe(Amq)16 b Fi(-m)g(option)62 +2336 y Fo(The)c(\\-m")e(option)h(displa)o(ys)h(similar)h(information)e(ab)q +(out)g(moun)o(ted)g(\014lesystems,)h(rather)e(than)h(automoun)o(t)0 +2386 y(p)q(oin)o(ts.)20 b(The)c(output)f(includes)i(the)e(follo)o(wing)h +(information:)37 2457 y Fn(\017)30 b Fo(the)15 b(moun)o(t)g(information,)37 +2520 y Fn(\017)30 b Fo(the)15 b(moun)o(t)g(p)q(oin)o(t,)37 +2582 y Fn(\017)30 b Fo(the)15 b(\014lesystem)h(t)o(yp)q(e,)37 +2645 y Fn(\017)30 b Fo(the)15 b(n)o(um)o(b)q(er)h(of)f(references)g(to)g +(this)h(\014lesystem,)p eop +%%Page: 30 32 +30 31 bop 15 -83 a Fo(SMM:13-30)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)37 158 y Fn(\017)30 b Fo(the)15 b(serv)o(er)g +(hostname,)37 221 y Fn(\017)30 b Fo(the)15 b(state)g(of)f(the)i(\014le)g +(serv)o(er,)37 284 y Fn(\017)30 b Fo(an)o(y)15 b(error)f(whic)o(h)i(has)f(o)q +(ccured.)62 375 y(F)l(or)g(example:)120 446 y Fl("root")262 +b(truth:\(pid602\))117 b(root)71 b(1)24 b(localhost)e(is)i(up)120 +496 y(hesiod.home)142 b(/home)333 b(toplvl)23 b(1)h(localhost)e(is)i(up)120 +546 y(hesiod.vol)166 b(/vol)357 b(toplvl)23 b(1)h(localhost)e(is)i(up)120 +595 y(hesiod.homes)118 b(/homes)309 b(toplvl)23 b(1)h(localhost)e(is)i(up)120 +645 y(amy:/home/amy)94 b(/a/amy/home/amy)f(nfs)i(5)24 b(amy)f(is)h(up)120 +695 y(swan:/home/swan)46 b(/a/swan/home/swan)f(nfs)95 b(0)24 +b(swan)f(is)h(up)f(\(Permission)g(denied\))120 745 y(ex:/home/ex)142 +b(/a/ex/home/ex)f(nfs)95 b(0)24 b(ex)f(is)h(down)62 836 y Fo(When)15 +b(the)g(reference)g(coun)o(t)f(is)h(zero)g(the)f(\014lesystem)i(is)f(not)f +(moun)o(ted)g(but)h(the)g(moun)o(t)f(p)q(oin)o(t)h(and)f(serv)o(er)0 +886 y(information)h(is)h(still)h(b)q(eing)f(main)o(tained)g(b)o(y)f +Fp(Amd)p Fo(.)0 1032 y Fi(6.3.5)30 b Fe(Amq)16 b Fi(-M)g(option)62 +1123 y Fo(The)j(\\-M")f(option)i(passes)e(a)h(new)g(map)g(en)o(try)f(to)g +Fp(Amd)j Fo(and)e(w)o(aits)g(for)f(it)h(to)f(b)q(e)i(ev)m(aluated,)g(p)q +(ossibly)0 1173 y(causing)i(a)f(moun)o(t.)38 b(F)l(or)21 b(example,)j(the)d +(follo)o(wing)h(command)g(w)o(ould)f(cause)h(`)p Fl(/home/toytown)p +Fo(')d(on)i(host)0 1223 y(`)p Fl(toytown)p Fo(')13 b(to)i(b)q(e)h(moun)o(ted) +f(lo)q(cally)i(on)e(`)p Fl(/mnt/toytown)p Fo('.)120 1293 y +Fl(amq)23 b(-M)h('/mnt/toytown)e(type:=nfs;rfs:=/home/toytow)o(n;rhost)o +(:=toytow)o(n;fs:=$)o({key}')62 1385 y Fp(Amd)13 b Fo(applies)g(some)e +(simple)i(securit)o(y)e(c)o(hec)o(ks)h(b)q(efore)f(allo)o(wing)h(this)g(op)q +(eration.)18 b(The)12 b(c)o(hec)o(k)f(tests)g(whether)0 1434 +y(the)16 b(incoming)h(request)f(is)g(from)f(a)h(privileged)i(UDP)d(p)q(ort)h +(on)g(the)f(lo)q(cal)i(mac)o(hine.)23 b(\\P)o(ermission)16 +b(denied")h(is)0 1484 y(returned)f(if)f(the)h(c)o(hec)o(k)f(fails.)62 +1555 y(A)f(future)f(release)h(of)e Fp(Amd)j Fo(will)g(include)h(co)q(de)e(to) +e(allo)o(w)i(the)f Fk(moun)o(t)p Fo(\(8\))f(command)h(to)f(moun)o(t)h +(automoun)o(t)0 1605 y(p)q(oin)o(ts:)120 1675 y Fl(mount)23 +b(-t)h(amd)f(/vol)h(hesiod.vol)62 1766 y Fo(This)16 b(will)h(then)e(allo)o(w) +h Fp(Amd)h Fo(to)e(b)q(e)g(con)o(trolled)h(from)f(the)g(standard)g(system)g +(\014lesystem)h(moun)o(t)e(list.)0 1912 y Fi(6.3.6)30 b Fe(Amq)16 +b Fi(-s)g(option)62 2004 y Fo(The)h(\\-s")f(option)h(displa)o(ys)h(global)f +(statistics.)24 b(If)17 b(an)o(y)g(other)f(options)h(are)f(sp)q(eci\014ed)j +(or)d(an)o(y)g(\014lesystems)0 2053 y(named)f(then)h(this)g(option)f(is)h +(ignored.)k(F)l(or)15 b(example:)120 2124 y Fl(requests)47 +b(stale)118 b(mount)h(mount)g(unmount)120 2174 y(deferred)47 +b(fhandles)f(ok)191 b(failed)95 b(failed)120 2224 y(1054)143 +b(1)214 b(487)167 b(290)g(7017)0 2294 y Fo(`)p Fl(Deferred)14 +b(requests)p Fo(')240 2357 y(are)k(those)f(for)h(whic)o(h)h(an)f(immediate)h +(reply)f(could)h(not)f(b)q(e)h(constructed.)28 b(F)l(or)17 +b(example,)j(this)240 2407 y(w)o(ould)c(happ)q(en)g(if)g(a)e(bac)o(kground)i +(moun)o(t)e(w)o(as)h(required.)0 2470 y(`)p Fl(Stale)f(filehandles)p +Fo(')240 2532 y(coun)o(ts)f(the)g(n)o(um)o(b)q(er)g(of)g(times)g(the)g(k)o +(ernel)h(passes)f(a)g(stale)g(\014lehandle)i(to)e Fp(Amd)p +Fo(.)19 b(Large)13 b(n)o(um)o(b)q(ers)240 2582 y(indicate)k(problems.)0 +2645 y(`)p Fl(Mount)d(ok)p Fo(')32 b(coun)o(ts)15 b(the)g(n)o(um)o(b)q(er)h +(of)f(automoun)o(ts)f(whic)o(h)i(w)o(ere)e(successful.)p eop +%%Page: 31 33 +31 32 bop 0 -83 a Fo(Chapter)15 b(7:)k(FSinfo)1362 b(SMM:13-31)0 +158 y(`)p Fl(Mount)14 b(failed)p Fo(')240 222 y(coun)o(ts)h(the)g(n)o(um)o(b) +q(er)h(of)f(automoun)o(ts)f(whic)o(h)i(failed.)0 286 y(`)p +Fl(Unmount)e(failed)p Fo(')240 350 y(coun)o(ts)h(the)g(n)o(um)o(b)q(er)g(of)f +(times)h(a)g(\014lesystem)g(could)h(not)f(b)q(e)g(unmoun)o(ted.)21 +b(V)l(ery)15 b(large)g(n)o(um)o(b)q(ers)240 400 y(here)h(indicate)g(that)f +(the)g(time)h(b)q(et)o(w)o(een)f(unmoun)o(t)g(attempts)f(should)j(b)q(e)f +(increased.)0 554 y Fi(6.3.7)30 b Fe(Amq)16 b Fi(-u)g(option)62 +645 y Fo(The)f(\\-u")g(option)g(causes)h(the)f(time-to-liv)o(e)h(in)o(terv)m +(al)g(of)e(the)h(named)h(moun)o(t)e(p)q(oin)o(ts)h(to)g(b)q(e)g(expired,)h +(th)o(us)0 695 y(causing)f(an)e(unmoun)o(t)h(attempt.)19 b(This)14 +b(is)g(the)g(only)h(safe)e(w)o(a)o(y)g(to)g(unmoun)o(t)h(an)g(automoun)o(ted) +f(\014lesystem.)20 b(It)0 745 y(is)c(not)f(p)q(ossible)h(to)f(unmoun)o(t)g(a) +g(\014lesystem)h(whic)o(h)g(has)f(b)q(een)h(moun)o(ted)f(with)h(the)f(`)p +Fl(nounmount)p Fo(')e(\015ag.)0 899 y Fi(6.3.8)30 b Fe(Amq)16 +b Fi(-v)g(option)62 990 y Fo(The)g(\\-v")e(option)i(displa)o(ys)g(the)f(v)o +(ersion)h(of)f Fp(Amd)i Fo(in)f(a)f(similar)h(w)o(a)o(y)e(to)h +Fp(Amd)r Fo('s)f(\\-v")h(option.)0 1145 y Fi(6.3.9)30 b(Other)15 +b Fe(Amq)h Fi(options)62 1236 y Fo(Three)j(other)g(op)q(erations)f(are)h +(implemen)o(ted.)32 b(These)19 b(mo)q(dify)g(the)g(state)f(of)g +Fp(Amd)j Fo(as)d(a)h(whole,)h(rather)0 1286 y(than)e(an)o(y)g(particular)h +(\014lesystem.)30 b(The)19 b(\\-l",)g(\\-x")f(and)h(\\-D")e(options)i(ha)o(v) +o(e)f(exactly)h(the)f(same)g(e\013ect)g(as)0 1336 y Fp(Amd)r +Fo('s)g(corresp)q(onding)h(command)g(line)h(options.)30 b(The)18 +b(\\-l")h(option)g(is)g(rejected)f(b)o(y)h Fp(Amd)h Fo(in)g(the)e(curren)o(t) +0 1385 y(v)o(ersion)e(for)e(ob)o(vious)i(securit)o(y)g(reasons.)j(When)d +Fp(Amd)h Fo(receiv)o(es)g(a)e(\\-x"\015ag)f(it)i(limits)g(the)g(log)f +(options)h(b)q(eing)0 1435 y(mo)q(di\014ed)g(to)e(those)h(whic)o(h)g(w)o(ere) +g(not)f(enabled)j(at)d(startup.)19 b(This)c(prev)o(en)o(ts)g(a)f(user)h +(turning)g Fp(o\013)23 b Fo(an)o(y)15 b(logging)0 1485 y(option)h(whic)o(h)h +(w)o(as)f(sp)q(eci\014ed)i(at)d(startup,)h(though)g(an)o(y)g(whic)o(h)h(ha)o +(v)o(e)e(b)q(een)j(turned)e(o\013)f(since)j(then)e(can)h(still)0 +1535 y(b)q(e)f(turned)f(o\013.)20 b(The)15 b(\\-D")f(option)i(has)f(a)g +(similar)h(b)q(eha)o(viour.)0 1737 y Fm(7)41 b(FSinfo)0 1964 +y Fq(7.1)33 b Ff(FSinfo)16 b Fq(o)n(v)n(erview)62 2056 y Fp(FSinfo)h +Fo(is)d(a)f(\014lesystem)h(managemen)o(t)f(to)q(ol.)19 b(It)14 +b(has)g(b)q(een)g(designed)h(to)e(w)o(ork)g(with)h Fp(Amd)i +Fo(to)c(help)j(system)0 2105 y(administrators)g(k)o(eep)g(trac)o(k)g(of)f +(the)i(ev)o(er)f(increasing)h(\014lesystem)g(namespace)g(under)g(their)f(con) +o(trol.)62 2176 y(The)20 b(purp)q(ose)g(of)f Fp(FSinfo)j Fo(is)e(to)e +(generate)h(all)i(the)e(imp)q(ortan)o(t)g(standard)g(\014lesystem)h(data)e +(\014les)j(from)d(a)0 2226 y(single)g(set)e(of)g(input)h(data.)23 +b(Starting)16 b(with)h(a)f(single)h(data)f(source)h(guaran)o(tees)e(that)h +(all)h(the)g(generated)f(\014les)0 2276 y(are)i(self-consisten)o(t.)28 +b(One)19 b(of)e(the)h(p)q(ossible)i(output)e(data)f(formats)f(is)j(a)e(set)h +(of)f Fp(Amd)j Fo(maps)e(whic)o(h)g(can)g(b)q(e)0 2325 y(used)e(amongst)e +(the)h(set)g(of)g(hosts)g(describ)q(ed)i(in)f(the)f(input)h(data.)62 +2396 y Fp(FSinfo)i Fo(implemen)o(ts)f(a)e(declarativ)o(e)h(language.)k(This)c +(language)g(is)g(sp)q(eci\014cally)i(designed)e(for)f(describing)0 +2446 y(\014lesystem)21 b(namespace)g(and)f(ph)o(ysical)i(la)o(y)o(outs.)34 +b(The)21 b(basic)g(declaration)g(de\014nes)g(a)f(moun)o(ted)g(\014lesystem)0 +2496 y(including)e(its)e(device)h(name,)e(moun)o(t)g(p)q(oin)o(t,)g(and)h +(all)g(the)g(v)o(olumes)g(and)f(access)h(p)q(ermissions.)22 +b Fp(FSinfo)c Fo(reads)0 2545 y(this)e(information)g(and)f(builds)j(an)d(in)o +(ternal)h(map)f(of)h(the)f(en)o(tire)h(net)o(w)o(ork)e(of)h(hosts.)21 +b(Using)16 b(this)f(map,)g(man)o(y)0 2595 y(di\013eren)o(t)d(data)g(formats)f +(can)h(b)q(e)h(pro)q(duced)h(including)h(`)p Fl(/etc/fstab)p +Fo(',)10 b(`)p Fl(/etc/exports)p Fo(',)g Fp(Amd)k Fo(moun)o(t)e(maps)0 +2645 y(and)j(`)p Fl(/etc/bootparams)p Fo('.)p eop +%%Page: 32 34 +32 33 bop 15 -83 a Fo(SMM:13-32)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 158 y Fq(7.2)33 b(Using)15 b Ff(FSinfo)62 +250 y Fo(The)20 b(basic)h(strategy)d(when)i(using)h Fp(FSinfo)h +Fo(is)e(to)f(gather)g(all)i(the)f(information)g(ab)q(out)f(all)i(disks)f(on)g +(all)0 299 y(mac)o(hines)i(in)o(to)e(one)h(set)g(of)g(declarations.)37 +b(F)l(or)20 b(eac)o(h)h(mac)o(hine)h(b)q(eing)g(managed,)g(the)f(follo)o +(wing)g(data)f(is)0 349 y(required:)37 420 y Fn(\017)30 b Fo(Hostname)37 +482 y Fn(\017)g Fo(List)16 b(of)f(all)h(\014lesystems)f(and,)g(optionally)l +(,)i(their)e(moun)o(t)g(p)q(oin)o(ts.)37 544 y Fn(\017)30 b +Fo(Names)15 b(of)g(v)o(olumes)g(stored)g(on)g(eac)o(h)g(\014lesystem.)37 +606 y Fn(\017)30 b Fo(NFS)15 b(exp)q(ort)g(information)h(for)e(eac)o(h)h(v)o +(olume.)37 668 y Fn(\017)30 b Fo(The)15 b(list)h(of)f(static)g(\014lesystem)h +(moun)o(ts.)62 759 y(The)g(follo)o(wing)g(information)f(can)h(also)f(b)q(e)h +(en)o(tered)g(in)o(to)f(the)h(same)f(con\014guration)g(\014les)i(so)e(that)f +(all)j(data)0 809 y(can)e(b)q(e)h(k)o(ept)f(in)h(one)g(place.)37 +879 y Fn(\017)30 b Fo(List)16 b(of)f(net)o(w)o(ork)f(in)o(terfaces)37 +941 y Fn(\017)30 b Fo(IP)16 b(address)f(of)g(eac)o(h)g(in)o(terface)37 +1003 y Fn(\017)30 b Fo(Hardw)o(are)14 b(address)i(of)e(eac)o(h)i(in)o +(terface)37 1065 y Fn(\017)30 b Fo(Dumpset)15 b(to)g(whic)o(h)h(eac)o(h)f +(\014lesystem)h(b)q(elongs)37 1127 y Fn(\017)30 b Fo(and)15 +b(more)g Fj(:)8 b(:)g(:)62 1218 y Fo(T)l(o)13 b(generate)f +Fp(Amd)j Fo(moun)o(t)d(maps,)g(the)h(automoun)o(t)f(tree)g(m)o(ust)g(also)h +(b)q(e)g(de\014ned)h(\(see)f(Section)g(7.8)f([FSinfo)0 1268 +y(automoun)o(t)k(de\014nitions],)j(page)34 b(SMM:13-39\).)23 +b(This)18 b(will)h(ha)o(v)o(e)d(b)q(een)j(designed)f(at)f(the)g(time)g(the)h +(v)o(olume)0 1318 y(names)f(w)o(ere)f(allo)q(cated.)26 b(Some)17 +b(v)o(olume)g(names)f(will)j(not)d(b)q(e)i(automoun)o(ted,)e(so)g +Fp(FSinfo)k Fo(needs)d(an)g(explicit)0 1368 y(list)f(of)f(whic)o(h)h(v)o +(olumes)f(should)i(b)q(e)e(automoun)o(ted.)62 1438 y(Hostnames)k(are)f +(required)j(at)d(sev)o(eral)h(places)h(in)g(the)f Fp(FSinfo)j +Fo(language.)32 b(It)19 b(is)g(imp)q(ortan)o(t)g(to)f(stic)o(k)i(to)0 +1488 y(either)15 b(fully)h(quali\014ed)g(names)e(or)g(unquali\014ed)j(names.) +i(Using)c(a)f(mixture)h(of)f(the)g(t)o(w)o(o)f(will)j(inevitably)h(result)0 +1538 y(in)f(confusion.)62 1609 y(Sometimes)c(v)o(olumes)f(need)h(to)e(b)q(e)i +(referenced)g(whic)o(h)g(are)e(not)h(de\014ned)h(in)g(the)f(set)g(of)f(hosts) +h(b)q(eing)h(managed)0 1658 y(with)19 b Fp(FSinfo)p Fo(.)31 +b(The)18 b(required)i(action)f(is)g(to)f(add)h(a)f(dumm)o(y)h(set)f(of)g +(de\014nitions)j(for)d(the)h(host)f(and)h(v)o(olume)0 1708 +y(names)d(required.)24 b(Since)17 b(the)g(\014les)g(generated)f(for)f(those)h +(particular)h(hosts)f(will)i(not)d(b)q(e)i(used)g(on)f(them,)g(the)0 +1758 y(exact)f(v)m(alues)h(used)g(is)g(not)f(critical.)0 1914 +y Fq(7.3)33 b Ff(FSinfo)16 b Fq(grammar)62 2006 y Fp(FSinfo)24 +b Fo(has)d(a)g(relativ)o(ely)i(simple)g(grammar.)36 b(Distinct)22 +b(syn)o(tactic)f(constructs)g(exist)h(for)f(eac)o(h)g(of)g(the)0 +2056 y(di\013eren)o(t)c(t)o(yp)q(es)f(of)g(data,)g(though)g(they)h(share)f(a) +g(common)g(\015a)o(v)o(our.)23 b(Sev)o(eral)17 b(con)o(v)o(en)o(tions)f(are)h +(used)g(in)g(the)0 2105 y(grammar)d(fragmen)o(ts)g(b)q(elo)o(w.)62 +2176 y(The)g(notation,)f Fp(list\()t Fl(xxx)p Fp(\))p Fo(,)g(indicates)i(a)e +(list)h(of)f(zero)h(or)e(more)h Fl(xxx)p Fo('s.)19 b(The)13 +b(notation,)g Fp(opt\()t Fl(xxx)p Fp(\))p Fo(,)g(indicates)0 +2226 y(zero)22 b(or)g(one)g Fl(xxx)p Fo(.)41 b(Items)23 b(in)g(double)g +(quotes,)h Fp(eg)i Fl("host")p Fo(,)d(represen)o(t)f(input)h(tok)o(ens.)41 +b(Items)22 b(in)h(angle)0 2276 y(brac)o(k)o(ets,)d Fp(eg)j +Fl(<)p Fp(hostname)p Fl(>)p Fo(,)d(represen)o(t)g(strings)g(in)g(the)g +(input.)35 b(Strings)20 b(need)g(not)g(b)q(e)g(in)h(double)g(quotes,)0 +2325 y(except)d(to)e(di\013eren)o(tiate)i(them)f(from)f(reserv)o(ed)i(w)o +(ords.)25 b(Quoted)17 b(strings)g(ma)o(y)g(include)i(the)f(usual)f(set)g(of)g +(C)0 2375 y(\\)p Fl(\\)p Fo(")12 b(escap)q(e)h(sequences)g(with)f(one)h +(exception:)19 b(a)12 b(bac)o(kslash-newline-whi)q(tespace)j(sequence)e(is)g +(squashed)g(in)o(to)0 2425 y(a)i(single)i(space)g(c)o(haracter.)j(T)l(o)c +(defeat)f(this)i(feature,)e(put)h(a)f(further)h(bac)o(kslash)g(at)f(the)h +(start)e(of)i(the)f(second)0 2475 y(line.)62 2545 y(A)o(t)f(the)h(outermost)e +(lev)o(el)j(of)e(the)g(grammar,)f(the)i(input)g(consists)g(of)f(a)g(sequence) +h(of)f(host)g(and)h(automoun)o(t)0 2595 y(declarations.)34 +b(These)20 b(declarations)h(are)e(all)i(parsed)f(b)q(efore)g(they)g(are)f +(analyzed.)35 b(This)20 b(means)g(they)g(can)0 2645 y(app)q(ear)15 +b(in)h(an)o(y)f(order)g(and)h(cyclic)h(host)d(references)i(are)f(p)q +(ossible.)p eop +%%Page: 33 35 +33 34 bop 0 -83 a Fo(Chapter)15 b(7:)k(FSinfo)1362 b(SMM:13-33)120 +158 y Fl(fsinfo)142 b(:)24 b Fp(list\()t Fl(fsinfo_attr)p Fp(\))g +Fl(;)120 258 y(fsinfo_attr)e(:)i(host)f(|)h(automount)f(;)0 +460 y Fq(7.4)33 b Ff(FSinfo)16 b Fq(host)f(de\014nitions)62 +552 y Fo(A)h(host)g(declaration)g(consists)g(of)g(three)g(parts:)k(a)c(set)f +(of)h(mac)o(hine)g(attribute)g(data,)f(a)g(list)i(of)e(\014lesystems)0 +601 y(ph)o(ysically)i(attac)o(hed)e(to)f(the)i(mac)o(hine,)f(and)h(a)e(list)i +(of)f(additional)i(statically)f(moun)o(ted)f(\014lesystems.)120 +672 y Fl(host)190 b(:)24 b("host")f(host_data)g Fp(list\()t +Fl(filesystem)p Fp(\))h(list\()t Fl(mount)p Fp(\))g Fl(;)62 +763 y Fo(Eac)o(h)15 b(host)f(m)o(ust)g(b)q(e)i(declared)g(in)f(this)h(w)o(a)o +(y)d(exactly)i(once.)20 b(Suc)o(h)c(things)f(as)f(the)h(hardw)o(are)f +(address,)h(the)0 813 y(arc)o(hitecture)e(and)f(op)q(erating)h(system)f(t)o +(yp)q(es)h(and)f(the)h(cluster)g(name)g(are)f(all)h(sp)q(eci\014ed)i(within)e +(the)g Fp(host)f(data)p Fo(.)62 884 y(All)h(the)e(disks)h(the)f(mac)o(hine)h +(has)f(should)h(then)g(b)q(e)f(describ)q(ed)j(in)e(the)f Fp(list)h(of)e +(\014lesystems)p Fo(.)20 b(When)11 b(describing)0 933 y(disks,)17 +b(y)o(ou)f(can)h(sp)q(ecify)h(what)e Fp(v)o(olname)j Fo(the)e(disk/partition) +g(should)h(ha)o(v)o(e)e(and)h(all)g(suc)o(h)g(en)o(tries)g(are)g(built)0 +983 y(up)f(in)o(to)f(a)g(dictionary)h(whic)o(h)g(can)f(then)h(b)q(e)g(used)f +(for)g(building)j(the)d(automoun)o(ter)f(maps.)62 1054 y(The)f +Fp(list)g(of)e(moun)o(ts)j Fo(sp)q(eci\014es)g(all)f(the)f(\014lesystems)h +(that)e(should)i(b)q(e)g(statically)g(moun)o(ted)f(on)g(the)g(mac)o(hine.)0 +1263 y Fq(7.5)33 b Ff(FSinfo)16 b Fq(host)f(attributes)62 1354 +y Fo(The)20 b(host)g(data,)f Fp(host)p 472 1354 14 2 v 16 w(data)p +Fo(,)h(alw)o(a)o(ys)f(includes)j(the)e Fp(hostname)p Fo(.)33 +b(In)20 b(addition,)i(sev)o(eral)e(other)f(host)g(at-)0 1404 +y(tributes)d(can)f(b)q(e)h(giv)o(en.)120 1474 y Fl(host_data)70 +b(:)24 b(<)p Fp(hostname)p Fl(>)406 1524 y(|)g("{")g Fp(list\()t +Fl(host_attrs)p Fp(\))f Fl("}")h(<)p Fp(hostname)p Fl(>)406 +1574 y(;)120 1674 y(host_attrs)46 b(:)24 b(host_attr)f("=")g(<)p +Fp(string)p Fl(>)406 1724 y(|)h(netif)406 1773 y(;)120 1873 +y(host_attr)70 b(:)24 b("config")406 1923 y(|)g("arch")406 +1973 y(|)g("os")406 2022 y(|)g("cluster")406 2072 y(;)62 2164 +y Fo(The)16 b Fp(hostname)h Fo(is,)e(t)o(ypically)l(,)i(the)e(fully)i +(quali\014ed)g(hostname)e(of)f(the)i(mac)o(hine.)62 2234 y(Examples:)120 +2305 y Fl(host)23 b(dylan.doc.ic.ac.uk)120 2404 y(host)g({)215 +2454 y(os)h(=)g(hpux)215 2504 y(arch)g(=)f(hp300)120 2554 y(})h +(dougal.doc.ic.ac.uk)62 2645 y Fo(The)16 b(options)f(that)g(can)g(b)q(e)h +(giv)o(en)f(as)g(host)g(attributes)g(are)g(sho)o(wn)g(b)q(elo)o(w.)p +eop +%%Page: 34 36 +34 35 bop 15 -83 a Fo(SMM:13-34)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 158 y Fi(7.5.1)30 b(netif)15 b(Option)62 +250 y Fo(This)j(de\014nes)g(the)f(set)g(of)g(net)o(w)o(ork)f(in)o(terfaces)h +(con\014gured)h(on)f(the)g(mac)o(hine.)26 b(The)18 b(in)o(terface)f +(attributes)0 299 y(collected)k(b)o(y)e Fp(FSinfo)j Fo(are)d(the)g(IP)g +(address,)h(subnet)g(mask)e(and)i(hardw)o(are)e(address.)32 +b(Multiple)21 b(in)o(terfaces)0 349 y(ma)o(y)c(b)q(e)h(de\014ned)h(for)d +(hosts)h(with)h(sev)o(eral)g(in)o(terfaces)f(b)o(y)h(an)f(en)o(try)g(for)g +(eac)o(h)g(in)o(terface.)27 b(The)18 b(v)m(alues)g(giv)o(en)0 +399 y(are)d(sanit)o(y)g(c)o(hec)o(k)o(ed,)g(but)h(are)e(curren)o(tly)i(un)o +(used)g(for)f(an)o(ything)g(else.)120 470 y Fl(netif)166 b(:)24 +b("netif")f(<)p Fp(string)p Fl(>)h("{")f Fp(list\()t Fl(netif_attrs)p +Fp(\))h Fl("}")f(;)120 569 y(netif_attrs)f(:)i(netif_attr)f("=")g(<)p +Fp(string)p Fl(>)h(;)120 669 y(netif_attr)46 b(:)24 b("inaddr")f(|)h +("netmask")e(|)i("hwaddr")f(;)62 760 y Fo(Examples:)120 831 +y Fl(netif)g(ie0)h({)215 881 y(inaddr)47 b(=)24 b(129.31.81.37)215 +930 y(netmask)f(=)h(0xfffffe00)215 980 y(hwaddr)47 b(=)24 b +("08:00:20:01:a6:a5")120 1030 y(})120 1130 y(netif)f(ec0)h({)f(})0 +1292 y Fi(7.5.2)30 b(con\014g)15 b(Option)62 1383 y Fo(This)g(option)e(allo)o +(ws)h(y)o(ou)g(to)f(sp)q(ecify)i(con\014guration)e(v)m(ariables)i(for)e(the)h +(startup)f(scripts)h(\(`)p Fl(rc)p Fo(')e(scripts\).)20 b(A)0 +1433 y(simple)d(string)e(should)h(immediately)h(follo)o(w)e(the)g(k)o(eyw)o +(ord.)62 1503 y(Example:)120 1574 y Fl(config)23 b("NFS_SERVER=true")120 +1624 y(config)g("ZEPHYR=true")62 1715 y Fo(This)16 b(option)f(is)h(curren)o +(tly)g(unsupp)q(orted.)0 1877 y Fi(7.5.3)30 b(arc)n(h)16 b(Option)62 +1968 y Fo(This)g(de\014nes)g(the)g(arc)o(hitecture)f(of)g(the)g(mac)o(hine.) +21 b(F)l(or)14 b(example:)120 2039 y Fl(arch)23 b(=)h(hp300)62 +2130 y Fo(This)12 b(is)g(in)o(tended)h(to)e(b)q(e)h(of)f(use)h(when)g +(building)i(arc)o(hitecture)e(sp)q(eci\014c)h(moun)o(tmaps,)e(ho)o(w)o(ev)o +(er,)g(the)h(option)0 2180 y(is)k(curren)o(tly)f(unsupp)q(orted.)0 +2342 y Fi(7.5.4)30 b(os)15 b(Option)62 2433 y Fo(This)h(de\014nes)g(the)g(op) +q(erating)f(system)g(t)o(yp)q(e)g(of)g(the)g(host.)k(F)l(or)c(example:)120 +2504 y Fl(os)24 b(=)f(hpux)62 2595 y Fo(This)16 b(information)g(is)g(used)g +(when)g(creating)g(the)g(`)p Fl(fstab)p Fo(')e(\014les,)i(for)f(example)i(in) +f(c)o(ho)q(osing)g(whic)o(h)g(format)0 2645 y(to)f(use)g(for)g(the)g(`)p +Fl(fstab)p Fo(')f(en)o(tries)h(within)i(the)e(\014le.)p eop +%%Page: 35 37 +35 36 bop 0 -83 a Fo(Chapter)15 b(7:)k(FSinfo)1362 b(SMM:13-35)0 +158 y Fi(7.5.5)30 b(cluster)16 b(Option)62 250 y Fo(This)g(is)g(used)g(for)e +(sp)q(ecifying)j(in)f(whic)o(h)g(cluster)g(the)f(mac)o(hine)h(b)q(elongs.)21 +b(F)l(or)15 b(example:)120 320 y Fl(cluster)23 b(=)h("theory")62 +412 y Fo(The)13 b(cluster)f(is)h(in)o(tended)g(to)e(b)q(e)i(used)g(when)f +(generating)g(the)h(automoun)o(t)d(maps,)i(although)h(it)f(is)g(curren)o(tly) +0 461 y(unsupp)q(orted.)0 657 y Fq(7.6)33 b Ff(FSinfo)16 b +Fq(\014lesystems)62 748 y Fo(The)h(list)g(of)f(ph)o(ysically)j(attac)o(hed)d +(\014lesystems)h(follo)o(ws)f(the)h(mac)o(hine)g(attributes.)24 +b(These)16 b(should)i(de\014ne)0 798 y(all)e(the)f(\014lesystems)h(a)o(v)m +(ailable)g(from)f(this)g(mac)o(hine,)h(whether)f(exp)q(orted)g(or)g(not.)k +(In)d(addition)g(to)e(the)i(device)0 848 y(name,)g(\014lesystems)g(ha)o(v)o +(e)f(sev)o(eral)h(attributes,)f(suc)o(h)i(as)e(\014lesystem)h(t)o(yp)q(e,)g +(moun)o(t)f(options,)h(and)g(`)p Fl(fsck)p Fo(')e(pass)0 897 +y(n)o(um)o(b)q(er)i(whic)o(h)g(are)e(needed)j(to)e(generate)f(`)p +Fl(fstab)p Fo(')g(en)o(tries.)120 968 y Fl(filesystem)46 b(:)24 +b("fs")f(<)p Fp(device)p Fl(>)i("{")f Fp(list\()t Fl(fs_data)p +Fp(\))g Fl("}")g(;)120 1068 y(fs_data)118 b(:)24 b(fs_data_attr)e("=")i(<)p +Fp(string)p Fl(>)406 1117 y(|)g(mount)406 1167 y(;)120 1267 +y(fs_data_attr)406 1317 y(:)g("fstype")f(|)h("opts")f(|)g("passno")406 +1367 y(|)h("freq")f(|)h("dumpset")e(|)i("log")406 1416 y(;)62 +1508 y Fo(Here,)15 b Fl(<)p Fp(device)p Fl(>)h Fo(is)g(the)f(device)h(name)f +(of)g(the)g(disk)h(\(for)e(example,)h(`)p Fl(/dev/dsk/2s0)p +Fo('\).)i(The)f(device)g(name)0 1558 y(is)g(used)h(for)e(building)j(the)e +(moun)o(t)g(maps)f(and)h(for)f(the)h(`)p Fl(fstab)p Fo(')f(\014le.)23 +b(The)16 b(attributes)f(that)g(can)h(b)q(e)h(sp)q(eci\014ed)0 +1607 y(are)e(sho)o(wn)g(in)h(the)f(follo)o(wing)h(section.)62 +1678 y(The)g Fp(FSinfo)i Fo(con\014guration)d(\014le)h(for)f +Fl(dylan.doc.ic.ac.uk)d Fo(is)k(listed)h(b)q(elo)o(w.)120 1748 +y Fl(host)23 b(dylan.doc.ic.ac.uk)120 1848 y(fs)h(/dev/dsk/0s0)e({)120 +1898 y(fstype)h(=)h(swap)120 1948 y(})120 2047 y(fs)g(/dev/dsk/0s0)e({)120 +2097 y(fstype)h(=)h(hfs)120 2147 y(opts)f(=)h(rw,noquota,grpid)120 +2197 y(passno)f(=)h(0;)120 2247 y(freq)f(=)h(1;)120 2296 y(mount)f(/)h({)g(}) +120 2346 y(})120 2446 y(fs)g(/dev/dsk/1s0)e({)120 2496 y(fstype)h(=)h(hfs)120 +2545 y(opts)f(=)h(defaults)120 2595 y(passno)f(=)h(1;)120 2645 +y(freq)f(=)h(1;)p eop +%%Page: 36 38 +36 37 bop 15 -83 a Fo(SMM:13-36)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)120 158 y Fl(mount)23 b(/usr)g({)120 +208 y(local)g({)120 258 y(exportfs)g("dougal)g(eden)g(dylan)g(zebedee)g +(brian")120 308 y(volname)g(/nfs/hp300/local)120 358 y(})120 +407 y(})120 457 y(})120 557 y(fs)h(/dev/dsk/2s0)e({)120 607 +y(fstype)h(=)h(hfs)120 656 y(opts)f(=)h(defaults)120 706 y(passno)f(=)h(1;) +120 756 y(freq)f(=)h(1;)120 806 y(mount)f(default)g({)120 856 +y(exportfs)g("toytown_clients)e(hangers_on")120 906 y(volname)i +(/home/dylan/dk2)120 955 y(})120 1005 y(})120 1105 y(fs)h(/dev/dsk/3s0)e({) +120 1155 y(fstype)h(=)h(hfs)120 1204 y(opts)f(=)h(defaults)120 +1254 y(passno)f(=)h(1;)120 1304 y(freq)f(=)h(1;)120 1354 y(mount)f(default)g +({)120 1404 y(exportfs)g("toytown_clients)e(hangers_on")120 +1453 y(volname)i(/home/dylan/dk3)120 1503 y(})120 1553 y(})120 +1653 y(fs)h(/dev/dsk/5s0)e({)120 1703 y(fstype)h(=)h(hfs)120 +1752 y(opts)f(=)h(defaults)120 1802 y(passno)f(=)h(1;)120 1852 +y(freq)f(=)h(1;)120 1902 y(mount)f(default)g({)120 1952 y(exportfs)g +("toytown_clients)e(hangers_on")120 2001 y(volname)i(/home/dylan/dk5)120 +2051 y(})120 2101 y(})0 2234 y Fi(7.6.1)30 b(fst)n(yp)r(e)15 +b(Option)62 2325 y Fo(This)g(sp)q(eci\014es)h(the)f(t)o(yp)q(e)f(of)g +(\014lesystem)h(b)q(eing)h(declared)f(and)g(will)h(b)q(e)e(placed)i(in)o(to)e +(the)h(`)p Fl(fstab)p Fo(')e(\014le)i(as)f(is.)0 2375 y(The)g(v)m(alue)g(of)f +(this)h(option)f(will)i(b)q(e)f(handed)g(to)f Fl(mount)g Fo(as)f(the)i +(\014lesystem)g(t)o(yp)q(e|it)g(should)g(ha)o(v)o(e)f(suc)o(h)h(v)m(alues)0 +2425 y(as)h Fl(4.2)p Fo(,)f Fl(nfs)h Fo(or)g Fl(swap)p Fo(.)k(The)c(v)m(alue) +i(is)e(not)g(examined)i(for)d(correctness.)62 2496 y(There)21 +b(is)g(one)f(sp)q(ecial)i(case.)35 b(If)21 b(the)f(\014lesystem)h(t)o(yp)q(e) +f(is)h(sp)q(eci\014ed)i(as)d(`)p Fl(export)p Fo(')e(then)j(the)f +(\014lesystem)0 2545 y(information)d(will)h(not)f(b)q(e)g(added)h(to)e(the)h +(host's)f(`)p Fl(fstab)p Fo(')f(information,)i(but)g(it)g(will)h(still)h(b)q +(e)e(visible)i(on)e(the)0 2595 y(net)o(w)o(ork.)h(This)13 b(is)f(useful)h +(for)f(de\014ning)i(hosts)d(whic)o(h)i(con)o(tain)g(referenced)g(v)o(olumes)f +(but)h(whic)o(h)g(are)e(not)h(under)0 2645 y(full)17 b(con)o(trol)d(of)h +Fp(FSinfo)p Fo(.)p eop +%%Page: 37 39 +37 38 bop 0 -83 a Fo(Chapter)15 b(7:)k(FSinfo)1362 b(SMM:13-37)62 +158 y(Example:)120 229 y Fl(fstype)23 b(=)h(swap)0 378 y Fi(7.6.2)30 +b(opts)15 b(Option)62 470 y Fo(This)h(de\014nes)g(an)o(y)f(options)g(that)g +(should)h(b)q(e)g(giv)o(en)g(to)e Fk(moun)o(t)p Fo(\(8\))g(in)i(the)f(`)p +Fl(fstab)p Fo(')f(\014le.)21 b(F)l(or)15 b(example:)120 540 +y Fl(opts)23 b(=)h(rw,nosuid,grpid)0 690 y Fi(7.6.3)30 b(passno)15 +b(Option)62 781 y Fo(This)g(de\014nes)g(the)f Fk(fsc)o(k)p +Fo(\(8\))f(pass)h(n)o(um)o(b)q(er)g(in)h(whic)o(h)g(to)f(c)o(hec)o(k)g(the)g +(\014lesystem.)20 b(This)15 b(v)m(alue)g(will)h(b)q(e)f(placed)0 +831 y(in)o(to)g(the)g(`)p Fl(fstab)p Fo(')f(\014le.)62 902 +y(Example:)120 972 y Fl(passno)23 b(=)h(1)0 1122 y Fi(7.6.4)30 +b(freq)15 b(Option)62 1213 y Fo(This)k(de\014nes)f(the)g(in)o(terv)m(al)h +(\(in)f(da)o(ys\))f(b)q(et)o(w)o(een)h(dumps.)28 b(The)18 b(v)m(alue)h(is)f +(placed)h(as)f(is)g(in)o(to)g(the)f(`)p Fl(fstab)p Fo(')0 1263 +y(\014le.)62 1333 y(Example:)120 1404 y Fl(freq)23 b(=)h(3)0 +1553 y Fi(7.6.5)30 b(moun)n(t)15 b(Option)62 1645 y Fo(This)e(de\014nes)g +(the)f(moun)o(tp)q(oin)o(t)g(at)f(whic)o(h)i(to)f(place)h(the)f +(\014lesystem.)19 b(If)12 b(the)h(moun)o(tp)q(oin)o(t)f(of)f(the)h +(\014lesystem)0 1694 y(is)19 b(sp)q(eci\014ed)h(as)e Fl(default)p +Fo(,)f(then)i(the)f(\014lesystem)h(will)g(b)q(e)g(moun)o(ted)f(in)h(the)f +(automoun)o(ter's)f(tree)h(under)h(its)0 1744 y(v)o(olume)d(name)f(and)g(the) +g(moun)o(t)g(will)i(automatically)f(b)q(e)f(inherited)j(b)o(y)d(the)g +(automoun)o(ter.)62 1815 y(F)l(ollo)o(wing)21 b(the)e(moun)o(tp)q(oin)o(t,)i +(namespace)f(information)f(for)g(the)h(\014lesystem)g(ma)o(y)f(b)q(e)i +(describ)q(ed.)35 b(The)0 1865 y(options)15 b(that)g(can)g(b)q(e)h(giv)o(en)g +(here)f(are)g Fl(exportfs)p Fo(,)f Fl(volname)g Fo(and)h Fl(sel)p +Fo(.)62 1935 y(The)h(format)e(is:)120 2006 y Fl(mount)166 b(:)24 +b("mount")f(vol_tree)g(;)120 2105 y(vol_tree)94 b(:)24 b Fp(list\()t +Fl(vol_tree_attr)p Fp(\))f Fl(;)120 2205 y(vol_tree_attr)406 +2255 y(:)48 b(<)p Fp(string)p Fl(>)24 b("{")f Fp(list\()t Fl(vol_tree_info)p +Fp(\))g Fl(vol_tree)g("}")h(;)120 2355 y(vol_tree_info)406 +2404 y(:)g("exportfs")f(<)p Fp(exp)q(ort-data)p Fl(>)406 2454 +y(|)h("volname")f(<)p Fp(v)o(olname)p Fl(>)406 2504 y(|)h("sel")f(<)p +Fp(selector-list)p Fl(>)406 2554 y(;)62 2645 y Fo(Example:)p +eop +%%Page: 38 40 +38 39 bop 15 -83 a Fo(SMM:13-38)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)120 158 y Fl(mount)23 b(default)g({)215 +208 y(exportfs)g("dylan)g(dougal)g(florence)g(zebedee")215 +258 y(volname)g(/vol/andrew)120 308 y(})62 399 y Fo(In)15 b(the)f(ab)q(o)o(v) +o(e)f(example,)i(the)f(\014lesystem)g(curren)o(tly)h(b)q(eing)g(declared)g +(will)g(ha)o(v)o(e)f(an)f(en)o(try)h(placed)h(in)o(to)f(the)0 +449 y(`)p Fl(exports)p Fo(')d(\014le)j(allo)o(wing)g(the)f(\014lesystem)h(to) +e(b)q(e)i(exp)q(orted)f(to)g(the)g(mac)o(hines)g Fl(dylan)p +Fo(,)g Fl(dougal)p Fo(,)f Fl(florence)g Fo(and)0 499 y Fl(zebedee)p +Fo(.)18 b(The)d(v)o(olume)f(name)g(b)o(y)g(whic)o(h)h(the)f(\014lesystem)g +(will)i(b)q(e)f(referred)f(to)f(remotely)l(,)h(is)h(`)p Fl(/vol/andrew)p +Fo('.)0 549 y(By)h(declaring)i(the)e(moun)o(tp)q(oin)o(t)g(to)f(b)q(e)i +Fl(default)p Fo(,)e(the)h(\014lesystem)h(will)g(b)q(e)g(moun)o(ted)f(on)g +(the)g(lo)q(cal)h(mac)o(hine)0 598 y(in)f(the)f(automoun)o(ter)f(tree,)h +(where)g Fp(Amd)j Fo(will)f(automatically)e(inherit)i(the)e(moun)o(t)g(as)f +(`)p Fl(/vol/andrew)p Fo('.)0 669 y(`)p Fl(exportfs)p Fo(')240 +732 y(a)g(string)h(de\014ning)h(whic)o(h)f(mac)o(hines)g(the)g(\014lesystem)g +(ma)o(y)f(b)q(e)h(exp)q(orted)g(to.)k(This)c(is)g(copied,)g(as)240 +781 y(is,)g(in)o(to)h(the)f(`)p Fl(exports)p Fo(')e(\014le|no)k(sanit)o(y)e +(c)o(hec)o(king)h(is)g(p)q(erformed)f(on)g(this)h(string.)0 +844 y(`)p Fl(volname)p Fo(')46 b(a)19 b(string)h(whic)o(h)g(declares)h(the)f +(remote)f(name)h(b)o(y)f(whic)o(h)i(to)e(reference)h(the)g(\014lesystem.)34 +b(The)240 894 y(string)18 b(is)h(en)o(tered)g(in)o(to)f(a)h(dictionary)g(and) +g(allo)o(ws)f(y)o(ou)g(to)g(refer)g(to)g(this)h(\014lesystem)g(in)g(other)240 +944 y(places)d(b)o(y)f(this)h(v)o(olume)f(name.)0 1006 y(`)p +Fl(sel)p Fo(')142 b(a)15 b(string)g(whic)o(h)h(is)g(placed)g(in)o(to)f(the)h +(automoun)o(ter)e(maps)h(as)f(a)h(selector)h(for)e(the)i(\014lesystem.)0 +1150 y Fi(7.6.6)30 b(dumpset)15 b(Option)62 1242 y Fo(This)d(pro)o(vides)f +(supp)q(ort)g(for)f(Imp)q(erial)j(College's)e(lo)q(cal)h(\014le)g(bac)o(kup)g +(to)q(ols)e(and)h(is)h(not)e(do)q(cumen)o(ted)i(further)0 1292 +y(here.)0 1436 y Fi(7.6.7)30 b(log)14 b(Option)62 1527 y Fo(Sp)q(eci\014es)f +(the)e(log)g(device)i(for)d(the)h(curren)o(t)g(\014lesystem.)19 +b(This)11 b(is)h(ignored)f(if)h(not)e(required)i(b)o(y)f(the)g(particular)0 +1577 y(\014lesystem)16 b(t)o(yp)q(e.)0 1744 y Fq(7.7)33 b Ff(FSinfo)16 +b Fq(static)g(moun)n(ts)62 1836 y Fo(Eac)o(h)j(host)g(ma)o(y)f(also)h(ha)o(v) +o(e)g(a)g(n)o(um)o(b)q(er)g(of)g(statically)h(moun)o(ted)f(\014lesystems.)32 +b(F)l(or)19 b(example,)h(the)f(host)0 1885 y(ma)o(y)14 b(b)q(e)h(a)f +(diskless)i(w)o(orkstation)e(in)h(whic)o(h)g(case)g(it)g(will)h(ha)o(v)o(e)e +(no)h Fl(fs)f Fo(declarations.)20 b(In)15 b(this)g(case)g(the)g +Fl(mount)0 1935 y Fo(declaration)i(is)g(used)f(to)g(determine)h(from)e(where) +i(its)f(\014lesystems)h(will)h(b)q(e)e(moun)o(ted.)23 b(In)17 +b(addition)g(to)f(b)q(eing)0 1985 y(added)e(to)e(the)h(`)p +Fl(fstab)p Fo(')f(\014le,)i(this)g(information)f(can)g(also)g(b)q(e)h(used)g +(to)e(generate)h(a)g(suitable)h(`)p Fl(bootparams)p Fo(')d(\014le.)120 +2056 y Fl(mount)166 b(:)24 b("mount")f(<)p Fp(v)o(olname)p +Fl(>)h Fp(list\()t Fl(localinfo)p Fp(\))g Fl(;)120 2155 y(localinfo)70 +b(:)24 b(localinfo_attr)e(<)p Fp(string)p Fl(>)i(;)120 2255 +y(localinfo_attr)406 2305 y(:)g("as")406 2355 y(|)g("from")406 +2404 y(|)g("fstype")406 2454 y(|)g("opts")406 2504 y(;)62 2595 +y Fo(The)17 b(\014lesystem)g(sp)q(eci\014ed)h(to)e(b)q(e)h(moun)o(ted)f(will) +i(b)q(e)f(searc)o(hed)f(for)g(in)h(the)f(dictionary)i(of)d(v)o(olume)i(names) +0 2645 y(built)g(when)e(scanning)h(the)g(list)g(of)e(hosts')h(de\014nitions.) +p eop +%%Page: 39 41 +39 40 bop 0 -83 a Fo(Chapter)15 b(7:)k(FSinfo)1362 b(SMM:13-39)62 +158 y(The)16 b(attributes)f(ha)o(v)o(e)f(the)i(follo)o(wing)g(seman)o(tics:)0 +229 y(`)p Fl(from)e Fp(mac)o(hine)s Fo(')240 293 y(moun)o(t)h(the)g +(\014lesystem)h(from)e(the)i(mac)o(hine)g(with)f(the)g(hostname)g(of)g +Fp(mac)o(hine)p Fo(.)0 356 y(`)p Fl(as)g Fp(moun)o(tp)q(oin)o(t)q +Fo(')240 420 y(moun)o(t)e(the)h(\014lesystem)g(lo)q(cally)i(as)d(the)h(name)f +(giv)o(en,)h(in)h(case)e(this)h(is)h(di\013eren)o(t)f(from)e(the)i(adv)o(er-) +240 470 y(tised)i(v)o(olume)f(name)h(of)e(the)i(\014lesystem.)0 +534 y(`)p Fl(opts)e Fp(options)r Fo(')240 598 y(nativ)o(e)h +Fk(moun)o(t)p Fo(\(8\))f(options.)0 661 y(`)p Fl(fstype)g Fp(t)o(yp)q(e)s +Fo(')240 725 y(t)o(yp)q(e)h(of)g(\014lesystem)h(to)e(b)q(e)i(moun)o(ted.)62 +816 y(An)g(example:)120 887 y Fl(mount)23 b(/export/exec/hp300/local)e(as)i +(/usr/local)62 978 y Fo(If)15 b(the)g(moun)o(tp)q(oin)o(t)g(sp)q(eci\014ed)i +(is)f(either)g(`)p Fl(/)p Fo(')e(or)g(`)p Fl(swap)p Fo(',)f(the)i(mac)o(hine) +h(will)h(b)q(e)e(considered)i(to)d(b)q(e)h(b)q(o)q(oting)0 +1028 y(o\013)f(the)h(net)f(and)h(this)g(will)i(b)q(e)e(noted)g(for)f(use)h +(in)g(generating)g(a)g(`)p Fl(bootparams)p Fo(')d(\014le)k(for)e(the)h(host)f +(whic)o(h)i(o)o(wns)0 1078 y(the)f(\014lesystems.)0 1254 y +Fq(7.8)33 b(De\014ning)15 b(an)h Ff(Amd)g Fq(Moun)n(t)g(Map)f(in)h +Ff(FSinfo)62 1346 y Fo(The)i(maps)f(used)i(b)o(y)e Fp(Amd)j +Fo(can)d(b)q(e)i(constructed)e(from)g Fp(FSinfo)j Fo(b)o(y)e(de\014ning)h +(all)f(the)g(automoun)o(t)f(trees.)0 1396 y Fp(FSinfo)h Fo(tak)o(es)c(all)i +(the)g(de\014nitions)h(found)e(and)h(builds)h(one)e(map)g(for)g(eac)o(h)g +(top)g(lev)o(el)h(tree.)62 1466 y(The)23 b(automoun)o(t)e(tree)i(is)g +(usually)h(de\014ned)f(last.)42 b(A)23 b(single)g(automoun)o(t)f +(con\014guration)g(will)j(usually)0 1516 y(apply)e(to)f(an)g(en)o(tire)h +(managemen)o(t)e(domain.)41 b(One)23 b Fl(automount)e Fo(declaration)i(is)g +(needed)h(for)d(eac)o(h)i Fp(Amd)0 1566 y Fo(automoun)o(t)11 +b(p)q(oin)o(t.)20 b Fp(FSinfo)15 b Fo(determines)f(whether)f(the)f(automoun)o +(t)g(p)q(oin)o(t)h(is)g Fp(direct)h Fo(\(see)f(Section)g(5.9)f([Direct)0 +1616 y(Automoun)o(t)20 b(Filesystem],)i(page)41 b(SMM:13-25\))18 +b(or)j Fp(indirect)i Fo(\(see)d(Section)i(5.12)d([T)l(op-lev)o(el)j +(Filesystem],)0 1665 y(page)e(SMM:13-26\).)c(Direct)11 b(automoun)o(t)e(p)q +(oin)o(ts)h(are)g(distinguished)j(b)o(y)d(the)g(fact)g(that)f(there)h(is)h +(no)f(underlying)0 1715 y Fp(automoun)o(t)p 220 1715 14 2 v +15 w(tree)p Fo(.)120 1786 y Fl(automount)70 b(:)24 b("automount")e +(opt\(auto_opts)p Fp(\))h Fl(automount_tree)f(;)120 1885 y(auto_opts)70 +b(:)24 b("opts")f(<)p Fp(moun)o(t-options)p Fl(>)h(;)120 1985 +y(automount_tree)406 2035 y(:)g Fp(list\()t Fl(automount_attr)p +Fp(\))406 2085 y Fl(;)120 2184 y(automount_attr)406 2234 y(:)g(<)p +Fp(string)p Fl(>)g("=")f(<)p Fp(v)o(olname)p Fl(>)406 2284 +y(|)h(<)p Fp(string)p Fl(>)g("->")f(<)p Fp(symlink)p Fl(>)406 +2334 y(|)h(<)p Fp(string)p Fl(>)g("{")f(automount_tree)f("}")406 +2384 y(;)62 2475 y Fo(If)15 b Fl(<)p Fp(moun)o(t-options)p +Fl(>)e Fo(is)i(giv)o(en,)f(then)g(it)g(is)h(the)f(string)g(to)f(b)q(e)i +(placed)g(in)g(the)f(maps)g(for)f Fp(Amd)j Fo(for)d(the)i Fl(opts)0 +2525 y Fo(option.)62 2595 y(A)d Fp(map)g Fo(is)g(t)o(ypically)h(a)e(tree)g +(of)g(\014lesystems,)i(for)d(example)j(`)p Fl(home)p Fo(')d(normally)i(con)o +(tains)f(a)g(tree)g(of)g(\014lesystems)0 2645 y(represen)o(ting)16 +b(other)f(mac)o(hines)h(in)g(the)f(net)o(w)o(ork.)p eop +%%Page: 40 42 +40 41 bop 15 -83 a Fo(SMM:13-40)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)62 158 y(A)g(map)g(can)h(either)f(b)q(e)h(giv)o(en)g +(as)f(a)f(name)h(represen)o(ting)h(an)f(already)h(de\014ned)g(v)o(olume)g +(name,)f(or)f(it)i(can)0 208 y(b)q(e)g(a)g(tree.)27 b(A)18 +b(tree)g(is)g(represen)o(ted)g(b)o(y)g(placing)h(braces)f(after)f(the)h +(name.)28 b(F)l(or)17 b(example,)i(to)e(de\014ne)i(a)e(tree)0 +258 y(`)p Fl(/vol)p Fo(',)c(the)j(follo)o(wing)g(map)f(w)o(ould)g(b)q(e)h +(de\014ned:)120 329 y Fl(automount)23 b(/vol)g({)h(})62 420 +y Fo(Within)17 b(a)d(tree,)h(the)g(only)h(items)g(that)e(can)h(app)q(ear)h +(are)f(more)f(maps.)20 b(F)l(or)15 b(example:)120 490 y Fl(automount)23 +b(/vol)g({)215 540 y(andrew)g({)h(})215 590 y(X11)g({)g(})120 +640 y(})62 731 y Fo(In)13 b(this)g(case,)g Fp(FSinfo)i Fo(will)f(lo)q(ok)e +(for)g(v)o(olumes)h(named)f(`)p Fl(/vol/andrew)p Fo(')e(and)j(`)p +Fl(/vol/X11)p Fo(')e(and)h(a)g(map)g(en)o(try)0 781 y(will)17 +b(b)q(e)e(generated)h(for)e(eac)o(h.)20 b(If)15 b(the)g(v)o(olumes)h(are)f +(de\014ned)h(more)f(than)g(once,)g(then)g Fp(FSinfo)j Fo(will)e(generate)f(a) +0 831 y(series)h(of)f(alternate)g(en)o(tries)g(for)g(them)g(in)h(the)f(maps.) +62 901 y(Instead)j(of)g(a)f(tree,)h(either)g(a)f(link)i(\()p +Fp(name)h Fl(->)d Fp(destination)p Fo(\))i(or)e(a)g(reference)h(can)g(b)q(e)g +(sp)q(eci\014ed)i(\()p Fp(name)g Fl(=)0 951 y Fp(destination)p +Fo(\).)i(A)16 b(link)h(creates)f(a)f(sym)o(b)q(olic)i(link)g(to)f(the)f +(string)h(sp)q(eci\014ed,)i(without)e(further)f(pro)q(cessing)i(the)0 +1001 y(en)o(try)l(.)i(A)13 b(reference)h(will)h(examine)f(the)f(destination)h +(\014lesystem)g(and)g(optimise)g(the)f(reference.)20 b(F)l(or)12 +b(example,)0 1051 y(to)j(create)g(an)g(en)o(try)f(for)h Fl(njw)g +Fo(in)h(the)f(`)p Fl(/homes)p Fo(')f(map,)g(either)i(of)f(the)g(t)o(w)o(o)f +(forms)h(can)g(b)q(e)h(used:)120 1121 y Fl(automount)23 b(/homes)g({)215 +1171 y(njw)h(->)f(/home/dylan/njw)120 1221 y(})62 1312 y Fo(or)120 +1383 y Fl(automount)g(/homes)g({)215 1433 y(njw)h(=)g(/home/dylan/njw)120 +1483 y(})62 1574 y Fo(In)13 b(the)e(\014rst)h(example,)g(when)h(`)p +Fl(/homes/njw)p Fo(')c(is)j(referenced)h(from)e Fp(Amd)p Fo(,)h(a)f(link)i +(will)h(b)q(e)e(created)g(leading)h(to)0 1624 y(`)p Fl(/home/dylan/njw)p +Fo(')f(and)j(the)g(automoun)o(ter)e(will)j(b)q(e)g(referenced)g(a)e(second)h +(time)g(to)f(resolv)o(e)h(this)g(\014lename.)0 1673 y(The)g(map)g(en)o(try)g +(w)o(ould)h(b)q(e:)120 1744 y Fl(njw)23 b(type:=link;fs:=/home/dylan/nj)o(w) +62 1835 y Fo(In)17 b(the)g(second)g(example,)g(the)f(destination)i(directory) +e(is)h(analysed)g(and)g(found)g(to)e(b)q(e)j(in)f(the)f(\014lesystem)0 +1885 y(`)p Fl(/home/dylan)p Fo(')c(whic)o(h)j(has)g(previously)g(b)q(een)h +(de\014ned)g(in)f(the)f(maps.)20 b(Hence)15 b(the)f(map)g(en)o(try)g(will)j +(lo)q(ok)d(lik)o(e:)120 1956 y Fl(njw)23 b(rhost:=dylan;rfs:=/home/dylan)o +(;sublink)o(:=njw)62 2047 y Fo(Creating)15 b(only)h(one)f(sym)o(b)q(olic)i +(link,)f(and)f(one)h(access)f(to)g Fp(Amd)p Fo(.)0 2292 y Fq(7.9)33 +b Ff(FSinfo)16 b Fq(Command)f(Line)h(Options)62 2384 y Fp(FSinfo)i +Fo(is)e(started)e(from)h(the)g(command)g(line)i(b)o(y)e(using)h(the)f +(command:)120 2454 y Fl(fsinfo)23 b([)p Fp(options)r Fl(])h(files)f(...)62 +2545 y Fo(The)16 b(input)h(to)d Fp(FSinfo)19 b Fo(is)d(a)f(single)i(set)e(of) +g(de\014nitions)i(of)e(mac)o(hines)i(and)e(automoun)o(t)g(maps.)20 +b(If)c(m)o(ultiple)0 2595 y(\014les)21 b(are)e(giv)o(en)h(on)f(the)h +(command-line,)i(then)e(the)f(\014les)i(are)e(concatenated)h(together)f(to)f +(form)h(the)h(input)0 2645 y(source.)g(The)15 b(\014les)i(are)d(passed)i +(individuall)q(y)i(through)d(the)g(C)g(pre-pro)q(cessor)g(b)q(efore)h(b)q +(eing)g(parsed.)p eop +%%Page: 41 43 +41 42 bop 0 -83 a Fo(Chapter)15 b(7:)k(FSinfo)1362 b(SMM:13-41)62 +158 y(Sev)o(eral)18 b(options)f(de\014ne)i(a)e(pre\014x)h(for)e(the)i(name)f +(of)g(an)g(output)g(\014le.)27 b(If)18 b(the)f(pre\014x)h(is)g(not)f(sp)q +(eci\014ed)i(no)0 208 y(output)14 b(of)f(that)g(t)o(yp)q(e)h(is)g(pro)q +(duced.)20 b(The)14 b(su\016x)g(used)g(will)i(corresp)q(ond)e(either)g(to)f +(the)h(hostname)g(to)f(whic)o(h)h(a)0 258 y(\014le)j(b)q(elongs,)f(or)f(to)g +(the)g(t)o(yp)q(e)h(of)f(output)g(if)h(only)g(one)g(\014le)g(is)g(pro)q +(duced.)22 b(Dumpsets)16 b(and)g(the)f(`)p Fl(bootparams)p +Fo(')0 308 y(\014le)h(are)e(in)h(the)g(latter)f(class.)20 b(T)l(o)14 +b(put)g(the)h(output)f(in)o(to)h(a)f(sub)q(directory)h(simply)h(put)f(a)f(`)p +Fl(/)p Fo(')f(at)h(the)h(end)g(of)f(the)0 358 y(pre\014x,)h(making)h(sure)f +(that)f(the)i(directory)f(has)g(already)h(b)q(een)g(made)f(b)q(efore)h +(running)g(`)p Fl(fsinfo)p Fo('.)0 550 y Fi(7.9.1)30 b Fd(-a)15 +b Fe(auto)q(dir)62 642 y Fo(Sp)q(eci\014es)h(the)e(directory)g(name)g(in)g +(whic)o(h)h(to)e(place)i(the)f(automoun)o(ter's)e(moun)o(tp)q(oin)o(ts.)19 +b(This)14 b(defaults)h(to)0 691 y(`)p Fl(/a)p Fo('.)k(Some)c(sites)h(ha)o(v)o +(e)e(the)i(auto)q(dir)f(set)g(to)g(b)q(e)g(`)p Fl(/amd)p Fo(',)f(and)h(this)h +(w)o(ould)g(b)q(e)f(ac)o(hiev)o(ed)i(b)o(y:)120 762 y Fl(fsinfo)23 +b(-a)h(/amd)f(...)0 955 y Fi(7.9.2)30 b Fd(-b)15 b Fe(b)q(o)q(otparams)62 +1046 y Fo(This)i(sp)q(eci\014es)h(the)f(pre\014x)g(for)f(the)g(`)p +Fl(bootparams)p Fo(')e(\014lename.)25 b(If)16 b(it)h(is)g(not)f(giv)o(en,)h +(then)f(the)h(\014le)g(will)h(not)0 1096 y(b)q(e)h(generated.)27 +b(The)18 b(`)p Fl(bootparams)p Fo(')e(\014le)j(will)h(b)q(e)e(constructed)g +(for)f(the)h(destination)h(mac)o(hine)g(and)f(will)h(b)q(e)0 +1146 y(placed)g(in)o(to)f(a)f(\014le)i(named)f(`)p Fl(bootparams)p +Fo(')e(and)i(pre\014xed)h(b)o(y)f(this)g(string.)28 b(The)18 +b(\014le)h(generated)e(con)o(tains)h(a)0 1195 y(list)e(of)f(en)o(tries)g +(describing)i(eac)o(h)f(diskless)g(clien)o(t)h(that)d(can)i(b)q(o)q(ot)f +(from)f(the)h(destination)h(mac)o(hine.)62 1266 y(As)f(an)g(example,)g(to)f +(create)g(a)h(`)p Fl(bootparams)p Fo(')d(\014le)k(in)g(the)e(directory)h(`)p +Fl(generic)p Fo(',)e(the)i(follo)o(wing)g(w)o(ould)g(b)q(e)0 +1316 y(used:)120 1386 y Fl(fsinfo)23 b(-b)h(generic/)e(...)0 +1579 y Fi(7.9.3)30 b Fd(-d)15 b Fe(dumpsets)62 1670 y Fo(This)k(sp)q +(eci\014es)g(the)f(pre\014x)g(for)f(the)h(`)p Fl(dumpsets)p +Fo(')d(\014le.)29 b(If)18 b(it)g(is)g(not)f(sp)q(eci\014ed,)j(then)e(the)g +(\014le)h(will)g(not)e(b)q(e)0 1720 y(generated.)h(The)12 b(\014le)g(will)g +(b)q(e)g(for)e(the)h(destination)h(mac)o(hine)f(and)h(will)g(b)q(e)g(placed)g +(in)o(to)f(a)f(\014lename)i(`)p Fl(dumpsets)p Fo(',)0 1770 +y(pre\014xed)k(b)o(y)f(this)h(string.)k(The)15 b(`)p Fl(dumpsets)p +Fo(')e(\014le)k(is)e(for)g(use)h(b)o(y)f(Imp)q(erial)i(College's)e(lo)q(cal)i +(bac)o(kup)e(system.)62 1840 y(F)l(or)22 b(example,)i(to)d(create)g(a)h +(dumpsets)g(\014le)h(in)g(the)f(directory)g(`)p Fl(generic)p +Fo(',)g(then)g(y)o(ou)f(w)o(ould)i(use)f(the)0 1890 y(follo)o(wing:)120 +1961 y Fl(fsinfo)h(-d)h(generic/)e(...)0 2153 y Fi(7.9.4)30 +b Fd(-e)15 b Fe(exp)q(ortfs)62 2245 y Fo(De\014nes)d(the)g(pre\014x)g(for)f +(the)g(`)p Fl(exports)p Fo(')f(\014les.)20 b(If)11 b(it)h(is)g(not)f(giv)o +(en,)i(then)e(the)h(\014le)h(will)g(not)e(b)q(e)h(generated.)19 +b(F)l(or)0 2295 y(eac)o(h)14 b(mac)o(hine)h(de\014ned)g(in)f(the)g +(con\014guration)g(\014les)h(as)e(ha)o(ving)h(disks,)h(an)f(`)p +Fl(exports)p Fo(')e(\014le)j(is)f(constructed)g(and)0 2344 +y(giv)o(en)k(a)e(\014lename)j(determined)f(b)o(y)f(the)g(name)g(of)g(the)g +(mac)o(hine,)h(pre\014xed)g(with)g(this)f(string.)26 b(If)17 +b(a)g(mac)o(hine)0 2394 y(is)j(de\014ned)h(as)e(diskless,)j(then)e(no)f(`)p +Fl(exports)p Fo(')f(\014le)j(will)g(b)q(e)f(created)g(for)e(it.)34 +b(The)19 b(\014les)i(con)o(tain)f(en)o(tries)g(for)0 2444 y(directories)c(on) +f(the)h(mac)o(hine)g(that)e(ma)o(y)h(b)q(e)g(exp)q(orted)h(to)f(clien)o(ts.) +62 2515 y(Example:)k(T)l(o)10 b(create)h(the)g(`)p Fl(exports)p +Fo(')e(\014les)j(for)e(eac)o(h)h(diskful)h(mac)o(hine)g(and)f(place)h(them)f +(in)o(to)g(the)g(directory)0 2564 y(`)p Fl(exports)p Fo(':)120 +2635 y Fl(fsinfo)23 b(-e)h(exports/)e(...)p eop +%%Page: 42 44 +42 43 bop 15 -83 a Fo(SMM:13-42)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 158 y Fi(7.9.5)30 b Fd(-f)15 b Fe(fstab)62 +250 y Fo(This)f(de\014nes)g(the)f(pre\014x)h(for)e(the)h(`)p +Fl(fstab)p Fo(')f(\014les.)20 b(The)13 b(\014les)i(will)f(only)g(b)q(e)g +(created)f(if)g(this)h(pre\014x)f(is)h(de\014ned.)0 299 y(F)l(or)21 +b(eac)o(h)h(mac)o(hine)g(de\014ned)h(in)g(the)f(con\014guration)g(\014les,)i +(a)d(`)p Fl(fstab)p Fo(')f(\014le)j(is)f(created)g(with)g(the)g(\014lename)0 +349 y(determined)c(b)o(y)f(pre\014xing)h(this)g(string)f(with)g(the)g(name)h +(of)e(the)h(mac)o(hine.)27 b(These)17 b(\014les)h(con)o(tain)f(en)o(tries)h +(for)0 399 y(\014lesystems)e(and)f(partitions)h(to)e(moun)o(t)h(at)f(b)q(o)q +(ot)h(time.)62 470 y(Example,)h(to)e(create)h(the)g(\014les)i(in)f(the)f +(directory)g(`)p Fl(fstabs)p Fo(':)120 540 y Fl(fsinfo)23 b(-f)h(fstabs/)f +(...)0 686 y Fi(7.9.6)30 b Fd(-h)15 b Fe(hostname)62 778 y +Fo(De\014nes)d(the)g(hostname)f(of)g(the)h(destination)g(mac)o(hine)g(to)f +(pro)q(cess)h(for.)18 b(If)12 b(this)g(is)g(not)f(sp)q(eci\014ed,)j(it)d +(defaults)0 827 y(to)k(the)g(lo)q(cal)h(mac)o(hine)g(name,)f(as)g(returned)g +(b)o(y)h Fk(gethostname)p Fo(\(2\).)62 898 y(Example:)120 969 +y Fl(fsinfo)23 b(-h)h(dylan.doc.ic.ac.uk)d(...)0 1115 y Fi(7.9.7)30 +b Fd(-m)15 b Fe(moun)o(t-maps)62 1206 y Fo(De\014nes)k(the)f(pre\014x)g(for)g +(the)g(automoun)o(ter)f(\014les.)29 b(The)18 b(maps)g(will)i(only)e(b)q(e)h +(pro)q(duced)g(if)g(this)f(pre\014x)g(is)0 1256 y(de\014ned.)j(The)15 +b(moun)o(t)f(maps)g(suitable)i(for)e(the)h(net)o(w)o(ork)e(de\014ned)j(b)o(y) +f(the)g(con\014guration)g(\014les)g(will)h(b)q(e)g(placed)0 +1306 y(in)o(to)f(\014les)h(with)g(names)f(calculated)i(b)o(y)e(pre\014xing)h +(this)g(string)f(to)f(the)i(name)f(of)g(eac)o(h)g(map.)62 1376 +y(F)l(or)g(example,)g(to)g(create)g(the)g(automoun)o(ter)f(maps)h(and)h +(place)g(them)f(in)h(the)f(directory)h(`)p Fl(automaps)p Fo(':)120 +1447 y Fl(fsinfo)23 b(-m)h(automaps/)e(...)0 1593 y Fi(7.9.8)30 +b Fd(-q)62 1684 y Fo(Selects)21 b(quiet)f(mo)q(de.)34 b Fp(FSinfo)23 +b Fo(suppress)d(the)g(\\running)g(commen)o(tary")f(and)h(only)g(outputs)f(an) +o(y)h(error)0 1734 y(messages)15 b(whic)o(h)h(are)f(generated.)0 +1880 y Fi(7.9.9)30 b Fd(-v)62 1971 y Fo(Selects)21 b(v)o(erb)q(ose)e(mo)q +(de.)34 b(When)19 b(this)h(is)g(activ)m(ated,)h(the)f(program)e(will)j +(displa)o(y)g(more)e(messages,)h(and)0 2021 y(displa)o(y)c(all)g(the)e +(information)h(disco)o(v)o(ered)h(when)f(p)q(erforming)g(the)g(seman)o(tic)g +(analysis)g(phase.)20 b(Eac)o(h)15 b(v)o(erb)q(ose)0 2071 y(message)g(is)g +(output)g(to)g(`)p Fl(stdout)p Fo(')f(on)h(a)g(line)h(starting)f(with)h(a)e +(`)p Fl(#)p Fo(')h(c)o(haracter.)0 2217 y Fi(7.9.10)29 b Fd(-D)16 +b Fe(name[=defn])62 2308 y Fo(De\014nes)f(a)g(sym)o(b)q(ol)f +Fp(name)j Fo(for)d(the)h(prepro)q(cessor)g(when)g(reading)g(the)f +(con\014guration)h(\014les.)21 b(Equiv)m(alen)o(t)16 b(to)0 +2358 y Fl(#define)e Fo(directiv)o(e.)0 2504 y Fi(7.9.11)29 +b Fd(-I)16 b Fe(directory)62 2595 y Fo(This)g(option)g(is)g(passed)g(in)o(to) +f(the)h(prepro)q(cessor)f(for)g(the)h(con\014guration)f(\014les.)22 +b(It)15 b(sp)q(eci\014es)j(directories)e(in)0 2645 y(whic)o(h)g(to)f(\014nd)h +(include)h(\014les)p eop +%%Page: 43 45 +43 44 bop 0 -83 a Fo(Chapter)15 b(7:)k(FSinfo)1362 b(SMM:13-43)0 +158 y Fi(7.9.12)29 b Fd(-U)16 b Fe(name)62 250 y Fo(Remo)o(v)o(es)f(an)o(y)g +(initial)i(de\014nition)g(of)e(the)h(sym)o(b)q(ol)f Fp(name)p +Fo(.)20 b(In)o(v)o(erse)15 b(of)g(the)g Fl(-D)g Fo(option.)0 +423 y Fq(7.10)32 b(Errors)16 b(pro)r(duced)g(b)n(y)g Ff(FSinfo)62 +514 y Fo(The)g(follo)o(wing)g(table)f(do)q(cumen)o(ts)h(the)f(errors)f(and)i +(w)o(arnings)f(whic)o(h)h Fp(FSinfo)i Fo(ma)o(y)c(pro)q(duce.)0 +585 y Fl(can't)23 b(open)g Fp(\014lename)28 b Fl(for)c(writing)240 +648 y Fo(Occurs)16 b(if)g(an)o(y)e(errors)h(are)g(encoun)o(tered)h(when)f(op) +q(ening)i(an)e(output)g(\014le.)0 712 y Fl(unknown)23 b(host)g(attribute)240 +775 y Fo(Occurs)16 b(if)g(an)f(unrecognised)h(k)o(eyw)o(ord)f(is)g(used)h +(when)g(de\014ning)h(a)d(host.)0 839 y Fl(unknown)23 b(filesystem)f +(attribute)240 902 y Fo(Occurs)16 b(if)g(an)f(unrecognised)h(k)o(eyw)o(ord)f +(is)g(used)h(when)g(de\014ning)h(a)d(host's)h(\014lesystems.)0 +965 y Fl(not)23 b(allowed)g('/')h(in)f(a)h(directory)f(name)240 +1029 y Fo(When)14 b(reading)g(the)g(con\014guration)g(input,)h(if)f(there)g +(is)g(a)f(\014lesystem)i(de\014nition)g(whic)o(h)g(con)o(tains)240 +1079 y(a)f(pathname)g(with)g(m)o(ultiple)i(directories)f(for)e(an)o(y)h(part) +f(of)g(the)i(moun)o(tp)q(oin)o(t)f(elemen)o(t,)g(and)g(it)g(is)240 +1128 y(not)h(a)g(single)h(absolute)g(path,)e(then)i(this)g(message)e(will)j +(b)q(e)f(pro)q(duced)g(b)o(y)g(the)f(parser.)0 1192 y Fl(unknown)23 +b(directory)g(attribute)240 1255 y Fo(If)d(an)g(unkno)o(wn)h(k)o(eyw)o(ord)e +(is)h(found)h(while)g(reading)g(the)f(de\014nition)i(of)e(a)f(hosts's)g +(\014lesystem)240 1305 y(moun)o(t)c(option.)0 1368 y Fl(unknown)23 +b(mount)g(attribute)240 1432 y Fo(Occurs)16 b(if)g(an)f(unrecognised)h(k)o +(eyw)o(ord)f(is)g(found)h(while)h(parsing)e(the)g(list)h(of)f(static)g(moun)o +(ts.)0 1495 y Fl(")24 b(expected)240 1558 y Fo(Occurs)16 b(if)g(an)f(unescap) +q(ed)h(newline)i(is)d(found)h(in)g(a)f(quoted)g(string.)0 1622 +y Fl(unknown)23 b(\\)h(sequence)240 1685 y Fo(Occurs)12 b(if)h(an)e(unkno)o +(wn)h(escap)q(e)h(sequence)g(is)f(found)g(inside)i(a)d(string.)19 +b(Within)13 b(a)e(string,)h(y)o(ou)g(can)240 1735 y(giv)o(e)j(the)g(standard) +g(C)g(escap)q(e)h(sequences)g(for)e(strings,)h(suc)o(h)h(as)e(newlines)j(and) +e(tab)g(c)o(haracters.)0 1798 y Fp(\014lename)s Fl(:)24 b(cannot)f(open)h +(for)f(reading)240 1862 y Fo(If)18 b(a)f(\014le)h(sp)q(eci\014ed)i(on)d(the)h +(command)f(line)i(as)e(con)o(taining)h(con\014guration)g(data)f(could)h(not)f +(b)q(e)240 1912 y(op)q(ened.)0 1975 y Fl(end)23 b(of)h(file)f(within)g +(comment)240 2038 y Fo(A)15 b(commen)o(t)g(w)o(as)f(un)o(terminated)i(b)q +(efore)g(the)f(end)h(of)e(one)i(of)f(the)g(con\014guration)g(\014les.)0 +2102 y Fl(host)23 b(field)g(")p Fp(\014eld-name)s Fl(")i(already)e(set)240 +2165 y Fo(If)15 b(duplicate)i(de\014nitions)g(are)e(giv)o(en)h(for)f(an)o(y)f +(of)h(the)g(\014elds)i(with)e(a)g(host)g(de\014nition.)0 2229 +y Fl(duplicate)23 b(host)g Fp(hostname)s Fl(!)240 2292 y Fo(If)15 +b(a)g(host)g(has)g(more)g(than)g(one)g(de\014nition.)0 2355 +y Fl(netif)23 b(field)g Fp(\014eld-name)28 b Fl(already)23 +b(set)240 2419 y Fo(Occurs)16 b(if)g(y)o(ou)e(attempt)h(to)f(de\014ne)j(an)e +(attribute)g(of)f(an)i(in)o(terface)f(more)g(than)g(once.)0 +2482 y Fl(malformed)23 b(IP)g(dotted)g(quad:)g Fp(address)240 +2545 y Fo(If)e(the)g(In)o(ternet)h(address)f(of)f(an)h(in)o(terface)g(is)h +(incorrectly)g(sp)q(eci\014ed.)39 b(An)22 b(In)o(ternet)f(address)240 +2595 y(de\014nition)e(is)e(handled)i(to)d Fk(inet)p 801 2595 +14 3 v 17 w(addr)p Fo(\(3N\))h(to)f(see)i(if)f(it)g(can)g(cop)q(e.)26 +b(If)17 b(not,)g(then)g(this)g(message)240 2645 y(will)g(b)q(e)f(displa)o(y)o +(ed.)p eop +%%Page: 44 46 +44 45 bop 15 -83 a Fo(SMM:13-44)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 158 y Fl(malformed)23 b(netmask:)f +Fp(netmask)240 223 y Fo(If)16 b(the)g(netmask)f(cannot)g(b)q(e)i(deco)q(ded)g +(as)e(though)h(it)g(w)o(ere)f(a)g(hexadecimal)j(n)o(um)o(b)q(er,)d(then)i +(this)240 273 y(message)i(will)h(b)q(e)g(displa)o(y)o(ed.)32 +b(It)19 b(will)i(t)o(ypically)f(b)q(e)g(caused)g(b)o(y)e(incorrect)i(c)o +(haracters)e(in)i(the)240 322 y Fp(netmask)e Fo(v)m(alue.)0 +387 y Fl(fs)24 b(field)f(")p Fp(\014eld-name)s Fl(")h(already)f(set)240 +451 y Fo(Occurs)16 b(when)g(m)o(ultiple)h(de\014nitions)g(are)e(giv)o(en)h +(for)f(one)g(of)g(the)g(attributes)h(of)e(a)h(host's)g(\014lesys-)240 +501 y(tem.)0 565 y Fl(mount)23 b(tree)g(field)h(")p Fp(\014eld-name)s +Fl(")g(already)f(set)240 630 y Fo(Occurs)13 b(when)h(the)f +Fp(\014eld-name)j Fo(is)e(de\014ned)g(more)e(than)h(once)g(during)h(the)f +(de\014nition)h(of)e(a)h(\014lesys-)240 680 y(tems)i(moun)o(tp)q(oin)o(t.)0 +744 y Fl(mount)23 b(field)g(")p Fp(\014eld-name)s Fl(")i(already)e(set)240 +809 y Fo(Occurs)16 b(when)g(a)e(static)h(moun)o(t)g(has)g(m)o(ultiple)i +(de\014nitions)g(of)e(the)g(same)g(\014eld.)0 873 y Fl(no)24 +b(disk)f(mounts)g(on)h Fp(hostname)240 937 y Fo(If)11 b(there)g(are)g(no)g +(static)g(moun)o(ts,)g(nor)f(lo)q(cal)i(disk)g(moun)o(ts)f(sp)q(eci\014ed)i +(for)d(a)h(mac)o(hine,)h(this)f(message)240 987 y(will)17 b(b)q(e)f(displa)o +(y)o(ed.)0 1052 y Fp(host)q Fl(:)p Fp(device)27 b Fl(needs)d(field)f(")p +Fp(\014eld-name)s Fl(")240 1116 y Fo(Occurs)13 b(when)f(a)g(\014lesystem)g +(is)h(missing)f(a)g(required)h(\014eld.)20 b Fp(\014eld-name)c +Fo(could)d(b)q(e)g(one)f(of)f Fl(fstype)p Fo(,)240 1166 y Fl(opts)p +Fo(,)j Fl(passno)h Fo(or)f Fl(mount)p Fo(.)0 1230 y Fp(\014lesystem)25 +b Fl(has)e(a)h(volname)f(but)g(no)h(exportfs)e(data)240 1295 +y Fo(Occurs)13 b(when)f(a)g(v)o(olume)h(name)f(is)g(declared)i(for)d(a)h +(\014le)h(system,)f(but)g(the)g(string)g(sp)q(ecifying)j(what)240 +1345 y(mac)o(hines)h(the)f(\014lesystem)h(can)f(b)q(e)h(exp)q(orted)g(to)e +(is)i(missing.)0 1409 y Fl(sub-directory)22 b Fp(directory)28 +b Fl(of)c Fp(directory-tree)i Fl(starts)d(with)h('/')240 1473 +y Fo(Within)13 b(the)f(\014lesystem)h(sp)q(eci\014cation)h(for)d(a)h(host,)f +(if)i(an)f(elemen)o(t)g Fp(directory)k Fo(of)c(the)g(moun)o(tp)q(oin)o(t)240 +1523 y(b)q(egins)k(with)g(a)f(`)p Fl(/)p Fo(')f(and)h(it)h(is)g(not)e(the)i +(start)e(of)g(the)i(tree.)0 1588 y Fp(host)q Fl(:)p Fp(device)27 +b Fl(has)d(no)f(mount)h(point)240 1652 y Fo(Occurs)16 b(if)g(the)f(`)p +Fl(mount)p Fo(')f(option)h(is)h(not)e(sp)q(eci\014ed)k(for)c(a)h(host's)g +(\014lesystem.)0 1717 y Fp(host)q Fl(:)p Fp(device)27 b Fl(has)d(more)f(than) +g(one)h(mount)f(point)240 1781 y Fo(Occurs)17 b(if)g(the)g(moun)o(t)f(option) +h(for)f(a)g(host's)g(\014lesystem)h(sp)q(eci\014es)h(m)o(ultiple)h(trees)d +(at)g(whic)o(h)i(to)240 1831 y(place)e(the)f(moun)o(tp)q(oin)o(t.)0 +1895 y Fl(no)24 b(volname)e(given)i(for)f Fp(host)q Fl(:)p +Fp(device)240 1960 y Fo(Occurs)15 b(when)h(a)e(\014lesystem)h(is)g(de\014ned) +h(to)e(b)q(e)i(moun)o(ted)e(on)h(`)p Fl(default)p Fo(',)e(but)h(no)h(v)o +(olume)g(name)240 2009 y(is)h(giv)o(en)f(for)g(the)g(\014le)h(system,)f(then) +g(the)h(moun)o(tp)q(oin)o(t)f(cannot)g(b)q(e)h(determined.)0 +2074 y Fp(host)q Fl(:mount)23 b(field)g(specified)f(for)i(swap)f(partition) +240 2138 y Fo(Occurs)16 b(if)g(a)e(moun)o(tp)q(oin)o(t)i(is)f(giv)o(en)h(for) +f(a)f(\014lesystem)i(whose)f(t)o(yp)q(e)h(is)f(declared)i(to)d(b)q(e)i +Fl(swap)p Fo(.)0 2203 y Fl(ambiguous)23 b(mount:)g Fp(v)o(olume)k +Fl(is)c(a)h(replicated)e(filesystem)240 2267 y Fo(If)17 b(sev)o(eral)f +(\014lesystems)h(are)f(declared)h(as)f(ha)o(ving)g(the)h(same)f(v)o(olume)g +(name,)h(they)f(will)i(b)q(e)f(con-)240 2317 y(sidered)j(replicated)h +(\014lesystems.)33 b(T)l(o)19 b(moun)o(t)g(a)g(replicated)h(\014lesystem)g +(statically)l(,)h(a)e(sp)q(eci\014c)240 2367 y(host)e(will)h(need)g(to)e(b)q +(e)i(named,)f(to)g(sa)o(y)f(whic)o(h)i(particular)f(cop)o(y)g(to)g(try)f(and) +h(moun)o(t,)g(else)h(this)240 2417 y(error)c(will)j(result.)0 +2481 y Fl(cannot)23 b(determine)g(localname)f(since)h(volname)g +Fp(v)o(olume)k Fl(is)d(not)f(uniquely)g(defined)240 2545 y +Fo(If)c(a)g(v)o(olume)h(is)g(replicated)g(and)g(an)f(attempt)f(is)i(made)f +(to)f(moun)o(t)h(the)g(\014lesystem)h(statically)240 2595 y(without)d(sp)q +(ecifying)j(a)d(lo)q(cal)h(moun)o(tp)q(oin)o(t,)g Fp(FSinfo)i +Fo(cannot)d(calculate)h(a)f(moun)o(tp)q(oin)o(t,)h(as)f(the)240 +2645 y(desired)f(pathname)g(w)o(ould)f(b)q(e)h(am)o(biguous.)p +eop +%%Page: 45 47 +45 46 bop 0 -83 a Fo(Chapter)15 b(8:)k(Examples)1300 b(SMM:13-45)0 +158 y Fl(volname)23 b Fp(v)o(olume)k Fl(is)c(unknown)240 223 +y Fo(Occurs)14 b(if)g(an)f(attempt)f(is)i(made)f(to)f(moun)o(t)h(or)g +(reference)g(a)g(v)o(olume)h(name)f(whic)o(h)h(has)f(not)g(b)q(een)240 +273 y(declared)j(during)g(the)g(host)f(\014lesystem)g(de\014nitions.)0 +338 y Fl(volname)23 b Fp(v)o(olume)k Fl(not)c(exported)g(from)g +Fp(mac)o(hine)240 402 y Fo(Occurs)d(if)h(y)o(ou)e(attempt)g(to)g(moun)o(t)g +(the)h(v)o(olume)g Fp(v)o(olume)j Fo(from)c(a)g(mac)o(hine)i(whic)o(h)g(has)e +(not)240 452 y(declared)d(itself)h(to)d(ha)o(v)o(e)h(suc)o(h)g(a)g +(\014lesystem)h(a)o(v)m(ailable.)0 517 y Fl(network)23 b(booting)g(requires)g +(both)g(root)g(and)h(swap)f(areas)240 581 y Fo(Occurs)18 b(if)g(a)f(mac)o +(hine)h(has)f(moun)o(t)g(declarations)h(for)e(either)i(the)f(ro)q(ot)g +(partition)g(or)g(the)h(sw)o(ap)240 631 y(area,)12 b(but)f(not)h(b)q(oth.)19 +b(Y)l(ou)12 b(cannot)f(de\014ne)i(a)f(mac)o(hine)g(to)g(only)g(partially)h(b) +q(o)q(ot)e(via)i(the)e(net)o(w)o(ork.)0 696 y Fl(unknown)23 +b(volname)g Fp(v)o(olume)k Fl(automounted)22 b Fp([)29 b Fl(on)24 +b()f Fp(])240 761 y Fo(Occurs)c(if)f Fp(v)o(olume)j Fo(is)e(used)g(in)g +(a)e(de\014nition)j(of)e(an)g(automoun)o(t)f(map)h(but)g(the)g(v)o(olume)h +(name)240 810 y(has)c(not)g(b)q(een)h(declared)h(during)f(the)f(host)g +(\014lesystem)h(de\014nitions.)0 875 y Fl(not)23 b(allowed)g('/')h(in)f(a)h +(directory)f(name)240 940 y Fo(Occurs)15 b(when)g(a)f(pathname)g(with)h(m)o +(ultiple)h(directory)f(elemen)o(ts)g(is)g(sp)q(eci\014ed)i(as)d(the)g(name)h +(for)240 990 y(an)g(automoun)o(ter)f(tree.)20 b(A)15 b(tree)g(should)h(only)g +(ha)o(v)o(e)f(one)g(name)g(at)g(eac)o(h)g(lev)o(el.)0 1054 +y Fp(device)28 b Fl(has)23 b(duplicate)g(exportfs)g(data)240 +1119 y Fo(Pro)q(duced)16 b(if)h(the)e(`)p Fl(exportfs)p Fo(')f(option)i(is)g +(used)g(m)o(ultiple)i(times)d(within)i(the)f(same)f(branc)o(h)h(of)f(a)240 +1169 y(\014lesytem)e(de\014nition.)21 b(F)l(or)12 b(example,)h(if)g(y)o(ou)f +(attempt)f(to)h(set)g(the)h(`)p Fl(exportfs)p Fo(')d(data)i(at)g(di\013eren)o +(t)240 1219 y(lev)o(els)k(of)f(the)h(moun)o(tp)q(oin)o(t)f(directory)g(tree.) +0 1283 y Fl(sub-directory)22 b(of)i Fp(directory-tree)i Fl(is)e(named)f +("default")240 1348 y Fo(`)p Fl(default)p Fo(')17 b(is)h(a)g(k)o(eyw)o(ord)g +(used)h(to)f(sp)q(ecify)h(if)g(a)f(moun)o(tp)q(oin)o(t)g(should)i(b)q(e)f +(automatically)f(cal-)240 1398 y(culated)g(b)o(y)f Fp(FSinfo)p +Fo(.)25 b(If)17 b(y)o(ou)g(attempt)f(to)g(sp)q(ecify)i(a)f(directory)g(name)g +(as)f(this,)i(it)f(will)i(use)e(the)240 1448 y(\014lename)f(of)f(`)p +Fl(default)p Fo(')f(but)h(will)i(pro)q(duce)f(this)f(w)o(arning.)0 +1512 y Fl(pass)23 b(number)g(for)h Fp(host)q Fl(:)p Fp(device)j +Fl(is)d(non-zero)240 1577 y Fo(Occurs)14 b(if)h Fp(device)i +Fo(has)d(its)g(`)p Fl(fstype)p Fo(')e(declared)j(to)e(b)q(e)h(`)p +Fl(swap)p Fo(')f(or)g(`)p Fl(export)p Fo(')f(and)i(the)g Fk(fsc)o(k)p +Fo(\(8\))e(pass)240 1627 y(n)o(um)o(b)q(er)i(is)h(set.)k(Sw)o(ap)14 +b(devices)h(should)g(not)e(b)q(e)i(fsc)o(k'd.)k(See)14 b(Section)h(7.6.1)d +([FSinfo)i(\014lesystems)240 1677 y(fst)o(yp)q(e],)g(page)31 +b(SMM:13-36)0 1741 y Fl(dump)23 b(frequency)g(for)g Fp(host)q +Fl(:)p Fp(device)28 b Fl(is)23 b(non-zero)240 1806 y Fo(Occurs)12 +b(if)h Fp(device)i Fo(has)d(its)g(`)p Fl(fstype)p Fo(')e(declared)j(to)e(b)q +(e)h(`)p Fl(swap)p Fo(')e(or)i(`)p Fl(export)p Fo(')e(and)i(the)f(`)p +Fl(dump)p Fo(')g(option)240 1856 y(is)16 b(set)f(to)f(a)h(v)m(alue)i(greater) +d(than)h(zero.)20 b(Sw)o(ap)15 b(devices)h(should)g(not)f(b)q(e)h(dump)q(ed.) +0 2065 y Fm(8)41 b(Examples)0 2313 y Fq(8.1)33 b(User)14 b(Filesystems)62 +2404 y Fo(With)g(more)g(than)g(one)g(\014leserv)o(er,)g(the)g(directories)h +(most)e(frequen)o(tly)i(cross-moun)o(ted)e(are)h(those)g(con)o(tain-)0 +2454 y(ing)19 b(user)g(home)f(directories.)31 b(A)19 b(common)f(con)o(v)o(en) +o(tion)h(used)g(at)f(Imp)q(erial)i(College)f(is)g(to)f(moun)o(t)g(the)h(user) +0 2504 y(disks)d(under)g Fl(/home/)p Fp(mac)o(hine)p Fo(.)62 +2575 y(T)o(ypically)l(,)h(the)e(`)p Fl(/etc/fstab)p Fo(')e(\014le)j(con)o +(tained)g(a)f(long)h(list)g(of)e(en)o(tries)i(suc)o(h)f(as:)120 +2645 y Fp(mac)o(hine)s Fl(:/home/)p Fp(mac)o(hine)27 b Fl(/home/)p +Fp(mac)o(hine)f Fl(nfs)e(...)p eop +%%Page: 46 48 +46 47 bop 15 -83 a Fo(SMM:13-46)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)62 158 y(for)e(eac)o(h)g(\014leserv)o(er)h(on)f(the)g +(net)o(w)o(ork.)62 229 y(There)20 b(are)e(n)o(umerous)h(problems)h(with)f +(this)h(system.)31 b(The)19 b(moun)o(t)f(list)i(can)f(b)q(ecome)h(quite)g +(large)f(and)0 279 y(some)d(of)h(the)f(mac)o(hines)i(ma)o(y)e(b)q(e)h(do)o +(wn)g(when)g(a)f(system)h(is)g(b)q(o)q(oted.)24 b(When)18 b(a)e(new)h +(\014leserv)o(er)g(is)g(installed,)0 329 y(`)p Fl(/etc/fstab)p +Fo(')d(m)o(ust)h(b)q(e)i(up)q(dated)g(on)f(ev)o(ery)g(mac)o(hine,)g(the)g +(moun)o(t)g(directory)g(created)g(and)g(the)g(\014lesystem)0 +378 y(moun)o(ted.)62 449 y(In)f(man)o(y)f(en)o(vironmen)o(ts)h(most)e(p)q +(eople)j(use)f(the)f(same)g(few)g(w)o(orkstations,)f(but)i(it)f(is)h(con)o(v) +o(enien)o(t)g(to)f(go)g(to)0 499 y(a)i(colleague's)g(mac)o(hine)h(and)f +(access)g(y)o(our)f(o)o(wn)h(\014les.)23 b(When)16 b(a)f(serv)o(er)h(go)q(es) +f(do)o(wn,)h(it)g(can)g(cause)g(a)g(pro)q(cess)0 549 y(on)e(a)g(clien)o(t)h +(mac)o(hine)g(to)e(hang.)20 b(By)14 b(minimising)i(the)e(moun)o(ted)g +(\014lesystems)h(to)e(only)i(include)h(those)e(activ)o(ely)0 +598 y(b)q(eing)i(used,)g(there)f(is)h(less)g(c)o(hance)f(that)g(a)g +(\014lesystem)h(will)h(b)q(e)e(moun)o(ted)h(when)f(a)g(serv)o(er)g(go)q(es)g +(do)o(wn.)62 669 y(The)f(follo)o(wing)g(is)g(a)f(short)g(extract)f(from)h(a)g +(map)g(tak)o(en)g(from)g(a)g(researc)o(h)g(\014leserv)o(er)i(at)d(Imp)q +(erial)j(College.)62 739 y(Note)g(the)h(en)o(try)f(for)f(`)p +Fl(localhost)p Fo(')g(whic)o(h)i(is)f(used)h(for)f(users)g(suc)o(h)h(as)f +(the)g(op)q(erator)g(\(`)p Fl(opr)p Fo('\))e(who)i(ha)o(v)o(e)g(a)0 +789 y(home)g(directory)h(on)f(most)f(mac)o(hine)i(as)f(`)p +Fl(/home/localhost/opr)p Fo('.)120 860 y Fl(/defaults)166 b +(opts:=rw,intr,grpid,nosui)o(d)120 910 y(charm)262 b +(host!=${key};type:=nfs;rh)o(ost:=${)o(key};rf)o(s:=/home)o(/${key})20 +b(\\)502 959 y(host==${key};type:=ufs;de)o(v:=/dev)o(/xd0g)120 +1009 y(#)120 1059 y(...)120 1159 y(#)120 1209 y(localhost)166 +b(type:=link;fs:=${host})120 1258 y(...)120 1308 y(#)120 1358 +y(#)24 b(dylan)f(has)g(two)h(user)f(disks)g(so)h(have)f(a)120 +1408 y(#)h(top)f(directory)g(in)g(which)h(to)f(mount)g(them.)120 +1458 y(#)120 1507 y(dylan)262 b(type:=auto;fs:=${map};pre)o(f:=${ke)o(y}/)120 +1557 y(#)120 1607 y(dylan/dk2)166 b(host!=dylan;type:=nfs;rho)o(st:=dyl)o +(an;rfs:)o(=/home/$)o({key})21 b(\\)502 1657 y(host==dylan;type:=ufs;dev)o +(:=/dev/)o(dsk/2s0)120 1707 y(#)120 1757 y(dylan/dk5)166 b +(host!=dylan;type:=nfs;rho)o(st:=dyl)o(an;rfs:)o(=/home/$)o({key})21 +b(\\)502 1806 y(host==dylan;type:=ufs;dev)o(:=/dev/)o(dsk/5s0)120 +1856 y(...)120 1906 y(#)120 1956 y(toytown)214 b(host!=${key};type:=nfs;rh)o +(ost:=${)o(key};rf)o(s:=/home)o(/${key})20 b(\\)502 2006 y +(host==${key};type:=ufs;de)o(v:=/dev)o(/xy1g)120 2055 y(...)120 +2105 y(#)120 2155 y(zebedee)214 b(host!=${key};type:=nfs;rh)o(ost:=${)o +(key};rf)o(s:=/home)o(/${key})20 b(\\)502 2205 y(host==${key};type:=ufs;de)o +(v:=/dev)o(/dsk/1s)o(0)120 2255 y(#)120 2304 y(#)k(Just)f(for)g(access...)120 +2354 y(#)120 2404 y(gould)262 b(type:=auto;fs:=${map};pre)o(f:=${ke)o(y}/)120 +2454 y(gould/staff)118 b(host!=gould;type:=nfs;rho)o(st:=gou)o(ld;rfs:)o +(=/home/$)o({key})120 2504 y(#)120 2554 y(gummo)262 b +(host!=${key};type:=nfs;rh)o(ost:=${)o(key};rf)o(s:=/home)o(/${key})120 +2603 y(...)p eop +%%Page: 47 49 +47 48 bop 0 -83 a Fo(Chapter)15 b(8:)k(Examples)1300 b(SMM:13-47)62 +158 y(This)17 b(map)e(is)h(shared)g(b)o(y)g(most)e(of)i(the)f(mac)o(hines)i +(listed)g(so)e(on)g(those)h(systems)f(an)o(y)g(of)h(the)f(user)h(disks)g(is)0 +208 y(accessible)h(via)f(a)e(consisten)o(t)i(name.)k Fp(Amd)d +Fo(is)f(started)e(with)i(the)f(follo)o(wing)h(command)120 279 +y Fl(amd)23 b(/home)h(amd.home)62 370 y Fo(Note)16 b(that)g(when)g(moun)o +(ting)h(a)e(remote)h(\014lesystem,)h(the)f Fp(automoun)o(ted)h +Fo(moun)o(t)f(p)q(oin)o(t)h(is)f(referenced,)h(so)0 420 y(that)c(the)h +(\014lesystem)h(will)g(b)q(e)g(moun)o(ted)f(if)g(it)g(is)g(not)g(y)o(et)f +(\(at)g(the)h(time)g(the)g(remote)g(`)p Fl(mountd)p Fo(')e(obtains)i(the)g +(\014le)0 470 y(handle\).)0 628 y Fq(8.2)33 b(Home)14 b(Directories)62 +719 y Fo(One)e(con)o(v)o(en)o(tion)e(for)g(home)h(directories)h(is)f(to)f(lo) +q(cate)h(them)f(in)i(`)p Fl(/homes)p Fo(')d(so)h(user)h(`)p +Fl(jsp)p Fo(''s)e(home)i(directory)f(is)0 769 y(`)p Fl(/homes/jsp)p +Fo('.)17 b(With)e(more)f(than)h(a)f(single)i(\014leserv)o(er)f(it)f(is)h(con) +o(v)o(enien)o(t)h(to)d(spread)i(user)g(\014les)g(across)f(sev)o(eral)0 +819 y(mac)o(hines.)34 b(All)21 b(that)f(is)g(required)h(is)f(a)f(moun)o +(t-map)h(whic)o(h)g(con)o(v)o(erts)f(login)i(names)f(to)f(an)h(automoun)o +(ted)0 868 y(directory)l(.)62 939 y(Suc)o(h)c(a)f(map)g(migh)o(t)g(b)q(e)h +(started)e(b)o(y)h(the)h(command:)120 1010 y Fl(amd)23 b(/homes)g(amd.homes) +62 1101 y Fo(where)16 b(the)f(map)g(`)p Fl(amd.homes)p Fo(')e(con)o(tained)j +(the)f(en)o(tries:)120 1171 y Fl(/defaults)70 b(type:=link)h(#)23 +b(All)h(the)f(entries)g(are)h(of)f(type:=link)120 1221 y(jsp)214 +b(fs:=/home/charm/jsp)120 1271 y(njw)g(fs:=/home/dylan/dk5/njw)120 +1321 y(...)120 1371 y(phjk)190 b(fs:=/home/toytown/ai/phjk)120 +1421 y(sjv)214 b(fs:=/home/ganymede/sjv)62 1512 y Fo(Whenev)o(er)21 +b(a)e(login)i(name)f(is)g(accessed)h(in)g(`)p Fl(/homes)p Fo(')d(a)i(sym)o(b) +q(olic)h(link)g(app)q(ears)f(p)q(oin)o(ting)h(to)f(the)g(real)0 +1562 y(lo)q(cation)12 b(of)f(that)f(user's)h(home)h(directory)l(.)19 +b(In)12 b(this)f(example,)i(`)p Fl(/homes/jsp)p Fo(')c(w)o(ould)j(app)q(ear)f +(to)g(b)q(e)h(a)f(sym)o(b)q(olic)0 1611 y(link)17 b(p)q(oin)o(ting)f(to)e(`)p +Fl(/home/charm/jsp)p Fo('.)k(Of)d(course,)g(`)p Fl(/home)p +Fo(')f(w)o(ould)h(also)g(b)q(e)h(an)f(automoun)o(t)f(p)q(oin)o(t.)62 +1682 y(This)j(system)f(causes)h(an)f(extra)g(lev)o(el)h(of)f(sym)o(b)q(olic)i +(links)f(to)f(b)q(e)h(used.)24 b(Although)17 b(that)e(turns)i(out)f(to)f(b)q +(e)0 1732 y(relativ)o(ely)i(inexp)q(ensiv)o(e,)i(an)d(alternativ)o(e)g(is)h +(to)f(directly)h(moun)o(t)f(the)g(required)h(\014lesystems)g(in)g(the)g(`)p +Fl(/homes)p Fo(')0 1782 y(map.)i(The)14 b(required)g(map)f(is)h(simple,)h +(but)e(long,)h(and)f(its)h(creation)f(is)h(b)q(est)g(automated.)k(The)c(en)o +(try)e(for)h(`)p Fl(jsp)p Fo(')0 1831 y(could)j(b)q(e:)120 +1902 y Fl(jsp)71 b(-sublink:=${key};rfs:=/home)o(/charm)21 +b(\\)478 1952 y(host==charm;type:=ufs;dev:)o(=/dev/x)o(d0g)g(\\)478 +2002 y(host!=charm;type:=nfs;rhos)o(t:=char)o(m)62 2093 y Fo(This)14 +b(map)g(can)f(b)q(ecome)h(quite)h(big)f(if)f(it)h(con)o(tains)g(a)f(large)g +(n)o(um)o(b)q(er)h(of)f(en)o(tries.)20 b(By)14 b(com)o(bining)g(t)o(w)o(o)e +(other)0 2143 y(features)j(of)g Fp(Amd)i Fo(it)e(can)h(b)q(e)f(greatly)g +(simpli\014ed.)62 2213 y(First)e(the)g(UFS)g(partitions)g(should)h(b)q(e)g +(moun)o(ted)f(under)h(the)f(con)o(trol)f(of)h(`)p Fl(/etc/fstab)p +Fo(',)e(taking)i(care)g(that)0 2263 y(they)j(are)f(moun)o(ted)g(in)i(the)e +(same)h(place)g(that)f Fp(Amd)i Fo(w)o(ould)f(ha)o(v)o(e)f(automoun)o(ted)g +(them.)21 b(In)16 b(most)f(cases)h(this)0 2313 y(w)o(ould)e(b)q(e)h +(something)f(lik)o(e)h(`)p Fl(/a/)p Fp(host)q Fl(/home/)p Fp(host)q +Fo(')c(and)j(`)p Fl(/etc/fstab)p Fo(')e(on)i(host)f(`)p Fl(charm)p +Fo(')f(w)o(ould)j(ha)o(v)o(e)e(a)h(line:)120 2384 y Fl(/dev/xy0g)23 +b(/a/charm/home/charm)e(4.2)i(rw,nosuid,grpid)f(1)i(5)62 2475 +y Fo(The)16 b(map)f(can)g(then)h(b)q(e)f(c)o(hanged)h(to:)120 +2545 y Fl(/defaults)94 b(type:=nfs;sublink:=${key};op)o(ts:=rw,)o(intr,no)o +(suid,grp)o(id)120 2595 y(jsp)238 b(rhost:=charm;rfs:=/home/char)o(m)120 +2645 y(njw)g(rhost:=dylan;rfs:=/home/dyla)o(n/dk5)p eop +%%Page: 48 50 +48 49 bop 15 -83 a Fo(SMM:13-48)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)120 158 y Fl(...)120 208 y(phjk)214 +b(rhost:=toytown;rfs:=/home/to)o(ytown;s)o(ublink:)o(=ai/${ke)o(y})120 +258 y(sjv)238 b(rhost:=ganymede;rfs:=/home/g)o(anymede)62 349 +y Fo(This)17 b(map)e(op)q(erates)h(as)f(usual)h(on)g(a)f(remote)h(mac)o(hine) +g(\()p Fp(ie)j Fl(${host})c Fo(not)g(equal)h(to)g Fl(${rhost})p +Fo(\).)k(On)c(the)0 399 y(mac)o(hine)f(where)f(the)f(\014lesystem)i(is)f +(stored)f(\()p Fp(ie)k Fl(${host})c Fo(equal)h(to)g Fl(${rhost})p +Fo(\),)e Fp(Amd)k Fo(will)f(construct)e(a)h(lo)q(cal)0 449 +y(\014lesystem)k(moun)o(t)g(p)q(oin)o(t)g(whic)o(h)h(corresp)q(onds)f(to)f +(the)h(name)g(of)f(the)h(lo)q(cally)h(moun)o(ted)f(UFS)g(partition.)28 +b(If)0 499 y Fp(Amd)18 b Fo(is)f(started)f(with)h(the)f(\\-r")g(option)g +(then)h(instead)g(of)f(attempting)g(an)g(NFS)h(moun)o(t,)e +Fp(Amd)k Fo(will)f(simply)0 549 y(inherit)d(the)f(UFS)g(moun)o(t)f(\(see)h +(Section)h(5.14)d([Inheritance)j(Filesystem],)f(page)28 b(SMM:13-26\).)17 +b(If)d(\\-r")f(is)h(not)0 598 y(used)i(then)g(a)f(lo)q(opbac)o(k)g(NFS)h +(moun)o(t)e(will)j(b)q(e)f(made.)21 b(This)16 b(t)o(yp)q(e)f(of)g(moun)o(t)g +(is)h(kno)o(wn)f(to)f(cause)i(a)f(deadlo)q(c)o(k)0 648 y(on)g(man)o(y)g +(systems.)0 810 y Fq(8.3)33 b(Arc)n(hitecture)16 b(Sharing)62 +902 y Fo(Often)h(a)f(\014lesystem)h(will)h(b)q(e)f(shared)f(b)o(y)h(mac)o +(hines)g(of)f(di\013eren)o(t)g(arc)o(hitectures.)24 b(Separate)16 +b(trees)g(can)g(b)q(e)0 951 y(main)o(tained)f(for)f(the)g(executable)h +(images)f(for)g(eac)o(h)g(arc)o(hitecture,)g(but)h(it)f(ma)o(y)g(b)q(e)g +(more)g(con)o(v)o(enien)o(t)h(to)e(ha)o(v)o(e)0 1001 y(a)i(shared)g(tree,)g +(with)g(distinct)i(sub)q(directories.)62 1072 y(A)23 b(shared)f(tree)h(migh)o +(t)f(ha)o(v)o(e)g(the)h(follo)o(wing)g(structure)f(on)g(the)h(\014leserv)o +(er)g(\(called)h(`)p Fl(fserver)p Fo(')d(in)i(the)0 1122 y(example\):)120 +1192 y Fl(local/tex)120 1242 y(local/tex/fonts)120 1292 y(local/tex/lib)120 +1342 y(local/tex/bin)120 1391 y(local/tex/bin/sun3)120 1441 +y(local/tex/bin/sun4)120 1491 y(local/tex/bin/hp9000)120 1541 +y(...)62 1632 y Fo(In)15 b(this)g(example,)g(the)g(sub)q(directories)h(of)e +(`)p Fl(local/tex/bin)p Fo(')e(should)j(b)q(e)g(hidden)h(when)f(accessed)g +(via)g(the)0 1682 y(automoun)o(t)f(p)q(oin)o(t)i(\(con)o(v)o(en)o(tionally)g +(`)p Fl(/vol)p Fo('\).)i(A)d(moun)o(t-map)g(for)f(`)p Fl(/vol)p +Fo(')g(to)h(ac)o(hiev)o(e)h(this)f(w)o(ould)h(lo)q(ok)f(lik)o(e:)120 +1752 y Fl(/defaults)70 b(sublink:=${/key};rhost:=fserv)o(er;type)o(:=link)120 +1802 y(tex)214 b(type:=auto;fs:=${map};pref:=$)o({key}/)120 +1852 y(tex/fonts)70 b(host!=fserver;type:=nfs;rfs:=)o(/vol/te)o(x)21 +b(\\)406 1902 y(host==fserver;fs:=/usr/local/)o(tex)120 1952 +y(tex/lib)118 b(host!=fserver;type:=nfs;rfs:=)o(/vol/te)o(x)21 +b(\\)406 2002 y(host==fserver;fs:=/usr/local/)o(tex)120 2051 +y(tex/bin)118 b(-sublink:=${/key}/${arch})21 b(host!=fserver;type:=nfs;r)o +(fs:=/vo)o(l/tex)120 2101 y(\\)406 2151 y(host:=fserver;fs:=/usr/local/)o +(tex)62 2242 y Fo(When)12 b(`)p Fl(/vol/tex/bin)p Fo(')d(is)k(referenced,)g +(the)e(curren)o(t)h(mac)o(hine)g(arc)o(hitecture)g(is)g(automatically)g(app)q +(ended)0 2292 y(to)j(the)h(path)g(b)o(y)f(the)h Fl(${sublink})e +Fo(v)m(ariable.)23 b(This)17 b(means)e(that)g(users)h(can)g(ha)o(v)o(e)g(`)p +Fl(/vol/tex/bin)p Fo(')d(in)j(their)0 2342 y(`)p Fl(PATH)p +Fo(')e(without)h(concern)h(for)e(arc)o(hitecture)i(dep)q(endencies.)0 +2504 y Fq(8.4)33 b(Wildcard)17 b(names)e(&)g(Replicated)i(Serv)n(ers)62 +2595 y Fo(By)h(using)g(the)g(wildcard)h(facilit)o(y)l(,)g Fp(Amd)h +Fo(can)e Fp(o)o(v)o(erla)o(y)j Fo(an)c(existing)i(directory)f(with)g +(additional)h(en)o(tries.)0 2645 y(The)12 b(system)f(\014les)i(are)e(usually) +j(moun)o(ted)d(under)i(`)p Fl(/usr)p Fo('.)k(If)12 b(instead)g +Fp(Amd)i Fo(is)e(moun)o(ted)g(on)g(`)p Fl(/usr)p Fo(',)f(additional)p +eop +%%Page: 49 51 +49 50 bop 0 -83 a Fo(Chapter)15 b(8:)k(Examples)1300 b(SMM:13-49)0 +158 y(names)18 b(can)g(b)q(e)h(o)o(v)o(erla)o(y)o(ed)e(to)h(augmen)o(t)f(or)h +(replace)h(names)f(in)g(the)h(\\master")d(`)p Fl(/usr)p Fo('.)27 +b(A)18 b(map)g(to)g(do)g(this)0 208 y(w)o(ould)e(ha)o(v)o(e)e(the)i(form:)120 +279 y Fl(local)47 b(type:=auto;fs:=local-map)120 329 y(share)g +(type:=auto;fs:=share-map)120 378 y(*)143 b(-type:=nfs;rfs:=/export/ex)o +(ec/${arc)o(h};subl)o(ink:="$)o({key}")21 b(\\)311 428 y(rhost:=fserv1)46 +b(rhost:=fserv2)g(rhost:=fserv3)62 519 y Fo(Note)11 b(that)g(the)g(assignmen) +o(t)g(to)g Fl(${sublink})f Fo(is)i(surrounded)g(b)o(y)f(double)i(quotes)e(to) +f(prev)o(en)o(t)h(the)h(incoming)0 569 y(k)o(ey)j(from)f(causing)i(the)f(map) +f(to)h(b)q(e)g(misin)o(terpreted.)21 b(This)16 b(map)f(has)f(the)h(e\013ect)g +(of)g(directing)h(an)o(y)f(access)g(to)0 619 y(`)p Fl(/usr/local)p +Fo(')e(or)i(`)p Fl(/usr/share)p Fo(')e(to)h(another)h(automoun)o(t)f(p)q(oin) +o(t.)62 690 y(In)i(this)g(example,)g(it)g(is)f(assumed)h(that)f(the)g(`)p +Fl(/usr)p Fo(')f(\014les)i(are)f(replicated)i(on)f(three)f(\014leserv)o(ers:) +21 b(`)p Fl(fserv1)p Fo(',)0 739 y(`)p Fl(fserv2)p Fo(')15 +b(and)h(`)p Fl(fserv3)p Fo('.)21 b(F)l(or)16 b(an)o(y)g(references)h(other)f +(than)g(to)f(`)p Fl(local)p Fo(')g(and)h(`)p Fl(share)p Fo(')f(one)i(of)e +(the)i(serv)o(ers)e(is)0 789 y(used)j(and)g(a)f(sym)o(b)q(olic)i(link)g(to)e +Fl(${autodir}/${rhost}/expo)o(rt/exec/)o(${arch})o(/)p Fp(whatev)o(er)g +Fo(is)i(returned)0 839 y(once)d(an)f(appropriate)g(\014lesystem)h(has)f(b)q +(een)h(moun)o(ted.)0 1011 y Fq(8.5)33 b(`)p Fg(rwho)p Fq(')13 +b(serv)n(ers)62 1102 y Fo(The)j(`)p Fl(/usr/spool/rwho)p Fo(')c(directory)j +(is)h(a)f(go)q(o)q(d)g(candidate)h(for)f(automoun)o(ting.)k(F)l(or)c +(e\016ciency)h(reasons)0 1152 y(it)d(is)f(b)q(est)h(to)f(capture)g(the)h +(rwho)e(data)h(on)g(a)g(small)i(n)o(um)o(b)q(er)e(of)g(mac)o(hines)h(and)g +(then)f(moun)o(t)g(that)g(information)0 1202 y(on)o(to)g(a)h(large)g(n)o(um)o +(b)q(er)h(of)f(clien)o(ts.)20 b(The)14 b(data)e(written)i(in)o(to)f(the)g +(rwho)g(\014les)h(is)g(b)o(yte)f(order)g(dep)q(enden)o(t)i(so)d(only)0 +1252 y(serv)o(ers)j(with)g(the)h(correct)e(b)o(yte)h(ordering)h(can)f(b)q(e)h +(used)g(b)o(y)f(a)g(clien)o(t:)120 1322 y Fl(/defaults)214 +b(type:=nfs)120 1372 y(usr/spool/rwho)94 b(-byte==little;rfs:=/usr)o(/spool/) +o(rwho)21 b(\\)645 1422 y(rhost:=vaxA)46 b(rhost:=vaxB)23 b(\\)550 +1472 y(||)g(-rfs:=/usr/spool/rwho)e(\\)645 1521 y(rhost:=sun4)46 +b(rhost:=hp300)0 1694 y Fq(8.6)33 b(`)p Fg(/vol)p Fq(')62 1786 +y Fo(`)p Fl(/vol)p Fo(')14 b(is)i(used)g(as)e(a)h(catc)o(h-all)h(for)f(v)o +(olumes)g(whic)o(h)i(do)e(not)f(ha)o(v)o(e)h(other)g(con)o(v)o(en)o(tional)h +(names.)62 1856 y(Belo)o(w)21 b(is)f(part)g(of)f(the)h(`)p +Fl(/vol)p Fo(')f(map)h(for)g(the)g(domain)g(`)p Fl(doc.ic.ac.uk)p +Fo('.)32 b(The)21 b(`)p Fl(r+d)p Fo(')d(tree)i(is)h(used)g(for)0 +1906 y(new)15 b(or)e(exp)q(erimen)o(tal)j(soft)o(w)o(are)d(that)g(needs)i(to) +f(b)q(e)h(a)o(v)m(ailable)h(ev)o(erywhere)e(without)h(installing)h(it)e(on)h +(all)g(the)0 1956 y(\014leserv)o(ers.)24 b(Users)16 b(wishing)i(to)d(try)h +(out)g(the)g(new)h(soft)o(w)o(are)d(then)j(simply)h(include)g(`)p +Fl(/vol/r+d/{bin,ucb})p Fo(')0 2006 y(in)e(their)g(path.)62 +2076 y(The)e(main)g(tree)f(resides)h(on)g(one)f(host)g(`)p +Fl(gould.doc.ic.ac.uk)p Fo(',)d(whic)o(h)15 b(has)e(di\013eren)o(t)h(`)p +Fl(bin)p Fo(',)e(`)p Fl(etc)p Fo(',)g(`)p Fl(lib)p Fo(')0 2126 +y(and)k(`)p Fl(ucb)p Fo(')e(sub-directories)k(for)d(eac)o(h)g(mac)o(hine)i +(arc)o(hitecture.)k(F)l(or)15 b(example,)i(`)p Fl(/vol/r+d/bin)p +Fo(')c(for)i(a)g(Sun-4)0 2176 y(w)o(ould)e(b)q(e)g(stored)e(in)j(the)e +(sub-directory)h(`)p Fl(bin/sun4)p Fo(')d(of)i(the)h(\014lesystem)g(`)p +Fl(/usr/r+d)p Fo('.)k(When)12 b(it)h(w)o(as)e(accessed)0 2226 +y(a)k(sym)o(b)q(olic)h(link)h(p)q(oin)o(ting)f(to)f(`)p Fl +(/a/gould/usr/r+d/bin/s)o(un4)p Fo(')d(w)o(ould)j(b)q(e)h(returned.)120 +2296 y Fl(/defaults)94 b(type:=nfs;opts:=rw,grpid,nos)o(uid,int)o(r,soft)120 +2346 y(wp)262 b(-opts:=rw,grpid,nosuid;rhost)o(:=charm)20 b(\\)430 +2396 y(host==charm;type:=link;fs:=/)o(usr/loc)o(al/wp)h(\\)430 +2446 y(host!=charm;type:=nfs;rfs:=/)o(vol/wp)120 2496 y(...)120 +2545 y(#)120 2595 y(src)238 b(-opts:=rw,grpid,nosuid;rhost)o(:=charm)20 +b(\\)430 2645 y(host==charm;type:=link;fs:=/)o(usr/src)g(\\)p +eop +%%Page: 50 52 +50 51 bop 15 -83 a Fo(SMM:13-50)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)430 158 y Fl(host!=charm;type:=nfs;rfs:=/)o(vol/src) +120 208 y(#)120 258 y(r+d)238 b(type:=auto;fs:=${map};pref:=)o(r+d/)120 +308 y(#)24 b(per)f(architecture)f(bin,etc,lib&ucb...)120 358 +y(r+d/bin)142 b(rhost:=gould.doc.ic.ac.uk;rf)o(s:=/usr)o(/r+d;su)o(blink:=$)o +({/key}/)o(${arch})120 407 y(r+d/etc)g(rhost:=gould.doc.ic.ac.uk;rf)o +(s:=/usr)o(/r+d;su)o(blink:=$)o({/key}/)o(${arch})120 457 y(r+d/include)46 +b(rhost:=gould.doc.ic.ac.uk;rf)o(s:=/usr)o(/r+d;su)o(blink:=$)o({/key})120 +507 y(r+d/lib)142 b(rhost:=gould.doc.ic.ac.uk;rf)o(s:=/usr)o(/r+d;su)o +(blink:=$)o({/key}/)o(${arch})120 557 y(r+d/man)g +(rhost:=gould.doc.ic.ac.uk;rf)o(s:=/usr)o(/r+d;su)o(blink:=$)o({/key})120 +607 y(r+d/src)g(rhost:=gould.doc.ic.ac.uk;rf)o(s:=/usr)o(/r+d;su)o(blink:=$)o +({/key})120 656 y(r+d/ucb)g(rhost:=gould.doc.ic.ac.uk;rf)o(s:=/usr)o(/r+d;su) +o(blink:=$)o({/key}/)o(${arch})120 706 y(#)24 b(hades)f(pictures)120 +756 y(pictures)118 b(-opts:=rw,grpid,nosuid;rhost)o(:=thpfs)20 +b(\\)430 806 y(host==thpfs;type:=link;fs:=/)o(nbsd/pi)o(ctures)g(\\)430 +856 y(host!=thpfs;type:=nfs;rfs:=/)o(nbsd;su)o(blink:=)o(pictures)120 +906 y(#)k(hades)f(tools)120 955 y(hades)190 b(-opts:=rw,grpid,nosuid;rhost)o +(:=thpfs)20 b(\\)430 1005 y(host==thpfs;type:=link;fs:=/)o(nbsd/ha)o(des)h +(\\)430 1055 y(host!=thpfs;type:=nfs;rfs:=/)o(nbsd;su)o(blink:=)o(hades)120 +1105 y(#)j(bsd)f(tools)g(for)h(hp.)120 1155 y(bsd)238 b +(-opts:=rw,grpid,nosuid;arch=)o(=hp9000)o(;rhost:)o(=thpfs)21 +b(\\)430 1204 y(host==thpfs;type:=link;fs:=/)o(nbsd/bs)o(d)g(\\)430 +1254 y(host!=thpfs;type:=nfs;rfs:=/)o(nbsd;su)o(blink:=)o(bsd)0 +1468 y Fm(9)41 b(In)n(ternals)0 1709 y Fq(9.1)33 b(Log)14 b(Messages)62 +1800 y Fo(In)h(the)f(follo)o(wing)h(sections)g(a)f(brief)g(explanation)i(is)e +(giv)o(en)h(of)e(some)h(of)g(the)g(log)g(messages)g(made)g(b)o(y)g +Fp(Amd)p Fo(.)0 1850 y(Where)20 b(the)f(message)g(is)h(in)h(`)p +Fl(typewriter)p Fo(')c(fon)o(t,)i(it)h(corresp)q(onds)g(exactly)g(to)f(the)g +(message)g(pro)q(duced)i(b)o(y)0 1900 y Fp(Amd)p Fo(.)i(W)l(ords)16 +b(in)i Fp(italic)i Fo(are)c(replaced)i(b)o(y)e(an)g(appropriate)g(string.)24 +b(V)l(ariables,)17 b Fl(${var})p Fo(,)e(indicate)j(that)e(the)0 +1950 y(v)m(alue)g(of)f(the)g(appropriate)h(v)m(ariable)g(is)g(output.)62 +2020 y(Log)h(messages)f(are)g(either)h(sen)o(t)g(direct)g(to)f(a)g(\014le,)i +(or)e(logged)h(via)g(the)f Fk(syslog)p Fo(\(3\))g(mec)o(hanism.)25 +b(Messages)0 2070 y(are)15 b(logged)g(with)g(facilit)o(y)h(`)p +Fl(LOG_DAEMON)p Fo(')d(when)i(using)h Fk(syslog)p Fo(\(3\).)j(In)c(either)h +(case,)f(en)o(tries)g(in)h(the)f(\014le)h(are)e(of)0 2120 y(the)h(form:)120 +2191 y Fp(date-string)52 b(hostname)26 b Fl(amd[)p Fp(pid)r +Fl(])48 b Fp(message)0 2355 y Fi(9.1.1)30 b(F)-5 b(atal)14 +b(errors)62 2446 y Fp(Amd)20 b Fo(attempts)c(to)h(deal)h(with)g(un)o(usual)g +(ev)o(en)o(ts.)27 b(Whenev)o(er)17 b(it)h(is)g(not)f(p)q(ossible)i(to)e(deal) +h(with)g(suc)o(h)g(an)0 2496 y(error,)d Fp(Amd)k Fo(will)f(log)e(an)g +(appropriate)h(message)e(and,)i(if)f(it)h(cannot)f(p)q(ossibly)i(con)o(tin)o +(ue,)f(will)h(either)f(exit)f(or)0 2545 y(ab)q(ort.)24 b(These)17 +b(messages)f(are)g(selected)i(b)o(y)e(`)p Fl(-x)f(fatal)p Fo(')g(on)i(the)g +(command)f(line.)26 b(When)17 b Fk(syslog)p Fo(\(3\))f(is)h(b)q(eing)0 +2595 y(used,)22 b(they)e(are)g(logged)h(with)g(lev)o(el)g(`)p +Fl(LOG_FATAL)p Fo('.)34 b(Ev)o(en)20 b(if)h Fp(Amd)h Fo(con)o(tin)o(ues)f(to) +f(op)q(erate)g(it)h(is)f(lik)o(ely)j(to)0 2645 y(remain)16 +b(in)g(a)f(precarious)g(state)g(and)g(should)h(b)q(e)g(restarted)e(at)h(the)g +(earliest)h(opp)q(ortunit)o(y)l(.)p eop +%%Page: 51 53 +51 52 bop 0 -83 a Fo(Chapter)15 b(9:)k(In)o(ternals)1317 b(SMM:13-51)0 +158 y Fl(Attempting)22 b(to)i(inherit)f(not-a-filesystem)240 +219 y Fo(The)14 b(protot)o(yp)q(e)g(moun)o(t)g(p)q(oin)o(t)g(created)h +(during)g(a)f(\014lesystem)h(restart)e(did)i(not)f(con)o(tain)g(a)g(refer-) +240 269 y(ence)i(to)f(the)g(restarted)f(\014lesystem.)21 b(This)16 +b(erorr)e(\\should)i(nev)o(er)f(happ)q(en".)0 330 y Fl(Can't)23 +b(bind)g(to)h(domain)f(")p Fp(NIS-domain)p Fl(")240 391 y Fo(A)e(sp)q +(eci\014c)i(NIS)e(domain)h(w)o(as)e(requested)h(on)g(the)g(command)f(line,)k +(but)d(no)g(serv)o(er)f(for)h(that)240 441 y(domain)16 b(is)f(a)o(v)m +(ailable)i(on)e(the)h(lo)q(cal)g(net.)0 502 y Fl(Can't)23 b(determine)g(IP)g +(address)g(of)h(this)f(host)h(\()p Fp(hostname)s Fl(\))240 +563 y Fo(When)11 b Fp(Amd)h Fo(starts)d(it)i(determines)g(its)g(o)o(wn)e(IP)i +(address.)18 b(If)11 b(this)g(lo)q(okup)g(fails)g(then)g Fp(Amd)h +Fo(cannot)240 612 y(con)o(tin)o(ue.)19 b(The)11 b(hostname)e(it)i(lo)q(oks)g +(up)g(is)f(that)g(obtained)h(returned)g(b)o(y)f Fk(gethostname)p +Fo(\(2\))f(system)240 662 y(call.)0 723 y Fl(Can't)23 b(find)g(root)h(file)f +(handle)g(for)h Fp(automoun)o(t)14 b(p)q(oin)o(t)240 784 y(Amd)19 +b Fo(creates)d(its)h(o)o(wn)g(\014le)g(handles)h(for)f(the)f(automoun)o(t)g +(p)q(oin)o(ts.)25 b(When)17 b(it)g(moun)o(ts)g(itself)g(as)240 +834 y(a)i(serv)o(er,)i(it)f(m)o(ust)f(pass)h(these)g(\014le)g(handles)h(to)f +(the)g(lo)q(cal)g(k)o(ernel.)35 b(If)20 b(the)g(\014lehandle)i(is)e(not)240 +884 y(obtainable)c(the)g(moun)o(t)e(p)q(oin)o(t)i(is)g(ignored.)k(This)c +(error)e(\\should)i(nev)o(er)g(happ)q(en".)0 945 y Fl(Must)23 +b(be)h(root)f(to)h(mount)f(filesystems)f(\(euid)i(=)f Fp(euid)r +Fl(\))240 1006 y Fo(T)l(o)13 b(prev)o(en)o(t)f(em)o(barrassmen)o(t,)g +Fp(Amd)j Fo(mak)o(es)d(sure)h(it)g(has)g(appropriate)g(system)f(privileges.) +21 b(This)240 1055 y(amoun)o(ts)12 b(to)g(ha)o(ving)h(an)f(euid)i(of)f(0.)18 +b(The)13 b(c)o(hec)o(k)g(is)g(made)g(after)f(argumen)o(t)g(pro)q(cessing)h +(complete)240 1105 y(to)i(giv)o(e)g(non-ro)q(ot)g(users)g(a)g(c)o(hance)h(to) +e(access)h(the)h(\\-v")f(option.)0 1166 y Fl(No)24 b(work)f(to)g(do)h(-)g +(quitting)240 1227 y Fo(No)15 b(automoun)o(t)f(p)q(oin)o(ts)i(w)o(ere)f(giv)o +(en)g(on)g(the)h(command)f(line)i(and)e(so)g(there)g(is)h(no)f(w)o(ork)f(to)h +(do.)0 1288 y Fl(Out)23 b(of)h(memory)f(in)h(realloc)240 1349 +y Fo(While)c(attempting)e(to)g(reallo)q(c)h(some)f(memory)l(,)h(the)f(memory) +g(space)h(a)o(v)m(ailable)h(to)d Fp(Amd)k Fo(w)o(as)240 1399 +y(exhausted.)f(This)c(is)g(an)f(unreco)o(v)o(erable)h(error.)0 +1460 y Fl(Out)23 b(of)h(memory)240 1521 y Fo(While)c(attempting)e(to)g(mallo) +q(c)h(some)f(memory)l(,)h(the)f(memory)g(space)h(a)o(v)m(ailable)h(to)d +Fp(Amd)k Fo(w)o(as)240 1570 y(exhausted.)f(This)c(is)g(an)f(unreco)o(v)o +(erable)h(error.)0 1631 y Fl(cannot)23 b(create)g(rpc/udp)g(service)240 +1692 y Fo(Either)16 b(the)f(NFS)g(or)g(AMQ)g(endp)q(oin)o(t)h(could)h(not)d +(b)q(e)i(created.)0 1753 y Fl(gethostname:)e Fp(description)240 +1814 y Fo(The)h Fk(gethostname)p Fo(\(2\))f(system)h(call)i(failed)f(during)g +(startup.)0 1875 y Fl(host)23 b(name)h(is)f(not)h(set)240 1936 +y Fo(The)14 b Fk(gethostname)p Fo(\(2\))g(system)f(call)j(returned)e(a)g +(zero)h(length)f(host)g(name.)20 b(This)15 b(can)f(happ)q(en)h(if)240 +1986 y Fp(Amd)i Fo(is)f(started)e(in)i(single)h(user)e(mo)q(de)h(just)f +(after)f(b)q(o)q(oting)i(the)f(system.)0 2047 y Fl(ifs_match)23 +b(called!)240 2108 y Fo(An)i(in)o(ternal)g(error)f(o)q(ccurred)h(while)i +(restarting)d(a)g(pre-moun)o(ted)h(\014lesystem.)48 b(This)26 +b(error)240 2158 y(\\should)16 b(nev)o(er)f(happ)q(en".)0 2219 +y Fl(mount_afs:)f Fp(description)240 2279 y Fo(An)h(error)g(o)q(ccured)h +(while)h Fp(Amd)g Fo(w)o(as)d(moun)o(ting)i(itself.)0 2340 +y Fl(run_rpc)23 b(failed)240 2401 y Fo(Someho)o(w)15 b(the)g(main)h(NFS)f +(serv)o(er)g(lo)q(op)g(failed.)22 b(This)15 b(error)g(\\should)h(nev)o(er)f +(happ)q(en".)0 2462 y Fl(unable)23 b(to)h(free)f(rpc)g(arguments)g(in)h +(amqprog_1)240 2523 y Fo(The)15 b(incoming)i(argumen)o(ts)d(to)h(the)g(AMQ)g +(serv)o(er)g(could)h(not)f(b)q(e)h(free'ed.)0 2584 y Fl(unable)23 +b(to)h(free)f(rpc)g(arguments)g(in)h(nfs_program_1)240 2645 +y Fo(The)15 b(incoming)i(argumen)o(ts)d(to)h(the)g(NFS)g(serv)o(er)g(could)h +(not)f(b)q(e)h(free'ed.)p eop +%%Page: 52 54 +52 53 bop 15 -83 a Fo(SMM:13-52)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 158 y Fl(unable)23 b(to)h(register)e(\(AMQ_PROGRAM,) +g(AMQ_VERSION,)h(udp\))240 221 y Fo(The)d(AMQ)g(serv)o(er)g(could)g(not)g(b)q +(e)g(registered)h(with)f(the)g(lo)q(cal)h(p)q(ortmapp)q(er)f(or)f(the)h(in)o +(ternal)240 271 y(RPC)15 b(dispatc)o(her.)0 334 y Fl(unable)23 +b(to)h(register)e(\(NFS_PROGRAM,)g(NFS_VERSION,)h(0\))240 397 +y Fo(The)15 b(NFS)h(serv)o(er)e(could)j(not)d(b)q(e)i(registered)g(with)f +(the)h(in)o(ternal)g(RPC)f(dispatc)o(her.)0 543 y Fi(9.1.2)30 +b(Info)14 b(messages)62 634 y Fp(Amd)f Fo(generates)e(information)g(messages) +g(to)f(record)i(state)e(c)o(hanges.)18 b(These)12 b(messages)e(are)h +(selected)i(b)o(y)e(`)p Fl(-x)0 684 y(info)p Fo(')j(on)h(the)h(command)f +(line.)21 b(When)16 b Fk(syslog)p Fo(\(3\))e(is)i(b)q(eing)g(used,)g(they)f +(are)g(logged)g(with)h(lev)o(el)g(`)p Fl(LOG_INFO)p Fo('.)62 +754 y(The)h(messages)f(listed)i(b)q(elo)o(w)g(can)f(b)q(e)g(generated)g(and)g +(are)f(in)i(a)e(format)f(suitable)j(for)e(simple)j(statistical)0 +804 y(analysis.)24 b Fp(moun)o(t-info)18 b Fo(is)f(the)g(string)f(that)f(is)i +(displa)o(y)o(ed)h(b)o(y)e Fp(Amq)h Fo(in)g(its)g(moun)o(t)e(information)i +(column)g(and)0 854 y(placed)f(in)g(the)g(system)e(moun)o(t)h(table.)0 +924 y Fl(mount)23 b(of)h("${)p Fp(path)p Fl(}")f(on)g(${)p +Fp(fs)r Fl(})h(timed)f(out)240 987 y Fo(A)o(ttempts)13 b(to)h(moun)o(t)f(a)h +(\014lesystem)h(for)f(the)g(giv)o(en)h(automoun)o(t)e(p)q(oin)o(t)h(ha)o(v)o +(e)g(failed)i(to)d(complete)240 1037 y(within)j(30)f(seconds.)0 +1100 y Fl("${)p Fp(path)p Fl(}")23 b(forcibly)g(timed)g(out)240 +1163 y Fo(An)15 b(automoun)o(t)g(p)q(oin)o(t)g(has)g(b)q(een)i(timed)e(out)g +(b)o(y)g(the)h Fp(Amq)g Fo(command.)0 1226 y Fl(restarting)22 +b Fp(moun)o(t-info)27 b Fl(on)c(${)p Fp(fs)r Fl(})240 1288 +y Fo(A)15 b(pre-moun)o(ted)h(\014le)g(system)f(has)g(b)q(een)h(noted.)0 +1351 y Fl("${)p Fp(path)p Fl(}")23 b(has)h(timed)f(out)240 +1414 y Fo(No)15 b(access)g(to)g(the)g(automoun)o(t)f(p)q(oin)o(t)i(has)f(b)q +(een)h(made)f(within)i(the)e(timeout)g(p)q(erio)q(d.)0 1477 +y Fl(file)23 b(server)g(${)p Fp(rhost)q Fl(})g(is)h(down)f(-)h(timeout)f(of)g +("${)p Fp(path)p Fl(}")g(ignored)240 1540 y Fo(An)18 b(automoun)o(t)e(p)q +(oin)o(t)i(has)f(timed)h(out,)f(but)h(the)g(corresp)q(onding)g(\014le)g(serv) +o(er)f(is)h(kno)o(wn)g(to)e(b)q(e)240 1590 y(do)o(wn.)23 b(This)17 +b(message)f(is)h(only)g(pro)q(duced)g(once)g(for)f(eac)o(h)g(moun)o(t)g(p)q +(oin)o(t)h(for)f(whic)o(h)h(the)f(serv)o(er)240 1639 y(is)g(do)o(wn.)0 +1702 y Fl(Re-synchronizing)22 b(cache)h(for)g(map)h(${)p Fp(map)q +Fl(})240 1765 y Fo(The)15 b(named)h(map)f(has)g(b)q(een)h(mo)q(di\014ed)h +(and)e(the)h(in)o(ternal)g(cac)o(he)f(is)h(b)q(eing)g(re-sync)o(hronized.)0 +1828 y Fl(Filehandle)22 b(denied)i(for)f("${)p Fp(rhost)q Fl(}:${)p +Fp(rfs)r Fl(}")240 1891 y Fo(The)15 b(moun)o(t)g(daemon)g(refused)h(to)f +(return)g(a)g(\014le)h(handle)g(for)f(the)g(requested)h(\014lesystem.)0 +1954 y Fl(Filehandle)22 b(error)i(for)f("${)p Fp(rhost)q Fl(}:${)p +Fp(rfs)r Fl(}":)13 b Fp(description)240 2017 y Fo(The)i(moun)o(t)g(daemon)g +(ga)o(v)o(e)g(some)f(other)h(error)g(for)f(the)i(requested)f(\014lesystem.)0 +2079 y Fl(file)23 b(server)g(${)p Fp(rhost)q Fl(})g(type)h(nfs)f(starts)g(up) +240 2142 y Fo(A)15 b(new)h(NFS)f(\014le)h(serv)o(er)f(has)g(b)q(een)h +(referenced)g(and)g(is)g(kno)o(wn)e(to)h(b)q(e)h(up.)0 2205 +y Fl(file)23 b(server)g(${)p Fp(rhost)q Fl(})g(type)h(nfs)f(starts)g(down)240 +2268 y Fo(A)15 b(new)h(NFS)f(\014le)h(serv)o(er)f(has)g(b)q(een)h(referenced) +g(and)g(is)g(kno)o(wn)e(to)h(b)q(e)h(do)o(wn.)0 2331 y Fl(file)23 +b(server)g(${)p Fp(rhost)q Fl(})g(type)h(nfs)f(is)h(up)240 +2394 y Fo(An)15 b(NFS)h(\014le)g(serv)o(er)f(that)f(w)o(as)h(previously)h(do) +o(wn)f(is)h(no)o(w)e(up.)0 2457 y Fl(file)23 b(server)g(${)p +Fp(rhost)q Fl(})g(type)h(nfs)f(is)h(down)240 2519 y Fo(An)15 +b(NFS)h(\014le)g(serv)o(er)f(that)f(w)o(as)h(previously)h(up)g(is)f(no)o(w)g +(do)o(wn.)0 2582 y Fl(Finishing)23 b(with)g(status)g Fp(exit-status)240 +2645 y(Amd)17 b Fo(is)f(ab)q(out)f(to)f(exit)i(with)g(the)f(giv)o(en)h(exit)f +(status.)p eop +%%Page: 53 55 +53 54 bop 0 -83 a Fo(Index)1613 b(SMM:13-53)0 158 y Fp(moun)o(t-info)26 +b Fl(mounted)d(fstype)g(${)p Fp(t)o(yp)q(e)s Fl(})g(on)h(${)p +Fp(fs)r Fl(})240 221 y Fo(A)15 b(new)h(\014le)g(system)f(has)g(b)q(een)h +(moun)o(ted.)0 283 y Fp(moun)o(t-info)26 b Fl(restarted)d(fstype)g(${)p +Fp(t)o(yp)q(e)s Fl(})g(on)h(${)p Fp(fs)r Fl(})240 345 y Fp(Amd)17 +b Fo(is)f(using)g(a)f(pre-moun)o(ted)g(\014lesystem)h(to)f(satisfy)g(a)f +(moun)o(t)h(request.)0 407 y Fp(moun)o(t-info)26 b Fl(unmounted)d(fstype)g +(${)p Fp(t)o(yp)q(e)s Fl(})g(from)g(${)p Fp(fs)r Fl(})240 470 +y Fo(A)15 b(\014le)h(system)f(has)g(b)q(een)i(unmoun)o(ted.)0 +532 y Fp(moun)o(t-info)26 b Fl(unmounted)d(fstype)g(${)p Fp(t)o(yp)q(e)s +Fl(})g(from)g(${)p Fp(fs)r Fl(})h(link)f(${)p Fp(fs)r Fl(}/${)p +Fp(sublink)s Fl(})240 594 y Fo(A)15 b(\014le)h(system)f(of)g(whic)o(h)h(only) +g(a)f(sub-directory)h(w)o(as)e(in)i(use)g(has)f(b)q(een)h(unmoun)o(ted.)0 +784 y Fm(Ac)n(kno)n(wledgemen)n(ts)e(&)h(T)-7 b(rademarks)62 +904 y Fo(Thanks)19 b(to)g(the)g(F)l(ormal)f(Metho)q(ds)h(Group)g(at)f(Imp)q +(erial)j(College)f(for)e(su\013ering)i(patien)o(tly)f(while)i +Fp(Amd)0 954 y Fo(w)o(as)14 b(b)q(eing)j(dev)o(elop)q(ed)g(on)e(their)h(mac)o +(hines.)62 1024 y(Thanks)j(to)f(the)h(man)o(y)f(p)q(eople)i(who)e(ha)o(v)o(e) +h(help)q(ed)h(with)f(the)g(dev)o(elopmen)o(t)h(of)e Fp(Amd)p +Fo(,)h(esp)q(ecially)i(Piete)0 1074 y(Bro)q(oks)c(at)g(the)h(Cam)o(bridge)g +(Univ)o(ersit)o(y)g(Computing)g(Lab)g(for)f(man)o(y)g(hours)h(of)f(testing,)h +(exp)q(erimen)o(tation)0 1124 y(and)d(discussion.)37 1195 y +Fn(\017)30 b Fk(DEC)p Fo(,)14 b Fk(V)-5 b(AX)16 b Fo(and)g +Fk(Ultrix)g Fo(are)f(registered)h(trademarks)e(of)h(Digital)h(Equipmen)o(t)g +(Corp)q(oration.)37 1257 y Fn(\017)30 b Fk(AIX)16 b Fo(and)f +Fk(IBM)h Fo(are)f(registered)g(trademarks)g(of)f(In)o(ternational)i(Business) +h(Mac)o(hines)e(Corp)q(oration.)37 1319 y Fn(\017)30 b Fk(Sun)p +Fo(,)16 b Fk(NFS)e Fo(and)h Fk(SunOS)i Fo(are)e(registered)g(trademarks)f(of) +h(Sun)h(Microsystems,)e(Inc.)37 1381 y Fn(\017)30 b Fk(Unix)20 +b Fo(is)f(a)g(registered)g(trademark)f(of)h(A)l(T&T)g(Unix)h(Systems)f(Lab)q +(oratories)g(in)h(the)f(USA)g(and)g(other)90 1431 y(coun)o(tries.)0 +1606 y Fm(Index)0 1826 y Fc(/etc/amd.start)t Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(33)0 1871 +y(/etc/passwd)d(maps)9 b Fb(:)e(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)22 b Fc(13)0 1917 y(/etc/rc.lo)q(cal)15 b(additions)e +Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)23 b Fc(33)0 1963 +y(/v)o(ol)11 b Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)22 b +Fc(56)0 2008 y(Additions)15 b(to)e(/etc/rc.lo)q(cal)7 b Fb(:)h(:)f(:)f(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)20 b Fc(33)0 2054 y(Aliased)15 b(hostnames)8 b Fb(:)f(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)20 b Fc(22)0 2100 y(Alternate)14 +b(lo)q(cations)t Fb(:)8 b(:)e(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)17 b Fc(6)0 2145 y(Amd)c(command)h(line)g(options)8 b Fb(:)g(:)e(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)21 b Fc(21)0 2191 y(Amq)13 b(command)d Fb(:)d(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)22 b Fc(33)0 2236 y(arc)o(h,)13 +b(FSinfo)h(host)g(attribute)6 b Fb(:)h(:)f(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)19 +b Fc(41)0 2282 y(arc)o(h,)13 b(moun)o(t)h(selector)c Fb(:)c(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)22 b Fc(16)0 2328 y(Arc)o(hitecture)14 +b(dep)q(enden)o(t)h(v)o(olumes)e Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)24 b Fc(55)0 2373 y(Arc)o(hitecture)14 +b(sharing)8 b Fb(:)g(:)e(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)21 +b Fc(55)0 2419 y(Arc)o(hitecture)14 b(sp)q(eci\014c)h(moun)o(ts)9 +b Fb(:)e(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)22 b Fc(56)0 2465 y(A)o(tomic)13 b(NFS)g(moun)o(ts)8 +b Fb(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)20 b Fc(27)0 +2510 y(auto,)13 b(\014lesystem)i(t)o(yp)q(e)6 b Fb(:)g(:)g(:)g(:)g(:)h(:)f(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)19 b Fc(29)0 2556 y(auto)q(dir,)14 b(moun)o(t)g(selector)c +Fb(:)c(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)22 b Fc(16)0 2602 y(Automatic)14 +b(generation)h(of)d(user)i(maps)t Fb(:)6 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(13)1015 1826 y(Automoun)o(t)d(directory)f +Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)24 b Fc(21)1015 +1871 y(Automoun)o(t)14 b(\014lesystem)t Fb(:)8 b(:)f(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)18 b Fc(29)1015 1917 y(Automoun)o(ter)c(con\014guration)i(maps)t +Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)17 b Fc(11)1015 1963 y(Automoun)o(ter)d(fundamen)o(tals)f +Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)23 b Fc(5)1015 2008 y(Bac)o(kground)15 +b(moun)o(ts)5 b Fb(:)i(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 +b Fc(6)1015 2054 y(Binding)e(names)e(to)f(\014lesystems)6 b +Fb(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)19 b Fc(6)1015 2100 y(b)q(o)q(otparams,)c(FSinfo)f +(pre\014x)s Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)16 b Fc(47)1015 +2145 y(Bug)e(rep)q(orts)5 b Fb(:)i(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b Fc(3)1015 2191 +y(b)o(yte,)c(moun)o(t)f(selector)c Fb(:)e(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)22 b Fc(16)1015 2236 y(Cac)o(he)14 b(in)o(terv)n(al)9 +b Fb(:)f(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)22 +b Fc(21)1015 2282 y(cac)o(he,)14 b(moun)o(t)f(option)e Fb(:)6 +b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)23 b Fc(29)1015 +2328 y(Catc)o(h-all)15 b(moun)o(t)e(p)q(oin)o(t)f Fb(:)6 b(:)g(:)h(:)f(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)24 b Fc(56)1015 2373 y(Changing)15 b(the)e(in)o(terv)n(al)i(b) +q(efore)e(a)g(\014lesystem)i(times)f(out)1098 2419 y Fb(:)6 +b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)18 b Fc(21)1015 2465 y(Cluster)c(names)9 +b Fb(:)e(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)22 +b Fc(24)1015 2510 y(cluster,)14 b(FSinfo)g(host)g(attribute)t +Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)17 b Fc(41)1015 2556 y(cluster,)d(moun)o(t)g(selector)6 +b Fb(:)h(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(17)1015 +2602 y(Command)14 b(line)h(options,)f(Amd)6 b Fb(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 +b Fc(21)p eop +%%Page: 54 56 +54 55 bop 15 -83 a Fo(SMM:13-54)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 158 y Fc(Command)d(line)g(options,)g(FSinfo)9 +b Fb(:)f(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)22 b Fc(47)0 204 y(con\014g,)14 b(FSinfo)g(host)f(attribute)f +Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)23 b Fc(40)0 250 y(Con\014guration)15 b(map)f(t)o(yp)q(es) +6 b Fb(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)18 b Fc(11)0 295 y(Con)o(trolling)e(Amd)t +Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 +b Fc(34)0 341 y(Creating)d(a)f(pid)h(\014le)e Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)23 b Fc(22)0 387 y(Debug)14 b(options)8 +b Fb(:)f(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)20 +b Fc(24)0 432 y(De\014ning)15 b(a)e(host,)g(FSinfo)g Fb(:)6 +b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)24 b Fc(39)0 478 y(De\014ning)15 +b(an)e(Amd)g(moun)o(t)h(map,)f(FSinfo)s Fb(:)7 b(:)f(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)16 b Fc(45)0 524 y(De\014ning)f(host)e +(attributes,)i(FSinfo)7 b Fb(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(39)0 569 y(dela)o(y)m(,)14 +b(moun)o(t)f(option)t Fb(:)8 b(:)e(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +17 b Fc(18)0 615 y(Dela)o(ying)e(moun)o(ts)f(from)f(sp)q(eci\014c)h(lo)q +(cations)8 b Fb(:)h(:)d(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)21 +b Fc(18)0 661 y(Determining)15 b(the)f(map)f(t)o(yp)q(e)8 b +Fb(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)21 b Fc(11)0 706 y(dev,)13 b(moun)o(t)h(option)8 +b Fb(:)g(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)21 +b Fc(28)0 752 y(Direct)14 b(automoun)o(t)g(\014lesystem)e Fb(:)6 +b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)23 b Fc(30)0 798 y(direct,)14 b(\014lesystem)g(t)o(yp)q(e)t +Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(30)0 +843 y(Disco)o(v)o(ering)f(v)o(ersion)e(information)8 b Fb(:)h(:)d(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)21 +b Fc(23)0 889 y(Disco)o(v)o(ering)16 b(what)d(is)g(going)i(on)e(at)g +(run-time)7 b Fb(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 +b Fc(34)0 935 y(Disk)14 b(\014lesystems)t Fb(:)8 b(:)e(:)g(:)g(:)g(:)g(:)g(:) +g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(28)0 980 y(Displa)o(yin)q(g)f(the) +d(pro)q(cess)h(id)t Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)16 b +Fc(22)0 1026 y(Domain)f(name)s Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)16 b Fc(21)0 1072 y(Domain)f(stripping)7 +b Fb(:)i(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)20 +b Fc(15)0 1117 y(domain,)14 b(moun)o(t)g(selector)9 b Fb(:)e(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)22 b Fc(17)0 1163 y(Domainname)15 b(op)q(erators)c +Fb(:)6 b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)23 b Fc(15)0 1209 y(dumpset,)14 +b(FSinfo)g(\014lesystems)g(option)6 b Fb(:)i(:)e(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b Fc(44)0 1254 y(dumpset,)14 +b(FSinfo)g(pre\014x)5 b Fb(:)i(:)f(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)18 +b Fc(48)0 1300 y(Duplicated)e(v)o(olumes)7 b Fb(:)h(:)e(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(5)0 1346 y(En)o(vironmen)o(t)15 +b(v)n(ariables)9 b Fb(:)f(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)22 +b Fc(15)0 1391 y(Error)13 b(\014lesystem)t Fb(:)8 b(:)e(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(31)0 1437 y(error,)c +(\014lesystem)h(t)o(yp)q(e)e Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)24 +b Fc(31)0 1483 y(Example)14 b(of)f(arc)o(hitecture)i(sp)q(eci\014c)f(moun)o +(ts)6 b Fb(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)19 +b Fc(56)0 1528 y(Example)14 b(of)f(moun)o(ting)i(home)e(directories)8 +b Fb(:)h(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)21 b +Fc(54)0 1574 y(exp)q(ort,)13 b(FSinfo)h(sp)q(ecial)i(fst)o(yp)q(e)8 +b Fb(:)e(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)21 b Fc(43)0 1620 y(exp)q(ortfs,)13 b(FSinfo)h(moun)o(t)g +(option)f Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)24 b Fc(44)0 1665 y(exp)q(orts,)14 b(FSinfo)g(pre\014x)6 +b Fb(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)19 b Fc(48)0 +1711 y(File)14 b(map)g(syn)o(tactic)g(con)o(v)o(en)o(tions)6 +b Fb(:)j(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)19 b Fc(11)0 1757 y(File)14 b(maps)t Fb(:)7 b(:)f(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)17 +b Fc(11)0 1802 y(Fileserv)o(er)6 b Fb(:)i(:)e(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b +Fc(5)0 1848 y(Filesystem)c(info)f(pac)o(k)n(age)7 b Fb(:)g(:)f(:)g(:)g(:)g(:) +g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)20 b Fc(38)0 1893 y(Filesystem)15 b(t)o(yp)q(e;)e(auto)7 +b Fb(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)20 b Fc(29)0 +1939 y(Filesystem)15 b(t)o(yp)q(e;)e(direct)5 b Fb(:)i(:)f(:)g(:)g(:)h(:)f(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)18 b Fc(30)0 1985 y(Filesystem)d(t)o(yp)q(e;)e(error)t +Fb(:)6 b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(31)0 +2030 y(Filesystem)e(t)o(yp)q(e;)e(host)d Fb(:)c(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)22 b Fc(26)0 2076 y(Filesystem)15 b(t)o(yp)q(e;)e(inherit)6 +b Fb(:)i(:)e(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b Fc(32)0 2122 y(Filesystem)c(t)o +(yp)q(e;)e(linkx)s Fb(:)8 b(:)e(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)16 +b Fc(29)0 2167 y(Filesystem)f(t)o(yp)q(e;)e(link)5 b Fb(:)j(:)e(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)17 b Fc(29)0 2213 y(Filesystem)e(t)o(yp)q(e;)e +(nfsx)e Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)23 b +Fc(27)0 2259 y(Filesystem)15 b(t)o(yp)q(e;)e(nfs)t Fb(:)6 b(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)16 b Fc(26)0 2304 y(Filesystem)f(t)o(yp)q(e;)e +(program)8 b Fb(:)f(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)21 b Fc(28)0 2350 +y(Filesystem)15 b(t)o(yp)q(e;)e(ro)q(ot)d Fb(:)c(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)23 b Fc(31)0 2396 y(Filesystem)15 b(t)o(yp)q(e;)e(toplvl)5 +b Fb(:)j(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)17 b Fc(31)0 2441 +y(Filesystem)e(t)o(yp)q(e;)e(ufs)t Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)16 b Fc(28)0 2487 y(Filesystem)f(t)o(yp)q(e;)e(union)6 +b Fb(:)i(:)e(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)19 b Fc(31)0 2533 +y(Filesystem)c(t)o(yp)q(es)6 b Fb(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)19 b Fc(26)0 2578 y(Filesystem)7 b Fb(:)h(:)e(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)19 +b Fc(5)0 2624 y(Flat)14 b(\014le)g(maps)t Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(11)1015 +158 y(Flushing)f(the)d(map)h(cac)o(he)6 b Fb(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)19 b Fc(35)1015 204 y(F)m(orcing)c(\014lesystem)f(to)f(time)g(out)5 +b Fb(:)i(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)18 b Fc(37)1015 250 y(freq,)13 b(FSinfo)h(\014lesystems)h +(option)e Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)25 b Fc(43)1015 295 y(fs,)13 b(moun)o(t)g(option)7 +b Fb(:)h(:)e(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)21 +b Fc(18)1015 341 y(FSinfo)15 b(arc)o(h)e(host)g(attribute)s +Fb(:)8 b(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)16 b Fc(41)1015 387 y(FSinfo)f(automoun)o(t)f +(de\014nitions)s Fb(:)9 b(:)d(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)16 b Fc(45)1015 432 y(FSinfo)f(cluster)f +(host)f(attribute)c Fb(:)e(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)22 b Fc(41)1015 478 y(FSinfo)15 +b(command)f(line)g(options)f Fb(:)6 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)24 b Fc(47)1015 +524 y(FSinfo)15 b(con\014g)f(host)f(attribute)7 b Fb(:)g(:)f(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)20 +b Fc(40)1015 569 y(FSinfo)15 b(dumpset)f(\014lesystems)g(option)f +Fb(:)6 b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)25 +b Fc(44)1015 615 y(FSinfo)15 b(error)e(messages)6 b Fb(:)g(:)g(:)g(:)h(:)f(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)19 b Fc(49)1015 661 y(FSinfo)c(\014lesystems)t +Fb(:)8 b(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)17 +b Fc(41)1015 706 y(FSinfo)e(freq)e(\014lesystems)h(option)8 +b Fb(:)g(:)e(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)22 b Fc(43)1015 752 y(FSinfo)15 b(fst)o(yp)q(e)e +(\014lesystems)h(option)7 b Fb(:)h(:)e(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)20 b Fc(43)1015 798 y(FSinfo)15 +b(grammar)9 b Fb(:)d(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)22 b Fc(39)1015 843 y(FSinfo)15 b(host)e(attributes)t Fb(:)7 +b(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(39)1015 889 +y(FSinfo)e(host)e(de\014nitions)8 b Fb(:)h(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:) +f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:) +21 b Fc(39)1015 935 y(FSinfo)15 b(log)e(\014lesystems)i(option)7 +b Fb(:)h(:)e(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)21 b Fc(45)1015 980 y(FSinfo)15 b(moun)o(t)e +(\014lesystems)i(option)t Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(44)1015 1026 y(FSinfo)e(opts)e +(\014lesystems)i(option)5 b Fb(:)i(:)f(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)18 b Fc(43)1015 1072 +y(FSinfo)d(os)e(host)g(attribute)5 b Fb(:)i(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 +b Fc(41)1015 1117 y(FSinfo)d(o)o(v)o(erview)t Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(38)1015 1163 +y(FSinfo)e(passno)f(\014lesystems)g(option)e Fb(:)6 b(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)24 b Fc(43)1015 +1209 y(FSinfo)15 b(static)e(moun)o(ts)5 b Fb(:)j(:)e(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)19 b Fc(45)1015 1254 y(FSinfo)6 b Fb(:)i(:)e(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)19 b Fc(38)1015 1300 y(fstab,)13 b(FSinfo)h(pre\014x)e Fb(:)6 +b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)23 b Fc(48)1015 +1346 y(fst)o(yp)q(e,)13 b(FSinfo)i(\014lesystems)f(option)e +Fb(:)6 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)24 b Fc(43)1015 1391 y(Generic)15 b(v)o(olume)f(name)7 b +Fb(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)20 b Fc(56)1015 +1437 y(Global)15 b(statistics)d Fb(:)6 b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)23 b Fc(36)1015 1483 y(Grammar,)14 b(FSinfo)7 +b Fb(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)20 +b Fc(39)1015 1528 y(Hesio)q(d)15 b(maps)5 b Fb(:)h(:)g(:)g(:)h(:)f(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)18 b Fc(13)1015 +1574 y(Home)13 b(directories)t Fb(:)c(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)18 b Fc(54)1015 1620 y(host,)c(\014lesystem)g(t)o(yp)q(e)8 +b Fb(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)21 b Fc(26)1015 +1665 y(host,)14 b(moun)o(t)f(selector)e Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)23 b Fc(17)1015 1711 y(hostd,)14 b(moun)o(t)f(selector)8 +b Fb(:)f(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)21 b Fc(17)1015 +1757 y(Hostname)14 b(normalisation)f Fb(:)6 b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)23 +b Fc(22)1015 1802 y(hostname,)14 b(FSinfo)g(command)g(line)h(option)t +Fb(:)7 b(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b +Fc(48)1015 1848 y(Ho)o(w)c(k)o(eys)g(are)h(lo)q(ok)o(ed)g(up)6 +b Fb(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)19 b Fc(14)1015 1893 +y(Ho)o(w)13 b(lo)q(cations)i(are)e(parsed)s Fb(:)8 b(:)e(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)17 b Fc(14)1015 1939 y(Ho)o(w)c(to)g(access)g(en)o(vironmen)o(t)i(v)n +(ariables)h(in)d(maps)5 b Fb(:)i(:)f(:)g(:)g(:)g(:)g(:)18 b +Fc(15)1015 1985 y(Ho)o(w)13 b(to)g(disco)o(v)o(er)h(y)o(our)g(v)o(ersion)g +(of)f(Amd)t Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 +b Fc(23)1015 2030 y(Ho)o(w)13 b(to)g(moun)o(t)g(a)g(lo)q(cal)i(disk)9 +b Fb(:)e(:)f(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)22 b Fc(28)1015 2076 y(Ho)o(w)13 +b(to)g(moun)o(t)g(a)g(UFS)g(\014lesystems)6 b Fb(:)i(:)e(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b Fc(28)1015 +2122 y(Ho)o(w)13 b(to)g(moun)o(t)g(all)i(NFS)e(exp)q(orted)h(\014lesystems)9 +b Fb(:)f(:)e(:)g(:)g(:)g(:)g(:)g(:)22 b Fc(26)1015 2167 y(Ho)o(w)12 +b(to)g(moun)o(t)h(an)f(atomic)h(group)g(of)f(NFS)g(\014lesystems)5 +b Fb(:)j(:)17 b Fc(27)1015 2213 y(Ho)o(w)c(to)g(moun)o(t)g(and)h(NFS)f +(\014lesystem)c Fb(:)f(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:) +g(:)g(:)22 b Fc(26)1015 2259 y(Ho)o(w)13 b(to)g(reference)g(an)g(existing)j +(part)d(of)g(the)g(lo)q(cal)h(name)1092 2304 y(space)f Fb(:)6 +b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)25 b Fc(29)1015 2350 y(Ho)o(w)13 b(to)g(reference)g(part)g(of)g(the)g +(lo)q(cal)i(name)e(space)8 b Fb(:)f(:)f(:)g(:)g(:)g(:)21 b +Fc(29)1015 2396 y(Ho)o(w)13 b(to)g(select)h(log)g(messages)6 +b Fb(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)19 b Fc(23)1015 2441 y(Ho)o(w)13 +b(to)g(set)g(default)h(map)f(parameters)f Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:) +h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)24 b Fc(15)1015 2487 y(Ho)o(w)13 +b(to)g(set)g(map)g(cac)o(he)h(parameters)6 b Fb(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(29)1015 +2533 y(Ho)o(w)13 b(to)g(start)g(a)g(direct)h(automoun)o(t)g(p)q(oin)o(t)9 +b Fb(:)e(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)22 b +Fc(30)1015 2578 y(Ho)o(w)13 b(to)g(start)g(an)g(indirect)i(automoun)o(t)f(p)q +(oin)o(t)8 b Fb(:)g(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)21 b +Fc(29)1015 2624 y(Ho)o(w)13 b(v)n(ariables)i(are)e(expanded)5 +b Fb(:)j(:)e(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)18 b Fc(15)p eop +%%Page: 55 57 +55 56 bop 0 -83 a Fo(Index)1613 b(SMM:13-55)0 158 y Fc(inherit,)14 +b(\014lesystem)h(t)o(yp)q(e)5 b Fb(:)i(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 +b Fc(32)0 204 y(Inheritance)d(\014lesystem)6 b Fb(:)h(:)f(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)19 b Fc(32)0 250 y(In)o(terv)n(al)14 b(b)q(efore)f(a)g +(\014lesystem)i(times)e(out)5 b Fb(:)i(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)18 b Fc(21)0 295 y(In)o(tro)q(duction)8 b Fb(:)g(:)e(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)20 +b Fc(4)0 341 y(k)n(arc)o(h,)13 b(moun)o(t)h(selector)9 b Fb(:)e(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)21 b Fc(17)0 387 y(Keep-aliv)o(es)11 +b Fb(:)c(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)22 b Fc(7)0 432 y(Key)13 b(lo)q(okup)7 b Fb(:)h(:)e(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 +b Fc(14)0 478 y(k)o(ey)m(,)13 b(moun)o(t)g(selector)e Fb(:)6 +b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)23 b Fc(17)0 +524 y(License)14 b(Information)6 b Fb(:)i(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)18 b Fc(2)0 569 y(link,)c(\014lesystem)h(t)o(yp)q(e)s +Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)16 b +Fc(29)0 615 y(linkx,)f(\014lesystem)f(t)o(yp)q(e)d Fb(:)6 b(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)23 b Fc(29)0 661 y(Listing)15 b(curren)o(tly)f(moun)o +(ted)g(\014lesystems)e Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)23 b Fc(34)0 706 y(Lo)q(cation)14 b(format)d Fb(:)6 +b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)23 +b Fc(14)0 752 y(Lo)q(cation)14 b(lists)8 b Fb(:)h(:)d(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)21 b Fc(6)0 +798 y(Log)13 b(\014lename)5 b Fb(:)j(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b Fc(22)0 843 y(Log)13 +b(message)h(selection)6 b Fb(:)i(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)18 +b Fc(23)0 889 y(log,)c(FSinfo)g(\014lesystems)g(option)e Fb(:)6 +b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)23 b Fc(45)0 935 y(Lo)q(oking)15 b(up)e(k)o(eys)c Fb(:)e(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)21 b Fc(14)0 +980 y(Mac)o(hine)15 b(arc)o(hitecture)f(names)6 b Fb(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)18 +b Fc(9)0 1026 y(Mac)o(hine)d(arc)o(hitectures)f(supp)q(orted)h(b)o(y)e(Amd)s +Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)16 b Fc(9)0 +1072 y(Mailing)g(list)9 b Fb(:)e(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)21 b Fc(3)0 1117 y(Map)14 +b(cac)o(he)f(options)6 b Fb(:)i(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)19 b Fc(29)0 1163 y(Map)14 b(cac)o(he)f(sync)o(hronising)6 +b Fb(:)j(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b Fc(29)0 1209 y(Map)c(cac)o(he)f(t)o +(yp)q(es)6 b Fb(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)18 b Fc(29)0 1254 y(Map)c(cac)o(he,)f(\015ushing)5 b Fb(:)j(:)e(:)g(:)g(:) +g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b Fc(35)0 1300 y(Map)c(defaults)d +Fb(:)6 b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)23 b Fc(15)0 1346 y(Map)14 b(en)o(try)f(format)t Fb(:)6 +b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b +Fc(14)0 1391 y(Map)d(lo)q(okup)f Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)24 b Fc(14)0 1437 y(Map)14 +b(options)7 b Fb(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)19 b Fc(17)0 1483 y(Map)14 b(t)o(yp)q(es)6 +b Fb(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)19 b Fc(11)0 1528 y(map,)13 b(moun)o(t)h(selector)9 +b Fb(:)e(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)22 b Fc(17)0 +1574 y(maps,)13 b(FSinfo)h(command)g(line)h(option)6 b Fb(:)h(:)f(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b Fc(48)0 +1620 y(Moun)o(t)14 b(a)f(\014lesystem)h(under)g(program)g(con)o(trol)t +Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(28)0 1665 +y(Moun)o(t)d(home)f(directories)6 b Fb(:)i(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 +b Fc(54)0 1711 y(Moun)o(t)14 b(information)t Fb(:)8 b(:)e(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)16 b Fc(11)0 1757 y(Moun)o(t)e(map)f(t)o(yp)q(es)6 +b Fb(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)18 +b Fc(11)0 1802 y(Moun)o(t)c(maps)6 b Fb(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b Fc(11)0 1848 +y(Moun)o(t)14 b(option;)g(cac)o(he)8 b Fb(:)e(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)21 b Fc(29)0 1893 y(Moun)o(t)14 b(option;)g(dela)o(y)d +Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)22 b Fc(18)0 +1939 y(Moun)o(t)14 b(option;)g(dev)7 b Fb(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)20 b Fc(28)0 1985 y(Moun)o(t)14 b(option;)g(fs)6 +b Fb(:)f(:)h(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)18 +b Fc(18)0 2030 y(Moun)o(t)c(option;)g(moun)o(t)8 b Fb(:)f(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)21 b Fc(28)0 2076 y(Moun)o(t)14 b(option;)g(opts)c +Fb(:)c(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)22 b Fc(18)0 +2122 y(Moun)o(t)14 b(option;)g(remopts)e Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)24 b Fc(19)0 2167 y(Moun)o(t)14 b(option;)g(rfs)7 b Fb(:)e(:)i(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)19 b Fc(26)0 2213 y(Moun)o(t)14 +b(option;)g(rhost)d Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)23 +b Fc(26)0 2259 y(Moun)o(t)14 b(option;)g(sublink)e Fb(:)7 b(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)23 b Fc(20)0 2304 y(Moun)o(t)14 b(option;)g(t)o(yp)q(e)8 +b Fb(:)e(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)21 b +Fc(20)0 2350 y(Moun)o(t)14 b(option;)g(unmoun)o(t)t Fb(:)7 +b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)16 b Fc(28)0 2396 y(Moun)o(t)e(retries)7 +b Fb(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)20 b Fc(6)0 2441 y(Moun)o(t)14 b(selector;)f(arc)o(h)8 +b Fb(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)20 b Fc(16)0 +2487 y(Moun)o(t)14 b(selector;)f(auto)q(dir)8 b Fb(:)g(:)e(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)20 b Fc(16)0 2533 y(Moun)o(t)14 b(selector;)f(b)o(yte)7 +b Fb(:)g(:)f(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(16)0 +2578 y(Moun)o(t)14 b(selector;)f(cluster)5 b Fb(:)j(:)e(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)18 b Fc(17)0 2624 y(Moun)o(t)c(selector;)f(domain)7 +b Fb(:)h(:)e(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(17)1015 158 +y(Moun)o(t)14 b(selector;)g(hostd)6 b Fb(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)19 b Fc(17)1015 204 y(Moun)o(t)14 b(selector;)g(host)8 +b Fb(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)21 b Fc(17)1015 +250 y(Moun)o(t)14 b(selector;)g(k)n(arc)o(h)7 b Fb(:)g(:)f(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)20 b Fc(17)1015 295 y(Moun)o(t)14 b(selector;)g(k)o(ey)7 +b Fb(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b +Fc(17)1015 341 y(Moun)o(t)14 b(selector;)g(map)7 b Fb(:)g(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)20 b Fc(17)1015 387 y(Moun)o(t)14 b(selector;)g(os)9 +b Fb(:)d(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)22 +b Fc(17)1015 432 y(Moun)o(t)14 b(selector;)g(path)5 b Fb(:)i(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)18 b Fc(17)1015 478 y(Moun)o(t)c(selector;)g(wire) +8 b Fb(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)21 b Fc(17)1015 +524 y(moun)o(t)14 b(system)f(call)i(\015ags)9 b Fb(:)e(:)f(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)22 b Fc(18)1015 569 y(moun)o(t)14 b(system)f(call)f +Fb(:)6 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)24 +b Fc(18)1015 615 y(Moun)o(t)14 b(t)o(yp)q(es)6 b Fb(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b +Fc(26)1015 661 y(moun)o(t,)14 b(FSinfo)g(\014lesystems)g(option)7 +b Fb(:)h(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)20 b Fc(44)1015 706 y(moun)o(t,)14 b(moun)o(t)f(option)e +Fb(:)6 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)23 b Fc(28)1015 +752 y(Moun)o(ting)15 b(a)e(lo)q(cal)i(disk)6 b Fb(:)i(:)e(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)19 b Fc(28)1015 798 y(Moun)o(ting)c(a)e(UFS)g(\014lesystem)g +Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)24 b Fc(28)1015 843 y(Moun)o(ting)15 +b(a)e(v)o(olume)e Fb(:)6 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +23 b Fc(6)1015 889 y(Moun)o(ting)15 b(an)f(atomic)g(group)f(of)g(NFS)g +(\014lesystems)7 b Fb(:)h(:)e(:)g(:)g(:)g(:)20 b Fc(27)1015 +935 y(Moun)o(ting)15 b(an)e(existing)i(part)e(of)g(the)g(lo)q(cal)i(name)e +(space)5 b Fb(:)i(:)18 b Fc(29)1015 980 y(Moun)o(ting)d(an)f(NFS)f +(\014lesystem)8 b Fb(:)g(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)22 b Fc(26)1015 1026 y(Moun)o(ting)15 +b(en)o(tire)f(exp)q(ort)g(trees)7 b Fb(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(26)1015 +1072 y(Moun)o(ting)15 b(part)f(of)e(the)i(lo)q(cal)g(name)g(space)8 +b Fb(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)22 b +Fc(29)1015 1117 y(Moun)o(ting)15 b(user)f(\014lesystems)5 b +Fb(:)j(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b Fc(53)1015 1163 y(Multiple-thre)q(aded)d +(serv)o(er)9 b Fb(:)e(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)22 b Fc(8)1015 +1209 y(Namespace)12 b Fb(:)6 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)24 b Fc(6)1015 1254 y(ndbm)14 +b(maps)5 b Fb(:)i(:)f(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)18 b Fc(12)1015 1300 y(Net)o(w)o(ork)13 +b(\014lesystem)i(group)10 b Fb(:)c(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)23 +b Fc(27)1015 1346 y(Net)o(w)o(ork)13 b(host)h(\014lesystem)5 +b Fb(:)j(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b Fc(26)1015 1391 +y(Net)o(w)o(ork-wide)14 b(naming)6 b Fb(:)i(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)19 b Fc(5)1015 1437 y(NFS)13 b(ping)7 b Fb(:)h(:)e(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)20 +b Fc(7)1015 1483 y(nfs,)13 b(\014lesystem)i(t)o(yp)q(e)c Fb(:)6 +b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)24 b Fc(26)1015 +1528 y(nfsx,)13 b(\014lesystem)i(t)o(yp)q(e)9 b Fb(:)e(:)f(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)22 b Fc(27)1015 1574 y(NFS)6 b Fb(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)19 b Fc(26)1015 1620 y(NIS)13 b(\(YP\))g(domain)h(name)5 +b Fb(:)j(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b Fc(24)1015 1665 +y(NIS)13 b(\(YP\))g(maps)6 b Fb(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(12)1015 1711 y(No)q(des)14 b(generated)g(on)f +(a)g(restart)5 b Fb(:)i(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)18 b Fc(32)1015 1757 y(Non-blo)q(c)o(king) +e(op)q(eration)c Fb(:)6 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)23 +b Fc(8)1015 1802 y(Normalising)16 b(hostnames)c Fb(:)6 b(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)24 b Fc(22)1015 1848 y(Obtaining)16 b(the)d(source)h(co)q(de)s +Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(3)1015 1893 y(Op)q(erating)e +(system)e(names)8 b Fb(:)f(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)21 +b Fc(9)1015 1939 y(Op)q(erating)15 b(systems)e(supp)q(orted)i(b)o(y)e(Amd)6 +b Fb(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 +b Fc(9)1015 1985 y(Op)q(erational)d(principles)t Fb(:)9 b(:)d(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)16 b Fc(6)1015 2030 y(opts,)e(FSinfo)g(\014lesystems)g +(option)8 b Fb(:)g(:)e(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)22 b Fc(43)1015 2076 y(opts,)14 b(moun)o(t)f(option)g +Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)24 b +Fc(18)1015 2122 y(os,)13 b(FSinfo)h(host)g(attribute)8 b Fb(:)f(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)21 b Fc(41)1015 2167 y(os,)13 b(moun)o(t)h(selector)e +Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)24 +b Fc(17)1015 2213 y(Ov)o(erriding)16 b(defaults)e(on)f(the)g(command)h(line)6 +b Fb(:)i(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b Fc(21)1015 +2259 y(Ov)o(erriding)d(the)d(default)h(moun)o(t)f(p)q(oin)o(t)f +Fb(:)6 b(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)24 +b Fc(18)1015 2304 y(Ov)o(erriding)16 b(the)d(lo)q(cal)h(domain)h(name)t +Fb(:)6 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 +b Fc(21)1015 2350 y(Ov)o(erriding)f(the)d(NIS)g(\(YP\))f(domain)j(name)t +Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b +Fc(24)1015 2396 y(P)o(assing)d(parameters)f(to)f(the)g(moun)o(t)g(system)h +(call)7 b Fb(:)g(:)g(:)f(:)g(:)g(:)g(:)20 b Fc(18)1015 2441 +y(passno,)14 b(FSinfo)g(\014lesystems)h(option)5 b Fb(:)j(:)e(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)18 b Fc(43)1015 +2487 y(P)o(assw)o(ord)c(\014le)g(maps)t Fb(:)6 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(13)1015 2533 y(path,)d(moun)o(t)f(selector)7 +b Fb(:)g(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(17)1015 +2578 y(P)o(athname)14 b(op)q(erators)e Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)23 b Fc(15)1015 2624 y(Pic)o(king)16 b(up)d(existing)i(moun)o +(ts)d Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)h(:)f(:)24 b Fc(23)p eop +%%Page: 56 58 +56 57 bop 15 -83 a Fo(SMM:13-56)889 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 158 y Fc(pid)d(\014le,)g(creating)g(with)f(-p)g +(option)g Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +h(:)f(:)g(:)g(:)23 b Fc(22)0 204 y(Primary)14 b(serv)o(er)t +Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 +b Fc(18)0 250 y(pro)q(cess)d(id)g(of)e(Amd)h(daemon)8 b Fb(:)f(:)f(:)g(:)g(:) +g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)20 b Fc(22)0 295 y(Pro)q(cess)14 b(id)c Fb(:)c(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)22 b +Fc(22)0 341 y(Program)14 b(\014lesystem)e Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)23 b Fc(28)0 387 y(program,)13 b(\014lesystem)i(t)o(yp)q +(e)7 b Fb(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(28)0 432 y(Querying)15 +b(an)e(alternate)h(host)t Fb(:)7 b(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)17 b Fc(35)0 +478 y(quiet,)d(FSinfo)g(command)g(line)g(option)8 b Fb(:)g(:)e(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)20 b Fc(49)0 524 +y(Referencing)15 b(an)e(existing)i(part)e(of)g(the)g(lo)q(cal)i(name)e(space) +82 569 y Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b Fc(29)0 +615 y(Referencing)d(part)e(of)g(the)g(lo)q(cal)h(name)g(space)8 +b Fb(:)f(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)21 b Fc(29)0 +661 y(Regular)15 b(expressions)g(in)f(maps)d Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)23 +b Fc(29)0 706 y(remopts,)13 b(moun)o(t)h(option)5 b Fb(:)i(:)f(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)17 b Fc(19)0 752 y(Replacemen)o(t)e(v)o(olumes)9 +b Fb(:)e(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)21 b Fc(5)0 +798 y(Replicated)15 b(v)o(olumes)d Fb(:)6 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)23 b Fc(5)0 843 y(Resolving)16 b(aliased)f(hostnames)c +Fb(:)6 b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)23 b Fc(22)0 889 y(Restarting)15 b(existing)g(moun)o(ts)5 +b Fb(:)h(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)17 b Fc(23)0 935 y(rfs,)12 b(moun)o(t)i(option)8 +b Fb(:)g(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)21 +b Fc(26)0 980 y(rhost,)13 b(moun)o(t)h(option)s Fb(:)8 b(:)e(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)16 b Fc(26)0 1026 y(Ro)q(ot)d(\014lesystem)8 +b Fb(:)g(:)e(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)21 +b Fc(31)0 1072 y(ro)q(ot,)13 b(\014lesystem)h(t)o(yp)q(e)9 +b Fb(:)e(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)21 b Fc(31)0 +1117 y(RPC)13 b(retries)t Fb(:)7 b(:)f(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(8)0 1163 y(Run-time)d +(administration)7 b Fb(:)i(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:) +f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b Fc(33)0 +1209 y(rwho)13 b(serv)o(ers)7 b Fb(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(56)0 1254 y(Secondary)15 +b(serv)o(er)t Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:) +f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)17 b Fc(18)0 1300 y(sel,)c(FSinfo)h(moun)o(t)g(option)6 +b Fb(:)i(:)e(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)19 b Fc(44)0 1346 y(Selecting)c(sp)q +(eci\014c)g(log)f(messages)s Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)16 b Fc(23)0 1391 +y(Selector;)e(arc)o(h)7 b Fb(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)19 b Fc(16)0 1437 y(Selector;)14 +b(auto)q(dir)7 b Fb(:)g(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)19 b Fc(16)0 1483 y(Selector;)14 b(b)o(yte)6 b Fb(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b +Fc(16)0 1528 y(Selector;)14 b(cluster)t Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(17)0 1574 y(Selector;)d(domain)6 +b Fb(:)i(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)19 +b Fc(17)0 1620 y(Selector;)14 b(hostd)5 b Fb(:)i(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b Fc(17)0 1665 y(Selector;)c(host)7 +b Fb(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)20 b Fc(17)0 1711 y(Selector;)14 b(k)n(arc)o(h)6 b Fb(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b Fc(17)0 +1757 y(Selector;)14 b(k)o(ey)6 b Fb(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)18 b Fc(17)0 1802 y(Selector;)c(map)6 +b Fb(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)19 b Fc(17)0 1848 y(Selector;)14 b(os)8 b Fb(:)f(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)21 b +Fc(17)0 1893 y(Selector;)14 b(path)t Fb(:)7 b(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(17)0 1939 y(Selector;)d(wire)7 +b Fb(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)20 b Fc(17)0 1985 y(Selectors)t Fb(:)8 b(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 +b Fc(16)0 2030 y(Serv)o(er)d(crashes)e Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)24 b Fc(7)0 2076 +y(Setting)14 b(a)f(dela)o(y)i(on)e(a)g(moun)o(t)g(lo)q(cation)6 +b Fb(:)j(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)19 +b Fc(18)0 2122 y(Setting)14 b(Amd's)f(RPC)g(parameters)7 b +Fb(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)20 b Fc(23)0 2167 y(Setting)14 b(debug)g(\015ags)f Fb(:)6 +b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)24 b Fc(24)0 +2213 y(Setting)14 b(default)g(map)g(parameters)8 b Fb(:)e(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)20 b +Fc(15)0 2259 y(Setting)14 b(map)g(cac)o(he)f(parameters)s Fb(:)8 +b(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)16 b Fc(29)0 2304 y(Setting)e(map)g(options)e Fb(:)6 +b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)23 b Fc(17)0 2350 +y(Setting)14 b(system)g(moun)o(t)f(options)i(for)e(non-lo)q(cal)i(net)o(w)o +(orks)82 2396 y Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b +Fc(19)0 2441 y(Setting)c(system)g(moun)o(t)f(options)6 b Fb(:)i(:)e(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 +b Fc(18)0 2487 y(Setting)14 b(the)f(cluster)h(name)8 b Fb(:)f(:)f(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)21 b Fc(24)0 2533 y(Setting)14 b(the)f(default)h(moun)o(t)g +(directory)9 b Fb(:)e(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)22 b Fc(21)0 2578 y(Setting)14 b(the)f(\014lesystem)i(t)o(yp)q(e)e(option) +7 b Fb(:)h(:)e(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +20 b Fc(20)0 2624 y(Setting)14 b(the)f(in)o(terv)n(al)i(b)q(efore)e(a)g +(\014lesystem)i(times)f(out)c Fb(:)c(:)g(:)22 b Fc(21)1015 +158 y(Setting)15 b(the)e(in)o(terv)n(al)i(b)q(et)o(w)o(een)e(unmoun)o(t)h +(attempts)e Fb(:)6 b(:)g(:)g(:)25 b Fc(23)1015 204 y(Setting)15 +b(the)e(Kernel)h(arc)o(hitecture)5 b Fb(:)i(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b Fc(22)1015 +250 y(Setting)d(the)e(lo)q(cal)i(domain)f(name)8 b Fb(:)f(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)21 +b Fc(21)1015 295 y(Setting)15 b(the)e(lo)q(cal)i(moun)o(t)e(p)q(oin)o(t)8 +b Fb(:)g(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)22 b Fc(18)1015 341 y(Setting)15 b(the)e(log)h(\014le)8 +b Fb(:)f(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)22 +b Fc(22)1015 387 y(Setting)15 b(the)e(NIS)g(\(YP\))f(domain)j(name)9 +b Fb(:)d(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)22 +b Fc(24)1015 432 y(Setting)15 b(the)e(sublink)i(option)s Fb(:)9 +b(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(20)1015 478 y(Sharing)e(a)e(\014leserv)o(er)i +(b)q(et)o(w)o(een)e(arc)o(hitectures)g Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)24 b Fc(55)1015 524 y(SIGHUP)13 b(signal)8 b Fb(:)h(:)d(:)g(:)g(:)g(:) +g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)22 b Fc(29)1015 +569 y(SIGINT)13 b(signal)7 b Fb(:)h(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(34)1015 615 y(SIGTERM)14 +b(signal)9 b Fb(:)f(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)22 +b Fc(34)1015 661 y(Source)14 b(co)q(de)g(distribution)g Fb(:)6 +b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)24 b Fc(3)1015 706 y(Starting)15 +b(Amd)5 b Fb(:)h(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)18 b Fc(33)1015 752 y(Statically)e(moun)o(ts)e(\014lesystems,)g +(FSinfo)7 b Fb(:)h(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)20 +b Fc(45)1015 798 y(Statistics)12 b Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)23 b +Fc(36)1015 843 y(Stopping)16 b(Amd)7 b Fb(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(34)1015 889 y(Stripping)c(the)d +(lo)q(cal)i(domain)f(name)7 b Fb(:)g(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(15)1015 935 y(sublink,)c(moun)o(t)d +(option)g Fb(:)6 b(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)25 b Fc(20)1015 +980 y(sublink)13 b Fb(:)6 b(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)23 b Fc(5)1015 +1026 y(Supp)q(orted)15 b(mac)o(hine)g(arc)o(hitectures)8 b +Fb(:)f(:)f(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)21 b Fc(9)1015 1072 y(Supp)q(orted)15 b(op)q(erating)g(systems)5 +b Fb(:)i(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)18 b Fc(9)1015 1117 y(Sym)o(b)q(olic)e(link)f +(\014lesystem)f(I)q(I)8 b Fb(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)21 b Fc(29)1015 +1163 y(Sym)o(b)q(olic)16 b(link)f(\014lesystem)s Fb(:)8 b(:)e(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)17 b Fc(29)1015 1209 y(symlink,)e(link)g(\014lesystem)f(t)o(yp)q +(e)9 b Fb(:)e(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)22 b Fc(29)1015 1254 y(symlink,)15 b(linkx)g +(\014lesystem)g(t)o(yp)q(e)7 b Fb(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)20 b Fc(29)1015 +1300 y(Sync)o(hronisi)q(ng)c(the)d(map)h(cac)o(he)5 b Fb(:)h(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 +b Fc(29)1015 1346 y(syslog)d(priorities)6 b Fb(:)j(:)d(:)g(:)g(:)g(:)g(:)h(:) +f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b Fc(23)1015 1391 y(syslog)13 +b Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)24 b Fc(22)1015 1437 y(The)13 +b(moun)o(t)h(system)f(call)5 b Fb(:)j(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)18 +b Fc(18)1015 1483 y(T)m(op)13 b(lev)o(el)i(\014lesystem)7 b +Fb(:)h(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)20 b Fc(31)1015 +1528 y(toplvl,)15 b(\014lesystem)f(t)o(yp)q(e)s Fb(:)8 b(:)e(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)17 b Fc(31)1015 1574 y(t)o(yp)q(e,)d(moun)o(t)f(option)e +Fb(:)6 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)23 b +Fc(20)1015 1620 y(T)o(yp)q(es)14 b(of)f(con\014guration)i(map)8 +b Fb(:)f(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)22 b Fc(11)1015 1665 y(T)o(yp)q(es)14 +b(of)f(\014lesystem)f Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:) +24 b Fc(26)1015 1711 y(T)o(yp)q(es)14 b(of)f(moun)o(t)g(map)5 +b Fb(:)h(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b Fc(11)1015 +1757 y(ufs,)13 b(\014lesystem)i(t)o(yp)q(e)c Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)24 b Fc(28)1015 1802 y(UFS)6 b Fb(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)19 b Fc(28)1015 1848 y(Union)c(\014le)e(maps)6 +b Fb(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 +b Fc(13)1015 1893 y(Union)c(\014lesystem)7 b Fb(:)g(:)g(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)20 b Fc(31)1015 1939 y(union,)15 +b(\014lesystem)f(t)o(yp)q(e)5 b Fb(:)i(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:) +f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:) +18 b Fc(31)1015 1985 y(Unix)c(\014lesystem)9 b Fb(:)f(:)e(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)22 b Fc(28)1015 2030 +y(Unix)14 b(namespace)e Fb(:)6 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)23 b Fc(6)1015 2076 y(unmoun)o(t)15 b(attempt)e(bac)o(k)o +(o\013)h(in)o(terv)n(al)8 b Fb(:)g(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:) +f(:)g(:)g(:)g(:)g(:)g(:)21 b Fc(23)1015 2122 y(unmoun)o(t,)14 +b(moun)o(t)g(option)5 b Fb(:)j(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:) +f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)18 +b Fc(28)1015 2167 y(Unmoun)o(ting)d(a)e(\014lesystem)6 b Fb(:)i(:)e(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)19 b Fc(37)1015 2213 y(User)13 b(\014lesystems)t +Fb(:)8 b(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 +b Fc(53)1015 2259 y(User)c(maps,)g(automatic)i(generation)t +Fb(:)8 b(:)e(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)18 b Fc(13)1015 2304 y(Using)c(FSinfo)s Fb(:)8 b(:)e(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)17 b Fc(38)1015 +2350 y(Using)d(syslog)h(to)e(log)h(errors)c Fb(:)c(:)g(:)g(:)g(:)g(:)h(:)f(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)23 +b Fc(22)1015 2396 y(Using)14 b(the)g(passw)o(ord)f(\014le)h(as)f(a)g(map)6 +b Fb(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)19 b Fc(13)1015 2441 y(V)m(ariable)c(expansion)5 b Fb(:)j(:)e(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)18 b Fc(15)1015 2487 y(v)o(erb)q(ose,)c +(FSinfo)g(command)g(line)h(option)t Fb(:)8 b(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)18 b Fc(49)1015 2533 y(V)m(ersion)c(information)h(at)e +(run-time)6 b Fb(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)19 b Fc(37)1015 2578 y(V)m(ersion)14 b(information)6 +b Fb(:)i(:)e(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)19 b +Fc(23)1015 2624 y(v)o(olname,)c(FSinfo)f(moun)o(t)f(option)f +Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g +(:)g(:)g(:)23 b Fc(44)p eop +%%Page: 57 59 +57 58 bop 0 -83 a Fo(Index)1613 b(SMM:13-57)0 158 y Fc(V)m(olume)14 +b(binding)6 b Fb(:)j(:)d(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)19 b Fc(6)0 204 y(V)m(olume)14 b(names)8 b Fb(:)f(:)f(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)21 b +Fc(5)0 250 y(V)m(olume)7 b Fb(:)g(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)20 b +Fc(5)0 295 y(Wildcards)c(in)d(maps)5 b Fb(:)j(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)18 b Fc(14)1015 158 y(wire,)13 b(moun)o(t)h(selector)d +Fb(:)6 b(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g(:)23 b Fc(17)1015 +204 y(YP)13 b(domain)i(name)8 b Fb(:)e(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:) +g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)g(:)g +(:)g(:)g(:)g(:)21 b Fc(24)p eop +%%Page: -1 60 +-1 59 bop 1756 -83 a Fo(SMM:13-i)0 158 y Fm(T)-7 b(able)15 +b(of)g(Con)n(ten)n(ts)0 308 y Fq(Preface)c Fa(:)e(:)i(:)f(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)34 b Fq(1)0 420 y(License)13 b Fa(:)e(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)35 b Fq(1)0 532 y(Source)23 +b(Distribution)15 b Fa(:)d(:)e(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:) +g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)37 b Fq(1)149 594 y Fo(Bug)16 b(Rep)q(orts)e +Fj(:)7 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)28 b Fo(1)149 644 y(Mailing)17 b(List)8 b Fj(:)g(:)f(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)22 +b Fo(2)0 750 y Fq(In)n(tro)r(duction)14 b Fa(:)e(:)e(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)36 +b Fq(2)0 862 y(1)67 b(Ov)n(erview)11 b Fa(:)f(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)33 +b Fq(2)149 925 y Fo(1.1)45 b(F)l(undamen)o(tals)10 b Fj(:)d(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)24 b Fo(2)149 975 y(1.2)45 +b(Filesystems)16 b(and)f(V)l(olumes)10 b Fj(:)e(:)f(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)24 +b Fo(3)149 1024 y(1.3)45 b(V)l(olume)16 b(Naming)9 b Fj(:)e(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)23 b Fo(3)149 1074 y(1.4)45 +b(V)l(olume)16 b(Binding)8 b Fj(:)i(:)d(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)22 b Fo(3)149 1124 y(1.5)45 b(Op)q(erational)16 b(Principles)6 +b Fj(:)k(:)d(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)20 b Fo(3)149 1174 y(1.6)45 +b(Moun)o(ting)15 b(a)g(V)l(olume)e Fj(:)7 b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)26 +b Fo(4)149 1224 y(1.7)45 b(Automatic)15 b(Unmoun)o(ting)e Fj(:)7 +b(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)27 b Fo(4)149 1273 y(1.8)45 b(Keep-aliv)o(es)5 +b Fj(:)10 b(:)d(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)20 b Fo(5)149 1323 y(1.9)45 b(Non-blo)q(c)o(king)17 b(Op)q(eration)10 +b Fj(:)e(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)24 b Fo(5)0 1430 y Fq(2)67 b(Supp)r(orted)24 +b(Platforms)11 b Fa(:)e(:)i(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)33 +b Fq(6)149 1492 y Fo(2.1)45 b(Supp)q(orted)16 b(Op)q(erating)g(Systems)11 +b Fj(:)c(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)25 +b Fo(6)149 1542 y(2.2)45 b(Supp)q(orted)16 b(Mac)o(hine)g(Arc)o(hitectures)6 +b Fj(:)i(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)20 +b Fo(7)0 1648 y Fq(3)67 b(Moun)n(t)23 b(Maps)11 b Fa(:)f(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)34 +b Fq(7)149 1710 y Fo(3.1)45 b(Map)15 b(T)o(yp)q(es)5 b Fj(:)j(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)20 b Fo(7)299 +1760 y(3.1.1)44 b(File)16 b(maps)9 b Fj(:)e(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)23 b Fo(8)299 1810 y(3.1.2)44 b(ndbm)16 b(maps)10 b Fj(:)d(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)24 b Fo(8)299 1859 y(3.1.3)44 b(NIS)16 b(maps)9 +b Fj(:)e(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)23 b Fo(9)299 1909 +y(3.1.4)44 b(Hesio)q(d)16 b(maps)10 b Fj(:)d(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)24 +b Fo(9)299 1959 y(3.1.5)44 b(P)o(assw)o(ord)14 b(maps)f Fj(:)7 +b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)28 b Fo(10)299 2009 y(3.1.6)44 b(Union)16 b(maps)6 b +Fj(:)h(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:) +g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)21 b Fo(10)149 2059 y(3.2)45 b(Ho)o(w)15 +b(k)o(eys)g(are)f(lo)q(ok)o(ed)i(up)c Fj(:)7 b(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:) +g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)26 b +Fo(10)149 2108 y(3.3)45 b(Lo)q(cation)16 b(F)l(ormat)11 b Fj(:)5 +b(:)i(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)25 b Fo(11)299 2158 +y(3.3.1)44 b(Map)15 b(Defaults)c Fj(:)6 b(:)i(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)25 b +Fo(12)299 2208 y(3.3.2)44 b(V)l(ariable)16 b(Expansion)e Fj(:)7 +b(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)28 +b Fo(12)299 2258 y(3.3.3)44 b(Selectors)8 b Fj(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:) +h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)22 b Fo(13)299 2308 y(3.3.4)44 b(Map)15 b(Options)5 +b Fj(:)i(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)19 b Fo(14)448 2357 y(3.3.4.1)44 +b(dela)o(y)15 b(Option)5 b Fj(:)j(:)g(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)20 b Fo(14)448 2407 y(3.3.4.2)44 b(fs)15 b(Option)c +Fj(:)c(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:) +g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:) +25 b Fo(14)448 2457 y(3.3.4.3)44 b(opts)14 b(Option)5 b Fj(:)j(:)g(:)f(:)g(:) +g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)20 b Fo(15)448 +2507 y(3.3.4.4)44 b(remopts)14 b(Option)7 b Fj(:)i(:)e(:)g(:)g(:)h(:)f(:)g(:) +g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)22 b Fo(16)448 2557 y(3.3.4.5)44 b(sublink)17 +b(Option)6 b Fj(:)h(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)20 +b Fo(16)448 2607 y(3.3.4.6)44 b(t)o(yp)q(e)15 b(Option)f Fj(:)7 +b(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)28 +b Fo(16)p eop +%%Page: -2 61 +-2 60 bop 15 -83 a Fo(SMM:13-ii)911 b(4.4)15 b(BSD)g(Automoun)o(ter)f +(Reference)j(Man)o(ual)0 17 y Fq(4)67 b Ff(Amd)24 b Fq(Command)e(Line)h +(Options)6 b Fa(:)11 b(:)f(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:) +g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)29 b Fq(16)149 79 y Fo(4.1)45 +b Fl(-a)15 b Fp(directory)8 b Fj(:)f(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)19 b Fo(17)149 129 y(4.2)45 b Fl(-c)15 b +Fp(cac)o(he-in)o(terv)m(al)c Fj(:)e(:)e(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)24 +b Fo(17)149 178 y(4.3)45 b Fl(-d)15 b Fp(domain)d Fj(:)c(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)27 b Fo(17)149 228 +y(4.4)45 b Fl(-k)15 b Fp(k)o(ernel-arc)o(hitecture)f Fj(:)7 +b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)25 b Fo(17)149 278 y(4.5)45 b Fl(-l)15 b +Fp(log-option)6 b Fj(:)h(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)20 b Fo(18)149 328 y(4.6)45 b Fl(-n)12 b Fj(:)7 b(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)27 +b Fo(18)149 378 y(4.7)45 b Fl(-p)12 b Fj(:)7 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:) +h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)27 +b Fo(18)149 428 y(4.8)45 b Fl(-r)12 b Fj(:)7 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:) +h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)27 +b Fo(18)149 477 y(4.9)45 b Fl(-t)15 b Fp(timeout.retransmit)10 +b Fj(:)c(:)h(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)24 b Fo(18)149 527 y(4.10)45 b Fl(-v)11 +b Fj(:)6 b(:)i(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:) +f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)26 b Fo(19)149 577 y(4.11)45 b Fl(-w)15 +b Fp(w)o(ait-timeout)8 b Fj(:)f(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)22 +b Fo(19)149 627 y(4.12)45 b Fl(-x)15 b Fp(opts)d Fj(:)7 b(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)26 b Fo(19)149 +677 y(4.13)45 b Fl(-y)15 b Fp(NIS-domain)6 b Fj(:)i(:)f(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)20 b Fo(20)149 726 y(4.14)45 b Fl(-C)15 +b Fp(cluster-name)9 b Fj(:)f(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)22 +b Fo(20)149 776 y(4.15)45 b Fl(-D)15 b Fp(opts)d Fj(:)7 b(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)26 b Fo(20)0 +883 y Fq(5)67 b(Filesystem)23 b(T)n(yp)r(es)7 b Fa(:)j(:)h(:)f(:)g(:)g(:)g(:) +h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)30 b Fq(20)149 945 y +Fo(5.1)45 b(Net)o(w)o(ork)14 b(Filesystem)i(\(`)p Fl(type:=nfs)p +Fo('\))7 b Fj(:)e(:)i(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)22 +b Fo(21)149 995 y(5.2)45 b(Net)o(w)o(ork)14 b(Host)g(Filesystem)i(\(`)p +Fl(type:=host)p Fo('\))10 b Fj(:)d(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:) +g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)27 b Fo(21)149 +1045 y(5.3)45 b(Net)o(w)o(ork)14 b(Filesystem)i(Group)f(\(`)p +Fl(type:=nfsx)p Fo('\))5 b Fj(:)t(:)j(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)20 b Fo(22)149 +1094 y(5.4)45 b(Unix)16 b(Filesystem)g(\(`)p Fl(type:=ufs)p +Fo('\))10 b Fj(:)d(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:) +g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:) +27 b Fo(22)149 1144 y(5.5)45 b(Program)14 b(Filesystem)i(\(`)p +Fl(type:=program)p Fo('\))6 b Fj(:)f(:)i(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)22 +b Fo(23)149 1194 y(5.6)45 b(Sym)o(b)q(olic)17 b(Link)f(Filesystem)g(\(`)p +Fl(type:=link)p Fo('\))7 b Fj(:)t(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)21 b Fo(23)149 +1244 y(5.7)45 b(Sym)o(b)q(olic)17 b(Link)f(Filesystem)g(I)q(I)g(\(`)p +Fl(type:=link)p Fo('\))10 b Fj(:)d(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:) +g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)27 b Fo(24)149 1294 +y(5.8)45 b(Automoun)o(t)14 b(Filesystem)i(\(`)p Fl(type:=auto)p +Fo('\))6 b Fj(:)t(:)i(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)20 b Fo(24)149 +1343 y(5.9)45 b(Direct)15 b(Automoun)o(t)g(Filesystem)h(\(`)p +Fl(type:=direct)p Fo('\))10 b Fj(:)d(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)28 b Fo(25)149 1393 y(5.10)45 b(Union)16 +b(Filesystem)g(\(`)p Fl(type:=union)p Fo('\))5 b Fj(:)g(:)i(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)20 b Fo(25)149 1443 y(5.11)45 b(Error)14 +b(Filesystem)i(\(`)p Fl(type:=error)p Fo('\))9 b Fj(:)e(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)27 b Fo(26)149 1493 y(5.12)45 b(T)l(op-lev)o(el)16 +b(Filesystem)g(\(`)p Fl(type:=toplvl)p Fo('\))11 b Fj(:)c(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)29 b Fo(26)149 1543 y(5.13)45 b(Ro)q(ot)15 b(Filesystem)t +Fj(:)8 b(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)19 b Fo(26)149 +1592 y(5.14)45 b(Inheritance)16 b(Filesystem)d Fj(:)7 b(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)27 +b Fo(26)0 1699 y Fq(6)67 b(Run-time)24 b(Administration)6 b +Fa(:)13 b(:)d(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)29 b Fq(27)149 1761 y Fo(6.1)45 +b(Starting)15 b Fp(Amd)c Fj(:)c(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)24 b Fo(27)149 1811 y(6.2)45 b(Stopping)16 b Fp(Amd)e +Fj(:)7 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)26 b +Fo(28)149 1861 y(6.3)45 b(Con)o(trolling)16 b Fp(Amd)10 b Fj(:)d(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)23 b Fo(28)299 1911 y(6.3.1)44 b +Fp(Amq)16 b Fo(default)g(information)9 b Fj(:)e(:)g(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)23 b Fo(28)299 1960 y(6.3.2)44 b Fp(Amq)16 +b Fo(-f)f(option)t Fj(:)8 b(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)19 b Fo(29)299 2010 +y(6.3.3)44 b Fp(Amq)16 b Fo(-h)f(option)9 b Fj(:)f(:)f(:)g(:)g(:)g(:)h(:)f(:) +g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)23 +b Fo(29)299 2060 y(6.3.4)44 b Fp(Amq)16 b Fo(-m)f(option)e +Fj(:)7 b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)27 b Fo(29)299 2110 y(6.3.5)44 b Fp(Amq)16 b +Fo(-M)f(option)10 b Fj(:)e(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:) +g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)25 b Fo(30)299 2160 y(6.3.6)44 +b Fp(Amq)16 b Fo(-s)f(option)e Fj(:)7 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)27 b Fo(30)299 +2209 y(6.3.7)44 b Fp(Amq)16 b Fo(-u)f(option)9 b Fj(:)f(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)23 +b Fo(31)299 2259 y(6.3.8)44 b Fp(Amq)16 b Fo(-v)f(option)9 +b Fj(:)f(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)24 b Fo(31)299 2309 y(6.3.9)44 b(Other)15 +b Fp(Amq)h Fo(options)d Fj(:)7 b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)27 b Fo(31)p eop +%%Page: -3 62 +-3 61 bop 1730 -83 a Fo(SMM:13-iii)0 17 y Fq(7)67 b(FSinfo)11 +b Fa(:)f(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)33 b Fq(31)149 79 +y Fo(7.1)45 b Fp(FSinfo)18 b Fo(o)o(v)o(erview)8 b Fj(:)f(:)g(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)23 b Fo(31)149 129 y(7.2)45 b(Using)16 +b Fp(FSinfo)9 b Fj(:)f(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:) +h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)22 +b Fo(32)149 178 y(7.3)45 b Fp(FSinfo)18 b Fo(grammar)12 b Fj(:)c(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)29 b Fo(32)149 228 y(7.4)45 b Fp(FSinfo)18 +b Fo(host)d(de\014nitions)f Fj(:)7 b(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)27 b Fo(33)149 +278 y(7.5)45 b Fp(FSinfo)18 b Fo(host)d(attributes)8 b Fj(:)e(:)h(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)22 b Fo(33)299 328 y(7.5.1)44 b(netif)16 b(Option)e Fj(:)7 +b(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)28 b Fo(34)299 378 y(7.5.2)44 b(con\014g)15 +b(Option)10 b Fj(:)f(:)e(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)25 b Fo(34)299 428 y(7.5.3)44 +b(arc)o(h)15 b(Option)6 b Fj(:)i(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)21 b +Fo(34)299 477 y(7.5.4)44 b(os)15 b(Option)8 b Fj(:)f(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)23 b Fo(34)299 527 y(7.5.5)44 b(cluster)16 b(Option)d +Fj(:)7 b(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)28 b Fo(35)149 577 y(7.6)45 b Fp(FSinfo)18 +b Fo(\014lesystems)8 b Fj(:)g(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)23 +b Fo(35)299 627 y(7.6.1)44 b(fst)o(yp)q(e)15 b(Option)9 b Fj(:)f(:)f(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)24 b Fo(36)299 677 y(7.6.2)44 b(opts)15 b(Option)6 b Fj(:)i(:)f(:)g(:)h(:) +f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)21 b Fo(37)299 726 y(7.6.3)44 b(passno)15 b(Option)e +Fj(:)7 b(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)27 b Fo(37)299 776 y(7.6.4)44 b(freq)15 +b(Option)10 b Fj(:)e(:)f(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)25 b Fo(37)299 826 +y(7.6.5)44 b(moun)o(t)14 b(Option)5 b Fj(:)j(:)f(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)19 +b Fo(37)299 876 y(7.6.6)44 b(dumpset)15 b(Option)g Fj(:)7 b(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)29 +b Fo(38)299 926 y(7.6.7)44 b(log)15 b(Option)9 b Fj(:)f(:)f(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)24 b Fo(38)149 976 y(7.7)45 b Fp(FSinfo)18 b Fo(static)d(moun)o(ts)10 +b Fj(:)c(:)h(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)24 b Fo(38)149 1025 y(7.8)45 +b(De\014ning)16 b(an)f Fp(Amd)i Fo(Moun)o(t)e(Map)g(in)h Fp(FSinfo)f +Fj(:)7 b(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)27 b Fo(39)149 1075 y(7.9)45 +b Fp(FSinfo)18 b Fo(Command)d(Line)h(Options)6 b Fj(:)i(:)g(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)21 b Fo(40)299 1125 +y(7.9.1)44 b Fl(-a)15 b Fp(auto)q(dir)e Fj(:)7 b(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)24 +b Fo(41)299 1175 y(7.9.2)44 b Fl(-b)15 b Fp(b)q(o)q(otparams)7 +b Fj(:)g(:)g(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)20 b Fo(41)299 1225 y(7.9.3)44 b Fl(-d)15 +b Fp(dumpsets)c Fj(:)c(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:) +g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)24 b Fo(41)299 1274 +y(7.9.4)44 b Fl(-e)15 b Fp(exp)q(ortfs)f Fj(:)7 b(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)27 +b Fo(41)299 1324 y(7.9.5)44 b Fl(-f)15 b Fp(fstab)5 b Fj(:)i(:)g(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)19 b Fo(42)299 1374 y(7.9.6)44 b Fl(-h)15 +b Fp(hostname)10 b Fj(:)d(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)23 b Fo(42)299 1424 +y(7.9.7)44 b Fl(-m)15 b Fp(moun)o(t-maps)c Fj(:)c(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)25 b +Fo(42)299 1474 y(7.9.8)44 b Fl(-q)11 b Fj(:)6 b(:)h(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)25 b Fo(42)299 1523 y(7.9.9)44 +b Fl(-v)11 b Fj(:)6 b(:)h(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)25 b Fo(42)299 1573 y(7.9.10)43 b Fl(-D)15 b Fp(name[=defn])8 +b Fj(:)g(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)21 b Fo(42)299 1623 y(7.9.11)43 b Fl(-I)15 b Fp(directory)h +Fj(:)7 b(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)26 b Fo(42)299 1673 y(7.9.12)43 b Fl(-U)15 +b Fp(name)c Fj(:)c(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:) +g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)23 b Fo(43)149 +1723 y(7.10)45 b(Errors)14 b(pro)q(duced)i(b)o(y)f Fp(FSinfo)e +Fj(:)8 b(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)25 b Fo(43)0 1829 y Fq(8)67 b(Examples)18 b Fa(:)10 b(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)40 +b Fq(45)149 1891 y Fo(8.1)45 b(User)15 b(Filesystems)10 b Fj(:)e(:)g(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)25 b Fo(45)149 1941 y(8.2)45 b(Home)15 +b(Directories)5 b Fj(:)j(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)20 +b Fo(47)149 1991 y(8.3)45 b(Arc)o(hitecture)16 b(Sharing)10 +b Fj(:)e(:)f(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)25 b Fo(48)149 2041 y(8.4)45 +b(Wildcard)16 b(names)f(&)h(Replicated)h(Serv)o(ers)12 b Fj(:)7 +b(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)27 b Fo(48)149 2091 y(8.5)45 +b(`)p Fl(rwho)p Fo(')14 b(serv)o(ers)d Fj(:)c(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)27 b Fo(49)149 2140 y(8.6)45 b(`)p Fl(/vol)p +Fo(')6 b Fj(:)g(:)h(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)g(:)21 b Fo(49)0 2240 y Fq(9)67 b(In)n(ternals)15 +b Fa(:)c(:)f(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)38 b Fq(50)149 2302 y Fo(9.1)45 +b(Log)15 b(Messages)c Fj(:)c(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f +(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h +(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)27 b Fo(50)299 2352 y(9.1.1)44 b(F)l(atal)15 b(errors)10 +b Fj(:)c(:)h(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)25 b Fo(50)299 2402 y(9.1.2)44 +b(Info)15 b(messages)10 b Fj(:)d(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)25 b Fo(52)0 +2508 y Fq(Ac)n(kno)n(wledgemen)n(ts)d(&)h(T)-6 b(rademarks)9 +b Fa(:)h(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g +(:)g(:)h(:)31 b Fq(53)0 2630 y(Index)7 b Fa(:)12 b(:)e(:)g(:)g(:)g(:)h(:)f(:) +g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g +(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)g(:)g +(:)h(:)f(:)g(:)g(:)h(:)f(:)30 b Fq(53)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/usr.sbin/amd/doc/amdref.texinfo b/usr.sbin/amd/doc/amdref.texinfo new file mode 100644 index 0000000..4a6d8e9 --- /dev/null +++ b/usr.sbin/amd/doc/amdref.texinfo @@ -0,0 +1,4554 @@ +\input texinfo @c -*-texinfo-*- +@c +@c Copyright (c) 1989 Jan-Simon Pendry +@c Copyright (c) 1989 Imperial College of Science, Technology & Medicine +@c Copyright (c) 1989 The Regents of the University of California. +@c All rights reserved. +@c +@c This code is derived from software contributed to Berkeley by +@c Jan-Simon Pendry at Imperial College, London. +@c +@c Redistribution and use in source and binary forms, with or without +@c modification, are permitted provided that the following conditions +@c are met: +@c 1. Redistributions of source code must retain the above copyright +@c notice, this list of conditions and the following disclaimer. +@c 2. Redistributions in binary form must reproduce the above copyright +@c notice, this list of conditions and the following disclaimer in the +@c documentation and/or other materials provided with the distribution. +@c 3. All advertising materials mentioning features or use of this software +@c must display the following acknowledgement: +@c This product includes software developed by the University of +@c California, Berkeley and its contributors. +@c 4. Neither the name of the University nor the names of its contributors +@c may be used to endorse or promote products derived from this software +@c without specific prior written permission. +@c +@c THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +@c ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +@c IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +@c ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +@c FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +@c DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +@c OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +@c HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +@c LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +@c OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +@c +@c @(#)amdref.texinfo 8.1 (Berkeley) 6/6/93 +@c +@c $Id: amdref.texinfo,v 5.2.2.1 1992/02/09 15:11:50 jsp beta $ +@c +@setfilename amdref.info +@c @setfilename /usr/local/emacs/info/amd +@tex +\overfullrule=0pt +@end tex + +@settitle 4.4 BSD Automounter Reference Manual +@titlepage +@sp 6 +@center @titlefont{Amd} +@sp 2 +@center @titlefont{The 4.4 BSD Automounter} +@sp 2 +@center @titlefont{Reference Manual} +@sp 2 +@center @authorfont{Jan-Simon Pendry} +@sp +@center @i{and} +@sp +@center @authorfont{Nick Williams} +@sp 4 +@center Last updated March 1991 +@center Documentation for software revision 5.3 Alpha +@page +Copyright @copyright{} 1989 Jan-Simon Pendry +@sp -1 +Copyright @copyright{} 1989 Imperial College of Science, Technology & Medicine +@sp -1 +Copyright @copyright{} 1989 The Regents of the University of California. +@sp 0 +All Rights Reserved. +@vskip 1ex +Permission to copy this document, or any portion of it, as +necessary for use of this software is granted provided this +copyright notice and statement of permission are included. +@end titlepage +@page +@ifinfo +@node Top, License, , (DIR) + +Amd - The 4.4 BSD Automounter +***************************** + +Amd is the 4.4 BSD Automounter. This Info file describes how +to use and understand Amd. +@end ifinfo + +@menu +* License:: Explains the terms and conditions for using + and distributing Amd. +* Distrib:: How to get the latest Amd distribution. +* Intro:: An introduction to Automounting concepts. +* Overview:: An overview of Amd. +* Supported Platforms:: Machines and Systems supported by Amd. +* Mount Maps:: Details of mount maps +* Amd Command Line Options:: All the Amd command line options explained. +* Filesystem Types:: The different mount types supported by Amd. +* Run-time Administration:: How to start, stop and control Amd. +* FSinfo:: The FSinfo filesystem management tool. +* Internals:: Internals. +* Acknowledgements & Trademarks:: Legal notes. +* Examples:: Some examples showing how Amd might be used. +* Internals:: Implementation details. +* Acknowledgements & Trademarks:: + +Indexes +* Index:: An item for each concept. +@end menu + +@iftex +@unnumbered Preface + +This manual documents the use of the 4.4 BSD automounter---@i{Amd}. +This is primarily a reference manual. Unfortunately, no tutorial +exists. + +This manual comes in two forms: the published form and the Info form. +The Info form is for on-line perusal with the INFO program which is +distributed along with GNU Emacs. Both forms contain substantially the +same text and are generated from a common source file, which is +distributed with the @i{Amd} source. +@end iftex + +@node License, Distrib, Top, Top +@unnumbered License +@cindex License Information + +@i{Amd} is not in the public domain; it is copyrighted and there are +restrictions on its distribution. + +Redistribution and use in source and binary forms are permitted provided +that: (1) source distributions retain this entire copyright notice and +comment, and (2) distributions including binaries display the following +acknowledgement: ``This product includes software developed by The +University of California, Berkeley and its Contributors'' in the +documentation or other materials provided with the distribution and in +all advertising materials mentioning features or use of this software. +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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +@node Distrib, Intro, License, Top +@unnumbered Source Distribution +@cindex Source code distribution +@cindex Obtaining the source code + +If you have access to the Internet, you can get the latest distribution +version of @i{Amd} from host @file{usc.edu} using anonymous FTP. Move to +the directory @file{/pub/amd} on that host and fetch the file @file{amd.tar.Z}. + +If you are in the UK, you can get the latest distribution version of +@i{Amd} from the UKnet info-server. Start by sending email to +@file{info-server@@doc.ic.ac.uk}. + +Sites on the UK JANET network can get the latest distribution by using +anonymous NIFTP to fetch the file @samp{amd.tar.Z} from host +@samp{uk.ac.imperial.doc.src}. + +Revision 5.2 was part of the 4.3 BSD Reno distribution. + +Revision 5.3bsdnet, a late alpha version of 5.3, was part +of the BSD network version 2 distribution + +@unnumberedsec Bug Reports +@cindex Bug reports + +Send all bug reports to @file{jsp@@doc.ic.ac.uk} quoting the details of +the release and your configuration. These can be obtained by running +the command @samp{amd -v}. + +@unnumberedsec Mailing List +@cindex Mailing list + +There is a mailing list for people interested in keeping uptodate with +developments. To subscribe, send a note to @file{amd-workers-request@@acl.lanl.gov}. + +@node Intro, Overview, Distrib, Top +@unnumbered Introduction +@cindex Introduction + +An @dfn{automounter} maintains a cache of mounted filesystems. +Filesystems are mounted on demand when they are first referenced, +and unmounted after a period of inactivity. + +@i{Amd} may be used as a replacement for Sun's automounter. The choice +of which filesystem to mount can be controlled dynamically with +@dfn{selectors}. Selectors allow decisions of the form ``hostname is +@var{this},'' or ``architecture is not @var{that}.'' Selectors may be +combined arbitrarily. @i{Amd} also supports a variety of filesystem +types, including NFS, UFS and the novel @dfn{program} filesystem. The +combination of selectors and multiple filesystem types allows identical +configuration files to be used on all machines so reducing the +administrative overhead. + +@i{Amd} ensures that it will not hang if a remote server goes down. +Moreover, @i{Amd} can determine when a remote server has become +inaccessible and then mount replacement filesystems as and when they +become available. + +@i{Amd} contains no proprietary source code and has been ported to +numerous flavours of Unix. + +@node Overview, Supported Platforms, Intro, Top +@chapter Overview + +@i{Amd} maintains a cache of mounted filesystems. Filesystems are +@dfn{demand-mounted} when they are first referenced, and unmounted after +a period of inactivity. @i{Amd} may be used as a replacement for Sun's +@b{automount}(8) program. It contains no proprietary source code and +has been ported to numerous flavours of Unix. @xref{Supported Operating +Systems}.@refill + +@i{Amd} was designed as the basis for experimenting with filesystem +layout and management. Although @i{Amd} has many direct applications it +is loaded with additional features which have little practical use. At +some point the infrequently used components may be removed to streamline +the production system. + +@c @i{Amd} supports the notion of @dfn{replicated} filesystems by evaluating +@c each member of a list of possible filesystem locations in parallel. +@c @i{Amd} checks that each cached mapping remains valid. Should a mapping be +@c lost -- such as happens when a fileserver goes down -- @i{Amd} automatically +@c selects a replacement should one be available. +@c +@menu +* Fundamentals:: +* Filesystems and Volumes:: +* Volume Naming:: +* Volume Binding:: +* Operational Principles:: +* Mounting a Volume:: +* Automatic Unmounting:: +* Keep-alives:: +* Non-blocking Operation:: +@end menu + +@node Fundamentals, Filesystems and Volumes, Overview, Overview +@comment node-name, next, previous, up +@section Fundamentals +@cindex Automounter fundamentals + +The fundamental concept behind @i{Amd} is the ability to separate the +name used to refer to a file from the name used to refer to its physical +storage location. This allows the same files to be accessed with the +same name regardless of where in the network the name is used. This is +very different from placing @file{/n/hostname} in front of the pathname +since that includes location dependent information which may change if +files are moved to another machine. + +By placing the required mappings in a centrally administered database, +filesystems can be re-organised without requiring changes to +configuration files, shell scripts and so on. + +@node Filesystems and Volumes, Volume Naming, Fundamentals, Overview +@comment node-name, next, previous, up +@section Filesystems and Volumes +@cindex Filesystem +@cindex Volume +@cindex Fileserver +@cindex sublink + +@i{Amd} views the world as a set of fileservers, each containg one or +more filesystems where each filesystem contains one or more +@dfn{volumes}. Here the term @dfn{volume} is used to refer to a +coherent set of files such as a user's home directory or a @TeX{} +distribution.@refill + +In order to access the contents of a volume, @i{Amd} must be told in +which filesystem the volume resides and which host owns the filesystem. +By default the host is assumed to be local and the volume is assumed to +be the entire filesystem. If a filesystem contains more than one +volume, then a @dfn{sublink} is used to refer to the sub-directory +within the filesystem where the volume can be found. + +@node Volume Naming, Volume Binding, Filesystems and Volumes, Overview +@comment node-name, next, previous, up +@section Volume Naming +@cindex Volume names +@cindex Network-wide naming +@cindex Replicated volumes +@cindex Duplicated volumes +@cindex Replacement volumes + +Volume names are defined to be unique across the entire network. A +volume name is the pathname to the volume's root as known by the users +of that volume. Since this name uniquely identifies the volume +contents, all volumes can be named and accessed from each host, subject +to administrative controls. + +Volumes may be replicated or duplicated. Replicated volumes contain +identical copies of the same data and reside at two or more locations in +the network. Each of the replicated volumes can be used +interchangeably. Duplicated volumes each have the same name but contain +different, though functionally identical, data. For example, +@samp{/vol/tex} might be the name of a @TeX{} distribution which varied +for each machine architecture.@refill + +@i{Amd} provides facilities to take advantage of both replicated and +duplicated volumes. Configuration options allow a single set of +configuration data to be shared across an entire network by taking +advantage of replicated and duplicated volumes. + +@i{Amd} can take advantage of replacement volumes by mounting them as +required should an active fileserver become unavailable. + +@node Volume Binding, Operational Principles, Volume Naming, Overview +@comment node-name, next, previous, up +@section Volume Binding +@cindex Volume binding +@cindex Unix namespace +@cindex Namespace +@cindex Binding names to filesystems + +Unix implements a namespace of hierarchically mounted filesystems. Two +forms of binding between names and files are provided. A @dfn{hard +link} completes the binding when the name is added to the filesystem. A +@dfn{soft link} delays the binding until the name is accessed. An +@dfn{automounter} adds a further form in which the binding of name to +filesystem is delayed until the name is accessed.@refill + +The target volume, in its general form, is a tuple (host, filesystem, +sublink) which can be used to name the physical location of any volume +in the network. + +When a target is referenced, @i{Amd} ignores the sublink element and +determines whether the required filesystem is already mounted. This is +done by computing the local mount point for the filesystem and checking +for an existing filesystem mounted at the same place. If such a +filesystem already exists then it is assumed to be functionally +identical to the target filesystem. By default there is a one-to-one +mapping between the pair (host, filesystem) and the local mount point so +this assumption is valid. + +@node Operational Principles, Mounting a Volume, Volume Binding, Overview +@comment node-name, next, previous, up +@section Operational Principles +@cindex Operational principles + +@i{Amd} operates by introducing new mount points into the namespace. +These are called @dfn{automount} points. The kernel sees these +automount points as NFS filesystems being served by @i{Amd}. Having +attached itself to the namespace, @i{Amd} is now able to control the +view the rest of the system has of those mount points. RPC calls are +received from the kernel one at a time. + +When a @dfn{lookup} call is received @i{Amd} checks whether the name is +already known. If it is not, the required volume is mounted. A +symbolic link pointing to the volume root is then returned. Once the +symbolic link is returned, the kernel will send all other requests +direct to the mounted filesystem. + +If a volume is not yet mounted, @i{Amd} consults a configuration +@dfn{mount-map} corresponding to the automount point. @i{Amd} then +makes a runtime decision on what and where to mount a filesystem based +on the information obtained from the map. + +@i{Amd} does not implement all the NFS requests; only those relevant +to name binding such as @dfn{lookup}, @dfn{readlink} and @dfn{readdir}. +Some other calls are also implemented but most simply return an error +code; for example @dfn{mkdir} always returns ``read-only filesystem''. + +@node Mounting a Volume, Automatic Unmounting, Operational Principles, Overview +@comment node-name, next, previous, up +@section Mounting a Volume +@cindex Mounting a volume +@cindex Location lists +@cindex Alternate locations +@cindex Mount retries +@cindex Background mounts + +Each automount point has a corresponding mount map. The mount map +contains a list of key--value pairs. The key is the name of the volume +to be mounted. The value is a list of locations describing where the +filesystem is stored in the network. In the source for the map the +value would look like + +@display +location1 location2 @dots{} locationN +@end display + +@i{Amd} examines each location in turn. Each location may contain +@dfn{selectors} which control whether @i{Amd} can use that location. +For example, the location may be restricted to use by certain hosts. +Those locations which cannot be used are ignored. + +@i{Amd} attempts to mount the filesystem described by each remaining +location until a mount succeeds or @i{Amd} can no longer proceed. The +latter can occur in three ways: + +@itemize @bullet +@item +If none of the locations could be used, or if all of the locations +caused an error, then the last error is returned. + +@item +If a location could be used but was being mounted in the background then +@i{Amd} marks that mount as being ``in progress'' and continues with +the next request; no reply is sent to the kernel. + +@item +Lastly, one or more of the mounts may have been @dfn{deferred}. A mount +is deferred if extra information is required before the mount can +proceed. When the information becomes available the mount will take +place, but in the mean time no reply is sent to the kernel. If the +mount is deferred, @i{Amd} continues to try any remaining locations. +@end itemize + +Once a volume has been mounted, @i{Amd} establishes a @dfn{volume +mapping} which is used to satisfy subsequent requests.@refill + +@node Automatic Unmounting, Keep-alives, Mounting a Volume, Overview +@comment node-name, next, previous, up +@section Automatic Unmounting + +To avoid an ever increasing number of filesystem mounts, @i{Amd} removes +volume mappings which have not been used recently. A time-to-live +interval is associated with each mapping and when that expires the +mapping is removed. When the last reference to a filesystem is removed, +that filesystem is unmounted. If the unmount fails, for example the +filesystem is still busy, the mapping is re-instated and its +time-to-live interval is extended. The global default for this grace +period is controlled by the ``-w'' command-line option (@pxref{-w +Option, -w}). It is also possible to set this value on a per-mount +basis (@pxref{opts Option, opts, opts}).@refill + +Filesystems can be forcefully timed out using the @i{Amq} command. +@xref{Run-time Administration}. + +@node Keep-alives, Non-blocking Operation, Automatic Unmounting, Overview +@comment node-name, next, previous, up +@section Keep-alives +@cindex Keep-alives +@cindex Server crashes +@cindex NFS ping + +Use of some filesystem types requires the presence of a server on +another machine. If a machine crashes then it is of no concern to +processes on that machine that the filesystem is unavailable. However, +to processes on a remote host using that machine as a fileserver this +event is important. This situation is most widely recognised when an +NFS server crashes and the behaviour observed on client machines is that +more and more processes hang. In order to provide the possibility of +recovery, @i{Amd} implements a @dfn{keep-alive} interval timer for some +filesystem types. Currently only NFS makes use of this service. + +The basis of the NFS keep-alive implementation is the observation that +most sites maintain replicated copies of common system data such as +manual pages, most or all programs, system source code and so on. If +one of those servers goes down it would be reasonable to mount one of +the others as a replacement. + +The first part of the process is to keep track of which fileservers are +up and which are down. @i{Amd} does this by sending RPC requests to the +servers' NFS @code{NullProc} and checking whether a reply is returned. +While the server state is uncertain the requests are re-transmitted at +three second intervals and if no reply is received after four attempts +the server is marked down. If a reply is received the fileserver is +marked up and stays in that state for 30 seconds at which time another +NFS ping is sent. + +Once a fileserver is marked down, requests continue to be sent every 30 +seconds in order to determine when the fileserver comes back up. During +this time any reference through @i{Amd} to the filesystems on that +server fail with the error ``Operation would block''. If a replacement +volume is available then it will be mounted, otherwise the error is +returned to the user. + +@c @i{Amd} keeps track of which servers are up and which are down. +@c It does this by sending RPC requests to the servers' NFS {\sc NullProc} and +@c checking whether a reply is returned. If no replies are received after a +@c short period, @i{Amd} marks the fileserver @dfn{down}. +@c RPC requests continue to be sent so that it will notice when a fileserver +@c comes back up. +@c ICMP echo packets \cite{rfc:icmp} are not used because it is the availability +@c of the NFS service that is important, not the existence of a base kernel. +@c Whenever a reference to a fileserver which is down is made via @i{Amd}, an alternate +@c filesystem is mounted if one is available. +@c +Although this action does not protect user files, which are unique on +the network, or processes which do not access files via @i{Amd} or +already have open files on the hung filesystem, it can prevent most new +processes from hanging. + +By default, fileserver state is not maintained for NFS/TCP mounts. The +remote fileserver is always assumed to be up. +@c +@c With a suitable combination of filesystem management and mount-maps, +@c machines can be protected against most server downtime. This can be +@c enhanced by allocating boot-servers dynamically which allows a diskless +@c workstation to be quickly restarted if necessary. Once the root filesystem +@c is mounted, @i{Amd} can be started and allowed to mount the remainder of +@c the filesystem from whichever fileservers are available. + +@node Non-blocking Operation, , Keep-alives, Overview +@comment node-name, next, previous, up +@section Non-blocking Operation +@cindex Non-blocking operation +@cindex Multiple-threaded server +@cindex RPC retries + +Since there is only one instance of @i{Amd} for each automount point, +and usually only one instance on each machine, it is important that it +is always available to service kernel calls. @i{Amd} goes to great +lengths to ensure that it does not block in a system call. As a last +resort @i{Amd} will fork before it attempts a system call that may block +indefinitely, such as mounting an NFS filesystem. Other tasks such as +obtaining filehandle information for an NFS filesystem, are done using a +purpose built non-blocking RPC library which is integrated with +@i{Amd}'s task scheduler. This library is also used to implement NFS +keep-alives (@pxref{Keep-alives}). + +Whenever a mount is deferred or backgrounded, @i{Amd} must wait for it +to complete before replying to the kernel. However, this would cause +@i{Amd} to block waiting for a reply to be constructed. Rather than do +this, @i{Amd} simply @dfn{drops} the call under the assumption that the +kernel RPC mechanism will automatically retry the request. + +@node Supported Platforms, Mount Maps, Overview, Top +@comment node-name, next, previous, up +@chapter Supported Platforms + +@i{Amd} has been ported to a wide variety of machines and operating systems. +The table below lists those platforms supported by the current release. + +@menu +* Supported Operating Systems:: +* Supported Machine Architectures:: +@end menu + +@node Supported Operating Systems, Supported Machine Architectures, Supported Platforms, Supported Platforms +@comment node-name, next, previous, up +@section Supported Operating Systems +@cindex Operating system names +@cindex Operating systems supported by Amd +@cindex Supported operating systems + +The following operating systems are currently supported by @i{Amd}. +@i{Amd}'s conventional name for each system is given. + +@table @code +@item acis43 +4.3 BSD for IBM RT. Contributed by Jan-Simon Pendry @t{} +@item aix3 +AIX 3.1. Contributed by Jan-Simon Pendry @t{} +@item aux +System V for Mac-II. Contributed by Julian Onions @t{} +@item bsd44 +4.4 BSD. Contributed by Jan-Simon Pendry @t{} +@item concentrix +Concentrix 5.0. Contributed by Sjoerd Mullender @t{} +@item convex +Convex OS 7.1. Contributed by Eitan Mizrotsky @t{} +@item dgux +Data General DG/UX. Contributed by Mark Davies @t{} +@item fpx4 +Celerity FPX 4.1/2. Contributed by Stephen Pope @t{} +@item hcx +Harris HCX/UX. Contributed by Chris Metcalf @t{} +@item hlh42 +HLH OTS 1.@i{x} (4.2 BSD). Contributed by Jan-Simon Pendry @t{} +@item hpux +HP-UX 6.@i{x} or 7.0. Contributed by Jan-Simon Pendry @t{} +@item irix +SGI Irix. Contributed by Scott R. Presnell @t{} +@item next +Mach for NeXT. Contributed by Bill Trost @t{} +@item pyrOSx +Pyramid OSx. Contributed by Stefan Petri @t{} +@item riscix +Acorn RISC iX. Contributed by Piete Brooks @t{} +@item sos3 +SunOS 3.4 & 3.5. Contributed by Jan-Simon Pendry @t{} +@item sos4 +SunOS 4.@i{x}. Contributed by Jan-Simon Pendry @t{} +@item u2_2 +Ultrix 2.2. Contributed by Piete Brooks @t{} +@item u3_0 +Ultrix 3. Contributed by Piete Brooks @t{} +@item u4_0 +Ultrix 4.0. Contributed by Chris Lindblad @t{} +@item umax43 +Umax 4.3 BSD. Contributed by Sjoerd Mullender @t{} +@item utek +Utek 4.0. Contributed by Bill Trost @t{} +@item xinu43 +mt Xinu MORE/bsd. Contributed by Jan-Simon Pendry @t{} +@end table + +@node Supported Machine Architectures, , Supported Operating Systems, Supported Platforms +@comment node-name, next, previous, up +@section Supported Machine Architectures +@cindex Supported machine architectures +@cindex Machine architecture names +@cindex Machine architectures supported by Amd + +@table @code +@item alliant +Alliant FX/4 +@item arm +Acorn ARM +@item aviion +Data General AViiON +@item encore +Encore +@item fps500 +FPS Model 500 +@item hp9000 +HP 9000/300 family +@item hp9k8 +HP 9000/800 family +@item ibm032 +IBM RT +@item ibm6000 +IBM RISC System/6000 +@item iris4d +SGI Iris 4D +@item macII +Apple Mac II +@item mips +MIPS RISC +@item multimax +Encore Multimax +@item orion105 +HLH Orion 1/05 +@item sun3 +Sun-3 family +@item sun4 +Sun-4 family +@item tahoe +Tahoe family +@item vax +DEC Vax +@end table + +@node Mount Maps, Amd Command Line Options, Supported Platforms, Top +@comment node-name, next, previous, up +@chapter Mount Maps +@cindex Mount maps +@cindex Automounter configuration maps +@cindex Mount information + +@i{Amd} has no built-in knowledge of machines or filesystems. +External @dfn{mount-maps} are used to provide the required information. +Specifically, @i{Amd} needs to know when and under what conditions it +should mount filesystems. + +The map entry corresponding to the requested name contains a list of +possible locations from which to resolve the request. Each location +specifies filesystem type, information required by that filesystem (for +example the block special device in the case of UFS), and some +information describing where to mount the filesystem (@pxref{fs Option}). A +location may also contain @dfn{selectors} (@pxref{Selectors}).@refill + +@menu +* Map Types:: +* Key Lookup:: +* Location Format:: +@end menu + +@node Map Types, Key Lookup, Mount Maps, Mount Maps +@comment node-name, next, previous, up +@section Map Types +@cindex Mount map types +@cindex Map types +@cindex Configuration map types +@cindex Types of mount map +@cindex Types of configuration map +@cindex Determining the map type + +A mount-map provides the run-time configuration information to @i{Amd}. +Maps can be implemented in many ways. Some of the forms supported by +@i{Amd} are regular files, ndbm databases, NIS maps the @dfn{Hesiod} +name server and even the password file. + +A mount-map @dfn{name} is a sequence of characters. When an automount +point is created a handle on the mount-map is obtained. For each map +type configured @i{Amd} attempts to reference the a map of the +appropriate type. If a map is found, @i{Amd} notes the type for future +use and deletes the reference, for example closing any open file +descriptors. The available maps are configure when @i{Amd} is built and +can be displayed by running the command @samp{amd -v}. + +By default, @i{Amd} caches data in a mode dependent on the type of map. +This is the same as specifying @samp{cache:=mapdefault} and selects a +suitable default cache mode depending on the map type. The individual +defaults are described below. The @var{cache} option can be specified +on automount points to alter the caching behaviour (@pxref{Automount +Filesystem}).@refill + +The following map types have been implemented, though some are not +available on all machines. Run the command @samp{amd -v} to obtain a +list of map types configured on your machine. + +@menu +* File maps:: +* ndbm maps:: +* NIS maps:: +* Hesiod maps:: +* Password maps:: +* Union maps:: +@end menu + +@node File maps, ndbm maps, Map Types, Map Types +@comment node-name, next, previous, up +@subsection File maps +@cindex File maps +@cindex Flat file maps +@cindex File map syntactic conventions + +When @i{Amd} searches a file for a map entry it does a simple scan of +the file and supports both comments and continuation lines. + +Continuation lines are indicated by a backslash character (@samp{\}) as +the last character of a line in the file. The backslash, newline character +@emph{and any leading white space on the following line} are discarded. A maximum +line length of 2047 characters is enforced after continuation lines are read +but before comments are stripped. Each line must end with +a newline character; that is newlines are terminators, not separators. +The following examples illustrate this: + +@example +key valA valB; \ + valC +@end example + +specifies @emph{three} locations, and is identical to + +@example +key valA valB; valC +@end example + +However, + +@example +key valA valB;\ + valC +@end example + +specifies only @emph{two} locations, and is identical to + +@example +key valA valB;valC +@end example + +After a complete line has been read from the file, including +continuations, @i{Amd} determines whether there is a comment on the +line. A comment begins with a hash (``@samp{#}'') character and +continues to the end of the line. There is no way to escape or change +the comment lead-in character. + +Note that continuation lines and comment support @dfn{only} apply to +file maps, or ndbm maps built with the @code{mk-amd-map} program. + +When caching is enabled, file maps have a default cache mode of +@code{all} (@pxref{Automount Filesystem}). + +@node ndbm maps, NIS maps, File maps, Map Types +@comment node-name, next, previous, up +@subsection ndbm maps +@cindex ndbm maps + +An ndbm map may be used as a fast access form of a file map. The program, +@code{mk-amd-map}, converts a normal map file into an ndbm database. +This program supports the same continuation and comment conventions that +are provided for file maps. Note that ndbm format files may @emph{not} +be sharable across machine architectures. The notion of speed generally +only applies to large maps; a small map, less than a single disk block, +is almost certainly better implemented as a file map. + +ndbm maps do not support cache mode @samp{all} and, when caching is +enabled, have a default cache mode of @samp{inc} (@pxref{Automount Filesystem}). + +@node NIS maps, Hesiod maps, ndbm maps, Map Types +@comment node-name, next, previous, up +@subsection NIS maps +@cindex NIS (YP) maps + +When using NIS (formerly YP), an @i{Amd} map is implemented directly +by the underlying NIS map. Comments and continuation lines are +@emph{not} supported in the automounter and must be stripped when +constructing the NIS server's database. + +NIS maps do not support cache mode @code{all} and, when caching is +enabled, have a default cache mode of @code{inc} (@pxref{Automount Filesystem}). + +The following rule illustrates what could be added to your NIS @file{Makefile}, +in this case causing the @file{amd.home} map to be rebuilt: +@example +$(YPTSDIR)/amd.home.time: $(ETCDIR)/amd.home + -@@sed -e "s/#.*$$//" -e "/^$$/d" $(ETCDIR)/amd.home | \ + awk '@{ \ + for (i = 1; i <= NF; i++) \ + if (i == NF) @{ \ + if (substr($$i, length($$i), 1) == "\\") \ + printf("%s", substr($$i, 1, length($$i) - 1)); \ + else \ + printf("%s\n", $$i); \ + @} \ + else \ + printf("%s ", $$i); \ + @}' | \ + $(MAKEDBM) - $(YPDBDIR)/amd.home; \ + touch $(YPTSDIR)/amd.home.time; \ + echo "updated amd.home"; \ + if [ ! $(NOPUSH) ]; then \ + $(YPPUSH) amd.home; \ + echo "pushed amd.home"; \ + else \ + : ; \ + fi +@end example + +Here @code{$(YPTSDIR)} contains the time stamp files, and @code{$(YPDBDIR)} contains +the dbm format NIS files. + +@node Hesiod maps, Password maps, NIS maps, Map Types +@comment node-name, next, previous, up +@subsection Hesiod maps +@cindex Hesiod maps + +When the map name begins with the string @samp{hesiod.} lookups are made +using the @dfn{Hesiod} name server. The string following the dot is +used as a name qualifier and is prepended with the key being located. +The entire string is then resolved in the @code{automount} context. For +example, if the the key is @samp{jsp} and map name is +@samp{hesiod.homes} then @dfn{Hesiod} is asked to resolve +@samp{jsp.homes.automount}. + +Hesiod maps do not support cache mode @samp{all} and, when caching is +enabled, have a default cache mode of @samp{inc} (@pxref{Automount Filesystem}). + +The following is an example of a @dfn{Hesiod} map entry: + +@example +jsp.homes.automount HS TXT "rfs:=/home/charm;rhost:=charm;sublink:=jsp" +njw.homes.automount HS TXT "rfs:=/home/dylan/dk2;rhost:=dylan;sublink:=njw" +@end example + +@node Password maps, Union maps, Hesiod maps, Map Types +@comment node-name, next, previous, up +@subsection Password maps +@cindex Password file maps +@cindex /etc/passwd maps +@cindex User maps, automatic generation +@cindex Automatic generation of user maps +@cindex Using the password file as a map + +The password map support is unlike the four previous map types. When +the map name is the string @file{/etc/passwd} @i{Amd} can lookup a user +name in the password file and re-arrange the home directory field to +produce a usable map entry. + +@i{Amd} assumes the home directory has the format +`@t{/}@i{anydir}@t{/}@i{dom1}@t{/../}@i{domN}@t{/}@i{login}'. +@c @footnote{This interpretation is not necessarily exactly what you want.} +It breaks this string into a map entry where @code{$@{rfs@}} has the +value `@t{/}@i{anydir}@t{/}@i{domN}', @code{$@{rhost@}} has the value +`@i{domN}@t{.}@i{...}@t{.}@i{dom1}', and @code{$@{sublink@}} has the +value @samp{login}.@refill + +Thus if the password file entry was + +@example +/home/achilles/jsp +@end example + +the map entry used by @i{Amd} would be + +@example +rfs:=/home/achilles;rhost:=achilles;sublink:=jsp +@end example + +Similarly, if the password file entry was + +@example +/home/cc/sugar/mjh +@end example + +the map entry used by @i{Amd} would be + +@example +rfs:=/home/sugar;rhost:=sugar.cc;sublink:=jsp +@end example + +@node Union maps, , Password maps, Map Types +@comment node-name, next, previous, up +@subsection Union maps +@cindex Union file maps + +The union map support is provided specifically for use with the union +filesystem, @pxref{Union Filesystem}. + +It is identified by the string @samp{union:} which is followed by a +colon separated list of directories. The directories are read in order, +and the names of all entries are recorded in the map cache. Later +directories take precedence over earlier ones. The union filesystem +type then uses the map cache to determine the union of the names in all +the directories. + +@c subsection Gdbm + +@node Key Lookup, Location Format, Map Types, Mount Maps +@comment node-name, next, previous, up +@section How keys are looked up +@cindex Key lookup +@cindex Map lookup +@cindex Looking up keys +@cindex How keys are looked up +@cindex Wildcards in maps + +The key is located in the map whose type was determined when the +automount point was first created. In general the key is a pathname +component. In some circumstances this may be modified by variable +expansion (@pxref{Variable Expansion}) and prefixing. If the automount +point has a prefix, specified by the @var{pref} option, then that is +prepended to the search key before the map is searched. + +If the map cache is a @samp{regexp} cache then the key is treated as an +egrep-style regular expression, otherwise a normal string comparison is +made. + +If the key cannot be found then a @dfn{wildcard} match is attempted. +@i{Amd} repeatedly strips the basename from the key, appends @samp{/*} and +attempts a lookup. Finally, @i{Amd} attempts to locate the special key @samp{*}. + +@group +For example, the following sequence would be checked if @file{home/dylan/dk2} was +being located: + +@example + home/dylan/dk2 + home/dylan/* + home/* + * +@end example +@end group + +At any point when a wildcard is found, @i{Amd} proceeds as if an exact +match had been found and the value field is then used to resolve the +mount request, otherwise an error code is propagated back to the kernel. +(@pxref{Filesystem Types}).@refill + +@node Location Format, , Key Lookup, Mount Maps +@comment node-name, next, previous, up +@section Location Format +@cindex Location format +@cindex Map entry format +@cindex How locations are parsed + +The value field from the lookup provides the information required to +mount a filesystem. The information is parsed according to the syntax +shown below. + +@display +@i{location-list}: + @i{location-selection} + @i{location-list} @i{white-space} @t{||} @i{white-space} @i{location-selection} +@i{location-selection}: + @i{location} + @i{location-selection} @i{white-space} @i{location} +@i{location}: + @i{location-info} + @t{-}@i{location-info} + @t{-} +@i{location-info}: + @i{sel-or-opt} + @i{location-info}@t{;}@i{sel-or-opt} + @t{;} +@i{sel-or-opt}: + @i{selection} + @i{opt-ass} +@i{selection}: + selector@t{==}@i{value} + selector@t{!=}@i{value} +@i{opt-ass}: + option@t{:=}@i{value} +@i{white-space}: + space + tab +@end display + +Note that unquoted whitespace is not allowed in a location description. +White space is only allowed, and is mandatory, where shown with non-terminal +@samp{white-space}. + +A @dfn{location-selection} is a list of possible volumes with which to +satisfy the request. @dfn{location-selection}s are separated by the +@samp{||} operator. The effect of this operator is to prevent use of +location-selections to its right if any of the location-selections on +its left were selected whether or not any of them were successfully +mounted (@pxref{Selectors}).@refill + +The location-selection, and singleton @dfn{location-list}, +@samp{type:=ufs;dev:=/dev/xd1g} would inform @i{Amd} to mount a UFS +filesystem from the block special device @file{/dev/xd1g}. + +The @dfn{sel-or-opt} component is either the name of an option required +by a specific filesystem, or it is the name of a built-in, predefined +selector such as the architecture type. The value may be quoted with +double quotes @samp{"}, for example +@samp{type:="ufs";dev:="/dev/xd1g"}. These quotes are stripped when the +value is parsed and there is no way to get a double quote into a value +field. Double quotes are used to get white space into a value field, +which is needed for the program filesystem (@pxref{Program Filesystem}).@refill + +@menu +* Map Defaults:: +* Variable Expansion:: +* Selectors:: +* Map Options:: +@end menu + +@node Map Defaults, Variable Expansion, Location Format, Location Format +@comment node-name, next, previous, up +@subsection Map Defaults +@cindex Map defaults +@cindex How to set default map parameters +@cindex Setting default map parameters + +A location beginning with a dash @samp{-} is used to specify default +values for subsequent locations. Any previously specified defaults in +the location-list are discarded. The default string can be empty in +which case no defaults apply. + +The location @samp{-fs:=/mnt;opts:=ro} would set the local mount point +to @file{/mnt} and cause mounts to be read-only by default. Defaults +specified this way are appended to, and so override, any global map +defaults given with @samp{/defaults}). +@c +@c A @samp{/defaults} value @dfn{gdef} and a location list +@c \begin{quote} +@c $@samp{-}@dfn{def}_a $\verb*+ +$ @dfn{loc}_{a_1} $\verb*+ +$ @dfn{loc}_{a_2} $\verb*+ +$ @samp{-}@dfn{def}_b $\verb*+ +$ @dfn{loc}_{b_1} \ldots$ +@c \end{quote} +@c is equivalent to +@c \begin{quote} +@c $@samp{-}@dfn{gdef}@samp{;}@dfn{def}_a $\verb*+ +$ @dfn{loc}_{a_1} $\verb*+ +$ @dfn{loc}_{a_2} $\verb*+ +$ @samp{-}@dfn{gdef}@samp{;}@dfn{def}_b $\verb*+ +$ @dfn{loc}_{b_1} \ldots$ +@c \end{quote} +@c which is equivalent to +@c \begin{quote} +@c $@dfn{gdef}@samp{;}@dfn{def}_a@samp{;}@dfn{loc}_{a_1} $\verb*+ +$@dfn{gdef}@samp{;}@dfn{def}_a@samp{;}@dfn{loc}_{a_2} $\verb*+ +$@dfn{gdef}@samp{;}@dfn{def}_b@samp{;}@dfn{loc}_{b_1} \ldots$ +@c \end{quote} + +@node Variable Expansion, Selectors, Map Defaults, Location Format +@comment node-name, next, previous, up +@subsection Variable Expansion +@cindex Variable expansion +@cindex How variables are expanded +@cindex Pathname operators +@cindex Domain stripping +@cindex Domainname operators +@cindex Stripping the local domain name +@cindex Environment variables +@cindex How to access environment variables in maps + +To allow generic location specifications @i{Amd} does variable expansion +on each location and also on some of the option strings. Any option or +selector appearing in the form @code{$@dfn{var}} is replaced by the +current value of that option or selector. For example, if the value of +@code{$@{key@}} was @samp{bin}, @code{$@{autodir@}} was @samp{/a} and +@code{$@{fs@}} was `@t{$@{autodir@}}@t{/local/}@t{$@{key@}}' then +after expansion @code{$@{fs@}} would have the value @samp{/a/local/bin}. +Any environment variable can be accessed in a similar way.@refill + +Two pathname operators are available when expanding a variable. If the +variable name begins with @samp{/} then only the last component of +then pathname is substituted. For example, if @code{$@{path@}} was +@samp{/foo/bar} then @code{$@{/path@}} would be expanded to @samp{bar}. +Similarly, if the variable name ends with @samp{/} then all but the +last component of the pathname is substituted. In the previous example, +@code{$@{path/@}} would be expanded to @samp{/foo}.@refill + +Two domain name operators are also provided. If the variable name +begins with @samp{.} then only the domain part of the name is +substituted. For example, if @code{$@{rhost@}} was +@samp{swan.doc.ic.ac.uk} then @code{$@{.rhost@}} would be expanded to +@samp{doc.ic.ac.uk}. Similarly, if the variable name ends with @samp{.} +then only the host component is substituted. In the previous example, +@code{$@{rhost.@}} would be expanded to @samp{swan}.@refill + +Variable expansion is a two phase process. Before a location is parsed, +all references to selectors, @i{eg} @code{$@{path@}}, are expanded. The +location is then parsed, selections are evaluated and option assignments +recorded. If there were no selections or they all succeeded the +location is used and the values of the following options are expanded in +the order given: @var{sublink}, @var{rfs}, @var{fs}, @var{opts}, +@var{remopts}, @var{mount} and @var{unmount}. + +Note that expansion of option values is done after @dfn{all} assignments +have been completed and not in a purely left to right order as is done +by the shell. This generally has the desired effect but care must be +taken if one of the options references another, in which case the +ordering can become significant. + +There are two special cases concerning variable expansion: + +@enumerate +@item +before a map is consulted, any selectors in the name received +from the kernel are expanded. For example, if the request from the +kernel was for `@t{$@{arch@}}@t{.bin}' and the machine architecture +was @samp{vax}, the value given to @code{$@{key@}} would be +@samp{vax.bin}.@refill + +@item +the value of @code{$@{rhost@}} is expanded and normalized before the +other options are expanded. The normalization process strips any local +sub-domain components. For example, if @code{$@{domain@}} was +@samp{Berkeley.EDU} and @code{$@{rhost@}} was initially +@samp{snow.Berkeley.EDU}, after the normalization it would simply be +@samp{snow}. Hostname normalization is currently done in a +@emph{case-dependent} manner.@refill +@end enumerate + +@node Selectors, Map Options, Variable Expansion, Location Format +@comment node-name, next, previous, up +@subsection Selectors +@cindex Selectors + +Selectors are used to control the use of a location. It is possible to +share a mount map between many machines in such a way that filesystem +location, architecture and operating system differences are hidden from +the users. A selector of the form @samp{arch==sun3;os==sos4} would only +apply on Sun-3s running SunOS 4.x. + +Selectors are evaluated left to right. If a selector fails then that +location is ignored. Thus the selectors form a conjunction and the +locations form a disjunction. If all the locations are ignored or +otherwise fail then @i{Amd} uses the @dfn{error} filesystem +(@pxref{Error Filesystem}). This is equivalent to having a location +@samp{type:=error} at the end of each mount-map entry.@refill + +The selectors currently implemented are: + +@table @samp +@cindex arch, mount selector +@cindex Mount selector; arch +@cindex Selector; arch +@item arch +the machine architecture which was automatically determined at compile +time. The architecture type can be displayed by running the command +@samp{amd -v}. @xref{Supported Machine Architectures}.@refill + +@item autodir +@cindex autodir, mount selector +@cindex Mount selector; autodir +@cindex Selector; autodir +the default directory under which to mount filesystems. This may be +changed by the ``-a'' command line option. See the @var{fs} option. + +@item byte +@cindex byte, mount selector +@cindex Mount selector; byte +@cindex Selector; byte +the machine's byte ordering. This is either @samp{little}, indicating +little-endian, or @samp{big}, indicating big-endian. One possible use +is to share @samp{rwho} databases (@pxref{rwho servers}). Another is to +share ndbm databases, however this use can be considered a courageous +juggling act. + +@item cluster +@cindex cluster, mount selector +@cindex Mount selector; cluster +@cindex Selector; cluster +is provided as a hook for the name of the local cluster. This can be +used to decide which servers to use for copies of replicated +filesystems. @code{$@{cluster@}} defaults to the value of +@code{$@{domain@}} unless a different value is set with the ``-C'' +command line option. + +@item domain +@cindex domain, mount selector +@cindex Mount selector; domain +@cindex Selector; domain +the local domain name as specified by the ``-d'' command line option. +See @samp{host}. + +@item host +@cindex host, mount selector +@cindex Mount selector; host +@cindex Selector; host +the local hostname as determined by @b{gethostname}(2). If no domain +name was specified on the command line and the hostname contains a +period @samp{.} then the string before the period is used as the +host name, and the string after the period is assigned to +@code{$@{domain@}}. For example, if the hostname is +@samp{styx.doc.ic.ac.uk} then @code{host} would be @samp{styx} and +@code{domain} would be @samp{doc.ic.ac.uk}. @code{hostd} would be +@samp{styx.doc.ic.ac.uk}.@refill + +@item hostd +@cindex hostd, mount selector +@cindex Mount selector; hostd +@cindex Selector; hostd +is @code{$@{host@}} and @code{$@{domain@}} concatenated with a +@samp{.} inserted between them if required. If @code{$@{domain@}} +is an empty string then @code{$@{host@}} and @code{$@{hostd@}} will be +identical. + +@item karch +@cindex karch, mount selector +@cindex Mount selector; karch +@cindex Selector; karch +is provided as a hook for the kernel architecture. This is used on +SunOS 4, for example, to distinguish between different @samp{/usr/kvm} +volumes. @code{$@{karch@}} defaults to the value of @code{$@{arch@}} +unless a different value is set with the ``-k'' command line option. + +@item os +@cindex os, mount selector +@cindex Mount selector; os +@cindex Selector; os +the operating system. Like the machine architecture, this is +automatically determined at compile time. The operating system name can +be displayed by running the command @samp{amd -v}. @xref{Supported +Operating Systems}.@refill + +@end table + +The following selectors are also provided. Unlike the other selectors, +they vary for each lookup. Note that when the name from the kernel is +expanded prior to a map lookup, these selectors are all defined as empty +strings. + +@table @samp +@item key +@cindex key, mount selector +@cindex Mount selector; key +@cindex Selector; key +the name being resolved. For example, if @file{/home} is an automount +point, then accessing @file{/home/foo} would set @code{$@{key@}} to the +string @samp{foo}. The key is prefixed by the @var{pref} option set in +the parent mount point. The default prefix is an empty string. If the +prefix was @file{blah/} then @code{$@{key@}} would be set to +@file{blah/foo}.@refill + +@item map +@cindex map, mount selector +@cindex Mount selector; map +@cindex Selector; map +the name of the mount map being used. + +@item path +@cindex path, mount selector +@cindex Mount selector; path +@cindex Selector; path +the full pathname of the name being resolved. For example +@file{/home/foo} in the example above. + +@item wire +@cindex wire, mount selector +@cindex Mount selector; wire +@cindex Selector; wire +the name of the network to which the primary network interface is +attached. If a symbolic name cannot be found in the networks or hosts +database then dotted IP address format is used. This value is also +output by the ``-v'' option. + +@end table + +Selectors can be negated by using @samp{!=} instead of @samp{==}. For +example to select a location on all non-Vax machines the selector +@samp{arch!=vax} would be used. + +@node Map Options, , Selectors, Location Format +@comment node-name, next, previous, up +@subsection Map Options +@cindex Map options +@cindex Setting map options + +Options are parsed concurrently with selectors. The difference is that +when an option is seen the string following the @samp{:=} is +recorded for later use. As a minimum the @var{type} option must be +specified. Each filesystem type has other options which must also be +specified. @xref{Filesystem Types}, for details on the filesystem +specific options.@refill + +Superfluous option specifications are ignored and are not reported +as errors. + +The following options apply to more than one filesystem type. + +@menu +* delay Option:: +* fs Option:: +* opts Option:: +* remopts Option:: +* sublink Option:: +* type Option:: +@end menu + +@node delay Option, fs Option, Map Options, Map Options +@comment node-name, next, previous, up +@subsubsection delay Option +@cindex Setting a delay on a mount location +@cindex Delaying mounts from specific locations +@cindex Primary server +@cindex Secondary server +@cindex delay, mount option +@cindex Mount option; delay + +The delay, in seconds, before an attempt will be made to mount from the current location. +Auxilliary data, such as network address, file handles and so on are computed +regardless of this value. + +A delay can be used to implement the notion of primary and secondary file servers. +The secondary servers would have a delay of a few seconds, +thus giving the primary servers a chance to respond first. + +@node fs Option, opts Option, delay Option, Map Options +@comment node-name, next, previous, up +@subsubsection fs Option +@cindex Setting the local mount point +@cindex Overriding the default mount point +@cindex fs, mount option +@cindex Mount option; fs + +The local mount point. The semantics of this option vary between +filesystems. + +For NFS and UFS filesystems the value of @code{$@{fs@}} is used as the +local mount point. For other filesystem types it has other meanings +which are described in the section describing the respective filesystem +type. It is important that this string uniquely identifies the +filesystem being mounted. To satisfy this requirement, it should +contain the name of the host on which the filesystem is resident and the +pathname of the filesystem on the local or remote host. + +The reason for requiring the hostname is clear if replicated filesystems +are considered. If a fileserver goes down and a replacement filesystem +is mounted then the @dfn{local} mount point @dfn{must} be different from +that of the filesystem which is hung. Some encoding of the filesystem +name is required if more than one filesystem is to be mounted from any +given host. + +If the hostname is first in the path then all mounts from a particular +host will be gathered below a single directory. If that server goes +down then the hung mount points are less likely to be accidentally +referenced, for example when @b{getwd}(3) traverses the namespace to +find the pathname of the current directory. + +The @samp{fs} option defaults to +@code{$@{autodir@}/$@{rhost@}$@{rfs@}}. In addition, +@samp{rhost} defaults to the local host name (@code{$@{host@}}) and +@samp{rfs} defaults to the value of @code{$@{path@}}, which is the full +path of the requested file; @samp{/home/foo} in the example above +(@pxref{Selectors}). @code{$@{autodir@}} defaults to @samp{/a} but may +be changed with the ``-a'' command line option. Sun's automounter +defaults to @samp{/tmp_mnt}. Note that there is no @samp{/} between +the @code{$@{rhost@}} and @code{$@{rfs@}} since @code{$@{rfs@}} begins +with a @samp{/}.@refill + +@node opts Option, remopts Option, fs Option, Map Options +@comment node-name, next, previous, up +@subsubsection opts Option +@cindex Setting system mount options +@cindex Passing parameters to the mount system call +@cindex mount system call +@cindex mount system call flags +@cindex The mount system call +@cindex opts, mount option +@cindex Mount option; opts + +The options to pass to the mount system call. A leading @samp{-} is +silently ignored. The mount options supported generally correspond to +those used by @b{mount}(8) and are listed below. Some additional +pseudo-options are interpreted by @i{Amd} and are also listed. + +Unless specifically overridden, each of the system default mount options +applies. Any options not recognised are ignored. If no options list is +supplied the string @samp{rw,defaults} is used and all the system +default mount options apply. Options which are not applicable for a +particular operating system are silently ignored. For example, only 4.4 +BSD is known to implement the @code{compress} and @code{spongy} options. + +@table @code +@item compress +Use NFS compression protocol. +@item grpid +Use BSD directory group-id semantics. +@item intr +Allow keyboard interrupts on hard mounts. +@item noconn +Don't make a connection on datagram transports. +@item nocto +No close-to-open consistency. +@item nodevs +Don't allow local special devices on this filesystem. +@item nosuid +Don't allow set-uid or set-gid executables on this filesystem. +@item quota +Enable quota checking on this mount. +@item retrans=@i{n} +The number of NFS retransmits made before a user error is generated by a +@samp{soft} mounted filesystem, and before a @samp{hard} mounted +filesystem reports @samp{NFS server @dfn{yoyo} not responding still +trying}. +@item ro +Mount this filesystem readonly. +@item rsize=@var{n} +The NFS read packet size. You may need to set this if you are using +NFS/UDP through a gateway. +@item soft +Give up after @dfn{retrans} retransmissions. +@item spongy +Like @samp{soft} for status requests, and @samp{hard} for data transfers. +@item tcp +Use TCP/IP instead of UDP/IP, ignored if the NFS implementation does not +support TCP/IP mounts. +@item timeo=@var{n} +The NFS timeout, in tenth-seconds, before a request is retransmitted. +@item wsize=@var{n} +The NFS write packet size. You may need to set this if you are using +NFS/UDP through a gateway. +@end table + +The following options are implemented by @i{Amd}, rather than being +passed to the kernel. + +@table @code +@item nounmount +Configures the mount so that its time-to-live will +never expire. This is also the default for some filesystem types. +@c +@c Implementation broken: +@item ping=@var{n} +The interval, in seconds, between keep-alive pings. When four +consecutive pings have failed the mount point is marked as hung. This +interval defaults to 30 seconds. If the ping interval is less than zero, +no pings are sent and the host is assumed to be always +up. By default, pings are not sent for an NFS/TCP mount. +@item retry=@var{n} +The number of times to retry the mount system call. +@item utimeout=@var{n} +The interval, in seconds, by which the mount's +time-to-live is extended after an unmount attempt +has failed. In fact the interval is extended before the unmount is +attempted to avoid thrashing. The default value is 120 seconds (two +minutes) or as set by the ``-w'' command line option. +@end table + +@node remopts Option, sublink Option, opts Option, Map Options +@comment node-name, next, previous, up +@subsubsection remopts Option +@cindex Setting system mount options for non-local networks +@cindex remopts, mount option +@cindex Mount option; remopts + +This option has the same use as @code{$@{opts@}} but applies only when +the remote host is on a non-local network. For example, when using NFS +across a gateway it is often necessary to use smaller values for the +data read and write sizes. This can simply be done by specifying the +small values in @var{remopts}. When a non-local host is accessed, the +smaller sizes will automatically be used. + +@i{Amd} determines whether a host is local by examining the network +interface configuration at startup. Any interface changes made after +@i{Amd} has been started will not be noticed. The likely effect will +be that a host may incorrectly be declared non-local. + +Unless otherwise set, the value of @code{$@{rem@}} is the same as the +value of @code{$@{opts@}}. + +@node sublink Option, type Option, remopts Option, Map Options +@comment node-name, next, previous, up +@subsubsection sublink Option +@cindex Setting the sublink option +@cindex sublink, mount option +@cindex Mount option; sublink + +The subdirectory within the mounted filesystem to which the reference +should point. This can be used to prevent duplicate mounts in cases +where multiple directories in the same mounted filesystem are used. + +@node type Option, , sublink Option, Map Options +@comment node-name, next, previous, up +@subsubsection type Option +@cindex Setting the filesystem type option +@cindex type, mount option +@cindex Mount option; type + +The filesystem type to be used. @xref{Filesystem Types}, for a full +description of each type.@refill + +@node Amd Command Line Options, Filesystem Types, Mount Maps, Top +@comment node-name, next, previous, up +@chapter @i{Amd} Command Line Options +@cindex Command line options, Amd +@cindex Amd command line options +@cindex Overriding defaults on the command line + +Many of @i{Amd}'s parameters can be set from the command line. The +command line is also used to specify automount points and maps. + +The general format of a command line is + +@example +amd [@i{options}] @{ @i{directory} @i{map-name} [-@i{map-options}] @} ... +@end example + +For each directory and map-name given, @i{Amd} establishes an +automount point. The @dfn{map-options} may be any sequence of options +or selectors---@pxref{Location Format}. The @dfn{map-options} +apply only to @i{Amd}'s mount point. + +@samp{type:=toplvl;cache:=mapdefault;fs:=$@{map@}} is the default value for the +map options. Default options for a map are read from a special entry in +the map whose key is the string @samp{/defaults}. When default options +are given they are prepended to any options specified in the mount-map +locations as explained in. @xref{Map Defaults}, for more details. + +The @dfn{options} are any combination of those listed below. + +Once the command line has been parsed, the automount points are mounted. +The mount points are created if they do not already exist, in which case they +will be removed when @i{Amd} exits. +Finally, @i{Amd} disassociates itself from its controlling terminal and +forks into the background. + +Note: Even if @i{Amd} has been built with @samp{-DDEBUG} it will still +background itself and disassociate itself from the controlling terminal. +To use a debugger it is necessary to specify @samp{-D nodaemon} on the +command line. + +@menu +* -a Option:: Automount directory. +* -c Option:: Cache timeout interval. +* -d Option:: Domain name. +* -k Option:: Kernel architecture. +* -l Option:: Log file. +* -n Option:: Hostname normalisation. +* -p Option:: Output process id. +* -r Option:: Restart existing mounts. +* -t Option:: Kernel RPC timeout. +* -v Option:: Version information. +* -w Option:: Wait interval after failed unmount. +* -x Option:: Log options. +* -y Option:: NIS domain. +* -C-Option:: Cluster name. +* -D-Option:: Debug flags. +@end menu + +@node -a Option, -c Option, Amd Command Line Options, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-a} @var{directory} +@cindex Automount directory +@cindex Setting the default mount directory + +Specifies the default mount directory. This option changes the variable +@code{$@{autodir@}} which otherwise defaults to @file{/a}. For example, +some sites prefer @file{/amd}. + +@example +amd -a /amd ... +@end example + +@node -c Option, -d Option, -a Option, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-c} @var{cache-interval} +@cindex Cache interval +@cindex Interval before a filesystem times out +@cindex Setting the interval before a filesystem times out +@cindex Changing the interval before a filesystem times out + +Selects the period, in seconds, for which a name is cached by @i{Amd}. +If no reference is made to the volume in this period, @i{Amd} discards +the volume name to filesystem mapping. + +Once the last reference to a filesystem has been removed, @i{Amd} +attempts to unmount the filesystem. If the unmount fails the interval +is extended by a further period as specified by the @samp{-w} command +line option or by the @samp{utimeout} mount option. + +The default @dfn{cache-interval} is 300 seconds (five minutes). + +@node -d Option, -k Option, -c Option, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-d} @var{domain} +@cindex Domain name +@cindex Setting the local domain name +@cindex Overriding the local domain name + +Specifies the host's domain. This sets the internal variable +@code{$@{domain@}} and affects the @code{$@{hostd@}} variable. + +If this option is not specified and the hostname already contains the +local domain then that is used, otherwise the default value of +@code{$@{domain@}} is @samp{unknown.domain}. + +For example, if the local domain was @samp{doc.ic.ac.uk}, @i{Amd} could +be started as follows: + +@example +amd -d doc.ic.ac.uk ... +@end example + +@node -k Option, -l Option, -d Option, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-k} @var{kernel-architecture} +@cindex Setting the Kernel architecture + +Specifies the kernel architecture of the system. This is usually the +output of @samp{arch -k} and its only effect is to set the variable +@code{$@{karch@}}. If this option is not given, @code{$@{karch@}} has +the same value as @code{$@{arch@}}. + +This would be used as follows: + +@example +amd -k `arch -k` ... +@end example + +@node -l Option, -n Option, -k Option, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-l} @var{log-option} +@cindex Log filename +@cindex Setting the log file +@cindex Using syslog to log errors +@cindex syslog + +Selects the form of logging to be made. Two special @dfn{log-options} +are recognised. + +@enumerate +@item +If @dfn{log-option} is the string @samp{syslog}, @i{Amd} will use the +@b{syslog}(3) mechanism.@refill + +@item +If @dfn{log-option} is the string @samp{/dev/stderr}, @i{Amd} will use +standard error, which is also the default target for log messages. To +implement this, @i{Amd} simulates the effect of the @samp{/dev/fd} +driver. +@end enumerate + +Any other string is taken as a filename to use for logging. Log +messages are appended to the file if it already exists, otherwise a new +file is created. The file is opened once and then held open, rather +than being re-opened for each message. + +If the @samp{syslog} option is specified but the system does not support +syslog or if the named file cannot be opened or created, @i{Amd} will +use standard error. Error messages generated before @i{Amd} has +finished parsing the command line are printed on standard error. + +Using @samp{syslog} is usually best, in which case @i{Amd} would be +started as follows: + +@example +amd -l syslog ... +@end example + +@node -n Option, -p Option, -l Option, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-n} +@cindex Hostname normalisation +@cindex Aliased hostnames +@cindex Resolving aliased hostnames +@cindex Normalising hostnames + +Normalises the remote hostname before using it. Normalisation is done +by replacing the value of @code{$@{rhost@}} with the primary name +returned by a hostname lookup. + +This option should be used if several names are used to refer to a +single host in a mount map. + +@node -p Option, -r Option, -n Option, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-p} +@cindex Process id +@cindex Displaying the process id +@cindex process id of Amd daemon +@cindex pid file, creating with -p option +@cindex Creating a pid file + +Causes @i{Amd}'s process id to be printed on standard output. +This can be redirected to a suitable file for use with kill: + +@example +amd -p > /var/run/amd.pid ... +@end example + +This option only has an affect if @i{Amd} is running in daemon mode. +If @i{Amd} is started with the @code{-D nodaemon} debug flag, this +option is ignored. + +@node -r Option, -t Option, -p Option, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-r} +@cindex Restarting existing mounts +@cindex Picking up existing mounts + +Tells @i{Amd} to restart existing mounts (@pxref{Inheritance Filesystem}). +@c @dfn{This option will be made the default in the next release.} + +@node -t Option, -v Option, -r Option, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-t} @var{timeout.retransmit} +@cindex Setting Amd's RPC parameters + +Specifies the RPC @dfn{timeout} and @dfn{retransmit} intervals used by +the kernel to communicate to @i{Amd}. These are used to set the +@samp{timeo} and @samp{retrans} mount options. + +@i{Amd} relies on the kernel RPC retransmit mechanism to trigger mount +retries. The value of this parameter changes the retry interval. Too +long an interval gives poor interactive response, too short an interval +causes excessive retries. + +@node -v Option, -w Option, -t Option, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-v} +@cindex Version information +@cindex Discovering version information +@cindex How to discover your version of Amd + +Print version information on standard error and then exit. The output +is of the form: + +@example +amd 5.2.1.11 of 91/03/17 18:04:05 5.3Alpha11 #0: Sun Mar 17 18:07:28 GMT 1991 +Built by pendry@@vangogh.Berkeley.EDU for a hp300 running bsd44 (big-endian). +Map support for: root, passwd, union, file, error. +FS: ufs, nfs, nfsx, host, link, program, union, auto, direct, toplvl, error. +Primary network is 128.32.130.0. +@end example + +The information includes the version number, release date and name of +the release. The architecture (@pxref{Supported Machine Architectures}), +operating system (@pxref{Supported Operating Systems}) +and byte ordering are also printed as they appear in the @code{$@{os@}}, +@code{$@{arch@}} and @code{$@{byte@}} variables.@refill + +@node -w Option, -x Option, -v Option, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-w} @var{wait-timeout} +@cindex Setting the interval between unmount attempts +@cindex unmount attempt backoff interval + +Selects the interval in seconds between unmount attempts after the +initial time-to-live has expired. + +This defaults to 120 seconds (two minutes). + +@node -x Option, -y Option, -w Option, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-x} @var{opts} +@cindex Log message selection +@cindex Selecting specific log messages +@cindex How to select log messages +@cindex syslog priorities + +Specifies the type and verbosity of log messages. @dfn{opts} is +a comma separated list selected from the following options: + +@table @code +@item fatal +Fatal errors +@item error +Non-fatal errors +@item user +Non-fatal user errors +@item warn +Recoverable errors +@item warning +Alias for @code{warn} +@item info +Information messages +@item map +Mount map usage +@item stats +Additional statistics +@item all +All of the above +@end table + +Initially a set of default logging flags is enabled. This is as if +@samp{-x all,nomap,nostats} had been selected. The command line is +parsed and logging is controlled by the ``-x'' option. The very first +set of logging flags is saved and can not be subsequently disabled using +@i{Amq}. This default set of options is useful for general production +use.@refill + +The @samp{info} messages include details of what is mounted and +unmounted and when filesystems have timed out. If you want to have the +default set of messages without the @samp{info} messages then you simply +need @samp{-x noinfo}. The messages given by @samp{user} relate to +errors in the mount maps, so these are useful when new maps are +installed. The following table lists the syslog priorites used for each +of the message types.@refill + +@table @code +@item fatal +LOG_CRIT +@item error +LOG_ERR +@item user +LOG_WARNING +@item warning +LOG_WARNING +@item info +LOG_INFO +@item debug +LOG_DEBUG +@item map +LOG_DEBUG +@item stats +LOG_INFO +@end table + + +The options can be prefixed by the string @samp{no} to indicate +that this option should be turned off. For example, to obtain all +but @samp{info} messages the option @samp{-x all,noinfo} would be used. + +If @i{Amd} was built with debugging enabled the @code{debug} option is +automatically enabled regardless of the command line options. + +@node -y Option, -C-Option, -x Option, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-y} @var{NIS-domain} +@cindex NIS (YP) domain name +@cindex Overriding the NIS (YP) domain name +@cindex Setting the NIS (YP) domain name +@cindex YP domain name + +Selects an alternate NIS domain. This is useful for debugging and +cross-domain shared mounting. If this flag is specified, @i{Amd} +immediately attempts to bind to a server for this domain. +@c @i{Amd} refers to NIS maps when it starts, unless the ``-m'' option +@c is specified, and whenever required in a mount map. + +@node -C-Option, -D-Option, -y Option, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-C} @var{cluster-name} +@cindex Cluster names +@cindex Setting the cluster name + +Specifies the name of the cluster of which the local machine is a member. +The only effect is to set the variable @code{$@{cluster@}}. +The @dfn{cluster-name} is will usually obtained by running another command which uses +a database to map the local hostname into a cluster name. +@code{$@{cluster@}} can then be used as a selector to restrict mounting of +replicated data. +If this option is not given, @code{$@{cluster@}} has the same value as @code{$@{domain@}}. +This would be used as follows: + +@example +amd -C `clustername` ... +@end example + +@node -D-Option, , -C-Option, Amd Command Line Options +@comment node-name, next, previous, up +@section @code{-D} @var{opts} +@cindex Debug options +@cindex Setting debug flags + +Controls the verbosity and coverage of the debugging trace; @dfn{opts} +is a comma separated list of debugging options. The ``-D'' option is +only available if @i{Amd} was compiled with @samp{-DDEBUG}. The memory +debugging facilities are only available if @i{Amd} was compiled with +@samp{-DDEBUG_MEM} (in addition to @samp{-DDEBUG}). + +The most common options to use are @samp{-D trace} and @samp{-D test} +(which turns on all the useful debug options). See the program source +for a more detailed explanation of the available options. + +@node Filesystem Types, Run-time Administration, Amd Command Line Options, Top +@comment node-name, next, previous, up +@chapter Filesystem Types +@cindex Filesystem types +@cindex Mount types +@cindex Types of filesystem + +To mount a volume, @i{Amd} must be told the type of filesystem to be +used. Each filesystem type typically requires additional information +such as the fileserver name for NFS. + +From the point of view of @i{Amd}, a @dfn{filesystem} is anything that +can resolve an incoming name lookup. An important feature is support +for multiple filesystem types. Some of these filesystems are +implemented in the local kernel and some on remote fileservers, whilst +the others are implemented internally by @i{Amd}.@refill + +The two common filesystem types are UFS and NFS. Four other user +accessible filesystems (@samp{link}, @samp{program}, @samp{auto} and +@samp{direct}) are also implemented internally by @i{Amd} and these are +described below. There are two additional filesystem types internal to +@i{Amd} which are not directly accessible to the user (@samp{inherit} +and @samp{error}). Their use is described since they may still have an +effect visible to the user.@refill + +@menu +* Network Filesystem:: A single NFS filesystem. +* Network Host Filesystem:: NFS mount a host's entire export tree. +* Network Filesystem Group:: An atomic group of NFS filesystems. +* Unix Filesystem:: Native disk filesystem. +* Program Filesystem:: Generic Program mounts. +* Symbolic Link Filesystem:: Local link referencing existing filesystem. +* Automount Filesystem:: +* Direct Automount Filesystem:: +* Union Filesystem:: +* Error Filesystem:: +* Top-level Filesystem:: +* Root Filesystem:: +* Inheritance Filesystem:: +@end menu + +@node Network Filesystem, Network Host Filesystem, Filesystem Types, Filesystem Types +@comment node-name, next, previous, up +@section Network Filesystem (@samp{type:=nfs}) +@cindex NFS +@cindex Mounting an NFS filesystem +@cindex How to mount and NFS filesystem +@cindex nfs, filesystem type +@cindex Filesystem type; nfs + +The @dfn{nfs} filesystem type provides access to Sun's NFS. + +@noindent +The following options must be specified: + +@table @code +@cindex rhost, mount option +@cindex Mount option; rhost +@item rhost +the remote fileserver. This must be an entry in the hosts database. IP +addresses are not accepted. The default value is taken +from the local host name (@code{$@{host@}}) if no other value is +specified. + +@cindex rfs, mount option +@cindex Mount option; rfs +@item rfs +the remote filesystem. +If no value is specified for this option, an internal default of +@code{$@{path@}} is used. +@end table + +NFS mounts require a two stage process. First, the @dfn{file handle} of +the remote file system must be obtained from the server. Then a mount +system call must be done on the local system. @i{Amd} keeps a cache +of file handles for remote file systems. The cache entries have a +lifetime of a few minutes. + +If a required file handle is not in the cache, @i{Amd} sends a request +to the remote server to obtain it. @i{Amd} @dfn{does not} wait for +a response; it notes that one of the locations needs retrying, but +continues with any remaining locations. When the file handle becomes +available, and assuming none of the other locations was successfully +mounted, @i{Amd} will retry the mount. This mechanism allows several +NFS filesystems to be mounted in parallel. +@c @footnote{The mechanism +@c is general, however NFS is the only filesystem +@c for which the required hooks have been written.} +The first one which responds with a valid file handle will be used. + +@noindent +An NFS entry might be: + +@example +jsp host!=charm;type:=nfs;rhost:=charm;rfs:=/home/charm;sublink:=jsp +@end example + +The mount system call and any unmount attempts are always done +in a new task to avoid the possibilty of blocking @i{Amd}. + +@node Network Host Filesystem, Network Filesystem Group, Network Filesystem, Filesystem Types +@comment node-name, next, previous, up +@section Network Host Filesystem (@samp{type:=host}) +@cindex Network host filesystem +@cindex Mounting entire export trees +@cindex How to mount all NFS exported filesystems +@cindex host, filesystem type +@cindex Filesystem type; host + +@c NOTE: the current implementation of the @dfn{host} filesystem type +@c sometimes fails to maintain a consistent view of the remote mount tree. +@c This happens when the mount times out and only some of the remote mounts +@c are successfully unmounted. To prevent this from occuring, use the +@c @samp{nounmount} mount option. + +The @dfn{host} filesystem allows access to the entire export tree of an +NFS server. The implementation is layered above the @samp{nfs} +implementation so keep-alives work in the same way. The only option +which needs to specified is @samp{rhost} which is the name of the +fileserver to mount. + +The @samp{host} filesystem type works by querying the mount daemon on +the given fileserver to obtain its export list. @i{Amd} then obtains +filehandles for each of the exported filesystems. Any errors at this +stage cause that particular filesystem to be ignored. Finally each +filesystem is mounted. Again, errors are logged but ignored. One +common reason for mounts to fail is that the mount point does not exist. +Although @i{Amd} attempts to automatically create the mount point, it +may be on a remote filesystem to which @i{Amd} does not have write +permission. + +When an attempt to unmount a @samp{host} filesystem mount fails, @i{Amd} +remounts any filesystems which had succesfully been unmounted. To do +this @i{Amd} queries the mount daemon again and obtains a fresh copy of +the export list. @i{Amd} then tries to mount any exported filesystems +which are not currently mounted. + +Sun's automounter provides a special @samp{-hosts} map. To achieve the +same effect with @i{Amd} requires two steps. First a mount map must +be created as follows: + +@example +/defaults type:=host;fs:=$@{autodir@}/$@{rhost@}/root;rhost:=$@{key@} +* opts:=rw,nosuid,grpid +@end example + +@noindent +and then start @i{Amd} with the following command + +@example +amd /n net.map +@end example + +@noindent +where @samp{net.map} is the name of map described above. Note that the +value of @code{$@{fs@}} is overridden in the map. This is done to avoid +a clash between the mount tree and any other filesystem already mounted +from the same fileserver. + +If different mount options are needed for different hosts then +additional entries can be added to the map, for example + +@example +host2 opts:=ro,nosuid,soft +@end example + +@noindent +would soft mount @samp{host2} read-only. + +@node Network Filesystem Group, Unix Filesystem, Network Host Filesystem, Filesystem Types +@comment node-name, next, previous, up +@section Network Filesystem Group (@samp{type:=nfsx}) +@cindex Network filesystem group +@cindex Atomic NFS mounts +@cindex Mounting an atomic group of NFS filesystems +@cindex How to mount an atomic group of NFS filesystems +@cindex nfsx, filesystem type +@cindex Filesystem type; nfsx + +The @dfn{nfsx} filesystem allows a group of filesystems to be mounted +from a single NFS server. The implementation is layered above the +@samp{nfs} implementation so keep-alives work in the same way. + +The options are the same as for the @samp{nfs} filesystem with one +difference. + +@noindent +The following options must be specified: + +@table @code +@item rhost +the remote fileserver. This must be an entry in the hosts database. IP +addresses are not accepted. The default value is taken from the local +host name (@code{$@{host@}}) if no other value is specified. + +@item rfs +as a list of filesystems to mount. The list is in the form of a comma +separated strings. +@end table + +@noindent +For example: + +@example +pub type:=nfsx;rhost:=gould;\ + rfs:=/public,/,graphics,usenet;fs:=$@{autodir@}/$@{rhost@}/root +@end example + +The first string defines the root of the tree, and is applied as a +prefix to the remaining members of the list which define the individual +filesystems. The first string is @emph{not} used as a filesystem name. +A parallel operation is used to determine the local mount points to +ensure a consistent layout of a tree of mounts. + +Here, the @emph{three} filesystems, @samp{/public}, +@samp{/public/graphics} and @samp{/public/usenet}, would be mounted.@refill + +A local mount point, @code{$@{fs@}}, @emph{must} be specified. The +default local mount point will not work correctly in the general case. +A suggestion is to use @samp{fs:=$@{autodir@}/$@{rhost@}/root}.@refill + +@node Unix Filesystem, Program Filesystem, Network Filesystem Group, Filesystem Types +@comment node-name, next, previous, up +@section Unix Filesystem (@samp{type:=ufs}) +@cindex Unix filesystem +@cindex UFS +@cindex Mounting a UFS filesystem +@cindex Mounting a local disk +@cindex How to mount a UFS filesystems +@cindex How to mount a local disk +@cindex Disk filesystems +@cindex ufs, filesystem type +@cindex Filesystem type; ufs + +The @dfn{ufs} filesystem type provides access to the system's +standard disk filesystem---usually a derivative of the Berkeley Fast Filesystem. + +@noindent +The following option must be specified: + +@table @code +@cindex dev, mount option +@cindex Mount option; dev +@item dev +the block special device to be mounted. +@end table + +A UFS entry might be: + +@example +jsp host==charm;type:=ufs;dev:=/dev/xd0g;sublink:=jsp +@end example + +@node Program Filesystem, Symbolic Link Filesystem, Unix Filesystem, Filesystem Types +@comment node-name, next, previous, up +@section Program Filesystem (@samp{type:=program}) +@cindex Program filesystem +@cindex Mount a filesystem under program control +@cindex program, filesystem type +@cindex Filesystem type; program + +The @dfn{program} filesystem type allows a program to be run whenever a +mount or unmount is required. This allows easy addition of support for +other filesystem types, such as MIT's Remote Virtual Disk (RVD) +which has a programmatic interface via the commands +@samp{rvdmount} and @samp{rvdunmount}. + +@noindent +The following options must be specified: + +@table @code +@cindex mount, mount option +@cindex Mount option; mount +@item mount +the program which will perform the mount. + +@cindex unmount, mount option +@cindex Mount option; unmount +@item unmount +the program which will perform the unmount. +@end table + +The exit code from these two programs is interpreted as a Unix error +code. As usual, exit code zero indicates success. To execute the +program @i{Amd} splits the string on whitespace to create an array of +substrings. Single quotes @samp{'} can be used to quote whitespace +if that is required in an argument. There is no way to escape or change +the quote character. + +To run the program @samp{rvdmount} with a host name and filesystem as +arguments would be specified by @samp{mount:="/etc/rvdmount rvdmount +fserver $@{path@}"}. + +The first element in the array is taken as the pathname of the program +to execute. The other members of the array form the argument vector to +be passed to the program, @dfn{including argument zero}. This means +that the split string must have at least two elements. The program is +directly executed by @i{Amd}, not via a shell. This means that scripts +must begin with a @code{#!} interpreter specification. + +If a filesystem type is to be heavily used, it may be worthwhile adding +a new filesystem type into @i{Amd}, but for most uses the program +filesystem should suffice. + +When the program is run, standard input and standard error are inherited +from the current values used by @i{Amd}. Standard output is a +duplicate of standard error. The value specified with the ``-l'' +command line option has no effect on standard error. + +@node Symbolic Link Filesystem, Symbolic Link Filesystem II, Program Filesystem, Filesystem Types +@comment node-name, next, previous, up +@section Symbolic Link Filesystem (@samp{type:=link}) +@cindex Symbolic link filesystem +@cindex Referencing part of the local name space +@cindex Mounting part of the local name space +@cindex How to reference part of the local name space +@cindex link, filesystem type +@cindex symlink, link filesystem type +@cindex Filesystem type; link + +Each filesystem type creates a symbolic link to point from the volume +name to the physical mount point. The @samp{link} filesystem does the +same without any other side effects. This allows any part of the +machines name space to be accessed via @i{Amd}. + +One common use for the symlink filesystem is @file{/homes} which can be +made to contain an entry for each user which points to their +(auto-mounted) home directory. Although this may seem rather expensive, +it provides a great deal of administrative flexibility. + +@noindent +The following option must be defined: + +@table @code +@item fs +The value of @var{fs} option specifies the destination of the link, as +modified by the @var{sublink} option. If @var{sublink} is non-null, it +is appended to @code{$@{fs@}}@code{/} and the resulting string is used +as the target. +@end table + +The @samp{link} filesystem can be though of as identical to the +@samp{ufs} filesystem but without actually mounting anything. + +An example entry might be: + +@example +jsp host==charm;type:=link;fs:=/home/charm;sublink:=jsp +@end example +which would return a symbolic link pointing to @file{/home/charm/jsp}. + +@node Symbolic Link Filesystem II, Automount Filesystem, Program Filesystem, Filesystem Types +@comment node-name, next, previous, up +@section Symbolic Link Filesystem II (@samp{type:=link}) +@cindex Symbolic link filesystem II +@cindex Referencing an existing part of the local name space +@cindex Mounting an existing part of the local name space +@cindex How to reference an existing part of the local name space +@cindex linkx, filesystem type +@cindex symlink, linkx filesystem type +@cindex Filesystem type; linkx + +The @samp{linkx} filesystem type is identical to @samp{link} with the +exception that the target of the link must exist. Existence is checked +with the @samp{lstat} system call. + +The @samp{linkx} filesystem type is particularly useful for wildcard map +entries. In this case, a list of possible targets can be give and +@i{Amd} will choose the first one which exists on the local machine. + +@node Automount Filesystem, Direct Automount Filesystem, Symbolic Link Filesystem II, Filesystem Types +@comment node-name, next, previous, up +@section Automount Filesystem (@samp{type:=auto}) +@cindex Automount filesystem +@cindex Map cache types +@cindex Setting map cache parameters +@cindex How to set map cache parameters +@cindex How to start an indirect automount point +@cindex auto, filesystem type +@cindex Filesystem type; auto +@cindex SIGHUP signal +@cindex Map cache synchronising +@cindex Synchronising the map cache +@cindex Map cache options +@cindex Regular expressions in maps + +The @dfn{auto} filesystem type creates a new automount point below an +existing automount point. Top-level automount points appear as system +mount points. An automount mount point can also appear as a +sub-directory of an existing automount point. This allows some +additional structure to be added, for example to mimic the mount tree of +another machine. + +The following options may be specified: + +@table @code +@cindex cache, mount option +@cindex Mount option; cache +@item cache +specifies whether the data in this mount-map should be +cached. The default value is @samp{none}, in which case +no caching is done in order to conserve memory. +However, better performance and reliability can be obtained by caching +some or all of a mount-map. + +If the cache option specifies @samp{all}, +the entire map is enumerated when the mount point is created. + +If the cache option specifies @samp{inc}, caching is done incrementally +as and when data is required. +Some map types do not support cache mode @samp{all}, in which case @samp{inc} +is used whenever @samp{all} is requested. + +Caching can be entirely disabled by using cache mode @samp{none}. + +If the cache option specifies @samp{regexp} then the entire map will be +enumerated and each key will be treated as an egrep-style regular +expression. The order in which a cached map is searched does not +correspond to the ordering in the source map so the regular expressions +should be mutually exclusive to avoid confusion. + +Each mount map type has a default cache type, usually @samp{inc}, which +can be selected by specifying @samp{mapdefault}. + +The cache mode for a mount map can only be selected on the command line. +Starting @i{Amd} with the command: + +@example +amd /homes hesiod.homes -cache:=inc +@end example + +will cause @samp{/homes} to be automounted using the @dfn{Hesiod} name +server with local incremental caching of all succesfully resolved names. + +All cached data is forgotten whenever @i{Amd} receives a @samp{SIGHUP} +signal and, if cache @samp{all} mode was selected, the cache will be +reloaded. This can be used to inform @i{Amd} that a map has been +updated. In addition, whenever a cache lookup fails and @i{Amd} needs +to examine a map, the map's modify time is examined. If the cache is +out of date with respect to the map then it is flushed as if a +@samp{SIGHUP} had been received. + +An additional option (@samp{sync}) may be specified to force @i{Amd} to +check the map's modify time whenever a cached entry is being used. For +example, an incremental, synchronised cache would be created by the +following command: + +@example +amd /homes hesiod.homes -cache:=inc,sync +@end example + +@item fs +specifies the name of the mount map to use for the new mount point. + +Arguably this should have been specified with the @code{$@{rfs@}} option but +we are now stuck with it due to historical accident. + +@c %If the string @samp{.} is used then the same map is used; +@c %in addition the lookup prefix is set to the name of the mount point followed +@c %by a slash @samp{/}. +@c %This is the same as specifying @samp{fs:=\$@{map@};pref:=\$@{key@}/}. +@c + +@item pref +alters the name that is looked up in the mount map. If +@code{$@{pref@}}, the @dfn{prefix}, is non-null then it is prepended to +the name requested by the kernel @dfn{before} the map is searched. +@end table + +The server @samp{dylan.doc.ic.ac.uk} has two user disks: +@samp{/dev/dsk/2s0} and @samp{/dev/dsk/5s0}. These are accessed as +@samp{/home/dylan/dk2} and @samp{/home/dylan/dk5} respectively. Since +@samp{/home} is already an automount point, this naming is achieved with +the following map entries:@refill + +@example +dylan type:=auto;fs:=$@{map@};pref:=$@{key@}/ +dylan/dk2 type:=ufs;dev:=/dev/dsk/2s0 +dylan/dk5 type:=ufs;dev:=/dev/dsk/5s0 +@end example + +@node Direct Automount Filesystem, Union Filesystem, Automount Filesystem, Filesystem Types +@comment node-name, next, previous, up +@section Direct Automount Filesystem (@samp{type:=direct}) +@cindex Direct automount filesystem +@cindex How to start a direct automount point +@cindex direct, filesystem type +@cindex Filesystem type; direct + +The @dfn{direct} filesystem is almost identical to the automount +filesystem. Instead of appearing to be a directory of mount points, it +appears as a symbolic link to a mounted filesystem. The mount is done +at the time the link is accessed. @xref{Automount Filesystem} for a +list of required options. + +Direct automount points are created by specifying the @samp{direct} +filesystem type on the command line: + +@example +amd ... /usr/man auto.direct -type:=direct +@end example + +where @samp{auto.direct} would contain an entry such as: + +@example +usr/man -type:=nfs;rfs:=/usr/man \ + rhost:=man-server1 rhost:=man-server2 +@end example + +In this example, @samp{man-server1} and @samp{man-server2} are file +servers which export copies of the manual pages. Note that the key +which is looked up is the name of the automount point without the +leading @samp{/}. + +@node Union Filesystem, Error Filesystem, Direct Automount Filesystem, Filesystem Types +@comment node-name, next, previous, up +@section Union Filesystem (@samp{type:=union}) +@cindex Union filesystem +@cindex union, filesystem type +@cindex Filesystem type; union + +The @dfn{union} filesystem type allows the contents of several +directories to be merged and made visible in a single directory. This +can be used to overcome one of the major limitations of the Unix mount +mechanism which only allows complete directories to be mounted. + +For example, supposing @file{/tmp} and @file{/var/tmp} were to be merged +into a new directory called @file{/mtmp}, with files in @file{/var/tmp} +taking precedence. The following command could be used to achieve this +effect: + +@example +amd ... /mtmp union:/tmp:/var/tmp -type:=union +@end example + +Currently, the unioned directories must @emph{not} be automounted. That +would cause a deadlock. This seriously limits the current usefulness of +this filesystem type and the problem will be addressed in a future +release of @i{Amd}. + +Files created in the union directory are actually created in the last +named directory. This is done by creating a wildcard entry which points +to the correct directory. The wildcard entry is visible if the union +directory is listed, so allowing you to see which directory has +priority. + +The files visible in the union directory are computed at the time +@i{Amd} is started, and are not kept uptodate with respect to the +underlying directories. Similarly, if a link is removed, for example +with the @samp{rm} command, it will be lost forever. + +@node Error Filesystem, Top-level Filesystem, Union Filesystem, Filesystem Types +@comment node-name, next, previous, up +@section Error Filesystem (@samp{type:=error}) +@cindex Error filesystem +@cindex error, filesystem type +@cindex Filesystem type; error + +The @dfn{error} filesystem type is used internally as a catch-all in +the case where none of the other filesystems was selected, or some other +error occurred. +Lookups and mounts always fail with ``No such file or directory''. +All other operations trivially succeed. + +The error filesystem is not directly accessible. + +@node Top-level Filesystem, Root Filesystem, Error Filesystem, Filesystem Types +@comment node-name, next, previous, up +@section Top-level Filesystem (@samp{type:=toplvl}) +@cindex Top level filesystem +@cindex toplvl, filesystem type +@cindex Filesystem type; toplvl + +The @dfn{toplvl} filesystems is derived from the @samp{auto} filesystem +and is used to mount the top-level automount nodes. Requests of this +type are automatically generated from the command line arguments and +can also be passed in by using the ``-M'' option of the @dfn{Amq} command. + +@node Root Filesystem, Inheritance Filesystem, Top-level Filesystem, Filesystem Types +@comment node-name, next, previous, up +@section Root Filesystem +@cindex Root filesystem +@cindex root, filesystem type +@cindex Filesystem type; root + +The @dfn{root} (@samp{type:=root}) filesystem type acts as an internal +placeholder onto which @i{Amd} can pin @samp{toplvl} mounts. Only one +node of this type need ever exist and one is created automatically +during startup. The effect of creating a second root node is undefined. + +@node Inheritance Filesystem, , Root Filesystem, Filesystem Types +@comment node-name, next, previous, up +@section Inheritance Filesystem +@cindex Inheritance filesystem +@cindex Nodes generated on a restart +@cindex inherit, filesystem type +@cindex Filesystem type; inherit + +The @dfn{inheritance} (@samp{type:=inherit}) filesystem is not directly +accessible. Instead, internal mount nodes of this type are +automatically generated when @i{Amd} is started with the ``-r'' option. +At this time the system mount table is scanned to locate any filesystems +which are already mounted. If any reference to these filesystems is +made through @i{Amd} then instead of attempting to mount it, @i{Amd} +simulates the mount and @dfn{inherits} the filesystem. This allows a +new version of @i{Amd} to be installed on a live system simply by +killing the old daemon with @code{SIGTERM} and starting the new one.@refill + +This filesystem type is not generally visible externally, but it is +possible that the output from @samp{amq -m} may list @samp{inherit} as +the filesystem type. This happens when an inherit operation cannot +be completed for some reason, usually because a fileserver is down. + +@node Run-time Administration, FSinfo, Filesystem Types, Top +@comment node-name, next, previous, up +@chapter Run-time Administration +@cindex Run-time administration +@cindex Amq command + +@menu +* Starting Amd:: +* Stopping Amd:: +* Controlling Amd:: +@end menu + +@node Starting Amd, Stopping Amd, Run-time Administration, Run-time Administration +@comment node-name, next, previous, up +@section Starting @i{Amd} +@cindex Starting Amd +@cindex Additions to /etc/rc.local +@cindex /etc/rc.local additions +@cindex /etc/amd.start + +@i{Amd} is best started from @samp{/etc/rc.local}: + +@example +if [ -f /etc/amd.start ]; then + sh /etc/amd.start; (echo -n ' amd') >/dev/console +fi +@end example + +@noindent +The shell script, @samp{amd.start}, contains: + +@example +#!/bin/sh - +PATH=/etc:/bin:/usr/bin:/usr/ucb:$PATH export PATH + +# +# Either name of logfile or "syslog" +# +LOGFILE=syslog +#LOGFILE=/var/log/amd + +# +# Figure out whether domain name is in host name +# If the hostname is just the machine name then +# pass in the name of the local domain so that the +# hostnames in the map are domain stripped correctly. +# +case `hostname` in +*.*) dmn= ;; +*) dmn='-d doc.ic.ac.uk' +esac + +# +# Zap earlier log file +# +case "$LOGFILE" in +*/*) + mv "$LOGFILE" "$LOGFILE"- + > "$LOGFILE" + ;; +syslog) + : nothing + ;; +esac + +cd /usr/sbin +# +# -r restart +# -d dmn local domain +# -w wait wait between unmount attempts +# -l log logfile or "syslog" +# +eval ./amd -r $dmn -w 240 -l "$LOGFILE" \ + /homes amd.homes -cache:=inc \ + /home amd.home -cache:=inc \ + /vol amd.vol -cache:=inc \ + /n amd.net -cache:=inc +@end example + +If the list of automount points and maps is contained in a file or NIS map +it is easily incorporated onto the command line: + +@example +... +eval ./amd -r $dmn -w 240 -l "$LOGFILE" `ypcat -k auto.master` +@end example + +@node Stopping Amd, Controlling Amd, Starting Amd, Run-time Administration +@comment node-name, next, previous, up +@section Stopping @i{Amd} +@cindex Stopping Amd +@cindex SIGTERM signal +@cindex SIGINT signal + +@i{Amd} stops in response to two signals. + +@table @samp +@item SIGTERM +causes the top-level automount points to be unmounted and then @i{Amd} +to exit. Any automounted filesystems are left mounted. They can be +recovered by restarting @i{Amd} with the ``-r'' command line option.@refill + +@item SIGINT +causes @i{Amd} to attempt to unmount any filesystems which it has +automounted, in addition to the actions of @samp{SIGTERM}. This signal +is primarly used for debugging.@refill +@end table + +Actions taken for other signals are undefined. + +@node Controlling Amd, , Stopping Amd, Run-time Administration +@comment node-name, next, previous, up +@section Controlling @i{Amd} +@cindex Controlling Amd +@cindex Discovering what is going on at run-time +@cindex Listing currently mounted filesystems + +It is sometimes desirable or necessary to exercise external control +over some of @i{Amd}'s internal state. To support this requirement, +@i{Amd} implements an RPC interface which is used by the @dfn{Amq} program. +A variety of information is available. + +@i{Amq} generally applies an operation, specified by a single letter option, +to a list of mount points. The default operation is to obtain statistics +about each mount point. This is similar to the output shown above +but includes information about the number and type of accesses to each +mount point. + +@menu +* Amq default:: Default command behaviour. +* Amq -f option:: Flushing the map cache. +* Amq -h option:: Controlling a non-local host. +* Amq -m option:: Obtaining mount statistics. +* Amq -M-option:: Mounting a volume. +* Amq -s option:: Obtaining global statistics. +* Amq -u option:: Forcing volumes to time out. +* Amq -v option:: Version information. +* Other Amq options:: Three other special options. +@end menu + +@node Amq default, Amq -f option, Controlling Amd, Controlling Amd +@comment node-name, next, previous, up +@subsection @i{Amq} default information + +With no arguments, @dfn{Amq} obtains a brief list of all existing +mounts created by @i{Amd}. This is different from the list displayed by +@b{df}(1) since the latter only includes system mount points. + +@noindent +The output from this option includes the following information: + +@itemize @bullet +@item +the automount point, +@item +the filesystem type, +@item +the mount map or mount information, +@item +the internal, or system mount point. +@end itemize + +@noindent +For example: + +@example +/ root "root" sky:(pid75) +/homes toplvl /usr/local/etc/amd.homes /homes +/home toplvl /usr/local/etc/amd.home /home +/homes/jsp nfs charm:/home/charm /a/charm/home/charm/jsp +/homes/phjk nfs toytown:/home/toytown /a/toytown/home/toytown/ai/phjk +@end example + +@noindent +If an argument is given then statistics for that volume name will +be output. For example: + +@example +What Uid Getattr Lookup RdDir RdLnk Statfs Mounted@@ +/homes 0 1196 512 22 0 30 90/09/14 12:32:55 +/homes/jsp 0 0 0 0 1180 0 90/10/13 12:56:58 +@end example + +@table @code +@item What +the volume name. + +@item Uid +ignored. + +@item Getattr +the count of NFS @dfn{getattr} requests on this node. This should only be +non-zero for directory nodes. + +@item Lookup +the count of NFS @dfn{lookup} requests on this node. This should only be +non-zero for directory nodes. + +@item RdDir +the count of NFS @dfn{readdir} requests on this node. This should only +be non-zero for directory nodes. + +@item RdLnk +the count of NFS @dfn{readlink} requests on this node. This should be +zero for directory nodes. + +@item Statfs +the could of NFS @dfn{statfs} requests on this node. This should only +be non-zero for top-level automount points. + +@item Mounted@@ +the date and time the volume name was first referenced. +@end table + +@node Amq -f option, Amq -h option, Amq default, Controlling Amd +@comment node-name, next, previous, up +@subsection @i{Amq} -f option +@cindex Flushing the map cache +@cindex Map cache, flushing + +The ``-f'' option causes @i{Amd} to flush the internal mount map cache. +This is useful for Hesiod maps since @i{Amd} will not automatically +notice when they have been updated. The map cache can also be +synchronised with the map source by using the @samp{sync} option +(@pxref{Automount Filesystem}).@refill + +@node Amq -h option, Amq -m option, Amq -f option, Controlling Amd +@comment node-name, next, previous, up +@subsection @i{Amq} -h option +@cindex Querying an alternate host + +By default the local host is used. In an HP-UX cluster the root server +is used since that is the only place in the cluster where @i{Amd} will +be running. To query @i{Amd} on another host the ``-h'' option should +be used. + +@node Amq -m option, Amq -M-option, Amq -h option, Controlling Amd +@comment node-name, next, previous, up +@subsection @i{Amq} -m option + +The ``-m'' option displays similar information about mounted +filesystems, rather than automount points. The output includes the +following information: + +@itemize @bullet +@item +the mount information, +@item +the mount point, +@item +the filesystem type, +@item +the number of references to this filesystem, +@item +the server hostname, +@item +the state of the file server, +@item +any error which has occured. +@end itemize + +For example: + +@example +"root" truth:(pid602) root 1 localhost is up +hesiod.home /home toplvl 1 localhost is up +hesiod.vol /vol toplvl 1 localhost is up +hesiod.homes /homes toplvl 1 localhost is up +amy:/home/amy /a/amy/home/amy nfs 5 amy is up +swan:/home/swan /a/swan/home/swan nfs 0 swan is up (Permission denied) +ex:/home/ex /a/ex/home/ex nfs 0 ex is down +@end example + +When the reference count is zero the filesystem is not mounted but +the mount point and server information is still being maintained +by @i{Amd}. + +@node Amq -M-option, Amq -s option, Amq -m option, Controlling Amd +@comment node-name, next, previous, up +@subsection @i{Amq} -M option + +The ``-M'' option passes a new map entry to @i{Amd} and waits for it to +be evaluated, possibly causing a mount. For example, the following +command would cause @samp{/home/toytown} on host @samp{toytown} to be +mounted locally on @samp{/mnt/toytown}. + +@example +amq -M '/mnt/toytown type:=nfs;rfs:=/home/toytown;rhost:=toytown;fs:=$@{key@}' +@end example + +@i{Amd} applies some simple security checks before allowing this +operation. The check tests whether the incoming request is from a +privileged UDP port on the local machine. ``Permission denied'' is +returned if the check fails. + +A future release of @i{Amd} will include code to allow the @b{mount}(8) +command to mount automount points: + +@example +mount -t amd /vol hesiod.vol +@end example + +This will then allow @i{Amd} to be controlled from the standard system +filesystem mount list. + +@node Amq -s option, Amq -u option, Amq -M-option, Controlling Amd +@comment node-name, next, previous, up +@subsection @i{Amq} -s option +@cindex Global statistics +@cindex Statistics + +The ``-s'' option displays global statistics. If any other options are specified +or any filesystems named then this option is ignored. For example: + +@example +requests stale mount mount unmount +deferred fhandles ok failed failed +1054 1 487 290 7017 +@end example + +@table @samp +@item Deferred requests +are those for which an immediate reply could not be constructed. For +example, this would happen if a background mount was required. + +@item Stale filehandles +counts the number of times the kernel passes a stale filehandle to @i{Amd}. +Large numbers indicate problems. + +@item Mount ok +counts the number of automounts which were successful. + +@item Mount failed +counts the number of automounts which failed. + +@item Unmount failed +counts the number of times a filesystem could not be unmounted. Very +large numbers here indicate that the time between unmount attempts +should be increased. +@end table + +@node Amq -u option, Amq -v option, Amq -s option, Controlling Amd +@comment node-name, next, previous, up +@subsection @i{Amq} -u option +@cindex Forcing filesystem to time out +@cindex Unmounting a filesystem + +The ``-u'' option causes the time-to-live interval of the named mount +points to be expired, thus causing an unmount attempt. This is the only +safe way to unmount an automounted filesystem. It is not possible to +unmount a filesystem which has been mounted with the @samp{nounmount} +flag. + +@c The ``-H'' option informs @i{Amd} that the specified mount point has hung - +@c as if its keepalive timer had expired. + +@node Amq -v option, Other Amq options, Amq -u option, Controlling Amd +@comment node-name, next, previous, up +@subsection @i{Amq} -v option +@cindex Version information at run-time + +The ``-v'' option displays the version of @i{Amd} in a similar way to +@i{Amd}'s ``-v'' option. + +@node Other Amq options, , Amq -v option, Controlling Amd +@comment node-name, next, previous, up +@subsection Other @i{Amq} options + +Three other operations are implemented. These modify the state of +@i{Amd} as a whole, rather than any particular filesystem. The ``-l'', +``-x'' and ``-D'' options have exactly the same effect as @i{Amd}'s +corresponding command line options. The ``-l'' option is rejected by +@i{Amd} in the current version for obvious security reasons. When +@i{Amd} receives a ``-x''flag it limits the log options being modified +to those which were not enabled at startup. This prevents a user +turning @emph{off} any logging option which was specified at startup, +though any which have been turned off since then can still be turned +off. The ``-D'' option has a similar behaviour. + +@node FSinfo, Examples, Run-time Administration, Top +@comment node-name, next, previous, up +@chapter FSinfo +@cindex FSinfo +@cindex Filesystem info package + +@menu +* FSinfo Overview:: Introduction to FSinfo. +* Using FSinfo:: Basic concepts. +* FSinfo Grammar:: Language syntax, semantics and examples. +* FSinfo host definitions:: Defining a new host. +* FSinfo host attributes:: Definable host attributes. +* FSinfo filesystems:: Defining locally attached filesystems. +* FSinfo static mounts:: Defining additional static mounts. +* FSinfo automount definitions:: +* FSinfo command line options:: +* FSinfo errors:: +@end menu + +@node FSinfo Overview, Using FSinfo, FSinfo, FSinfo +@comment node-name, next, previous, up +@section @i{FSinfo} overview +@cindex FSinfo overview + +@i{FSinfo} is a filesystem management tool. It has been designed to +work with @i{Amd} to help system administrators keep track of the ever +increasing filesystem namespace under their control. + +The purpose of @i{FSinfo} is to generate all the important standard +filesystem data files from a single set of input data. Starting with a +single data source guarantees that all the generated files are +self-consistent. One of the possible output data formats is a set of +@i{Amd} maps which can be used amongst the set of hosts described in the +input data. + +@i{FSinfo} implements a declarative language. This language is +specifically designed for describing filesystem namespace and physical +layouts. The basic declaration defines a mounted filesystem including +its device name, mount point, and all the volumes and access +permissions. @i{FSinfo} reads this information and builds an internal +map of the entire network of hosts. Using this map, many different data +formats can be produced including @file{/etc/fstab}, +@file{/etc/exports}, @i{Amd} mount maps and +@file{/etc/bootparams}.@refill + +@node Using FSinfo, FSinfo Grammar, FSinfo Overview, FSinfo +@comment node-name, next, previous, up +@section Using @i{FSinfo} +@cindex Using FSinfo + +The basic strategy when using @i{FSinfo} is to gather all the +information about all disks on all machines into one set of +declarations. For each machine being managed, the following data is +required: + +@itemize @bullet +@item +Hostname +@item +List of all filesystems and, optionally, their mount points. +@item +Names of volumes stored on each filesystem. +@item +NFS export information for each volume. +@item +The list of static filesystem mounts. +@end itemize + +The following information can also be entered into the same +configuration files so that all data can be kept in one place. + +@itemize @bullet +@item +List of network interfaces +@item +IP address of each interface +@item +Hardware address of each interface +@item +Dumpset to which each filesystem belongs +@item +and more @dots{} +@end itemize + +To generate @i{Amd} mount maps, the automount tree must also be defined +(@pxref{FSinfo automount definitions}). This will have been designed at +the time the volume names were allocated. Some volume names will not be +automounted, so @i{FSinfo} needs an explicit list of which volumes +should be automounted.@refill + +Hostnames are required at several places in the @i{FSinfo} language. It +is important to stick to either fully qualified names or unqualified +names. Using a mixture of the two will inevitably result in confusion. + +Sometimes volumes need to be referenced which are not defined in the set +of hosts being managed with @i{FSinfo}. The required action is to add a +dummy set of definitions for the host and volume names required. Since +the files generated for those particular hosts will not be used on them, +the exact values used is not critical. + +@node FSinfo Grammar, FSinfo host definitions, Using FSinfo, FSinfo +@comment node-name, next, previous, up +@section @i{FSinfo} grammar +@cindex FSinfo grammar +@cindex Grammar, FSinfo + +@i{FSinfo} has a relatively simple grammar. Distinct syntactic +constructs exist for each of the different types of data, though they +share a common flavour. Several conventions are used in the grammar +fragments below. + +The notation, @i{list(}@t{xxx}@i{)}, indicates a list of zero or more +@t{xxx}'s. The notation, @i{opt(}@t{xxx}@i{)}, indicates zero or one +@t{xxx}. Items in double quotes, @i{eg} @t{"host"}, represent input +tokens. Items in angle brackets, @i{eg} @var{}, represent +strings in the input. Strings need not be in double quotes, except to +differentiate them from reserved words. Quoted strings may include the +usual set of C ``@t{\}'' escape sequences with one exception: a +backslash-newline-whitespace sequence is squashed into a single space +character. To defeat this feature, put a further backslash at the start +of the second line. + +At the outermost level of the grammar, the input consists of a +sequence of host and automount declarations. These declarations are +all parsed before they are analyzed. This means they can appear in +any order and cyclic host references are possible. + +@example +fsinfo : @i{list(}fsinfo_attr@i{)} ; + +fsinfo_attr : host | automount ; +@end example + +@menu +* FSinfo host definitions:: +* FSinfo automount definitions:: +@end menu + +@node FSinfo host definitions, FSinfo host attributes, FSinfo grammar, FSinfo +@comment node-name, next, previous, up +@section @i{FSinfo} host definitions +@cindex FSinfo host definitions +@cindex Defining a host, FSinfo + +A host declaration consists of three parts: a set of machine attribute +data, a list of filesystems physically attached to the machine, and a +list of additional statically mounted filesystems. + +@example +host : "host" host_data @i{list(}filesystem@i{@i{)}} @i{list(}mount@i{@i{)}} ; +@end example + +Each host must be declared in this way exactly once. Such things as the +hardware address, the architecture and operating system types and the +cluster name are all specified within the @dfn{host data}. + +All the disks the machine has should then be described in the @dfn{list +of filesystems}. When describing disks, you can specify what +@dfn{volname} the disk/partition should have and all such entries are +built up into a dictionary which can then be used for building the +automounter maps. + +The @dfn{list of mounts} specifies all the filesystems that should be +statically mounted on the machine. + +@menu +* FSinfo host attributes:: +* FSinfo filesystems:: +* FSinfo static mounts:: +@end menu + +@node FSinfo host attributes, FSinfo filesystems, FSinfo host definitions , FSinfo host definitions +@comment node-name, next, previous, up +@section @i{FSinfo} host attributes +@cindex FSinfo host attributes +@cindex Defining host attributes, FSinfo + +The host data, @dfn{host_data}, always includes the @dfn{hostname}. In +addition, several other host attributes can be given. + +@example +host_data : @var{} + | "@{" @i{list(}host_attrs@i{)} "@}" @var{} + ; + +host_attrs : host_attr "=" @var{} + | netif + ; + +host_attr : "config" + | "arch" + | "os" + | "cluster" + ; +@end example + +The @dfn{hostname} is, typically, the fully qualified hostname of the +machine. + +Examples: + +@example +host dylan.doc.ic.ac.uk + +host @{ + os = hpux + arch = hp300 +@} dougal.doc.ic.ac.uk +@end example + +The options that can be given as host attributes are shown below. + +@menu +* netif Option: FSinfo host netif: +* config Option: FSinfo host config: +* arch Option: FSinfo host arch: +* os Option: FSinfo host os: +* cluster Option: FSinfo host cluster: +@end menu + +@node FSinfo host netif, FSinfo host config, , FSinfo host attributes +@comment node-name, next, previous, up +@subsection netif Option + +This defines the set of network interfaces configured on the machine. +The interface attributes collected by @i{FSinfo} are the IP address, +subnet mask and hardware address. Multiple interfaces may be defined +for hosts with several interfaces by an entry for each interface. The +values given are sanity checked, but are currently unused for anything +else. + +@example +netif : "netif" @var{} "@{" @i{list(}netif_attrs@i{)} "@}" ; + +netif_attrs : netif_attr "=" @var{} ; + +netif_attr : "inaddr" | "netmask" | "hwaddr" ; +@end example + +Examples: + +@example +netif ie0 @{ + inaddr = 129.31.81.37 + netmask = 0xfffffe00 + hwaddr = "08:00:20:01:a6:a5" +@} + +netif ec0 @{ @} +@end example + +@node FSinfo host config, FSinfo host arch, FSinfo host netif, FSinfo host attributes +@comment node-name, next, previous, up +@subsection config Option +@cindex FSinfo config host attribute +@cindex config, FSinfo host attribute + +This option allows you to specify configuration variables for the +startup scripts (@file{rc} scripts). A simple string should immediately +follow the keyword. + +Example: + +@example +config "NFS_SERVER=true" +config "ZEPHYR=true" +@end example + +This option is currently unsupported. + +@node FSinfo host arch, FSinfo host os, FSinfo host config, FSinfo host attributes +@comment node-name, next, previous, up +@subsection arch Option +@cindex FSinfo arch host attribute +@cindex arch, FSinfo host attribute + +This defines the architecture of the machine. For example: + +@example +arch = hp300 +@end example + +This is intended to be of use when building architecture specific +mountmaps, however, the option is currently unsupported. + +@node FSinfo host os, FSinfo host cluster, FSinfo host arch, FSinfo host attributes +@comment node-name, next, previous, up +@subsection os Option +@cindex FSinfo os host attribute +@cindex os, FSinfo host attribute + +This defines the operating system type of the host. For example: + +@example +os = hpux +@end example + +This information is used when creating the @file{fstab} files, for +example in choosing which format to use for the @file{fstab} entries +within the file. + +@node FSinfo host cluster, , FSinfo host os, FSinfo host attributes +@comment node-name, next, previous, up +@subsection cluster Option +@cindex FSinfo cluster host attribute +@cindex cluster, FSinfo host attribute + +This is used for specifying in which cluster the machine belongs. For +example: + +@example +cluster = "theory" +@end example + +The cluster is intended to be used when generating the automount maps, +although it is currently unsupported. + +@node FSinfo filesystems, FSinfo static mounts, FSinfo host attributes, FSinfo host definitions +@comment node-name, next, previous, up +@section @i{FSinfo} filesystems +@cindex FSinfo filesystems + +The list of physically attached filesystems follows the machine +attributes. These should define all the filesystems available from this +machine, whether exported or not. In addition to the device name, +filesystems have several attributes, such as filesystem type, mount +options, and @samp{fsck} pass number which are needed to generate +@file{fstab} entries. + +@example +filesystem : "fs" @var{} "@{" @i{list(}fs_data@i{)} "@}" ; + +fs_data : fs_data_attr "=" @var{} + | mount + ; + +fs_data_attr + : "fstype" | "opts" | "passno" + | "freq" | "dumpset" | "log" + ; +@end example + +Here, @var{} is the device name of the disk (for example, +@file{/dev/dsk/2s0}). The device name is used for building the mount +maps and for the @file{fstab} file. The attributes that can be +specified are shown in the following section. + +The @i{FSinfo} configuration file for @code{dylan.doc.ic.ac.uk} is listed below. + +@example +host dylan.doc.ic.ac.uk + +fs /dev/dsk/0s0 @{ + fstype = swap +@} + +fs /dev/dsk/0s0 @{ + fstype = hfs + opts = rw,noquota,grpid + passno = 0; + freq = 1; + mount / @{ @} +@} + +fs /dev/dsk/1s0 @{ + fstype = hfs + opts = defaults + passno = 1; + freq = 1; + mount /usr @{ + local @{ + exportfs "dougal eden dylan zebedee brian" + volname /nfs/hp300/local + @} + @} +@} + +fs /dev/dsk/2s0 @{ + fstype = hfs + opts = defaults + passno = 1; + freq = 1; + mount default @{ + exportfs "toytown_clients hangers_on" + volname /home/dylan/dk2 + @} +@} + +fs /dev/dsk/3s0 @{ + fstype = hfs + opts = defaults + passno = 1; + freq = 1; + mount default @{ + exportfs "toytown_clients hangers_on" + volname /home/dylan/dk3 + @} +@} + +fs /dev/dsk/5s0 @{ + fstype = hfs + opts = defaults + passno = 1; + freq = 1; + mount default @{ + exportfs "toytown_clients hangers_on" + volname /home/dylan/dk5 + @} +@} +@end example + +@menu +* fstype Option: FSinfo filesystems fstype: +* opts Option: FSinfo filesystems opts: +* passno Option: FSinfo filesystems passno: +* freq Option: FSinfo filesystems freq: +* mount Option: FSinfo filesystems mount: +* dumpset Option: FSinfo filesystems dumpset: +* log Option: FSinfo filesystems log: +@end menu + +@node FSinfo filesystems fstype, FSinfo filesystems opts, , FSinfo filesystems +@comment node-name, next, previous, up +@subsection fstype Option +@cindex FSinfo fstype filesystems option +@cindex fstype, FSinfo filesystems option +@cindex export, FSinfo special fstype + +This specifies the type of filesystem being declared and will be placed +into the @file{fstab} file as is. The value of this option will be +handed to @code{mount} as the filesystem type---it should have such +values as @code{4.2}, @code{nfs} or @code{swap}. The value is not +examined for correctness. + +There is one special case. If the filesystem type is specified as +@samp{export} then the filesystem information will not be added to the +host's @file{fstab} information, but it will still be visible on the +network. This is useful for defining hosts which contain referenced +volumes but which are not under full control of @i{FSinfo}. + +Example: + +@example +fstype = swap +@end example + +@node FSinfo filesystems opts, FSinfo filesystems passno,FSinfo filesystems fstype, FSinfo filesystems +@comment node-name, next, previous, up +@subsection opts Option +@cindex FSinfo opts filesystems option +@cindex opts, FSinfo filesystems option + +This defines any options that should be given to @b{mount}(8) in the +@file{fstab} file. For example: + +@example +opts = rw,nosuid,grpid +@end example + +@node FSinfo filesystems passno, FSinfo filesystems freq, FSinfo filesystems opts, FSinfo filesystems +@comment node-name, next, previous, up +@subsection passno Option +@cindex FSinfo passno filesystems option +@cindex passno, FSinfo filesystems option + +This defines the @b{fsck}(8) pass number in which to check the +filesystem. This value will be placed into the @file{fstab} file. + +Example: + +@example +passno = 1 +@end example + +@node FSinfo filesystems freq, FSinfo filesystems mount, FSinfo filesystems passno, FSinfo filesystems +@comment node-name, next, previous, up +@subsection freq Option +@cindex FSinfo freq filesystems option +@cindex freq, FSinfo filesystems option + +This defines the interval (in days) between dumps. The value is placed +as is into the @file{fstab} file. + +Example: + +@example +freq = 3 +@end example + +@node FSinfo filesystems mount, FSinfo filesystems dumpset, FSinfo filesystems freq, FSinfo filesystems +@comment node-name, next, previous, up +@subsection mount Option +@cindex FSinfo mount filesystems option +@cindex mount, FSinfo filesystems option +@cindex exportfs, FSinfo mount option +@cindex volname, FSinfo mount option +@cindex sel, FSinfo mount option + +This defines the mountpoint at which to place the filesystem. If the +mountpoint of the filesystem is specified as @code{default}, then the +filesystem will be mounted in the automounter's tree under its volume +name and the mount will automatically be inherited by the automounter. + +Following the mountpoint, namespace information for the filesystem may +be described. The options that can be given here are @code{exportfs}, +@code{volname} and @code{sel}. + +The format is: + +@example +mount : "mount" vol_tree ; + +vol_tree : @i{list(}vol_tree_attr@i{)} ; + +vol_tree_attr + : @var{} "@{" @i{list(}vol_tree_info@i{)} vol_tree "@}" ; + +vol_tree_info + : "exportfs" @var{} + | "volname" @var{} + | "sel" @var{} + ; +@end example + +Example: + +@example +mount default @{ + exportfs "dylan dougal florence zebedee" + volname /vol/andrew +@} +@end example + +In the above example, the filesystem currently being declared will have +an entry placed into the @file{exports} file allowing the filesystem to +be exported to the machines @code{dylan}, @code{dougal}, @code{florence} +and @code{zebedee}. The volume name by which the filesystem will be +referred to remotely, is @file{/vol/andrew}. By declaring the +mountpoint to be @code{default}, the filesystem will be mounted on the +local machine in the automounter tree, where @i{Amd} will automatically +inherit the mount as @file{/vol/andrew}.@refill + +@table @samp +@item exportfs +a string defining which machines the filesystem may be exported to. +This is copied, as is, into the @file{exports} file---no sanity checking +is performed on this string.@refill + +@item volname +a string which declares the remote name by which to reference the +filesystem. The string is entered into a dictionary and allows you to +refer to this filesystem in other places by this volume name.@refill + +@item sel +a string which is placed into the automounter maps as a selector for the +filesystem.@refill + +@end table + +@node FSinfo filesystems dumpset, FSinfo filesystems log, FSinfo filesystems mount, FSinfo filesystems +@comment node-name, next, previous, up +@subsection dumpset Option +@cindex FSinfo dumpset filesystems option +@cindex dumpset, FSinfo filesystems option + +This provides support for Imperial College's local file backup tools and +is not documented further here. + +@node FSinfo filesystems log, , FSinfo filesystems dumpset, FSinfo filesystems +@comment node-name, next, previous, up +@subsection log Option +@cindex FSinfo log filesystems option +@cindex log, FSinfo filesystems option + +Specifies the log device for the current filesystem. This is ignored if +not required by the particular filesystem type. + +@node FSinfo static mounts, FSinfo automount definitions , FSinfo filesystems, FSinfo host definitions +@comment node-name, next, previous, up +@section @i{FSinfo} static mounts +@cindex FSinfo static mounts +@cindex Statically mounts filesystems, FSinfo + +Each host may also have a number of statically mounted filesystems. For +example, the host may be a diskless workstation in which case it will +have no @code{fs} declarations. In this case the @code{mount} +declaration is used to determine from where its filesystems will be +mounted. In addition to being added to the @file{fstab} file, this +information can also be used to generate a suitable @file{bootparams} +file.@refill + +@example +mount : "mount" @var{} @i{list(}localinfo@i{)} ; + +localinfo : localinfo_attr @var{} ; + +localinfo_attr + : "as" + | "from" + | "fstype" + | "opts" + ; +@end example + +The filesystem specified to be mounted will be searched for in the +dictionary of volume names built when scanning the list of hosts' +definitions. + +The attributes have the following semantics: +@table @samp +@item from @var{machine} +mount the filesystem from the machine with the hostname of +@dfn{machine}.@refill + +@item as @var{mountpoint} +mount the filesystem locally as the name given, in case this is +different from the advertised volume name of the filesystem. + +@item opts @var{options} +native @b{mount}(8) options. + +@item fstype @var{type} +type of filesystem to be mounted. +@end table + +An example: + +@example +mount /export/exec/hp300/local as /usr/local +@end example + +If the mountpoint specified is either @file{/} or @file{swap}, the +machine will be considered to be booting off the net and this will be +noted for use in generating a @file{bootparams} file for the host which +owns the filesystems. + +@node FSinfo automount definitions, FSinfo Command Line Options, FSinfo static mounts, FSinfo +@comment node-name, next, previous, up +@section Defining an @i{Amd} Mount Map in @i{FSinfo} +@cindex FSinfo automount definitions +@cindex Defining an Amd mount map, FSinfo + +The maps used by @i{Amd} can be constructed from @i{FSinfo} by defining +all the automount trees. @i{FSinfo} takes all the definitions found and +builds one map for each top level tree. + +The automount tree is usually defined last. A single automount +configuration will usually apply to an entire management domain. One +@code{automount} declaration is needed for each @i{Amd} automount point. +@i{FSinfo} determines whether the automount point is @dfn{direct} +(@pxref{Direct Automount Filesystem}) or @dfn{indirect} +(@pxref{Top-level Filesystem}). Direct automount points are +distinguished by the fact that there is no underlying +@dfn{automount_tree}.@refill + +@example +automount : "automount" opt(auto_opts@i{)} automount_tree ; + +auto_opts : "opts" @var{} ; + +automount_tree + : @i{list(}automount_attr@i{)} + ; + +automount_attr + : @var{} "=" @var{} + | @var{} "->" @var{} + | @var{} "@{" automount_tree "@}" + ; +@end example + +If @var{} is given, then it is the string to be placed in +the maps for @i{Amd} for the @code{opts} option. + +A @dfn{map} is typically a tree of filesystems, for example @file{home} +normally contains a tree of filesystems representing other machines in +the network. + +A map can either be given as a name representing an already defined +volume name, or it can be a tree. A tree is represented by placing +braces after the name. For example, to define a tree @file{/vol}, the +following map would be defined: + +@example +automount /vol @{ @} +@end example + +Within a tree, the only items that can appear are more maps. +For example: + +@example +automount /vol @{ + andrew @{ @} + X11 @{ @} +@} +@end example + +In this case, @i{FSinfo} will look for volumes named @file{/vol/andrew} +and @file{/vol/X11} and a map entry will be generated for each. If the +volumes are defined more than once, then @i{FSinfo} will generate +a series of alternate entries for them in the maps.@refill + +Instead of a tree, either a link (@var{name} @code{->} +@var{destination}) or a reference can be specified (@var{name} @code{=} +@var{destination}). A link creates a symbolic link to the string +specified, without further processing the entry. A reference will +examine the destination filesystem and optimise the reference. For +example, to create an entry for @code{njw} in the @file{/homes} map, +either of the two forms can be used:@refill + +@example +automount /homes @{ + njw -> /home/dylan/njw +@} +@end example + +or + +@example +automount /homes @{ + njw = /home/dylan/njw +@} +@end example + +In the first example, when @file{/homes/njw} is referenced from @i{Amd}, +a link will be created leading to @file{/home/dylan/njw} and the +automounter will be referenced a second time to resolve this filename. +The map entry would be: + +@example +njw type:=link;fs:=/home/dylan/njw +@end example + +In the second example, the destination directory is analysed and found +to be in the filesystem @file{/home/dylan} which has previously been +defined in the maps. Hence the map entry will look like: + +@example +njw rhost:=dylan;rfs:=/home/dylan;sublink:=njw +@end example + +Creating only one symbolic link, and one access to @i{Amd}. + +@c --------------------------------------------- +@node FSinfo Command Line Options, FSinfo errors, FSinfo automount definitions, FSinfo +@comment node-name, next, previous, up +@section @i{FSinfo} Command Line Options +@cindex FSinfo command line options +@cindex Command line options, FSinfo + +@i{FSinfo} is started from the command line by using the command: + +@example +fsinfo [@i{options}] files ... +@end example + +The input to @i{FSinfo} is a single set of definitions of machines and +automount maps. If multiple files are given on the command-line, then +the files are concatenated together to form the input source. The files +are passed individually through the C pre-processor before being parsed. + +Several options define a prefix for the name of an output file. If the +prefix is not specified no output of that type is produced. The suffix +used will correspond either to the hostname to which a file belongs, or +to the type of output if only one file is produced. Dumpsets and the +@file{bootparams} file are in the latter class. To put the output into +a subdirectory simply put a @file{/} at the end of the prefix, making +sure that the directory has already been made before running +@samp{fsinfo}. + +@menu +* -a FSinfo Option:: Amd automount directory: +* -b FSinfo Option:: Prefix for bootparams files. +* -d FSinfo Option:: Prefix for dumpset data files. +* -e FSinfo Option:: Prefix for exports files. +* -f FSinfo Option:: Prefix for fstab files. +* -h FSinfo Option:: Local hostname. +* -m FSinfo Option:: Prefix for automount maps. +* -q FSinfo Option:: Ultra quiet mode. +* -v FSinfo Option:: Verbose mode. +* -I FSinfo Option:: Define new #include directory. +* -D-FSinfo Option:: Define macro. +* -U FSinfo Option:: Undefine macro. +@end menu + +@node -a FSinfo Option, -b FSinfo Option, FSinfo Command Line Options, FSinfo Command Line Options +@comment node-name, next, previous, up +@subsection @code{-a} @var{autodir} + +Specifies the directory name in which to place the automounter's +mountpoints. This defaults to @file{/a}. Some sites have the autodir set +to be @file{/amd}, and this would be achieved by: + +@example +fsinfo -a /amd ... +@end example + +@node -b FSinfo Option, -d FSinfo Option, -a FSinfo Option, FSinfo Command Line Options +@comment node-name, next, previous, up +@subsection @code{-b} @var{bootparams} +@cindex bootparams, FSinfo prefix + +This specifies the prefix for the @file{bootparams} filename. If it is +not given, then the file will not be generated. The @file{bootparams} +file will be constructed for the destination machine and will be placed +into a file named @file{bootparams} and prefixed by this string. The +file generated contains a list of entries describing each diskless +client that can boot from the destination machine. + +As an example, to create a @file{bootparams} file in the directory +@file{generic}, the following would be used: + +@example +fsinfo -b generic/ ... +@end example + +@node -d FSinfo Option, -e FSinfo Option, -b FSinfo Option, FSinfo Command Line Options +@comment node-name, next, previous, up +@subsection @code{-d} @var{dumpsets} +@cindex dumpset, FSinfo prefix + +This specifies the prefix for the @file{dumpsets} file. If it is not +specified, then the file will not be generated. The file will be for +the destination machine and will be placed into a filename +@file{dumpsets}, prefixed by this string. The @file{dumpsets} file is +for use by Imperial College's local backup system. + +For example, to create a dumpsets file in the directory @file{generic}, +then you would use the following: + +@example +fsinfo -d generic/ ... +@end example + +@node -e FSinfo Option, -f FSinfo Option, -d FSinfo Option, FSinfo Command Line Options +@comment node-name, next, previous, up +@subsection @code{-e} @var{exportfs} +@cindex exports, FSinfo prefix + +Defines the prefix for the @file{exports} files. If it is not given, +then the file will not be generated. For each machine defined in the +configuration files as having disks, an @file{exports} file is +constructed and given a filename determined by the name of the machine, +prefixed with this string. If a machine is defined as diskless, then no +@file{exports} file will be created for it. The files contain entries +for directories on the machine that may be exported to clients. + +Example: To create the @file{exports} files for each diskful machine +and place them into the directory @file{exports}: + +@example +fsinfo -e exports/ ... +@end example + +@node -f FSinfo Option, -h FSinfo Option, -e FSinfo Option, FSinfo Command Line Options +@comment node-name, next, previous, up +@subsection @code{-f} @var{fstab} +@cindex fstab, FSinfo prefix + +This defines the prefix for the @file{fstab} files. The files will only +be created if this prefix is defined. For each machine defined in the +configuration files, a @file{fstab} file is created with the filename +determined by prefixing this string with the name of the machine. These +files contain entries for filesystems and partitions to mount at boot +time. + +Example, to create the files in the directory @file{fstabs}: + +@example +fsinfo -f fstabs/ ... +@end example + +@node -h FSinfo Option, -m FSinfo Option, -f FSinfo Option, FSinfo Command Line Options +@comment node-name, next, previous, up +@subsection @code{-h} @var{hostname} +@cindex hostname, FSinfo command line option + +Defines the hostname of the destination machine to process for. If this +is not specified, it defaults to the local machine name, as returned by +@b{gethostname}(2). + +Example: + +@example +fsinfo -h dylan.doc.ic.ac.uk ... +@end example + +@node -m FSinfo Option, -q FSinfo Option, -h FSinfo Option, FSinfo Command Line Options +@comment node-name, next, previous, up +@subsection @code{-m} @var{mount-maps} +@cindex maps, FSinfo command line option + +Defines the prefix for the automounter files. The maps will only be +produced if this prefix is defined. The mount maps suitable for the +network defined by the configuration files will be placed into files +with names calculated by prefixing this string to the name of each map. + +For example, to create the automounter maps and place them in the +directory @file{automaps}: + +@example +fsinfo -m automaps/ ... +@end example + +@node -q FSinfo Option, -v FSinfo Option, -m FSinfo Option, FSinfo Command Line Options +@comment node-name, next, previous, up +@subsection @code{-q} +@cindex quiet, FSinfo command line option + +Selects quiet mode. @i{FSinfo} suppress the ``running commentary'' and +only outputs any error messages which are generated. + +@node -v FSinfo Option, -D-FSinfo Option, -q FSinfo Option, FSinfo Command Line Options +@comment node-name, next, previous, up +@subsection @code{-v} +@cindex verbose, FSinfo command line option + +Selects verbose mode. When this is activated, the program will display +more messages, and display all the information discovered when +performing the semantic analysis phase. Each verbose message is output +to @file{stdout} on a line starting with a @samp{#} character. + +@node -D-FSinfo Option, -I FSinfo Option, -v FSinfo Option, FSinfo Command Line Options +@comment node-name, next, previous, up +@subsection @code{-D} @var{name[=defn]} + +Defines a symbol @dfn{name} for the preprocessor when reading the +configuration files. Equivalent to @code{#define} directive. + +@node -I FSinfo Option, -U FSinfo Option, -D-FSinfo Option, FSinfo Command Line Options +@comment node-name, next, previous, up +@subsection @code{-I} @var{directory} + +This option is passed into the preprocessor for the configuration files. +It specifies directories in which to find include files + +@node -U FSinfo Option, , -I FSinfo Option, FSinfo Command Line Options +@comment node-name, next, previous, up +@subsection @code{-U} @var{name} + +Removes any initial definition of the symbol @dfn{name}. Inverse of the +@code{-D} option. + +@node FSinfo errors, , FSinfo command line options, FSinfo +@comment node-name, next, previous, up +@section Errors produced by @i{FSinfo} +@cindex FSinfo error messages + +The following table documents the errors and warnings which @i{FSinfo} may produce. + +@table @t + +@item can't open @var{filename} for writing +Occurs if any errors are encountered when opening an output file.@refill + +@item unknown host attribute +Occurs if an unrecognised keyword is used when defining a host.@refill + +@item unknown filesystem attribute +Occurs if an unrecognised keyword is used when defining a host's +filesystems.@refill + +@item not allowed '/' in a directory name +When reading the configuration input, if there is a filesystem +definition which contains a pathname with multiple directories for any +part of the mountpoint element, and it is not a single absolute path, +then this message will be produced by the parser.@refill + +@item unknown directory attribute +If an unknown keyword is found while reading the definition of a hosts's +filesystem mount option. + +@item unknown mount attribute +Occurs if an unrecognised keyword is found while parsing the list of +static mounts.@refill + +@item " expected +Occurs if an unescaped newline is found in a quoted string. + +@item unknown \ sequence +Occurs if an unknown escape sequence is found inside a string. Within a +string, you can give the standard C escape sequences for strings, such +as newlines and tab characters.@refill + +@item @var{filename}: cannot open for reading +If a file specified on the command line as containing configuration data +could not be opened.@refill + +@item end of file within comment +A comment was unterminated before the end of one of the configuration +files. + +@item host field "@var{field-name}" already set +If duplicate definitions are given for any of the fields with a host +definition. + +@item duplicate host @var{hostname}! +If a host has more than one definition. + +@item netif field @var{field-name} already set +Occurs if you attempt to define an attribute of an interface more than +once. + +@item malformed IP dotted quad: @var{address} +If the Internet address of an interface is incorrectly specified. An +Internet address definition is handled to @b{inet_addr}(3N) to see if it +can cope. If not, then this message will be displayed. + +@item malformed netmask: @var{netmask} +If the netmask cannot be decoded as though it were a hexadecimal number, +then this message will be displayed. It will typically be caused by +incorrect characters in the @var{netmask} value.@refill + +@item fs field "@var{field-name}" already set +Occurs when multiple definitions are given for one of the attributes of a +host's filesystem. + +@item mount tree field "@var{field-name}" already set +Occurs when the @var{field-name} is defined more than once during the +definition of a filesystems mountpoint. + +@item mount field "@var{field-name}" already set +Occurs when a static mount has multiple definitions of the same field. + +@item no disk mounts on @var{hostname} +If there are no static mounts, nor local disk mounts specified for a +machine, this message will be displayed. + +@item @var{host}:@var{device} needs field "@var{field-name}" +Occurs when a filesystem is missing a required field. @var{field-name} could +be one of @code{fstype}, @code{opts}, @code{passno} or +@code{mount}.@refill + +@item @var{filesystem} has a volname but no exportfs data +Occurs when a volume name is declared for a file system, but the string +specifying what machines the filesystem can be exported to is +missing. + +@item sub-directory @var{directory} of @var{directory-tree} starts with '/' +Within the filesystem specification for a host, if an element +@var{directory} of the mountpoint begins with a @samp{/} and it is not +the start of the tree.@refill + +@item @var{host}:@var{device} has no mount point +Occurs if the @samp{mount} option is not specified for a host's +filesystem.@refill + +@item @var{host}:@var{device} has more than one mount point +Occurs if the mount option for a host's filesystem specifies multiple +trees at which to place the mountpoint.@refill + +@item no volname given for @var{host}:@var{device} +Occurs when a filesystem is defined to be mounted on @file{default}, but +no volume name is given for the file system, then the mountpoint cannot +be determined.@refill + +@item @var{host}:mount field specified for swap partition +Occurs if a mountpoint is given for a filesystem whose type is declared +to be @code{swap}.@refill + +@item ambiguous mount: @var{volume} is a replicated filesystem +If several filesystems are declared as having the same volume name, they +will be considered replicated filesystems. To mount a replicated +filesystem statically, a specific host will need to be named, to say +which particular copy to try and mount, else this error will +result.@refill + +@item cannot determine localname since volname @var{volume} is not uniquely defined +If a volume is replicated and an attempt is made to mount the filesystem +statically without specifying a local mountpoint, @i{FSinfo} cannot +calculate a mountpoint, as the desired pathname would be +ambiguous.@refill + +@item volname @var{volume} is unknown +Occurs if an attempt is made to mount or reference a volume name which +has not been declared during the host filesystem definitions.@refill + +@item volname @var{volume} not exported from @var{machine} +Occurs if you attempt to mount the volume @var{volume} from a machine +which has not declared itself to have such a filesystem +available.@refill + +@item network booting requires both root and swap areas +Occurs if a machine has mount declarations for either the root partition +or the swap area, but not both. You cannot define a machine to only +partially boot via the network.@refill + +@item unknown volname @var{volume} automounted @i{[} on @i{]} +Occurs if @var{volume} is used in a definition of an automount map but the volume +name has not been declared during the host filesystem definitions.@refill + +@item not allowed '/' in a directory name +Occurs when a pathname with multiple directory elements is specified as +the name for an automounter tree. A tree should only have one name at +each level. + +@item @var{device} has duplicate exportfs data +Produced if the @samp{exportfs} option is used multiple times within the +same branch of a filesytem definition. For example, if you attempt to +set the @samp{exportfs} data at different levels of the mountpoint +directory tree.@refill + +@item sub-directory of @var{directory-tree} is named "default" +@samp{default} is a keyword used to specify if a mountpoint should be +automatically calculated by @i{FSinfo}. If you attempt to specify a +directory name as this, it will use the filename of @file{default} but +will produce this warning.@refill + +@item pass number for @var{host}:@var{device} is non-zero +Occurs if @var{device} has its @samp{fstype} declared to be @samp{swap} +or @samp{export} and the @b{fsck}(8) pass number is set. Swap devices should not be +fsck'd. @xref{FSinfo filesystems fstype}@refill + +@item dump frequency for @var{host}:@var{device} is non-zero +Occurs if @var{device} has its @samp{fstype} declared to be @samp{swap} +or @samp{export} and the @samp{dump} option is set to a value greater +than zero. Swap devices should not be dumped.@refill + +@end table + +@node Examples, Internals, FSinfo, Top +@comment node-name, next, previous, up +@chapter Examples + +@menu +* User Filesystems:: +* Home Directories:: +* Architecture Sharing:: +* Wildcard names:: +* rwho servers:: +* /vol:: +@end menu + +@node User Filesystems, Home Directories, Examples, Examples +@comment node-name, next, previous, up +@section User Filesystems +@cindex User filesystems +@cindex Mounting user filesystems + +With more than one fileserver, the directories most frequently +cross-mounted are those containing user home directories. A common +convention used at Imperial College is to mount the user disks under +@t{/home/}@i{machine}. + +Typically, the @samp{/etc/fstab} file contained a long list of entries +such as: + +@example +@i{machine}:/home/@i{machine} /home/@i{machine} nfs ... +@end example + +for each fileserver on the network. + +There are numerous problems with this system. The mount list can become +quite large and some of the machines may be down when a system is +booted. When a new fileserver is installed, @samp{/etc/fstab} must be +updated on every machine, the mount directory created and the filesystem +mounted. + +In many environments most people use the same few workstations, but +it is convenient to go to a colleague's machine and access your own +files. When a server goes down, it can cause a process on a client +machine to hang. By minimising the mounted filesystems to only include +those actively being used, there is less chance that a filesystem will +be mounted when a server goes down. + +The following is a short extract from a map taken from a research fileserver +at Imperial College. + +Note the entry for @samp{localhost} which is used for users such as +the operator (@samp{opr}) who have a home directory on most machine as +@samp{/home/localhost/opr}. + +@example +/defaults opts:=rw,intr,grpid,nosuid +charm host!=$@{key@};type:=nfs;rhost:=$@{key@};rfs:=/home/$@{key@} \ + host==$@{key@};type:=ufs;dev:=/dev/xd0g +# +... + +# +localhost type:=link;fs:=$@{host@} +... +# +# dylan has two user disks so have a +# top directory in which to mount them. +# +dylan type:=auto;fs:=$@{map@};pref:=$@{key@}/ +# +dylan/dk2 host!=dylan;type:=nfs;rhost:=dylan;rfs:=/home/$@{key@} \ + host==dylan;type:=ufs;dev:=/dev/dsk/2s0 +# +dylan/dk5 host!=dylan;type:=nfs;rhost:=dylan;rfs:=/home/$@{key@} \ + host==dylan;type:=ufs;dev:=/dev/dsk/5s0 +... +# +toytown host!=$@{key@};type:=nfs;rhost:=$@{key@};rfs:=/home/$@{key@} \ + host==$@{key@};type:=ufs;dev:=/dev/xy1g +... +# +zebedee host!=$@{key@};type:=nfs;rhost:=$@{key@};rfs:=/home/$@{key@} \ + host==$@{key@};type:=ufs;dev:=/dev/dsk/1s0 +# +# Just for access... +# +gould type:=auto;fs:=$@{map@};pref:=$@{key@}/ +gould/staff host!=gould;type:=nfs;rhost:=gould;rfs:=/home/$@{key@} +# +gummo host!=$@{key@};type:=nfs;rhost:=$@{key@};rfs:=/home/$@{key@} +... +@end example + +This map is shared by most of the machines listed so on those +systems any of the user disks is accessible via a consistent name. +@i{Amd} is started with the following command + +@example +amd /home amd.home +@end example + +Note that when mounting a remote filesystem, the @dfn{automounted} +mount point is referenced, so that the filesystem will be mounted if +it is not yet (at the time the remote @samp{mountd} obtains the file handle). + +@node Home Directories, Architecture Sharing, User Filesystems, Examples +@comment node-name, next, previous, up +@section Home Directories +@cindex Home directories +@cindex Example of mounting home directories +@cindex Mount home directories + +One convention for home directories is to locate them in @samp{/homes} +so user @samp{jsp}'s home directory is @samp{/homes/jsp}. With more +than a single fileserver it is convenient to spread user files across +several machines. All that is required is a mount-map which converts +login names to an automounted directory. + +Such a map might be started by the command: + +@example +amd /homes amd.homes +@end example + +where the map @samp{amd.homes} contained the entries: + +@example +/defaults type:=link # All the entries are of type:=link +jsp fs:=/home/charm/jsp +njw fs:=/home/dylan/dk5/njw +... +phjk fs:=/home/toytown/ai/phjk +sjv fs:=/home/ganymede/sjv +@end example + +Whenever a login name is accessed in @samp{/homes} a symbolic link +appears pointing to the real location of that user's home directory. In +this example, @samp{/homes/jsp} would appear to be a symbolic link +pointing to @samp{/home/charm/jsp}. Of course, @samp{/home} would also +be an automount point. + +This system causes an extra level of symbolic links to be used. +Although that turns out to be relatively inexpensive, an alternative is +to directly mount the required filesystems in the @samp{/homes} +map. The required map is simple, but long, and its creation is best automated. +The entry for @samp{jsp} could be: + +@example +jsp -sublink:=$@{key@};rfs:=/home/charm \ + host==charm;type:=ufs;dev:=/dev/xd0g \ + host!=charm;type:=nfs;rhost:=charm +@end example + +This map can become quite big if it contains a large number of entries. +By combining two other features of @i{Amd} it can be greatly simplified. + +First the UFS partitions should be mounted under the control of +@samp{/etc/fstab}, taking care that they are mounted in the same place +that @i{Amd} would have automounted them. In most cases this would be +something like @samp{/a/@dfn{host}/home/@dfn{host}} and +@samp{/etc/fstab} on host @samp{charm} would have a line:@refill + +@example +/dev/xy0g /a/charm/home/charm 4.2 rw,nosuid,grpid 1 5 +@end example + +The map can then be changed to: + +@example +/defaults type:=nfs;sublink:=$@{key@};opts:=rw,intr,nosuid,grpid +jsp rhost:=charm;rfs:=/home/charm +njw rhost:=dylan;rfs:=/home/dylan/dk5 +... +phjk rhost:=toytown;rfs:=/home/toytown;sublink:=ai/$@{key@} +sjv rhost:=ganymede;rfs:=/home/ganymede +@end example + +This map operates as usual on a remote machine (@i{ie} @code{$@{host@}} +not equal to @code{$@{rhost@}}). On the machine where the filesystem is +stored (@i{ie} @code{$@{host@}} equal to @code{$@{rhost@}}), @i{Amd} +will construct a local filesystem mount point which corresponds to the +name of the locally mounted UFS partition. If @i{Amd} is started with +the ``-r'' option then instead of attempting an NFS mount, @i{Amd} will +simply inherit the UFS mount (@pxref{Inheritance Filesystem}). If +``-r'' is not used then a loopback NFS mount will be made. This type of +mount is known to cause a deadlock on many systems. + +@node Architecture Sharing, Wildcard Names, Home Directories, Examples +@comment node-name, next, previous, up +@section Architecture Sharing +@cindex Architecture sharing +@cindex Sharing a fileserver between architectures +@cindex Architecture dependent volumes + +@c %At the moment some of the research machines have sets of software +@c %mounted in @samp{/vol}. This contains subdirectories for \TeX, +@c %system sources, local sources, prolog libraries and so on. +Often a filesystem will be shared by machines of different architectures. +Separate trees can be maintained for the executable images for each +architecture, but it may be more convenient to have a shared tree, +with distinct subdirectories. + +A shared tree might have the following structure on the fileserver (called +@samp{fserver} in the example): + +@example +local/tex +local/tex/fonts +local/tex/lib +local/tex/bin +local/tex/bin/sun3 +local/tex/bin/sun4 +local/tex/bin/hp9000 +... +@end example + +In this example, the subdirectories of @samp{local/tex/bin} should be +hidden when accessed via the automount point (conventionally @samp{/vol}). +A mount-map for @samp{/vol} to achieve this would look like: + +@example +/defaults sublink:=$@{/key@};rhost:=fserver;type:=link +tex type:=auto;fs:=$@{map@};pref:=$@{key@}/ +tex/fonts host!=fserver;type:=nfs;rfs:=/vol/tex \ + host==fserver;fs:=/usr/local/tex +tex/lib host!=fserver;type:=nfs;rfs:=/vol/tex \ + host==fserver;fs:=/usr/local/tex +tex/bin -sublink:=$@{/key@}/$@{arch@} host!=fserver;type:=nfs;rfs:=/vol/tex \ + host:=fserver;fs:=/usr/local/tex +@end example + +When @samp{/vol/tex/bin} is referenced, the current machine architecture +is automatically appended to the path by the @code{$@{sublink@}} +variable. This means that users can have @samp{/vol/tex/bin} in their +@samp{PATH} without concern for architecture dependencies. + +@node Wildcard Names, rwho servers, Architecture Sharing, Examples +@comment node-name, next, previous, up +@section Wildcard names & Replicated Servers + +By using the wildcard facility, @i{Amd} can @dfn{overlay} an existing +directory with additional entries. +The system files are usually mounted under @samp{/usr}. If instead +@i{Amd} is mounted on @samp{/usr}, additional +names can be overlayed to augment or replace names in the ``master'' @samp{/usr}. +A map to do this would have the form: + +@example +local type:=auto;fs:=local-map +share type:=auto;fs:=share-map +* -type:=nfs;rfs:=/export/exec/$@{arch@};sublink:="$@{key@}" \ + rhost:=fserv1 rhost:=fserv2 rhost:=fserv3 +@end example + +Note that the assignment to @code{$@{sublink@}} is surrounded by double +quotes to prevent the incoming key from causing the map to be +misinterpreted. This map has the effect of directing any access to +@samp{/usr/local} or @samp{/usr/share} to another automount point. + +In this example, it is assumed that the @samp{/usr} files are replicated +on three fileservers: @samp{fserv1}, @samp{fserv2} and @samp{fserv3}. +For any references other than to @samp{local} and @samp{share} one of +the servers is used and a symbolic link to +@t{$@{autodir@}/$@{rhost@}/export/exec/$@{arch@}/@i{whatever}} is +returned once an appropriate filesystem has been mounted.@refill + +@node rwho servers, /vol, Wildcard Names, Examples +@comment node-name, next, previous, up +@section @samp{rwho} servers +@cindex rwho servers +@cindex Architecture specific mounts +@cindex Example of architecture specific mounts + +The @samp{/usr/spool/rwho} directory is a good candidate for automounting. +For efficiency reasons it is best to capture the rwho data on a small +number of machines and then mount that information onto a large number +of clients. The data written into the rwho files is byte order dependent +so only servers with the correct byte ordering can be used by a client: + +@example +/defaults type:=nfs +usr/spool/rwho -byte==little;rfs:=/usr/spool/rwho \ + rhost:=vaxA rhost:=vaxB \ + || -rfs:=/usr/spool/rwho \ + rhost:=sun4 rhost:=hp300 +@end example + +@node /vol, , rwho servers, Examples +@comment node-name, next, previous, up +@section @samp{/vol} +@cindex /vol +@cindex Catch-all mount point +@cindex Generic volume name + +@samp{/vol} is used as a catch-all for volumes which do not have other +conventional names. + +Below is part of the @samp{/vol} map for the domain @samp{doc.ic.ac.uk}. +The @samp{r+d} tree is used for new or experimental software that needs +to be available everywhere without installing it on all the fileservers. +Users wishing to try out the new software then simply include +@samp{/vol/r+d/@{bin,ucb@}} in their path.@refill + +The main tree resides on one host @samp{gould.doc.ic.ac.uk}, which has +different @samp{bin}, @samp{etc}, @samp{lib} and @samp{ucb} +sub-directories for each machine architecture. For example, +@samp{/vol/r+d/bin} for a Sun-4 would be stored in the sub-directory +@samp{bin/sun4} of the filesystem @samp{/usr/r+d}. When it was accessed +a symbolic link pointing to @samp{/a/gould/usr/r+d/bin/sun4} would be +returned.@refill + +@example +/defaults type:=nfs;opts:=rw,grpid,nosuid,intr,soft +wp -opts:=rw,grpid,nosuid;rhost:=charm \ + host==charm;type:=link;fs:=/usr/local/wp \ + host!=charm;type:=nfs;rfs:=/vol/wp +... +# +src -opts:=rw,grpid,nosuid;rhost:=charm \ + host==charm;type:=link;fs:=/usr/src \ + host!=charm;type:=nfs;rfs:=/vol/src +# +r+d type:=auto;fs:=$@{map@};pref:=r+d/ +# per architecture bin,etc,lib&ucb... +r+d/bin rhost:=gould.doc.ic.ac.uk;rfs:=/usr/r+d;sublink:=$@{/key@}/$@{arch@} +r+d/etc rhost:=gould.doc.ic.ac.uk;rfs:=/usr/r+d;sublink:=$@{/key@}/$@{arch@} +r+d/include rhost:=gould.doc.ic.ac.uk;rfs:=/usr/r+d;sublink:=$@{/key@} +r+d/lib rhost:=gould.doc.ic.ac.uk;rfs:=/usr/r+d;sublink:=$@{/key@}/$@{arch@} +r+d/man rhost:=gould.doc.ic.ac.uk;rfs:=/usr/r+d;sublink:=$@{/key@} +r+d/src rhost:=gould.doc.ic.ac.uk;rfs:=/usr/r+d;sublink:=$@{/key@} +r+d/ucb rhost:=gould.doc.ic.ac.uk;rfs:=/usr/r+d;sublink:=$@{/key@}/$@{arch@} +# hades pictures +pictures -opts:=rw,grpid,nosuid;rhost:=thpfs \ + host==thpfs;type:=link;fs:=/nbsd/pictures \ + host!=thpfs;type:=nfs;rfs:=/nbsd;sublink:=pictures +# hades tools +hades -opts:=rw,grpid,nosuid;rhost:=thpfs \ + host==thpfs;type:=link;fs:=/nbsd/hades \ + host!=thpfs;type:=nfs;rfs:=/nbsd;sublink:=hades +# bsd tools for hp. +bsd -opts:=rw,grpid,nosuid;arch==hp9000;rhost:=thpfs \ + host==thpfs;type:=link;fs:=/nbsd/bsd \ + host!=thpfs;type:=nfs;rfs:=/nbsd;sublink:=bsd +@end example + +@node Internals, Acknowledgements & Trademarks, Examples, Top +@comment node-name, next, previous, up +@chapter Internals + +@menu +* Log Messages:: +@end menu + +@node Log Messages, , Internals, Internals +@comment node-name, next, previous, up +@section Log Messages + +In the following sections a brief explanation is given of some of the +log messages made by @i{Amd}. Where the message is in @samp{typewriter} +font, it corresponds exactly to the message produced by @i{Amd}. Words +in @dfn{italic} are replaced by an appropriate string. Variables, +@code{$@{var@}}, indicate that the value of the appropriate variable is +output. + +Log messages are either sent direct to a file, +or logged via the @b{syslog}(3) mechanism. +Messages are logged with facility @samp{LOG_DAEMON} when using @b{syslog}(3). +In either case, entries in the file are of the form: +@example +@i{date-string} @i{hostname} @t{amd[}@i{pid}@t{]} @i{message} +@end example + +@menu +* Fatal errors:: +* Info messages:: +@end menu + +@node Fatal errors, Info messages, Log Messages, Log Messages +@comment node-name, next, previous, up +@subsection Fatal errors + +@i{Amd} attempts to deal with unusual events. Whenever it is not +possible to deal with such an error, @i{Amd} will log an appropriate +message and, if it cannot possibly continue, will either exit or abort. +These messages are selected by @samp{-x fatal} on the command line. +When @b{syslog}(3) is being used, they are logged with level +@samp{LOG_FATAL}. Even if @i{Amd} continues to operate it is likely to +remain in a precarious state and should be restarted at the earliest +opportunity. + +@table @asis +@item @t{Attempting to inherit not-a-filesystem} +The prototype mount point created during a filesystem restart did not +contain a reference to the restarted filesystem. This erorr ``should +never happen''. + +@item @t{Can't bind to domain "@i{NIS-domain}"} +A specific NIS domain was requested on the command line, but no server +for that domain is available on the local net. + +@item @t{Can't determine IP address of this host (@i{hostname})} +When @i{Amd} starts it determines its own IP address. If this lookup +fails then @i{Amd} cannot continue. The hostname it looks up is that +obtained returned by @b{gethostname}(2) system call. + +@item @t{Can't find root file handle for @i{automount point}} +@i{Amd} creates its own file handles for the automount points. When it +mounts itself as a server, it must pass these file handles to the local +kernel. If the filehandle is not obtainable the mount point is ignored. +This error ``should never happen''. + +@item @t{Must be root to mount filesystems (euid = @i{euid})} +To prevent embarrassment, @i{Amd} makes sure it has appropriate system +privileges. This amounts to having an euid of 0. The check is made +after argument processing complete to give non-root users a chance to +access the ``-v'' option. + +@item @t{No work to do - quitting} +No automount points were given on the command line and so there is no +work to do. + +@item @t{Out of memory in realloc} +While attempting to realloc some memory, the memory space available to +@i{Amd} was exhausted. This is an unrecoverable error. + +@item @t{Out of memory} +While attempting to malloc some memory, the memory space available to +@i{Amd} was exhausted. This is an unrecoverable error. + +@item @t{cannot create rpc/udp service} +Either the NFS or AMQ endpoint could not be created. + +@item @t{gethostname:} @i{description} +The @b{gethostname}(2) system call failed during startup. + +@item @t{host name is not set} +The @b{gethostname}(2) system call returned a zero length host name. +This can happen if @i{Amd} is started in single user mode just after +booting the system. + +@item @t{ifs_match called!} +An internal error occurred while restarting a pre-mounted filesystem. +This error ``should never happen''. + +@item @t{mount_afs:} @i{description} +An error occured while @i{Amd} was mounting itself. + +@item @t{run_rpc failed} +Somehow the main NFS server loop failed. This error ``should never +happen''. + +@item @t{unable to free rpc arguments in amqprog_1} +The incoming arguments to the AMQ server could not be free'ed. + +@item @t{unable to free rpc arguments in nfs_program_1} +The incoming arguments to the NFS server could not be free'ed. + +@item @t{unable to register (AMQ_PROGRAM, AMQ_VERSION, udp)} +The AMQ server could not be registered with the local portmapper or the +internal RPC dispatcher. + +@item @t{unable to register (NFS_PROGRAM, NFS_VERSION, 0)} +The NFS server could not be registered with the internal RPC dispatcher. + +@end table + +@node Info messages, , Fatal errors, Log Messages +@comment node-name, next, previous, up +@subsection Info messages + +@i{Amd} generates information messages to record state changes. These +messages are selected by @samp{-x info} on the command line. When +@b{syslog}(3) is being used, they are logged with level @samp{LOG_INFO}. + +The messages listed below can be generated and are in a format suitable +for simple statistical analysis. @dfn{mount-info} is the string +that is displayed by @dfn{Amq} in its mount information column and +placed in the system mount table. + +@table @asis +@item @t{mount of "@t{$@{@i{path}@}}" on @t{$@{@i{fs}@}} timed out} +Attempts to mount a filesystem for the given automount point have failed +to complete within 30 seconds. + +@item @t{"@t{$@{@i{path}@}}" forcibly timed out} +An automount point has been timed out by the @i{Amq} command. + +@item @t{restarting @i{mount-info} on @t{$@{@i{fs}@}}} +A pre-mounted file system has been noted. + +@item @t{"@t{$@{@i{path}@}}" has timed out} +No access to the automount point has been made within the timeout +period. + +@item @t{file server @t{$@{@i{rhost}@}} is down - timeout of "@t{$@{@i{path}@}}" ignored} +An automount point has timed out, but the corresponding file server is +known to be down. This message is only produced once for each mount +point for which the server is down. + +@item @t{Re-synchronizing cache for map @t{$@{@i{map}@}}} +The named map has been modified and the internal cache is being re-synchronized. + +@item @t{Filehandle denied for "@t{$@{@i{rhost}@}}:@t{$@{@i{rfs}@}}"} +The mount daemon refused to return a file handle for the requested filesystem. + +@item @t{Filehandle error for "$@{@i{rhost}@}:$@{@i{rfs}@}":} @i{description} +The mount daemon gave some other error for the requested filesystem. + +@item @t{file server @t{$@{@i{rhost}@}} type nfs starts up} +A new NFS file server has been referenced and is known to be up. + +@item @t{file server @t{$@{@i{rhost}@}} type nfs starts down} +A new NFS file server has been referenced and is known to be down. + +@item @t{file server @t{$@{@i{rhost}@}} type nfs is up} +An NFS file server that was previously down is now up. + +@item @t{file server @t{$@{@i{rhost}@}} type nfs is down} +An NFS file server that was previously up is now down. + +@item @t{Finishing with status @i{exit-status}} +@i{Amd} is about to exit with the given exit status. + +@item @t{@i{mount-info} mounted fstype @t{$@{@i{type}@}} on @t{$@{@i{fs}@}}} +A new file system has been mounted. + +@item @t{@i{mount-info} restarted fstype @t{$@{@i{type}@}} on @t{$@{@i{fs}@}}} +@i{Amd} is using a pre-mounted filesystem to satisfy a mount request. + +@item @t{@i{mount-info} unmounted fstype @t{$@{@i{type}@}} from @t{$@{@i{fs}@}}} +A file system has been unmounted. + +@item @t{@i{mount-info} unmounted fstype @t{$@{@i{type}@}} from @t{$@{@i{fs}@}} link @t{$@{@i{fs}@}}/@t{$@{@i{sublink}@}}} +A file system of which only a sub-directory was in use has been unmounted. + +@end table + +@node Acknowledgements & Trademarks, Index, Internals, Top +@comment node-name, next, previous, up +@unnumbered Acknowledgements & Trademarks + +Thanks to the Formal Methods Group at Imperial College for +suffering patiently while @i{Amd} was being developed on their machines. + +Thanks to the many people who have helped with the development of +@i{Amd}, especially Piete Brooks at the Cambridge University Computing +Lab for many hours of testing, experimentation and discussion. + +@itemize @bullet +@item +@b{DEC}, @b{VAX} and @b{Ultrix} are registered trademarks of Digital +Equipment Corporation. +@item +@b{AIX} and @b{IBM} are registered trademarks of International Business +Machines Corporation. +@item +@b{Sun}, @b{NFS} and @b{SunOS} are registered trademarks of Sun +Microsystems, Inc. +@item +@b{Unix} is a registered trademark of AT&T Unix Systems Laboratories +in the USA and other countries. +@end itemize + +@node Index, Intro, Acknowledgements & Trademarks, Top +@comment node-name, next, previous, up +@unnumbered Index + +@printindex cp + +@contents +@bye diff --git a/usr.sbin/amd/doc/texinfo.tex b/usr.sbin/amd/doc/texinfo.tex new file mode 100644 index 0000000..73528ed --- /dev/null +++ b/usr.sbin/amd/doc/texinfo.tex @@ -0,0 +1,2192 @@ +%% TeX macros to handle texinfo files + +% Copyright (C) 1985, 1986, 1988 Free Software Foundation, Inc. + +%GNU CC is free software; you can redistribute it and/or modify +%it under the terms of the GNU General Public License as published by +%the Free Software Foundation; either version 1, or (at your option) +%any later version. + +%GNU CC is distributed in the hope that it will be useful, +%but WITHOUT ANY WARRANTY; without even the implied warranty of +%MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%GNU General Public License for more details. + +%You should have received a copy of the GNU General Public License +%along with GNU CC; see the file COPYING. If not, write to +%the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + +%In other words, you are welcome to use, share and improve this program. +%You are forbidden to forbid anyone else to use, share and improve +%what you give them. Help stamp out software-hoarding! + +\def\texinfoversion{1.26} +\message{Loading texinfo package [Version \texinfoversion]:} +\message{} + +% Save some parts of plain tex whose names we will redefine. + +\let\ptexlbrace=\{ +\let\ptexrbrace=\} +\let\ptexdot=\. +\let\ptexstar=\* +\let\ptexend=\end +\let\ptexbullet=\bullet +\let\ptexb=\b +\let\ptexc=\c +\let\ptexi=\i +\let\ptext=\t +\let\ptexl=\l +\let\ptexL=\L + +\def\tie{\penalty 10000\ } % Save plain tex definition of ~. + +\message{Basics,} +\chardef\other=12 + +\hyphenation{ap-pen-dix} +\hyphenation{mini-buf-fer mini-buf-fers} +\hyphenation{eshell} + +% Margin to add to right of even pages, to left of odd pages. +\newdimen \bindingoffset \bindingoffset=0pt +\newdimen \normaloffset \normaloffset=\hoffset +\newdimen\pagewidth \newdimen\pageheight +\pagewidth=\hsize \pageheight=\vsize + +%---------------------Begin change----------------------- +% +% Dimensions to add cropmarks at corners Added by P. A. MacKay, 12 Nov. 1986 +% +\newdimen\cornerlong \newdimen\cornerthick +\newdimen \topandbottommargin +\newdimen \outerhsize \newdimen \outervsize +\cornerlong=1pc\cornerthick=.3pt % These set size of cropmarks +\outerhsize=7in +\outervsize=9.5in +\topandbottommargin=.75in +% +%---------------------End change----------------------- + +% \onepageout takes a vbox as an argument. Note that \pagecontents +% does insertions itself, but you have to call it yourself. +\chardef\PAGE=255 \output={\onepageout{\pagecontents\PAGE}} +\def\onepageout#1{\hoffset=\normaloffset +\ifodd\pageno \advance\hoffset by \bindingoffset +\else \advance\hoffset by -\bindingoffset\fi +\shipout\vbox{{\let\hsize=\pagewidth \makeheadline} \pagebody{#1}% + {\let\hsize=\pagewidth \makefootline}} +\advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi} + + +% Here is a modification of the main output routine for Near East Publications +% This provides right-angle cropmarks at all four corners. +% The contents of the page are centerlined into the cropmarks, +% and any desired binding offset is added as an \hskip on either +% site of the centerlined box. (P. A. MacKay, 12 November, 1986) +% +\def\croppageout#1{\hoffset=0pt % make sure this doesn't mess things up + \shipout + \vbox to \outervsize{\hsize=\outerhsize + \vbox{\line{\ewtop\hfill\ewtop}} + \nointerlineskip + \line{\vbox{\moveleft\cornerthick\nstop} + \hfill + \vbox{\moveright\cornerthick\nstop}} + \vskip \topandbottommargin + \centerline{\ifodd\pageno\hskip\bindingoffset\fi + \vbox{ + {\let\hsize=\pagewidth \makeheadline} + \pagebody{#1} + {\let\hsize=\pagewidth \makefootline}} + \ifodd\pageno\else\hskip\bindingoffset\fi} + \vskip \topandbottommargin plus1fill minus1fill + \boxmaxdepth\cornerthick + \line{\vbox{\moveleft\cornerthick\nsbot} + \hfill + \vbox{\moveright\cornerthick\nsbot}} + \nointerlineskip + \vbox{\line{\ewbot\hfill\ewbot}} + } + \advancepageno + \ifnum\outputpenalty>-20000 \else\dosupereject\fi} +% +% Do @cropmarks to get crop marks +\def\cropmarks{\let\onepageout=\croppageout } + +\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} +{\catcode`\@ =11 +\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +\dimen@=\dp#1 \unvbox#1 +\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi +\ifr@ggedbottom \kern-\dimen@ \vfil \fi} +} + +% +% Here are the rules for the cropmarks. Note that they are +% offset so that the space between them is truly \outerhsize or \outervsize +% (P. A. MacKay, 12 November, 1986) +% +\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} +\def\nstop{\vbox + {\hrule height\cornerthick depth\cornerlong width\cornerthick}} +\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} +\def\nsbot{\vbox + {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + +% Parse an argument, then pass it to #1. +% The argument can be delimited with [...] or with "..." or braces +% or it can be a whole line. +% #1 should be a macro which expects +% an ordinary undelimited TeX argument. + +\def\parsearg #1{\let\next=#1\begingroup\obeylines\futurelet\temp\parseargx} + +\def\parseargx{% +\ifx \obeyedspace\temp \aftergroup\parseargdiscardspace \else% +\aftergroup \parseargline % +\fi \endgroup} + +{\obeyspaces % +\gdef\parseargdiscardspace {\begingroup\obeylines\futurelet\temp\parseargx}} + +\gdef\obeyedspace{\ } + +\def\parseargline{\begingroup \obeylines \parsearglinex} +{\obeylines % +\gdef\parsearglinex #1^^M{\endgroup \next {#1}}} + +\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + +%% These are used to keep @begin/@end levels from running away +%% Call \inENV within environments (after a \begingroup) +\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} +\def\ENVcheck{% +\ifENV\errmessage{Still within an environment. Type Return to continue.} +\endgroup\fi} % This is not perfect, but it should reduce lossage + +% @begin foo is the same as @foo, for now. +\newhelp\EMsimple{Type to continue} + +\outer\def\begin{\parsearg\beginxxx} + +\def\beginxxx #1{% +\expandafter\ifx\csname #1\endcsname\relax +{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else +\csname #1\endcsname\fi} + +%% @end foo executes the definition of \Efoo. +%% foo can be delimited by doublequotes or brackets. + +\def\end{\parsearg\endxxx} + +\def\endxxx #1{% +\expandafter\ifx\csname E#1\endcsname\relax +\expandafter\ifx\csname #1\endcsname\relax +\errmessage{Undefined command @end #1}\else +\errorE{#1}\fi\fi +\csname E#1\endcsname} +\def\errorE#1{ +{\errhelp=\EMsimple \errmessage{@end #1 not within #1 environment}}} + +% Single-spacing is done by various environments. + +\newskip\singlespaceskip \singlespaceskip = \baselineskip +\def\singlespace{% +{\advance \baselineskip by -\singlespaceskip +\kern \baselineskip}% +\baselineskip=\singlespaceskip +} + +%% Simple single-character @ commands + +% @@ prints an @ +% Kludge this until the fonts are right (grr). +\def\@{{\sf \char '100}} + +% Define @` and @' to be the same as ` and ' +% but suppressing ligatures. +\def\`{{`}} +\def\'{{'}} + +% Used to generate quoted braces. + +\def\mylbrace {{\tt \char '173}} +\def\myrbrace {{\tt \char '175}} +\let\{=\mylbrace +\let\}=\myrbrace + +% @: forces normal size whitespace following. +\def\:{\spacefactor=1000 } + +% @* forces a line break. +\def\*{\hfil\break} + +% @. is an end-of-sentence period. +\def\.{.\spacefactor=3000 } + +% @w prevents a word break +\def\w #1{\hbox{#1}} + +% @group ... @end group forces ... to be all on one page. + +\def\group{\begingroup% \inENV ??? +\def \Egroup{\egroup\endgroup} +\vbox\bgroup} + +% @br forces paragraph break + +\let\br = \par + +% @dots{} output some dots + +\def\dots{$\ldots$} + +% @page forces the start of a new page + +\def\page{\par\vfill\supereject} + +% @exdent text.... +% outputs text on separate line in roman font, starting at standard page margin + +\def\exdent{\errmessage{@exdent in filled text}} + % @lisp, etc, define \exdent locally from \internalexdent + +{\obeyspaces +\gdef\internalexdent{\parsearg\exdentzzz}} + +\def\exdentzzz #1{{\advance \leftskip by -\lispnarrowing +\advance \hsize by -\leftskip +\advance \hsize by -\rightskip +\leftline{{\rm#1}}}} + +% @include file insert text of that file as input. + +\def\include{\parsearg\includezzz} +\def\includezzz #1{{\def\thisfile{#1}\input #1 +}} + +\def\thisfile{} + +% @center line outputs that line, centered + +\def\center{\parsearg\centerzzz} +\def\centerzzz #1{{\advance\hsize by -\leftskip +\advance\hsize by -\rightskip +\centerline{#1}}} + +% @sp n outputs n lines of vertical space + +\def\sp{\parsearg\spxxx} +\def\spxxx #1{\par \vskip #1\baselineskip} + +% @comment ...line which is ignored... +% @c is the same as @comment +% @ignore ... @end ignore is another way to write a comment + +\def\comment{\parsearg \commentxxx} + +\def\commentxxx #1{} + +\let\c=\comment + +% Prevent errors for section commands. +% Used in @ignore and in failing conditionals. +\def\ignoresections{% +\let\chapter=\relax +\let\unnumbered=\relax +\let\unnumberedsec=\relax +\let\unnumberedsection=\relax +\let\unnumberedsubsec=\relax +\let\unnumberedsubsection=\relax +\let\unnumberedsubsubsec=\relax +\let\unnumberedsubsubsection=\relax +\let\section=\relax +\let\subsec=\relax +\let\subsubsec=\relax +\let\subsection=\relax +\let\subsubsection=\relax +\let\appendix=\relax +\let\appendixsec=\relax +\let\appendixsection=\relax +\let\appendixsubsec=\relax +\let\appendixsubsection=\relax +\let\appendixsubsubsec=\relax +\let\appendixsubsubsection=\relax +} + +\def\ignore{\begingroup\ignoresections\ignorexxx} +\long\def\ignorexxx #1\end ignore{\endgroup} + +% Conditionals to test whether a flag is set. + +\outer\def\ifset{\begingroup\ignoresections\parsearg\ifsetxxx} + +\def\ifsetxxx #1{\endgroup +\expandafter\ifx\csname IF#1\endcsname\relax \let\temp=\ifsetfail +\else \let\temp=\relax \fi +\temp} +\def\Eifset{} +\def\ifsetfail{\begingroup\ignoresections\ifsetfailxxx} +\long\def\ifsetfailxxx #1\end ifset{\endgroup} + +\outer\def\ifclear{\begingroup\ignoresections\parsearg\ifclearxxx} + +\def\ifclearxxx #1{\endgroup +\expandafter\ifx\csname IF#1\endcsname\relax \let\temp=\relax +\else \let\temp=\ifclearfail \fi +\temp} +\def\Eifclear{} +\def\ifclearfail{\begingroup\ignoresections\ifclearfailxxx} +\long\def\ifclearfailxxx #1\end ifclear{\endgroup} + +% Some texinfo constructs that are trivial in tex + +\def\iftex{} +\def\Eiftex{} +\def\ifinfo{\begingroup\ignoresections\ifinfoxxx} +\long\def\ifinfoxxx #1\end ifinfo{\endgroup} +\long\def\menu #1\end menu{} +\def\asis#1{#1} + +\def\node{\parsearg\nodezzz} +\def\nodezzz#1{\nodexxx [#1,]} +\def\nodexxx[#1,#2]{\gdef\lastnode{#1}} +\let\lastnode=\relax + +\def\donoderef{\ifx\lastnode\relax\else +\expandafter\expandafter\expandafter\setref{\lastnode}\fi +\let\lastnode=\relax} + +\def\unnumbnoderef{\ifx\lastnode\relax\else +\expandafter\expandafter\expandafter\unnumbsetref{\lastnode}\fi +\let\lastnode=\relax} + +\let\refill=\relax + +% @setfilename is done at the beginning of every texinfo file. +% So open here the files we need to have open while reading the input. +% This makes it possible to make a .fmt file for texinfo. +\def\setfilename{% + \readauxfile + \opencontents + \openindices + \fixbackslash % Turn off hack to swallow `\input texinfo'. + \comment % Ignore the actual filename. +} + +\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + +\def\inforef #1{\inforefzzz #1,,,,**} +\def\inforefzzz #1,#2,#3,#4**{See Info file \file{\losespace#3{}}, node `\losespace#1{}'} +\def\losespace #1{#1} + +\message{fonts,} + +% Font-change commands. + +%% Try out Computer Modern fonts at \magstephalf +\font\tenrm=cmr10 scaled \magstephalf +\font\tentt=cmtt10 scaled \magstephalf +% Instead of cmb10, you many want to use cmbx10. +% cmbx10 is a prettier font on its own, but cmb10 +% looks better when embedded in a line with cmr10. +\font\tenbf=cmb10 scaled \magstephalf +\font\tenit=cmti10 scaled \magstephalf +\font\tensl=cmsl10 scaled \magstephalf +\font\tensf=cmss10 scaled \magstephalf +\def\li{\sf} +\font\tensc=cmcsc10 scaled \magstephalf + +% Fonts for @defun, etc. +\font\defbf=cmbx10 scaled \magstep1 %was 1314 +\let\deftt=\tentt +\def\df{\let\tt=\deftt \defbf} + +% Font for title +\font\titlerm = cmbx10 scaled \magstep5 + +% Fonts for indices +\font\indit=cmti9 \font\indrm=cmr9 +\def\indbf{\indrm} \def\indsl{\indit} +\def\indexfonts{\let\it=\indit \let\sl=\indsl \let\bf=\indbf \let\rm=\indrm} + +% Fonts for headings +\font\chaprm=cmbx10 scaled \magstep3 +\font\chapit=cmti10 scaled \magstep3 +\font\chapsl=cmsl10 scaled \magstep3 +\font\chaptt=cmtt10 scaled \magstep3 +\font\chapsf=cmss10 scaled \magstep3 +\let\chapbf=\chaprm + +\font\secrm=cmbx10 scaled \magstep2 +\font\secit=cmti10 scaled \magstep2 +\font\secsl=cmsl10 scaled \magstep2 +\font\sectt=cmtt10 scaled \magstep2 +\font\secsf=cmss10 scaled \magstep2 +\let\secbf=\secrm + +% \font\ssecrm=cmbx10 scaled \magstep1 % This size an fontlooked bad. +% \font\ssecit=cmti10 scaled \magstep1 % The letters were too crowded. +% \font\ssecsl=cmsl10 scaled \magstep1 +% \font\ssectt=cmtt10 scaled \magstep1 +% \font\ssecsf=cmss10 scaled \magstep1 + +\font\ssecrm=cmb10 at 13pt % Note the use of cmb rather than cmbx. +\font\ssecit=cmti10 at 13pt % Also, the size is a little larger than +\font\ssecsl=cmsl10 at 13pt % being scaled magstep1. +\font\ssectt=cmtt10 at 13pt +\font\ssecsf=cmss10 at 13pt + +\let\ssecbf=\ssecrm + +\def\textfonts{\let\rm=\tenrm\let\it=\tenit\let\sl=\tensl\let\bf=\tenbf% +\let\smallcaps=\tensc\let\sf=\tensf} +\def\chapfonts{\let\rm=\chaprm\let\it=\chapit\let\sl=\chapsl\let\bf=\chapbf\let\tt=\chaptt\let\sf=\chapsf} +\def\secfonts{\let\rm=\secrm\let\it=\secit\let\sl=\secsl\let\bf=\secbf\let\tt=\sectt\let\sf=\secsf} +\def\subsecfonts{\let\rm=\ssecrm\let\it=\ssecit\let\sl=\ssecsl\let\bf=\ssecbf\let\tt=\ssectt\let\sf=\ssecsf} +% Count depth in font-changes, for error checks +\newcount\fontdepth \fontdepth=0 + +% Font for table of contents. +\font\truesecrm=cmr12 + +%% Add scribe-like font environments, plus @l for inline lisp (usually sans +%% serif) and @ii for TeX italic + +\def\i#1{{\sl #1}} +\let\var=\i +\let\dfn=\i +\let\emph=\i +\let\cite=\i + +\def\b#1{{\bf #1}} +\let\strong=\b + +\def\t#1{{\tt \rawbackslash \frenchspacing #1}\null} +\let\ttfont = \t +\let\kbd=\t +\let\code=\t +\def\samp #1{`{\tt \rawbackslash \frenchspacing #1}'\null} +\def\key #1{{\tt \uppercase{#1}}\null} +\def\ctrl #1{{\tt \rawbackslash \hat}#1} + +\let\file=\samp + +\def\l#1{{\li #1}\null} % + +\def\r#1{{\rm #1}} % roman font +\def\sc#1{{\\smallcaps #1}} % smallcaps font +\def\ii#1{{\it #1}} % italic font + +\def\titlefont#1{{\titlerm #1}} + +% Make altmode in file print out right + +\catcode `\^^[=\active \def^^[{$\diamondsuit$} + +\message{page headings,} + +\newskip\titlepagetopglue \titlepagetopglue = 1.5in +\newskip\titlepagebottomglue \titlepagebottomglue = 2pc + +% First the title page. Must do @settitle before @titlepage. +\font\titlerm = cmbx12 scaled \magstep2 +\def\titlefont#1{{\titlerm #1}} + +\newtoks\realeverypar +\newif\ifseenauthor + +\def\titlepage{\begingroup \parindent=0pt \textfonts + \font\subtitlerm = cmr10 scaled \magstephalf + \def\subtitlefont{\subtitlerm \normalbaselineskip = 12pt \normalbaselines}% + % + \font\authorrm = cmbx12 scaled \magstep1 + \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}% + % + % The first subtitle should have some space before it, but not the + % others. They all should be ragged left. +% ??? This code turned off because (1) it is wrong for all old title +% pages, and (2) it makes an extra group which never is ended. +% \begingroup \realeverypar = {\leftskip = 2in plus 3em minus 1em +% \parfillskip = 0pt}% +% \everypar = {\vglue \baselineskip \the\realeverypar +% \everypar={\the\realeverypar}}% + % + % Now you can print the title using @title. + \def\title{\parsearg\titlezzz}% + \def\titlezzz##1{\leftline{\titlefont{##1} + \vskip4pt \hrule height 4pt \vskip4pt}% + \vglue\titlepagetopglue + % + % Now you can put text using @subtitle. + \def\subtitle{\parsearg\subtitlezzz}% + \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% + % + % @author should come last, but may come many times. + \def\author{\parsearg\authorzzz}% + \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi + {\authorfont \leftline{##1}}}% + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page +% \def\page{\vskip4pt \hrule height 2pt \vskip\titlepagebottomglue +% \oldpage \endgroup\hrule height0pt\relax}% + \def\page{\oldpage \hbox{}}} +} + +\def\Etitlepage{\endgroup\page\HEADINGSon} + +%%% Set up page headings and footings. + +\let\thispage=\folio + +\newtoks \evenheadline % Token sequence for heading line of even pages +\newtoks \oddheadline % Token sequence for heading line of odd pages +\newtoks \evenfootline % Token sequence for footing line of even pages +\newtoks \oddfootline % Token sequence for footing line of odd pages + +% Now make Tex use those variables +\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline \else \the\evenheadline \fi}} +\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline \else \the\evenfootline \fi}} + +% Commands to set those variables. +% For example, this is what @headings on does +% @evenheading @thistitle|@thispage|@thischapter +% @oddheading @thischapter|@thispage|@thistitle +% @evenfooting @thisfile|| +% @oddfooting ||@thisfile + +\def\evenheading{\parsearg\evenheadingxxx} +\def\oddheading{\parsearg\oddheadingxxx} +\def\everyheading{\parsearg\everyheadingxxx} + +\def\evenfooting{\parsearg\evenfootingxxx} +\def\oddfooting{\parsearg\oddfootingxxx} +\def\everyfooting{\parsearg\everyfootingxxx} + +{\catcode`\@=0 % + +\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} +\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% +\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} +\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% +\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\everyheadingxxx #1{\everyheadingyyy #1@|@|@|@|\finish} +\gdef\everyheadingyyy #1@|#2@|#3@|#4\finish{% +\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}} +\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} +\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% +\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} +\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% +\global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\everyfootingxxx #1{\everyfootingyyy #1@|@|@|@|\finish} +\gdef\everyfootingyyy #1@|#2@|#3@|#4\finish{% +\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}} +\global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} +% +}% unbind the catcode of @. + +% @headings double turns headings on for double-sided printing. +% @headings single turns headings on for single-sided printing. +% @headings off turns them off. +% @headings on same as @headings double, retained for compatibility. +% By default, they are off. + +\def\headings #1 {\csname HEADINGS#1\endcsname} + +\def\HEADINGSoff{ +\global\evenheadline={\hfil} \global\evenfootline={\hfil} +\global\oddheadline={\hfil} \global\oddfootline={\hfil}} +\HEADINGSoff +% When we turn headings on, set the page number to 1. +% For double-sided printing, put current file name in lower left corner, +% chapter name on inside top of right hand pages, document +% title on inside top of left hand pages, and page numbers on outside top +% edge of all pages. +\def\HEADINGSdouble{ +%\pagealignmacro +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +} +% For single-sided printing, chapter title goes across top left of page, +% page number on top right. +\def\HEADINGSsingle{ +%\pagealignmacro +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +} +\def\HEADINGSon{\HEADINGSdouble} + +% Subroutines used in generating headings +% Produces Day Month Year style of output. +\def\today{\number\day\space +\ifcase\month\or +January\or February\or March\or April\or May\or June\or +July\or August\or September\or October\or November\or December\fi +\space\number\year} + +% Use this if you want the Month Day, Year style of output. +%\def\today{\ifcase\month\or +%January\or February\or March\or April\or May\or June\or +%July\or August\or September\or October\or November\or December\fi +%\space\number\day, \number\year} + +% @settitle line... specifies the title of the document, for headings +% It generates no output of its own + +\def\thistitle{No Title} +\def\settitle{\parsearg\settitlezzz} +\def\settitlezzz #1{\gdef\thistitle{#1}} + +\message{tables,} + +% Tables -- @table, @ftable, @item(x), @kitem(x), @xitem(x). + +% default indentation of table text +\newdimen\tableindent \tableindent=.8in +% default indentation of @itemize and @enumerate text +\newdimen\itemindent \itemindent=.3in +% margin between end of table item and start of table text. +\newdimen\itemmargin \itemmargin=.1in + +% used internally for \itemindent minus \itemmargin +\newdimen\itemmax + +% Note @table and @ftable define @item, @itemx, etc., with these defs. +% They also define \itemindex +% to index the item name in whatever manner is desired (perhaps none). + +\def\internalBitem{\smallbreak \parsearg\itemzzz} +\def\internalBitemx{\par \parsearg\itemzzz} + +\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} +\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \par \parsearg\xitemzzz} + +\def\internalBkitem{\smallbreak \parsearg\kitemzzz} +\def\internalBkitemx{\par \parsearg\kitemzzz} + +\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}\itemzzz {#1}} + +\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}\itemzzz {#1}} + +\def\itemzzz #1{\begingroup % +\advance \hsize by -\rightskip % +\advance \hsize by -\leftskip % +\setbox0=\hbox{\itemfont{#1}}% +\itemindex{#1}% +\parskip=0in % +\noindent % +\ifdim \wd0>\itemmax % +\vadjust{\penalty 10000}% +\hbox to \hsize{\hskip -\tableindent\box0\hss}\ % +\else % +\hbox to 0pt{\hskip -\tableindent\box0\hss}% +\fi % +\endgroup % +} + +\def\item{\errmessage{@item while not in a table}} +\def\itemx{\errmessage{@itemx while not in a table}} +\def\kitem{\errmessage{@kitem while not in a table}} +\def\kitemx{\errmessage{@kitemx while not in a table}} +\def\xitem{\errmessage{@xitem while not in a table}} +\def\xitemx{\errmessage{@xitemx while not in a table}} + +%% Contains a kludge to get @end[description] to work +\def\description{\tablez{\dontindex}{1}{}{}{}{}} + +\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} +{\obeylines\obeyspaces% +\gdef\tablex #1^^M{% +\tabley\dontindex#1 \endtabley}} + +\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} +{\obeylines\obeyspaces% +\gdef\ftablex #1^^M{% +\tabley\fnitemindex#1 \endtabley}} + +\def\dontindex #1{} +\def\fnitemindex #1{\doind {fn}{\code{#1}}}% + +{\obeyspaces % +\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% +\tablez{#1}{#2}{#3}{#4}{#5}{#6}}} + +\def\tablez #1#2#3#4#5#6{% +\aboveenvbreak % +\begingroup % +\def\Edescription{\Etable}% Neccessary kludge. +\let\itemindex=#1% +\ifnum 0#3>0 \advance \leftskip by #3\mil \fi % +\ifnum 0#4>0 \tableindent=#4\mil \fi % +\ifnum 0#5>0 \advance \rightskip by #5\mil \fi % +\def\itemfont{#2}% +\itemmax=\tableindent % +\advance \itemmax by -\itemmargin % +\advance \leftskip by \tableindent % +\parindent = 0pt +\parskip = \smallskipamount +\ifdim \parskip=0pt \parskip=2pt \fi% +\def\Etable{\endgraf\endgroup\afterenvbreak}% +\let\item = \internalBitem % +\let\itemx = \internalBitemx % +\let\kitem = \internalBkitem % +\let\kitemx = \internalBkitemx % +\let\xitem = \internalBxitem % +\let\xitemx = \internalBxitemx % +} + +% This is the counter used by @enumerate, which is really @itemize + +\newcount \itemno + +\def\itemize{\parsearg\itemizezzz} + +\def\itemizezzz #1{\itemizey {#1}{\Eitemize}} + +\def\itemizey #1#2{% +\aboveenvbreak % +\begingroup % +\itemno = 0 % +\itemmax=\itemindent % +\advance \itemmax by -\itemmargin % +\advance \leftskip by \itemindent % +\parindent = 0pt +\parskip = \smallskipamount +\ifdim \parskip=0pt \parskip=2pt \fi% +\def#2{\endgraf\endgroup\afterenvbreak}% +\def\itemcontents{#1}% +\let\item=\itemizeitem} + +\def\bullet{$\ptexbullet$} +\def\minus{$-$} + +\def\enumerate{\itemizey{\the\itemno.}\Eenumerate\flushcr} + +% Definition of @item while inside @itemize. + +\def\itemizeitem{% +\advance\itemno by 1 +{\let\par=\endgraf \smallbreak}% +\ifhmode \errmessage{\in hmode at itemizeitem}\fi +{\parskip=0in \hskip 0pt +\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% +\vadjust{\penalty 300}}% +\flushcr} + +\message{indexing,} +% Index generation facilities + +% Define \newwrite to be identical to plain tex's \newwrite +% except not \outer, so it can be used within \newindex. +{\catcode`\@=11 +\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} + +% \newindex {foo} defines an index named foo. +% It automatically defines \fooindex such that +% \fooindex ...rest of line... puts an entry in the index foo. +% It also defines \fooindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is foo. +% The name of an index should be no more than 2 characters long +% for the sake of vms. + +\def\newindex #1{ +\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file +\openout \csname#1indfile\endcsname \jobname.#1 % Open the file +\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex +\noexpand\doindex {#1}} +} + +% @defindex foo == \newindex{foo} + +\def\defindex{\parsearg\newindex} + +% Define @defcodeindex, like @defindex except put all entries in @code. + +\def\newcodeindex #1{ +\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file +\openout \csname#1indfile\endcsname \jobname.#1 % Open the file +\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex +\noexpand\docodeindex {#1}} +} + +\def\defcodeindex{\parsearg\newcodeindex} + +% @synindex foo bar makes index foo feed into index bar. +% Do this instead of @defindex foo if you don't want it as a separate index. +\def\synindex #1 #2 {% +\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex +\noexpand\doindex {#2}}% +} + +% @syncodeindex foo bar similar, but put all entries made for index foo +% inside @code. +\def\syncodeindex #1 #2 {% +\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex +\noexpand\docodeindex {#2}}% +} + +% Define \doindex, the driver for all \fooindex macros. +% Argument #1 is generated by the calling \fooindex macro, +% and it is "foo", the name of the index. + +% \doindex just uses \parsearg; it calls \doind for the actual work. +% This is because \doind is more useful to call from other macros. + +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. + +\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} +\def\singleindexer #1{\doind{\indexname}{#1}} + +% like the previous two, but they put @code around the argument. +\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} +\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} + +\def\indexdummies{% +\def\bf{\realbackslash bf }% +\def\rm{\realbackslash rm }% +\def\sl{\realbackslash sl }% +\def\dots{\realbackslash dots }% +\def\copyright{\realbackslash copyright }% +} + +% \indexnofonts no-ops all font-change commands. +% This is used when outputting the strings to sort the index by. +\def\indexdummyfont#1{#1} +\def\indexnofonts{% +\let\code=\indexdummyfont +\let\samp=\indexdummyfont +\let\kbd=\indexdummyfont +\let\key=\indexdummyfont +\let\var=\indexdummyfont +} + +% To define \realbackslash, we must make \ not be an escape. +% We must first make another character (@) an escape +% so we do not become unable to do a definition. + +{\catcode`\@=0 \catcode`\\=\other +@gdef@realbackslash{\}} + +\let\indexbackslash=0 %overridden during \printindex. + +\def\doind #1#2{% +{\indexdummies % Must do this here, since \bf, etc expand at this stage +\count10=\lastpenalty % +\escapechar=`\\% +{\let\folio=0% Expand all macros now EXCEPT \folio +\def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now +% so it will be output as is; and it will print as backslash in the indx. +% +% Now process the index-string once, with all font commands turned off, +% to get the string to sort the index by. +{\indexnofonts +\xdef\temp1{#2}% +}% +% Now produce the complete index entry. We process the index-string again, +% this time with font commands expanded, to get what to print in the index. +\edef\temp{% +\write \csname#1indfile\endcsname{% +\realbackslash entry {\temp1}{\folio}{#2}}}% +\temp }% +\penalty\count10}} + +\def\dosubind #1#2#3{% +{\indexdummies % Must do this here, since \bf, etc expand at this stage +\count10=\lastpenalty % +\escapechar=`\\% +{\let\folio=0% +\def\rawbackslashxx{\indexbackslash}% +% +% Now process the index-string once, with all font commands turned off, +% to get the string to sort the index by. +{\indexnofonts +\xdef\temp1{#2 #3}% +}% +% Now produce the complete index entry. We process the index-string again, +% this time with font commands expanded, to get what to print in the index. +\edef\temp{% +\write \csname#1indfile\endcsname{% +\realbackslash entry {\temp1}{\folio}{#2}{#3}}}% +\temp }% +\penalty\count10}} + +% The index entry written in the file actually looks like +% \entry {sortstring}{page}{topic} +% or +% \entry {sortstring}{page}{topic}{subtopic} +% The texindex program reads in these files and writes files +% containing these kinds of lines: +% \initial {c} +% before the first topic whose initial is c +% \entry {topic}{pagelist} +% for a topic that is used without subtopics +% \primary {topic} +% for the beginning of a topic that is used with subtopics +% \secondary {subtopic}{pagelist} +% for each subtopic. + +% Define the user-accessible indexing commands +% @findex, @vindex, @kindex, @cindex. + +\def\findex {\fnindex} +\def\kindex {\kyindex} +\def\cindex {\cpindex} +\def\vindex {\vrindex} +\def\tindex {\tpindex} +\def\pindex {\pgindex} + +\def\cindexsub {\begingroup\obeylines\cindexsub} +{\obeylines % +\gdef\cindexsub "#1" #2^^M{\endgroup % +\dosubind{cp}{#2}{#1}}} + +% Define the macros used in formatting output of the sorted index material. + +% This is what you call to cause a particular index to get printed. +% Write +% @unnumbered Function Index +% @printindex fn + +\def\printindex{\parsearg\doprintindex} + +\def\doprintindex#1{\tex % +\catcode`\%=\other\catcode`\&=\other\catcode`\#=\other +\catcode`\$=\other\catcode`\_=\other +\catcode`\~=\other +\def\indexbackslash{\rawbackslashxx} +\indexfonts\rm \tolerance=9500 \advance\baselineskip -1pt +\begindoublecolumns +\openin 1 \jobname.#1s +\ifeof 1 \else \closein 1 \input \jobname.#1s +\fi +\enddoublecolumns +\Etex} + +% These macros are used by the sorted index file itself. +% Change them to control the appearance of the index. + +% Same as \bigskipamount except no shrink. +% \balancecolumns gets confused if there is any shrink. +\newskip\initialskipamount \initialskipamount 12pt plus4pt + +\outer\def\initial #1{% +{\let\tentt=\sectt \let\sf=\sectt +\ifdim\lastskip<\initialskipamount +\removelastskip \penalty-200 \vskip \initialskipamount\fi +\line{\secbf#1\hfill}\kern 2pt\penalty3000}} + +\outer\def\entry #1#2{ +{\parfillskip=0in \parskip=0in \parindent=0in +\hangindent=1in \hangafter=1% +\noindent\hbox{#1}\dotfill #2\par +}} + +\def\primary #1{\line{#1\hfil}} + +\newskip\secondaryindent \secondaryindent=0.5cm + +\def\secondary #1#2{ +{\parfillskip=0in \parskip=0in +\hangindent =1in \hangafter=1 +\noindent\hskip\secondaryindent\hbox{#1}\dotfill #2\par +}} + +%% Define two-column mode, which is used in indexes. +%% Adapted from the TeXBook, page 416 +\catcode `\@=11 + +\newbox\partialpage + +\newdimen\doublecolumnhsize \doublecolumnhsize = 3.11in +\newdimen\doublecolumnvsize \doublecolumnvsize = 19.1in + +\def\begindoublecolumns{\begingroup + \output={\global\setbox\partialpage=\vbox{\unvbox255\kern -\topskip \kern \baselineskip}}\eject + \output={\doublecolumnout} \hsize=\doublecolumnhsize \vsize=\doublecolumnvsize} +\def\enddoublecolumns{\output={\balancecolumns}\eject + \endgroup \pagegoal=\vsize} + +\def\doublecolumnout{\splittopskip=\topskip \splitmaxdepth=\maxdepth + \dimen@=\pageheight \advance\dimen@ by-\ht\partialpage + \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ + \onepageout\pagesofar \unvbox255 \penalty\outputpenalty} +\def\pagesofar{\unvbox\partialpage % + \hsize=\doublecolumnhsize % have to restore this since output routine +% changes it to set cropmarks (P. A. MacKay, 12 Nov. 1986) + \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}} +\def\balancecolumns{\setbox0=\vbox{\unvbox255} \dimen@=\ht0 + \advance\dimen@ by\topskip \advance\dimen@ by-\baselineskip + \divide\dimen@ by2 \splittopskip=\topskip + {\vbadness=10000 \loop \global\setbox3=\copy0 + \global\setbox1=\vsplit3 to\dimen@ + \ifdim\ht3>\dimen@ \global\advance\dimen@ by1pt \repeat} + \setbox0=\vbox to\dimen@{\unvbox1} \setbox2=\vbox to\dimen@{\unvbox3} + \pagesofar} + +\catcode `\@=\other +\message{sectioning,} +% Define chapters, sections, etc. + +\newcount \chapno +\newcount \secno +\newcount \subsecno +\newcount \subsubsecno + +% This counter is funny since it counts through charcodes of letters A, B, ... +\newcount \appendixno \appendixno = `\@ +\def\appendixletter{\char\the\appendixno} + +\newwrite \contentsfile +% This is called from \setfilename. +\def\opencontents{\openout \contentsfile = \jobname.toc} + +% Each @chapter defines this as the name of the chapter. +% page headings and footings can use it. @section does likewise + +\def\thischapter{} \def\thissection{} +\def\seccheck#1{\if \pageno<0 % +\errmessage{@#1 not allowed after generating table of contents}\fi +% +} + +\outer\def\chapter{\parsearg\chapterzzz} +\def\chapterzzz #1{\seccheck{chapter}% +\secno=0 \subsecno=0 \subsubsecno=0 \global\advance \chapno by 1 \message{Chapter \the\chapno}% +\chapmacro {#1}{\the\chapno}% +\gdef\thissection{#1}\gdef\thischapter{#1}% +\let\rawbackslash=\relax% +\let\frenchspacing=\relax% +\edef\temp{{\realbackslash chapentry {#1}{\the\chapno}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\donoderef % +} + +\outer\def\appendix{\parsearg\appendixzzz} +\def\appendixzzz #1{\seccheck{appendix}% +\secno=0 \subsecno=0 \subsubsecno=0 \global\advance \appendixno by 1 \message{Appendix \appendixletter}% +\chapmacro {#1}{Appendix \appendixletter}% +\gdef\thischapter{#1}\gdef\thissection{#1}% +\let\rawbackslash=\relax% +\let\frenchspacing=\relax% +\edef\temp{{\realbackslash chapentry {#1}{Appendix \appendixletter}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\unnumbnoderef % +} + +\outer\def\unnumbered{\parsearg\unnumberedzzz} +\def\unnumberedzzz #1{\seccheck{unnumbered}% +\secno=0 \subsecno=0 \subsubsecno=0 \message{(#1)} +\unnumbchapmacro {#1}% +\gdef\thischapter{#1}\gdef\thissection{#1}% +\let\rawbackslash=\relax% +\let\frenchspacing=\relax% +\edef\temp{{\realbackslash unnumbchapentry {#1}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\unnumbnoderef % +} + +\outer\def\section{\parsearg\sectionzzz} +\def\sectionzzz #1{\seccheck{section}% +\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % +\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% +\let\rawbackslash=\relax% +\let\frenchspacing=\relax% +\edef\temp{{\realbackslash secentry % +{#1}{\the\chapno}{\the\secno}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\donoderef % +\penalty 10000 % +} + +\outer\def\appendixsection{\parsearg\appendixsectionzzz} +\outer\def\appendixsec{\parsearg\appendixsectionzzz} +\def\appendixsectionzzz #1{\seccheck{appendixsection}% +\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % +\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% +\let\rawbackslash=\relax% +\let\frenchspacing=\relax% +\edef\temp{{\realbackslash secentry % +{#1}{\appendixletter}{\the\secno}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\unnumbnoderef % +\penalty 10000 % +} + +\outer\def\unnumberedsec{\parsearg\unnumberedseczzz} +\def\unnumberedseczzz #1{\seccheck{unnumberedsec}% +\plainsecheading {#1}\gdef\thissection{#1}% +\let\rawbackslash=\relax% +\let\frenchspacing=\relax% +\edef\temp{{\realbackslash unnumbsecentry{#1}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\unnumbnoderef % +\penalty 10000 % +} + +\outer\def\subsection{\parsearg\subsectionzzz} +\def\subsectionzzz #1{\seccheck{subsection}% +\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % +\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% +\let\rawbackslash=\relax% +\let\frenchspacing=\relax% +\edef\temp{{\realbackslash subsecentry % +{#1}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\donoderef % +\penalty 10000 % +} + +\outer\def\appendixsubsec{\parsearg\appendixsubseczzz} +\def\appendixsubseczzz #1{\seccheck{appendixsubsec}% +\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % +\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% +\let\rawbackslash=\relax% +\let\frenchspacing=\relax% +\edef\temp{{\realbackslash subsecentry % +{#1}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\unnumbnoderef % +\penalty 10000 % +} + +\outer\def\unnumberedsubsec{\parsearg\unnumberedsubseczzz} +\def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}% +\plainsecheading {#1}\gdef\thissection{#1}% +\let\rawbackslash=\relax% +\let\frenchspacing=\relax% +\edef\temp{{\realbackslash unnumbsubsecentry{#1}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\unnumbnoderef % +\penalty 10000 % +} + +\outer\def\subsubsection{\parsearg\subsubsectionzzz} +\def\subsubsectionzzz #1{\seccheck{subsubsection}% +\gdef\thissection{#1}\global\advance \subsubsecno by 1 % +\subsubsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% +\let\rawbackslash=\relax% +\let\frenchspacing=\relax% +\edef\temp{{\realbackslash subsubsecentry % +{#1}{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}%\ +\escapechar=`\\% +\write \contentsfile \temp % +\donoderef % +\penalty 10000 % +} + +\outer\def\appendixsubsubsec{\parsearg\appendixsubsubseczzz} +\def\appendixsubsubseczzz #1{\seccheck{appendixsubsubsec}% +\gdef\thissection{#1}\global\advance \subsubsecno by 1 % +\subsubsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% +\let\rawbackslash=\relax% +\let\frenchspacing=\relax% +\edef\temp{{\realbackslash subsubsecentry{#1}% +{\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}%\ +\escapechar=`\\% +\write \contentsfile \temp % +\unnumbnoderef % +\penalty 10000 % +} + +\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} +\def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}% +\plainsecheading {#1}\gdef\thissection{#1}% +\let\rawbackslash=\relax% +\let\frenchspacing=\relax% +\edef\temp{{\realbackslash unnumbsubsubsecentry{#1}{\noexpand\folio}}}% +\escapechar=`\\% +\write \contentsfile \temp % +\unnumbnoderef % +\penalty 10000 % +} + +% These are variants which are not "outer", so they can appear in @ifinfo. +\def\infounnumbered{\parsearg\unnumberedzzz} +\def\infounnumberedsec{\parsearg\unnumberedseczzz} +\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} +\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} + +\def\infoappendix{\parsearg\appendixzzz} +\def\infoappendixsec{\parsearg\appendixseczzz} +\def\infoappendixsubsec{\parsearg\appendixsubseczzz} +\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} + +\def\infochapter{\parsearg\chapterzzz} +\def\infosection{\parsearg\sectionzzz} +\def\infosubsection{\parsearg\subsectionzzz} +\def\infosubsubsection{\parsearg\subsubsectionzzz} + +% Define @majorheading, @heading and @subheading + +\def\majorheading #1{% +{\advance\chapheadingskip by 10pt \chapbreak }% +{\chapfonts \line{\rm #1\hfill}}\bigskip \par\penalty 200} + +\def\chapheading #1{\chapbreak % +{\chapfonts \line{\rm #1\hfill}}\bigskip \par\penalty 200} + +\def\heading{\parsearg\secheadingi} + +% These macros generate a chapter, section, etc. heading only +% (including whitespace, linebreaking, etc. around it), +% given all the information in convenient, parsed form. + +%%% Args are the skip and penalty (usually negative) +\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} + +\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} + +%%% Define plain chapter starts, and page on/off switching for it +% Parameter controlling skip before chapter headings (if needed) + +\newskip \chapheadingskip \chapheadingskip = 30pt plus 8pt minus 4pt + +\def\chapbreak{\dobreak \chapheadingskip {-4000}} +\def\chappager{\par\vfill\supereject} +\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} + +\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} + +\def\CHAPPAGoff{ +\global\let\pchapsepmacro=\chapbreak +\global\let\pagealignmacro=\chappager} + +\def\CHAPPAGon{ +\global\let\pchapsepmacro=\chappager +\global\let\pagealignmacro=\chappager +\global\def\HEADINGSon{\HEADINGSsingle}} + +\def\CHAPPAGodd{ +\global\let\pchapsepmacro=\chapoddpage +\global\let\pagealignmacro=\chapoddpage +\global\def\HEADINGSon{\HEADINGSdouble}} + +\CHAPPAGon + +\def\CHAPFplain{ +\global\let\chapmacro=\chfplain +\global\let\unnumbchapmacro=\unnchfplain} + +\def\chfplain #1#2{% +\pchapsepmacro % +{\chapfonts \line{\rm #2.\enspace #1\hfill}}\bigskip \par\penalty 5000 % +} + +\def\unnchfplain #1{% +\pchapsepmacro % +{\chapfonts \line{\rm #1\hfill}}\bigskip \par\penalty 10000 % +} +\CHAPFplain % The default + +\def\unnchfopen #1{% +\chapoddpage {\chapfonts \line{\rm #1\hfill}}\bigskip \par\penalty 10000 % +} + +\def\chfopen #1#2{\chapoddpage {\chapfonts +\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% +\par\penalty 5000 % +} + +\def\CHAPFopen{ +\global\let\chapmacro=\chfopen +\global\let\unnumbchapmacro=\unnchfopen} + +% Parameter controlling skip before section headings. + +\newskip \subsecheadingskip \subsecheadingskip = 17pt plus 8pt minus 4pt +\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} + +\newskip \secheadingskip \secheadingskip = 21pt plus 8pt minus 4pt +\def\secheadingbreak{\dobreak \secheadingskip {-1000}} + + +% Section fonts are the base font at magstep2, which produces +% a size a bit more than 14 points in the default situation. + +\def\secheading #1#2#3{\secheadingi {#2.#3\enspace #1}} +\def\plainsecheading #1{\secheadingi {#1}} +\def\secheadingi #1{{\advance \secheadingskip by \parskip % +\secheadingbreak}% +{\secfonts \line{\rm #1\hfill}}% +\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 } + + +% Subsection fonts are the base font at magstep1, +% which produces a size of 12 points. + +\def\subsecheading #1#2#3#4{{\advance \subsecheadingskip by \parskip % +\subsecheadingbreak}% +{\subsecfonts \line{\rm#2.#3.#4\enspace #1\hfill}}% +\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 } + +\def\subsubsecfonts{\subsecfonts} % Maybe this should change: + % Perhaps make sssec fonts scaled + % magstep half +\def\subsubsecheading #1#2#3#4#5{{\advance \subsecheadingskip by \parskip % +\subsecheadingbreak}% +{\subsubsecfonts \line{\rm#2.#3.#4.#5\enspace #1\hfill}}% +\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000} + + +\message{toc printing,} + +% Finish up the main text and prepare to read what we've written +% to \contentsfile. + +\def\startcontents#1{% + \ifnum \pageno>0 + \pagealignmacro + \immediate\closeout \contentsfile + \pageno = -1 % Request roman numbered pages. + \fi + \unnumbchapmacro{#1}\def\thischapter{#1}% + \begingroup % Set up to handle contents files properly. + \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 + \raggedbottom % Worry more about breakpoints than the bottom. + \advance\hsize by -1in % Don't use the full line length. +} + + +% Normal (long) toc. +\outer\def\contents{% + \startcontents{Table of Contents}% + \input \jobname.toc + \endgroup + \vfill \eject +} + +% And just the chapters. +\outer\def\summarycontents{% + \startcontents{Short Contents}% + % + \let\chapentry = \shortchapentry + \let\unnumbchapentry = \shortunnumberedentry + % We want a true roman here for the page numbers. + \secfonts \let\rm = \truesecrm \rm + \advance\baselineskip by 1pt % Open it up a little. + \def\secentry ##1##2##3##4{} + \def\unnumbsecentry ##1##2{} + \def\subsecentry ##1##2##3##4##5{} + \def\unnumbsubsecentry ##1##2{} + \def\subsubsecentry ##1##2##3##4##5##6{} + \def\unnumbsubsubsecentry ##1##2{} + \input \jobname.toc + \endgroup + \vfill \eject +} +\let\shortcontents = \summarycontents + +% These macros generate individual entries in the table of contents. +% The first argument is the chapter or section name. +% The last argument is the page number. +% The arguments in between are the chapter number, section number, ... + +% Chapter-level things, for both the long and short contents. +\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} +\def\shortchapentry#1#2#3{% + \line{{#2\labelspace #1}\dotfill\doshortpageno{#3}}% +} + +\def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} +\def\shortunnumberedentry#1#2{% + \line{#1\dotfill\doshortpageno{#2}}% +} + +% Sections. +\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} +\def\unnumbsecentry#1#2{\dosecentry{#1}{#2}} + +% Subsections. +\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} +\def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}} + +% And subsubsections. +\def\subsubsecentry#1#2#3#4#5#6{\dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} +\def\unnumbsubsecentry#1#2{\dosubsubsecentry{#1}{#2}} + + +% This parameter controls the indentation of the various levels. +\newdimen\tocindent \tocindent = 3pc + +% Now for the actual typesetting. In all these, #1 is the text and #2 is the +% page number. +% +% If the toc has to be broken over pages, we would want to be at chapters +% if at all possible; hence the \penalty. +\def\dochapentry#1#2{% + \penalty-300 \vskip\baselineskip + \line{\chapentryfonts #1\dotfill \dopageno{#2}}% + \nobreak\vskip .25\baselineskip +} + +\def\dosecentry#1#2{% + \line{\secentryfonts \hskip\tocindent #1\dotfill \dopageno{#2}}% +} + +\def\dosubsecentry#1#2{% + \line{\subsecentryfonts \hskip2\tocindent #1\dotfill \dopageno{#2}}% +} + +\def\dosubsubsecentry#1#2{% + \line{\subsubsecentryfonts \hskip3\tocindent #1\dotfill \dopageno{#2}}% +} + +% Space between chapter (or whatever) number and the title. +\def\labelspace{\hskip1em \relax} + +\def\dopageno#1{{\rm #1}} +\def\doshortpageno#1{{\rm #1}} + +\def\chapentryfonts{\secfonts \let\rm = \sf \sf} +\def\secentryfonts{\textfonts} +\let\subsecentryfonts = \textfonts +\let\subsubsecentryfonts = \textfonts + + +\message{environments,} + +% @tex ... @end tex escapes into raw Tex temporarily. +% One exception: @ is still an escape character, so that @end tex works. +% But \@ or @@ will get a plain tex @ character. + +\def\tex{\begingroup +\catcode `\\=0 \catcode `\{=1 \catcode `\}=2 +\catcode `\$=3 \catcode `\&=4 \catcode `\#=6 +\catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie +\catcode `\%=14 +\catcode`\"=12 +\catcode`\|=12 +\catcode`\<=12 +\catcode`\>=12 +\escapechar=`\\ +% +\let\{=\ptexlbrace +\let\}=\ptexrbrace +\let\.=\ptexdot +\let\*=\ptexstar +\def\@={@}% +\let\bullet=\ptexbullet +\let\b=\ptexb \let\c=\ptexc \let\i=\ptexi \let\t=\ptext \let\l=\ptexl +\let\L=\ptexL +% +\let\Etex=\endgroup} + +% Define @lisp ... @endlisp. +% @lisp does a \begingroup so it can rebind things, +% including the definition of @endlisp (which normally is erroneous). + +% Amount to narrow the margins by for @lisp. +\newskip\lispnarrowing \lispnarrowing=0.4in + +% This is the definition that ^M gets inside @lisp +% phr: changed space to \null, to avoid overfull hbox problems. +{\obeyspaces% +\gdef\lisppar{\null\endgraf}} + +% Cause \obeyspaces to make each Space cause a word-separation +% rather than the default which is that it acts punctuation. +% This is because space in tt font looks funny. +{\obeyspaces % +\gdef\sepspaces{\def {\ }}} + +\newskip\aboveenvskipamount \aboveenvskipamount= 0pt +\def\aboveenvbreak{{\advance\aboveenvskipamount by \parskip +\endgraf \ifdim\lastskip<\aboveenvskipamount +\removelastskip \penalty-50 \vskip\aboveenvskipamount \fi}} + +\def\afterenvbreak{\endgraf \ifdim\lastskip<\aboveenvskipamount +\removelastskip \penalty-50 \vskip\aboveenvskipamount \fi} + +\def\lisp{\aboveenvbreak\begingroup\inENV %This group ends at the end of the @lisp body +\hfuzz=12truept % Don't be fussy +% Make spaces be word-separators rather than space tokens. +\sepspaces % +% Single space lines +\singlespace % +% The following causes blank lines not to be ignored +% by adding a space to the end of each line. +\let\par=\lisppar +\def\Elisp{\endgroup\afterenvbreak}% +\parskip=0pt +\advance \leftskip by \lispnarrowing +\parindent=0pt +\let\exdent=\internalexdent +\obeyspaces \obeylines \tt \rawbackslash +\def\next##1{}\next} + + +\let\example=\lisp +\def\Eexample{\Elisp} + +\let\smallexample=\lisp +\def\Esmallexample{\Elisp} + +% Macro for 9 pt. examples, necessary to print with 5" lines. +% From Pavel@xerox. This is not really used unless the +% @smallbook command is given. + +\def\smalllispx{\aboveenvbreak\begingroup\inENV +% This group ends at the end of the @lisp body +\hfuzz=12truept % Don't be fussy +% Make spaces be word-separators rather than space tokens. +\sepspaces % +% Single space lines +\singlespace % +% The following causes blank lines not to be ignored +% by adding a space to the end of each line. +\let\par=\lisppar +\def\Esmalllisp{\endgroup\afterenvbreak}% +\parskip=0pt +\advance \leftskip by \lispnarrowing +\parindent=0pt +\let\exdent=\internalexdent +\obeyspaces \obeylines \ninett \rawbackslash +\def\next##1{}\next} + +% This is @display; same as @lisp except use roman font. + +\def\display{\begingroup\inENV %This group ends at the end of the @display body +\aboveenvbreak +% Make spaces be word-separators rather than space tokens. +\sepspaces % +% Single space lines +\singlespace % +% The following causes blank lines not to be ignored +% by adding a space to the end of each line. +\let\par=\lisppar +\def\Edisplay{\endgroup\afterenvbreak}% +\parskip=0pt +\advance \leftskip by \lispnarrowing +\parindent=0pt +\let\exdent=\internalexdent +\obeyspaces \obeylines +\def\next##1{}\next} + +% This is @format; same as @lisp except use roman font and don't narrow margins + +\def\format{\begingroup\inENV %This group ends at the end of the @format body +\aboveenvbreak +% Make spaces be word-separators rather than space tokens. +\sepspaces % +\singlespace % +% The following causes blank lines not to be ignored +% by adding a space to the end of each line. +\let\par=\lisppar +\def\Eformat{\endgroup\afterenvbreak} +\parskip=0pt \parindent=0pt +\obeyspaces \obeylines +\def\next##1{}\next} + +% @flushleft and @flushright + +\def\flushleft{\begingroup\inENV %This group ends at the end of the @format body +\aboveenvbreak +% Make spaces be word-separators rather than space tokens. +\sepspaces % +% The following causes blank lines not to be ignored +% by adding a space to the end of each line. +% This also causes @ to work when the directive name +% is terminated by end of line. +\let\par=\lisppar +\def\Eflushleft{\endgroup\afterenvbreak}% +\parskip=0pt \parindent=0pt +\obeyspaces \obeylines +\def\next##1{}\next} + +\def\flushright{\begingroup\inENV %This group ends at the end of the @format body +\aboveenvbreak +% Make spaces be word-separators rather than space tokens. +\sepspaces % +% The following causes blank lines not to be ignored +% by adding a space to the end of each line. +% This also causes @ to work when the directive name +% is terminated by end of line. +\let\par=\lisppar +\def\Eflushright{\endgroup\afterenvbreak}% +\parskip=0pt \parindent=0pt +\advance \leftskip by 0pt plus 1fill +\obeyspaces \obeylines +\def\next##1{}\next} + +% @quotation - narrow the margins. + +\def\quotation{\begingroup\inENV %This group ends at the end of the @quotation body +{\parskip=0pt % because we will skip by \parskip too, later +\aboveenvbreak}% +\singlespace +\parindent=0pt +\def\Equotation{\par\endgroup\afterenvbreak}% +\advance \rightskip by \lispnarrowing +\advance \leftskip by \lispnarrowing} + +\message{defuns,} +% Define formatter for defuns +% First, allow user to change definition object font (\df) internally +\def\setdeffont #1 {\csname DEF#1\endcsname} + +\newskip\defbodyindent \defbodyindent=36pt +\newskip\defargsindent \defargsindent=50pt +\newskip\deftypemargin \deftypemargin=12pt +\newskip\deflastargmargin \deflastargmargin=18pt + +\newcount\parencount +% define \functionparens, which makes ( and ) and & do special things. +% \functionparens affects the group it is contained in. +\def\activeparens{% +\catcode`\(=\active \catcode`\)=\active \catcode`\&=\active +\catcode`\[=\active \catcode`\]=\active} +{\activeparens % Now, smart parens don't turn on until &foo (see \amprm) +\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } +\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} + +% Definitions of (, ) and & used in args for functions. +% This is the definition of ( outside of all parentheses. +\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested % +\global\advance\parencount by 1 } +% +% This is the definition of ( when already inside a level of parens. +\gdef\opnested{\char`\(\global\advance\parencount by 1 } +% +\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. +% also in that case restore the outer-level definition of (. +\ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi +\global\advance \parencount by -1 } +% If we encounter &foo, then turn on ()-hacking afterwards +\gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } +% +\gdef\normalparens{\boldbrax\let&=\ampnr} +} % End of definition inside \activeparens +%% These parens (in \boldbrax) actually are a little bolder than the +%% contained text. This is especially needed for [ and ] +\def\opnr{{\sf\char`\(}} \def\clnr{{\sf\char`\)}} \def\ampnr{\&} +\def\lbrb{{\tt\char`\[}} \def\rbrb{{\tt\char`\]}} + +% First, defname, which formats the header line itself. +% #1 should be the function name. +% #2 should be the type of definition, such as "Function". + +\def\defname #1#2{% +\leftskip = 0in % +\noindent % +\setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% +\dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line +\dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations +\parshape 2 0in \dimen0 \defargsindent \dimen1 % +% Now output arg 2 ("Function" or some such) +% ending at \deftypemargin from the right margin, +% but stuck inside a box of width 0 so it does not interfere with linebreaking +\rlap{\rightline{{\rm #2}\hskip \deftypemargin}}% +\tolerance=10000 \hbadness=10000 % Make all lines underfull and no complaints +{\df #1}\enskip % Generate function name +} + +% Actually process the body of a definition +% #1 should be the terminating control sequence, such as \Edefun. +% #2 should be the "another name" control sequence, such as \defunx. +% #3 should be the control sequence that actually processes the header, +% such as \defunheader. + +\def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2{\begingroup\obeylines\activeparens\spacesplit#3}% +\parindent=0in \leftskip=\defbodyindent % +\begingroup\obeylines\activeparens\spacesplit#3} + +\def\defmethparsebody #1#2#3#4 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% +\parindent=0in \leftskip=\defbodyindent % +\begingroup\obeylines\activeparens\spacesplit{#3{#4}}} + +\def\defopparsebody #1#2#3#4#5 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 ##2 {\def#4{##1}% +\begingroup\obeylines\activeparens\spacesplit{#3{##2}}}% +\parindent=0in \leftskip=\defbodyindent % +\begingroup\obeylines\activeparens\spacesplit{#3{#5}}} + +% Split up #2 at the first space token. +% call #1 with two arguments: +% the first is all of #2 before the space token, +% the second is all of #2 after that space token. +% If #2 contains no space token, all of it is passed as the first arg +% and the second is passed as empty. + +{\obeylines +\gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}% +\long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{% +\ifx\relax #3% +#1{#2}{}\else #1{#2}{#3#4}\fi}} + +% So much for the things common to all kinds of definitions. + +% Define @defun. + +% First, define the processing that is wanted for arguments of \defun +% Use this to expand the args and terminate the paragraph they make up + +\def\defunargs #1{\functionparens \sl #1% +\ifnum\parencount=0 \else \errmessage{unbalanced parens in @def arguments}\fi% +\interlinepenalty=10000 +\endgraf\vskip -\parskip \penalty 10000} + +% Do complete processing of one @defun or @defunx line already parsed. + +% @deffn Command forward-char nchars + +\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} + +\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% +\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup} + +% @defun == @deffn Function + +\def\defun{\defparsebody\Edefun\defunx\defunheader} + +\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{Function}% +\defunargs {#2}\endgroup % +} + +% @defmac == @deffn Macro + +\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} + +\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{Macro}% +\defunargs {#2}\endgroup % +} + +% @defspec == @deffn Special Form + +\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} + +\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{Special form}% +\defunargs {#2}\endgroup % +} + +% This definition is run if you use @defunx +% anywhere other than immediately after a @defun or @defunx. + +\def\deffnx #1 {\errmessage{@deffnx in invalid context}} +\def\defunx #1 {\errmessage{@defunx in invalid context}} +\def\defmacx #1 {\errmessage{@defmacx in invalid context}} +\def\defspecx #1 {\errmessage{@defspecx in invalid context}} + +% @defmethod, and so on + +% @defop {Funny Method} foo-class frobnicate argument + +\def\defop #1 {\def\defoptype{#1}% +\defopparsebody\Edefop\defopx\defopheader\defoptype} + +\def\defopheader #1#2#3{\dosubind {fn}{\code{#2}}{on #1}% Make entry in function index +\begingroup\defname {#2}{\defoptype{} on #1}% +\defunargs {#3}\endgroup % +} + +% @defmethod == @defop Method + +\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} + +\def\defmethodheader #1#2#3{\dosubind {fn}{\code{#2}}{on #1}% entry in function index +\begingroup\defname {#2}{Operation on #1}% +\defunargs {#3}\endgroup % +} + +% @defcv {Class Option} foo-class foo-flag + +\def\defcv #1 {\def\defcvtype{#1}% +\defopparsebody\Edefcv\defcvx\defcvheader\defcvtype} + +\def\defcvarheader #1#2#3{% +\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index +\begingroup\defname {#2}{\defcvtype of #1}% +\defvarargs {#3}\endgroup % +} + +% @defivar == @defcv {Instance Variable} + +\def\defivar{\defmethparsebody\Edefivar\defivarx\defivarheader} + +\def\defivarheader #1#2#3{% +\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index +\begingroup\defname {#2}{Instance variable of #1}% +\defvarargs {#3}\endgroup % +} + +% These definitions are run if you use @defmethodx, etc., +% anywhere other than immediately after a @defmethod, etc. + +\def\defopx #1 {\errmessage{@defopx in invalid context}} +\def\defmethodx #1 {\errmessage{@defmethodx in invalid context}} +\def\defcvx #1 {\errmessage{@defcvx in invalid context}} +\def\defivarx #1 {\errmessage{@defivarx in invalid context}} + +% Now @defvar + +% First, define the processing that is wanted for arguments of @defvar. +% This is actually simple: just print them in roman. +% This must expand the args and terminate the paragraph they make up +\def\defvarargs #1{\normalparens #1% +\interlinepenalty=10000 +\endgraf\vskip -\parskip \penalty 10000} + +% @defvr Counter foo-count + +\def\defvr{\defmethparsebody\Edefvr\defvrx\defvrheader} + +\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% +\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} + +% @defvar == @defvr Variable + +\def\defvar{\defparsebody\Edefvar\defvarx\defvarheader} + +\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{Variable}% +\defvarargs {#2}\endgroup % +} + +% @defopt == @defvr {User Option} + +\def\defopt{\defparsebody\Edefopt\defoptx\defoptheader} + +\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{User Option}% +\defvarargs {#2}\endgroup % +} + +% This definition is run if you use @defvarx +% anywhere other than immediately after a @defvar or @defvarx. + +\def\defvrx #1 {\errmessage{@defvrx in invalid context}} +\def\defvarx #1 {\errmessage{@defvarx in invalid context}} +\def\defoptx #1 {\errmessage{@defoptx in invalid context}} + +% Now define @deftp +% Args are printed in bold, a slight difference from @defvar. + +\def\deftpargs #1{\bf \defvarargs{#1}} + +% @deftp Class window height width ... + +\def\deftp{\defmethparsebody\Edeftp\deftpx\deftpheader} + +\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% +\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} + +% This definition is run if you use @deftpx, etc +% anywhere other than immediately after a @deftp, etc. + +\def\deftpx #1 {\errmessage{@deftpx in invalid context}} + +\message{cross reference,} +% Define cross-reference macros +\newwrite \auxfile + +% \setref{foo} defines a cross-reference point named foo. + +\def\setref#1{% +\dosetq{#1-pg}{Ypagenumber}% +\dosetq{#1-snt}{Ysectionnumberandtype}} + +\def\unnumbsetref#1{% +\dosetq{#1-pg}{Ypagenumber}% +\dosetq{#1-snt}{Ynothing}} + +% \xref and \pxref generate cross references to specified points. + +\def\pxref #1{see \xrefX [#1,,,,,,,]} +\def\xref #1{See \xrefX [#1,,,,,,,]} +\def\xrefX [#1,#2,#3,#4,#5,#6]{% +\setbox1=\hbox{\i{\losespace#5{}}}% +\setbox0=\hbox{\losespace#3{}}% +\ifdim \wd0 =0pt \setbox0=\hbox{\losespace#1{}}\fi% +\ifdim \wd1 >0pt% +section \unhbox0{} in \unhbox1% +\else% +\refx{#1-snt} [\unhbox0], page\tie \refx{#1-pg}% +\fi } + +% \dosetq is the interface for calls from other macros + +\def\dosetq #1#2{{\let\folio=0% +\edef\next{\write\auxfile{\internalsetq {#1}{#2}}}% +\next}} + +% \internalsetq {foo}{page} expands into CHARACTERS 'xrdef {foo}{...expansion of \Ypage...} +% When the aux file is read, ' is the escape character + +\def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}} + +% Things to be expanded by \internalsetq + +\def\Ypagenumber{\folio} + +\def\Ynothing{} + +\def\Ysectionnumberandtype{% +\ifnum\secno=0 chapter\xreftie\the\chapno % +\else \ifnum \subsecno=0 section\xreftie\the\chapno.\the\secno % +\else \ifnum \subsubsecno=0 % +section\xreftie\the\chapno.\the\secno.\the\subsecno % +\else % +section\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % +\fi \fi \fi } + +\gdef\xreftie{'tie} + +% Define @refx to reference a specific cross-reference string. + +\def\refx#1{% +{% +\expandafter\ifx\csname X#1\endcsname\relax +% If not defined, say something at least. +\expandafter\gdef\csname X#1\endcsname {$<$undefined$>$}% +\message {WARNING: Cross-reference "#1" used but not yet defined}% +\message {}% +\fi % +\csname X#1\endcsname %It's defined, so just use it. +}} + +% Read the last existing aux file, if any. No error if none exists. + +% This is the macro invoked by entries in the aux file. +\def\xrdef #1#2{ +{\catcode`\'=\other\expandafter \gdef \csname X#1\endcsname {#2}}} + +\def\readauxfile{% +\begingroup +\catcode `\^^@=\other +\catcode `\=\other +\catcode `\=\other +\catcode `\^^C=\other +\catcode `\^^D=\other +\catcode `\^^E=\other +\catcode `\^^F=\other +\catcode `\^^G=\other +\catcode `\^^H=\other +\catcode `\ =\other +\catcode `\^^L=\other +\catcode `\=\other +\catcode `\=\other +\catcode `\=\other +\catcode `\=\other +\catcode `\=\other +\catcode `\=\other +\catcode `\=\other +\catcode `\=\other +\catcode `\=\other +\catcode `\=\other +\catcode `\=\other +\catcode `\=\other +\catcode `\=\other +\catcode `\^^[=\other +\catcode `\^^\=\other +\catcode `\^^]=\other +\catcode `\^^^=\other +\catcode `\^^_=\other +\catcode `\@=\other +\catcode `\^=\other +\catcode `\~=\other +\catcode `\[=\other +\catcode `\]=\other +\catcode`\"=\other +\catcode`\_=\other +\catcode`\|=\other +\catcode`\<=\other +\catcode`\>=\other +\catcode `\$=\other +\catcode `\#=\other +\catcode `\&=\other +% the aux file uses ' as the escape. +% Turn off \ as an escape so we do not lose on +% entries which were dumped with control sequences in their names. +% For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^ +% Reference to such entries still does not work the way one would wish, +% but at least they do not bomb out when the aux file is read in. +\catcode `\{=1 \catcode `\}=2 +\catcode `\%=\other +\catcode `\'=0 +\catcode `\\=\other +\openin 1 \jobname.aux +\ifeof 1 \else \closein 1 \input \jobname.aux +\fi +% Open the new aux file. Tex will close it automatically at exit. +\openout \auxfile=\jobname.aux +\endgroup} + + +% Footnotes. + +\newcount \footnoteno + +\def\supereject{\par\penalty -20000\footnoteno =0 } + +\let\ptexfootnote=\footnote + +{\catcode `\@=11 +\gdef\footnote{\global\advance \footnoteno by \@ne +\edef\thisfootno{$^{\the\footnoteno}$}% +\let\@sf\empty +\ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi +\thisfootno\@sf\parsearg\footnotezzz} + +\gdef\footnotezzz #1{\insert\footins{ +\interlinepenalty\interfootnotelinepenalty +\splittopskip\ht\strutbox % top baseline for broken footnotes +\splitmaxdepth\dp\strutbox \floatingpenalty\@MM +\leftskip\z@skip \rightskip\z@skip \spaceskip\z@skip \xspaceskip\z@skip +\footstrut\hang\textindent{\thisfootno}#1\strut}} + +}%end \catcode `\@=11 + +% End of control word definitions. + +\message{and turning on texinfo input format.} + +\def\openindices{% + \newindex{cp}% + \newcodeindex{fn}% + \newcodeindex{vr}% + \newcodeindex{tp}% + \newcodeindex{ky}% + \newcodeindex{pg}% +} + +% Set some numeric style parameters, for 8.5 x 11 format. + +\hsize = 6.5in +\parindent 15pt +\parskip 18pt plus 1pt +\baselineskip 15pt +\advance\topskip by 1.2cm + +% Prevent underfull vbox error messages. +\vbadness=10000 + +% Use @smallbook to reset parameters for 7x9.5 format +\def\smallbook{ +\global\lispnarrowing = 0.3in +\global\baselineskip 12pt +\global\parskip 3pt plus 1pt +\global\hsize = 5in +\global\doublecolumnhsize=2.4in \global\doublecolumnvsize=15.0in +\global\vsize=7.5in +\global\tolerance=700 +\global\hfuzz=1pt + +\global\pagewidth=\hsize +\global\pageheight=\vsize +\global\font\ninett=cmtt9 + +\global\let\smalllisp=\smalllispx +\global\let\smallexample=\smalllispx +\global\def\Esmallexample{\Esmalllisp} +} + +%% For a final copy, take out the rectangles +%% that mark overfull boxes (in case you have decided +%% that the text looks ok even though it passes the margin). +\def\finalout{\overfullrule=0pt} + +% Turn off all special characters except @ +% (and those which the user can use as if they were ordinary) +% Define certain chars to be always in tt font. + +\catcode`\"=\active +\def\activedoublequote{{\tt \char '042}} +\let"=\activedoublequote +\catcode`\~=\active +\def~{{\tt \char '176}} +\chardef\hat=`\^ +\catcode`\^=\active +\def^{{\tt \hat}} +\catcode`\_=\active +\def_{{\tt \char '137}} +\catcode`\|=\active +\def|{{\tt \char '174}} +\chardef \less=`\< +\catcode`\<=\active +\def<{{\tt \less}} +\chardef \gtr=`\> +\catcode`\>=\active +\def>{{\tt \gtr}} + +\catcode`\@=0 + +% \rawbackslashxx output one backslash character in current font +{\catcode`\\=\other +@gdef@rawbackslashxx{\}} + +% \rawbackslash redefines \ as input to do \rawbackslashxx. +{\catcode`\\=\active +@gdef@rawbackslash{@let\=@rawbackslashxx }} + +% \normalbackslash outputs one backslash in fixed width font. +\def\normalbackslash{{\tt\rawbackslashxx}} + +% Say @foo, not \foo, in error messages. +\escapechar=`\@ + +@c \catcode 17=0 @c Define control-q +\catcode`\\=\active + +% If a .fmt file is being used, we don't want the `\input texinfo' to show up. +% That is what \eatinput is for; after that, the `\' should revert to printing +% a backslash. +% +@gdef@eatinput input texinfo{@fixbackslash} +@global@let\ = @eatinput + +% On the other hand, perhaps the file did not have a `\input texinfo'. Then +% the first `\{ in the file would cause an error. This macro tries to fix +% that, assuming it is called before the first `\' could plausibly occur. +% +@gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi} + +%% These look ok in all fonts, so just make them not special. The @rm below +%% makes sure that the current font starts out as the newly loaded cmr10 +@catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other + +@textfonts +@rm diff --git a/usr.sbin/amd/fsinfo/Makefile b/usr.sbin/amd/fsinfo/Makefile new file mode 100644 index 0000000..50f4642 --- /dev/null +++ b/usr.sbin/amd/fsinfo/Makefile @@ -0,0 +1,30 @@ +# @(#)Makefile 8.1 (Berkeley) 6/28/93 + +PROG= fsinfo +MAN8= fsinfo.0 +SRCS= fsinfo.c fsi_gram.c fsi_lex.c \ + fsi_util.c fsi_analyze.c fsi_dict.c \ + wr_atab.c wr_bparam.c wr_dumpset.c \ + wr_exportfs.c wr_fstab.c +CLEANFILES= \ + fsi_gram.c y.tab.c fsi_gram.h y.tab.h \ + fsi_lex.c lex.yy.c y.output +CFLAGS+=-I. +CFLAGS+=-I${.CURDIR}/../include +CFLAGS+=-I${.CURDIR}/../config +CFLAGS+=-DOS_HDR=\"os-bsd44.h\" + +fsi_lex.o fsinfo.o: fsi_gram.h +fsi_gram.c fsi_gram.h: ../fsinfo/fsi_gram.y + @echo "# expect 2 shift/reduce conflicts" + ${YACC} -d ${.CURDIR}/fsi_gram.y + mv y.tab.c fsi_gram.c + mv y.tab.h fsi_gram.h + +fsi_lex.c: ../fsinfo/fsi_lex.l + ${LEX} ${.CURDIR}/fsi_lex.l + mv lex.yy.c fsi_lex.c + +.PATH: ${.CURDIR}/../config +.include "../../Makefile.inc" +.include diff --git a/usr.sbin/amd/fsinfo/conf/automounts b/usr.sbin/amd/fsinfo/conf/automounts new file mode 100644 index 0000000..ee4b4ee --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/automounts @@ -0,0 +1,48 @@ +host localhost.doc.ic.ac.uk + +fs localhost:/localhost { + fstype = export + mount default { + exportfs "" + volname /home/localhost + } +} + +automount opts "opts:=rw,nosuid,grpid" /vol { + rwho {} + r+d {} + public {} + src { gnu{} athena{} gould{} utx{} sos4{} xinu43{} } + export { + exec { + sun3 {} + sun4 {} + } + roots {} + swaps { + tsun1 {} tsun2 {} tsun3 {} tsun4 {} tsun5 {} tsun6 {} + tsun7 {} tsun8 {} tsun9 {} tsun10 {} tsun11 {} tsun12 {} + tsun13 {} tsun14 {} tsun15 {} tsun16 {} tsun17 {} tsun18 {} + tsun19 {} + tcsun1 {} tcsun2 {} tcsun3 {} tcsun4 {} tcsun5 {} + } + misc {} + } +} + +automount opts "opts:=rw,nosuid,grpid" /home { + achilles {} + toytown {} + gummo {} + dylan { dk2{} dk5 {} } + ganymede {} + gould { staff{} teach{} } + "localhost" -> localhost +} + +automount opts "opts:=rw,nosuid,grpid" /homes { + opr -> /home/localhost/opr +#include "users" +} + +automount /usr/achilles = /home/achilles diff --git a/usr.sbin/amd/fsinfo/conf/csg_sun3 b/usr.sbin/amd/fsinfo/conf/csg_sun3 new file mode 100644 index 0000000..7d75db2 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/csg_sun3 @@ -0,0 +1,18 @@ +// $Id$ +// standard setups for DoC tsuns. +// note that no /var/spool/rwho is mounted as we now expect amd to do this as /vol/rwho + +// a sun3 +#ifndef SOS4_SYS_OPTS +#define SOS4_SYS_OPTS grpid,hard,intr +#endif +#define CSG_SUN3(HOST,DOMAIN,BOOT,EXEC) \ +host HOST.DOMAIN \ +\ +mount /vol/export/roots/HOST as / from BOOT opts rw,SOS4_SYS_OPTS \ +mount /vol/export/swaps/HOST fstype swap as swap from BOOT opts swap \ +mount /vol/export/exec/sun3 as /usr from EXEC opts ro,SOS4_SYS_OPTS \ +mount /vol/export/misc/crash/HOST as /var/crash/HOST from EXEC opts rw,nosuid,SOS4_SYS_OPTS \ +mount /vol/export/misc/tmp/HOST as /tmp from EXEC opts rw,nosuid,SOS4_SYS_OPTS \ +mount /vol/export/misc/usr.tmp/HOST as /var/tmp from EXEC opts rw,nosuid,SOS4_SYS_OPTS \ +mount /var/mmdf from BOOT opts rw,nosuid,SOS4_SYS_OPTS diff --git a/usr.sbin/amd/fsinfo/conf/csg_vax b/usr.sbin/amd/fsinfo/conf/csg_vax new file mode 100644 index 0000000..0ef23a5 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/csg_vax @@ -0,0 +1,67 @@ +// $Id$ +// csg vax config - really just for {s,r}vax + +#define FSTYPE_UFS 4.2 +#define DEFAULT_OPTS rw + +#define CSG_VAX(HOST,DOMAIN) \ +host HOST.DOMAIN\ +\ +/*\ +arch vax\ +os xinu43\ +cluster csg\ +dumphost flamingo.doc.ic.ac.uk\ +*/\ +\ +// root\ +fs /dev/hp0a {\ + fstype = FSTYPE_UFS\ + opts = DEFAULT_OPTS\ + freq = 1\ + passno = 1\ + mount / {}\ +}\ +\ +// swap\ +fs /dev/hp0b {\ + fstype = swap\ +}\ +\ +// usr\ +fs /dev/hp0e {\ + fstype = FSTYPE_UFS\ + opts = DEFAULT_OPTS\ + freq = 1\ + passno = 2\ + mount /usr {\ + exportfs "\\\ + sky.doc.ic.ac.uk\\\ + svax.doc.ic.ac.uk\\\ + rvax.doc.ic.ac.uk\\\ + ivax.doc.ic.ac.uk\\\ + "\ + }\ +}\ +\ +// var\ +fs /dev/hp0d {\ + fstype = FSTYPE_UFS\ + opts = DEFAULT_OPTS\ + freq = 1\ + passno = 3\ + mount /var {}\ +}\ +\ +// home directories\ +fs /dev/hp0f {\ + fstype = FSTYPE_UFS\ + opts = DEFAULT_OPTS\ + freq = 1\ + passno = 3\ + mount /a/HOST/home/HOST {\ + exportfs "\\\ + teach_hosts\\\ + "\ + }\ +} \ No newline at end of file diff --git a/usr.sbin/amd/fsinfo/conf/diskless_sun3_sos4 b/usr.sbin/amd/fsinfo/conf/diskless_sun3_sos4 new file mode 100644 index 0000000..0cacb20 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/diskless_sun3_sos4 @@ -0,0 +1,9 @@ +#define DISKLESS_SUN3_SOS4(HOST,DOMAIN,BOOTSERVER) \ +host HOST.DOMAIN \ +\ +mount /export/root/HOST as / from BOOTSERVER opts rw,grpid,intr \ +mount /export/swap/HOST as swap fstype swap from BOOTSERVER opts swap \ +mount /export/exec/sun3 as /usr from BOOTSERVER opts rw,grpid,intr \ +mount /var/clients/HOST as /var from BOOTSERVER opts rw,grpid,intr,nosuid \ +mount /var/clients/HOST.tmp as /tmp from BOOTSERVER opts rw,grpid,intr,nosuid \ +mount /var/spool/mail from BOOTSERVER opts rw,grpid,intr,nosuid diff --git a/usr.sbin/amd/fsinfo/conf/hosts/achilles.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/achilles.doc.ic.ac.uk new file mode 100644 index 0000000..6a46ce8 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/achilles.doc.ic.ac.uk @@ -0,0 +1,116 @@ +// mkfsinfo + +host achilles.doc.ic.ac.uk + +/* +arch sun4 +os sos4 +cluster theory +dumphost achilles.doc.ic.ac.uk +*/ + +// SWAP Partitions +fs /dev/xd0b { + fstype = swap +} + +fs /dev/xd1b { + fstype = swap +} + +// ROOT +fs /dev/xd0a { + fstype = 4.2 + opts = rw,noquota,grpid + passno = 1; + freq = 1; + mount / { } +} + +// ROOT Backup +fs /dev/xd1a { + fstype = ignore + opts = rw,noquota,grpid + passno = 1; + freq = 1; + mount /backup { } +} + +fs /dev/xd1d { + fstype = 4.2 + opts = rw,noquota,grpid + passno = 1; + freq = 1; + mount /export { + root { + truth { exportfs "-root=truth,access=truth" } + } + swap { + truth { exportfs "-root=truth,access=truth" } + } + exec { + sun4 { exportfs "-access=toytown_clients:hangers_on:gummo:harpo:opus,rw=dylan:truth:florence:toytown" } + } + } +} + +fs /dev/xd1f { + fstype = 4.2 + opts = rw,noquota,grpid + passno = 1; + freq = 1; + mount /var { + clients { + truth { exportfs "-root=truth,access=truth" } + truth.tmp { exportfs "-root=truth,access=truth" } + } + spool { + mail { exportfs "-root=truth,access=truth" } + rwho { exportfs "ro" volname /vol/rwho sel "byte==big" } + } + } +} + +fs /dev/xd0d { + fstype = 4.2 + opts = rw,noquota,grpid + passno = 1; + freq = 1; + mount /tmp { + X11NeWS { exportfs "-ro" } + } +} + +fs /dev/xd0g { + fstype = 4.2 + opts = rw,noquota,grpid + passno = 1 + freq = 1 + mount default { + exportfs "-access=toytown_clients:hangers_on" + volname /home/achilles + } +} + +fs /dev/xd1g { + fstype = 4.2 + opts = rw,noquota + passno = 1 + freq = 1 + mount /usr { + exportfs "-access=toytown_clients:hangers_on:gummo:harpo:opus,rw=dylan:truth:florence:toytown" + share { + volname "/usr/share" + //exportfs "blah" + } + src { + local { + //exportfs "-access=toytown:zebedee:dougal:dylan:florence:opus,rw=dylan:florence,root=dylan:florence" + bits { gnu { volname "/vol/src/gnu" } } + athena { volname "/vol/src/athena" } + } + } + } +} + +/*mount /export/exec/sun3 fstype nfs from gould.doc.ic.ac.uk as /usr opts "rw"*/ diff --git a/usr.sbin/amd/fsinfo/conf/hosts/bigears.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/bigears.doc.ic.ac.uk new file mode 100644 index 0000000..bda2fd8 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/bigears.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../diskless_sun3_sos4" + +DISKLESS_SUN3_SOS4(bigears,doc.ic.ac.uk,toytown.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/dylan.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/dylan.doc.ic.ac.uk new file mode 100644 index 0000000..5284147 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/dylan.doc.ic.ac.uk @@ -0,0 +1,68 @@ +// mkfsinfo + +host dylan.doc.ic.ac.uk + +// SWAP +fs /dev/dsk/0s0 { + fstype = swap +} + +// SWAP +fs /dev/dsk/1s0 { + fstype = swap +} + +// ROOT +fs /dev/dsk/0s0 { + fstype = hfs + opts = rw,noquota,grpid + passno = 0; + freq = 1; + mount / { } +} + +fs /dev/dsk/1s0 { + fstype = hfs + opts = defaults + passno = 1; + freq = 1; + mount /usr { + local { + exportfs "dougal eden dylan zebedee brian" + volname /nfs/hp300/local + } + } +} + +fs /dev/dsk/2s0 { + fstype = hfs + opts = defaults + passno = 1; + freq = 1; + mount default { + exportfs "toytown_clients hangers_on" + volname /home/dylan/dk2 + } +} + +fs /dev/dsk/3s0 { + fstype = hfs + opts = defaults + passno = 1; + freq = 1; + mount default { + exportfs "toytown_clients hangers_on" + volname /home/dylan/dk3 + } +} + +fs /dev/dsk/5s0 { + fstype = hfs + opts = defaults + passno = 1; + freq = 1; + mount default { + exportfs "toytown_clients hangers_on" + volname /home/dylan/dk5 + } +} diff --git a/usr.sbin/amd/fsinfo/conf/hosts/flamingo.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/flamingo.doc.ic.ac.uk new file mode 100644 index 0000000..31f1be0 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/flamingo.doc.ic.ac.uk @@ -0,0 +1,104 @@ +// mkfsinfo for flamingo +// $Id$ + +host flamingo.doc.ic.ac.uk + +/* +arch sun3 +os sos4 +cluster csg +dumphost flamingo.doc.ic.ac.uk +*/ + +#define FSTYPE_UFS 4.2 +#define DEFAULT_OPTS rw,noquota,nosuid,grpid + +// swap +fs /dev/xy0b { + fstype = swap +} + +// root +fs /dev/xy0a { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + passno = 1 + freq = 1 + dumpset = csg_sun3_vax + mount / {} +} + +// usr +fs /dev/xy0f { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 2 + dumpset = csg_sun3_vax + mount /usr { + volname /vol/export/exec/sun3 + exportfs "-ro,access=teach_hosts:ssun2.doc.ic.ac.uk:pelican:gould,\ + root=gould:pelican:ssun2.doc.ic.ac.uk" + } +} + +// tmp +fs /dev/xy0d { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS,nosuid + freq = 1 + passno = 3 + mount /tmp { + exportfs "-access=ssun1:tsunfs,root=tsunfs" + } +} + +// var +fs /dev/xy0e { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 4 + dumpset = csg_sun3_vax + mount /var { + tmp { + exportfs "-access=ssun1:sky.doc.ic.ac.uk" + } + crash { + exportfs "-access=ssun1" + } + misc { + exportfs "-access=teach_hosts" + } + spool { + rwho { + volname /vol/rwho + exportfs "-ro,access=teach_hosts" + sel "byte==big" + } + } + } +} + +// source - sos4 +fs /dev/xy0h { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 6 + mount /usr/src { + volname /vol/src/sos4 + exportfs "-access=svax:pelican:gould,root=pelican:svax" + } +} + +// home directories +fs /dev/xy0g { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 5 + mount /a/flamingo/home/flamingo { + exportfs "-access=teach_hosts:thp_hosts:ssun2:obsidian:truth,root=gould" + } +} diff --git a/usr.sbin/amd/fsinfo/conf/hosts/ganymede.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/ganymede.doc.ic.ac.uk new file mode 100644 index 0000000..e847c85 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/ganymede.doc.ic.ac.uk @@ -0,0 +1,33 @@ +host ganymede.doc.ic.ac.uk + +fs /dev/xy0a { + fstype = 4.2 + opts = rw + freq = 1 + passno = 1 + mount / { + } +} + +fs /dev/xy0g { + fstype = 4.2 + opts = rw + freq = 1 + passno = 2 + mount /usr { + exportfs "-access=toytown:toytown_clients" + } +} + +fs /dev/xy0h { + fstype = 4.2 + opts = rw + freq = 1 + passno = 3 + mount /home/ganymede { + exportfs "-access=toytown_clients:samson:hangers_on" + } +} + +mount /home/toytown opts rw,bg,nosuid +mount /usr/local from toytown.doc.ic.ac.uk opts ro,bg diff --git a/usr.sbin/amd/fsinfo/conf/hosts/gould.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/gould.doc.ic.ac.uk new file mode 100644 index 0000000..8804c8e --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/gould.doc.ic.ac.uk @@ -0,0 +1,477 @@ +// mkfsinfo for gould +// $Id$ + +host gould.doc.ic.ac.uk + +/* +arch powernode +os utx21 +cluster csg +dumphost flamingo.doc.ic.ac.uk +*/ + +#define FSTYPE_UFS 4.3 +#define DEFAULT_OPTS rw,noquota + +// swap +fs /dev/dk0b { + fstype = swap +} + +fs /dev/dk1b { + fstype = swap +} + +fs /dev/dk4b { + fstype = swap +} + +// root +fs /dev/dk0a { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + passno = 1 + freq = 1 + dumpset = csg_nightly + mount / {} +} + +// root backup +fs /dev/dk4a { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 4 + mount /backup {} +} + +// usr +fs /dev/dk4d { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 2 + dumpset = csg_nightly + mount /usr {} +} + +// tmp +fs /dev/dk1a { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS,nosuid + freq = 0 + passno = 2 + mount /tmp {} +} + +// var +fs /dev/dk4g { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 3 + dumpset = csg_nightly + mount /var {} +} + +// shared stuff - usually for Suns +fs /dev/dk5f { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 6 + mount /usr/share { + exportfs "-rdonly=1 \ + ivax.doc.ic.ac.uk \ + rvax.doc.ic.ac.uk \ + ssun1.doc.ic.ac.uk \ + ssun2.doc.ic.ac.uk \ + svax.doc.ic.ac.uk \ + tsun1.doc.ic.ac.uk \ + tsun10.doc.ic.ac.uk \ + tsun11.doc.ic.ac.uk \ + tsun12.doc.ic.ac.uk \ + tsun13.doc.ic.ac.uk \ + tsun14.doc.ic.ac.uk \ + tsun15.doc.ic.ac.uk \ + tsun16.doc.ic.ac.uk \ + tsun17.doc.ic.ac.uk \ + tsun18.doc.ic.ac.uk \ + tsun19.doc.ic.ac.uk \ + tsun2.doc.ic.ac.uk \ + tsun3.doc.ic.ac.uk \ + tsun4.doc.ic.ac.uk \ + tsun5.doc.ic.ac.uk \ + tsun6.doc.ic.ac.uk \ + tsun7.doc.ic.ac.uk \ + tsun8.doc.ic.ac.uk \ + tsun9.doc.ic.ac.uk \ + tsunfs.doc.ic.ac.uk \ + flamingo.doc.ic.ac.uk \ + pelican.doc.ic.ac.uk \ + oriona \ + sky.doc.ic.ac.uk \ + whoops.doc.ic.ac.uk \ + whoops \ + " + } +} + +// spool stuff, including the news +fs /dev/dk4f { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 5 + mount /var/spool { + exportfs "\ + oriona \ + rpcsfg \ + " + } +} + +fs /dev/dk3h { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 2 + mount /var/spool/News {} +} + +// this is the public ftp area +fs /dev/dk3f { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 4 + mount /usr/reserve { + PUBLIC { + volname /vol/public + exportfs "\ + oriona \ + ssun1.doc.ic.ac.uk \ + ssun2.doc.ic.ac.uk \ + obsidian \ + gummo \ + tsunfs.doc.ic.ac.uk \ + flamingo.doc.ic.ac.uk \ + " + } + } +} + +// sources - local and public +fs /dev/dk7c { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 2 + dumpset = csg_nightly + mount /usr/src { + volname /vol/src/gould + exportfs "\ + flamingo.doc.ic.ac.uk \ + pelican.doc.ic.ac.uk \ + oriona \ + ssun1.doc.ic.ac.uk \ + svax.doc.ic.ac.uk \ + rvax.doc.ic.ac.uk \ + obsidian \ + tsunfs \ + " + } +} + +// sources - utx +fs /dev/dk4e { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 6 + dumpset = csg_nightly + mount /usr/src/utx { + volname /vol/src/utx + exportfs "-rdonly=1 \ + flamingo.doc.ic.ac.uk \ + " + } +} + +// home directories +fs /dev/dk1h { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 3 + dumpset = csg_nightly + mount /home/gould/teach { + exportfs "\ + thp1 \ + thp2 \ + thp3 \ + thp4 \ + thp5 \ + thp6 \ + thp7 \ + thp8 \ + thp9 \ + thp10 \ + thpfs \ + ivax.doc.ic.ac.uk \ + rvax.doc.ic.ac.uk \ + ssun1.doc.ic.ac.uk \ + ssun2.doc.ic.ac.uk \ + svax.doc.ic.ac.uk \ + tsun1.doc.ic.ac.uk \ + tsun10.doc.ic.ac.uk \ + tsun11.doc.ic.ac.uk \ + tsun12.doc.ic.ac.uk \ + tsun13.doc.ic.ac.uk \ + tsun14.doc.ic.ac.uk \ + tsun15.doc.ic.ac.uk \ + tsun16.doc.ic.ac.uk \ + tsun17.doc.ic.ac.uk \ + tsun18.doc.ic.ac.uk \ + tsun19.doc.ic.ac.uk \ + tsun2.doc.ic.ac.uk \ + tsun3.doc.ic.ac.uk \ + tsun4.doc.ic.ac.uk \ + tsun5.doc.ic.ac.uk \ + tsun6.doc.ic.ac.uk \ + tsun7.doc.ic.ac.uk \ + tsun8.doc.ic.ac.uk \ + tsun9.doc.ic.ac.uk \ + tsunfs.doc.ic.ac.uk \ + flamingo.doc.ic.ac.uk \ + pelican.doc.ic.ac.uk \ + oriona \ + sky.doc.ic.ac.uk \ + whoops.doc.ic.ac.uk \ + whoops \ + vlsi.doc.ic.ac.uk \ + vlsi \ + " + } +} + +fs /dev/dk0h { + fstype = FSTYPE_UFS + opts = rw,quota + freq = 1 + passno = 2 + dumpset = csg_nightly + mount /home/gould/staff { + exportfs "\ + achilles \ + thp1 \ + thp2 \ + thp3 \ + thp4 \ + thp5 \ + thp6 \ + thp7 \ + thp8 \ + thp9 \ + thp10 \ + thpfs \ + ivax.doc.ic.ac.uk \ + rvax.doc.ic.ac.uk \ + ssun1.doc.ic.ac.uk \ + ssun2.doc.ic.ac.uk \ + svax.doc.ic.ac.uk \ + tsun1.doc.ic.ac.uk \ + tsun10.doc.ic.ac.uk \ + tsun11.doc.ic.ac.uk \ + tsun12.doc.ic.ac.uk \ + tsun13.doc.ic.ac.uk \ + tsun14.doc.ic.ac.uk \ + tsun15.doc.ic.ac.uk \ + tsun16.doc.ic.ac.uk \ + tsun17.doc.ic.ac.uk \ + tsun18.doc.ic.ac.uk \ + tsun19.doc.ic.ac.uk \ + tsun2.doc.ic.ac.uk \ + tsun3.doc.ic.ac.uk \ + tsun4.doc.ic.ac.uk \ + tsun5.doc.ic.ac.uk \ + tsun6.doc.ic.ac.uk \ + tsun7.doc.ic.ac.uk \ + tsun8.doc.ic.ac.uk \ + tsun9.doc.ic.ac.uk \ + tsunfs.doc.ic.ac.uk \ + flamingo.doc.ic.ac.uk \ + pelican.doc.ic.ac.uk \ + oriona \ + sky.doc.ic.ac.uk \ + whoops.doc.ic.ac.uk \ + whoops \ + vlsi.doc.ic.ac.uk \ + vlsi \ + vlsi02 \ + " + } +} + +// booting diskless suns +fs /dev/dk5e { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 3 + dumpset = csg_nightly + mount /export { +#ifndef ok + volname /vol/export +#endif + exportfs "\ + -rootid=0 \ + whoops \ + whoops.doc.ic.ac.uk \ + " + misc { + volname /vol/export/misc + } + } +} + +fs /dev/dk5a { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 4 + dumpset = csg_nightly + mount /export/roots { + volname /vol/export/roots + exportfs "\ + -rootid=0 \ + whoops \ + whoops.doc.ic.ac.uk \ + " + } +} + +fs /dev/dk5d { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 5 + dumpset = csg_nightly + mount /export/exec/sun3 { + volname /vol/export/exec/sun3 + exportfs "\ + ssun1.doc.ic.ac.uk \ + ssun2.doc.ic.ac.uk \ + tsun1.doc.ic.ac.uk \ + tsun10.doc.ic.ac.uk \ + tsun11.doc.ic.ac.uk \ + tsun12.doc.ic.ac.uk \ + tsun13.doc.ic.ac.uk \ + tsun14.doc.ic.ac.uk \ + tsun15.doc.ic.ac.uk \ + tsun16.doc.ic.ac.uk \ + tsun17.doc.ic.ac.uk \ + tsun18.doc.ic.ac.uk \ + tsun19.doc.ic.ac.uk \ + tsun2.doc.ic.ac.uk \ + tsun3.doc.ic.ac.uk \ + tsun4.doc.ic.ac.uk \ + tsun5.doc.ic.ac.uk \ + tsun6.doc.ic.ac.uk \ + tsun7.doc.ic.ac.uk \ + tsun8.doc.ic.ac.uk \ + tsun9.doc.ic.ac.uk \ + tsunfs.doc.ic.ac.uk \ + flamingo.doc.ic.ac.uk \ + pelican.doc.ic.ac.uk \ + whoops.doc.ic.ac.uk \ + whoops \ + " + } +} + +// various r+d things - used for athena, etc +fs /dev/dk5g { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 2 + mount /usr/r+d { + volname /vol/r+d + exportfs "\ + ivax.doc.ic.ac.uk \ + rvax.doc.ic.ac.uk \ + ssun1.doc.ic.ac.uk \ + ssun2.doc.ic.ac.uk \ + svax.doc.ic.ac.uk \ + tsun1.doc.ic.ac.uk \ + tsun10.doc.ic.ac.uk \ + tsun11.doc.ic.ac.uk \ + tsun12.doc.ic.ac.uk \ + tsun13.doc.ic.ac.uk \ + tsun14.doc.ic.ac.uk \ + tsun15.doc.ic.ac.uk \ + tsun16.doc.ic.ac.uk \ + tsun17.doc.ic.ac.uk \ + tsun18.doc.ic.ac.uk \ + tsun19.doc.ic.ac.uk \ + tsun2.doc.ic.ac.uk \ + tsun3.doc.ic.ac.uk \ + tsun4.doc.ic.ac.uk \ + tsun5.doc.ic.ac.uk \ + tsun6.doc.ic.ac.uk \ + tsun7.doc.ic.ac.uk \ + tsun8.doc.ic.ac.uk \ + tsun9.doc.ic.ac.uk \ + tsunfs.doc.ic.ac.uk \ + flamingo.doc.ic.ac.uk \ + pelican.doc.ic.ac.uk \ + oriona \ + sky.doc.ic.ac.uk \ + whoops.doc.ic.ac.uk \ + whoops \ + " + } +} + +fs /dev/dk3d { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 3 + mount /usr/r+d/r1 { + exportfs "\ + ssun1.doc.ic.ac.uk \ + ssun2.doc.ic.ac.uk \ + " + } +} + +fs /dev/dk4h { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 7 + mount /usr/r+d/r2 { + exportfs "\ + achilles \ + gummo \ + harpo \ + oriona \ + ssun1.doc.ic.ac.uk \ + ssun2.doc.ic.ac.uk \ + thpfs \ + toytown \ + obsidian \ + " + } +} + +// this bit of disc needs a name ! +fs /dev/dk5h { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 7 + mount /mnt2 {} +} diff --git a/usr.sbin/amd/fsinfo/conf/hosts/gummo.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/gummo.doc.ic.ac.uk new file mode 100644 index 0000000..aae6a5d --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/gummo.doc.ic.ac.uk @@ -0,0 +1,12 @@ +// mkfsinfo + +host gummo.doc.ic.ac.uk + +// ROOT +fs /dev/xxx1 { + fstype = export + mount default { + exportfs "" + volname /home/gummo + } +} diff --git a/usr.sbin/amd/fsinfo/conf/hosts/ivax.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/ivax.doc.ic.ac.uk new file mode 100644 index 0000000..c8fcb5d --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/ivax.doc.ic.ac.uk @@ -0,0 +1,84 @@ +// $Id$ +// ivax + +#define FSTYPE_UFS 4.2 +#define DEFAULT_OPTS rw + +host { + config "NFS_SERVER=true" + config "NFS_CLIENT=true" + config "YP_SERVER=false" + config "YP_CLIENT=false" + + arch = vax + os = xinu43 + cluster = teach.doc.ic.ac.uk + netif il0 { hwaddr = "08:08:08:08:08:08" netmask = 0xfffffe00 inaddr = 129.31.80.36 } + +} ivax.doc.ic.ac.uk + +// root +fs /dev/hp0a { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 1 + mount / {} +} + +// swap +fs /dev/hp0b { + fstype = swap +} + +// usr +fs /dev/hp0e { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 2 + mount /usr { + exportfs "\ + sky.doc.ic.ac.uk\ + svax.doc.ic.ac.uk\ + rvax.doc.ic.ac.uk\ + ivax.doc.ic.ac.uk\ + " + } +} + +// var +fs /dev/hp0d { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 3 + mount /var {} +} + +// home directories +fs /dev/hp0f { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 3 + mount default { + volname /home/ivax + exportfs "\ + sky.doc.ic.ac.uk\ + " + } +} + +// sources which are used by the gould for the infoserver +fs /dev/hp2c { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 3 + mount /public { + exportfs "\ + gould\ + " + } +} diff --git a/usr.sbin/amd/fsinfo/conf/hosts/obsidian.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/obsidian.doc.ic.ac.uk new file mode 100644 index 0000000..dd9f0f7 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/obsidian.doc.ic.ac.uk @@ -0,0 +1,28 @@ +// $Id$ +// conf for obsidian + +#define FSTYPE_UFS hfs +#define DEFAULT_OPTS rw + +host obsidian.doc.ic.ac.uk + +fs /dev/dsk/0s0 { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 1 + mount / {} +} + +fs /dev/dsk/1s0 { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 1 + mount default { + volname /home/obsidian + exportfs "\ + gould\ + " + } +} diff --git a/usr.sbin/amd/fsinfo/conf/hosts/pelican.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/pelican.doc.ic.ac.uk new file mode 100644 index 0000000..1ffd8d7 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/pelican.doc.ic.ac.uk @@ -0,0 +1,208 @@ +// mkfsinfo for pelican +// $Id$ + +host pelican.doc.ic.ac.uk + +/* +arch sun3 +os sos4 +cluster csg +dumphost flamingo.doc.ic.ac.uk +*/ + +#define FSTYPE_UFS 4.2 +#define DEFAULT_OPTS rw,noquota,nosuid,grpid + +// swap +fs /dev/xd0b { + fstype = swap +} + +// root +fs /dev/xd0a { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + passno = 1 + freq = 1 + dumpset = csg_sun3_vax + mount / { + exportfs "-ro,access=tsunfs,root=tsunfs" + } +} + +// usr +fs /dev/xd0f { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 2 + dumpset = csg_sun3_vax + mount /usr { + volname /vol/export/exec/sun3 + exportfs "-ro,access=teach_hosts,root=gould:flamingo:tsunfs" + } +} + +// tmp +fs /dev/xd0d { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS,nosuid + freq = 1 + passno = 3 + mount /tmp { + exportfs "\ + -access=\ + flamingo:\ + tsun16.doc.ic.ac.uk:\ + tsun17.doc.ic.ac.uk:\ + tsun18.doc.ic.ac.uk:\ + tsun19.doc.ic.ac.uk" + } +} + +// var +fs /dev/xd0e { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 4 + dumpset = csg_sun3_vax + mount /var { + misc { + // this is due to differences between tsunfs and pelican + volname /vol/export/misc + exportfs "\ + -access=teach_hosts,\ + root=\ + tcsun1.doc.ic.ac.uk:\ + tcsun2.doc.ic.ac.uk:\ + tcsun3.doc.ic.ac.uk:\ + tcsun4.doc.ic.ac.uk:\ + tcsun5.doc.ic.ac.uk:\ + tsun16.doc.ic.ac.uk:\ + tsun17.doc.ic.ac.uk:\ + tsun18.doc.ic.ac.uk:\ + tsun19.doc.ic.ac.uk" + } + mmdf { + exportfs "\ + -access=teach_hosts,\ + root=\ + tcsun1.doc.ic.ac.uk:\ + tcsun2.doc.ic.ac.uk:\ + tcsun3.doc.ic.ac.uk:\ + tcsun4.doc.ic.ac.uk:\ + tcsun5.doc.ic.ac.uk:\ + tsun16.doc.ic.ac.uk:\ + tsun17.doc.ic.ac.uk:\ + tsun18.doc.ic.ac.uk:\ + tsun19.doc.ic.ac.uk" + } + spool { + rwho { + volname /vol/rwho + exportfs "-ro,access=teach_hosts" + sel "byte==big" + } + } + } +} + +// export for diskless clients +fs /dev/xd0h { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 6 + mount /export { + roots { + tcsun1 { + volname /vol/export/roots/tcsun1 + exportfs "-root=tcsun1.doc.ic.ac.uk,access=tcsun1.doc.ic.ac.uk" + } + tcsun2 { + volname /vol/export/roots/tcsun2 + exportfs "-root=tcsun2.doc.ic.ac.uk,access=tcsun2.doc.ic.ac.uk" + } + tcsun3 { + volname /vol/export/roots/tcsun3 + exportfs "-root=tcsun3.doc.ic.ac.uk,access=tcsun3.doc.ic.ac.uk" + } + tcsun4 { + volname /vol/export/roots/tcsun4 + exportfs "-root=tcsun4.doc.ic.ac.uk,access=tcsun4.doc.ic.ac.uk" + } + tcsun5 { + volname /vol/export/roots/tcsun5 + exportfs "-root=tcsun5.doc.ic.ac.uk,access=tcsun5.doc.ic.ac.uk" + } + + tsun16 { + volname /vol/export/roots/tsun16 + exportfs "-root=tsun16.doc.ic.ac.uk,access=tsun16.doc.ic.ac.uk" + } + tsun17 { + volname /vol/export/roots/tsun17 + exportfs "-root=tsun17.doc.ic.ac.uk,access=tsun17.doc.ic.ac.uk" + } + tsun18 { + volname /vol/export/roots/tsun18 + exportfs "-root=tsun18.doc.ic.ac.uk,access=tsun18.doc.ic.ac.uk" + } + tsun19 { + volname /vol/export/roots/tsun19 + exportfs "-root=tsun19.doc.ic.ac.uk,access=tsun19.doc.ic.ac.uk" + } + } + swaps { + tcsun1 { + volname /vol/export/swaps/tcsun1 + exportfs "-root=tcsun1.doc.ic.ac.uk,access=tcsun1.doc.ic.ac.uk" + } + tcsun2 { + volname /vol/export/swaps/tcsun2 + exportfs "-root=tcsun2.doc.ic.ac.uk,access=tcsun2.doc.ic.ac.uk" + } + tcsun3 { + volname /vol/export/swaps/tcsun3 + exportfs "-root=tcsun3.doc.ic.ac.uk,access=tcsun3.doc.ic.ac.uk" + } + tcsun4 { + volname /vol/export/swaps/tcsun4 + exportfs "-root=tcsun4.doc.ic.ac.uk,access=tcsun4.doc.ic.ac.uk" + } + tcsun5 { + volname /vol/export/swaps/tcsun5 + exportfs "-root=tcsun5.doc.ic.ac.uk,access=tcsun5.doc.ic.ac.uk" + } + tsun16 { + volname /vol/export/swaps/tsun16 + exportfs "-root=tsun16.doc.ic.ac.uk,access=tsun16.doc.ic.ac.uk" + } + tsun17 { + volname /vol/export/swaps/tsun17 + exportfs "-root=tsun17.doc.ic.ac.uk,access=tsun17.doc.ic.ac.uk" + } + tsun18 { + volname /vol/export/swaps/tsun18 + exportfs "-root=tsun18.doc.ic.ac.uk,access=tsun18.doc.ic.ac.uk" + } + tsun19 { + volname /vol/export/swaps/tsun19 + exportfs "-root=tsun19.doc.ic.ac.uk,access=tsun19.doc.ic.ac.uk" + } + } + } +} + +// home directories +fs /dev/xd0g { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 5 + mount default { + volname /home/pelican + exportfs "-access=teach_hosts:thp_hosts:ssun2:obsidian:truth,root=gould" + } +} diff --git a/usr.sbin/amd/fsinfo/conf/hosts/rvax.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/rvax.doc.ic.ac.uk new file mode 100644 index 0000000..303d552 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/rvax.doc.ic.ac.uk @@ -0,0 +1,66 @@ +// $Id$ +// rvax + +#define FSTYPE_UFS 4.2 +#define DEFAULT_OPTS rw + +host rvax.doc.ic.ac.uk + +/* +arch vax +os xinu43 +cluster csg +dumphost flamingo.doc.ic.ac.uk +*/ + +// root +fs /dev/hp0a { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 1 + mount / {} +} + +// swap +fs /dev/hp0b { + fstype = swap +} + +// usr +fs /dev/hp0e { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 2 + mount /usr { + exportfs "\ + sky.doc.ic.ac.uk\ + svax.doc.ic.ac.uk\ + rvax.doc.ic.ac.uk\ + ivax.doc.ic.ac.uk\ + " + } +} + +// var +fs /dev/hp0d { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 3 + mount /var {} +} + +// home directories +fs /dev/hp0f { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 3 + mount /a/rvax/home/rvax { + exportfs "\ + teach_hosts\ + " + } +} \ No newline at end of file diff --git a/usr.sbin/amd/fsinfo/conf/hosts/sky.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/sky.doc.ic.ac.uk new file mode 100644 index 0000000..7877659 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/sky.doc.ic.ac.uk @@ -0,0 +1,79 @@ +// $Id$ +// sky + +#define FSTYPE_UFS 4.2 +#define DEFAULT_OPTS rw + +host sky.doc.ic.ac.uk + +/* +arch vax +os xinu43 +cluster csg +dumphost flamingo.doc.ic.ac.uk +*/ + +// root +fs /dev/hp0a { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 1 + mount / {} +} + +// swap +fs /dev/hp0b { + fstype = swap +} + +// usr +fs /dev/hp0e { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 2 + mount /usr { + exportfs "\ + sky.doc.ic.ac.uk\ + svax.doc.ic.ac.uk\ + rvax.doc.ic.ac.uk\ + ivax.doc.ic.ac.uk\ + " + } +} + +// var +fs /dev/hp0d { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 3 + mount /var {} +} + +// home directories +fs /dev/hp0f { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 3 + mount /a/sky/home/sky {} +} + +// 4.3 sources +fs /dev/hp1g { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 2 + mount /usr/src { + volname /vol/src/xinu43 + exportfs "\ + svax.doc.ic.ac.uk\ + rvax.doc.ic.ac.uk\ + sky.doc.ic.ac.uk\ + ivax.doc.ic.ac.uk\ + " + } +} \ No newline at end of file diff --git a/usr.sbin/amd/fsinfo/conf/hosts/svax.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/svax.doc.ic.ac.uk new file mode 100644 index 0000000..aa99fbf --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/svax.doc.ic.ac.uk @@ -0,0 +1,66 @@ +// $Id$ +// svax + +#define FSTYPE_UFS 4.2 +#define DEFAULT_OPTS rw + +host svax.doc.ic.ac.uk + +/* +arch vax +os xinu43 +cluster csg +dumphost flamingo.doc.ic.ac.uk +*/ + +// root +fs /dev/hp0a { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 1 + mount / {} +} + +// swap +fs /dev/hp0b { + fstype = swap +} + +// usr +fs /dev/hp0e { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 2 + mount /usr { + exportfs "\ + sky.doc.ic.ac.uk\ + svax.doc.ic.ac.uk\ + rvax.doc.ic.ac.uk\ + ivax.doc.ic.ac.uk\ + " + } +} + +// var +fs /dev/hp0d { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 3 + mount /var {} +} + +// home directories +fs /dev/hp0f { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 3 + mount /a/svax/home/svax { + exportfs "\ + teach_hosts\ + " + } +} \ No newline at end of file diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tcsun1.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tcsun1.doc.ic.ac.uk new file mode 100644 index 0000000..1b10d84 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tcsun1.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tcsun1,doc.ic.ac.uk,pelican.doc.ic.ac.uk,pelican.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tcsun2.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tcsun2.doc.ic.ac.uk new file mode 100644 index 0000000..933d2f4 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tcsun2.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tcsun2,doc.ic.ac.uk,pelican.doc.ic.ac.uk,pelican.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tcsun3.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tcsun3.doc.ic.ac.uk new file mode 100644 index 0000000..ccef4d4 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tcsun3.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tcsun3,doc.ic.ac.uk,pelican.doc.ic.ac.uk,pelican.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tcsun4.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tcsun4.doc.ic.ac.uk new file mode 100644 index 0000000..9de9a9a --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tcsun4.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tcsun4,doc.ic.ac.uk,pelican.doc.ic.ac.uk,pelican.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tcsun5.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tcsun5.doc.ic.ac.uk new file mode 100644 index 0000000..7f268a0 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tcsun5.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tcsun5,doc.ic.ac.uk,pelican.doc.ic.ac.uk,pelican.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/toytown.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/toytown.doc.ic.ac.uk new file mode 100644 index 0000000..7b27f16 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/toytown.doc.ic.ac.uk @@ -0,0 +1,116 @@ +host toytown.doc.ic.ac.uk + +fs /dev/xy0a { + fstype = 4.2 + opts = rw,noquota,grpid + freq = 25 + passno = 1 + mount / { + } +} + +fs /dev/xy0g { + fstype = 4.2 + opts = rw,noquota,grpid + freq = 25 + passno = 2 + mount /usr { + exportfs "-access=toytown_clients:hangers_on:pythagoras,ro" + sun3 { } + local { } + } +} + +fs /dev/xy1g { + fstype = 4.2 + opts = rw,grpid,nosuid + freq = 6 + passno = 2 + mount /home/toytown { + exportfs "-access=toytown_clients:hangers_on,root=achilles" + } +} + +fs /dev/xy0f { + fstype = 4.2 + opts = rw,noquota,grpid,nosuid + freq = 25 + passno = 4 + mount /var { + spool { + exportfs "-access=toytown_clients:hangers_on" + mail { } + rwho { volname /vol/rwho sel "byte==big" } +/* + mail { exportfs "-access=toytown_clients:hangers_on" } + rwho { exportfs "ro" volname /vol/rwho sel "byte==big" } +*/ + } + clients { + archimedes { exportfs "-access=archimedes,root=archimedes" } + archimedes.tmp { exportfs "-access=archimedes,root=archimedes" } + aver { exportfs "-access=aver,root=aver" } + aver.tmp { exportfs "-access=aver,root=aver" } + bigears { exportfs "-access=bigears,root=bigears" } + bigears.tmp { exportfs "-access=bigears,root=bigears" } + diadem { exportfs "-access=diadem,root=diadem" } + diadem.tmp { exportfs "-access=diadem,root=diadem" } + montague { exportfs "-access=montague,root=montague" } + montague.tmp { exportfs "-access=montague,root=montague" } + noddy { exportfs "-access=noddy,root=noddy" } + noddy.tmp { exportfs "-access=noddy,root=noddy" } + pcplod { exportfs "-access=pcplod,root=pcplod" } + pcplod.tmp { exportfs "-access=pcplod,root=pcplod" } + samson { exportfs "-access=samson,root=samson" } + samson.tmp { exportfs "-access=samson,root=samson" } + turing { exportfs "-access=turing,root=turing" } + turing.tmp { exportfs "-access=turing,root=turing" } + } + } +} + +fs /dev/xy0d { + fstype = 4.2 + opts = rw,noquota,grpid,nosuid + freq = 25 + passno = 3 + mount /export { + exec { + sun3 { exportfs "-access=toytown_clients:hangers_on:pythagoras" } + } + root { + archimedes { exportfs "-access=archimedes,root=archimedes" } + aver { exportfs "-access=aver,root=aver" } + bigears { exportfs "-access=bigears,root=bigears" } + diadem { exportfs "-access=diadem,root=diadem" } + montague { exportfs "-access=montague,root=montague" } + noddy { exportfs "-access=noddy,root=noddy" } + pcplod { exportfs "-access=pcplod,root=pcplod" } + samson { exportfs "-access=samson,root=samson" } + turing { exportfs "-access=turing,root=turing" } + } + swap { + archimedes { exportfs "-access=archimedes,root=archimedes" } + aver { exportfs "-access=aver,root=aver" } + bigears { exportfs "-access=bigears,root=bigears" } + diadem { exportfs "-access=diadem,root=diadem" } + montague { exportfs "-access=montague,root=montague" } + noddy { exportfs "-access=noddy,root=noddy" } + pcplod { exportfs "-access=pcplod,root=pcplod" } + samson { exportfs "-access=samson,root=samson" } + turing { exportfs "-access=turing,root=turing" } + } + } +} + +fs /dev/xy0b { + fstype = swap +} + +fs /dev/xy1b { + fstype = swap +} + +mount /home/ganymede opts rw,grpid,nosuid,bg,intr +mount /home/achilles opts rw,grpid,nosuid,bg,intr +mount /usr/src from achilles.doc.ic.ac.uk opts rw,grpid,nosuid,bg,intr diff --git a/usr.sbin/amd/fsinfo/conf/hosts/truth.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/truth.doc.ic.ac.uk new file mode 100644 index 0000000..0139279 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/truth.doc.ic.ac.uk @@ -0,0 +1,9 @@ +host truth.doc.ic.ac.uk + +mount /export/exec/sun4 from achilles.doc.ic.ac.uk as /usr opts "rw,grpid,intr" +mount /export/root/truth from achilles.doc.ic.ac.uk as / opts "rw,grpid,intr" +mount /export/swap/truth from achilles.doc.ic.ac.uk fstype swap as swap opts swap +mount /var/clients/truth.tmp from achilles.doc.ic.ac.uk as /tmp opts "rw,nosuid,grpid,intr" +mount /var/clients/truth from achilles.doc.ic.ac.uk as /var opts "rw,nosuid,grpid,intr" +mount /var/spool/mail from achilles.doc.ic.ac.uk as /var/spool/mail opts "rw,nosuid,grpid,intr" +mount /usr/src from achilles.doc.ic.ac.uk as /usr/src opts "rw,nosuid,grpid,intr,bg" diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun1.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun1.doc.ic.ac.uk new file mode 100644 index 0000000..ff5016c --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun1.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun1,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun10.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun10.doc.ic.ac.uk new file mode 100644 index 0000000..2496cdb --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun10.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun10,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun11.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun11.doc.ic.ac.uk new file mode 100644 index 0000000..d6e7b9d --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun11.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun11,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun12.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun12.doc.ic.ac.uk new file mode 100644 index 0000000..a8439bb --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun12.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun12,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun13.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun13.doc.ic.ac.uk new file mode 100644 index 0000000..44e4956 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun13.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun13,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun14.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun14.doc.ic.ac.uk new file mode 100644 index 0000000..66a5051 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun14.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun14,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun15.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun15.doc.ic.ac.uk new file mode 100644 index 0000000..3246df3 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun15.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun15,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun16.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun16.doc.ic.ac.uk new file mode 100644 index 0000000..4ab7bd0 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun16.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun16,doc.ic.ac.uk,pelican.doc.ic.ac.uk,pelican.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun17.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun17.doc.ic.ac.uk new file mode 100644 index 0000000..11ef757 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun17.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun17,doc.ic.ac.uk,pelican.doc.ic.ac.uk,pelican.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun18.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun18.doc.ic.ac.uk new file mode 100644 index 0000000..fbdf879 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun18.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun18,doc.ic.ac.uk,pelican.doc.ic.ac.uk,pelican.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun19.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun19.doc.ic.ac.uk new file mode 100644 index 0000000..da9aba8 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun19.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun19,doc.ic.ac.uk,pelican.doc.ic.ac.uk,pelican.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun2.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun2.doc.ic.ac.uk new file mode 100644 index 0000000..b6fca77 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun2.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun2,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun3.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun3.doc.ic.ac.uk new file mode 100644 index 0000000..e40bd16 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun3.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun3,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun4.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun4.doc.ic.ac.uk new file mode 100644 index 0000000..cd97358 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun4.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun4,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun5.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun5.doc.ic.ac.uk new file mode 100644 index 0000000..3a8c7e2 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun5.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun5,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun6.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun6.doc.ic.ac.uk new file mode 100644 index 0000000..4c6ea76 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun6.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun6,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun7.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun7.doc.ic.ac.uk new file mode 100644 index 0000000..9df32a9 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun7.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun7,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun8.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun8.doc.ic.ac.uk new file mode 100644 index 0000000..e2b5e1f --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun8.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun8,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsun9.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsun9.doc.ic.ac.uk new file mode 100644 index 0000000..e82e815 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsun9.doc.ic.ac.uk @@ -0,0 +1,3 @@ +#include "../csg_sun3" + +CSG_SUN3(tsun9,doc.ic.ac.uk,tsunfs.doc.ic.ac.uk,gould.doc.ic.ac.uk) diff --git a/usr.sbin/amd/fsinfo/conf/hosts/tsunfs.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/tsunfs.doc.ic.ac.uk new file mode 100644 index 0000000..b09db9d --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/tsunfs.doc.ic.ac.uk @@ -0,0 +1,211 @@ +// mkfsinfo for tsunfs +// $Id$ + +host tsunfs.doc.ic.ac.uk + +/* +arch sun3 +os sos4 +cluster csg +dumphost flamingo.doc.ic.ac.uk +*/ + +#define FSTYPE_UFS 4.2 +#define DEFAULT_OPTS rw,noquota,nosuid,grpid + +// swap +fs /dev/xy0b { + fstype = swap +} + +// root +fs /dev/xy0a { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + passno = 1 + freq = 1 + dumpset = csg_sun3_vax + mount / {} +} + +// usr +fs /dev/xy0f { + fstype = FSTYPE_UFS + opts = rw,grpid + freq = 1 + passno = 2 + dumpset = csg_sun3_vax + mount /usr {} +} + +// var +fs /dev/xy0e { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 4 + dumpset = csg_sun3_vax + mount /var { + mmdf { + exportfs "-access=teach_hosts,root=\ + tsun1.doc.ic.ac.uk:\ + tsun2.doc.ic.ac.uk:\ + tsun3.doc.ic.ac.uk:\ + tsun4.doc.ic.ac.uk:\ + tsun5.doc.ic.ac.uk:\ + tsun6.doc.ic.ac.uk:\ + tsun7.doc.ic.ac.uk:\ + tsun8.doc.ic.ac.uk:\ + tsun9.doc.ic.ac.uk:\ + tsun10.doc.ic.ac.uk:\ + tsun11.doc.ic.ac.uk:\ + tsun12.doc.ic.ac.uk:\ + tsun13.doc.ic.ac.uk:\ + tsun14.doc.ic.ac.uk:\ + tsun15.doc.ic.ac.uk:\ + ssun1.doc.ic.ac.uk:\ + whoops.doc.ic.ac.uk:\ + " + } + } +} + +// root filesystems for diskless clients +fs /dev/xy0d { + fstype = FSTYPE_UFS + opts = rw,grpid + freq = 1 + passno = 3 + mount /export/roots { + tsun1 { + volname /vol/export/roots/tsun1 + exportfs "-root=tsun1.doc.ic.ac.uk,-access=tsun1.doc.ic.ac.uk" + } + tsun2 { + volname /vol/export/roots/tsun2 + exportfs "-root=tsun2.doc.ic.ac.uk,-access=tsun2.doc.ic.ac.uk" + } + tsun3 { + volname /vol/export/roots/tsun3 + exportfs "-root=tsun3.doc.ic.ac.uk,-access=tsun3.doc.ic.ac.uk" + } + tsun4 { + volname /vol/export/roots/tsun4 + exportfs "-root=tsun4.doc.ic.ac.uk,-access=tsun4.doc.ic.ac.uk" + } + tsun5 { + volname /vol/export/roots/tsun5 + exportfs "-root=tsun5.doc.ic.ac.uk,-access=tsun5.doc.ic.ac.uk" + } + tsun6 { + volname /vol/export/roots/tsun6 + exportfs "-root=tsun6.doc.ic.ac.uk,-access=tsun6.doc.ic.ac.uk" + } + tsun7 { + volname /vol/export/roots/tsun7 + exportfs "-root=tsun7.doc.ic.ac.uk,-access=tsun7.doc.ic.ac.uk" + } + tsun8 { + volname /vol/export/roots/tsun8 + exportfs "-root=tsun8.doc.ic.ac.uk,-access=tsun8.doc.ic.ac.uk" + } + tsun9 { + volname /vol/export/roots/tsun9 + exportfs "-root=tsun9.doc.ic.ac.uk,-access=tsun9.doc.ic.ac.uk" + } + tsun10 { + volname /vol/export/roots/tsun10 + exportfs "-root=tsun10.doc.ic.ac.uk,-access=tsun10.doc.ic.ac.uk" + } + tsun11 { + volname /vol/export/roots/tsun11 + exportfs "-root=tsun11.doc.ic.ac.uk,-access=tsun11.doc.ic.ac.uk" + } + tsun12 { + volname /vol/export/roots/tsun12 + exportfs "-root=tsun12.doc.ic.ac.uk,-access=tsun12.doc.ic.ac.uk" + } + tsun13 { + volname /vol/export/roots/tsun13 + exportfs "-root=tsun13.doc.ic.ac.uk,-access=tsun13.doc.ic.ac.uk" + } + tsun14 { + volname /vol/export/roots/tsun14 + exportfs "-root=tsun14.doc.ic.ac.uk,-access=tsun14.doc.ic.ac.uk" + } + tsun15 { + volname /vol/export/roots/tsun15 + exportfs "-root=tsun15.doc.ic.ac.uk,-access=tsun15.doc.ic.ac.uk" + } + } +} + +// swap for diskless clients +fs /dev/xy1c { + fstype = FSTYPE_UFS + opts = DEFAULT_OPTS + freq = 1 + passno = 5 + mount /export/swaps { + tsun1 { + volname /vol/export/swaps/tsun1 + exportfs "-root=tsun1.doc.ic.ac.uk,-access=tsun1.doc.ic.ac.uk" + } + tsun2 { + volname /vol/export/swaps/tsun2 + exportfs "-root=tsun2.doc.ic.ac.uk,-access=tsun2.doc.ic.ac.uk" + } + tsun3 { + volname /vol/export/swaps/tsun3 + exportfs "-root=tsun3.doc.ic.ac.uk,-access=tsun3.doc.ic.ac.uk" + } + tsun4 { + volname /vol/export/swaps/tsun4 + exportfs "-root=tsun4.doc.ic.ac.uk,-access=tsun4.doc.ic.ac.uk" + } + tsun5 { + volname /vol/export/swaps/tsun5 + exportfs "-root=tsun5.doc.ic.ac.uk,-access=tsun5.doc.ic.ac.uk" + } + tsun6 { + volname /vol/export/swaps/tsun6 + exportfs "-root=tsun6.doc.ic.ac.uk,-access=tsun6.doc.ic.ac.uk" + } + tsun7 { + volname /vol/export/swaps/tsun7 + exportfs "-root=tsun7.doc.ic.ac.uk,-access=tsun7.doc.ic.ac.uk" + } + tsun8 { + volname /vol/export/swaps/tsun8 + exportfs "-root=tsun8.doc.ic.ac.uk,-access=tsun8.doc.ic.ac.uk" + } + tsun9 { + volname /vol/export/swaps/tsun9 + exportfs "-root=tsun9.doc.ic.ac.uk,-access=tsun9.doc.ic.ac.uk" + } + tsun10 { + volname /vol/export/swaps/tsun10 + exportfs "-root=tsun10.doc.ic.ac.uk,-access=tsun10.doc.ic.ac.uk" + } + tsun11 { + volname /vol/export/swaps/tsun11 + exportfs "-root=tsun11.doc.ic.ac.uk,-access=tsun11.doc.ic.ac.uk" + } + tsun12 { + volname /vol/export/swaps/tsun12 + exportfs "-root=tsun12.doc.ic.ac.uk,-access=tsun12.doc.ic.ac.uk" + } + tsun13 { + volname /vol/export/swaps/tsun13 + exportfs "-root=tsun13.doc.ic.ac.uk,-access=tsun13.doc.ic.ac.uk" + } + tsun14 { + volname /vol/export/swaps/tsun14 + exportfs "-root=tsun14.doc.ic.ac.uk,-access=tsun14.doc.ic.ac.uk" + } + tsun15 { + volname /vol/export/swaps/tsun15 + exportfs "-root=tsun15.doc.ic.ac.uk,-access=tsun15.doc.ic.ac.uk" + } + } +} diff --git a/usr.sbin/amd/fsinfo/conf/hosts/whoops.doc.ic.ac.uk b/usr.sbin/amd/fsinfo/conf/hosts/whoops.doc.ic.ac.uk new file mode 100644 index 0000000..831053b --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/hosts/whoops.doc.ic.ac.uk @@ -0,0 +1,21 @@ +// $Id$ +// sm's bastardised csg_sun3 +// note that no /var/spool/rwho is mounted as we now expect amd to do this as /vol/rwho + +#define HOST whoops +#define DOMAIN doc.ic.ac.uk +#define BOOT gould.doc.ic.ac.uk +#define EXEC gould.doc.ic.ac.uk +#define MAIL tsunfs.doc.ic.ac.uk + +// a sun3 +host HOST.DOMAIN + +mount /vol/export/roots/HOST as / from BOOT opts rw,grpid,hard,intr +mount /vol/export/swaps/HOST fstype swap as swap from BOOT opts swap +mount /vol/export/exec/sun3 as /usr from EXEC opts ro,grpid,hard,intr +mount /vol/export/misc/crash/HOST as /var/crash/HOST from EXEC opts rw,nosuid,grpid,hard,intr +mount /vol/export/misc/tmp/HOST as /tmp from EXEC opts rw,nosuid,grpid,hard,intr +mount /vol/export/misc/usr.tmp/HOST as /var/tmp from EXEC opts rw,nosuid,grpid,hard,intr +mount /var/mmdf from MAIL opts rw,nosuid,grpid,hard,intr + diff --git a/usr.sbin/amd/fsinfo/conf/users b/usr.sbin/amd/fsinfo/conf/users new file mode 100644 index 0000000..9dc83d9 --- /dev/null +++ b/usr.sbin/amd/fsinfo/conf/users @@ -0,0 +1,106 @@ +audit -> /etc/security/audit +bin -> /bin +daemon -> / +games -> /usr/games +ingres -> /usr/ingres +news -> /var/spool/news +nobody -> /nonexistent +root -> / +sync -> / +sys -> / +sysdiag -> /usr/diag/sysdiag +uucp -> /var/spool/uucppublic +acwf = /home/toytown/others/acwf +adh = /home/dylan/dk2/adh +ae = /home/toytown/samson/ae +aj = /home/toytown/samson/aj +athena = /vol/src/athena +bh = /home/toytown/jim/bh +bp = /home/toytown/others/bp +brg = /home/gummo/users/brg +bt = /home/toytown/samson/bt +ca = /home/toytown/diadem/ca +ccm = /home/toytown/ai/ccm +chlo = /home/toytown/samson/chlo +clh = /home/toytown/ai/clh +cr = /home/toytown/samson/cr +cw = /home/toytown/genesis/cw +dds = /home/toytown/genesis/dds +dg = /home/toytown/dov/dg +dgb = /home/dylan/dk2/dgb +dme = /home/achilles/dme +dp = /home/gummo/usersdiana +ds = /home/toytown/ai/ds +dwj = /home/achilles/dwj +eaa = /home/toytown/dov/eaa +esh = /home/toytown/ai/esh +fcs = /home/ganymede/fcs +fst = /home/dylan/dk2/fst +glb = /home/toytown/ai/glb +grace = /home/toytown/others/grace +guest = /home/toytown/others/guest +hd = /home/toytown/others/hd +hf = /home/toytown/genesis/hf +iccp = /home/toytown/samson/iccp +ids = /home/toytown/samson/ids +ih = /home/toytown/others/ih +ja = /home/toytown/ai/ja +jfc = /home/toytown/jim/jfc +jg = /home/toytown/genesis/jg +jjc = /home/toytown/genesis/jjc +js = /home/toytown/samson/js +jsp = /home/achilles/jsp +jvp = /home/toytown/jim/jvp +kdr = /home/dylan/dk2/kdr +kevin = /home/toytown/others/kpt +kpt = /home/toytown/others/kpt +ksa = /home/toytown/ai/ksa +lkcl = /home/dylan/dk2/lkcl +ll = /home/toytown/dov/ll +ll1 = /home/toytown/others/ll1 +lmjm = /home/toytown/others/lmjm +lsh = /home/toytown/ai/lsh +mb = /home/toytown/jim/mb +md = /home/achilles/md +mdr = /home/achilles/mdr +mg = /home/ganymede/mg +mjh = /home/toytown/others/mjh +mrs = /home/achilles/mrs +mwg = /home/achilles/mwg +mwt = /home/achilles/mwt +nd = /home/gummo/users/nd +njw = /home/dylan/dk2/njw +ok = /home/ganymede/ok +pah = /home/toytown/jim/pah +pdg = /home/toytown/samson/pdg +phjk = /home/toytown/ai/phjk +pm = /home/achilles/pm +pm2 = /home/dylan/dk2/pm2 +ps = /home/toytown/genesis/ps +pt = /home/toytown/dov/pt +pvr = /home/toytown/jim/pvr +rgc = /home/toytown/jim/rgc +rjc = /home/toytown/jim/rjc +rjq = /home/achilles/rjq +sa = /home/toytown/samson/sa +shb = /home/toytown/others/shb +shc = /home/dylan/dk2/shc +sjk = /home/toytown/jim/sjk +sjl2 = /home/achilles/sjl2 +sjv = /home/ganymede/sjv +sm = /home/toytown/others/sm +sme = /home/ganymede/sme +sph = /home/toytown/ai/sph +ssp = /home/toytown/others/ssp +sw = /home/toytown/others/sw +sza = /home/ganymede/sza +teb = /home/dylan/dk2/teb +thp = /home/achilles/thp +tm = /home/toytown/ai/tm +tsem = /home/toytown/genesis/tsem +umacd20 = /home/ganymede/umacd20 +wmvh = /home/dylan/dk2/wmvh +wrdo = /home/ganymede/wrdo +ygal = /home/toytown/samson/ygal +zmact03 = /home/toytown/jim/zmact03 +zmacy26 = /home/toytown/jim/zmacy26 diff --git a/usr.sbin/amd/fsinfo/fsi_analyze.c b/usr.sbin/amd/fsinfo/fsi_analyze.c new file mode 100644 index 0000000..d436a49 --- /dev/null +++ b/usr.sbin/amd/fsinfo/fsi_analyze.c @@ -0,0 +1,645 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)fsi_analyze.c 8.1 (Berkeley) 6/6/93 + * + * $Id: fsi_analyze.c,v 5.2.2.1 1992/02/09 15:09:41 jsp beta $ + * + */ + +/* + * Analyze filesystem declarations + * + * Note: most of this is magic! + */ + +#include "../fsinfo/fsinfo.h" + +char *disk_fs_strings[] = { + "fstype", "opts", "dumpset", "passno", "freq", "mount", "log", 0, +}; + +char *mount_strings[] = { + "volname", "exportfs", 0, +}; + +char *fsmount_strings[] = { + "as", "volname", "fstype", "opts", "from", 0, +}; + +char *host_strings[] = { + "host", "netif", "config", "arch", "cluster", "os", 0, +}; + +char *ether_if_strings[] = { + "inaddr", "netmask", "hwaddr", 0, +}; + +/* + * Strip off the trailing part of a domain + * to produce a short-form domain relative + * to the local host domain. + * Note that this has no effect if the domain + * names do not have the same number of + * components. If that restriction proves + * to be a problem then the loop needs recoding + * to skip from right to left and do partial + * matches along the way -- ie more expensive. + */ +void domain_strip(otherdom, localdom) +char *otherdom, *localdom; +{ +#ifdef PARTIAL_DOMAINS + char *p1 = otherdom-1; + char *p2 = localdom-1; + + do { + if (p1 = strchr(p1+1, '.')) + if (p2 = strchr(p2+1, '.')) + if (STREQ(p1+1, p2+1)) { + *p1 = '\0'; + break; + } + } while (p1 && p2); +#else + char *p1, *p2; + + if ((p1 = strchr(otherdom, '.')) && + (p2 = strchr(localdom, '.')) && + (strcmp(p1+1, p2+1) == 0)) + *p1 = '\0'; +#endif /* PARTIAL_DOMAINS */ +} + +/* + * Take a little-endian domain name and + * transform into a big-endian Un*x pathname. + * For example: kiska.doc.ic -> ic/doc/kiska + */ +static char *compute_hostpath(hn) +char *hn; +{ + char *p = strdup(hn); + char *d; + char path[MAXPATHLEN]; + + domain_strip(p, hostname); + path[0] = '\0'; + + do { + d = strrchr(p, '.'); + if (d) { + *d = 0; + strcat(path, d+1); + strcat(path, "/"); + } else { + strcat(path, p); + } + } while (d); + + log("hostpath of '%s' is '%s'", hn, path); + + strcpy(p, path); + return p; +} + +static dict_ent *find_volname(nn) +char *nn; +{ + dict_ent *de; + char *p = strdup(nn); + char *q; + + do { + log("Searching for volname %s", p); + de = dict_locate(dict_of_volnames, p); + q = strrchr(p, '/'); + if (q) *q = '\0'; + } while (!de && q); + + free(p); + return de; +} + +static show_required(l, mask, info, hostname, strings) +ioloc *l; +int mask; +char *info; +char *hostname; +char *strings[]; +{ + int i; + log("mask left for %s:%s is %#x", hostname, info, mask); + + for (i = 0; strings[i]; i++) + if (ISSET(mask, i)) + lerror(l, "%s:%s needs field \"%s\"", hostname, info, strings[i]); +} + +/* + * Check and fill in "exportfs" details. + * Make sure the m_exported field references + * the most local node with an "exportfs" entry. + */ +static int check_exportfs(q, e) +qelem *q; +mount *e; +{ + mount *mp; + int errors = 0; + + ITER(mp, mount, q) { + if (ISSET(mp->m_mask, DM_EXPORTFS)) { + if (e) + lwarning(mp->m_ioloc, "%s has duplicate exportfs data", mp->m_name); + mp->m_exported = mp; + if (!ISSET(mp->m_mask, DM_VOLNAME)) + set_mount(mp, DM_VOLNAME, strdup(mp->m_name)); + } else { + mp->m_exported = e; + } + + /* + * Recursively descend the mount tree + */ + if (mp->m_mount) + errors += check_exportfs(mp->m_mount, mp->m_exported); + + /* + * If a volume name has been specified, but this node and none + * of its parents has been exported, report an error. + */ + if (ISSET(mp->m_mask, DM_VOLNAME) && !mp->m_exported) { + lerror(mp->m_ioloc, "%s has a volname but no exportfs data", mp->m_name); + errors++; + } + } + + return errors; +} + +static int analyze_dkmount_tree(q, parent, dk) +qelem *q; +mount *parent; +disk_fs *dk; +{ + mount *mp; + int errors = 0; + + ITER(mp, mount, q) { + log("Mount %s:", mp->m_name); + if (parent) { + char n[MAXPATHLEN]; + sprintf(n, "%s/%s", parent->m_name, mp->m_name); + if (*mp->m_name == '/') + lerror(mp->m_ioloc, "sub-directory %s of %s starts with '/'", mp->m_name, parent->m_name); + else if (STREQ(mp->m_name, "default")) + lwarning(mp->m_ioloc, "sub-directory of %s is named \"default\"", parent->m_name); + log("Changing name %s to %s", mp->m_name, n); + free(mp->m_name); + mp->m_name = strdup(n); + } + mp->m_name_len = strlen(mp->m_name); + mp->m_parent = parent; + mp->m_dk = dk; + if (mp->m_mount) + analyze_dkmount_tree(mp->m_mount, mp, dk); + } + + return errors; +} + +/* + * The mount tree is a singleton list + * containing the top-level mount + * point for a disk. + */ +static int analyze_dkmounts(dk, q) +disk_fs *dk; +qelem *q; +{ + int errors = 0; + mount *mp, *mp2 = 0; + int i = 0; + + /* + * First scan the list of subdirs to make + * sure there is only one - and remember it + */ + if (q) { + ITER(mp, mount, q) { + mp2 = mp; + i++; + } + } + + /* + * Check... + */ + if (i < 1) { + lerror(dk->d_ioloc, "%s:%s has no mount point", dk->d_host->h_hostname, dk->d_dev); + return 1; + } + if (i > 1) { + lerror(dk->d_ioloc, "%s:%s has more than one mount point", dk->d_host->h_hostname, dk->d_dev); + errors++; + } + /* + * Now see if a default mount point is required + */ + if (STREQ(mp2->m_name, "default")) { + if (ISSET(mp2->m_mask, DM_VOLNAME)) { + char nbuf[1024]; + compute_automount_point(nbuf, dk->d_host, mp2->m_volname); + free(mp2->m_name); + mp2->m_name = strdup(nbuf); + log("%s:%s has default mount on %s", dk->d_host->h_hostname, dk->d_dev, mp2->m_name); + } else { + lerror(dk->d_ioloc, "no volname given for %s:%s", dk->d_host->h_hostname, dk->d_dev); + errors++; + } + } + /* + * Fill in the disk mount point + */ + if (!errors && mp2 && mp2->m_name) + dk->d_mountpt = strdup(mp2->m_name); + else + dk->d_mountpt = strdup("error"); + + /* + * Analyze the mount tree + */ + errors += analyze_dkmount_tree(q, 0, dk); + + /* + * Analyze the export tree + */ + errors += check_exportfs(q, 0); + + return errors; +} + +static void fixup_required_disk_info(dp) +disk_fs *dp; +{ + /* + * "fstype" + */ + if (ISSET(dp->d_mask, DF_FSTYPE)) { + if (STREQ(dp->d_fstype, "swap")) { + /* + * Fixup for a swap device + */ + if (!ISSET(dp->d_mask, DF_PASSNO)) { + dp->d_passno = 0; + BITSET(dp->d_mask, DF_PASSNO); + } else if (dp->d_freq != 0) { + lwarning(dp->d_ioloc, + "Pass number for %s:%s is non-zero", + dp->d_host->h_hostname, dp->d_dev); + } + + /* + * "freq" + */ + if (!ISSET(dp->d_mask, DF_FREQ)) { + dp->d_freq = 0; + BITSET(dp->d_mask, DF_FREQ); + } else if (dp->d_freq != 0) { + lwarning(dp->d_ioloc, + "dump frequency for %s:%s is non-zero", + dp->d_host->h_hostname, dp->d_dev); + } + + /* + * "opts" + */ + if (!ISSET(dp->d_mask, DF_OPTS)) + set_disk_fs(dp, DF_OPTS, strdup("swap")); + + /* + * "mount" + */ + if (!ISSET(dp->d_mask, DF_MOUNT)) { + qelem *q = new_que(); + mount *m = new_mount(); + m->m_name = strdup("swap"); + m->m_mount = new_que(); + ins_que(&m->m_q, q->q_back); + dp->d_mount = q; + BITSET(dp->d_mask, DF_MOUNT); + } else { + lerror(dp->d_ioloc, "%s: mount field specified for swap partition", dp->d_host->h_hostname); + } + } else if (STREQ(dp->d_fstype, "export")) { + /* + * "passno" + */ + if (!ISSET(dp->d_mask, DF_PASSNO)) { + dp->d_passno = 0; + BITSET(dp->d_mask, DF_PASSNO); + } else if (dp->d_passno != 0) { + lwarning(dp->d_ioloc, + "pass number for %s:%s is non-zero", + dp->d_host->h_hostname, dp->d_dev); + } + + /* + * "freq" + */ + if (!ISSET(dp->d_mask, DF_FREQ)) { + dp->d_freq = 0; + BITSET(dp->d_mask, DF_FREQ); + } else if (dp->d_freq != 0) { + lwarning(dp->d_ioloc, + "dump frequency for %s:%s is non-zero", + dp->d_host->h_hostname, dp->d_dev); + } + + /* + * "opts" + */ + if (!ISSET(dp->d_mask, DF_OPTS)) + set_disk_fs(dp, DF_OPTS, strdup("rw,defaults")); + + } + } +} + +static void fixup_required_mount_info(fp, de) +fsmount *fp; +dict_ent *de; +{ + if (!ISSET(fp->f_mask, FM_FROM)) { + if (de->de_count != 1) { + lerror(fp->f_ioloc, "ambiguous mount: %s is a replicated filesystem", fp->f_volname); + } else { + dict_data *dd; + mount *mp = 0; + ITER(dd, dict_data, &de->de_q) { + mp = (mount *) dd->dd_data; + break; + } + if (!mp) + abort(); + fp->f_ref = mp; + set_fsmount(fp, FM_FROM, mp->m_dk->d_host->h_hostname); + log("set: %s comes from %s", fp->f_volname, fp->f_from); + } + } + + if (!ISSET(fp->f_mask, FM_FSTYPE)) { + set_fsmount(fp, FM_FSTYPE, strdup("nfs")); + log("set: fstype is %s", fp->f_fstype); + } + + if (!ISSET(fp->f_mask, FM_OPTS)) { + set_fsmount(fp, FM_OPTS, strdup("rw,nosuid,grpid,defaults")); + log("set: opts are %s", fp->f_opts); + } + + if (!ISSET(fp->f_mask, FM_LOCALNAME)) { + if (fp->f_ref) { + set_fsmount(fp, FM_LOCALNAME, strdup(fp->f_volname)); + log("set: localname is %s", fp->f_localname); + } else { + lerror(fp->f_ioloc, "cannot determine localname since volname %s is not uniquely defined", fp->f_volname); + } + } +} + +/* + * For each disk on a host + * analyze the mount information + * and fill in any derivable + * details. + */ +static void analyze_drives(hp) +host *hp; +{ + qelem *q = hp->h_disk_fs; + disk_fs *dp; + + ITER(dp, disk_fs, q) { + int req; + log("Disk %s:", dp->d_dev); + dp->d_host = hp; + fixup_required_disk_info(dp); + req = ~dp->d_mask & DF_REQUIRED; + if (req) + show_required(dp->d_ioloc, req, dp->d_dev, hp->h_hostname, disk_fs_strings); + analyze_dkmounts(dp, dp->d_mount); + } +} + +/* + * Check that all static mounts make sense and + * that the source volumes exist. + */ +static void analyze_mounts(hp) +host *hp; +{ + qelem *q = hp->h_mount; + fsmount *fp; + int netbootp = 0; + + ITER(fp, fsmount, q) { + char *p; + char *nn = strdup(fp->f_volname); + int req; + dict_ent *de; + int found = 0; + int matched = 0; + do { + p = 0; + de = find_volname(nn); + log("Mount: %s (trying %s)", fp->f_volname, nn); + + if (de) { + found = 1; + /* + * Check that the from field is really exporting + * the filesystem requested. + */ + if (ISSET(fp->f_mask, FM_FROM)) { + dict_data *dd; + mount *mp2 = 0; + ITER(dd, dict_data, &de->de_q) { + mount *mp = (mount *) dd->dd_data; + if (STREQ(mp->m_dk->d_host->h_hostname, fp->f_from)) { + mp2 = mp; + break; + } + } + + if (mp2) { + fp->f_ref = mp2; + matched = 1; + break; + } + } else { + matched = 1; + break; + } + } + p = strrchr(nn, '/'); + if (p) + *p = 0; + } while (de && p); + free(nn); + + if (!found) { + lerror(fp->f_ioloc, "volname %s unknown", fp->f_volname); + } else if (matched) { + fixup_required_mount_info(fp, de); + req = ~fp->f_mask & FM_REQUIRED; + if (req) { + show_required(fp->f_ioloc, req, fp->f_volname, hp->h_hostname, + fsmount_strings); + } else if (strcmp(fp->f_localname, "/") == 0) { + hp->h_netroot = fp; + netbootp |= FM_NETROOT; + } else if (strcmp(fp->f_localname, "swap") == 0) { + hp->h_netswap = fp; + netbootp |= FM_NETSWAP; + } + } else { + lerror(fp->f_ioloc, "volname %s not exported from %s", fp->f_volname, + fp->f_from ? fp->f_from : "anywhere"); + } + } + + if (netbootp && (netbootp != FM_NETBOOT)) + lerror(hp->h_ioloc, "network booting requires both root and swap areas"); +} + +void analyze_hosts(q) +qelem *q; +{ + host *hp; + + show_area_being_processed("analyze hosts", 5); + + /* + * Check all drives + */ + ITER(hp, host, q) { + log("disks on host %s", hp->h_hostname); + show_new("ana-host"); + hp->h_hostpath = compute_hostpath(hp->h_hostname); + + if (hp->h_disk_fs) + analyze_drives(hp); + + } + + show_area_being_processed("analyze mounts", 5); + + /* + * Check static mounts + */ + ITER(hp, host, q) { + log("mounts on host %s", hp->h_hostname); + show_new("ana-mount"); + if (hp->h_mount) + analyze_mounts(hp); + + } +} + +/* + * Check an automount request + */ +static void analyze_automount(ap) +automount *ap; +{ + dict_ent *de = find_volname(ap->a_volname); + if (de) { + ap->a_mounted = de; + } else { + if (STREQ(ap->a_volname, ap->a_name)) + lerror(ap->a_ioloc, "unknown volname %s automounted", ap->a_volname); + else + lerror(ap->a_ioloc, "unknown volname %s automounted on %s", ap->a_volname, ap->a_name); + } +} + +static void analyze_automount_tree(q, pref, lvl) +qelem *q; +char *pref; +int lvl; +{ + automount *ap; + + ITER(ap, automount, q) { + char nname[1024]; + if (lvl > 0 || ap->a_mount) + if (ap->a_name[1] && strchr(ap->a_name+1, '/')) + lerror(ap->a_ioloc, "not allowed '/' in a directory name"); + sprintf(nname, "%s/%s", pref, ap->a_name); + free(ap->a_name); + ap->a_name = strdup(nname[1] == '/' ? nname+1 : nname); + log("automount point %s:", ap->a_name); + show_new("ana-automount"); + if (ap->a_mount) { + analyze_automount_tree(ap->a_mount, ap->a_name, lvl+1); + } else if (ap->a_volname) { + log("\tautomount from %s", ap->a_volname); + analyze_automount(ap); + } else if (ap->a_symlink) { + log("\tsymlink to %s", ap->a_symlink); + } else { + ap->a_volname = strdup(ap->a_name); + log("\timplicit automount from %s", ap->a_volname); + analyze_automount(ap); + } + } +} + +void analyze_automounts(q) +qelem *q; +{ + auto_tree *tp; + + show_area_being_processed("analyze automount", 5); + /* + * q is a list of automounts + */ + ITER(tp, auto_tree, q) + analyze_automount_tree(tp->t_mount, "", 0); +} diff --git a/usr.sbin/amd/fsinfo/fsi_data.h b/usr.sbin/amd/fsinfo/fsi_data.h new file mode 100644 index 0000000..3fc10c4 --- /dev/null +++ b/usr.sbin/amd/fsinfo/fsi_data.h @@ -0,0 +1,236 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)fsi_data.h 8.1 (Berkeley) 6/6/93 + * + * $Id: fsi_data.h,v 5.2.2.1 1992/02/09 15:09:53 jsp beta $ + * + */ + +typedef struct auto_tree auto_tree; +typedef struct automount automount; +typedef struct dict dict; +typedef struct dict_data dict_data; +typedef struct dict_ent dict_ent; +typedef struct disk_fs disk_fs; +typedef struct ether_if ether_if; +typedef struct fsmount fsmount; +typedef struct host host; +typedef struct ioloc ioloc; +typedef struct mount mount; +typedef struct qelem qelem; + +/* + * Linked lists... + */ +struct qelem { + qelem *q_forw; + qelem *q_back; +}; + +/* + * Automount tree + */ +struct automount { + qelem a_q; + ioloc *a_ioloc; + char *a_name; /* Automount key */ + char *a_volname; /* Equivalent volume to be referenced */ + char *a_symlink; /* Symlink representation */ + qelem *a_mount; /* Tree representation */ + dict_ent *a_mounted; +}; + +/* + * List of automount trees + */ +struct auto_tree { + qelem t_q; + ioloc *t_ioloc; + char *t_defaults; + qelem *t_mount; +}; + +/* + * A host + */ +struct host { + qelem q; + int h_mask; + ioloc *h_ioloc; + fsmount *h_netroot, *h_netswap; +#define HF_HOST 0 + char *h_hostname; /* The full name of the host */ + char *h_lochost; /* The name of the host with local domains stripped */ + char *h_hostpath; /* The filesystem path to the host (cf compute_hostpath) */ +#define HF_ETHER 1 + qelem *h_ether; +#define HF_CONFIG 2 + qelem *h_config; +#define HF_ARCH 3 + char *h_arch; +#define HF_CLUSTER 4 + char *h_cluster; +#define HF_OS 5 + char *h_os; + qelem *h_disk_fs; + qelem *h_mount; +}; + +/* + * An ethernet interface + */ +struct ether_if { + qelem e_q; + int e_mask; + ioloc *e_ioloc; + char *e_if; +#define EF_INADDR 0 + struct in_addr e_inaddr; +#define EF_NETMASK 1 + u_long e_netmask; +#define EF_HWADDR 2 + char *e_hwaddr; +}; + +/* + * Disk filesystem structure. + * + * If the DF_* numbers are changed + * disk_fs_strings in analyze.c will + * need updating. + */ +struct disk_fs { + qelem d_q; + int d_mask; + ioloc *d_ioloc; + host *d_host; + char *d_mountpt; + char *d_dev; +#define DF_FSTYPE 0 + char *d_fstype; +#define DF_OPTS 1 + char *d_opts; +#define DF_DUMPSET 2 + char *d_dumpset; +#define DF_PASSNO 3 + int d_passno; +#define DF_FREQ 4 + int d_freq; +#define DF_MOUNT 5 + qelem *d_mount; +#define DF_LOG 6 + char *d_log; +}; +#define DF_REQUIRED ((1<dd_data = v; + ins_que(&dd->dd_q, de->de_q.q_back); + de->de_count++; +} + +static dict_ent *new_dict_ent(k) +char *k; +{ + dict_ent *de = ALLOC(dict_ent); + de->de_key = k; + init_que(&de->de_q); + return de; +} + +dict_ent *dict_locate(dp, k) +dict *dp; +char *k; +{ + dict_ent *de = dp->de[dict_hash(k)]; + while (de && !STREQ(de->de_key, k)) + de = de->de_next; + + return de; +} + +void dict_add(dp, k, v) +dict *dp; +char *k, *v; +{ + dict_ent *de = dict_locate(dp, k); + if (!de) { + dict_ent **dep = &dp->de[dict_hash(k)]; + de = new_dict_ent(k); + de->de_next = *dep; + *dep = de; + } + dict_add_data(de, v); +} + +int dict_iter(dp, fn) +dict *dp; +int (*fn)(); +{ + int i; + int errors = 0; + + for (i = 0; i < DICTHASH; i++) { + dict_ent *de = dp->de[i]; + while (de) { + errors += (*fn)(&de->de_q); + de = de->de_next; + } + } + return errors; +} diff --git a/usr.sbin/amd/fsinfo/fsi_gram.y b/usr.sbin/amd/fsinfo/fsi_gram.y new file mode 100644 index 0000000..b4aa245 --- /dev/null +++ b/usr.sbin/amd/fsinfo/fsi_gram.y @@ -0,0 +1,394 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)fsi_gram.y 8.1 (Berkeley) 6/6/93 + * + * $Id: fsi_gram.y,v 5.2.2.1 1992/02/09 15:09:35 jsp beta $ + * + */ + +%{ +#include "../fsinfo/fsinfo.h" +#include + +extern qelem *list_of_hosts, *list_of_automounts; +%} + +%union { + auto_tree *a; + disk_fs *d; + ether_if *e; + host *h; + qelem *q; + char *s; + mount *m; + fsmount *f; +} + +%token tARCH +%token tAS +%token tAUTOMOUNT +%token tCLUSTER +%token tCONFIG +%token tDUMPSET +%token tEQ +%token tEXPORTFS +%token tFREQ +%token tFROM +%token tFS +%token tFSTYPE +%token tHWADDR +%token tINADDR +%token tHOST +%token tLOCALHOST +%token tLOG +%token tMOUNT +%token tNETMASK +%token tNETIF +%token tVOLNAME +%token tOPTS +%token tOS +%token tPASSNO +%token tSEL +%token tSTR + +%start list_of_hosts + +%type automount +%type automount_tree +%type ether_attr +%type dir_tree_info +%type filesystem fs_info_list +%type host host_attr host_attr_list +%type list_of_hosts list_of_filesystems list_of_mounts dir_tree +%type localinfo_list +%type opt_auto_opts + +%% + +list_of_hosts : + /* empty */ + { $$ = new_que(); } + + | list_of_hosts host + { if ($2) ins_que((qelem *) $2, list_of_hosts->q_back); + $$ = $1; } + + | list_of_hosts automount + { if ($2) ins_que((qelem *) $2, list_of_automounts->q_back); + $$ = $1; } + ; + +/* + * A new host: + * + * host foo.domain + */ +host : + tHOST host_attr list_of_filesystems list_of_mounts + { $$ = $2; $$->h_disk_fs = $3; $$->h_mount = $4; } + + | error tHOST host_attr list_of_filesystems list_of_mounts + { $$ = $3; $$->h_disk_fs = $4; $$->h_mount = $5; } + + ; + +host_attr : + tSTR + { $$ = new_host(); set_host($$, HF_HOST, $1); } + + | '{' host_attr_list '}' tSTR + { $$ = $2; set_host($$, HF_HOST, $4); } + + ; + +host_attr_list : + /* empty */ + { $$ = new_host(); } + + | host_attr_list tNETIF tSTR '{' ether_attr '}' + { if ($5) { + $5->e_if = $3; + $$ = $1; set_host($$, HF_ETHER, $5); } + } + + | host_attr_list tCONFIG tSTR + { $$ = $1; set_host($$, HF_CONFIG, $3); } + + | host_attr_list tARCH '=' tSTR + { $$ = $1; set_host($$, HF_ARCH, $4); } + + | host_attr_list tOS '=' tSTR + { $$ = $1; set_host($$, HF_OS, $4); } + + | host_attr_list tCLUSTER '=' tSTR + { $$ = $1; set_host($$, HF_CLUSTER, $4); } + + | host_attr_list error '=' tSTR + { yyerror("unknown host attribute"); } + ; + +ether_attr : + /* empty */ + { $$ = new_ether_if(); } + + | ether_attr tINADDR '=' tSTR + { $$ = $1; set_ether_if($$, EF_INADDR, $4); } + | ether_attr tNETMASK '=' tSTR + { $$ = $1; set_ether_if($$, EF_NETMASK, $4); } + | ether_attr tHWADDR '=' tSTR + { $$ = $1; set_ether_if($$, EF_HWADDR, $4); } + ; + +/* + * A new automount tree: + * + * automount /mountpoint { ... } + */ +automount : + tAUTOMOUNT opt_auto_opts automount_tree + { if ($3) { + $$ = new_auto_tree($2, $3); + } else { + $$ = 0; + } + } + + | tAUTOMOUNT error + { $$ = 0; } + ; + +opt_auto_opts : + /* empty */ + { $$ = strdup(""); } + + | tOPTS tSTR + { $$ = $2; } + ; + +list_of_filesystems : + /* empty */ + { $$ = 0; } + + | list_of_filesystems filesystem + { if ($2) { + if ($1) + $$ = $1; + else + $$ = new_que(); + ins_que(&$2->d_q, $$->q_back); + } else { + $$ = $1; + } + } + ; + +/* + * A new filesystem: + * + * fs /dev/whatever { ... } + */ +filesystem : + tFS tSTR '{' fs_info_list '}' + { $4->d_dev = $2; $$ = $4; } + + | tFS error '}' + { $$ = (disk_fs *) 0; } + ; + +/* + * Per-filesystem information: + * + * fstype - the type of the filesystem (4.2, nfs, swap, export) + * opts - the mount options ("rw,grpid") + * passno - fsck pass number + * freq - dump frequency + * dumpset - tape set for filesystem dumps + * mount - where to mount this filesystem + * log - log device + */ +fs_info_list : + /* empty */ + { $$ = new_disk_fs(); } + + | fs_info_list tFSTYPE '=' tSTR + { $$ = $1; set_disk_fs($$, DF_FSTYPE, $4); } + + | fs_info_list tOPTS '=' tSTR + { $$ = $1; set_disk_fs($$, DF_OPTS, $4); } + + | fs_info_list tPASSNO '=' tSTR + { $$ = $1; set_disk_fs($$, DF_PASSNO, $4); } + + | fs_info_list tFREQ '=' tSTR + { $$ = $1; set_disk_fs($$, DF_FREQ, $4); } + + | fs_info_list tMOUNT dir_tree + { $$ = $1; set_disk_fs($$, DF_MOUNT, (char *) $3); } + + | fs_info_list tDUMPSET '=' tSTR + { $$ = $1; set_disk_fs($$, DF_DUMPSET, $4); } + + | fs_info_list tLOG '=' tSTR + { $$ = $1; set_disk_fs($$, DF_LOG, $4); } + + | fs_info_list error '=' tSTR + { yyerror("unknown filesystem attribute"); } + ; + +/* + * An automount tree: + * + * name = "volname" name is a reference to volname + * name -> "string" name is a link to "string" + * name { ... } name is an automount tree + */ +automount_tree : + /* empty */ + { $$ = 0; } + + | automount_tree tSTR '=' tSTR + { automount *a = new_automount($2); + a->a_volname = $4; + if ($1) + $$ = $1; + else + $$ = new_que(); + ins_que(&a->a_q, $$->q_back); + } + + | automount_tree tSTR tEQ tSTR + { automount *a = new_automount($2); + a->a_symlink = $4; + if ($1) + $$ = $1; + else + $$ = new_que(); + ins_que(&a->a_q, $$->q_back); + } + + | automount_tree tSTR '{' automount_tree '}' + { automount *a = new_automount($2); + a->a_mount = $4; + if ($1) + $$ = $1; + else + $$ = new_que(); + ins_que(&a->a_q, $$->q_back); + } + ; + +dir_tree : + /* empty */ + { $$ = 0; } + + | dir_tree tSTR '{' dir_tree_info dir_tree '}' + { $4->m_mount = $5; + $4->m_name = $2; + if ($2[0] != '/' && $2[1] && strchr($2+1, '/')) + yyerror("not allowed '/' in a directory name"); + if ($1) + $$ = $1; + else + $$ = new_que(); + ins_que(&$4->m_q, $$->q_back); + } + ; + +dir_tree_info : + /* empty */ + { $$ = new_mount(); } + + | dir_tree_info tEXPORTFS tSTR + { $$ = $1; set_mount($$, DM_EXPORTFS, $3); } + + | dir_tree_info tVOLNAME tSTR + { $$ = $1; set_mount($$, DM_VOLNAME, $3); } + + | dir_tree_info tSEL tSTR + { $$ = $1; set_mount($$, DM_SEL, $3); } + + | dir_tree_info error '=' tSTR + { yyerror("unknown directory attribute"); } + ; + +/* + * Additional mounts on a host + * + * mount "volname" ... + */ +list_of_mounts : + /* empty */ + { $$ = 0; } + + | list_of_mounts tMOUNT tSTR localinfo_list + { set_fsmount($4, FM_VOLNAME, $3); + if ($1) + $$ = $1; + else + $$ = new_que(); + ins_que(&$4->f_q, $$->q_back); + } + ; + +/* + * Mount info: + * + * from "hostname" - obtain the object from the named host + * as "string" - where to mount, if different from the volname + * opts "string" - mount options + * fstype "type" - type of filesystem mount, if not nfs + */ +localinfo_list : + /* empty */ + { $$ = new_fsmount(); } + + | localinfo_list tAS tSTR + { $$ = $1; set_fsmount($$, FM_LOCALNAME, $3); } + + | localinfo_list tFROM tSTR + { $$ = $1; set_fsmount($$, FM_FROM, $3); } + + | localinfo_list tFSTYPE tSTR + { $$ = $1; set_fsmount($$, FM_FSTYPE, $3); } + + | localinfo_list tOPTS tSTR + { $$ = $1; set_fsmount($$, FM_OPTS, $3); } + + | localinfo_list error '=' tSTR + { yyerror("unknown mount attribute"); } + ; diff --git a/usr.sbin/amd/fsinfo/fsi_lex.l b/usr.sbin/amd/fsinfo/fsi_lex.l new file mode 100644 index 0000000..46ec532 --- /dev/null +++ b/usr.sbin/amd/fsinfo/fsi_lex.l @@ -0,0 +1,403 @@ +%{ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)fsi_lex.l 8.2 (Berkeley) 2/17/94 + * + * $Id: fsi_lex.l,v 5.2.2.1 1992/02/09 15:09:36 jsp beta $ + * + */ + +/* + * Lexical analyzer for fsinfo. + * TODO: Needs rewriting. + */ + +static int xinput(); +static void xunput(); + +#ifdef FLEX_SCANNER +static int yylineno; +/* Flex support with help from Vern Paxson */ +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ +{ \ + int i; \ + for (i = 0; i < max_size; i++) { \ + int ch = xinput(i == 0); \ + if (ch == 0) \ + break; \ + buf[i] = ch; \ + } \ + result = i; \ +} + +#define INIT_STATE { \ + switch ((yy_start - 1) / 2) { \ + case 0: \ + BEGIN F; \ + break; \ + } \ +} + + +#else +/* + * Using old lex... + */ +#undef unput +#define unput(ch) xunput(ch) +#undef input +#define input() xinput(1) + +#define INIT_STATE { \ + switch (yybgin - yysvec - 1) { \ + case 0: \ + BEGIN F; \ + break; \ + } \ +} + +#endif /* FLEX_SCANNER */ + +#include "../fsinfo/fsinfo.h" +#include "fsi_gram.h" +#include + +static char *filename; +static char *optr; +static char ostr[1024]; +static find_resword(); +static unsigned char ibuf[64]; +static unsigned char *iptr = ibuf; +static int quoted; +static int lastch, nextch = '\n'; +YYSTYPE yylval; + +struct r { + char *rw; + int tok; +} rr[] = { + { "->", tEQ }, + { "arch", tARCH }, + { "as", tAS }, + { "automount", tAUTOMOUNT }, + { "cluster", tCLUSTER }, + { "config", tCONFIG }, + { "dumpset", tDUMPSET }, + { "exportfs", tEXPORTFS }, + { "freq", tFREQ }, + { "from", tFROM }, + { "fs", tFS }, + { "fstype", tFSTYPE }, + { "host", tHOST }, + { "hwaddr", tHWADDR }, + { "inaddr", tINADDR }, + { "localhost", tLOCALHOST }, + { "log", tLOG }, + { "mount", tMOUNT }, + { "netif", tNETIF }, + { "netmask", tNETMASK }, + { "opts", tOPTS }, + { "os", tOS }, + { "passno", tPASSNO }, + { "sel", tSEL }, + { "volname", tVOLNAME }, + { 0, 0 }, +}; +#define NRES_WORDS (sizeof(rr)/sizeof(rr[0])-1) + +%} + +%start F Q + +%% + INIT_STATE; /* witchcraft */ + +[^ \t\n"={}]+ { return find_resword(yytext); } +[ \t] ; +"\n" { yylineno++; } +[={}] { return *yytext; } + +\" { BEGIN Q; optr = ostr; quoted = 1; } +\n { yylineno++; yyerror("\" expected"); BEGIN F; } +\\b { *optr++ = '\b'; /* escape */ } +\\t { *optr++ = '\t'; /* escape */ } +\\\" { *optr++ = '\"'; /* escape */ } +\\\\ { *optr++ = '\\'; /* escape */ } +\\\n { yylineno++; /* continue */ } +\\r { *optr++ = '\r'; /* escape */ } +\\n { *optr++ = '\n'; /* escape */ } +\\f { *optr++ = '\f'; /* escape */ } +"\\ " { *optr++ = ' '; /* force space */ } +\\. { yyerror("Unknown \\ sequence"); } +([ \t]|"\\\n"){2,} { char *p = yytext-1; while (p = strchr(p+1, '\n')) yylineno++; } +\" { BEGIN F; quoted = 0; + *optr = '\0'; + yylval.s = strdup(ostr); + return tSTR; + } +. { *optr++ = *yytext; } + +%% + +static int find_resword(s) +char *s; +{ + int tok = 0; + + int l = 0, m = NRES_WORDS/2, h = NRES_WORDS-1; + int rc = 0; + + m = NRES_WORDS/2; + +#define FSTRCMP(p, q) ((*(p) == *(q)) ? strcmp((p)+1, (q)+1) : *(p) - *(q)) + + while ((l <= h) && (rc = FSTRCMP(s, rr[m].rw))) { + /*fprintf(stderr, "failed to cmp(%s, %s), %d, %d, %d\n", s, rr[m].rw, l, m, h);*/ + if (rc < 0) + h = m - 1; + else + l = m + 1; + m = (h + l) / 2; + } + + if (rc == 0) + tok = rr[m].tok; + + switch (tok) { + case tLOCALHOST: + s = "${host}"; + /* fall through... */ + case 0: + yylval.s = strdup(s); + tok = tSTR; + /* fall through... */ + default: + return tok; + } + +} + +int yyerror(s, s1, s2, s3, s4) +char *s; +char *s1, *s2, *s3, *s4; +{ + col_cleanup(0); + fprintf(stderr, "%s:%d: ", filename ? filename : "/dev/stdin", yylineno); + fprintf(stderr, s, s1, s2, s3, s4); + fputc('\n', stderr); + parse_errors++; +} + +ioloc *current_location() +{ + ioloc *ip = ALLOC(ioloc); + ip->i_line = yylineno; + ip->i_file = filename; + return ip; +} + +#ifdef FLEX_SCANNER +#undef yywrap +#endif + +int yywrap() +{ +static int first = 1; + if (first) { + char prog[16*1024]; + strcpy(prog, "for file in "); + while (*++g_argv) { + if (access(*g_argv, 4) < 0) { + error("\"%s\": Cannot open for reading", *g_argv); + file_io_errors++; + } else { + strcat(prog, *g_argv); + strcat(prog, " "); + } + } + strcat(prog, "; do /lib/cpp "); + strcat(prog, idvbuf); + strcat(prog, " -DHOSTNAME=\'"); + strcat(prog, hostname); + strcat(prog, "\' \"$file\"; done"); + yyin = popen(prog, "r"); + if (yyin) { + /*if (filename) free(filename);*/ + filename = strdup("unknown"); + yylineno = 1; + first = 0; + return 0; + } else { + perror(prog); + } + } + + if (!first && yyin && pclose(yyin) != 0) + parse_errors++; + + return 1; +} + +#define xgetc(fp) ((iptr > ibuf) ? (*--iptr) : (lastch = nextch, nextch = getc(fp), (nextch == EOF ? nextch = lastch, EOF : nextch))) + +static int xinput(need) +int need; +{ +static int c_comment = 0; + int ch, ch2; + + do { + ch = xgetc(yyin); + /* fprintf(stderr, "ch = %c, %#x, %d\n", ch, ibuf,iptr-ibuf); */ + if (ch == EOF) return 0; + if (quoted) + return ch; + if (c_comment) { + ch2 = ch; + do { + if (ch2 == '\n') { + nextch = '\n'; + return ch2; + } + /* C style comment */ + do { + ch2 = getc(yyin); + if (ch2 == '\n') { + nextch = '\n'; + return ch2; + } + } while (ch2 != '*' && ch2 != EOF); + + while (ch2 == '*') + ch2 = getc(yyin); + } while (ch2 != '/' && ch2 != EOF); + c_comment = 0; + if (ch2 == EOF) + break; + continue; + } + + if (ch == '#') { + /*log("lastch = '%c' (%#x)", lastch, lastch);*/ + if (lastch == '\n') { + char fname[MAXPATHLEN]; + char *fptr; + if (!need) { + xunput('#'); + nextch = '\n'; + return 0; + } + fname[0] = '\0'; + /* Skip past space */ + do { + ch2 = getc(yyin); + } while (ch2 != EOF && ch2 != '\n' && !isdigit(ch2)); + if (isdigit(ch2)) { + /* Read in line number */ + fptr = fname; + do { + *fptr++ = ch2; + ch2 = getc(yyin); + } while (isdigit(ch2)); + *fptr = '\0'; + if (fptr != fname) + yylineno = atoi(fname) - 1; + } + /* Skip past space */ + while (ch2 != EOF && ch2 != '\"' && ch2 != '\n') + ch2 = getc(yyin); + if (ch2 == '\"') { + /* Read file name */ + fptr = fname; + ch2 = getc(yyin); + while (ch2 != '\"' && ch2 != EOF && ch2 != EOF) { + *fptr++ = ch2; + ch2 = getc(yyin); + } + *fptr = '\0'; + if (fname[0]) { + log("Setting filename to \"%s\"", fname); + /*if (filename) free(filename);*/ + filename = strdup(fname); + } + } + while (ch2 != '\n' && ch2 != EOF) + ch2 = getc(yyin); + } else do { + ch2 = getc(yyin); + } while (ch2 != '\n' && ch2 != EOF); + if (ch2 == '\n') { + nextch = '\n'; + return ch2; + } + } else if (ch == '/') { + ch2 = getc(yyin); + if (ch2 == '/') { + /* C++ style comment */ + do { + ch2 = getc(yyin); + } while (ch2 != '\n' && ch2 != EOF); + if (ch2 == '\n') { + nextch = '\n'; + return ch2; + } + } else if (ch2 == '*') { + c_comment = 1; + continue; + } else { + xunput(ch2); + return ch; + } + } else { + return ch; + } + } while (ch2 != EOF); + error("End of file within comment"); + return 0; +} + +static void xunput(c) +int c; +{ + if (c && c != EOF) { + if (iptr == ibuf + sizeof(ibuf) - 1) + fatal("Out of space in lexical pushback"); + *iptr++ = c; + } +} diff --git a/usr.sbin/amd/fsinfo/fsi_util.c b/usr.sbin/amd/fsinfo/fsi_util.c new file mode 100644 index 0000000..c0d8088 --- /dev/null +++ b/usr.sbin/amd/fsinfo/fsi_util.c @@ -0,0 +1,573 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 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. + * + * @(#)fsi_util.c 8.1 (Berkeley) 6/6/93 + * + * $Id: fsi_util.c,v 5.2.2.1 1992/02/09 15:09:39 jsp beta $ + * + */ + +#include "../fsinfo/fsinfo.h" + +/* + * Lots of ways of reporting errors... + */ +void error(s, s1, s2, s3, s4) +char *s, *s1, *s2, *s3, *s4; +{ + col_cleanup(0); + fprintf(stderr, "%s: Error, ", progname); + fprintf(stderr, s, s1, s2, s3, s4); + fputc('\n', stderr); + errors++; +} + +void lerror(l, s, s1, s2, s3, s4) +ioloc *l; +char *s, *s1, *s2, *s3, *s4; +{ + col_cleanup(0); + fprintf(stderr, "%s:%d: ", l->i_file, l->i_line); + fprintf(stderr, s, s1, s2, s3, s4); + fputc('\n', stderr); + errors++; +} + +void lwarning(l, s, s1, s2, s3, s4) +ioloc *l; +char *s, *s1, *s2, *s3, *s4; +{ + col_cleanup(0); + fprintf(stderr, "%s:%d: ", l->i_file, l->i_line); + fprintf(stderr, s, s1, s2, s3, s4); + fputc('\n', stderr); + +} + +void fatal(s, s1, s2, s3, s4) +char *s, *s1, *s2, *s3, *s4; +{ + col_cleanup(1); + fprintf(stderr, "%s: Fatal, ", progname); + fprintf(stderr, s, s1, s2, s3, s4); + fputc('\n', stderr); + exit(1); +} + +/* + * Dup a string + */ +char *strdup(s) +char *s; +{ + int len = strlen(s); + char *sp = (char *) xmalloc(len+1); + + bcopy(s, sp, len); + sp[len] = 0; + + return sp; +} + +/* + * Debug log + */ +void log(s, s1, s2, s3, s4) +char *s, *s1, *s2, *s3, *s4; +{ + if (verbose > 0) { + fputc('#', stdout); + fprintf(stdout, "%s: ", progname); + fprintf(stdout, s, s1, s2, s3, s4); + putc('\n', stdout); + } +} + +void info_hdr(ef, info) +FILE *ef; +char *info; +{ + fprintf(ef, "# *** NOTE: This file contains %s info\n", info); +} + +void gen_hdr(ef, hn) +FILE *ef; +char *hn; +{ + fprintf(ef, "# *** NOTE: Only for use on %s\n", hn); +} + +static void make_banner(fp) +FILE *fp; +{ + time_t t = time((time_t*) 0); + char *ctime(), *cp = ctime(&t); + + fprintf(fp, +"\ +# *** This file was automatically generated -- DO NOT EDIT HERE ***\n\ +# \"%s\" run by %s@%s on %s\ +#\n\ +", + progname, username, hostname, cp); +} + +static int show_range = 10; +static int col = 0; +static int total_shown = 0; +static int total_mmm = 8; + +static int col_output(len) +int len; +{ + int wrapped = 0; + col += len; + if (col > 77) { + fputc('\n', stdout); + col = len; + wrapped = 1; + } + return wrapped; +} + +static void show_total() +{ + if (total_mmm != -show_range+1) { + char n[8]; + int len; + if (total_mmm < 0) + fputc('*', stdout); + sprintf(n, "%d", total_shown); + len = strlen(n); + if (col_output(len)) + fputc(' ', stdout); + fputs(n, stdout); fflush(stdout); + total_mmm = -show_range; + } +} + +col_cleanup(eoj) +int eoj; +{ + if (verbose < 0) return; + if (eoj) { + show_total(); + fputs(")]", stdout); + } + if (col) { + fputc('\n', stdout); + col = 0; + } +} + +void show_new(msg) +char *msg; +{ + if (verbose < 0) return; + total_shown++; + if (total_mmm > show_range) { + show_total(); + } else if (total_mmm == 0) { + fputc('*', stdout); fflush(stdout); + col += 1; + } + total_mmm++; +} + +void show_area_being_processed(area, n) +char *area; +int n; +{ +static char *last_area = 0; + if (verbose < 0) return; + if (last_area) { + if (total_shown) + show_total(); + fputs(")", stdout); + col += 1; + } + if (!last_area || strcmp(area, last_area) != 0) { + if (last_area) { + col_cleanup(0); + total_shown = 0; + total_mmm = show_range+1; + } + (void) col_output(strlen(area)+2); + fprintf(stdout, "[%s", area); + last_area = area; + } + + fputs(" (", stdout); + col += 2; + show_range = n; + total_mmm = n + 1; + + fflush(stdout); +} + +/* + * Open a file with the given prefix and name + */ +FILE *pref_open(pref, hn, hdr, arg) +char *pref; +char *hn; +void (*hdr)(); +char *arg; +{ + char p[MAXPATHLEN]; + FILE *ef; + sprintf(p, "%s%s", pref, hn); + log("Writing %s info for %s to %s", pref, hn, p); + ef = fopen(p, "w"); + if (ef) { + (*hdr)(ef, arg); + make_banner(ef, hn); + } else { + error("can't open %s for writing", p); + } + + return ef; +} + +int pref_close(fp) +FILE *fp; +{ + return fclose(fp) == 0; +} + +/* + * Determine where Amd would automount the host/volname pair + */ +void compute_automount_point(buf, hp, vn) +char *buf; +host *hp; +char *vn; +{ +#ifdef AMD_USES_HOSTPATH + sprintf(buf, "%s/%s%s", autodir, hp->h_hostpath, vn); +#else + sprintf(buf, "%s/%s%s", autodir, hp->h_lochost, vn); +#endif +} + +char *xcalloc(i, s) +int i; +int s; +{ + char *p = (char *) calloc(i, (unsigned) s); + if (!p) + fatal("Out of memory"); + return p; +} + +char *xmalloc(i) +int i; +{ + char *p = (char *) malloc(i); + if (!p) + fatal("Out of memory"); + return p; +} + +/* + * Data constructors.. + */ + +automount *new_automount(name) +char *name; +{ + automount *ap = ALLOC(automount); + ap->a_ioloc = current_location(); + ap->a_name = name; + ap->a_volname = 0; + ap->a_mount = 0; + show_new("automount"); + return ap; +} + +auto_tree *new_auto_tree(def, ap) +char *def; +qelem *ap; +{ + auto_tree *tp = ALLOC(auto_tree); + tp->t_ioloc = current_location(); + tp->t_defaults = def; + tp->t_mount = ap; + show_new("auto_tree"); + return tp; +} + +host *new_host() +{ + host *hp = ALLOC(host); + hp->h_ioloc = current_location(); + hp->h_mask = 0; + show_new("host"); + return hp; +} + +void set_host(hp, k, v) +host *hp; +int k; +char *v; +{ + int m = 1 << k; + if (hp->h_mask & m) { + yyerror("host field \"%s\" already set", host_strings[k]); + return; + } + + hp->h_mask |= m; + + switch (k) { + case HF_HOST: { + char *p = strdup(v); + dict_ent *de = dict_locate(dict_of_hosts, v); + if (de) + yyerror("duplicate host %s!", v); + else + dict_add(dict_of_hosts, v, (char *) hp); + hp->h_hostname = v; + domain_strip(p, hostname); + if (strchr(p, '.') != 0) + free(p); + else + hp->h_lochost = p; + } break; + case HF_CONFIG: { + qelem *q; + qelem *vq = (qelem *) v; + hp->h_mask &= ~m; + if (hp->h_config) + q = hp->h_config; + else + q = hp->h_config = new_que(); + ins_que(vq, q->q_back); + } break; + case HF_ETHER: { + qelem *q; + qelem *vq = (qelem *) v; + hp->h_mask &= ~m; + if (hp->h_ether) + q = hp->h_ether; + else + q = hp->h_ether = new_que(); + ins_que(vq, q->q_back); + } break; + case HF_ARCH: hp->h_arch = v; break; + case HF_OS: hp->h_os = v; break; + case HF_CLUSTER: hp->h_cluster = v; break; + default: abort(); break; + } +} + +ether_if *new_ether_if() +{ + ether_if *ep = ALLOC(ether_if); + ep->e_mask = 0; + ep->e_ioloc = current_location(); + show_new("ether_if"); + return ep; +} + +void set_ether_if(ep,k, v) +ether_if *ep; +int k; +char *v; +{ + int m = 1 << k; + if (ep->e_mask & m) { + yyerror("netif field \"%s\" already set", ether_if_strings[k]); + return; + } + + ep->e_mask |= m; + + switch (k) { + case EF_INADDR: { + extern u_long inet_addr(); + ep->e_inaddr.s_addr = inet_addr(v); + if (ep->e_inaddr.s_addr == (u_long) -1) + yyerror("malformed IP dotted quad: %s", v); + free(v); + } break; + case EF_NETMASK: { + u_long nm = 0; + if ((sscanf(v, "0x%lx", &nm) == 1 || sscanf(v, "%lx", &nm) == 1) && nm != 0) + ep->e_netmask = htonl(nm); + else + yyerror("malformed netmask: %s", v); + free(v); + } break; + case EF_HWADDR: + ep->e_hwaddr = v; + break; + default: abort(); break; + } +} + +void set_disk_fs(dp, k, v) +disk_fs *dp; +int k; +char *v; +{ + int m = 1 << k; + if (dp->d_mask & m) { + yyerror("fs field \"%s\" already set", disk_fs_strings[k]); + return; + } + + dp->d_mask |= m; + + switch (k) { + case DF_FSTYPE: dp->d_fstype = v; break; + case DF_OPTS: dp->d_opts = v; break; + case DF_DUMPSET: dp->d_dumpset = v; break; + case DF_LOG: dp->d_log = v; break; + case DF_PASSNO: dp->d_passno = atoi(v); free(v); break; + case DF_FREQ: dp->d_freq = atoi(v); free(v); break; + case DF_MOUNT: dp->d_mount = &((mount *) v)->m_q; break; + default: abort(); break; + } +} + +disk_fs *new_disk_fs() +{ + disk_fs *dp = ALLOC(disk_fs); + dp->d_ioloc = current_location(); + show_new("disk_fs"); + return dp; +} + +void set_mount(mp, k, v) +mount *mp; +int k; +char *v; +{ + int m = 1 << k; + if (mp->m_mask & m) { + yyerror("mount tree field \"%s\" already set", mount_strings[k]); + return; + } + + mp->m_mask |= m; + + switch (k) { + case DM_VOLNAME: + dict_add(dict_of_volnames, v, (char *) mp); + mp->m_volname = v; + break; + case DM_EXPORTFS: + mp->m_exportfs = v; + break; + case DM_SEL: + mp->m_sel = v; + break; + default: abort(); break; + } +} + +mount *new_mount() +{ + mount *fp = ALLOC(mount); + fp->m_ioloc = current_location(); + show_new("mount"); + return fp; +} + +void set_fsmount(fp, k, v) +fsmount *fp; +int k; +char *v; +{ + int m = 1 << k; + if (fp->f_mask & m) { + yyerror("mount field \"%s\" already set", fsmount_strings[k]); + return; + } + + fp->f_mask |= m; + + switch (k) { + case FM_LOCALNAME: fp->f_localname = v; break; + case FM_VOLNAME: fp->f_volname = v; break; + case FM_FSTYPE: fp->f_fstype = v; break; + case FM_OPTS: fp->f_opts = v; break; + case FM_FROM: fp->f_from = v; break; + default: abort(); break; + } +} + +fsmount *new_fsmount() +{ + fsmount *fp = ALLOC(fsmount); + fp->f_ioloc = current_location(); + show_new("fsmount"); + return fp; +} + +void init_que(q) +qelem *q; +{ + q->q_forw = q->q_back = q; +} + +qelem *new_que() +{ + qelem *q = ALLOC(qelem); + init_que(q); + return q; +} + +void ins_que(elem, pred) +qelem *elem, *pred; +{ + qelem *p; + p = pred->q_forw; + elem->q_back = pred; + elem->q_forw = p; + pred->q_forw = elem; + p->q_back = elem; +} + +void rem_que(elem) +qelem *elem; +{ + qelem *p, *p2; + p = elem->q_forw; + p2 = elem->q_back; + + p2->q_forw = p; + p->q_back = p2; +} diff --git a/usr.sbin/amd/fsinfo/fsinfo.8 b/usr.sbin/amd/fsinfo/fsinfo.8 new file mode 100644 index 0000000..34db7c2 --- /dev/null +++ b/usr.sbin/amd/fsinfo/fsinfo.8 @@ -0,0 +1,77 @@ +.\" Copyright (c) 1993 Jan-Simon Pendry. +.\" 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. +.\" +.\" @(#)fsinfo.8 8.1 (Berkeley) 6/28/93 +.\" +.Dd June 28, 1993 +.Dt FSINFO 8 +.Os +.Sh NAME +.Nm fsinfo +.Nd co-ordinate site-wide filesystem information +.Sh SYNOPSIS +.Nm \&fsinfo +.Op Fl v +.Op Fl a Ar autodir +.Op Fl b Ar bootparams +.Op Fl d Ar dumpsets +.Op Fl e Ar exports +.Op Fl f Ar fstabs +.Op Fl h Ar hostname +.Op Fl m Ar automounts +.Op Fl I Ar dir +.Op Fl D Ar string[=string]] +.Op Fl U Ar string[=string]] +.Ar config ... +.Sh DESCRIPTION +The +.Nm fsinfo +utility takes a set of system configuration information, and generates +a co-ordinated set of +.Xr amd , +.Xr mount +and +.Xr mountd +configuration files. +.Pp +The +.Nm fsinfo +command is fully described in the document +.%T "Amd - The 4.4BSD Automounter" +.Sh "SEE ALSO" +.Xr amd 8 , +.Xr mount 8 , +.Xr mountd 8 . +.Sh HISTORY +The +.Nm fsinfo +command first appeared in 4.4BSD. diff --git a/usr.sbin/amd/fsinfo/fsinfo.c b/usr.sbin/amd/fsinfo/fsinfo.c new file mode 100644 index 0000000..a4b867b --- /dev/null +++ b/usr.sbin/amd/fsinfo/fsinfo.c @@ -0,0 +1,275 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)fsinfo.c 8.1 (Berkeley) 6/6/93 + * + * $Id: fsinfo.c,v 5.2.2.1 1992/02/09 15:09:33 jsp beta $ + * + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1989, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +/* + * fsinfo + */ + +#include "../fsinfo/fsinfo.h" +#include "fsi_gram.h" +#include + +qelem *list_of_hosts; +qelem *list_of_automounts; +dict *dict_of_volnames; +dict *dict_of_hosts; +char *autodir = "/a"; +char hostname[MAXHOSTNAMELEN+1]; +char *username; +int file_io_errors; +int parse_errors; +int errors; +int verbose; +char idvbuf[1024]; + +char **g_argv; +char *progname; + +/* + * Output file prefixes + */ +char *exportfs_pref; +char *fstab_pref; +char *dumpset_pref; +char *mount_pref; +char *bootparams_pref; + +/* + * Argument cracking... + */ +static void get_args(c, v) +int c; +char *v[]; +{ + extern char *optarg; + extern int optind; + int ch; + int usage = 0; + char *iptr = idvbuf; + + /* + * Determine program name + */ + if (v[0]) { + progname = strrchr(v[0], '/'); + if (progname && progname[1]) + progname++; + else + progname = v[0]; + } + if (!progname) + progname = "fsinfo"; + + while ((ch = getopt(c, v, "a:b:d:e:f:h:m:D:U:I:qv")) != EOF) + switch (ch) { + case 'a': + autodir = optarg; + break; + case 'b': + if (bootparams_pref) + fatal("-b option specified twice"); + bootparams_pref = optarg; + break; + case 'd': + if (dumpset_pref) + fatal("-d option specified twice"); + dumpset_pref = optarg; + break; + case 'h': + strncpy(hostname, optarg, sizeof(hostname)-1); + break; + case 'e': + if (exportfs_pref) + fatal("-e option specified twice"); + exportfs_pref = optarg; + break; + case 'f': + if (fstab_pref) + fatal("-f option specified twice"); + fstab_pref = optarg; + break; + case 'm': + if (mount_pref) + fatal("-m option specified twice"); + mount_pref = optarg; + break; + case 'q': + verbose = -1; + break; + case 'v': + verbose = 1; + break; + case 'I': case 'D': case 'U': + sprintf(iptr, "-%c%s ", ch, optarg); + iptr += strlen(iptr); + break; + default: + usage++; + break; + } + + if (c != optind) { + g_argv = v + optind - 1; + if (yywrap()) + fatal("Cannot read any input files"); + } else { + usage++; + } + + if (usage) { + fprintf(stderr, +"\ +Usage: %s [-v] [-a autodir] [-h hostname] [-b bootparams] [-d dumpsets]\n\ +\t[-e exports] [-f fstabs] [-m automounts]\n\ +\t[-I dir] [-D|-U string[=string]] config ...\n", progname); + exit(1); + } + + + if (g_argv[0]) + log("g_argv[0] = %s", g_argv[0]); + else + log("g_argv[0] = (nil)"); +} + +/* + * Determine username of caller + */ +static char *find_username() +{ + extern char *getlogin(); + extern char *getenv(); + char *u = getlogin(); + if (!u) { + struct passwd *pw = getpwuid(getuid()); + if (pw) + u = pw->pw_name; + } + if (!u) + u = getenv("USER"); + if (!u) + u = getenv("LOGNAME"); + if (!u) + u = "root"; + + return strdup(u); +} + +/* + * MAIN + */ +main(argc, argv) +int argc; +char *argv[]; +{ + /* + * Process arguments + */ + get_args(argc, argv); + + /* + * If no hostname given then use the local name + */ + if (!*hostname && gethostname(hostname, sizeof(hostname)) < 0) { + perror("gethostname"); + exit(1); + } + + /* + * Get the username + */ + username = find_username(); + + /* + * New hosts and automounts + */ + list_of_hosts = new_que(); + list_of_automounts = new_que(); + + /* + * New dictionaries + */ + dict_of_volnames = new_dict(); + dict_of_hosts = new_dict(); + + /* + * Parse input + */ + show_area_being_processed("read config", 11); + if (yyparse()) + errors = 1; + errors += file_io_errors + parse_errors; + + if (errors == 0) { + /* + * Do semantic analysis of input + */ + analyze_hosts(list_of_hosts); + analyze_automounts(list_of_automounts); + } + + /* + * Give up if errors + */ + if (errors == 0) { + /* + * Output data files + */ + + write_atab(list_of_automounts); + write_bootparams(list_of_hosts); + write_dumpset(list_of_hosts); + write_exportfs(list_of_hosts); + write_fstab(list_of_hosts); + } + + col_cleanup(1); + + exit(errors); +} diff --git a/usr.sbin/amd/fsinfo/fsinfo.h b/usr.sbin/amd/fsinfo/fsinfo.h new file mode 100644 index 0000000..0d07e21 --- /dev/null +++ b/usr.sbin/amd/fsinfo/fsinfo.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)fsinfo.h 8.1 (Berkeley) 6/6/93 + * + * $Id: fsinfo.h,v 5.2.2.1 1992/02/09 15:09:51 jsp beta $ + * + */ + +/* + * Get this in now so that OS_HDR can use it + */ +#ifdef __STDC__ +#define P(x) x +#define P_void void +#define Const const +#else +#define P(x) () +#define P_void /* as nothing */ +#define Const /* as nothing */ +#endif /* __STDC__ */ + +#ifdef __GNUC__ +#define INLINE /* __inline */ +#else +#define INLINE +#endif /* __GNUC__ */ + +/* + * Pick up target dependent definitions + */ +#include "os-defaults.h" +#include OS_HDR + +#ifdef VOIDP +typedef void *voidp; +#else +typedef char *voidp; +#endif /* VOIDP */ + +#include +#include +#include + +/* + * Bogosity to deal with ether { ... } + */ +#include +#include +#include +#include + +#include "fsi_data.h" + +extern char* strchr P((Const char*, int)); /* C */ +extern char* strrchr P((Const char*, int)); /* C */ +extern char *strdup P((char*)); /* C */ +extern void fatal(); +extern void warning(); +extern void error(); +extern void analyze_automounts P((qelem*)); +extern void analyze_hosts P((qelem*)); +extern void compute_automount_point P((char*, host*, char*)); +extern automount *new_automount P((char*)); +extern auto_tree *new_auto_tree P((char*, qelem*)); +extern host *new_host P((void)); +extern disk_fs *new_disk_fs P((void)); +extern void set_disk_fs P((disk_fs*, int, char*)); +extern ether_if *new_ether_if P((void)); +extern mount *new_mount P((void)); +extern void set_mount P((mount*, int, char*)); +extern fsmount *new_fsmount P((void)); +extern void set_fsmount P((fsmount*, int, char*)); +extern qelem *new_que P((void)); +extern void init_que P((qelem*)); +extern void ins_que P((qelem*, qelem*)); +extern void rem_que P((qelem*)); +extern dict *new_dict P((void)); +extern dict_ent *dict_locate P((dict*, char*)); +extern void dict_add P((dict*, char*, char*)); +extern int dict_iter P((dict*, int (*)())); +extern void info_hdr(); +extern void gen_hdr(); +extern FILE *pref_open(); +extern int pref_close(); +extern ioloc *current_location(); + +extern char *disk_fs_strings[]; +extern char *mount_strings[]; +extern char *fsmount_strings[]; +extern char *host_strings[]; +extern char *ether_if_strings[]; +extern char *autodir; +extern char *progname; +extern char hostname[]; +extern char *username; +extern char **g_argv; +extern char *fstab_pref; +extern char *exportfs_pref; +extern char *mount_pref; +extern char *dumpset_pref; +extern char *bootparams_pref; +extern char idvbuf[]; + +extern int file_io_errors; +extern int parse_errors; +extern int errors; +extern int verbose; + +extern dict *dict_of_hosts; +extern dict *dict_of_volnames; + +extern char *xcalloc(); +extern char *xmalloc(); +#define ALLOC(x) ((struct x *) xcalloc(1, sizeof(struct x))) +#define STREQ(s,t) (*(s) == *(t) && strcmp((s)+1,(t)+1) == 0) +#define ISSET(m,b) ((m) & (1<<(b))) +#define BITSET(m,b) ((m) |= (1<<(b))) + +#define FIRST(ty, q) ((ty *) ((q)->q_forw)) +#define LAST(ty, q) ((ty *) ((q)->q_back)) +#define NEXT(ty, q) ((ty *) (((qelem *) q)->q_forw)) +#define HEAD(ty, q) ((ty *) q) +#define ITER(v, ty, q) \ + for ((v) = FIRST(ty,(q)); (v) != HEAD(ty,(q)); (v) = NEXT(ty,(v))) diff --git a/usr.sbin/amd/fsinfo/wr_atab.c b/usr.sbin/amd/fsinfo/wr_atab.c new file mode 100644 index 0000000..3e07965 --- /dev/null +++ b/usr.sbin/amd/fsinfo/wr_atab.c @@ -0,0 +1,284 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)wr_atab.c 8.1 (Berkeley) 6/6/93 + * + * $Id: wr_atab.c,v 5.2.2.1 1992/02/09 15:09:44 jsp beta $ + * + */ + +#include "../fsinfo/fsinfo.h" + +/* + * Write a sequence of automount mount map entries + */ +static int write_amount_info(af, ap, sk) +FILE *af; +automount *ap; +int sk; +{ + int errors = 0; + if (ap->a_mount) { + /* + * A pseudo-directory. + * This can also be a top-level directory, in which + * case the type:=auto is not wanted... + * + * type:=auto;fs:=${map};pref:=whatever/ + */ + automount *ap2; + if (strlen(ap->a_name) > sk) { + fprintf(af, "%s type:=auto;fs:=${map};pref:=%s/\n", + ap->a_name + sk, ap->a_name + sk); + } + ITER(ap2, automount, ap->a_mount) + errors += write_amount_info(af, ap2, sk); + } else if (ap->a_mounted) { + /* + * A mounted partition + * type:=link [ link entries ] type:=nfs [ nfs entries ] + */ + dict_data *dd; + dict_ent *de = ap->a_mounted; + int done_type_link = 0; + char *key = ap->a_name + sk; + + /* + * Output the map key + */ + fputs(key, af); + + /* + * First output any Link locations that would not + * otherwise be correctly mounted. These refer + * to filesystem which are not mounted in the same + * place which the automounter would use. + */ + ITER(dd, dict_data, &de->de_q) { + mount *mp = (mount *) dd->dd_data; + /* + * If the mount point and the exported volname are the + * same then this filesystem will be recognised by + * the restart code - so we don't need to put out a + * special rule for it. + */ + if (mp->m_dk->d_host->h_lochost) { + char amountpt[1024]; + compute_automount_point(amountpt, mp->m_dk->d_host, mp->m_exported->m_volname); + if (strcmp(mp->m_dk->d_mountpt, amountpt) != 0) { + /* + * ap->a_volname is the name of the aliased volume + * mp->m_name is the mount point of the filesystem + * mp->m_volname is the volume name of the filesystems + */ + + /* + * Find length of key and volume names + */ + int avlen = strlen(ap->a_volname); + int mnlen = strlen(mp->m_volname); + /* + * Make sure a -type:=link is output once + */ + if (!done_type_link) { + done_type_link = 1; + fputs(" -type:=link", af); + } + /* + * Output a selector for the hostname, + * the device from which to mount and + * where to mount. This will correspond + * to the values output for the fstab. + */ + if (mp->m_dk->d_host->h_lochost) + fprintf(af, " host==%s", mp->m_dk->d_host->h_lochost); + else + fprintf(af, " hostd==%s", mp->m_dk->d_host->h_hostname); + fprintf(af, ";fs:=%s", mp->m_name); + /* + * ... and a sublink if needed + */ + if (mnlen < avlen) { + char *sublink = ap->a_volname + mnlen + 1; + fprintf(af, "/%s", sublink); + } + fputs(" ||", af); + } + } + } + + /* + * Next do the NFS locations + */ + + if (done_type_link) + fputs(" -", af); + + ITER(dd, dict_data, &de->de_q) { + mount *mp = (mount *) dd->dd_data; + int namelen = mp->m_name_len; + int exp_namelen = mp->m_exported->m_name_len; + int volnlen = strlen(ap->a_volname); + int mvolnlen = strlen(mp->m_volname); + fputc(' ', af); +#ifdef notdef + fprintf(af, "\\\n /* avolname = %s, mname = %s,\n * mvolname = %s, mexp_name = %s,\n * mexp_volname = %s\n */\\\n", + ap->a_volname, mp->m_name, mp->m_volname, mp->m_exported->m_name, mp->m_exported->m_volname); +#endif + /* + * Output any selectors + */ + if (mp->m_sel) + fprintf(af, "%s;", mp->m_sel); + /* + * Print host and volname of exported filesystem + */ + fprintf(af, "rhost:=%s", + mp->m_dk->d_host->h_lochost ? + mp->m_dk->d_host->h_lochost : + mp->m_dk->d_host->h_hostname); + fprintf(af, ";rfs:=%s", mp->m_exported->m_volname); + /* + * Now determine whether a sublink is required. + */ + if (exp_namelen < namelen || mvolnlen < volnlen) { + char sublink[1024]; + sublink[0] = '\0'; + if (exp_namelen < namelen) { + strcat(sublink, mp->m_name + exp_namelen + 1); + if (mvolnlen < volnlen) + strcat(sublink, "/"); + } + if (mvolnlen < volnlen) + strcat(sublink, ap->a_volname + mvolnlen + 1); + + fprintf(af, ";sublink:=%s", sublink); + } + } + fputc('\n', af); + } else if (ap->a_symlink) { + /* + * A specific link. + * + * type:=link;fs:=whatever + */ + fprintf(af, "%s type:=link;fs:=%s\n", ap->a_name + sk, ap->a_symlink); + } + return errors; +} + +/* + * Write a single automount configuration file + */ +static int write_amount(q, def) +qelem *q; +char *def; +{ + automount *ap; + int errors = 0; + int direct = 0; + + /* + * Output all indirect maps + */ + ITER(ap, automount, q) { + FILE *af; + char *p; + /* + * If there is no a_mount node then this is really + * a direct mount, so just keep a count and continue. + * Direct mounts are output into a special file during + * the second pass below. + */ + if (!ap->a_mount) { + direct++; + continue; + } + p = strrchr(ap->a_name, '/'); + if (!p) p = ap->a_name; + else p++; + af = pref_open(mount_pref, p, gen_hdr, ap->a_name); + if (af) { + show_new(ap->a_name); + fputs("/defaults ", af); + if (*def) + fprintf(af, "%s;", def); + fputs("type:=nfs\n", af); + errors += write_amount_info(af, ap, strlen(ap->a_name) + 1); + errors += pref_close(af); + } + } + + /* + * Output any direct map entries which were found during the + * previous pass over the data. + */ + if (direct) { + FILE *af = pref_open(mount_pref, "direct.map", info_hdr, "direct mount"); + if (af) { + show_new("direct mounts"); + fputs("/defaults ", af); + if (*def) + fprintf(af, "%s;", def); + fputs("type:=nfs\n", af); + ITER(ap, automount, q) + if (!ap->a_mount) + errors += write_amount_info(af, ap, 1); + errors += pref_close(af); + } + } + + return errors; +} + +/* + * Write all the needed automount configuration files + */ +write_atab(q) +qelem *q; +{ + int errors = 0; + + if (mount_pref) { + auto_tree *tp; + show_area_being_processed("write automount", ""); + ITER(tp, auto_tree, q) + errors += write_amount(tp->t_mount, tp->t_defaults); + } + + return errors; +} diff --git a/usr.sbin/amd/fsinfo/wr_bparam.c b/usr.sbin/amd/fsinfo/wr_bparam.c new file mode 100644 index 0000000..9ef0fcd --- /dev/null +++ b/usr.sbin/amd/fsinfo/wr_bparam.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)wr_bparam.c 8.1 (Berkeley) 6/6/93 + * + * $Id: wr_bparam.c,v 5.2.2.1 1992/02/09 15:09:46 jsp beta $ + * + */ + +#include "../fsinfo/fsinfo.h" + +/* + * Write a host/path in NFS format + */ +static int write_nfsname(ef, fp, hn) +FILE *ef; +fsmount *fp; +char *hn; +{ + int errors = 0; + char *h = strdup(fp->f_ref->m_dk->d_host->h_hostname); + domain_strip(h, hn); + fprintf(ef, "%s:%s", h, fp->f_volname); + free(h); + return errors; +} + +/* + * Write a bootparams entry for a host + */ +static int write_boot_info(ef, hp) +FILE *ef; +host *hp; +{ + int errors = 0; + fprintf(ef, "%s\troot=", hp->h_hostname); + errors += write_nfsname(ef, hp->h_netroot, hp->h_hostname); + fputs(" swap=", ef); + errors += write_nfsname(ef, hp->h_netswap, hp->h_hostname); + fputs("\n", ef); + + return 0; +} + +/* + * Output a bootparams file + */ +int write_bootparams(q) +qelem *q; +{ + int errors = 0; + + if (bootparams_pref) { + FILE *ef = pref_open(bootparams_pref, "bootparams", info_hdr, "bootparams"); + if (ef) { + host *hp; + ITER(hp, host, q) + if (hp->h_netroot && hp->h_netswap) + errors += write_boot_info(ef, hp); + errors += pref_close(ef); + } else { + errors++; + } + } + + return errors; +} diff --git a/usr.sbin/amd/fsinfo/wr_dumpset.c b/usr.sbin/amd/fsinfo/wr_dumpset.c new file mode 100644 index 0000000..d118feb --- /dev/null +++ b/usr.sbin/amd/fsinfo/wr_dumpset.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)wr_dumpset.c 8.1 (Berkeley) 6/6/93 + * + * $Id: wr_dumpset.c,v 5.2.2.1 1992/02/09 15:09:47 jsp beta $ + * + */ + +#include "../fsinfo/fsinfo.h" + +static int write_dumpset_info(ef, q) +FILE *ef; +qelem *q; +{ + int errors = 0; + disk_fs *dp; + + ITER(dp, disk_fs, q) { + if (dp->d_dumpset) { + fprintf(ef, "%s\t%s:%-30s\t# %s\n", + dp->d_dumpset, + dp->d_host->h_lochost ? + dp->d_host->h_lochost : + dp->d_host->h_hostname, + dp->d_mountpt, + dp->d_dev); + } + } + return errors; +} + +int write_dumpset(q) +qelem *q; +{ + int errors = 0; + + if (dumpset_pref) { + FILE *ef = pref_open(dumpset_pref, "dumpsets", info_hdr, "exabyte dumpset"); + if (ef) { + host *hp; + ITER(hp, host, q) { + if (hp->h_disk_fs) { + errors += write_dumpset_info(ef, hp->h_disk_fs); + } + } + errors += pref_close(ef); + } else { + errors++; + } + } + + return errors; +} diff --git a/usr.sbin/amd/fsinfo/wr_exportfs.c b/usr.sbin/amd/fsinfo/wr_exportfs.c new file mode 100644 index 0000000..982b538f --- /dev/null +++ b/usr.sbin/amd/fsinfo/wr_exportfs.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)wr_exportfs.c 8.1 (Berkeley) 6/6/93 + * + * $Id: wr_exportfs.c,v 5.2.2.1 1992/02/09 15:09:48 jsp beta $ + * + */ + +#include "../fsinfo/fsinfo.h" + +static int write_export_info(ef, q, errors) +FILE *ef; +qelem *q; +int errors; +{ + mount *mp; + + ITER(mp, mount, q) { + if (mp->m_mask & (1<m_volname, mp->m_exportfs); + if (mp->m_mount) + errors += write_export_info(ef, mp->m_mount, 0); + } + + return errors; +} + +static int write_dkexports(ef, q) +FILE *ef; +qelem *q; +{ + int errors = 0; + disk_fs *dp; + + ITER(dp, disk_fs, q) { + if (dp->d_mount) + errors += write_export_info(ef, dp->d_mount, 0); + } + return errors; +} + +int write_exportfs(q) +qelem *q; +{ + int errors = 0; + + if (exportfs_pref) { + host *hp; + show_area_being_processed("write exportfs", ""); + ITER(hp, host, q) { + if (hp->h_disk_fs) { + FILE *ef = pref_open(exportfs_pref, hp->h_hostname, gen_hdr, hp->h_hostname); + if (ef) { + show_new(hp->h_hostname); + errors += write_dkexports(ef, hp->h_disk_fs); + errors += pref_close(ef); + } else { + errors++; + } + } + } + } + + return errors; +} diff --git a/usr.sbin/amd/fsinfo/wr_fstab.c b/usr.sbin/amd/fsinfo/wr_fstab.c new file mode 100644 index 0000000..85d3687 --- /dev/null +++ b/usr.sbin/amd/fsinfo/wr_fstab.c @@ -0,0 +1,303 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)wr_fstab.c 8.1 (Berkeley) 6/6/93 + * + * $Id: wr_fstab.c,v 5.2.2.1 1992/02/09 15:09:49 jsp beta $ + * + */ + +#include "../fsinfo/fsinfo.h" + +/* ---------- AIX 1 ------------------------------ */ + +/* + * AIX 1 format + */ +static void write_aix1_dkfstab(ef, dp) +FILE *ef; +disk_fs *dp; +{ + char *hp = strdup(dp->d_host->h_hostname); + char *p = strchr(hp, '.'); + if (p) + *p = '\0'; + + fprintf(ef, "\n%s:\n\tdev = %s\n\tvfs = %s\n\ttype = %s\n\tlog = %s\n\tvol = %s\n\topts = %s\n\tmount = true\n\tcheck = true\n\tfree = false\n", + dp->d_mountpt, + dp->d_dev, + dp->d_fstype, + dp->d_fstype, + dp->d_log, + dp->d_mountpt, + dp->d_opts); + free(hp); +} + +static void write_aix1_dkrmount(ef, hn, fp) +FILE *ef; +char *hn; +fsmount *fp; +{ + char *h = strdup(fp->f_ref->m_dk->d_host->h_hostname); + char *hp = strdup(h); + char *p = strchr(hp, '.'); + if (p) + *p = '\0'; + domain_strip(h, hn); + fprintf(ef, "\n%s:\n\tsite = %s\n\tdev = %s:%s\n\tvfs = %s\n\ttype = %s\n\tvol = %s\n\topts = %s\n\tmount = true\n\tcheck = true\n\tfree = false\n", + fp->f_localname, + hp, + h, + fp->f_volname, + fp->f_fstype, + fp->f_fstype, + fp->f_localname, + fp->f_opts); + + free(hp); + free(h); +} + +/* ---------- AIX 3 ------------------------------ */ + +/* + * AIX 3 format + */ +static void write_aix3_dkfstab(ef, dp) +FILE *ef; +disk_fs *dp; +{ + if (strcmp(dp->d_fstype, "jfs") == 0 && strncmp(dp->d_dev, "/dev/", 5) == 0 && !dp->d_log) + error("aix 3 needs a log device for journalled filesystem (jfs) mounts"); + + fprintf(ef, "\n%s:\n\tdev = %s\n\tvfs = %s\n\ttype = %s\n\tlog = %s\n\tvol = %s\n\topts = %s\n\tmount = true\n\tcheck = true\n\tfree = false\n", + dp->d_mountpt, + dp->d_dev, + dp->d_fstype, + dp->d_fstype, + dp->d_log, + dp->d_mountpt, + dp->d_opts); +} + +static void write_aix3_dkrmount(ef, hn, fp) +FILE *ef; +char *hn; +fsmount *fp; +{ + char *h = strdup(fp->f_ref->m_dk->d_host->h_hostname); + domain_strip(h, hn); + fprintf(ef, "\n%s:\n\tdev = %s:%s\n\tvfs = %s\n\ttype = %s\n\tvol = %s\n\topts = %s\n\tmount = true\n\tcheck = true\n\tfree = false\n", + fp->f_localname, + h, + fp->f_volname, + fp->f_fstype, + fp->f_fstype, + fp->f_localname, + fp->f_opts); + + free(h); +} + +/* ---------- Ultrix ----------------------------- */ + +static void write_ultrix_dkfstab(ef, dp) +FILE *ef; +disk_fs *dp; +{ + fprintf(ef, "%s:%s:%s:%s:%d:%d\n", + dp->d_dev, + dp->d_mountpt, + dp->d_fstype, + dp->d_opts, + dp->d_freq, + dp->d_passno); +} + +static void write_ultrix_dkrmount(ef, hn, fp) +FILE *ef; +char *hn; +fsmount *fp; +{ + char *h = strdup(fp->f_ref->m_dk->d_host->h_hostname); + domain_strip(h, hn); + fprintf(ef, "%s@%s:%s:%s:%s:0:0\n", + fp->f_volname, + h, + fp->f_localname, + fp->f_fstype, + fp->f_opts); + free(h); +} + +/* ---------- Generic ---------------------------- */ + +/* + * Generic (BSD, SunOS, HPUX) format + */ +static void write_generic_dkfstab(ef, dp) +FILE *ef; +disk_fs *dp; +{ + fprintf(ef, "%s %s %s %s %d %d\n", + dp->d_dev, + dp->d_mountpt, + dp->d_fstype, + dp->d_opts, + dp->d_freq, + dp->d_passno); +} + +static void write_generic_dkrmount(ef, hn, fp) +FILE *ef; +char *hn; +fsmount *fp; +{ + char *h = strdup(fp->f_ref->m_dk->d_host->h_hostname); + domain_strip(h, hn); + fprintf(ef, "%s:%s %s %s %s 0 0\n", + h, + fp->f_volname, + fp->f_localname, + fp->f_fstype, + fp->f_opts); + free(h); +} + +/* ----------------------------------------------- */ + +static struct os_fstab_type { + char *os_name; + void (*op_fstab)(); + void (*op_mount)(); +} os_tabs[] = { + { "aix1", write_aix1_dkfstab, write_aix1_dkrmount }, /* AIX 1 */ + { "aix3", write_aix3_dkfstab, write_aix3_dkrmount }, /* AIX 3 */ + { "generic", write_generic_dkfstab, write_generic_dkrmount }, /* Generic */ + { "u2_0", write_ultrix_dkfstab, write_ultrix_dkrmount }, /* Ultrix */ + { "u3_0", write_ultrix_dkfstab, write_ultrix_dkrmount }, /* Ultrix */ + { "u4_0", write_ultrix_dkfstab, write_ultrix_dkrmount }, /* Ultrix */ + { 0, 0, 0 } +}; + +#define GENERIC_OS_NAME "generic" + +static struct os_fstab_type *find_fstab_type(hp) +host *hp; +{ + struct os_fstab_type *op = 0; + char *os_name = 0; + +again:; + if (os_name == 0) { + if (ISSET(hp->h_mask, HF_OS)) + os_name = hp->h_os; + else + os_name = GENERIC_OS_NAME; + } + + for (op = os_tabs; op->os_name; op++) + if (strcmp(os_name, op->os_name) == 0) + return op; + + os_name = GENERIC_OS_NAME; + goto again; +} + +static int write_dkfstab(ef, q, output) +FILE *ef; +qelem *q; +void (*output)(); +{ + int errors = 0; + disk_fs *dp; + + ITER(dp, disk_fs, q) + if (strcmp(dp->d_fstype, "export") != 0) + (*output)(ef, dp); + + return errors; +} + +static int write_dkrmount(ef, q, hn, output) +FILE *ef; +qelem *q; +char *hn; +void (*output)(); +{ + int errors = 0; + fsmount *fp; + + ITER(fp, fsmount, q) + (*output)(ef, hn, fp); + + return errors; +} + +int write_fstab(q) +qelem *q; +{ + int errors = 0; + + if (fstab_pref) { + host *hp; + show_area_being_processed("write fstab", 4); + ITER(hp, host, q) { + if (hp->h_disk_fs || hp->h_mount) { + FILE *ef = pref_open(fstab_pref, hp->h_hostname, gen_hdr, hp->h_hostname); + if (ef) { + struct os_fstab_type *op = find_fstab_type(hp); + show_new(hp->h_hostname); + if (hp->h_disk_fs) + errors += write_dkfstab(ef, hp->h_disk_fs, op->op_fstab); + else + log("No local disk mounts on %s", hp->h_hostname); + + if (hp->h_mount) + errors += write_dkrmount(ef, hp->h_mount, hp->h_hostname, op->op_mount); + + pref_close(ef); + } + } else { + error("no disk mounts on %s", hp->h_hostname); + } + } + } + + return errors; +} diff --git a/usr.sbin/amd/include/am.h b/usr.sbin/amd/include/am.h new file mode 100644 index 0000000..14a728d --- /dev/null +++ b/usr.sbin/amd/include/am.h @@ -0,0 +1,567 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)am.h 5.6 (Berkeley) 6/6/93 + * + * $Id: am.h,v 5.2.2.1 1992/02/09 15:09:54 jsp beta $ + * + */ + +#include "config.h" + +/* + * Global declarations + */ +#include +#include +#include +#include "nfs_prot.h" +#ifdef MNTENT_HDR +#include MNTENT_HDR +#endif /* MNTENT_HDR */ +#include + +#ifdef DEBUG_MEM +#include +#endif /* DEBUG_MEM */ + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif /* MAXHOSTNAMELEN */ + +#ifndef MNTTYPE_AUTO +#define MNTTYPE_AUTO "auto" +#endif /* MNTTYPE_AUTO */ + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif /* FALSE */ + +#ifndef ROOT_MAP +#define ROOT_MAP "\"root\"" +#endif /* ROOT_MAP */ + +/* + * Flags from command line + */ +extern int print_pid; /* Print pid to stdout */ +extern int normalize_hosts; /* Normalize host names before use */ +extern int restart_existing_mounts; +#ifdef HAS_NIS_MAPS +extern char *domain; /* NIS domain to use */ +#endif /* HAS_NIS_MAPS */ +extern int am_timeo; /* Cache period */ +extern int afs_timeo; /* AFS timeout */ +extern int afs_retrans; /* AFS retrans */ +extern int am_timeo_w; /* Unmount timeout */ +extern char *mtab; /* Mount table */ + +typedef enum { + Start, + Run, + Finishing, + Quit, + Done +} serv_state; + +extern serv_state amd_state; /* Should we go now */ +extern int immediate_abort; /* Should close-down unmounts be retried */ +extern time_t do_mapc_reload; /* Flush & reload mount map cache */ + +/* + * Useful constants + */ +extern char pid_fsname[]; /* kiska.southseas.nz:(pid%d) */ +extern char hostd[]; /* "kiska.southseas.nz" */ +extern char *hostdomain; /* "southseas.nz" */ +extern char *op_sys; /* "sos4" */ +extern char *arch; /* "sun4" */ +extern char *karch; /* "sun4c" */ +extern char *cluster; /* "r+d-kluster" */ +extern char *endian; /* "big" */ +extern char *auto_dir; /* "/a" */ +extern char copyright[]; /* Copyright info */ +extern char version[]; /* Version info */ + +typedef struct am_ops am_ops; +typedef struct am_node am_node; +typedef struct am_opts am_opts; +typedef struct mntfs mntfs; +typedef struct fserver fserver; +typedef struct fsrvinfo fsrvinfo; + +/* + * Debug defns. + */ +#ifdef DEBUG +#define DEBUG_MTAB "./mtab" + +extern int debug_flags; /* Debug options */ + +#define D_DAEMON 0x0001 /* Enter daemon mode */ +#define D_TRACE 0x0002 /* Do protocol trace */ +#define D_FULL 0x0004 /* Do full trace */ +#define D_MTAB 0x0008 /* Use local mtab */ +#define D_AMQ 0x0010 /* Register amq program */ +#define D_STR 0x0020 /* Debug string munging */ +#define D_MEM 0x0040 /* Trace memory allocations */ + +/* + * Normally, don't enter daemon mode, and don't register amq + */ +#define D_TEST (~(D_DAEMON|D_MEM|D_STR)) +#endif /* DEBUG */ + +/* + * Global variables. + */ +extern unsigned short nfs_port; /* Our NFS service port */ +extern struct in_addr myipaddr; /* (An) IP address of this host */ + +extern int foreground; /* Foreground process */ +extern time_t next_softclock; /* Time to call softclock() */ +extern int task_notify_todo; /* Task notifier needs running */ +#ifdef HAS_TFS +extern int nfs_server_code_available; +#endif /* HAS_TFS */ +extern int last_used_map; /* Last map being used for mounts */ +extern AUTH *nfs_auth; /* Dummy uthorisation for remote servers */ +extern am_node **exported_ap; /* List of nodes */ +extern int first_free_map; /* First free node */ +extern am_node *root_node; /* Node for "root" */ +extern char *wire; /* Name of primary connected network */ +#define NEXP_AP (254) +#define NEXP_AP_MARGIN (128) + +typedef int (*task_fun)P((voidp)); +typedef void (*cb_fun)P((int, int, voidp)); +typedef void (*fwd_fun)P((voidp, int, struct sockaddr_in *, + struct sockaddr_in *, voidp, int)); + +/* + * String comparison macros + */ +#define STREQ(s1, s2) (strcmp((s1), (s2)) == 0) +#define FSTREQ(s1, s2) ((*(s1) == *(s2)) && STREQ((s1),(s2))) + +/* + * Linked list + */ +typedef struct qelem qelem; +struct qelem { + qelem *q_forw; + qelem *q_back; +}; +#define FIRST(ty, q) ((ty *) ((q)->q_forw)) +#define LAST(ty, q) ((ty *) ((q)->q_back)) +#define NEXT(ty, q) ((ty *) (((qelem *) q)->q_forw)) +#define PREV(ty, q) ((ty *) (((qelem *) q)->q_back)) +#define HEAD(ty, q) ((ty *) q) +#define ITER(v, ty, q) \ + for ((v) = FIRST(ty,(q)); (v) != HEAD(ty,(q)); (v) = NEXT(ty,(v))) + +/* + * List of mount table entries + */ +typedef struct mntlist mntlist; +struct mntlist { + struct mntlist *mnext; + struct mntent *mnt; +}; + +/* + * Mount map + */ +typedef struct mnt_map mnt_map; + +/* + * Global routines + */ +extern int atoi P((Const char *)); /* C */ +extern void am_mounted P((am_node*)); +extern void am_unmounted P((am_node*)); +extern int background(P_void); +extern int bind_resv_port P((int, unsigned short*)); +extern int compute_mount_flags P((struct mntent *)); +extern int softclock(P_void); +#ifdef DEBUG +extern int debug_option P((char*)); +#endif /* DEBUG */ +extern void deslashify P((char*)); +/*extern void domain_strip P((char*, char*));*/ +extern mntfs* dup_mntfs P((mntfs*)); +extern fserver* dup_srvr P((fserver*)); +extern int eval_fs_opts P((am_opts*, char*, char*, char*, char*, char*)); +extern char* expand_key P((char*)); +extern am_node* exported_ap_alloc(P_void); +extern am_node* find_ap P((char*)); +extern am_node* find_mf P((mntfs*)); +extern mntfs* find_mntfs P((am_ops*, am_opts*, char*, char*, char*, char*, char*)); +extern void flush_mntfs(P_void); +extern void flush_nfs_fhandle_cache P((fserver*)); +extern void forcibly_timeout_mp P((am_node*)); +extern FREE_RETURN_TYPE free P((voidp)); /* C */ +extern void free_mntfs P((mntfs*)); +extern void free_opts P((am_opts*)); +extern void free_map P((am_node*)); +extern void free_mntlist P((mntlist*)); +extern void free_srvr P((fserver*)); +extern int fwd_init(P_void); +extern int fwd_packet P((int, voidp, int, struct sockaddr_in *, + struct sockaddr_in *, voidp, fwd_fun)); +extern void fwd_reply(P_void); +extern void get_args P((int, char*[])); +extern char *getwire P((void)); +#ifdef NEED_MNTOPT_PARSER +extern char *hasmntopt P((struct mntent*, char*)); +#endif /* NEED_MNTOPT_PARSER */ +extern int hasmntval P((struct mntent*, char*)); +extern void host_normalize P((char **)); +extern char *inet_dquad P((char*, unsigned long)); +extern void init_map P((am_node*, char*)); +extern void insert_am P((am_node*, am_node*)); +extern void ins_que P((qelem*, qelem*)); +extern int islocalnet P((unsigned long)); +extern int make_nfs_auth P((void)); +extern void make_root_node(P_void); +extern int make_rpc_packet P((char*, int, u_long, struct rpc_msg*, voidp, xdrproc_t, AUTH*)); +extern void map_flush_srvr P((fserver*)); +extern void mapc_add_kv P((mnt_map*, char*, char*)); +extern mnt_map* mapc_find P((char*, char*)); +extern void mapc_free P((mnt_map*)); +extern int mapc_keyiter P((mnt_map*, void (*)(char*,voidp), voidp)); +extern int mapc_search P((mnt_map*, char*, char**)); +extern void mapc_reload(P_void); +extern void mapc_showtypes P((FILE*)); +extern int mkdirs P((char*, int)); +extern void mk_fattr P((am_node*, enum ftype)); +extern void mnt_free P((struct mntent*)); +extern int mount_auto_node P((char*, voidp)); +extern int mount_automounter P((int)); +extern int mount_exported(P_void); +extern int mount_fs P((struct mntent*, int, caddr_t, int, MTYPE_TYPE)); +/*extern int mount_nfs_fh P((struct fhstatus*, char*, char*, char*, mntfs*));*/ +extern int mount_node P((am_node*)); +extern mntfs* new_mntfs(P_void); +extern void new_ttl P((am_node*)); +extern am_node* next_map P((int*)); +extern int nfs_srvr_port P((fserver*, u_short*, voidp)); +extern void normalize_slash P((char*)); +extern void ops_showfstypes P((FILE*)); +extern int pickup_rpc_reply P((voidp, int, voidp, xdrproc_t)); +extern mntlist* read_mtab P((char*)); +extern mntfs* realloc_mntfs P((mntfs*, am_ops*, am_opts*, char*, char*, char*, char*, char*)); +extern void rem_que P((qelem*)); +extern void reschedule_timeout_mp(P_void); +extern void restart(P_void); +#ifdef UPDATE_MTAB +extern void rewrite_mtab P((mntlist *)); +#endif /* UPDATE_MTAB */ +extern void rmdirs P((char*)); +extern am_node* root_ap P((char*, int)); +extern int root_keyiter P((void (*)(char*,voidp), voidp)); +extern void root_newmap P((char*, char*, char*)); +extern void rpc_msg_init P((struct rpc_msg*, u_long, u_long, u_long)); +extern void run_task P((task_fun, voidp, cb_fun, voidp)); +extern void sched_task P((cb_fun, voidp, voidp)); +extern void show_rcs_info P((Const char*, char*)); +extern void sigchld P((int)); +extern void srvrlog P((fserver*, char*)); +extern char* str3cat P((char*, char*, char*, char*)); +extern char* strcat P((char*, Const char*)); /* C */ +extern int strcmp P((Const char*, Const char*)); /* C */ +extern char* strdup P((Const char*)); +extern int strlen P((Const char*)); /* C */ +extern char* strnsave P((Const char*, int)); +extern char* strrchr P((Const char*, int)); /* C */ +extern char* strealloc P((char*, char *)); +extern char** strsplit P((char*, int, int)); +extern int switch_option P((char*)); +extern int switch_to_logfile P((char*)); +extern void do_task_notify(P_void); +extern int timeout P((unsigned int, void (*fn)(), voidp)); +extern void timeout_mp(P_void); +extern void umount_exported(P_void); +extern int umount_fs P((char*)); +/*extern int unmount_node P((am_node*)); +extern int unmount_node_wrap P((voidp));*/ +extern void unregister_amq(P_void); +extern void untimeout P((int)); +extern int valid_key P((char*)); +extern void wakeup P((voidp)); +extern void wakeup_task P((int,int,voidp)); +extern void wakeup_srvr P((fserver*)); +extern void write_mntent P((struct mntent*)); +#ifdef UPDATE_MTAB +extern void unlock_mntlist P((void)); +#else +#define unlock_mntlist() +#endif /* UPDATE_MTAB */ + + +#define ALLOC(ty) ((struct ty *) xmalloc(sizeof(struct ty))) + +/* + * Options + */ +struct am_opts { + char *fs_glob; /* Smashed copy of global options */ + char *fs_local; /* Expanded copy of local options */ + char *fs_mtab; /* Mount table entry */ + /* Other options ... */ + char *opt_dev; + char *opt_delay; + char *opt_dir; + char *opt_fs; + char *opt_group; + char *opt_mount; + char *opt_opts; + char *opt_remopts; + char *opt_pref; + char *opt_cache; + char *opt_rfs; + char *opt_rhost; + char *opt_sublink; + char *opt_type; + char *opt_unmount; + char *opt_user; +}; + +/* + * File Handle + * + * This is interpreted by indexing the exported array + * by fhh_id. + * + * The whole structure is mapped onto a standard fhandle_t + * when transmitted. + */ +struct am_fh { + int fhh_pid; /* process id */ + int fhh_id; /* map id */ + int fhh_gen; /* generation number */ +}; + +extern am_node *fh_to_mp P((nfs_fh*)); +extern am_node *fh_to_mp3 P((nfs_fh*,int*,int)); +extern void mp_to_fh P((am_node*, nfs_fh*)); +#define fh_to_mp2(fhp, rp) fh_to_mp3(fhp, rp, VLOOK_CREATE) +extern int auto_fmount P((am_node *mp)); +extern int auto_fumount P((am_node *mp)); + +#define MAX_READDIR_ENTRIES 16 + +typedef char* (*vfs_match)P((am_opts*)); +typedef int (*vfs_init)P((mntfs*)); +typedef int (*vmount_fs)P((am_node*)); +typedef int (*vfmount_fs)P((mntfs*)); +typedef int (*vumount_fs)P((am_node*)); +typedef int (*vfumount_fs)P((mntfs*)); +typedef am_node*(*vlookuppn)P((am_node*, char*, int*, int)); +typedef int (*vreaddir)P((am_node*, nfscookie, dirlist*, entry*, int)); +typedef am_node*(*vreadlink)P((am_node*, int*)); +typedef void (*vmounted)P((mntfs*)); +typedef void (*vumounted)P((am_node*)); +typedef fserver*(*vffserver)P((mntfs*)); + +struct am_ops { + char *fs_type; + vfs_match fs_match; + vfs_init fs_init; + vmount_fs mount_fs; + vfmount_fs fmount_fs; + vumount_fs umount_fs; + vfumount_fs fumount_fs; + vlookuppn lookuppn; + vreaddir readdir; + vreadlink readlink; + vmounted mounted; + vumounted umounted; + vffserver ffserver; + int fs_flags; +}; +extern am_node *efs_lookuppn P((am_node*, char*, int*, int)); +extern int efs_readdir P((am_node*, nfscookie, dirlist*, entry*, int)); + +#define VLOOK_CREATE 0x1 +#define VLOOK_DELETE 0x2 + +#define FS_DIRECTORY 0x0001 /* This looks like a dir, not a link */ +#define FS_MBACKGROUND 0x0002 /* Should background this mount */ +#define FS_NOTIMEOUT 0x0004 /* Don't bother with timeouts */ +#define FS_MKMNT 0x0008 /* Need to make the mount point */ +#define FS_UBACKGROUND 0x0010 /* Unmount in background */ +#define FS_BACKGROUND (FS_MBACKGROUND|FS_UBACKGROUND) +#define FS_DISCARD 0x0020 /* Discard immediately on last reference */ +#define FS_AMQINFO 0x0040 /* Amq is interested in this fs type */ + +#ifdef SUNOS4_COMPAT +extern am_ops *sunos4_match P((am_opts*, char*, char*, char*, char*, char*)); +#endif /* SUNOS4_COMPAT */ +extern am_ops *ops_match P((am_opts*, char*, char*, char*, char*, char*)); +#include "fstype.h" + +/* + * Per-mountpoint statistics + */ +struct am_stats { + time_t s_mtime; /* Mount time */ + u_short s_uid; /* Uid of mounter */ + int s_getattr; /* Count of getattrs */ + int s_lookup; /* Count of lookups */ + int s_readdir; /* Count of readdirs */ + int s_readlink; /* Count of readlinks */ + int s_statfs; /* Count of statfs */ +}; +typedef struct am_stats am_stats; + +/* + * System statistics + */ +struct amd_stats { + int d_drops; /* Dropped requests */ + int d_stale; /* Stale NFS handles */ + int d_mok; /* Succesful mounts */ + int d_merr; /* Failed mounts */ + int d_uerr; /* Failed unmounts */ +}; +extern struct amd_stats amd_stats; + +/* + * List of fileservers + */ +struct fserver { + qelem fs_q; /* List of fileservers */ + int fs_refc; /* Number of references to this node */ + char *fs_host; /* Normalized hostname of server */ + struct sockaddr_in *fs_ip; /* Network address of server */ + int fs_cid; /* Callout id */ + int fs_pinger; /* Ping (keepalive) interval */ + int fs_flags; /* Flags */ + char *fs_type; /* File server type */ + voidp fs_private; /* Private data */ + void (*fs_prfree)(); /* Free private data */ +}; +#define FSF_VALID 0x0001 /* Valid information available */ +#define FSF_DOWN 0x0002 /* This fileserver is thought to be down */ +#define FSF_ERROR 0x0004 /* Permanent error has occured */ +#define FSF_WANT 0x0008 /* Want a wakeup call */ +#define FSF_PINGING 0x0010 /* Already doing pings */ +#define FSRV_ISDOWN(fs) (((fs)->fs_flags & (FSF_DOWN|FSF_VALID)) == (FSF_DOWN|FSF_VALID)) +#define FSRV_ISUP(fs) (((fs)->fs_flags & (FSF_DOWN|FSF_VALID)) == (FSF_VALID)) + +/* + * List of mounted filesystems + */ +struct mntfs { + qelem mf_q; /* List of mounted filesystems */ + am_ops *mf_ops; /* Operations on this mountpoint */ + am_opts *mf_fo; /* File opts */ + char *mf_mount; /* "/a/kiska/home/kiska" */ + char *mf_info; /* Mount info */ + char *mf_auto; /* Automount opts */ + char *mf_mopts; /* FS mount opts */ + char *mf_remopts; /* Remote FS mount opts */ + fserver *mf_server; /* File server */ + int mf_flags; /* Flags */ + int mf_error; /* Error code from background mount */ + int mf_refc; /* Number of references to this node */ + int mf_cid; /* Callout id */ + void (*mf_prfree)(); /* Free private space */ + voidp mf_private; /* Private - per-fs data */ +}; + +#define MFF_MOUNTED 0x0001 /* Node is mounted */ +#define MFF_MOUNTING 0x0002 /* Mount is in progress */ +#define MFF_UNMOUNTING 0x0004 /* Unmount is in progress */ +#define MFF_RESTART 0x0008 /* Restarted node */ +#define MFF_MKMNT 0x0010 /* Delete this node's am_mount */ +#define MFF_ERROR 0x0020 /* This node failed to mount */ +#define MFF_LOGDOWN 0x0040 /* Logged that this mount is down */ +#define MFF_RSTKEEP 0x0080 /* Don't timeout this filesystem - restarted */ +#define MFF_WANTTIMO 0x0100 /* Need a timeout call when not busy */ + +/* + * Map of auto-mount points. + */ +struct am_node { + int am_mapno; /* Map number */ + mntfs *am_mnt; /* Mounted filesystem */ + char *am_name; /* "kiska" + Name of this node */ + char *am_path; /* "/home/kiska" + Path of this node's mount point */ + char *am_link; /* "/a/kiska/home/kiska/this/that" + Link to sub-directory */ + am_node *am_parent, /* Parent of this node */ + *am_ysib, /* Younger sibling of this node */ + *am_osib, /* Older sibling of this node */ + *am_child; /* First child of this node */ + struct attrstat am_attr; /* File attributes */ +#define am_fattr am_attr.attrstat_u.attributes + int am_flags; /* Boolean flags */ + int am_error; /* Specific mount error */ + time_t am_ttl; /* Time to live */ + int am_timeo_w; /* Wait interval */ + int am_timeo; /* Timeout interval */ + unsigned int am_gen; /* Generation number */ + char *am_pref; /* Mount info prefix */ + am_stats am_stats; /* Statistics gathering */ +}; + +#define AMF_NOTIMEOUT 0x0001 /* This node never times out */ +#define AMF_ROOT 0x0002 /* This is a root node */ + +#define ONE_HOUR (60 * 60) /* One hour in seconds */ + +/* + * The following values can be tuned... + */ +#define ALLOWED_MOUNT_TIME 40 /* 40s for a mount */ +#define AM_TTL (5 * 60) /* Default cache period */ +#define AM_TTL_W (2 * 60) /* Default unmount interval */ +#define AM_PINGER 30 /* NFS ping interval for live systems */ +#define AFS_TIMEO 8 /* Default afs timeout - .8s */ +#define AFS_RETRANS ((ALLOWED_MOUNT_TIME*10+5*afs_timeo)/afs_timeo * 2) + /* Default afs retrans - 1/10th seconds */ + +#define RPC_XID_PORTMAP 0 +#define RPC_XID_MOUNTD 1 +#define RPC_XID_NFSPING 2 +#define RPC_XID_MASK (0x0f) /* 16 id's for now */ +#define MK_RPC_XID(type_id, uniq) ((type_id) | ((uniq) << 4)) diff --git a/usr.sbin/amd/include/config.h b/usr.sbin/amd/include/config.h new file mode 100644 index 0000000..09b77bf --- /dev/null +++ b/usr.sbin/amd/include/config.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)config.h 8.1 (Berkeley) 6/6/93 + * + * $Id: config.h,v 5.2.2.1 1992/02/09 15:09:56 jsp beta $ + * + */ + +/* + * Get this in now so that OS_HDR can use it + */ +#ifdef __STDC__ +#define P(x) x +#define P_void void +#define Const const +#else +#define P(x) () +#define P_void /* as nothing */ +#define Const /* as nothing */ +#endif /* __STDC__ */ + +#ifdef __GNUC__ +#define INLINE /* __inline */ +#else +#define INLINE +#endif /* __GNUC__ */ + +/* + * Pick up target dependent definitions + */ +#include "os-defaults.h" +#include OS_HDR + +#ifdef VOIDP +typedef void *voidp; +#else +typedef char *voidp; +#endif /* VOIDP */ + +#include +#include +#include +extern int errno; +#include + +#define clocktime() (clock_valid ? clock_valid : time(&clock_valid)) +extern time_t time P((time_t *)); +extern time_t clock_valid; /* Clock needs recalculating */ + +extern char *progname; /* "amd"|"mmd" */ +extern char hostname[]; /* "kiska" */ +extern int mypid; /* Current process id */ + +#ifdef HAS_SYSLOG +extern int syslogging; /* Really using syslog */ +#endif /* HAS_SYSLOG */ +extern FILE *logfp; /* Log file */ +extern int xlog_level; /* Logging level */ +extern int xlog_level_init; + +extern int orig_umask; /* umask() on startup */ + +#define XLOG_FATAL 0x0001 +#define XLOG_ERROR 0x0002 +#define XLOG_USER 0x0004 +#define XLOG_WARNING 0x0008 +#define XLOG_INFO 0x0010 +#define XLOG_DEBUG 0x0020 +#define XLOG_MAP 0x0040 +#define XLOG_STATS 0x0080 + +#define XLOG_DEFSTR "all,nomap,nostats" /* Default log options */ +#define XLOG_ALL (XLOG_FATAL|XLOG_ERROR|XLOG_USER|XLOG_WARNING|XLOG_INFO|XLOG_MAP|XLOG_STATS) + +#ifdef DEBUG +#define D_ALL (~0) + +#ifdef DEBUG_MEM +#define free(x) xfree(__FILE__,__LINE__,x) +#endif /* DEBUG_MEM */ + +#define Debug(x) if (!(debug_flags & (x))) ; else +#define dlog Debug(D_FULL) dplog +#endif /* DEBUG */ + +/* + * Option tables + */ +struct opt_tab { + char *opt; + int flag; +}; + +extern struct opt_tab xlog_opt[]; + +extern int cmdoption P((char*, struct opt_tab*, int*)); +extern void going_down P((int)); +#ifdef DEBUG +extern void dplog (); +/*extern void dplog P((char*, ...));*/ +#endif /* DEBUG */ +extern void plog (); +/*extern void plog P((int, char*, ...));*/ +extern void show_opts P((int ch, struct opt_tab*)); +extern char* strchr P((const char*, int)); /* C */ +extern voidp xmalloc P((int)); +extern voidp xrealloc P((voidp, int)); diff --git a/usr.sbin/amd/include/fstype.h b/usr.sbin/amd/include/fstype.h new file mode 100644 index 0000000..03493d2 --- /dev/null +++ b/usr.sbin/amd/include/fstype.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)fstype.h 8.1 (Berkeley) 6/6/93 + * + * $Id: fstype.h,v 5.2.2.1 1992/02/09 15:09:57 jsp beta $ + * + */ + +/* + * File system types + */ + +/* + * Automount File System + */ +#define HAS_AFS +extern am_ops afs_ops; /* Automount file system (this!) */ +extern am_ops toplvl_ops; /* Top-level automount file system */ +extern am_ops root_ops; /* Root file system */ +extern qelem afs_srvr_list; +extern fserver *find_afs_srvr P((mntfs*)); + +/* + * Direct Automount File System + */ +#define HAS_DFS +extern am_ops dfs_ops; /* Direct Automount file system (this too) */ + +/* + * Error File System + */ +#define HAS_EFS +extern am_ops efs_ops; /* Error file system */ + +/* + * Inheritance File System + */ +#define HAS_IFS +extern am_ops ifs_ops; /* Inheritance file system */ + +/* + * Loopback File System + * LOFS is optional - you can compile without it. + */ +#ifdef OS_HAS_LOFS +/* + * Most systems can't support this, and in + * any case most of the functionality is + * available with Symlink FS. In fact, + * lofs_ops is not yet available. + */ +#define HAS_LOFS +extern am_ops lofs_ops; +#endif + +/* + * Netw*rk File System + * Good, slow, NFS. + * NFS host - a whole tree + */ +#define HAS_NFS +#define HAS_HOST +#define HAS_NFSX +extern am_ops nfs_ops; /* NFS */ +extern am_ops nfsx_ops; /* NFS X */ +extern am_ops host_ops; /* NFS host */ +#ifdef HOST_EXEC +extern char *host_helper; /* "/usr/local/etc/amd-host" */ +#endif +extern qelem nfs_srvr_list; +extern fserver *find_nfs_srvr P((mntfs*)); + +/* + * Program File System + * PFS is optional - you can compile without it. + * This is useful for things like RVD. + */ +#define HAS_PFS +extern am_ops pfs_ops; /* PFS */ + +/* + * Translucent File System + * TFS is optional - you can compile without it. + * This is just plain cute. + */ +#ifdef notdef +extern am_ops tfs_ops; /* TFS */ +#endif +#undef HAS_TFS + +/* + * Un*x File System + * Normal local disk file system. + */ +#define HAS_UFS +extern am_ops ufs_ops; /* Un*x file system */ + +/* + * Symbolic-link file system + * A "filesystem" which is just a symbol link. + * + * sfsx also checks that the target of the link exists. + */ +#define HAS_SFS +extern am_ops sfs_ops; /* Symlink FS */ +#define HAS_SFSX +extern am_ops sfsx_ops; /* Symlink FS with existence check */ + +/* + * Union file system + */ +#define HAS_UNION_FS +extern am_ops union_ops; /* Union FS */ diff --git a/usr.sbin/amd/include/re.h b/usr.sbin/amd/include/re.h new file mode 100644 index 0000000..73d6bf4 --- /dev/null +++ b/usr.sbin/amd/include/re.h @@ -0,0 +1,21 @@ +/* + * Definitions etc. for regexp(3) routines. + * + * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], + * not the System V one. + */ +#define NSUBEXP 10 +typedef struct regexp { + char *startp[NSUBEXP]; + char *endp[NSUBEXP]; + char regstart; /* Internal use only. */ + char reganch; /* Internal use only. */ + char *regmust; /* Internal use only. */ + int regmlen; /* Internal use only. */ + char program[1]; /* Unwarranted chumminess with compiler. */ +} regexp; + +extern regexp *regcomp(); +extern int regexec(); +extern void regsub(); +extern void regerror(); diff --git a/usr.sbin/amd/include/remagic.h b/usr.sbin/amd/include/remagic.h new file mode 100644 index 0000000..5acf447 --- /dev/null +++ b/usr.sbin/amd/include/remagic.h @@ -0,0 +1,5 @@ +/* + * The first byte of the regexp internal "program" is actually this magic + * number; the start node begins in the second byte. + */ +#define MAGIC 0234 diff --git a/usr.sbin/amd/include/uwait.h b/usr.sbin/amd/include/uwait.h new file mode 100644 index 0000000..c3f8cbe --- /dev/null +++ b/usr.sbin/amd/include/uwait.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)uwait.h 8.1 (Berkeley) 6/6/93 + * + * $Id: uwait.h,v 5.2.2.1 1992/02/09 15:10:01 jsp beta $ + * + */ + +#if defined(mc68k) || defined(mc68000) || defined(mc68020) || defined(sparc) || defined(hp9000s300) || defined(hp9000s800) +#define BITS_BIGENDIAN +#endif +#if defined(vax) || defined(i386) +#define BITS_LITTLENDIAN +#endif +#if !defined BITS_BIGENDIAN && !defined BITS_LITTLENDIAN + #error Do not know my byte ordering +#endif + +/* + * Structure of the information in the first word returned by both + * wait and wait3. If w_stopval==WSTOPPED, then the second structure + * describes the information returned, else the first. See WUNTRACED below. + */ +union wait { + int w_status; /* used in syscall */ + /* + * Terminated process status. + */ + struct { +#ifdef BITS_LITTLENDIAN + unsigned short w_Termsig:7; /* termination signal */ + unsigned short w_Coredump:1; /* core dump indicator */ + unsigned short w_Retcode:8; /* exit code if w_termsig==0 */ +#endif +#ifdef BITS_BIGENDIAN + unsigned short w_Fill1:16; /* high 16 bits unused */ + unsigned short w_Retcode:8; /* exit code if w_termsig==0 */ + unsigned short w_Coredump:1; /* core dump indicator */ + unsigned short w_Termsig:7; /* termination signal */ +#endif + } w_U; +}; +#define w_termsig w_U.w_Termsig +#define w_coredump w_U.w_Coredump +#define w_retcode w_U.w_Retcode + +#define WIFSIGNALED(x) ((x).w_termsig != 0) +#define WIFEXITED(x) ((x).w_termsig == 0) diff --git a/usr.sbin/amd/maps/a_master b/usr.sbin/amd/maps/a_master new file mode 100644 index 0000000..2f60dde --- /dev/null +++ b/usr.sbin/amd/maps/a_master @@ -0,0 +1,79 @@ +#machine opts info +achilles -opts:=rw,grpid,nosuid \ + type:=ufs;hostd==achilles.doc;dev:=/dev/xy1g \ + type:=nfs;hostd!=achilles.doc;rhost:=achilles.doc;rfs:=/home/achilles +# +dougal -opts:=rw,grpid,nosuid \ + type:=ufs;hostd==dougal.doc;dev:=/dev/dsk/1s0 \ + type:=nfs;hostd!=dougal.doc;rhost:=dougal.doc;rfs:=/home/dougal +# +dylan type:=auto;fs:=${map};pref:=${key}/ +dylan/dk2 -opts:=rw,grpid,nosuid \ + hostd==dylan.doc;type:=ufs;dev:=/dev/dsk/2s0 \ + hostd!=dylan.doc;type:=nfs;rhost:=dylan.doc;rfs:=/home/dylan/dk2 +# +dylan/dk3 -opts:=rw,grpid,nosuid \ + hostd==dylan.doc;type:=ufs;dev:=/dev/dsk/3s0 \ + hostd!=dylan.doc;type:=nfs;rhost:=dylan.doc;rfs:=/home/dylan/dk3 +# +dylan/dk5 -opts:=rw,grpid,nosuid \ + hostd==dylan.doc;type:=ufs;dev:=/dev/dsk/5s0 \ + hostd!=dylan.doc;type:=nfs;rhost:=dylan.doc;rfs:=/home/dylan/dk5 +# +ganymede -opts:=rw,grpid,nosuid \ + hostd!=${key}.${domain};type:=nfs;rhost:=${key}.${domain};rfs:=/home/${key} +gummo -opts:=rw,grpid,nosuid \ + hostd!=gummo.doc;type:=nfs;rhost:=gummo.doc;rfs:=/home/gummo +# +# Wildcard match +* -opts:=rw,grpid,nosuid \ + hostd!=${key}.${domain};type:=nfs;rhost:=${key}.${domain};rfs:=/home/${key} +# +# +gould -opts:=rw,grpid,nosuid \ + hostd!=gould.doc;type:=nfs;rhost:=gould.doc;rfs:=/home/gould +toytown -opts:=rw,grpid,nosuid \ + hostd!=toytown.doc;type:=nfs;rhost:=toytown.doc;rfs:=/home/${key} +zebedee -opts:=rw,grpid,nosuid \ + hostd!=zebedee.doc;type:=nfs;rhost:=zebedee.doc;rfs:=/home/zebedee +# +# Should be ENOENT from mountd on toytown... +# +testing -opts:=rw,grpid,nosuid \ + hostd!=toytown.doc;type:=nfs;rhost:=toytown.doc;rfs:=/this/that +# +# Somewhere else +# +pebbles -opts:=rw,grpid,nosuid \ + hostd!=pebbles.cc;type:=nfs;rhost:=pebbles.cc;rfs:=/home/cc/pebbles +# +# Specify where to mount +# +xtoy -opts:=rw,grpid,nosuid \ + type:=nfs;rhost:=toytown.doc;rfs:=/home/toytown;fs:=/tmp/junk99 +# +# Links... +# +alink type:=link;hostd==achilles.doc;fs:=/etc +tlink type:=link;hostd==truth.doc;fs:=/etc +uucp type:=link;hostd==truth.doc;fs:=/etc;sublink:=uucp +# +# Duplicate mounts to the same place +# +dup1 -opts:=rw,grpid,nosuid \ + type:=nfs;rhost:=toytown.doc;rfs:=/home/toytown;fs:=/tmp/tt-home +dup2 -opts:=rw,grpid,nosuid \ + type:=nfs;rhost:=ganymede.doc;rfs:=/home/ganymede;fs:=/tmp/tt-home +# +# Symlink +# +link type:=link;fs:=dylan/dk2/adh +# +# Program mount +# +exec type:=program;mount:="/bin/true false";unmount:="/bin/true true" +# +# Alternate mount locations. +# +alt -host==truth;type:=nfs;rfs:=/var/spool/mail \ + rhost:=toytown rhost:=charm rhost:=gummo diff --git a/usr.sbin/amd/maps/a_net b/usr.sbin/amd/maps/a_net new file mode 100644 index 0000000..ea2492b --- /dev/null +++ b/usr.sbin/amd/maps/a_net @@ -0,0 +1,3 @@ +/defaults fs:=${autodir}/${rhost}/root/${rfs} +* rhost:=${key};type=host;rfs:=/ + diff --git a/usr.sbin/amd/mk-amd-map/Makefile b/usr.sbin/amd/mk-amd-map/Makefile new file mode 100644 index 0000000..6db921a --- /dev/null +++ b/usr.sbin/amd/mk-amd-map/Makefile @@ -0,0 +1,11 @@ +# @(#)Makefile 8.1 (Berkeley) 6/28/93 + +PROG= mk-amd-map +CFLAGS+=-I${.CURDIR}/../include +CFLAGS+=-I${.CURDIR}/../rpcx +CFLAGS+=-I${.CURDIR}/../config +CFLAGS+=-DOS_HDR=\"os-bsd44.h\" +MAN8= mk-amd-map.0 + +.include "../../Makefile.inc" +.include diff --git a/usr.sbin/amd/mk-amd-map/mk-amd-map.8 b/usr.sbin/amd/mk-amd-map/mk-amd-map.8 new file mode 100644 index 0000000..20f3217 --- /dev/null +++ b/usr.sbin/amd/mk-amd-map/mk-amd-map.8 @@ -0,0 +1,59 @@ +.\" Copyright (c) 1993 Jan-Simon Pendry +.\" 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. +.\" +.\" @(#)mk-amd-map.8 8.1 (Berkeley) 6/28/93 +.\" +.Dd "June 28, 1993" +.Dt MK-AMD-MAP 8 +.Os BSD 4.4 +.Sh NAME +.Nm mk-amd-map +.Nd create database maps for Amd +.Sh SYNOPSIS +.Nm +.Op Fl p +.Ar mapname +.Sh DESCRIPTION +.Nm +creates the database maps used by the keyed map lookups in +.Xr amd 8 . +It reads input from the named file +and outputs them to a correspondingly named +hashed database. +.Pp +The +.Fl p +option prints the map on standard output instead of generating +a database. This is usually used to merge continuation lines +into one physical line. +.Sh SEE ALSO +.Xr amd 8 diff --git a/usr.sbin/amd/mk-amd-map/mk-amd-map.c b/usr.sbin/amd/mk-amd-map/mk-amd-map.c new file mode 100644 index 0000000..c2dfb71 --- /dev/null +++ b/usr.sbin/amd/mk-amd-map/mk-amd-map.c @@ -0,0 +1,384 @@ +/* + * Copyright (c) 1990, 1993 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)mk-amd-map.c 8.1 (Berkeley) 6/28/93 + * + * $Id: mk-amd-map.c,v 5.2.2.1 1992/02/09 15:09:18 jsp beta $ + */ + +/* + * Convert a file map into an ndbm map + */ + +#ifndef lint +char copyright[] = "\ +@(#)Copyright (c) 1990, 1993 Jan-Simon Pendry\n\ +@(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\ +@(#)Copyright (c) 1990, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char rcsid[] = "$Id: mk-amd-map.c,v 5.2.2.1 1992/02/09 15:09:18 jsp beta $"; +static char sccsid[] = "@(#)mk-amd-map.c 8.1 (Berkeley) 6/28/93"; +#endif /* not lint */ + +#include "am.h" + +#ifndef SIGINT +#include +#endif + +#ifdef OS_HAS_NDBM +#define HAS_DATABASE +#include + +#ifdef DBM_SUFFIX +#define USING_DB +#endif + +#define create_database(name) dbm_open(name, O_RDWR|O_CREAT, 0644) + +static int store_data(db, k, v) +voidp db; +char *k, *v; +{ + datum key, val; + + key.dptr = k; val.dptr = v; + key.dsize = strlen(k) + 1; + val.dsize = strlen(v) + 1; + return dbm_store((DBM *) db, key, val, DBM_INSERT); +} + +#endif /* OS_HAS_NDBM */ + +#ifdef HAS_DATABASE +#include +#include + +static int read_line(buf, size, fp) +char *buf; +int size; +FILE *fp; +{ + int done = 0; + + do { + while (fgets(buf, size, fp)) { + int len = strlen(buf); + done += len; + if (len > 1 && buf[len-2] == '\\' && + buf[len-1] == '\n') { + int ch; + buf += len - 2; + size -= len - 2; + *buf = '\n'; buf[1] = '\0'; + /* + * Skip leading white space on next line + */ + while ((ch = getc(fp)) != EOF && + isascii(ch) && isspace(ch)) + ; + (void) ungetc(ch, fp); + } else { + return done; + } + } + } while (size > 0 && !feof(fp)); + + return done; +} + +/* + * Read through a map + */ +static int read_file(fp, map, db) +FILE *fp; +char *map; +voidp db; +{ + char key_val[2048]; + int chuck = 0; + int line_no = 0; + int errs = 0; + + while (read_line(key_val, sizeof(key_val), fp)) { + char *kp; + char *cp; + char *hash; + int len = strlen(key_val); + line_no++; + + /* + * Make sure we got the whole line + */ + if (key_val[len-1] != '\n') { + fprintf(stderr, "line %d in \"%s\" is too long", line_no, map); + chuck = 1; + } else { + key_val[len-1] = '\0'; + } + + /* + * Strip comments + */ + hash = strchr(key_val, '#'); + if (hash) + *hash = '\0'; + + /* + * Find start of key + */ + for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++) + ; + + /* + * Ignore blank lines + */ + if (!*kp) + goto again; + + /* + * Find end of key + */ + for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++) + ; + + /* + * Check whether key matches, or whether + * the entry is a wildcard entry. + */ + if (*cp) + *cp++ = '\0'; + while (*cp && isascii(*cp) && isspace(*cp)) + cp++; + if (*kp == '+') { + fprintf(stderr, "Can't interpolate %s\n", kp); + errs++; + } else if (*cp) { + if (db) { + if (store_data(db, kp, cp) < 0) { + fprintf(stderr, "Could store %s -> %s\n", kp, cp); + errs++; + } + } else { + printf("%s\t%s\n", kp, cp); + } + } else { + fprintf(stderr, "%s: line %d has no value field", map, line_no); + errs++; + } + +again: + /* + * If the last read didn't get a whole line then + * throw away the remainder before continuing... + */ + if (chuck) { + while (fgets(key_val, sizeof(key_val), fp) && + !strchr(key_val, '\n')) + ; + chuck = 0; + } + } + return errs; +} + +static int remove_file(f) +char *f; +{ + if (unlink(f) < 0 && errno != ENOENT) + return -1; + return 0; +} + +main(argc, argv) +int argc; +char *argv[]; +{ + FILE *mapf; + char *map; + int rc = 0; + DBM *mapd; + static char maptmp[] = "dbmXXXXXX"; + char maptpag[16]; + char *mappag; +#ifndef USING_DB + char maptdir[16]; + char *mapdir; +#endif + int len; + char *sl; + int printit = 0; + int usage = 0; + int ch; + extern int optind; + + while ((ch = getopt(argc, argv, "p")) != EOF) + switch (ch) { + case 'p': + printit = 1; + break; + default: + usage++; + break; + } + + if (usage || optind != (argc - 1)) { + fputs("Usage: mk-amd-map [-p] file-map\n", stderr); + exit(1); + } + + map = argv[optind]; + sl = strrchr(map, '/'); + if (sl) { + *sl = '\0'; + if (chdir(map) < 0) { + fputs("Can't chdir to ", stderr); + perror(map); + exit(1); + } + map = sl + 1; + } + + if (!printit) { + len = strlen(map); +#ifdef USING_DB + mappag = (char *) malloc(len + 5); + if (!mappag) { + perror("mk-amd-map: malloc"); + exit(1); + } + mktemp(maptmp); + sprintf(maptpag, "%s%s", maptmp, DBM_SUFFIX); + if (remove_file(maptpag) < 0) { + fprintf(stderr, "Can't remove existing temporary file"); + perror(maptpag); + exit(1); + } +#else + mappag = (char *) malloc(len + 5); + mapdir = (char *) malloc(len + 5); + if (!mappag || !mapdir) { + perror("mk-amd-map: malloc"); + exit(1); + } + mktemp(maptmp); + sprintf(maptpag, "%s.pag", maptmp); + sprintf(maptdir, "%s.dir", maptmp); + if (remove_file(maptpag) < 0 || remove_file(maptdir) < 0) { + fprintf(stderr, "Can't remove existing temporary files; %s and", maptpag); + perror(maptdir); + exit(1); + } +#endif + } + + mapf = fopen(map, "r"); + if (mapf && !printit) + mapd = create_database(maptmp); + else + mapd = 0; + +#ifndef DEBUG + signal(SIGINT, SIG_IGN); +#endif + + if (mapd || printit) { + int error = read_file(mapf, map, mapd); + if (mapd) + dbm_close(mapd); + (void) fclose(mapf); + if (printit) { + if (error) { + fprintf(stderr, "Error creating ndbm map for %s\n", map); + rc = 1; + } + } else { + if (error) { + fprintf(stderr, "Error reading source file %s\n", map); + rc = 1; + } else { +#ifdef USING_DB + sprintf(mappag, "%s%s", map, DBM_SUFFIX); + if (rename(maptpag, mappag) < 0) { + fprintf(stderr, "Couldn't rename %s to ", maptpag); + perror(mappag); + /* Throw away the temporary map */ + unlink(maptpag); + rc = 1; + } +#else + sprintf(mappag, "%s.pag", map); + sprintf(mapdir, "%s.dir", map); + if (rename(maptpag, mappag) < 0) { + fprintf(stderr, "Couldn't rename %s to ", maptpag); + perror(mappag); + /* Throw away the temporary map */ + unlink(maptpag); + unlink(maptdir); + rc = 1; + } else if (rename(maptdir, mapdir) < 0) { + fprintf(stderr, "Couldn't rename %s to ", maptdir); + perror(mapdir); + /* Put the .pag file back */ + rename(mappag, maptpag); + /* Throw away remaining part of original map */ + unlink(mapdir); + fprintf(stderr, + "WARNING: existing map \"%s.{dir,pag}\" destroyed\n", + map); + rc = 1; + } +#endif + } + } + } else { + fprintf(stderr, "Can't open \"%s.{dir,pag}\" for ", map); + perror("writing"); + rc = 1; + } + exit(rc); +} +#else +main() +{ + fputs("mk-amd-map: This system does not support hashed database files\n", stderr); + exit(1); +} +#endif /* HAS_DATABASE */ diff --git a/usr.sbin/amd/rpcx/amq.h b/usr.sbin/amd/rpcx/amq.h new file mode 100644 index 0000000..7ec4d55 --- /dev/null +++ b/usr.sbin/amd/rpcx/amq.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)amq.h 8.1 (Berkeley) 6/6/93 + * + * $Id: amq.h,v 5.2.2.1 1992/02/09 15:09:22 jsp beta $ + * + */ + +#define AMQ_STRLEN 1024 + +typedef char *amq_string; +bool_t xdr_amq_string(); + + +typedef long *time_type; +bool_t xdr_time_type(); + + +struct amq_mount_tree { + amq_string mt_mountinfo; + amq_string mt_directory; + amq_string mt_mountpoint; + amq_string mt_type; + time_type mt_mounttime; + u_short mt_mountuid; + int mt_getattr; + int mt_lookup; + int mt_readdir; + int mt_readlink; + int mt_statfs; + struct amq_mount_tree *mt_next; + struct amq_mount_tree *mt_child; +}; +typedef struct amq_mount_tree amq_mount_tree; +bool_t xdr_amq_mount_tree(); + + +typedef amq_mount_tree *amq_mount_tree_p; +bool_t xdr_amq_mount_tree_p(); + + +struct amq_mount_info { + amq_string mi_type; + amq_string mi_mountpt; + amq_string mi_mountinfo; + amq_string mi_fserver; + int mi_error; + int mi_refc; + int mi_up; +}; +typedef struct amq_mount_info amq_mount_info; +bool_t xdr_amq_mount_info(); + + +typedef struct { + u_int amq_mount_info_list_len; + amq_mount_info *amq_mount_info_list_val; +} amq_mount_info_list; +bool_t xdr_amq_mount_info_list(); + + +typedef struct { + u_int amq_mount_tree_list_len; + amq_mount_tree_p *amq_mount_tree_list_val; +} amq_mount_tree_list; +bool_t xdr_amq_mount_tree_list(); + + +struct amq_mount_stats { + int as_drops; + int as_stale; + int as_mok; + int as_merr; + int as_uerr; +}; +typedef struct amq_mount_stats amq_mount_stats; +bool_t xdr_amq_mount_stats(); + + +enum amq_opt { + AMOPT_DEBUG = 0, + AMOPT_LOGFILE = 1, + AMOPT_XLOG = 2, + AMOPT_FLUSHMAPC = 3 +}; +typedef enum amq_opt amq_opt; +bool_t xdr_amq_opt(); + + +struct amq_setopt { + amq_opt as_opt; + amq_string as_str; +}; +typedef struct amq_setopt amq_setopt; +bool_t xdr_amq_setopt(); + + +#define AMQ_PROGRAM ((u_long)300019) +#define AMQ_VERSION ((u_long)1) +#define AMQPROC_NULL ((u_long)0) +extern voidp amqproc_null_1(); +#define AMQPROC_MNTTREE ((u_long)1) +extern amq_mount_tree_p *amqproc_mnttree_1(); +#define AMQPROC_UMNT ((u_long)2) +extern voidp amqproc_umnt_1(); +#define AMQPROC_STATS ((u_long)3) +extern amq_mount_stats *amqproc_stats_1(); +#define AMQPROC_EXPORT ((u_long)4) +extern amq_mount_tree_list *amqproc_export_1(); +#define AMQPROC_SETOPT ((u_long)5) +extern int *amqproc_setopt_1(); +#define AMQPROC_GETMNTFS ((u_long)6) +extern amq_mount_info_list *amqproc_getmntfs_1(); +#define AMQPROC_MOUNT ((u_long)7) +extern int *amqproc_mount_1(); +#define AMQPROC_GETVERS ((u_long)8) +extern amq_string *amqproc_getvers_1(); + diff --git a/usr.sbin/amd/rpcx/amq.x b/usr.sbin/amd/rpcx/amq.x new file mode 100644 index 0000000..d75805d --- /dev/null +++ b/usr.sbin/amd/rpcx/amq.x @@ -0,0 +1,185 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)amq.x 8.1 (Berkeley) 6/6/93 + * + * $Id: amq.x,v 5.2.2.1 1992/02/09 15:09:20 jsp beta $ + * + */ + +/* + * Protocol description used by the amq program + */ + +const AMQ_STRLEN = 1024; /* Maximum length of a pathname */ + +/* + * The type dirpath is the pathname of a directory + */ +typedef string amq_string; + +/* + * The type time_type should correspond to the system time_t + */ +typedef long time_type; + +/* + * A tree of what is mounted + */ +struct amq_mount_tree { + amq_string mt_mountinfo; /* Mounted filesystem */ + amq_string mt_directory; /* Virtual mount */ + amq_string mt_mountpoint; /* Mount point */ + amq_string mt_type; /* Filesystem type */ + time_type mt_mounttime; /* Mount time */ + u_short mt_mountuid; /* Mounter */ + int mt_getattr; /* Count of getattrs */ + int mt_lookup; /* Count of lookups */ + int mt_readdir; /* Count of readdirs */ + int mt_readlink; /* Count of readlinks */ + int mt_statfs; /* Count of statfss */ + amq_mount_tree *mt_next; /* Sibling mount tree */ + amq_mount_tree *mt_child; /* Child mount tree */ +}; +typedef amq_mount_tree *amq_mount_tree_p; + +/* + * List of mounted filesystems + */ +struct amq_mount_info { + amq_string mi_type; /* Type of mount */ + amq_string mi_mountpt; /* Mount point */ + amq_string mi_mountinfo; /* Mount info */ + amq_string mi_fserver; /* Fileserver */ + int mi_error; /* Error code */ + int mi_refc; /* References */ + int mi_up; /* Filesystem available */ +}; +typedef amq_mount_info amq_mount_info_list<>; + +/* + * A list of mount trees + */ +typedef amq_mount_tree_p amq_mount_tree_list<>; + +/* + * System wide stats + */ +struct amq_mount_stats { + int as_drops; /* Dropped requests */ + int as_stale; /* Stale NFS handles */ + int as_mok; /* Succesful mounts */ + int as_merr; /* Failed mounts */ + int as_uerr; /* Failed unmounts */ +}; + +enum amq_opt { + AMOPT_DEBUG=0, + AMOPT_LOGFILE=1, + AMOPT_XLOG=2, + AMOPT_FLUSHMAPC=3 +}; + +struct amq_setopt { + amq_opt as_opt; /* Option */ + amq_string as_str; /* String */ +}; + +program AMQ_PROGRAM { + version AMQ_VERSION { + /* + * Does no work. It is made available in all RPC services + * to allow server reponse testing and timing + */ + void + AMQPROC_NULL(void) = 0; + + /* + * Returned the mount tree descending from + * the given directory. The directory must + * be a top-level mount point of the automounter. + */ + amq_mount_tree_p + AMQPROC_MNTTREE(amq_string) = 1; + + /* + * Force a timeout unmount on the specified directory. + */ + void + AMQPROC_UMNT(amq_string) = 2; + + /* + * Obtain system wide statistics from the automounter + */ + amq_mount_stats + AMQPROC_STATS(void) = 3; + + /* + * Obtain full tree + */ + amq_mount_tree_list + AMQPROC_EXPORT(void) = 4; + + /* + * Control debug options. + * Return status: + * -1: debug not available + * 0: everything wonderful + * >0: number of options not recognised + */ + int + AMQPROC_SETOPT(amq_setopt) = 5; + + /* + * List of mounted filesystems + */ + amq_mount_info_list + AMQPROC_GETMNTFS(void) = 6; + + /* + * Mount a filesystem + */ + int + AMQPROC_MOUNT(amq_string) = 7; + + /* + * Get version info + */ + amq_string + AMQPROC_GETVERS(void) = 8; + } = 1; +} = 300019; /* Allocated by Sun, 89/8/29 */ diff --git a/usr.sbin/amd/rpcx/amq_clnt.c b/usr.sbin/amd/rpcx/amq_clnt.c new file mode 100644 index 0000000..5b70d11 --- /dev/null +++ b/usr.sbin/amd/rpcx/amq_clnt.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)amq_clnt.c 8.1 (Berkeley) 6/6/93 + * + * $Id: amq_clnt.c,v 5.2.2.1 1992/02/09 15:09:24 jsp beta $ + * + */ + +#include "am.h" +#include "amq.h" + +static struct timeval TIMEOUT = { ALLOWED_MOUNT_TIME, 0 }; + +voidp +amqproc_null_1(argp, clnt) + voidp argp; + CLIENT *clnt; +{ + static char res; + + bzero((char *)&res, sizeof(res)); + if (clnt_call(clnt, AMQPROC_NULL, xdr_void, argp, xdr_void, &res, TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return ((voidp)&res); +} + + +amq_mount_tree_p * +amqproc_mnttree_1(argp, clnt) + amq_string *argp; + CLIENT *clnt; +{ + static amq_mount_tree_p res; + + bzero((char *)&res, sizeof(res)); + if (clnt_call(clnt, AMQPROC_MNTTREE, xdr_amq_string, argp, xdr_amq_mount_tree_p, &res, TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&res); +} + + +voidp +amqproc_umnt_1(argp, clnt) + amq_string *argp; + CLIENT *clnt; +{ + static char res; + + bzero((char *)&res, sizeof(res)); + if (clnt_call(clnt, AMQPROC_UMNT, xdr_amq_string, argp, xdr_void, &res, TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return ((voidp)&res); +} + + +amq_mount_stats * +amqproc_stats_1(argp, clnt) + voidp argp; + CLIENT *clnt; +{ + static amq_mount_stats res; + + bzero((char *)&res, sizeof(res)); + if (clnt_call(clnt, AMQPROC_STATS, xdr_void, argp, xdr_amq_mount_stats, &res, TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&res); +} + + +amq_mount_tree_list * +amqproc_export_1(argp, clnt) + voidp argp; + CLIENT *clnt; +{ + static amq_mount_tree_list res; + + bzero((char *)&res, sizeof(res)); + if (clnt_call(clnt, AMQPROC_EXPORT, xdr_void, argp, xdr_amq_mount_tree_list, &res, TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&res); +} + +int * +amqproc_setopt_1(argp, clnt) + amq_setopt *argp; + CLIENT *clnt; +{ + static int res; + + bzero((char *)&res, sizeof(res)); + if (clnt_call(clnt, AMQPROC_SETOPT, xdr_amq_setopt, argp, xdr_int, &res, TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&res); +} + + +amq_mount_info_list * +amqproc_getmntfs_1(argp, clnt) + voidp argp; + CLIENT *clnt; +{ + static amq_mount_info_list res; + + bzero((char *)&res, sizeof(res)); + if (clnt_call(clnt, AMQPROC_GETMNTFS, xdr_void, argp, xdr_amq_mount_info_list, &res, TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&res); +} + + +int * +amqproc_mount_1(argp, clnt) + voidp argp; + CLIENT *clnt; +{ + static int res; + + bzero((char *)&res, sizeof(res)); + if (clnt_call(clnt, AMQPROC_MOUNT, xdr_amq_string, argp, xdr_int, &res, TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&res); +} + + +amq_string * +amqproc_getvers_1(argp, clnt) + voidp argp; + CLIENT *clnt; +{ + static amq_string res; + + bzero((char *)&res, sizeof(res)); + if (clnt_call(clnt, AMQPROC_GETVERS, xdr_void, argp, xdr_amq_string, &res, TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&res); +} + diff --git a/usr.sbin/amd/rpcx/amq_svc.c b/usr.sbin/amd/rpcx/amq_svc.c new file mode 100644 index 0000000..0d3599f --- /dev/null +++ b/usr.sbin/amd/rpcx/amq_svc.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)amq_svc.c 8.1 (Berkeley) 6/6/93 + * + * $Id: amq_svc.c,v 5.2.2.1 1992/02/09 15:09:26 jsp beta $ + * + */ + +#include "am.h" +#include "amq.h" +extern bool_t xdr_amq_mount_info_qelem(); + +void +amq_program_1(rqstp, transp) + struct svc_req *rqstp; + SVCXPRT *transp; +{ + union { + amq_string amqproc_mnttree_1_arg; + amq_string amqproc_umnt_1_arg; + amq_setopt amqproc_setopt_1_arg; + amq_string amqproc_mount_1_arg; + } argument; + char *result; + bool_t (*xdr_argument)(), (*xdr_result)(); + char *(*local)(); + + switch (rqstp->rq_proc) { + case AMQPROC_NULL: + xdr_argument = xdr_void; + xdr_result = xdr_void; + local = (char *(*)()) amqproc_null_1; + break; + + case AMQPROC_MNTTREE: + xdr_argument = xdr_amq_string; + xdr_result = xdr_amq_mount_tree_p; + local = (char *(*)()) amqproc_mnttree_1; + break; + + case AMQPROC_UMNT: + xdr_argument = xdr_amq_string; + xdr_result = xdr_void; + local = (char *(*)()) amqproc_umnt_1; + break; + + case AMQPROC_STATS: + xdr_argument = xdr_void; + xdr_result = xdr_amq_mount_stats; + local = (char *(*)()) amqproc_stats_1; + break; + + case AMQPROC_EXPORT: + xdr_argument = xdr_void; + xdr_result = xdr_amq_mount_tree_list; + local = (char *(*)()) amqproc_export_1; + break; + + case AMQPROC_SETOPT: + xdr_argument = xdr_amq_setopt; + xdr_result = xdr_int; + local = (char *(*)()) amqproc_setopt_1; + break; + + case AMQPROC_GETMNTFS: + xdr_argument = xdr_void; + xdr_result = xdr_amq_mount_info_qelem; + local = (char *(*)()) amqproc_getmntfs_1; + break; + + case AMQPROC_MOUNT: + xdr_argument = xdr_amq_string; + xdr_result = xdr_int; + local = (char *(*)()) amqproc_mount_1; + break; + + case AMQPROC_GETVERS: + xdr_argument = xdr_void; + xdr_result = xdr_amq_string; + local = (char *(*)()) amqproc_getvers_1; + break; + + default: + svcerr_noproc(transp); + return; + } + bzero((char *)&argument, sizeof(argument)); + if (!svc_getargs(transp, xdr_argument, &argument)) { + svcerr_decode(transp); + return; + } + result = (*local)(&argument, rqstp); + if (result != NULL && !svc_sendreply(transp, xdr_result, result)) { + svcerr_systemerr(transp); + } + if (!svc_freeargs(transp, xdr_argument, &argument)) { + plog(XLOG_FATAL, "unable to free rpc arguments in amqprog_1"); + going_down(1); + } +} + diff --git a/usr.sbin/amd/rpcx/amq_xdr.c b/usr.sbin/amd/rpcx/amq_xdr.c new file mode 100644 index 0000000..8a123a7 --- /dev/null +++ b/usr.sbin/amd/rpcx/amq_xdr.c @@ -0,0 +1,251 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)amq_xdr.c 8.1 (Berkeley) 6/6/93 + * + * $Id: amq_xdr.c,v 5.2.2.1 1992/02/09 15:09:23 jsp beta $ + * + */ + +#include "am.h" +#include "amq.h" + + +bool_t +xdr_amq_string(xdrs, objp) + XDR *xdrs; + amq_string *objp; +{ + if (!xdr_string(xdrs, objp, AMQ_STRLEN)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_time_type(xdrs, objp) + XDR *xdrs; + time_type *objp; +{ + if (!xdr_long(xdrs, objp)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_amq_mount_tree(xdrs, objp) + XDR *xdrs; + amq_mount_tree *objp; +{ + if (!xdr_amq_string(xdrs, &objp->mt_mountinfo)) { + return (FALSE); + } + if (!xdr_amq_string(xdrs, &objp->mt_directory)) { + return (FALSE); + } + if (!xdr_amq_string(xdrs, &objp->mt_mountpoint)) { + return (FALSE); + } + if (!xdr_amq_string(xdrs, &objp->mt_type)) { + return (FALSE); + } + if (!xdr_time_type(xdrs, &objp->mt_mounttime)) { + return (FALSE); + } + if (!xdr_u_short(xdrs, &objp->mt_mountuid)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->mt_getattr)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->mt_lookup)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->mt_readdir)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->mt_readlink)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->mt_statfs)) { + return (FALSE); + } + if (!xdr_pointer(xdrs, (char **)&objp->mt_next, sizeof(amq_mount_tree), xdr_amq_mount_tree)) { + return (FALSE); + } + if (!xdr_pointer(xdrs, (char **)&objp->mt_child, sizeof(amq_mount_tree), xdr_amq_mount_tree)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_amq_mount_tree_p(xdrs, objp) + XDR *xdrs; + amq_mount_tree_p *objp; +{ + if (!xdr_pointer(xdrs, (char **)objp, sizeof(amq_mount_tree), xdr_amq_mount_tree)) { + return (FALSE); + } + return (TRUE); +} + + + +bool_t +xdr_amq_mount_info(xdrs, objp) + XDR *xdrs; + amq_mount_info *objp; +{ + if (!xdr_amq_string(xdrs, &objp->mi_type)) { + return (FALSE); + } + if (!xdr_amq_string(xdrs, &objp->mi_mountpt)) { + return (FALSE); + } + if (!xdr_amq_string(xdrs, &objp->mi_mountinfo)) { + return (FALSE); + } + if (!xdr_amq_string(xdrs, &objp->mi_fserver)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->mi_error)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->mi_refc)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->mi_up)) { + return (FALSE); + } + return (TRUE); +} + + + +bool_t +xdr_amq_mount_info_list(xdrs, objp) + XDR *xdrs; + amq_mount_info_list *objp; +{ + if (!xdr_array(xdrs, (char **)&objp->amq_mount_info_list_val, (u_int *)&objp->amq_mount_info_list_len, ~0, sizeof(amq_mount_info), xdr_amq_mount_info)) { + return (FALSE); + } + return (TRUE); +} + + + +bool_t +xdr_amq_mount_tree_list(xdrs, objp) + XDR *xdrs; + amq_mount_tree_list *objp; +{ + if (!xdr_array(xdrs, (char **)&objp->amq_mount_tree_list_val, (u_int *)&objp->amq_mount_tree_list_len, ~0, sizeof(amq_mount_tree_p), xdr_amq_mount_tree_p)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_amq_mount_stats(xdrs, objp) + XDR *xdrs; + amq_mount_stats *objp; +{ + if (!xdr_int(xdrs, &objp->as_drops)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->as_stale)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->as_mok)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->as_merr)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->as_uerr)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_amq_opt(xdrs, objp) + XDR *xdrs; + amq_opt *objp; +{ + if (!xdr_enum(xdrs, (enum_t *)objp)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_amq_setopt(xdrs, objp) + XDR *xdrs; + amq_setopt *objp; +{ + if (!xdr_amq_opt(xdrs, &objp->as_opt)) { + return (FALSE); + } + if (!xdr_amq_string(xdrs, &objp->as_str)) { + return (FALSE); + } + return (TRUE); +} + + diff --git a/usr.sbin/amd/rpcx/mount.h b/usr.sbin/amd/rpcx/mount.h new file mode 100644 index 0000000..d30b0c3 --- /dev/null +++ b/usr.sbin/amd/rpcx/mount.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)mount.h 8.1 (Berkeley) 6/6/93 + * + * $Id: mount.h,v 5.2.2.1 1992/02/09 15:09:27 jsp beta $ + * + */ + +#define MNTPATHLEN 1024 +#define MNTNAMLEN 255 +#define FHSIZE 32 + +typedef char fhandle[FHSIZE]; +bool_t xdr_fhandle(); + + +struct fhstatus { + u_int fhs_status; + union { + fhandle fhs_fhandle; + } fhstatus_u; +}; +typedef struct fhstatus fhstatus; +bool_t xdr_fhstatus(); + + +typedef char *dirpath; +bool_t xdr_dirpath(); + + +typedef char *name; +bool_t xdr_name(); + + +typedef struct mountbody *mountlist; +bool_t xdr_mountlist(); + + +struct mountbody { + name ml_hostname; + dirpath ml_directory; + mountlist ml_next; +}; +typedef struct mountbody mountbody; +bool_t xdr_mountbody(); + + +typedef struct groupnode *groups; +bool_t xdr_groups(); + + +struct groupnode { + name gr_name; + groups gr_next; +}; +typedef struct groupnode groupnode; +bool_t xdr_groupnode(); + + +typedef struct exportnode *exports; +bool_t xdr_exports(); + + +struct exportnode { + dirpath ex_dir; + groups ex_groups; + exports ex_next; +}; +typedef struct exportnode exportnode; +bool_t xdr_exportnode(); + + +#define MOUNTPROG ((u_long)100005) +#define MOUNTVERS ((u_long)1) +#define MOUNTPROC_NULL ((u_long)0) +extern voidp mountproc_null_1(); +#define MOUNTPROC_MNT ((u_long)1) +extern fhstatus *mountproc_mnt_1(); +#define MOUNTPROC_DUMP ((u_long)2) +extern mountlist *mountproc_dump_1(); +#define MOUNTPROC_UMNT ((u_long)3) +extern voidp mountproc_umnt_1(); +#define MOUNTPROC_UMNTALL ((u_long)4) +extern voidp mountproc_umntall_1(); +#define MOUNTPROC_EXPORT ((u_long)5) +extern exports *mountproc_export_1(); +#define MOUNTPROC_EXPORTALL ((u_long)6) +extern exports *mountproc_exportall_1(); + diff --git a/usr.sbin/amd/rpcx/mount_xdr.c b/usr.sbin/amd/rpcx/mount_xdr.c new file mode 100644 index 0000000..f8d8f57 --- /dev/null +++ b/usr.sbin/amd/rpcx/mount_xdr.c @@ -0,0 +1,206 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)mount_xdr.c 8.1 (Berkeley) 6/6/93 + * + * $Id: mount_xdr.c,v 5.2.2.1 1992/02/09 15:09:28 jsp beta $ + * + */ + +#include "am.h" +#include "mount.h" + + +bool_t +xdr_fhandle(xdrs, objp) + XDR *xdrs; + fhandle objp; +{ + if (!xdr_opaque(xdrs, objp, FHSIZE)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_fhstatus(xdrs, objp) + XDR *xdrs; + fhstatus *objp; +{ + if (!xdr_u_int(xdrs, &objp->fhs_status)) { + return (FALSE); + } + switch (objp->fhs_status) { + case 0: + if (!xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle)) { + return (FALSE); + } + break; + } + return (TRUE); +} + + + + +bool_t +xdr_dirpath(xdrs, objp) + XDR *xdrs; + dirpath *objp; +{ + if (!xdr_string(xdrs, objp, MNTPATHLEN)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_name(xdrs, objp) + XDR *xdrs; + name *objp; +{ + if (!xdr_string(xdrs, objp, MNTNAMLEN)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_mountlist(xdrs, objp) + XDR *xdrs; + mountlist *objp; +{ + if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct mountbody), xdr_mountbody)) { + return (FALSE); + } + return (TRUE); +} + + + +bool_t +xdr_mountbody(xdrs, objp) + XDR *xdrs; + mountbody *objp; +{ + if (!xdr_name(xdrs, &objp->ml_hostname)) { + return (FALSE); + } + if (!xdr_dirpath(xdrs, &objp->ml_directory)) { + return (FALSE); + } + if (!xdr_mountlist(xdrs, &objp->ml_next)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_groups(xdrs, objp) + XDR *xdrs; + groups *objp; +{ + if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct groupnode), xdr_groupnode)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_groupnode(xdrs, objp) + XDR *xdrs; + groupnode *objp; +{ + if (!xdr_name(xdrs, &objp->gr_name)) { + return (FALSE); + } + if (!xdr_groups(xdrs, &objp->gr_next)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_exports(xdrs, objp) + XDR *xdrs; + exports *objp; +{ + if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct exportnode), xdr_exportnode)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_exportnode(xdrs, objp) + XDR *xdrs; + exportnode *objp; +{ + if (!xdr_dirpath(xdrs, &objp->ex_dir)) { + return (FALSE); + } + if (!xdr_groups(xdrs, &objp->ex_groups)) { + return (FALSE); + } + if (!xdr_exports(xdrs, &objp->ex_next)) { + return (FALSE); + } + return (TRUE); +} + + diff --git a/usr.sbin/amd/rpcx/nfs_prot.h b/usr.sbin/amd/rpcx/nfs_prot.h new file mode 100644 index 0000000..62a75f7 --- /dev/null +++ b/usr.sbin/amd/rpcx/nfs_prot.h @@ -0,0 +1,389 @@ +/* + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)nfs_prot.h 8.1 (Berkeley) 6/6/93 + * + * $Id: nfs_prot.h,v 5.2.2.1 1992/02/09 15:09:29 jsp beta $ + * + */ + +#define xdr_nfsstat xdr_enum +#define xdr_ftype xdr_enum + +#define NFS_PORT 2049 +#define NFS_MAXDATA 8192 +#define NFS_MAXPATHLEN 1024 +#define NFS_MAXNAMLEN 255 +#define NFS_FHSIZE 32 +#define NFS_COOKIESIZE 4 +#define NFS_FIFO_DEV -1 +#define NFSMODE_FMT 0170000 +#define NFSMODE_DIR 0040000 +#define NFSMODE_CHR 0020000 +#define NFSMODE_BLK 0060000 +#define NFSMODE_REG 0100000 +#define NFSMODE_LNK 0120000 +#define NFSMODE_SOCK 0140000 +#define NFSMODE_FIFO 0010000 + +enum nfsstat { + NFS_OK = 0, + NFSERR_PERM = 1, + NFSERR_NOENT = 2, + NFSERR_IO = 5, + NFSERR_NXIO = 6, + NFSERR_ACCES = 13, + NFSERR_EXIST = 17, + NFSERR_NODEV = 19, + NFSERR_NOTDIR = 20, + NFSERR_ISDIR = 21, + NFSERR_FBIG = 27, + NFSERR_NOSPC = 28, + NFSERR_ROFS = 30, + NFSERR_NAMETOOLONG = 63, + NFSERR_NOTEMPTY = 66, + NFSERR_DQUOT = 69, + NFSERR_STALE = 70, + NFSERR_WFLUSH = 99 +}; +typedef enum nfsstat nfsstat; +bool_t xdr_nfsstat(); + + +enum ftype { + NFNON = 0, + NFREG = 1, + NFDIR = 2, + NFBLK = 3, + NFCHR = 4, + NFLNK = 5, + NFSOCK = 6, + NFBAD = 7, + NFFIFO = 8 +}; +typedef enum ftype ftype; +/* static bool_t xdr_ftype(); */ + + +struct nfs_fh { + char data[NFS_FHSIZE]; +}; +typedef struct nfs_fh nfs_fh; +bool_t xdr_nfs_fh(); + + +struct nfstime { + u_int seconds; + u_int useconds; +}; +typedef struct nfstime nfstime; +/* static bool_t xdr_nfstime(); */ + + +struct fattr { + ftype type; + u_int mode; + u_int nlink; + u_int uid; + u_int gid; + u_int size; + u_int blocksize; + u_int rdev; + u_int blocks; + u_int fsid; + u_int fileid; + nfstime atime; + nfstime mtime; + nfstime ctime; +}; +typedef struct fattr fattr; +/* static bool_t xdr_fattr(); */ + + +struct sattr { + u_int mode; + u_int uid; + u_int gid; + u_int size; + nfstime atime; + nfstime mtime; +}; +typedef struct sattr sattr; +/* static bool_t xdr_sattr(); */ + + +typedef char *filename; +/* static bool_t xdr_filename(); */ + + +typedef char *nfspath; +bool_t xdr_nfspath(); + + +struct attrstat { + nfsstat status; + union { + fattr attributes; + } attrstat_u; +}; +typedef struct attrstat attrstat; +bool_t xdr_attrstat(); + + +struct sattrargs { + nfs_fh file; + sattr attributes; +}; +typedef struct sattrargs sattrargs; +bool_t xdr_sattrargs(); + + +struct diropargs { + nfs_fh dir; + filename name; +}; +typedef struct diropargs diropargs; +bool_t xdr_diropargs(); + + +struct diropokres { + nfs_fh file; + fattr attributes; +}; +typedef struct diropokres diropokres; +bool_t xdr_diropokres(); + + +struct diropres { + nfsstat status; + union { + diropokres diropres; + } diropres_u; +}; +typedef struct diropres diropres; +bool_t xdr_diropres(); + + +struct readlinkres { + nfsstat status; + union { + nfspath data; + } readlinkres_u; +}; +typedef struct readlinkres readlinkres; +bool_t xdr_readlinkres(); + + +struct readargs { + nfs_fh file; + u_int offset; + u_int count; + u_int totalcount; +}; +typedef struct readargs readargs; +bool_t xdr_readargs(); + + +struct readokres { + fattr attributes; + struct { + u_int data_len; + char *data_val; + } data; +}; +typedef struct readokres readokres; +bool_t xdr_readokres(); + + +struct readres { + nfsstat status; + union { + readokres reply; + } readres_u; +}; +typedef struct readres readres; +bool_t xdr_readres(); + + +struct writeargs { + nfs_fh file; + u_int beginoffset; + u_int offset; + u_int totalcount; + struct { + u_int data_len; + char *data_val; + } data; +}; +typedef struct writeargs writeargs; +bool_t xdr_writeargs(); + + +struct createargs { + diropargs where; + sattr attributes; +}; +typedef struct createargs createargs; +bool_t xdr_createargs(); + + +struct renameargs { + diropargs from; + diropargs to; +}; +typedef struct renameargs renameargs; +bool_t xdr_renameargs(); + + +struct linkargs { + nfs_fh from; + diropargs to; +}; +typedef struct linkargs linkargs; +bool_t xdr_linkargs(); + + +struct symlinkargs { + diropargs from; + nfspath to; + sattr attributes; +}; +typedef struct symlinkargs symlinkargs; +bool_t xdr_symlinkargs(); + + +typedef char nfscookie[NFS_COOKIESIZE]; +/* static bool_t xdr_nfscookie(); */ + + +struct readdirargs { + nfs_fh dir; + nfscookie cookie; + u_int count; +}; +typedef struct readdirargs readdirargs; +bool_t xdr_readdirargs(); + + +struct entry { + u_int fileid; + filename name; + nfscookie cookie; + struct entry *nextentry; +}; +typedef struct entry entry; +/* static bool_t xdr_entry(); */ + + +struct dirlist { + entry *entries; + bool_t eof; +}; +typedef struct dirlist dirlist; +/* static bool_t xdr_dirlist(); */ + + +struct readdirres { + nfsstat status; + union { + dirlist reply; + } readdirres_u; +}; +typedef struct readdirres readdirres; +bool_t xdr_readdirres(); + + +struct statfsokres { + u_int tsize; + u_int bsize; + u_int blocks; + u_int bfree; + u_int bavail; +}; +typedef struct statfsokres statfsokres; +bool_t xdr_statfsokres(); + + +struct statfsres { + nfsstat status; + union { + statfsokres reply; + } statfsres_u; +}; +typedef struct statfsres statfsres; +bool_t xdr_statfsres(); + + +#define NFS_PROGRAM ((u_long)100003) +#define NFS_VERSION ((u_long)2) +#define NFSPROC_NULL ((u_long)0) +extern voidp nfsproc_null_2(); +#define NFSPROC_GETATTR ((u_long)1) +extern attrstat *nfsproc_getattr_2(); +#define NFSPROC_SETATTR ((u_long)2) +extern attrstat *nfsproc_setattr_2(); +#define NFSPROC_ROOT ((u_long)3) +extern voidp nfsproc_root_2(); +#define NFSPROC_LOOKUP ((u_long)4) +extern diropres *nfsproc_lookup_2(); +#define NFSPROC_READLINK ((u_long)5) +extern readlinkres *nfsproc_readlink_2(); +#define NFSPROC_READ ((u_long)6) +extern readres *nfsproc_read_2(); +#define NFSPROC_WRITECACHE ((u_long)7) +extern voidp nfsproc_writecache_2(); +#define NFSPROC_WRITE ((u_long)8) +extern attrstat *nfsproc_write_2(); +#define NFSPROC_CREATE ((u_long)9) +extern diropres *nfsproc_create_2(); +#define NFSPROC_REMOVE ((u_long)10) +extern nfsstat *nfsproc_remove_2(); +#define NFSPROC_RENAME ((u_long)11) +extern nfsstat *nfsproc_rename_2(); +#define NFSPROC_LINK ((u_long)12) +extern nfsstat *nfsproc_link_2(); +#define NFSPROC_SYMLINK ((u_long)13) +extern nfsstat *nfsproc_symlink_2(); +#define NFSPROC_MKDIR ((u_long)14) +extern diropres *nfsproc_mkdir_2(); +#define NFSPROC_RMDIR ((u_long)15) +extern nfsstat *nfsproc_rmdir_2(); +#define NFSPROC_READDIR ((u_long)16) +extern readdirres *nfsproc_readdir_2(); +#define NFSPROC_STATFS ((u_long)17) +extern statfsres *nfsproc_statfs_2(); + diff --git a/usr.sbin/amd/rpcx/nfs_prot_svc.c b/usr.sbin/amd/rpcx/nfs_prot_svc.c new file mode 100644 index 0000000..21e47e3 --- /dev/null +++ b/usr.sbin/amd/rpcx/nfs_prot_svc.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)nfs_prot_svc.c 8.1 (Berkeley) 6/6/93 + * + * $Id: nfs_prot_svc.c,v 5.2.2.1 1992/02/09 15:09:30 jsp beta $ + * + */ + +#include "am.h" + +void nfs_program_2(rqstp, transp) +struct svc_req *rqstp; +SVCXPRT *transp; +{ + union { + nfs_fh nfsproc_getattr_2_arg; + sattrargs nfsproc_setattr_2_arg; + diropargs nfsproc_lookup_2_arg; + nfs_fh nfsproc_readlink_2_arg; + readargs nfsproc_read_2_arg; + writeargs nfsproc_write_2_arg; + createargs nfsproc_create_2_arg; + diropargs nfsproc_remove_2_arg; + renameargs nfsproc_rename_2_arg; + linkargs nfsproc_link_2_arg; + symlinkargs nfsproc_symlink_2_arg; + createargs nfsproc_mkdir_2_arg; + diropargs nfsproc_rmdir_2_arg; + readdirargs nfsproc_readdir_2_arg; + nfs_fh nfsproc_statfs_2_arg; + } argument; + char *result; + bool_t (*xdr_argument)(), (*xdr_result)(); + char *(*local)(); + + switch (rqstp->rq_proc) { + case NFSPROC_NULL: + xdr_argument = xdr_void; + xdr_result = xdr_void; + local = (char *(*)()) nfsproc_null_2; + break; + + case NFSPROC_GETATTR: + xdr_argument = xdr_nfs_fh; + xdr_result = xdr_attrstat; + local = (char *(*)()) nfsproc_getattr_2; + break; + + case NFSPROC_SETATTR: + xdr_argument = xdr_sattrargs; + xdr_result = xdr_attrstat; + local = (char *(*)()) nfsproc_setattr_2; + break; + + case NFSPROC_ROOT: + xdr_argument = xdr_void; + xdr_result = xdr_void; + local = (char *(*)()) nfsproc_root_2; + break; + + case NFSPROC_LOOKUP: + xdr_argument = xdr_diropargs; + xdr_result = xdr_diropres; + local = (char *(*)()) nfsproc_lookup_2; + break; + + case NFSPROC_READLINK: + xdr_argument = xdr_nfs_fh; + xdr_result = xdr_readlinkres; + local = (char *(*)()) nfsproc_readlink_2; + break; + + case NFSPROC_READ: + xdr_argument = xdr_readargs; + xdr_result = xdr_readres; + local = (char *(*)()) nfsproc_read_2; + break; + + case NFSPROC_WRITECACHE: + xdr_argument = xdr_void; + xdr_result = xdr_void; + local = (char *(*)()) nfsproc_writecache_2; + break; + + case NFSPROC_WRITE: + xdr_argument = xdr_writeargs; + xdr_result = xdr_attrstat; + local = (char *(*)()) nfsproc_write_2; + break; + + case NFSPROC_CREATE: + xdr_argument = xdr_createargs; + xdr_result = xdr_diropres; + local = (char *(*)()) nfsproc_create_2; + break; + + case NFSPROC_REMOVE: + xdr_argument = xdr_diropargs; + xdr_result = xdr_nfsstat; + local = (char *(*)()) nfsproc_remove_2; + break; + + case NFSPROC_RENAME: + xdr_argument = xdr_renameargs; + xdr_result = xdr_nfsstat; + local = (char *(*)()) nfsproc_rename_2; + break; + + case NFSPROC_LINK: + xdr_argument = xdr_linkargs; + xdr_result = xdr_nfsstat; + local = (char *(*)()) nfsproc_link_2; + break; + + case NFSPROC_SYMLINK: + xdr_argument = xdr_symlinkargs; + xdr_result = xdr_nfsstat; + local = (char *(*)()) nfsproc_symlink_2; + break; + + case NFSPROC_MKDIR: + xdr_argument = xdr_createargs; + xdr_result = xdr_diropres; + local = (char *(*)()) nfsproc_mkdir_2; + break; + + case NFSPROC_RMDIR: + xdr_argument = xdr_diropargs; + xdr_result = xdr_nfsstat; + local = (char *(*)()) nfsproc_rmdir_2; + break; + + case NFSPROC_READDIR: + xdr_argument = xdr_readdirargs; + xdr_result = xdr_readdirres; + local = (char *(*)()) nfsproc_readdir_2; + break; + + case NFSPROC_STATFS: + xdr_argument = xdr_nfs_fh; + xdr_result = xdr_statfsres; + local = (char *(*)()) nfsproc_statfs_2; + break; + + default: + svcerr_noproc(transp); + return; + } + bzero((char *)&argument, sizeof(argument)); + if (!svc_getargs(transp, xdr_argument, &argument)) { + svcerr_decode(transp); + return; + } + result = (*local)(&argument, rqstp); + if (result != NULL && !svc_sendreply(transp, xdr_result, result)) { + svcerr_systemerr(transp); + } + if (!svc_freeargs(transp, xdr_argument, &argument)) { + plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_1"); + going_down(1); + } +} + diff --git a/usr.sbin/amd/rpcx/nfs_prot_xdr.c b/usr.sbin/amd/rpcx/nfs_prot_xdr.c new file mode 100644 index 0000000..1786d01 --- /dev/null +++ b/usr.sbin/amd/rpcx/nfs_prot_xdr.c @@ -0,0 +1,627 @@ +/* + * Copyright (c) 1989 Jan-Simon Pendry + * Copyright (c) 1989 Imperial College of Science, Technology & Medicine + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * 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. + * + * @(#)nfs_prot_xdr.c 8.1 (Berkeley) 6/6/93 + * + * $Id: nfs_prot_xdr.c,v 5.2.2.1 1992/02/09 15:09:32 jsp beta $ + * + */ + +#include "am.h" + + +#ifndef xdr_nfsstat +bool_t +xdr_nfsstat(xdrs, objp) + XDR *xdrs; + nfsstat *objp; +{ + if (!xdr_enum(xdrs, (enum_t *)objp)) { + return (FALSE); + } + return (TRUE); +} +#endif /* xdr_nfsstat */ + + + +#ifndef xdr_ftype +static bool_t +xdr_ftype(xdrs, objp) + XDR *xdrs; + ftype *objp; +{ + if (!xdr_enum(xdrs, (enum_t *)objp)) { + return (FALSE); + } + return (TRUE); +} +#endif /* xdr_ftype */ + + + +bool_t +xdr_nfs_fh(xdrs, objp) + XDR *xdrs; + nfs_fh *objp; +{ + if (!xdr_opaque(xdrs, objp->data, NFS_FHSIZE)) { + return (FALSE); + } + return (TRUE); +} + + + + +static bool_t +xdr_nfstime(xdrs, objp) + XDR *xdrs; + nfstime *objp; +{ + if (!xdr_u_int(xdrs, &objp->seconds)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->useconds)) { + return (FALSE); + } + return (TRUE); +} + + + + +static bool_t +xdr_fattr(xdrs, objp) + XDR *xdrs; + fattr *objp; +{ + if (!xdr_ftype(xdrs, &objp->type)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->mode)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->nlink)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->uid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->gid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->size)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->blocksize)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->rdev)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->blocks)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->fsid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->fileid)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->atime)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->mtime)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->ctime)) { + return (FALSE); + } + return (TRUE); +} + + + + +static bool_t +xdr_sattr(xdrs, objp) + XDR *xdrs; + sattr *objp; +{ + if (!xdr_u_int(xdrs, &objp->mode)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->uid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->gid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->size)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->atime)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->mtime)) { + return (FALSE); + } + return (TRUE); +} + + + + +static bool_t +xdr_filename(xdrs, objp) + XDR *xdrs; + filename *objp; +{ + if (!xdr_string(xdrs, objp, NFS_MAXNAMLEN)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_nfspath(xdrs, objp) + XDR *xdrs; + nfspath *objp; +{ + if (!xdr_string(xdrs, objp, NFS_MAXPATHLEN)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_attrstat(xdrs, objp) + XDR *xdrs; + attrstat *objp; +{ + if (!xdr_nfsstat(xdrs, &objp->status)) { + return (FALSE); + } + switch (objp->status) { + case NFS_OK: + if (!xdr_fattr(xdrs, &objp->attrstat_u.attributes)) { + return (FALSE); + } + break; + } + return (TRUE); +} + + + + +bool_t +xdr_sattrargs(xdrs, objp) + XDR *xdrs; + sattrargs *objp; +{ + if (!xdr_nfs_fh(xdrs, &objp->file)) { + return (FALSE); + } + if (!xdr_sattr(xdrs, &objp->attributes)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_diropargs(xdrs, objp) + XDR *xdrs; + diropargs *objp; +{ + if (!xdr_nfs_fh(xdrs, &objp->dir)) { + return (FALSE); + } + if (!xdr_filename(xdrs, &objp->name)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_diropokres(xdrs, objp) + XDR *xdrs; + diropokres *objp; +{ + if (!xdr_nfs_fh(xdrs, &objp->file)) { + return (FALSE); + } + if (!xdr_fattr(xdrs, &objp->attributes)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_diropres(xdrs, objp) + XDR *xdrs; + diropres *objp; +{ + if (!xdr_nfsstat(xdrs, &objp->status)) { + return (FALSE); + } + switch (objp->status) { + case NFS_OK: + if (!xdr_diropokres(xdrs, &objp->diropres_u.diropres)) { + return (FALSE); + } + break; + } + return (TRUE); +} + + + + +bool_t +xdr_readlinkres(xdrs, objp) + XDR *xdrs; + readlinkres *objp; +{ + if (!xdr_nfsstat(xdrs, &objp->status)) { + return (FALSE); + } + switch (objp->status) { + case NFS_OK: + if (!xdr_nfspath(xdrs, &objp->readlinkres_u.data)) { + return (FALSE); + } + break; + } + return (TRUE); +} + + + + +bool_t +xdr_readargs(xdrs, objp) + XDR *xdrs; + readargs *objp; +{ + if (!xdr_nfs_fh(xdrs, &objp->file)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->offset)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->count)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->totalcount)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_readokres(xdrs, objp) + XDR *xdrs; + readokres *objp; +{ + if (!xdr_fattr(xdrs, &objp->attributes)) { + return (FALSE); + } + if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_readres(xdrs, objp) + XDR *xdrs; + readres *objp; +{ + if (!xdr_nfsstat(xdrs, &objp->status)) { + return (FALSE); + } + switch (objp->status) { + case NFS_OK: + if (!xdr_readokres(xdrs, &objp->readres_u.reply)) { + return (FALSE); + } + break; + } + return (TRUE); +} + + + + +bool_t +xdr_writeargs(xdrs, objp) + XDR *xdrs; + writeargs *objp; +{ + if (!xdr_nfs_fh(xdrs, &objp->file)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->beginoffset)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->offset)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->totalcount)) { + return (FALSE); + } + if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_createargs(xdrs, objp) + XDR *xdrs; + createargs *objp; +{ + if (!xdr_diropargs(xdrs, &objp->where)) { + return (FALSE); + } + if (!xdr_sattr(xdrs, &objp->attributes)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_renameargs(xdrs, objp) + XDR *xdrs; + renameargs *objp; +{ + if (!xdr_diropargs(xdrs, &objp->from)) { + return (FALSE); + } + if (!xdr_diropargs(xdrs, &objp->to)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_linkargs(xdrs, objp) + XDR *xdrs; + linkargs *objp; +{ + if (!xdr_nfs_fh(xdrs, &objp->from)) { + return (FALSE); + } + if (!xdr_diropargs(xdrs, &objp->to)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_symlinkargs(xdrs, objp) + XDR *xdrs; + symlinkargs *objp; +{ + if (!xdr_diropargs(xdrs, &objp->from)) { + return (FALSE); + } + if (!xdr_nfspath(xdrs, &objp->to)) { + return (FALSE); + } + if (!xdr_sattr(xdrs, &objp->attributes)) { + return (FALSE); + } + return (TRUE); +} + + + + +static bool_t +xdr_nfscookie(xdrs, objp) + XDR *xdrs; + nfscookie objp; +{ + if (!xdr_opaque(xdrs, objp, NFS_COOKIESIZE)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_readdirargs(xdrs, objp) + XDR *xdrs; + readdirargs *objp; +{ + if (!xdr_nfs_fh(xdrs, &objp->dir)) { + return (FALSE); + } + if (!xdr_nfscookie(xdrs, objp->cookie)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->count)) { + return (FALSE); + } + return (TRUE); +} + + + + +static bool_t +xdr_entry(xdrs, objp) + XDR *xdrs; + entry *objp; +{ + if (!xdr_u_int(xdrs, &objp->fileid)) { + return (FALSE); + } + if (!xdr_filename(xdrs, &objp->name)) { + return (FALSE); + } + if (!xdr_nfscookie(xdrs, objp->cookie)) { + return (FALSE); + } + if (!xdr_pointer(xdrs, (char **)&objp->nextentry, sizeof(entry), xdr_entry)) { + return (FALSE); + } + return (TRUE); +} + + + + +static bool_t +xdr_dirlist(xdrs, objp) + XDR *xdrs; + dirlist *objp; +{ + if (!xdr_pointer(xdrs, (char **)&objp->entries, sizeof(entry), xdr_entry)) { + return (FALSE); + } + if (!xdr_bool(xdrs, &objp->eof)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_readdirres(xdrs, objp) + XDR *xdrs; + readdirres *objp; +{ + if (!xdr_nfsstat(xdrs, &objp->status)) { + return (FALSE); + } + switch (objp->status) { + case NFS_OK: + if (!xdr_dirlist(xdrs, &objp->readdirres_u.reply)) { + return (FALSE); + } + break; + } + return (TRUE); +} + + + + +bool_t +xdr_statfsokres(xdrs, objp) + XDR *xdrs; + statfsokres *objp; +{ + if (!xdr_u_int(xdrs, &objp->tsize)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->bsize)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->blocks)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->bfree)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->bavail)) { + return (FALSE); + } + return (TRUE); +} + + + + +bool_t +xdr_statfsres(xdrs, objp) + XDR *xdrs; + statfsres *objp; +{ + if (!xdr_nfsstat(xdrs, &objp->status)) { + return (FALSE); + } + switch (objp->status) { + case NFS_OK: + if (!xdr_statfsokres(xdrs, &objp->statfsres_u.reply)) { + return (FALSE); + } + break; + } + return (TRUE); +} diff --git a/usr.sbin/amd/text/COPYRIGHT b/usr.sbin/amd/text/COPYRIGHT new file mode 100644 index 0000000..f2e96a6 --- /dev/null +++ b/usr.sbin/amd/text/COPYRIGHT @@ -0,0 +1,3 @@ +Copyright (c) 1990 Jan-Simon Pendry +Copyright (c) 1990 Imperial College of Science, Technology & Medicine +Copyright (c) 1990, 1993 The Regents of the University of California. diff --git a/usr.sbin/amd/text/INSTALL b/usr.sbin/amd/text/INSTALL new file mode 100644 index 0000000..d35aaaa --- /dev/null +++ b/usr.sbin/amd/text/INSTALL @@ -0,0 +1,194 @@ +Installation Notes for Amd. + +NOTE: Please read all of this before starting. + It is not very long and may save you time in the long term. + +1. ``Getting started...'' + +If you don't know what an Automounter does for you then read the +documentation in doc/amdref.texinfo. You can either use TeX to print +it out or read it directly using the GNU info package. + +2. ``Find out what version of UN*X you are running...'' + +To install Amd you need a port for your version of UN*X. In the +config/ directory are several files called os-*.h. One of these +should correspond to your version of UN*X. Run the program +"config/os-type" to find out what system Amd thinks you have. Check +the correspondong config/os-??? file to make sure that you and Amd are +in agreement. If os-type returns "unknown" then either no-one has yet +done a port, or your version of UN*X is so braindead that a port is +not possible (e.g. System V without reliable signals). The current +known operating systems (grouped by architecture) are: + + acis43 (AOS) ACIS 4.3BSD on an IBM RT + aix3 AIX 3.2 + aux Apple A/UX + bsd44 4.4 BSD on whatever + concentrix Concentrix on an Alliant + dgux Data General AViiON + fpx4 Celerity FPX 4.1/2 + hlh42 4.2 BSD on HLH Orion 1/05 + hpux HP-UX 6.* and 7.* on a HP9000/300 + irix3 SGI Iris + irix4 SGI Iris w/Irix 4.0.x + next NeXT + riscix 4.3 BSD on an Acorn Archimedes + sos3, sos4 SunOS 3.* and 4.* on a Sun-3 and Sun-4 + u2_2 Ultrix 2.2 (or 2.*?) on a VAX (broken) + u3_0 Ultrix 3.0 (or 3.*?) on a VAX (broken) + u4_2 Ultrix 4.2 + umax43 4.3 BSD on an Encore Multimax + xinu43 More/BSD (4.3 BSD) on a VAX or HP9000/300 + + + some others... + +If you do define a new operating system type foo, you may need to create a +file called Makefile.foo which defines the special Makefile parameters. + +3. ``Hacking the Makefile...'' + +Amd tries very hard to determine what type of machine you are using +and how best to compile itself. If this does not work then you will +have to find some heuristic which can differentiate your +configuration. You may need to edit "config/arch" and +"config/os-type". If you do make sure your changes can cope if +/etc/motd is missing and please send it to the address below. + +To check whether things are working, run: + sh config/arch + sh config/os-type + +You may care to tailor some site specific preferences in "Makefile.com". The +variables most likely to be changes are at the top. Any changes should be +added to a file called config/Makefile.local (if they are applicable to all +operating systems at your site) or Makefile.local.foo (where foo is the OS type +as determined in part 2). + +Additionally, some configuration options may be altered in +"config/Makefile.config". This means that you should not need to edit any +distributed files apart from "config/Makefile.config". As a minimum, you +should check: + +* You are using the correct C compiler. Amd, as shipped, does not use GCC. + Note that using GCC version 1.34 or later (e.g. 1.36) gives structure + passing problems with some parts of Sun's RPC library at least on Sun-4's. + The current workaround is to use the system CC to compile the part of the + automounter that gets hit by this problem. [[This is not the same problem + that is fixed by -fpcc-struct-return.]] Amd contains no "register" + declarations, so using old PCC based code generators is probably bad news. + + To use GNU CC, add the following to config/Makefile.local{.os-type}: + + CC = gcc ${GCCOPTS} + +* The installation directory (ETC) is set up correctly. + +* If you are running tests then it may be worth switching on the DEBUG flag + which will cause a running commentary to be printed to the log file. To + compile in the debug code, add the following to + config/Makefile.local{.os-type}: + + DEBUG = -DDEBUG + CCOPTS = -g + + The -g option will also allow you to use gdb. Using dbx is not advisable + since it puts a breakpoint on exit() which causes all of Amd's child + processes to dump core. gdb does not suffer from this problem. + +4. ``Build the executable...'' + +Now you need to compile the automounter. To do this you type: + + make + +in the top-level directory. You can also go into each of the program +directories and just run make there. + +If you are porting to a new machine you may want to do: + + make OS=foo + +where foo is the name of your version of UN*X as determined in part 1, until +you have made the changes to config/os-type and/or config/arch. When the +compilation is complete you will end up with a program called "A.arch_foo/amd". + +Try running: + + A.arch_foo/amd -v + +and check the output. It should look something like: + + Copyright (c) 1990 Jan-Simon Pendry + Copyright (c) 1990 Imperial College of Science, Technology & Medicine + Copyright (c) 1990 The Regents of the University of California. + amd 5.2.1.5 of 90/09/16 13:22:46 5.3Alpha5 #0: Sun Sep 16 13:23:28 BST 1990 + Built by pendry@okeeffe.Berkeley.EDU for a tahoe running bsd44 (big-endian) + Map support for: root, passwd, nis, file, error. + fstypes: ufs, nfs, nfsx, host, link, program, auto, direct, toplvl, error. + +Make sure the O/S and architecture types were correctly derived during the +build. + +5. ``Installation...'' + +If you are not just testing Amd, then you can install it by typing: + + make install + +to install "A.arch_foo/amd" in "/usr/local/etc/amd" (or as otherwise +modified in part 3). + +6. ``Update /etc/rpc'' + +Amq uses Sun RPC to talk to Amd using program number 300019 which has +been registered with Sun. Add the following lines to /etc/rpc or your +YP or Hesiod master: + +# Automount control protocol +amd 300019 amq + +Amd does not require this addition - it just keeps rpcinfo happy. + +7. ``Hanging your machine...'' + +WARNING: THIS MAY HANG YOUR MACHINE IF YOU GET IT WRONG. + +Running Amd with a carelessly thought out mount map can cause your Amd to +enter a deadlock inside the kernel. For example, attempting to automount a +directory which is automounted. This will cause the automounter to issue a mount +request causing the kernel to send an NFS request back to the same automounter, +which is currently stuck in a system call and unable to respond - even +kill -KILL won't get you out of this one. + +There is nothing you can do to fix it without rebooting your machine, so... + +Find a diskless workstation and play with that first before trying this on +your main 200 user service machine (unless you hate your users). Something +like a diskless Sun-4 is best for development testing - you can compile on a +Sun-4 server and run the binary on the diskless node. They reboot very fast +as well between tests. + +Now you can try running Amd. Please read the documentation in doc/Amd.tex +for more details. The configuration file "maps/a_master" provides a sample for +you to play with. Something like: + + ./amd -c 40 -D test,nodaemon /tmp/amnt ../maps/a_master & + +is good for testing. Note that Amd will clean up correctly if you send it a +SIGINT or SIGTERM. Other signals are either ignored or will blow it away, +leaving your machine in a potentially dangerous state. + +Remember that Amd needs to run as root in order to do mounts/unmounts +though it does check this condition somewhere near line one of main(). +It will also need write permission in the working directory if you +have built it with DEBUG defined and your system's mount table is +reflected in a file. In this case watch out for NFS stepping in and +mapping root to nobody. + +8. ``Report what happened...'' + +If anything interesting happened, eg it didn't work, please report it to me +-- Jan-Simon Pendry -- as detailed in the README file. + +$Id: INSTALL,v 5.2.2.2 1992/05/31 16:49:22 jsp Exp $ diff --git a/usr.sbin/amd/text/README b/usr.sbin/amd/text/README new file mode 100644 index 0000000..01d3a8b --- /dev/null +++ b/usr.sbin/amd/text/README @@ -0,0 +1,37 @@ +This program is an automounter. + +This automounter is a value-added, replacement for the SunOS 4 +automount(8) program. Though based on that program in spirit, it +contains no proprietary UN*X source code. + +The version you have here is release 5.3Alpha. + +This program is NOT in the Public Domain - it is covered by +the usual Berkeley software distribution license - but feel free +to take it and change it. + +It is believed to work correctly on Sun-3's (SunOS 3.5, 4.0, 4.1), +Sun-4's (SunOS 4.0, 4.1), HP-9000/300 (HP-UX, MORE/bsd & BSD 4.3 Reno), +IBM RTs (AOS 4.3), IBM RISC System/6000 (AIX 3.1), VAXen (Ultrix 4.0, +MORE/bsd & BSD 4.3 Reno) and a wide variety of other systems. If +your machine is not supported please feel free to try a port, but be +sure to send me a record of the changes you had to make. + + +This is the file text/README. + +See the file text/INSTALL for installation instructions. + +The documentation is in doc/amdref.texinfo. This is in GNU TeXinfo format +and you will need a TeX system before you can print it out. + +Please forward *all* bug reports to Jan-Simon Pendry +quoting the details of the release and your configuration, which can be +obtained by running the command "amd -v". Also send any additional +information which may be relevant such as command line options and the maps +being used. Thanks. + +The manual page (amd/amd.8) only lists the command line options. See the +texinfo document doc/amdref.texinfo for a more detailed discussion. + +$Id: README,v 5.2.2.1 1992/02/09 15:11:35 jsp beta $ diff --git a/usr.sbin/amd/text/amd.start.ex b/usr.sbin/amd/text/amd.start.ex new file mode 100644 index 0000000..d7cdc1f --- /dev/null +++ b/usr.sbin/amd/text/amd.start.ex @@ -0,0 +1,87 @@ +#!/bin/sh - +# +# Copyright (c) 1989 Jan-Simon Pendry +# Copyright (c) 1989 Imperial College of Science, Technology & Medicine +# Copyright (c) 1989, 1993 +# The Regents of the University of California. All rights reserved. +# +# This code is derived from software contributed to Berkeley by +# Jan-Simon Pendry at Imperial College, London. +# +# 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. +# +# @(#)amd.start.ex 8.1 (Berkeley) 6/6/93 +# +# Start amd +# +# $Id: amd.start.ex,v 5.2.2.1 1992/02/09 15:11:32 jsp beta $ +# +PATH=/usr/sbin:/bin:/usr/bin:$PATH export PATH + +# +# Either name of logfile or "syslog" +# +#LOGFILE=syslog +LOGFILE=/var/run/amd.log + +# +# Figure out whether domain name is in host name +# If the hostname is just the machine name then +# pass in the name of the local domain so that the +# hostnames in the map are domain stripped correctly. +# +case `hostname` in +*.*) dmn= ;; +*) dmn='-d doc.ic.ac.uk' +esac + +# +# Zap earlier log file +# +case "$LOGFILE" in +*/*) + mv "$LOGFILE" "$LOGFILE"- + > "$LOGFILE" + ;; +syslog) + : nothing + ;; +esac + +cd /usr/sbin +# +# -r restart +# -d dmn local domain +# -w wait wait between unmount attempts +# -l log logfile or "syslog" +# +eval nice --4 ./amd -p > /var/run/amd.pid -r $dmn -w 240 -l "$LOGFILE" \ + /homes amd.homes -cache:=inc \ + /home amd.home -cache:=inc \ + /vol amd.vol -cache:=inc diff --git a/usr.sbin/arp/Makefile b/usr.sbin/arp/Makefile new file mode 100644 index 0000000..f69a430 --- /dev/null +++ b/usr.sbin/arp/Makefile @@ -0,0 +1,13 @@ +# @(#)Makefile 8.2 (Berkeley) 4/18/94 + +PROG= arp +MAN8= arp.0 +CLEANFILES=arp4.0 + +all: ${PROG} arp4.0 ${MAN8} + +beforeinstall: + install -c -o ${MANOWN} -g ${MANGRP} -m ${MANMODE} arp4.0 \ + ${DESTDIR}${MANDIR}4/arp.0 + +.include diff --git a/usr.sbin/arp/arp.8 b/usr.sbin/arp/arp.8 new file mode 100644 index 0000000..27252dd --- /dev/null +++ b/usr.sbin/arp/arp.8 @@ -0,0 +1,127 @@ +.\" 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. +.\" +.\" @(#)arp.8 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt ARP 8 +.Os BSD 4.3 +.Sh NAME +.Nm arp +.Nd address resolution display and control +.Sh SYNOPSIS +.Nm arp +.Ar hostname +.Nm arp +.Fl a +.Nm arp +.Fl d Ar hostname +.Nm arp +.Fl s Ar hostname ether_addr +.Op Ar temp +.Op Ar pub +.Op Ar trail +.Nm arp +.Fl f Ar filename +.Sh DESCRIPTION +The +.Nm arp +program displays and modifies the Internet-to-Ethernet address translation +tables used by the address resolution protocol +.Pq Xr arp 4 . +With no flags, the program displays the current +.Tn ARP +entry for +.Ar hostname . +The host may be specified by name or by number, +using Internet dot notation. +.Pp +Available options: +.Bl -tag -width Ds +.It Fl a +The program displays all of the current +.Tn ARP +entries. +.It Fl d +A super-user may delete an entry for the host called +.Ar hostname +with the +.Fl d +flag. +.It Fl s Ar hostname ether_addr +Create an +.Tn ARP +entry for the host called +.Ar hostname +with the Ethernet address +.Ar ether_addr . +The Ethernet address is given as six hex bytes separated by colons. +The entry will be permanent unless the word +.Ar temp +is given in the command. +If the word +.Ar pub +is given, the entry will be "published"; i.e., this system will +act as an +.Tn ARP +server, +responding to requests for +.Ar hostname +even though the host address is not its own. +The word +.Ar trail +indicates that trailer encapsulations may be sent to this host. +.It Fl f +Causes the file +.Ar filename +to be read and multiple entries to be set in the +.Tn ARP +tables. Entries +in the file should be of the form +.Pp +.Bd -filled -offset indent -compact +.Ar hostname ether_addr +.Op Ar temp +.Op Ar pub +.Op Ar trail +.Ed +.Pp +with argument meanings as given above. +.El +.Sh SEE ALSO +.Xr inet 3 , +.Xr arp 4 , +.Xr ifconfig 8 +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.3 . diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c new file mode 100644 index 0000000..2182dc8 --- /dev/null +++ b/usr.sbin/arp/arp.c @@ -0,0 +1,514 @@ +/* + * Copyright (c) 1984, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Sun Microsystems, Inc. + * + * 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) 1984, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)arp.c 8.2 (Berkeley) 1/2/94"; +#endif /* not lint */ + +/* + * arp - display, set, and delete arp table entries + */ + + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +extern int errno; +static int pid; +static int kflag; +static int nflag; +static int s = -1; + +main(argc, argv) + int argc; + char **argv; +{ + int ch; + + pid = getpid(); + while ((ch = getopt(argc, argv, "ands")) != EOF) + switch((char)ch) { + case 'a': + dump(0); + exit(0); + case 'd': + if (argc < 3 || argc > 4) + usage(); + delete(argv[2], argv[3]); + exit(0); + case 'n': + nflag = 1; + continue; + case 's': + if (argc < 4 || argc > 7) + usage(); + exit(set(argc-2, &argv[2]) ? 1 : 0); + case '?': + default: + usage(); + } + if (argc != 2) + usage(); + get(argv[1]); + exit(0); +} + +/* + * Process a file to set standard arp entries + */ +file(name) + char *name; +{ + FILE *fp; + int i, retval; + char line[100], arg[5][50], *args[5]; + + if ((fp = fopen(name, "r")) == NULL) { + fprintf(stderr, "arp: cannot open %s\n", name); + exit(1); + } + args[0] = &arg[0][0]; + args[1] = &arg[1][0]; + args[2] = &arg[2][0]; + args[3] = &arg[3][0]; + args[4] = &arg[4][0]; + retval = 0; + while(fgets(line, 100, fp) != NULL) { + i = sscanf(line, "%s %s %s %s %s", arg[0], arg[1], arg[2], + arg[3], arg[4]); + if (i < 2) { + fprintf(stderr, "arp: bad line: %s\n", line); + retval = 1; + continue; + } + if (set(i, args)) + retval = 1; + } + fclose(fp); + return (retval); +} + +getsocket() { + if (s < 0) { + s = socket(PF_ROUTE, SOCK_RAW, 0); + if (s < 0) { + perror("arp: socket"); + exit(1); + } + } +} + +struct sockaddr_in so_mask = {8, 0, 0, { 0xffffffff}}; +struct sockaddr_inarp blank_sin = {sizeof(blank_sin), AF_INET }, sin_m; +struct sockaddr_dl blank_sdl = {sizeof(blank_sdl), AF_LINK }, sdl_m; +int expire_time, flags, export_only, doing_proxy, found_entry; +struct { + struct rt_msghdr m_rtm; + char m_space[512]; +} m_rtmsg; + +/* + * Set an individual arp entry + */ +set(argc, argv) + int argc; + char **argv; +{ + struct hostent *hp; + register struct sockaddr_inarp *sin = &sin_m; + register struct sockaddr_dl *sdl; + register struct rt_msghdr *rtm = &(m_rtmsg.m_rtm); + u_char *ea; + char *host = argv[0], *eaddr = argv[1]; + + getsocket(); + argc -= 2; + argv += 2; + sdl_m = blank_sdl; + sin_m = blank_sin; + sin->sin_addr.s_addr = inet_addr(host); + if (sin->sin_addr.s_addr == -1) { + if (!(hp = gethostbyname(host))) { + fprintf(stderr, "arp: %s: ", host); + herror((char *)NULL); + return (1); + } + bcopy((char *)hp->h_addr, (char *)&sin->sin_addr, + sizeof sin->sin_addr); + } + ea = (u_char *)LLADDR(&sdl_m); + if (ether_aton(eaddr, ea) == 0) + sdl_m.sdl_alen = 6; + doing_proxy = flags = export_only = expire_time = 0; + while (argc-- > 0) { + if (strncmp(argv[0], "temp", 4) == 0) { + struct timeval time; + gettimeofday(&time, 0); + expire_time = time.tv_sec + 20 * 60; + } + else if (strncmp(argv[0], "pub", 3) == 0) { + flags |= RTF_ANNOUNCE; + doing_proxy = SIN_PROXY; + } else if (strncmp(argv[0], "trail", 5) == 0) { + printf("%s: Sending trailers is no longer supported\n", + host); + } + argv++; + } +tryagain: + if (rtmsg(RTM_GET) < 0) { + perror(host); + return (1); + } + sin = (struct sockaddr_inarp *)(rtm + 1); + sdl = (struct sockaddr_dl *)(sin->sin_len + (char *)sin); + if (sin->sin_addr.s_addr == sin_m.sin_addr.s_addr) { + if (sdl->sdl_family == AF_LINK && + (rtm->rtm_flags & RTF_LLINFO) && + !(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) { + case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023: + case IFT_ISO88024: case IFT_ISO88025: + goto overwrite; + } + if (doing_proxy == 0) { + printf("set: can only proxy for %s\n", host); + return (1); + } + if (sin_m.sin_other & SIN_PROXY) { + printf("set: proxy entry exists for non 802 device\n"); + return(1); + } + sin_m.sin_other = SIN_PROXY; + export_only = 1; + goto tryagain; + } +overwrite: + if (sdl->sdl_family != AF_LINK) { + printf("cannot intuit interface index and type for %s\n", host); + return (1); + } + sdl_m.sdl_type = sdl->sdl_type; + sdl_m.sdl_index = sdl->sdl_index; + return (rtmsg(RTM_ADD)); +} + +/* + * Display an individual arp entry + */ +get(host) + char *host; +{ + struct hostent *hp; + struct sockaddr_inarp *sin = &sin_m; + u_char *ea; + + sin_m = blank_sin; + sin->sin_addr.s_addr = inet_addr(host); + if (sin->sin_addr.s_addr == -1) { + if (!(hp = gethostbyname(host))) { + fprintf(stderr, "arp: %s: ", host); + herror((char *)NULL); + exit(1); + } + bcopy((char *)hp->h_addr, (char *)&sin->sin_addr, + sizeof sin->sin_addr); + } + dump(sin->sin_addr.s_addr); + if (found_entry == 0) { + printf("%s (%s) -- no entry\n", + host, inet_ntoa(sin->sin_addr)); + exit(1); + } +} + +/* + * Delete an arp entry + */ +delete(host, info) + char *host; + char *info; +{ + struct hostent *hp; + register struct sockaddr_inarp *sin = &sin_m; + register struct rt_msghdr *rtm = &m_rtmsg.m_rtm; + struct sockaddr_dl *sdl; + u_char *ea; + char *eaddr; + + if (info && strncmp(info, "pro", 3) ) + export_only = 1; + getsocket(); + sin_m = blank_sin; + sin->sin_addr.s_addr = inet_addr(host); + if (sin->sin_addr.s_addr == -1) { + if (!(hp = gethostbyname(host))) { + fprintf(stderr, "arp: %s: ", host); + herror((char *)NULL); + return (1); + } + bcopy((char *)hp->h_addr, (char *)&sin->sin_addr, + sizeof sin->sin_addr); + } +tryagain: + if (rtmsg(RTM_GET) < 0) { + perror(host); + return (1); + } + sin = (struct sockaddr_inarp *)(rtm + 1); + sdl = (struct sockaddr_dl *)(sin->sin_len + (char *)sin); + if (sin->sin_addr.s_addr == sin_m.sin_addr.s_addr) { + if (sdl->sdl_family == AF_LINK && + (rtm->rtm_flags & RTF_LLINFO) && + !(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) { + case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023: + case IFT_ISO88024: case IFT_ISO88025: + goto delete; + } + } + if (sin_m.sin_other & SIN_PROXY) { + fprintf(stderr, "delete: can't locate %s\n",host); + return (1); + } else { + sin_m.sin_other = SIN_PROXY; + goto tryagain; + } +delete: + if (sdl->sdl_family != AF_LINK) { + printf("cannot locate %s\n", host); + return (1); + } + if (rtmsg(RTM_DELETE) == 0) + printf("%s (%s) deleted\n", host, inet_ntoa(sin->sin_addr)); +} + +/* + * Dump the entire arp table + */ +dump(addr) +u_long addr; +{ + int mib[6]; + size_t needed; + char *host, *malloc(), *lim, *buf, *next; + struct rt_msghdr *rtm; + struct sockaddr_inarp *sin; + struct sockaddr_dl *sdl; + extern int h_errno; + struct hostent *hp; + + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = AF_INET; + mib[4] = NET_RT_FLAGS; + mib[5] = RTF_LLINFO; + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + quit("route-sysctl-estimate"); + if ((buf = malloc(needed)) == NULL) + quit("malloc"); + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) + quit("actual retrieval of routing table"); + lim = buf + needed; + for (next = buf; next < lim; next += rtm->rtm_msglen) { + rtm = (struct rt_msghdr *)next; + sin = (struct sockaddr_inarp *)(rtm + 1); + sdl = (struct sockaddr_dl *)(sin + 1); + if (addr) { + if (addr != sin->sin_addr.s_addr) + continue; + found_entry = 1; + } + if (nflag == 0) + hp = gethostbyaddr((caddr_t)&(sin->sin_addr), + sizeof sin->sin_addr, AF_INET); + else + hp = 0; + if (hp) + host = hp->h_name; + else { + host = "?"; + if (h_errno == TRY_AGAIN) + nflag = 1; + } + printf("%s (%s) at ", host, inet_ntoa(sin->sin_addr)); + if (sdl->sdl_alen) + ether_print(LLADDR(sdl)); + else + printf("(incomplete)"); + if (rtm->rtm_rmx.rmx_expire == 0) + printf(" permanent"); + if (sin->sin_other & SIN_PROXY) + printf(" published (proxy only)"); + if (rtm->rtm_addrs & RTA_NETMASK) { + sin = (struct sockaddr_inarp *) + (sdl->sdl_len + (char *)sdl); + if (sin->sin_addr.s_addr == 0xffffffff) + printf(" published"); + if (sin->sin_len != 8) + printf("(wierd)"); + } + printf("\n"); + } +} + +ether_print(cp) + u_char *cp; +{ + printf("%x:%x:%x:%x:%x:%x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]); +} + +ether_aton(a, n) + char *a; + u_char *n; +{ + int i, o[6]; + + i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o[0], &o[1], &o[2], + &o[3], &o[4], &o[5]); + if (i != 6) { + fprintf(stderr, "arp: invalid Ethernet address '%s'\n", a); + return (1); + } + for (i=0; i<6; i++) + n[i] = o[i]; + return (0); +} + +usage() +{ + printf("usage: arp hostname\n"); + printf(" arp -a [kernel] [kernel_memory]\n"); + printf(" arp -d hostname\n"); + printf(" arp -s hostname ether_addr [temp] [pub]\n"); + printf(" arp -f filename\n"); + exit(1); +} + +rtmsg(cmd) +{ + static int seq; + int rlen; + register struct rt_msghdr *rtm = &m_rtmsg.m_rtm; + register char *cp = m_rtmsg.m_space; + register int l; + + errno = 0; + if (cmd == RTM_DELETE) + goto doit; + bzero((char *)&m_rtmsg, sizeof(m_rtmsg)); + rtm->rtm_flags = flags; + rtm->rtm_version = RTM_VERSION; + + switch (cmd) { + default: + fprintf(stderr, "arp: internal wrong cmd\n"); + exit(1); + case RTM_ADD: + rtm->rtm_addrs |= RTA_GATEWAY; + rtm->rtm_rmx.rmx_expire = expire_time; + rtm->rtm_inits = RTV_EXPIRE; + rtm->rtm_flags |= (RTF_HOST | RTF_STATIC); + sin_m.sin_other = 0; + if (doing_proxy) { + if (export_only) + sin_m.sin_other = SIN_PROXY; + else { + rtm->rtm_addrs |= RTA_NETMASK; + rtm->rtm_flags &= ~RTF_HOST; + } + } + /* FALLTHROUGH */ + case RTM_GET: + rtm->rtm_addrs |= RTA_DST; + } +#define NEXTADDR(w, s) \ + if (rtm->rtm_addrs & (w)) { \ + bcopy((char *)&s, cp, sizeof(s)); cp += sizeof(s);} + + NEXTADDR(RTA_DST, sin_m); + NEXTADDR(RTA_GATEWAY, sdl_m); + NEXTADDR(RTA_NETMASK, so_mask); + + rtm->rtm_msglen = cp - (char *)&m_rtmsg; +doit: + l = rtm->rtm_msglen; + rtm->rtm_seq = ++seq; + rtm->rtm_type = cmd; + if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) { + if (errno != ESRCH || cmd != RTM_DELETE) { + perror("writing to routing socket"); + return (-1); + } + } + do { + l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); + } while (l > 0 && (rtm->rtm_seq != seq || rtm->rtm_pid != pid)); + if (l < 0) + (void) fprintf(stderr, "arp: read from routing socket: %s\n", + strerror(errno)); + return (0); +} + +quit(msg) +char *msg; +{ + fprintf(stderr, "%s\n", msg); + exit(1); +} diff --git a/usr.sbin/arp/arp4.4 b/usr.sbin/arp/arp4.4 new file mode 100644 index 0000000..0cd7161 --- /dev/null +++ b/usr.sbin/arp/arp4.4 @@ -0,0 +1,124 @@ +.\" Copyright (c) 1985, 1986, 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. +.\" +.\" @(#)arp4.4 6.5 (Berkeley) 4/18/94 +.\" +.Dd April 18, 1994 +.Dt ARP 4 +.Os BSD 4 +.Sh NAME +.Nm arp +.Nd Address Resolution Protocol +.Sh SYNOPSIS +.Em "pseudo-device ether" +.Sh DESCRIPTION +The Address Resolution Protocol (ARP) is a protocol used to dynamically +map between Internet host addresses and 10Mb/s Ethernet addresses. +It is used by all the 10Mb/s Ethernet interface drivers. +It is not specific to Internet protocols or to 10Mb/s Ethernet, +but this implementation currently supports only that combination. +.Pp +ARP caches Internet-Ethernet address mappings. +When an interface requests a mapping for an address not in the cache, +ARP queues the message which requires the mapping and broadcasts +a message on the associated network requesting the address mapping. +If a response is provided, the new mapping is cached and any pending +message is transmitted. +ARP will queue at most one packet while waiting for a response to a +mapping request; +only the most recently ``transmitted'' packet is kept. +If the target host does not respond after several requests, +the host is considered to be down for a short period (normally 20 seconds), +allowing an error to be returned to transmission attempts during this +interval. +The error is +.Li EHOSTDOWN +for a non-responding destination host, and +.Li EHOSTUNREACH +for a non-responding router. +.Pp +The ARP cache is stored in the system routing table as +dynamically-created host routes. +The route to a directly-attached Ethernet network is installed as a +.Dq cloning +route (one with the +.Li RTF_CLONING +flag set), +causing routes to individual hosts on that network to be created on +demand. +These routes time out periodically (normally 20 minutes after validated; +entries are not validated when not in use). +An entry for a host which is not responding is a +.Dq reject +route (one with the +.Li RTF_REJECT +flag set). +.Pp +ARP entries may be added, deleted or changed with the +.Xr arp 8 +utility. +Manually-added entries may be temporary or permanent, +and may be +.Dq published , +in which case the system will respond to ARP requests for that host +as if it were the target of the request. +.Pp +In the past, +ARP was used to negotiate the use of a trailer encapsulation. +This is no longer supported. +.Pp +ARP watches passively for hosts impersonating the local host (i.e. a host +which responds to an ARP mapping request for the local host's address). +.Sh DIAGNOSTICS +.Em "duplicate IP address %x!! sent from ethernet address: %x:%x:%x:%x:%x:%x." +ARP has discovered another host on the local network which responds to +mapping requests for its own Internet address with a different Ethernet +address, generally indicating that two hosts are attempting to use the +same Internet address. +.Sh SEE ALSO +.Xr inet 4 , +.Xr route 4 , +.Xr arp 8 , +.Xr ifconfig 8 , +.Xr route 8 +.sp +.Rs +.%A Plummer, D. +.%B "An Ethernet Address Resolution Protocol" +.%T RFC826 +.Re +.Rs +.%A Leffler, S.J. +.%A Karels, M.J. +.%B "Trailer Encapsulations +.%T RFC893 +.Re + diff --git a/usr.sbin/bad144/Makefile b/usr.sbin/bad144/Makefile new file mode 100644 index 0000000..f3e10da --- /dev/null +++ b/usr.sbin/bad144/Makefile @@ -0,0 +1,7 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= bad144 +MAN8= bad144.0 +MANSUBDIR=/vax + +.include diff --git a/usr.sbin/bad144/bad144.8 b/usr.sbin/bad144/bad144.8 new file mode 100644 index 0000000..9ea8c88 --- /dev/null +++ b/usr.sbin/bad144/bad144.8 @@ -0,0 +1,186 @@ +.\" Copyright (c) 1980, 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. +.\" +.\" @(#)bad144.8 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt BAD144 8 +.Os BSD 4 +.Sh NAME +.Nm bad144 +.Nd read/write dec standard 144 bad sector information +.Sh SYNOPSIS +.Nm bad144 +.Op Fl c +.Op Fl f +.Op Fl v +.Ar disk +.Oo +.Ar sno +.Op Ar bad ... +.Oc +.Nm bad144 +.Fl a +.Op Fl c +.Op Fl f +.Op Fl v +.Ar disk +.Op Ar bad ... +.Sh DESCRIPTION +.Nm Bad144 +can be used to inspect the information stored on a disk that is used by +the disk drivers to implement bad sector forwarding. +.Pp +Available options: +.Pp +.Bl -tag -width Ds +.It Fl a +The argument list consists of new bad sectors to be added to an existing +list. +The new sectors are sorted into the list, +which must have been in order. +Replacement sectors are moved to accommodate the additions; +the new replacement sectors are cleared. +.It Fl c +Forces an attempt to copy the old sector to the replacement, +and may be useful when replacing an unreliable sector. +.It Fl f +For a RP06, RM03, RM05, Fujitsu Eagle, +or +.Tn SMD +disk on a Massbus, the +.Fl f +option may be used to mark the new bad sectors as ``bad'' +by reformatting them as unusable sectors. +This option is +.Em required unless +the sectors have already been marked bad, +or the system will not be notified that it should use the replacement sector. +This option may be used while running multiuser; it is no longer necessary +to perform format operations while running single-user. +.It Fl v +The entire process is described as it happens in gory detail if +.Fl v +(verbose) is given. +.El +.Pp +The format of +the information is specified by +.Tn DEC +standard 144, as follows. +The bad sector information is located in the first 5 even numbered sectors +of the last track of the disk pack. There are five identical copies of +the information, described by the +.Ar dkbad +structure. +.Pp +Replacement sectors are allocated starting with the first sector before +the bad sector information and working backwards towards the beginning +of the disk. A maximum of 126 bad sectors are supported. The position +of the bad sector in the bad sector table determines the replacement +sector to which it corresponds. +The bad sectors must be listed in ascending order. +.Pp +The bad sector information and replacement sectors are conventionally +only accessible through the ``c'' file system partition of the disk. If +that partition is used for a file system, the user is responsible for +making sure that it does not overlap the bad sector information or any +replacement sectors. +Thus, one track plus 126 sectors must be reserved to allow use +of all of the possible bad sector replacements. +.Pp +The bad sector structure is as follows: +.Bd -literal +struct dkbad { + long bt_csn; /* cartridge serial number */ + u_short bt_mbz; /* unused; should be 0 */ + u_short bt_flag; /* -1 => alignment cartridge */ + struct bt_bad { + u_short bt_cyl; /* bad sector cylinder number */ + u_short bt_trksec; /* track and sector number */ + } bt_bad[126]; +}; +.Ed +.Pp +Unused slots in the +.Ar bt_bad +array are filled with all bits set, a putatively +illegal value. +.Pp +.Nm Bad144 +is invoked by giving a device name (e.g. hk0, hp1, etc.). +With no optional arguments +it reads the first sector of the last track +of the corresponding disk and prints out the bad sector information. +It issues a warning if the bad sectors are out of order. +.Nm Bad144 +may also be invoked with a serial number for the pack and a list +of bad sectors. +It will write the supplied information into all copies +of the bad-sector file, replacing any previous information. +Note, however, that +.Nm bad144 +does not arrange for the specified sectors to be marked bad in this case. +This procedure should only be used to restore known bad sector information which +was destroyed. +.Pp +It is no longer necessary to reboot to allow the kernel +to reread the bad-sector table from the drive. +.Sh SEE ALSO +.Xr badsect 8 , +.Xr format 8 +.Sh BUGS +It should be possible to format disks on-line under +.Tn UNIX . +.Pp +It should be possible to mark bad sectors on drives of all type. +.Pp +On an 11/750, +the standard bootstrap drivers used to boot the system do +not understand bad sectors, +handle +.Tn ECC +errors, or the special +.Tn SSE +(skip sector) errors of RM80-type disks. +This means that none of these errors can occur when reading the file +.Pa /vmunix +to boot. Sectors 0-15 of the disk drive +must also not have any of these errors. +.Pp +The drivers which write a system core image on disk after a crash do not +handle errors; thus the crash dump area must be free of errors and bad +sectors. +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.1 . diff --git a/usr.sbin/bad144/bad144.c b/usr.sbin/bad144/bad144.c new file mode 100644 index 0000000..0afa9e4 --- /dev/null +++ b/usr.sbin/bad144/bad144.c @@ -0,0 +1,662 @@ +/* + * Copyright (c) 1993, 198019861988 + * 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) 1993, 198019861988\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif not lint + +#ifndef lint +static char sccsid[] = "@(#)bad144.c 8.1 (Berkeley) 6/6/93"; +#endif not lint + +/* + * bad144 + * + * This program prints and/or initializes a bad block record for a pack, + * in the format used by the DEC standard 144. + * It can also add bad sector(s) to the record, moving the sector + * replacements as necessary. + * + * It is preferable to write the bad information with a standard formatter, + * but this program will do. + * + * RP06 sectors are marked as bad by inverting the format bit in the + * header; on other drives the valid-sector bit is cleared. + */ +#include +#include +#include +#include +#include +#include + +#include +#include + +#define RETRIES 10 /* number of retries on reading old sectors */ +#define RAWPART "c" /* disk partition containing badsector tables */ + +int fflag, add, copy, verbose, nflag; +int compare(); +int dups; +int badfile = -1; /* copy of badsector table to use, -1 if any */ +#define MAXSECSIZE 1024 +struct dkbad curbad, oldbad; +#define DKBAD_MAGIC 0 + +char label[BBSIZE]; +daddr_t size, getold(), badsn(); +struct disklabel *dp; +char name[BUFSIZ]; +char *malloc(); +off_t lseek(); + +main(argc, argv) + int argc; + char *argv[]; +{ + register struct bt_bad *bt; + daddr_t sn, bn[126]; + int i, f, nbad, new, bad, errs; + + argc--, argv++; + while (argc > 0 && **argv == '-') { + (*argv)++; + while (**argv) { + switch (**argv) { +#if vax + case 'f': + fflag++; + break; +#endif + case 'a': + add++; + break; + case 'c': + copy++; + break; + case 'v': + verbose++; + break; + case 'n': + nflag++; + verbose++; + break; + default: + if (**argv >= '0' && **argv <= '4') { + badfile = **argv - '0'; + break; + } + goto usage; + } + (*argv)++; + } + argc--, argv++; + } + if (argc < 1) { +usage: + fprintf(stderr, + "usage: bad144 [ -f ] disk [ snum [ bn ... ] ]\n"); + fprintf(stderr, + "to read or overwrite bad-sector table, e.g.: bad144 hp0\n"); + fprintf(stderr, + "or bad144 -a [ -f ] [ -c ] disk bn ...\n"); + fprintf(stderr, "where options are:\n"); + fprintf(stderr, "\t-a add new bad sectors to the table\n"); + fprintf(stderr, "\t-f reformat listed sectors as bad\n"); + fprintf(stderr, "\t-c copy original sector to replacement\n"); + exit(1); + } + if (argv[0][0] != '/') + (void)sprintf(name, "%s/r%s%s", _PATH_DEV, argv[0], RAWPART); + else + strcpy(name, argv[0]); + f = open(name, argc == 1? O_RDONLY : O_RDWR); + if (f < 0) + Perror(name); + if (read(f, label, sizeof(label)) < 0) + Perror("read"); + for (dp = (struct disklabel *)(label + LABELOFFSET); + dp < (struct disklabel *) + (label + sizeof(label) - sizeof(struct disklabel)); + dp = (struct disklabel *)((char *)dp + 64)) + if (dp->d_magic == DISKMAGIC && dp->d_magic2 == DISKMAGIC) + break; + if (dp->d_magic != DISKMAGIC || dp->d_magic2 != DISKMAGIC) { + fprintf(stderr, "Bad pack magic number (pack is unlabeled)\n"); + exit(1); + } + if (dp->d_secsize > MAXSECSIZE || dp->d_secsize <= 0) { + fprintf(stderr, "Disk sector size too large/small (%d)\n", + dp->d_secsize); + exit(7); + } + size = dp->d_nsectors * dp->d_ntracks * dp->d_ncylinders; + argc--; + argv++; + if (argc == 0) { + sn = getold(f, &oldbad); + printf("bad block information at sector %d in %s:\n", + sn, name); + printf("cartridge serial number: %d(10)\n", oldbad.bt_csn); + switch (oldbad.bt_flag) { + + case (u_short)-1: + printf("alignment cartridge\n"); + break; + + case DKBAD_MAGIC: + break; + + default: + printf("bt_flag=%x(16)?\n", oldbad.bt_flag); + break; + } + bt = oldbad.bt_bad; + for (i = 0; i < 126; i++) { + bad = (bt->bt_cyl<<16) + bt->bt_trksec; + if (bad < 0) + break; + printf("sn=%d, cn=%d, tn=%d, sn=%d\n", badsn(bt), + bt->bt_cyl, bt->bt_trksec>>8, bt->bt_trksec&0xff); + bt++; + } + (void) checkold(&oldbad); + exit(0); + } + if (add) { + /* + * Read in the old badsector table. + * Verify that it makes sense, and the bad sectors + * are in order. Copy the old table to the new one. + */ + (void) getold(f, &oldbad); + i = checkold(&oldbad); + if (verbose) + printf("Had %d bad sectors, adding %d\n", i, argc); + if (i + argc > 126) { + printf("bad144: not enough room for %d more sectors\n", + argc); + printf("limited to 126 by information format\n"); + exit(1); + } + curbad = oldbad; + } else { + curbad.bt_csn = atoi(*argv++); + argc--; + curbad.bt_mbz = 0; + curbad.bt_flag = DKBAD_MAGIC; + if (argc > 126) { + printf("bad144: too many bad sectors specified\n"); + printf("limited to 126 by information format\n"); + exit(1); + } + i = 0; + } + errs = 0; + new = argc; + while (argc > 0) { + daddr_t sn = atoi(*argv++); + argc--; + if (sn < 0 || sn >= size) { + printf("%d: out of range [0,%d) for disk %s\n", + sn, size, dp->d_typename); + errs++; + continue; + } + bn[i] = sn; + curbad.bt_bad[i].bt_cyl = sn / (dp->d_nsectors*dp->d_ntracks); + sn %= (dp->d_nsectors*dp->d_ntracks); + curbad.bt_bad[i].bt_trksec = + ((sn/dp->d_nsectors) << 8) + (sn%dp->d_nsectors); + i++; + } + if (errs) + exit(1); + nbad = i; + while (i < 126) { + curbad.bt_bad[i].bt_trksec = -1; + curbad.bt_bad[i].bt_cyl = -1; + i++; + } + if (add) { + /* + * Sort the new bad sectors into the list. + * Then shuffle the replacement sectors so that + * the previous bad sectors get the same replacement data. + */ + qsort((char *)curbad.bt_bad, nbad, sizeof (struct bt_bad), + compare); + if (dups) { + fprintf(stderr, +"bad144: bad sectors have been duplicated; can't add existing sectors\n"); + exit(3); + } + shift(f, nbad, nbad-new); + } + if (badfile == -1) + i = 0; + else + i = badfile * 2; + for (; i < 10 && i < dp->d_nsectors; i += 2) { + if (lseek(f, dp->d_secsize * (size - dp->d_nsectors + i), + L_SET) < 0) + Perror("lseek"); + if (verbose) + printf("write badsect file at %d\n", + size - dp->d_nsectors + i); + if (nflag == 0 && write(f, (caddr_t)&curbad, sizeof(curbad)) != + sizeof(curbad)) { + char msg[80]; + (void)sprintf(msg, "bad144: write bad sector file %d", + i/2); + perror(msg); + } + if (badfile != -1) + break; + } +#ifdef vax + if (nflag == 0 && fflag) + for (i = nbad - new; i < nbad; i++) + format(f, bn[i]); +#endif +#ifdef DIOCSBAD + if (nflag == 0 && ioctl(f, DIOCSBAD, (caddr_t)&curbad) < 0) + fprintf(stderr, + "Can't sync bad-sector file; reboot for changes to take effect\n"); +#endif + exit(0); +} + +daddr_t +getold(f, bad) +struct dkbad *bad; +{ + register int i; + daddr_t sn; + char msg[80]; + + if (badfile == -1) + i = 0; + else + i = badfile * 2; + for (; i < 10 && i < dp->d_nsectors; i += 2) { + sn = size - dp->d_nsectors + i; + if (lseek(f, sn * dp->d_secsize, L_SET) < 0) + Perror("lseek"); + if (read(f, (char *) bad, dp->d_secsize) == dp->d_secsize) { + if (i > 0) + printf("Using bad-sector file %d\n", i/2); + return(sn); + } + (void)sprintf(msg, "bad144: read bad sector file at sn %d", sn); + perror(msg); + if (badfile != -1) + break; + } + fprintf(stderr, "bad144: %s: can't read bad block info\n", name); + exit(1); + /*NOTREACHED*/ +} + +checkold() +{ + register int i; + register struct bt_bad *bt; + daddr_t sn, lsn; + int errors = 0, warned = 0; + + if (oldbad.bt_flag != DKBAD_MAGIC) { + fprintf(stderr, "bad144: %s: bad flag in bad-sector table\n", + name); + errors++; + } + if (oldbad.bt_mbz != 0) { + fprintf(stderr, "bad144: %s: bad magic number\n", name); + errors++; + } + bt = oldbad.bt_bad; + for (i = 0; i < 126; i++, bt++) { + if (bt->bt_cyl == 0xffff && bt->bt_trksec == 0xffff) + break; + if ((bt->bt_cyl >= dp->d_ncylinders) || + ((bt->bt_trksec >> 8) >= dp->d_ntracks) || + ((bt->bt_trksec & 0xff) >= dp->d_nsectors)) { + fprintf(stderr, + "bad144: cyl/trk/sect out of range in existing entry: "); + fprintf(stderr, "sn=%d, cn=%d, tn=%d, sn=%d\n", + badsn(bt), bt->bt_cyl, bt->bt_trksec>>8, + bt->bt_trksec & 0xff); + errors++; + } + sn = (bt->bt_cyl * dp->d_ntracks + + (bt->bt_trksec >> 8)) * + dp->d_nsectors + (bt->bt_trksec & 0xff); + if (i > 0 && sn < lsn && !warned) { + fprintf(stderr, + "bad144: bad sector file is out of order\n"); + errors++; + warned++; + } + if (i > 0 && sn == lsn) { + fprintf(stderr, + "bad144: bad sector file contains duplicates (sn %d)\n", + sn); + errors++; + } + lsn = sn; + } + if (errors) + exit(1); + return (i); +} + +/* + * Move the bad sector replacements + * to make room for the new bad sectors. + * new is the new number of bad sectors, old is the previous count. + */ +shift(f, new, old) +{ + daddr_t repl; + + /* + * First replacement is last sector of second-to-last track. + */ + repl = size - dp->d_nsectors - 1; + new--; old--; + while (new >= 0 && new != old) { + if (old < 0 || + compare(&curbad.bt_bad[new], &oldbad.bt_bad[old]) > 0) { + /* + * Insert new replacement here-- copy original + * sector if requested and possible, + * otherwise write a zero block. + */ + if (!copy || + !blkcopy(f, badsn(&curbad.bt_bad[new]), repl - new)) + blkzero(f, repl - new); + } else { + if (blkcopy(f, repl - old, repl - new) == 0) + fprintf(stderr, + "Can't copy replacement sector %d to %d\n", + repl-old, repl-new); + old--; + } + new--; + } +} + +char *buf; + +/* + * Copy disk sector s1 to s2. + */ +blkcopy(f, s1, s2) +daddr_t s1, s2; +{ + register tries, n; + + if (buf == (char *)NULL) { + buf = malloc((unsigned)dp->d_secsize); + if (buf == (char *)NULL) { + fprintf(stderr, "Out of memory\n"); + exit(20); + } + } + for (tries = 0; tries < RETRIES; tries++) { + if (lseek(f, dp->d_secsize * s1, L_SET) < 0) + Perror("lseek"); + if ((n = read(f, buf, dp->d_secsize)) == dp->d_secsize) + break; + } + if (n != dp->d_secsize) { + fprintf(stderr, "bad144: can't read sector, %d: ", s1); + if (n < 0) + perror((char *)0); + return(0); + } + if (lseek(f, dp->d_secsize * s2, L_SET) < 0) + Perror("lseek"); + if (verbose) + printf("copying %d to %d\n", s1, s2); + if (nflag == 0 && write(f, buf, dp->d_secsize) != dp->d_secsize) { + fprintf(stderr, + "bad144: can't write replacement sector, %d: ", s2); + perror((char *)0); + return(0); + } + return(1); +} + +char *zbuf; + +blkzero(f, sn) +daddr_t sn; +{ + + if (zbuf == (char *)NULL) { + zbuf = malloc((unsigned)dp->d_secsize); + if (zbuf == (char *)NULL) { + fprintf(stderr, "Out of memory\n"); + exit(20); + } + } + if (lseek(f, dp->d_secsize * sn, L_SET) < 0) + Perror("lseek"); + if (verbose) + printf("zeroing %d\n", sn); + if (nflag == 0 && write(f, zbuf, dp->d_secsize) != dp->d_secsize) { + fprintf(stderr, + "bad144: can't write replacement sector, %d: ", sn); + perror((char *)0); + } +} + +compare(b1, b2) +register struct bt_bad *b1, *b2; +{ + if (b1->bt_cyl > b2->bt_cyl) + return(1); + if (b1->bt_cyl < b2->bt_cyl) + return(-1); + if (b1->bt_trksec == b2->bt_trksec) + dups++; + return (b1->bt_trksec - b2->bt_trksec); +} + +daddr_t +badsn(bt) +register struct bt_bad *bt; +{ + return ((bt->bt_cyl*dp->d_ntracks + (bt->bt_trksec>>8)) * dp->d_nsectors + + (bt->bt_trksec&0xff)); +} + +#ifdef vax + +struct rp06hdr { + short h_cyl; + short h_trksec; + short h_key1; + short h_key2; + char h_data[512]; +#define RP06_FMT 010000 /* 1 == 16 bit, 0 == 18 bit */ +}; + +/* + * Most massbus and unibus drives + * have headers of this form + */ +struct hpuphdr { + u_short hpup_cyl; + u_char hpup_sect; + u_char hpup_track; + char hpup_data[512]; +#define HPUP_OKSECT 0xc000 /* this normally means sector is good */ +#define HPUP_16BIT 0x1000 /* 1 == 16 bit format */ +}; +int rp06format(), hpupformat(); + +struct formats { + char *f_name; /* disk name */ + int f_bufsize; /* size of sector + header */ + int f_bic; /* value to bic in hpup_cyl */ + int (*f_routine)(); /* routine for special handling */ +} formats[] = { + { "rp06", sizeof (struct rp06hdr), RP06_FMT, rp06format }, + { "eagle", sizeof (struct hpuphdr), HPUP_OKSECT, hpupformat }, + { "capricorn", sizeof (struct hpuphdr), HPUP_OKSECT, hpupformat }, + { "rm03", sizeof (struct hpuphdr), HPUP_OKSECT, hpupformat }, + { "rm05", sizeof (struct hpuphdr), HPUP_OKSECT, hpupformat }, + { "9300", sizeof (struct hpuphdr), HPUP_OKSECT, hpupformat }, + { "9766", sizeof (struct hpuphdr), HPUP_OKSECT, hpupformat }, + { 0, 0, 0, 0 } +}; + +/*ARGSUSED*/ +hpupformat(fp, dp, blk, buf, count) + struct formats *fp; + struct disklabel *dp; + daddr_t blk; + char *buf; + int count; +{ + struct hpuphdr *hdr = (struct hpuphdr *)buf; + int sect; + + if (count < sizeof(struct hpuphdr)) { + hdr->hpup_cyl = (HPUP_OKSECT | HPUP_16BIT) | + (blk / (dp->d_nsectors * dp->d_ntracks)); + sect = blk % (dp->d_nsectors * dp->d_ntracks); + hdr->hpup_track = (u_char)(sect / dp->d_nsectors); + hdr->hpup_sect = (u_char)(sect % dp->d_nsectors); + } + return (0); +} + +/*ARGSUSED*/ +rp06format(fp, dp, blk, buf, count) + struct formats *fp; + struct disklabel *dp; + daddr_t blk; + char *buf; + int count; +{ + + if (count < sizeof(struct rp06hdr)) { + fprintf(stderr, "Can't read header on blk %d, can't reformat\n", + blk); + return (-1); + } + return (0); +} + +format(fd, blk) + int fd; + daddr_t blk; +{ + register struct formats *fp; + static char *buf; + static char bufsize; + struct format_op fop; + int n; + + for (fp = formats; fp->f_name; fp++) + if (strcmp(dp->d_typename, fp->f_name) == 0) + break; + if (fp->f_name == 0) { + fprintf(stderr, "bad144: don't know how to format %s disks\n", + dp->d_typename); + exit(2); + } + if (buf && bufsize < fp->f_bufsize) { + free(buf); + buf = NULL; + } + if (buf == NULL) + buf = malloc((unsigned)fp->f_bufsize); + if (buf == NULL) { + fprintf(stderr, "bad144: can't allocate sector buffer\n"); + exit(3); + } + bufsize = fp->f_bufsize; + /* + * Here we do the actual formatting. All we really + * do is rewrite the sector header and flag the bad sector + * according to the format table description. If a special + * purpose format routine is specified, we allow it to + * process the sector as well. + */ + if (verbose) + printf("format blk %d\n", blk); + bzero((char *)&fop, sizeof(fop)); + fop.df_buf = buf; + fop.df_count = fp->f_bufsize; + fop.df_startblk = blk; + bzero(buf, fp->f_bufsize); + if (ioctl(fd, DIOCRFORMAT, &fop) < 0) + perror("bad144: read format"); + if (fp->f_routine && + (*fp->f_routine)(fp, dp, blk, buf, fop.df_count) != 0) + return; + if (fp->f_bic) { + struct hpuphdr *xp = (struct hpuphdr *)buf; + + xp->hpup_cyl &= ~fp->f_bic; + } + if (nflag) + return; + bzero((char *)&fop, sizeof(fop)); + fop.df_buf = buf; + fop.df_count = fp->f_bufsize; + fop.df_startblk = blk; + if (ioctl(fd, DIOCWFORMAT, &fop) < 0) + Perror("write format"); + if (fop.df_count != fp->f_bufsize) { + char msg[80]; + (void)sprintf(msg, "bad144: write format %d", blk); + perror(msg); + } +} +#endif + +Perror(op) + char *op; +{ + + fprintf(stderr, "bad144: "); perror(op); + exit(4); +} diff --git a/usr.sbin/chown/Makefile b/usr.sbin/chown/Makefile new file mode 100644 index 0000000..084b4bc --- /dev/null +++ b/usr.sbin/chown/Makefile @@ -0,0 +1,9 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= chown +CFLAGS+=-DSUPPORT_DOT +MAN1= chgrp.0 +MAN8= chown.0 +LINKS= ${BINDIR}/chown /usr/bin/chgrp + +.include diff --git a/usr.sbin/chown/chgrp.1 b/usr.sbin/chown/chgrp.1 new file mode 100644 index 0000000..1adcb80 --- /dev/null +++ b/usr.sbin/chown/chgrp.1 @@ -0,0 +1,136 @@ +.\" Copyright (c) 1983, 1990, 1993, 1994 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the Institute of Electrical and Electronics Engineers, Inc. +.\" +.\" 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. +.\" +.\" @(#)chgrp.1 8.3 (Berkeley) 3/31/94 +.\" +.Dd March 31, 1994 +.Dt CHGRP 1 +.Os BSD 4.2 +.Sh NAME +.Nm chgrp +.Nd change group +.Sh SYNOPSIS +.Nm chgrp +.Oo +.Fl R +.Op Fl H | Fl L | Fl P +.Oc +.Op Fl f +.Ar group +.Ar files ... +.Sh DESCRIPTION +The chgrp utility sets the group ID of the file named by each +.Ar file +operand to the +.Ar group +ID specified by the group operand. +.Pp +Options: +.Bl -tag -width Ds +.It Fl H +If the +.Fl R +option is specified, symbolic links on the command line are followed. +(Symbolic links encountered in the tree traversal are not followed.) +.It Fl L +If the +.Fl R +option is specified, all symbolic links are followed. +.It Fl P +If the +.Fl R +option is specified, no symbolic links are followed. +.It Fl R +Change the group ID for the file hierarchies rooted +in the files instead of just the files themselves. +.It Fl f +The force option ignores errors, except for usage errors and doesn't +query about strange modes (unless the user does not have proper permissions). +.El +.Pp +Symbolic links don't have groups, so unless the +.Fl H +or +.Fl L +option is set, +.Nm chgrp +on a symbolic link always succeeds and has no effect. +The +.Fl H , +.Fl L +and +.Fl P +options are ignored unless the +.Fl R +option is specified. +In addition, these options override each other and the +command's actions are determined by the last one specified. +.Pp +The +.Ar group +operand can be either a group name from the group database, +or a numeric group ID. +If a group name is also a numeric group ID, the operand is used as a +group name. +.Pp +The user invoking +.Nm chgrp +must belong to the specified group and be the owner of the file, +or be the super-user. +.Pp +The +.Nm chgrp +utility exits 0 on success, and >0 if an error occurs. +.Sh COMPATIBILITY +Previous versions of the +.Nm chgrp +utility changed the group of symbolic links specified on the command +line. +In this system, symbolic links do not have groups. +.Sh FILES +.Bl -tag -width /etc/group -compact +.It Pa /etc/group +Group ID file +.El +.Sh SEE ALSO +.Xr chown 2 , +.Xr group 5 , +.Xr passwd 5 , +.Xr fts 3 , +.Xr symlink 7 , +.Xr chown 8 +.Sh STANDARDS +The +.Nm chgrp +utility is expected to be POSIX 1003.2 compatible. diff --git a/usr.sbin/chown/chown.8 b/usr.sbin/chown/chown.8 new file mode 100644 index 0000000..f0cd533 --- /dev/null +++ b/usr.sbin/chown/chown.8 @@ -0,0 +1,149 @@ +.\" Copyright (c) 1990, 1991, 1993, 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. +.\" +.\" @(#)chown.8 8.3 (Berkeley) 3/31/94 +.\" +.Dd March 31, 1994 +.Dt CHOWN 8 +.Os BSD 4 +.Sh NAME +.Nm chown +.Nd change file owner and group +.Sh SYNOPSIS +.Nm chown +.Oo +.Fl R +.Op Fl H | Fl L | Fl P +.Oc +.Op Fl f +.Ar owner Op Ar :group +.Ar file ... +.Nm chown +.Oo +.Fl R +.Op Fl H | Fl L | Fl P +.Oc +.Op Fl f +.Ar :group +.Ar file ... +.Sh DESCRIPTION +.Nm Chown +sets the user ID and/or the group ID of the specified files. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl H +If the +.Fl R +option is specified, symbolic links on the command line are followed. +(Symbolic links encountered in the tree traversal are not followed.) +.It Fl L +If the +.Fl R +option is specified, all symbolic links are followed. +.It Fl P +If the +.Fl R +option is specified, no symbolic links are followed. +.It Fl R +Change the user ID and/or the group ID for the file hierarchies rooted +in the files instead of just the files themselves. +.It Fl f +Don't report any failure to change file owner or group, nor modify +the exit status to reflect such failures. +.El +.Pp +Symbolic links don't have owners, so unless the +.Fl H +or +.Fl L +option is set, +.Nm chown +on a symbolic link always succeeds and has no effect. +The +.Fl H , +.Fl L +and +.Fl P +options are ignored unless the +.Fl R +option is specified. +In addition, these options override each other and the +command's actions are determined by the last one specified. +.Pp +The +.Ar owner +and +.Ar group +operands are both optional, however, one must be specified. +If the +.Ar group +operand is specified, it must be preceded by a colon (``:'') character. +.Pp +The +.Ar owner +may be either a numeric user ID or a user name. +If a user name is also a numeric user ID, the operand is used as a +user name. +The +.Ar group +may be either a numeric group ID or a group name. +If a group name is also a numeric group ID, the operand is used as a +group name. +.Pp +The ownership of a file may only be altered by a super-user for +obvious security reasons. +.Pp +The +.Nm chown +utility exits 0 on success, and >0 if an error occurs. +.Sh COMPATIBILITY +Previous versions of the +.Nm chown +utility used the dot (``.'') character to distinguish the group name. +This has been changed to be a colon (``:'') character so that user and +group names may contain the dot character. +.Pp +Previous versions of the +.Nm chown +utility changed the owner of symbolic links specified on the command +line. +In this system, symbolic links do not have owners. +.Sh SEE ALSO +.Xr chgrp 1 , +.Xr find 1 , +.Xr chown 2 , +.Xr fts 3 , +.Xr symlink 7 +.Sh STANDARDS +The +.Nm chown +command is expected to be POSIX 1003.2 compliant. diff --git a/usr.sbin/chown/chown.c b/usr.sbin/chown/chown.c new file mode 100644 index 0000000..9121777 --- /dev/null +++ b/usr.sbin/chown/chown.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 1988, 1993, 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1988, 1993, 1994\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)chown.c 8.8 (Berkeley) 4/4/94"; +#endif /* not lint */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void a_gid __P((char *)); +void a_uid __P((char *)); +void chownerr __P((char *)); +u_long id __P((char *, char *)); +void usage __P((void)); + +uid_t uid; +gid_t gid; +int Rflag, ischown, fflag; +char *gname, *myname; + +int +main(argc, argv) + int argc; + char *argv[]; +{ + FTS *ftsp; + FTSENT *p; + int Hflag, Lflag, Pflag, ch, fts_options, hflag, rval; + char *cp; + + myname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv; + ischown = myname[2] == 'o'; + + Hflag = Lflag = Pflag = hflag = 0; + while ((ch = getopt(argc, argv, "HLPRfh")) != EOF) + switch (ch) { + case 'H': + Hflag = 1; + Lflag = Pflag = 0; + break; + case 'L': + Lflag = 1; + Hflag = Pflag = 0; + break; + case 'P': + Pflag = 1; + Hflag = Lflag = 0; + break; + case 'R': + Rflag = 1; + break; + case 'f': + fflag = 1; + break; + case 'h': + /* + * In System V (and probably POSIX.2) the -h option + * causes chown/chgrp to change the owner/group of + * the symbolic link. 4.4BSD's symbolic links don't + * have owners/groups, so it's an undocumented noop. + * Do syntax checking, though. + */ + hflag = 1; + break; + case '?': + default: + usage(); + } + argv += optind; + argc -= optind; + + if (argc < 2) + usage(); + + fts_options = FTS_PHYSICAL; + if (Rflag) { + if (hflag) + errx(1, + "the -R and -h options may not be specified together."); + if (Hflag) + fts_options |= FTS_COMFOLLOW; + if (Lflag) { + fts_options &= ~FTS_PHYSICAL; + fts_options |= FTS_LOGICAL; + } + } + + uid = gid = -1; + if (ischown) { +#ifdef SUPPORT_DOT + if ((cp = strchr(*argv, '.')) != NULL) { + *cp++ = '\0'; + a_gid(cp); + } else +#endif + if ((cp = strchr(*argv, ':')) != NULL) { + *cp++ = '\0'; + a_gid(cp); + } + a_uid(*argv); + } else + a_gid(*argv); + + if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL) + err(1, NULL); + + for (rval = 0; (p = fts_read(ftsp)) != NULL;) { + switch (p->fts_info) { + case FTS_D: + if (Rflag) /* Change it at FTS_DP. */ + continue; + fts_set(ftsp, p, FTS_SKIP); + break; + case FTS_DNR: /* Warn, chown, continue. */ + warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); + rval = 1; + break; + case FTS_ERR: /* Warn, continue. */ + case FTS_NS: + warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); + rval = 1; + continue; + case FTS_SL: /* Ignore. */ + case FTS_SLNONE: + /* + * The only symlinks that end up here are ones that + * don't point to anything and ones that we found + * doing a physical walk. + */ + continue; + default: + break; + } + if (chown(p->fts_accpath, uid, gid) && !fflag) { + chownerr(p->fts_path); + rval = 1; + } + } + if (errno) + err(1, "fts_read"); + exit(rval); +} + +void +a_gid(s) + char *s; +{ + struct group *gr; + + if (*s == '\0') /* Argument was "uid[:.]". */ + return; + gname = s; + gid = ((gr = getgrnam(s)) == NULL) ? id(s, "group") : gr->gr_gid; +} + +void +a_uid(s) + char *s; +{ + struct passwd *pw; + + if (*s == '\0') /* Argument was "[:.]gid". */ + return; + uid = ((pw = getpwnam(s)) == NULL) ? id(s, "user") : pw->pw_uid; +} + +u_long +id(name, type) + char *name, *type; +{ + u_long val; + char *ep; + + /* + * XXX + * We know that uid_t's and gid_t's are unsigned longs. + */ + errno = 0; + val = strtoul(name, &ep, 10); + if (errno) + err(1, "%s", name); + if (*ep != '\0') + errx(1, "%s: illegal %s name", name, type); + return (val); +} + +void +chownerr(file) + char *file; +{ + static int euid = -1, ngroups = -1; + int groups[NGROUPS]; + + /* Check for chown without being root. */ + if (errno != EPERM || + uid != -1 && euid == -1 && (euid = geteuid()) != 0) { + if (fflag) + exit(0); + err(1, "%s", file); + } + + /* Check group membership; kernel just returns EPERM. */ + if (gid != -1 && ngroups == -1) { + ngroups = getgroups(NGROUPS, groups); + while (--ngroups >= 0 && gid != groups[ngroups]); + if (ngroups < 0) { + if (fflag) + exit(0); + errx(1, "you are not a member of group %s", gname); + } + } + + if (!fflag) + warn("%s", file); +} + +void +usage() +{ + (void)fprintf(stderr, + "usage: %s [-R [-H | -L | -P]] [-f] %s file ...\n", + myname, ischown ? "[owner][:group]" : "group"); + exit(1); +} diff --git a/usr.sbin/chroot/Makefile b/usr.sbin/chroot/Makefile new file mode 100644 index 0000000..086a7bc --- /dev/null +++ b/usr.sbin/chroot/Makefile @@ -0,0 +1,6 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= chroot +MAN8= chroot.0 + +.include diff --git a/usr.sbin/chroot/chroot.8 b/usr.sbin/chroot/chroot.8 new file mode 100644 index 0000000..76f488b --- /dev/null +++ b/usr.sbin/chroot/chroot.8 @@ -0,0 +1,79 @@ +.\" 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. +.\" +.\" @(#)chroot.8 8.1 (Berkeley) 6/9/93 +.\" +.Dd June 9, 1993 +.Dt CHROOT 8 +.Os BSD 4.3 +.Sh NAME +.Nm chroot +.Nd change root directory +.Sh SYNOPSIS +.Nm chroot +.Ar newroot +.Op Ar command +.Sh DESCRIPTION +The +.Nm chroot +command changes its root directory to the supplied directory +.Ar newroot +and exec's +.Ar command , +if supplied, or an interactive copy of your shell. +.Pp +Note, +.Ar command +or the shell are run as your real-user-id. +.Sh ENVIRONMENT +The following environment variable is referenced by +.Nm chroot : +.Bl -tag -width SHELL +.It Ev SHELL +If set, +the string specified by +.Ev SHELL +is interpreted as the name of +the shell to exec. +If the variable +.Ev SHELL +is not set, +.Pa /bin/sh +is used. +.El +.Sh SEE ALSO +.Xr chdir 2 , +.Xr chroot 2 , +.Xr environ 7 +.Sh HISTORY +The +.Nm chroot +utility first appeared in 4.4BSD. diff --git a/usr.sbin/chroot/chroot.c b/usr.sbin/chroot/chroot.c new file mode 100644 index 0000000..81bf675 --- /dev/null +++ b/usr.sbin/chroot/chroot.c @@ -0,0 +1,96 @@ +/* + * 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[] = "@(#)chroot.c 8.1 (Berkeley) 6/9/93"; +#endif /* not lint */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +void usage __P((void)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + int ch; + char *shell; + + while ((ch = getopt(argc, argv, "")) != EOF) + switch(ch) { + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc < 1) + usage(); + + if (chdir(argv[0]) || chroot(".")) + err(1, "%s", argv[0]); + + if (argv[1]) { + execvp(argv[1], &argv[1]); + err(1, "%s", argv[1]); + } + + if (!(shell = getenv("SHELL"))) + shell = _PATH_BSHELL; + execlp(shell, shell, "-i", NULL); + err(1, "%s", shell); + /* NOTREACHED */ +} + +void +usage() +{ + (void)fprintf(stderr, "usage: chroot newroot [command]\n"); + exit(1); +} diff --git a/usr.sbin/config.new/Makefile b/usr.sbin/config.new/Makefile new file mode 100644 index 0000000..6dc5a7e --- /dev/null +++ b/usr.sbin/config.new/Makefile @@ -0,0 +1,14 @@ +# @(#)Makefile 8.2 (Berkeley) 4/19/94 + +PROG= config +SRCS= files.c gram.y hash.c main.c mkheaders.c mkioconf.c mkmakefile.c \ + mkswap.c pack.c scan.l sem.c util.c +CFLAGS+=-I${.CURDIR} -I. +CLEANFILES=gram.c scan.c y.tab.h +MAN8= config.new.0 + +MLINKS+=config.new.0 config.0 + +.include + +.depend: gram.c scan.c diff --git a/usr.sbin/config.new/config.h b/usr.sbin/config.new/config.h new file mode 100644 index 0000000..dde683d --- /dev/null +++ b/usr.sbin/config.new/config.h @@ -0,0 +1,281 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratories. + * + * 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. + * + * @(#)config.h 8.1 (Berkeley) 6/6/93 + */ + +/* + * Name/value lists. Values can be strings or pointers and/or can carry + * integers. The names can be NULL, resulting in simple value lists. + */ +struct nvlist { + struct nvlist *nv_next; + const char *nv_name; + union { + const char *un_str; + void *un_ptr; + } nv_un; +#define nv_str nv_un.un_str +#define nv_ptr nv_un.un_ptr + int nv_int; +}; + +/* + * Kernel configurations. + */ +struct config { + struct config *cf_next; /* linked list */ + const char *cf_name; /* "vmunix" */ + int cf_lineno; /* source line */ + struct nvlist *cf_root; /* "root on ra0a" */ + struct nvlist *cf_swap; /* "swap on ra0b and ra1b" */ + struct nvlist *cf_dump; /* "dumps on ra0b" */ +}; + +/* + * Attributes. These come in two flavors: "plain" and "interface". + * Plain attributes (e.g., "ether") simply serve to pull in files. + * Interface attributes (e.g., "scsi") carry three lists: locators, + * child devices, and references. The locators are those things + * that must be specified in order to configure a device instance + * using this attribute (e.g., "tg0 at scsi0"). The a_devs field + * lists child devices that can connect here (e.g., "tg"s), while + * the a_refs are parents that carry the attribute (e.g., actual + * SCSI host adapter drivers such as the SPARC "esp"). + */ +struct attr { + const char *a_name; /* name of this attribute */ + int a_iattr; /* true => allows children */ + struct nvlist *a_locs; /* locators required */ + int a_loclen; /* length of above list */ + struct nvlist *a_devs; /* children */ + struct nvlist *a_refs; /* parents */ +}; + +/* + * The "base" part of a device ("uba", "sd"; but not "uba2" or + * "sd0"). It may be found "at" one or more attributes, including + * "at root" (this is represented by a NULL attribute). + * + * Each device may also export attributes. If any provide an output + * interface (e.g., "esp" provides "scsi"), other devices (e.g., + * "tg"s) can be found at instances of this one (e.g., "esp"s). + * Such a connection must provide locators as specified by that + * interface attribute (e.g., "target"). + * + * Each base carries a list of instances (via d_ihead). Note that this + * list "skips over" aliases; those must be found through the instances + * themselves. + */ +struct devbase { + const char *d_name; /* e.g., "sd" */ + struct devbase *d_next; /* linked list */ + int d_isdef; /* set once properly defined */ + int d_ispseudo; /* is a pseudo-device */ + int d_major; /* used for "root on sd0", e.g. */ + struct nvlist *d_atlist; /* e.g., "at tg" (attr list) */ + struct nvlist *d_vectors; /* interrupt vectors, if any */ + struct nvlist *d_attrs; /* attributes, if any */ + struct devi *d_ihead; /* first instance, if any */ + struct devi **d_ipp; /* used for tacking on more instances */ + int d_umax; /* highest unit number + 1 */ +}; + +/* + * An "instance" of a device. The same instance may be listed more + * than once, e.g., "xx0 at isa? port FOO" + "xx0 at isa? port BAR". + * + * After everything has been read in and verified, the devi's are + * "packed" to collect all the information needed to generate ioconf.c. + * In particular, we try to collapse multiple aliases into a single entry. + * We then assign each "primary" (non-collapsed) instance a cfdata index. + * Note that there may still be aliases among these. + */ +struct devi { + /* created while parsing config file */ + const char *i_name; /* e.g., "sd0" */ + int i_unit; /* unit from name, e.g., 0 */ + struct devbase *i_base;/* e.g., pointer to "sd" base */ + struct devi *i_next; /* list of all instances */ + struct devi *i_bsame; /* list on same base */ + struct devi *i_alias; /* other aliases of this instance */ + const char *i_at; /* where this is "at" (NULL if at root) */ + struct attr *i_atattr; /* attr that allowed attach */ + struct devbase *i_atdev;/* dev if "at ", else NULL */ + const char **i_locs; /* locators (as given by i_atattr) */ + int i_atunit; /* unit from "at" */ + int i_cfflags; /* flags from config line */ + int i_lineno; /* line # in config, for later errors */ + + /* created during packing or ioconf.c generation */ +/* i_loclen via i_atattr->a_loclen */ + short i_collapsed; /* set => this alias no longer needed */ + short i_cfindex; /* our index in cfdata */ + short i_pvlen; /* number of parents */ + short i_pvoff; /* offset in parents.vec */ + short i_locoff; /* offset in locators.vec */ + short i_ivoff; /* offset in interrupt vectors, if any */ + struct devi **i_parents;/* the parents themselves */ + +}; +/* special units */ +#define STAR (-1) /* unit number for, e.g., "sd*" */ +#define WILD (-2) /* unit number for, e.g., "sd?" */ + +/* + * Files. Each file is either standard (always included) or optional, + * depending on whether it has names on which to *be* optional. + */ +struct files { + struct files *fi_next; /* linked list */ + const char *fi_srcfile; /* the name of the "files" file that got us */ + u_short fi_srcline; /* and the line number */ + u_char fi_flags; /* as below */ + char fi_lastc; /* last char from path */ + const char *fi_path; /* full file path */ + const char *fi_tail; /* name, i.e., rindex(fi_path, '/') + 1 */ + const char *fi_base; /* tail minus ".c" (or whatever) */ + struct nvlist *fi_opt; /* optional on ... */ + const char *fi_mkrule; /* special make rule, if any */ +}; + +/* flags */ +#define FI_SEL 0x01 /* selected */ +#define FI_CONFIGDEP 0x02 /* config-dependent */ +#define FI_DRIVER 0x04 /* device-driver */ +#define FI_NEEDSCOUNT 0x08 /* needs-count */ +#define FI_NEEDSFLAG 0x10 /* needs-flag */ +#define FI_HIDDEN 0x20 /* obscured by other(s), base names overlap */ + +/* + * Hash tables look up name=value pairs. The pointer value of the name + * is assumed to be constant forever; this can be arranged by interning + * the name. (This is fairly convenient since our lexer does this for + * all identifier-like strings---it has to save them anyway, lest yacc's + * look-ahead wipe out the current one.) + */ +struct hashtab; + +const char *conffile; /* source file, e.g., "GENERIC.sparc" */ +const char *confdirbase; /* basename of compile directory, usu. same */ +const char *machine; /* machine type, e.g., "sparc" */ +int errors; /* counts calls to error() */ +int minmaxusers; /* minimum "maxusers" parameter */ +int defmaxusers; /* default "maxusers" parameter */ +int maxmaxusers; /* default "maxusers" parameter */ +int maxusers; /* configuration's "maxusers" parameter */ +struct nvlist *options; /* options */ +struct nvlist *mkoptions; /* makeoptions */ +struct hashtab *devbasetab; /* devbase lookup */ +struct hashtab *selecttab; /* selects things that are "optional foo" */ +struct hashtab *needcnttab; /* retains names marked "needs-count" */ + +struct devbase *allbases; /* list of all devbase structures */ +struct config *allcf; /* list of configured kernels */ +struct devi *alldevi; /* list of all instances */ +struct devi *allpseudo; /* list of all pseudo-devices */ +int ndevi; /* number of devi's (before packing) */ +int npseudo; /* number of pseudo's */ + +struct files *allfiles; /* list of all kernel source files */ + +struct devi **packed; /* arrayified table for packed devi's */ +int npacked; /* size of packed table, <= ndevi */ + +struct { /* pv[] table for config */ + short *vec; + int used; +} parents; +struct { /* loc[] table for config */ + const char **vec; + int used; +} locators; + +/* files.c */ +void initfiles __P((void)); +void checkfiles __P((void)); +int fixfiles __P((void)); /* finalize */ +void addfile __P((const char *, struct nvlist *, int, const char *)); + +/* hash.c */ +struct hashtab *ht_new __P((void)); +int ht_insrep __P((struct hashtab *, const char *, void *, int)); +#define ht_insert(ht, nam, val) ht_insrep(ht, nam, val, 0) +#define ht_replace(ht, nam, val) ht_insrep(ht, nam, val, 1) +void *ht_lookup __P((struct hashtab *, const char *)); +void initintern __P((void)); +const char *intern __P((const char *)); + +/* main.c */ +void addoption __P((const char *name, const char *value)); +void addmkoption __P((const char *name, const char *value)); + +/* mkheaders.c */ +int mkheaders __P((void)); + +/* mkioconf.c */ +int mkioconf __P((void)); + +/* mkmakefile.c */ +int mkmakefile __P((void)); + +/* mkswap.c */ +int mkswap __P((void)); + +/* pack.c */ +void pack __P((void)); + +/* scan.l */ +int currentline __P((void)); + +/* sem.c, other than for yacc actions */ +void initsem __P((void)); + +/* util.c */ +void *emalloc __P((size_t)); +void *erealloc __P((void *, size_t)); +char *path __P((const char *)); +void error __P((const char *, ...)); /* immediate errs */ +void xerror __P((const char *, int, const char *, ...)); /* delayed errs */ +__dead void panic __P((const char *, ...)); +struct nvlist *newnv __P((const char *, const char *, void *, int)); +void nvfree __P((struct nvlist *)); +void nvfreel __P((struct nvlist *)); diff --git a/usr.sbin/config.new/config.new.8 b/usr.sbin/config.new/config.new.8 new file mode 100644 index 0000000..5eae8d3 --- /dev/null +++ b/usr.sbin/config.new/config.new.8 @@ -0,0 +1,167 @@ +.\" Copyright (c) 1980, 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. +.\" +.\" @(#)config.8 8.2 (Berkeley) 4/19/94 +.\" +.Dd April 19, 1994 +.Dt CONFIG.NEW 8 +.Os BSD 4 +.Sh NAME +.Nm config.new +.Nd build kernel compilation directories +.Sh SYNOPSIS +.Nm config +.Op Fl p +.Ar system-name +.Sh DESCRIPTION +.Pp +This is the new version of the +.Nm config +program. +It understands the more modern autoconfiguration scheme +used on the SPARC and i386 platforms. +The old version of config is still used with the +HP300, DECstation, and derivative platforms. +Only the version of +.Nm config +applicable to the architecture that you are running +will be installed on your machine. +.Pp +.Nm Config +builds a set of configuration files from the file +.Ar system-name , +which describes +the system to configure. +.Pp +.Nm Config +should run from the +.Pa conf +subdirectory of the top-level machine-specific directory +of the system source (usually +.Pa /sys/MACHINE/conf , +where +.Pa MACHINE +is one of +.Pa vax , +.Pa tahoe , +.Pa hp300 , +and so forth). +.Nm Config +assumes the directory +.Pa ../../compile +exists; it places all output files in a subdirectory there, +creating the subdirectory if necessary. +The subdirectory name is taken from the +.Ar system-name ; +thus, configuring with +.Dq Li config PICKLE +will use the directory +.Pa ../../compile/PICKLE . +.Pp +If the +.Fl p +option is supplied, +.Pa .PROF +is appended to the compilation directory name, and +.Nm config +acts as if the lines +.Dq Li makeoptions PROF="-pg" +and +.Dq Li options GPROF +appeared in the configuration file. +This will build a system that includes profiling code; see +.Xr kgmon 8 +and +.Xr gprof 1 . +The +.Fl p +flag is expected to be used for +.Dq one-shot +profiles of existing systems; +for regular profiling, +it is probably wiser to make a separate configuration +containing the +.Li makeoptions +line. +.Pp +The old undocumented +.Fl g +flag is no longer supported. +Instead, use +.Dq Li makeoptions DEBUG="-g" +and (typically) +.Dq Li options KGDB . +.Pp +The output of +.Nm config +consists of a number of files, principally +.Pa ioconf.c , +a description of I/O devices that may be attached to the system; and a +.Pa Makefile , +used by +.Xr make 1 +in building the kernel. +.Pp +After running +.Nm config , +it is wise to run +.Dq Li make depend +in the directory where the new makefile +was created. +.Nm Config +prints a reminder of this when it completes. +.Pp +If +.Nm config +stops due to errors, the problems reported should be corrected and +.Nm config +should be run again. +.Nm Config +attempts to avoid changing the compilation directory +if there are configuration errors, +but this code is not well-tested, +and some problems (such as running out of disk space) +are unrecoverable. +.Sh SEE ALSO +The SYNOPSIS portion of each device in section 4. +.Rs +.%T "Building 4.4 BSD Systems with Config" +.\" .%T "Device Support in 4.4BSD" +.Re +.sp +.Xr config 8 +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.1 . +It was completely revised in +.Bx 4.4 . diff --git a/usr.sbin/config.new/files.c b/usr.sbin/config.new/files.c new file mode 100644 index 0000000..40cddf8 --- /dev/null +++ b/usr.sbin/config.new/files.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratories. + * + * 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. + * + * @(#)files.c 8.1 (Berkeley) 6/6/93 + */ + +#include +#include +#include +#include +#include +#include "config.h" + +extern const char *yyfile; + +/* + * We check that each full path name is unique. File base names + * should generally also be unique, e.g., having both a net/xx.c and + * a kern/xx.c (or, worse, a net/xx.c and a new/xx.c++) is probably + * wrong, but is permitted under some conditions. + */ +static struct hashtab *basetab; /* file base names */ +static struct hashtab *pathtab; /* full path names */ + +static struct files **nextfile; +static struct files **unchecked; + +void +initfiles() +{ + + basetab = ht_new(); + pathtab = ht_new(); + nextfile = &allfiles; + unchecked = &allfiles; +} + +static void +showprev(pref, fi) + const char *pref; + register struct files *fi; +{ + + xerror(fi->fi_srcfile, fi->fi_srcline, + "%sfile %s ...", pref, fi->fi_path); + errors--; +} + +void +addfile(path, opts, flags, rule) + const char *path; + struct nvlist *opts; + int flags; + const char *rule; +{ + struct files *fi; + const char *base, *dotp, *tail; + size_t baselen; + int needc, needf; + char buf[200]; + + /* check various errors */ + needc = flags & FI_NEEDSCOUNT; + needf = flags & FI_NEEDSFLAG; + if (needc && needf) { + error("cannot mix needs-count and needs-flag"); + goto bad; + } + if (opts == NULL && (needc || needf)) { + error("nothing to %s for %s", needc ? "count" : "flag", path); + goto bad; + } + if ((fi = ht_lookup(pathtab, path)) != NULL) { + showprev("", fi); + error("file %s listed again", path); + goto bad; + } + + /* find last part of pathname, and same without trailing suffix */ + tail = rindex(path, '/'); + if (tail == NULL) + tail = path; + else + tail++; + dotp = rindex(tail, '.'); + if (dotp == NULL || dotp[1] == 0 || + (baselen = dotp - tail) >= sizeof(buf)) { + error("invalid pathname `%s'", path); + goto bad; + } + + /* + * Make a copy of the path without the .c/.s/whatever suffix. + * This must be unique per "files" file (e.g., a specific + * file can override a standard file, but no standard file + * can override another standard file). This is not perfect + * but should catch any major errors. + */ + bcopy(tail, buf, baselen); + buf[baselen] = 0; + base = intern(buf); + if ((fi = ht_lookup(basetab, base)) != NULL) { + if (fi->fi_srcfile != yyfile) { + showprev("note: ", fi); + error("is overriden by %s", path); + errors--; /* take it away */ + fi->fi_flags |= FI_HIDDEN; + } else { + showprev("", fi); + error("collides with %s (both make %s.o)", + path, base); + goto bad; + } + } + + /* + * Commit this file to memory. + */ + fi = emalloc(sizeof *fi); + fi->fi_next = NULL; + fi->fi_srcfile = yyfile; + fi->fi_srcline = currentline(); + fi->fi_flags = flags; + fi->fi_lastc = dotp[strlen(dotp) - 1]; + fi->fi_path = path; + fi->fi_tail = tail; + fi->fi_base = base; + fi->fi_opt = opts; + fi->fi_mkrule = rule; + if (ht_insert(pathtab, path, fi)) + panic("addfile: ht_insert(%s)", path); + (void)ht_replace(basetab, base, fi); + *nextfile = fi; + nextfile = &fi->fi_next; + return; +bad: + nvfreel(opts); +} + +/* + * We have finished reading some "files" file, either ../../conf/files + * or ./files.$machine. Make sure that everything that is flagged as + * needing a count is reasonable. (This prevents ../../conf/files from + * depending on some machine-specific device.) + */ +void +checkfiles() +{ + register struct files *fi, *last; + register struct nvlist *nv; + + last = NULL; + for (fi = *unchecked; fi != NULL; last = fi, fi = fi->fi_next) { + if ((fi->fi_flags & FI_NEEDSCOUNT) == 0) + continue; + for (nv = fi->fi_opt; nv != NULL; nv = nv->nv_next) + if (ht_lookup(devbasetab, nv->nv_name) == NULL) { + xerror(fi->fi_srcfile, fi->fi_srcline, + "`%s' is not a countable device", + nv->nv_name); + /* keep fixfiles() from complaining again */ + fi->fi_flags |= FI_HIDDEN; + } + } + if (last != NULL) + unchecked = &last->fi_next; +} + +/* + * We have finished reading everything. Tack the files down: calculate + * selection and counts as needed. + */ +int +fixfiles() +{ + register struct files *fi; + register struct nvlist *nv; + register struct devbase *dev; + int sel, err; + + err = 0; + for (fi = allfiles; fi != NULL; fi = fi->fi_next) { + if (fi->fi_flags & FI_HIDDEN) + continue; + if ((nv = fi->fi_opt) == NULL) { /* standard */ + fi->fi_flags |= FI_SEL; + continue; + } + /* figure out whether it is selected */ + sel = 0; + if (fi->fi_flags & FI_NEEDSCOUNT) { + /* ... and compute counts too */ + do { + dev = ht_lookup(devbasetab, nv->nv_name); + if (dev == NULL) { + xerror(fi->fi_srcfile, fi->fi_srcline, + "`%s' is not a countable device", + nv->nv_name); + err = 1; + } else { + if (dev->d_umax) + sel = 1; + nv->nv_int = dev->d_umax; + (void)ht_insert(needcnttab, + nv->nv_name, nv); + } + } while ((nv = nv->nv_next) != NULL); + } else { + do { + if (ht_lookup(selecttab, nv->nv_name)) { + sel = 1; + break; + } + } while ((nv = nv->nv_next) != NULL); + if (fi->fi_flags & FI_NEEDSFLAG) + for (nv = fi->fi_opt; nv; nv = nv->nv_next) + nv->nv_int = sel; + } + /* if selected, we are go */ + if (sel) + fi->fi_flags |= FI_SEL; + } + return (err); +} diff --git a/usr.sbin/config.new/gram.y b/usr.sbin/config.new/gram.y new file mode 100644 index 0000000..6b53801 --- /dev/null +++ b/usr.sbin/config.new/gram.y @@ -0,0 +1,392 @@ +%{ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratories. + * + * 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. + * + * @(#)gram.y 8.1 (Berkeley) 6/6/93 + */ + +#include +#include +#include +#include +#include "config.h" +#include "sem.h" + +#define FORMAT(n) ((n) > -10 && (n) < 10 ? "%d" : "0x%x") + +#define stop(s) error(s), exit(1) + +int include __P((const char *, int)); +void yyerror __P((const char *)); +int yylex __P((void)); +extern const char *lastfile; + +static struct config conf; /* at most one active at a time */ + +/* the following is used to recover nvlist space after errors */ +static struct nvlist *alloc[1000]; +static int adepth; +#define new0(n,s,p,i) (alloc[adepth++] = newnv(n, s, p, i)) +#define new_n(n) new0(n, NULL, NULL, 0) +#define new_ns(n, s) new0(n, s, NULL, 0) +#define new_si(s, i) new0(NULL, s, NULL, i) +#define new_nsi(n,s,i) new0(n, s, NULL, i) +#define new_np(n, p) new0(n, NULL, p, 0) +#define new_s(s) new0(NULL, s, NULL, 0) +#define new_p(p) new0(NULL, NULL, p, 0) + +static void cleanup __P((void)); +static void setmachine __P((const char *)); + +%} + +%union { + struct attr *attr; + struct devbase *devb; + struct nvlist *list; + const char *str; + int val; +} + +%token AND AT COMPILE_WITH CONFIG DEFINE DEVICE DUMPS ENDFILE +%token XFILE FLAGS INCLUDE XMACHINE MAJOR MAKEOPTIONS MAXUSERS MINOR +%token ON OPTIONS PSEUDO_DEVICE ROOT SWAP VECTOR +%token FFLAG NUMBER +%token PATHNAME WORD + +%type fopts +%type fflgs +%type rule +%type attr +%type devbase +%type atlist interface_opt +%type atname +%type loclist_opt loclist locdef +%type locdefault +%type veclist_opt veclist +%type attrs_opt attrs +%type locators locator +%type swapdev_list dev_spec +%type device_instance +%type attachment +%type value +%type major_minor signed_number npseudo +%type flags_opt + +%% + +/* + * A configuration consists of a machine type, followed by the machine + * definition files (via the include() mechanism), followed by the + * configuration specification(s) proper. In effect, this is two + * separate grammars, with some shared terminals and nonterminals. + */ +Configuration: + hdrs machine_spec /* "machine foo" from machine descr. */ + dev_defs dev_eof /* ../../conf/devices */ + dev_defs dev_eof /* devices.foo */ + specs; /* rest of machine description */ + +hdrs: + hdrs hdr | + /* empty */; + +hdr: + include | + '\n'; + +machine_spec: + XMACHINE WORD = { setmachine($2); } | + error = { stop("cannot proceed without machine specifier"); }; + +dev_eof: + ENDFILE = { enddefs(lastfile); checkfiles(); }; + + + +/* + * Various nonterminals shared between the grammars. + */ +file: + XFILE PATHNAME fopts fflgs rule = { addfile($2, $3, $4, $5); }; + +/* order of options is important, must use right recursion */ +fopts: + WORD fopts = { ($$ = new_n($1))->nv_next = $2; } | + /* empty */ = { $$ = NULL; }; + +fflgs: + fflgs FFLAG = { $$ = $1 | $2; } | + /* empty */ = { $$ = 0; }; + +rule: + COMPILE_WITH WORD = { $$ = $2; } | + /* empty */ = { $$ = NULL; }; + +include: + INCLUDE WORD = { (void)include($2, '\n'); }; + +/* + * The machine definitions grammar. + */ +dev_defs: + dev_defs dev_def | + /* empty */; + +dev_def: + one_def '\n' = { adepth = 0; } | + '\n' | + error '\n' = { cleanup(); }; + +one_def: + file | + /* include | */ + DEFINE WORD interface_opt = { (void)defattr($2, $3); } | + DEVICE devbase AT atlist veclist_opt interface_opt attrs_opt + = { defdev($2, 0, $4, $5, $6, $7); } | + MAXUSERS NUMBER NUMBER NUMBER = { setdefmaxusers($2, $3, $4); } | + PSEUDO_DEVICE devbase attrs_opt = { defdev($2,1,NULL,NULL,NULL,$3); } | + MAJOR '{' majorlist '}'; + +atlist: + atlist ',' atname = { ($$ = new_n($3))->nv_next = $1; } | + atname = { $$ = new_n($1); }; + +atname: + WORD = { $$ = $1; } | + ROOT = { $$ = NULL; }; + +veclist_opt: + VECTOR veclist = { $$ = $2; } | + /* empty */ = { $$ = NULL; }; + +/* veclist order matters, must use right recursion */ +veclist: + WORD veclist = { ($$ = new_n($1))->nv_next = $2; } | + WORD = { $$ = new_n($1); }; + +devbase: + WORD = { $$ = getdevbase($1); }; + +interface_opt: + '{' loclist_opt '}' = { ($$ = new_n(""))->nv_next = $2; } | + /* empty */ = { $$ = NULL; }; + +loclist_opt: + loclist = { $$ = $1; } | + /* empty */ = { $$ = NULL; }; + +/* loclist order matters, must use right recursion */ +loclist: + locdef ',' loclist = { ($$ = $1)->nv_next = $3; } | + locdef = { $$ = $1; }; + +/* "[ WORD locdefault ]" syntax may be unnecessary... */ +locdef: + WORD locdefault = { $$ = new_nsi($1, $2, 0); } | + WORD = { $$ = new_nsi($1, NULL, 0); } | + '[' WORD locdefault ']' = { $$ = new_nsi($2, $3, 1); }; + +locdefault: + '=' value = { $$ = $2; }; + +value: + WORD = { $$ = $1; } | + signed_number = { char bf[40]; + (void)sprintf(bf, FORMAT($1), $1); + $$ = intern(bf); }; + +signed_number: + NUMBER = { $$ = $1; } | + '-' NUMBER = { $$ = -$2; }; + +attrs_opt: + ':' attrs = { $$ = $2; } | + /* empty */ = { $$ = NULL; }; + +attrs: + attrs ',' attr = { ($$ = new_p($3))->nv_next = $1; } | + attr = { $$ = new_p($1); }; + +attr: + WORD = { $$ = getattr($1); }; + +majorlist: + majorlist ',' majordef | + majordef; + +majordef: + devbase '=' NUMBER = { setmajor($1, $3); }; + + + +/* + * The configuration grammar. + */ +specs: + specs spec | + /* empty */; + +spec: + config_spec '\n' = { adepth = 0; } | + '\n' | + error '\n' = { cleanup(); }; + +config_spec: + file | + include | + OPTIONS opt_list | + MAKEOPTIONS mkopt_list | + MAXUSERS NUMBER = { setmaxusers($2); } | + CONFIG conf sysparam_list = { addconf(&conf); } | + PSEUDO_DEVICE WORD npseudo = { addpseudo($2, $3); } | + device_instance AT attachment locators flags_opt + = { adddev($1, $3, $4, $5); }; + +mkopt_list: + mkopt_list ',' mkoption | + mkoption; + +mkoption: + WORD '=' value = { addmkoption($1, $3); } + +opt_list: + opt_list ',' option | + option; + +option: + WORD = { addoption($1, NULL); } | + WORD '=' value = { addoption($1, $3); }; + +conf: + WORD = { conf.cf_name = $1; + conf.cf_lineno = currentline(); + conf.cf_root = NULL; + conf.cf_swap = NULL; + conf.cf_dump = NULL; }; + +sysparam_list: + sysparam_list sysparam | + sysparam; + +sysparam: + ROOT on_opt dev_spec = { setconf(&conf.cf_root, "root", $3); } | + SWAP on_opt swapdev_list = { setconf(&conf.cf_swap, "swap", $3); } | + DUMPS on_opt dev_spec = { setconf(&conf.cf_dump, "dumps", $3); }; + +swapdev_list: + dev_spec AND swapdev_list = { ($$ = $1)->nv_next = $3; } | + dev_spec = { $$ = $1; }; + +dev_spec: + WORD = { $$ = new_si($1, NODEV); } | + major_minor = { $$ = new_si(NULL, $1); }; + +major_minor: + MAJOR NUMBER MINOR NUMBER = { $$ = makedev($2, $4); }; + +on_opt: + ON | /* empty */; + +npseudo: + NUMBER = { $$ = $1; } | + /* empty */ = { $$ = 1; }; + +device_instance: + WORD '*' = { $$ = starref($1); } | + WORD = { $$ = $1; }; + +attachment: + ROOT = { $$ = NULL; } | + WORD '?' = { $$ = wildref($1); } | + WORD '*' = { $$ = starref($1); } | + WORD = { $$ = $1; }; + +locators: + locators locator = { ($$ = $2)->nv_next = $1; } | + /* empty */ = { $$ = NULL; }; + +locator: + WORD value = { $$ = new_ns($1, $2); } | + WORD '?' = { $$ = new_ns($1, NULL); }; + +flags_opt: + FLAGS NUMBER = { $$ = $2; } | + /* empty */ = { $$ = 0; }; + +%% + +void +yyerror(s) + const char *s; +{ + + error("%s", s); +} + +/* + * Cleanup procedure after syntax error: release any nvlists + * allocated during parsing the current line. + */ +static void +cleanup() +{ + register struct nvlist **np; + register int i; + + for (np = alloc, i = adepth; --i >= 0; np++) + nvfree(*np); + adepth = 0; +} + +static void +setmachine(mch) + const char *mch; +{ + char buf[MAXPATHLEN]; + + machine = mch; + (void)sprintf(buf, "files.%s", mch); + if (include(buf, ENDFILE) || + include("../../conf/files.newconf", ENDFILE)) + exit(1); +} diff --git a/usr.sbin/config.new/hash.c b/usr.sbin/config.new/hash.c new file mode 100644 index 0000000..d7617da --- /dev/null +++ b/usr.sbin/config.new/hash.c @@ -0,0 +1,279 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratories. + * + * 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. + * + * @(#)hash.c 8.1 (Berkeley) 6/6/93 + */ + +#include +#include +#include +#include "config.h" + +/* + * Interned strings are kept in a hash table. By making each string + * unique, the program can compare strings by comparing pointers. + */ +struct hashent { + struct hashent *h_next; /* hash buckets are chained */ + const char *h_name; /* the string */ + u_int h_hash; /* its hash value */ + void *h_value; /* other values (for name=value) */ +}; +struct hashtab { + size_t ht_size; /* size (power of 2) */ + u_int ht_mask; /* == ht_size - 1 */ + u_int ht_used; /* number of entries used */ + u_int ht_lim; /* when to expand */ + struct hashent **ht_tab; /* base of table */ +}; +static struct hashtab strings; + +/* + * HASHFRACTION controls ht_lim, which in turn controls the average chain + * length. We allow a few entries, on average, as comparing them is usually + * cheap (the h_hash values prevent a strcmp). + */ +#define HASHFRACTION(sz) ((sz) * 3 / 2) + +/* round up to next multiple of y, where y is a power of 2 */ +#define ROUND(x, y) (((x) + (y) - 1) & ~((y) - 1)) + +/* + * Allocate space that will never be freed. + */ +static void * +poolalloc(size) + size_t size; +{ + register char *p; + register size_t alloc; + static char *pool; + static size_t nleft; + + if (nleft < size) { + /* + * Compute a `good' size to allocate via malloc. + * 16384 is a guess at a good page size for malloc; + * 32 is a guess at malloc's overhead. + */ + alloc = ROUND(size + 32, 16384) - 32; + p = emalloc(alloc); + nleft = alloc - size; + } else { + p = pool; + nleft -= size; + } + pool = p + size; + return (p); +} + +/* + * Initialize a new hash table. The size must be a power of 2. + */ +static void +ht_init(ht, sz) + register struct hashtab *ht; + size_t sz; +{ + register struct hashent **h; + register u_int n; + + h = emalloc(sz * sizeof *h); + ht->ht_tab = h; + ht->ht_size = sz; + ht->ht_mask = sz - 1; + for (n = 0; n < sz; n++) + *h++ = NULL; + ht->ht_used = 0; + ht->ht_lim = HASHFRACTION(sz); +} + +/* + * Expand an existing hash table. + */ +static void +ht_expand(ht) + register struct hashtab *ht; +{ + register struct hashent *p, **h, **oldh, *q; + register u_int n, i; + + n = ht->ht_size * 2; + h = emalloc(n * sizeof *h); + for (i = 0; i < n; i++) + h[i] = NULL; + oldh = ht->ht_tab; + n--; + for (i = ht->ht_size; i != 0; i--) { + for (p = *oldh++; p != NULL; p = q) { + q = p->h_next; + p->h_next = h[p->h_hash & n]; + h[p->h_hash & n] = p; + } + } + free(ht->ht_tab); + ht->ht_tab = h; + ht->ht_mask = n; + ht->ht_size = ++n; + ht->ht_lim = HASHFRACTION(n); +} + +/* + * Make a new hash entry, setting its h_next to NULL. + */ +static inline struct hashent * +newhashent(name, h) + const char *name; + u_int h; +{ + register struct hashent *hp; + register char *m; + + m = poolalloc(sizeof(*hp) + ALIGNBYTES); + hp = (struct hashent *)ALIGN(m); + hp->h_name = name; + hp->h_hash = h; + hp->h_next = NULL; + return (hp); +} + +/* + * Hash a string. + */ +static inline u_int +hash(str) + register const char *str; +{ + register u_int h; + + for (h = 0; *str;) + h = (h << 5) + h + *str++; + return (h); +} + +void +initintern() +{ + + ht_init(&strings, 128); +} + +/* + * Generate a single unique copy of the given string. We expect this + * function to be used frequently, so it should be fast. + */ +const char * +intern(s) + register const char *s; +{ + register struct hashtab *ht; + register struct hashent *hp, **hpp; + register u_int h; + register char *p; + register size_t l; + + ht = &strings; + h = hash(s); + hpp = &ht->ht_tab[h & ht->ht_mask]; + for (; (hp = *hpp) != NULL; hpp = &hp->h_next) + if (hp->h_hash == h && strcmp(hp->h_name, s) == 0) + return (hp->h_name); + l = strlen(s) + 1; + p = poolalloc(l); + bcopy(s, p, l); + *hpp = newhashent(p, h); + if (++ht->ht_used > ht->ht_lim) + ht_expand(ht); + return (p); +} + +struct hashtab * +ht_new() +{ + register struct hashtab *ht; + + ht = emalloc(sizeof *ht); + ht_init(ht, 8); + return (ht); +} + +/* + * Insert and/or replace. + */ +int +ht_insrep(ht, nam, val, replace) + register struct hashtab *ht; + register const char *nam; + void *val; + int replace; +{ + register struct hashent *hp, **hpp; + register u_int h; + + h = hash(nam); + hpp = &ht->ht_tab[h & ht->ht_mask]; + for (; (hp = *hpp) != NULL; hpp = &hp->h_next) { + if (hp->h_name == nam) { + if (replace) + hp->h_value = val; + return (1); + } + } + *hpp = hp = newhashent(nam, h); + hp->h_value = val; + return (0); +} + +void * +ht_lookup(ht, nam) + register struct hashtab *ht; + register const char *nam; +{ + register struct hashent *hp, **hpp; + register u_int h; + + h = hash(nam); + hpp = &ht->ht_tab[h & ht->ht_mask]; + for (; (hp = *hpp) != NULL; hpp = &hp->h_next) + if (hp->h_name == nam) + return (hp->h_value); + return (NULL); +} diff --git a/usr.sbin/config.new/main.c b/usr.sbin/config.new/main.c new file mode 100644 index 0000000..50b930e --- /dev/null +++ b/usr.sbin/config.new/main.c @@ -0,0 +1,466 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratories. + * + * 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. + * + * @(#)main.c 8.1 (Berkeley) 6/6/93 + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1992, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "config.h" + +int firstfile __P((const char *)); +int yyparse __P((void)); + +extern char *optarg; +extern int optind; + +static struct hashtab *opttab; +static struct hashtab *mkopttab; +static struct nvlist **nextopt; +static struct nvlist **nextmkopt; + +static __dead void stop __P((void)); +static int do_option __P((struct hashtab *, struct nvlist ***, + const char *, const char *, const char *)); +static int crosscheck __P((void)); +static int badstar __P((void)); +static int mksymlinks __P((void)); +static int has_instances __P((struct devbase *, int)); +static int hasparent __P((struct devi *)); +static int cfcrosscheck __P((struct config *, const char *, struct nvlist *)); + +int +main(argc, argv) + int argc; + char **argv; +{ + register char *p; + int pflag, ch; + struct stat st; + + pflag = 0; + while ((ch = getopt(argc, argv, "gp")) != EOF) { + switch (ch) { + + case 'g': + /* + * In addition to DEBUG, you probably wanted to + * set "options KGDB" and maybe others. We could + * do that for you, but you really should just + * put them in the config file. + */ + (void)fputs( + "-g is obsolete (use makeoptions DEBUG=\"-g\")\n", + stderr); + goto usage; + + case 'p': + /* + * Essentially the same as makeoptions PROF="-pg", + * but also changes the path from ../../compile/FOO + * to ../../compile/FOO.prof; i.e., compile a + * profiling kernel based on a typical "regular" + * kernel. + * + * Note that if you always want profiling, you + * can (and should) use a "makeoptions" line. + */ + pflag = 1; + break; + + case '?': + default: + goto usage; + } + } + + argc -= optind; + argv += optind; + if (argc != 1) { +usage: + (void)fputs("usage: config [-p] sysname\n", stderr); + exit(1); + } + conffile = argv[0]; + if (firstfile(conffile)) { + (void)fprintf(stderr, "config: cannot read %s: %s\n", + conffile, strerror(errno)); + exit(2); + } + + /* + * Init variables. + */ + minmaxusers = 1; + maxmaxusers = 10000; + initintern(); + initfiles(); + initsem(); + devbasetab = ht_new(); + selecttab = ht_new(); + needcnttab = ht_new(); + opttab = ht_new(); + mkopttab = ht_new(); + nextopt = &options; + nextmkopt = &mkoptions; + + /* + * Handle profiling (must do this before we try to create any + * files). + */ + if (pflag) { + char *s; + + s = emalloc(strlen(conffile) + sizeof(".PROF")); + (void)sprintf(s, "%s.PROF", conffile); + confdirbase = s; + (void)addmkoption(intern("PROF"), "-pg"); + (void)addoption(intern("GPROF"), NULL); + } else + confdirbase = conffile; + + /* + * Verify, creating if necessary, the compilation directory. + */ + p = path(NULL); + if (stat(p, &st)) { + if (mkdir(p, 0777)) { + (void)fprintf(stderr, "config: cannot create %s: %s\n", + p, strerror(errno)); + exit(2); + } + } else if (!S_ISDIR(st.st_mode)) { + (void)fprintf(stderr, "config: %s is not a directory\n", p); + exit(2); + } + + /* + * Parse config file (including machine definitions). + */ + if (yyparse()) + stop(); + + /* + * Fix (as in `set firmly in place') files. + */ + if (fixfiles()) + stop(); + + /* + * Perform cross-checking. + */ + if (maxusers == 0) { + if (defmaxusers) { + (void)printf("maxusers not specified; %d assumed\n", + defmaxusers); + maxusers = defmaxusers; + } else { + (void)fprintf(stderr, + "config: need \"maxusers\" line\n"); + errors++; + } + } + if (crosscheck() || errors) + stop(); + + /* + * Squeeze things down and finish cross-checks (STAR checks must + * run after packing). + */ + pack(); + if (badstar()) + stop(); + + /* + * Ready to go. Build all the various files. + */ + if (mksymlinks() || mkmakefile() || mkheaders() || mkswap() || + mkioconf()) + stop(); + (void)printf("Don't forget to run \"make depend\"\n"); + exit(0); +} + +/* + * Make a symlink for "machine" so that "#include " works. + */ +static int +mksymlinks() +{ + int ret; + char *p, buf[200]; + + p = path("machine"); + (void)sprintf(buf, "../../%s/include", machine); + (void)unlink(p); + ret = symlink(buf, p); + if (ret) + (void)fprintf(stderr, "config: symlink(%s -> %s): %s\n", + p, buf, strerror(errno)); + free(p); + return (ret); +} + +static __dead void +stop() +{ + (void)fprintf(stderr, "*** Stop.\n"); + exit(1); +} + +/* + * Add an option from "options FOO". Note that this selects things that + * are "optional foo". + */ +void +addoption(name, value) + const char *name, *value; +{ + register const char *n; + register char *p, c; + char low[500]; + + if (do_option(opttab, &nextopt, name, value, "options")) + return; + + /* make lowercase, then add to select table */ + for (n = name, p = low; (c = *n) != '\0'; n++) + *p++ = isupper(c) ? tolower(c) : c; + *p = 0; + n = intern(low); + (void)ht_insert(selecttab, n, (void *)n); +} + +/* + * Add a "make" option. + */ +void +addmkoption(name, value) + const char *name, *value; +{ + + (void)do_option(mkopttab, &nextmkopt, name, value, "mkoptions"); +} + +/* + * Add a name=value pair to an option list. The value may be NULL. + */ +static int +do_option(ht, nppp, name, value, type) + struct hashtab *ht; + struct nvlist ***nppp; + const char *name, *value, *type; +{ + register struct nvlist *nv; + + /* assume it will work */ + nv = newnv(name, value, NULL, 0); + if (ht_insert(ht, name, nv) == 0) { + **nppp = nv; + *nppp = &nv->nv_next; + return (0); + } + + /* oops, already got that option */ + nvfree(nv); + if ((nv = ht_lookup(ht, name)) == NULL) + panic("do_option"); + if (nv->nv_str != NULL) + error("already have %s `%s=%s'", type, name, nv->nv_str); + else + error("already have %s `%s'", type, name); + return (1); +} + +/* + * Return true if there is at least one instance of the given unit + * on the given base (or any units, if unit == WILD). + */ +static int +has_instances(dev, unit) + register struct devbase *dev; + int unit; +{ + register struct devi *i; + + if (unit == WILD) + return (dev->d_ihead != NULL); + for (i = dev->d_ihead; i != NULL; i = i->i_bsame) + if (unit == i->i_unit) + return (1); + return (0); +} + +static int +hasparent(i) + register struct devi *i; +{ + register struct nvlist *nv; + int atunit = i->i_atunit; + + if (i->i_atdev != NULL && has_instances(i->i_atdev, atunit)) + return (1); + if (i->i_atattr != NULL) + for (nv = i->i_atattr->a_refs; nv != NULL; nv = nv->nv_next) + if (has_instances(nv->nv_ptr, atunit)) + return (1); + return (0); +} + +static int +cfcrosscheck(cf, what, nv) + register struct config *cf; + const char *what; + register struct nvlist *nv; +{ + register struct devbase *dev; + int errs; + + for (errs = 0; nv != NULL; nv = nv->nv_next) { + if (nv->nv_name == NULL) + continue; + dev = ht_lookup(devbasetab, nv->nv_name); + if (dev == NULL) + panic("cfcrosscheck(%s)", nv->nv_name); + if (has_instances(dev, STAR) || + has_instances(dev, minor(nv->nv_int) >> 3)) + continue; + (void)fprintf(stderr, + "%s%d: %s says %s on %s, but there's no %s\n", + conffile, cf->cf_lineno, + cf->cf_name, what, nv->nv_str, nv->nv_str); + errs++; + } + return (errs); +} + +/* + * Cross-check the configuration: make sure that each target device + * or attribute (`at foo[0*?]') names at least one real device. Also + * see that the root, swap, and dump devices for all configurations + * are there. + */ +int +crosscheck() +{ + register struct devi *i; + register struct config *cf; + int errs; + + errs = 0; + for (i = alldevi; i != NULL; i = i->i_next) { + if (i->i_at == NULL || hasparent(i)) + continue; + xerror(conffile, i->i_lineno, + "%s at %s is orphaned", i->i_name, i->i_at); + if (i->i_atunit == WILD) + (void)fprintf(stderr, " (no %s's declared)\n", + i->i_base->d_name); + else + (void)fprintf(stderr, " (no %s declared)\n", i->i_at); + errs++; + } + if (allcf == NULL) { + (void)fprintf(stderr, "%s has no configurations!\n", + conffile); + errs++; + } + for (cf = allcf; cf != NULL; cf = cf->cf_next) { + if (cf->cf_root != NULL) { /* i.e., not swap generic */ + errs += cfcrosscheck(cf, "root", cf->cf_root); + errs += cfcrosscheck(cf, "swap", cf->cf_swap); + errs += cfcrosscheck(cf, "dumps", cf->cf_dump); + } + } + return (errs); +} + +/* + * Check to see if there is more than one *'d unit for any device, + * or a *'d unit with a needs-count file. + */ +int +badstar() +{ + register struct devbase *d; + register struct devi *i; + register int errs, n; + + errs = 0; + for (d = allbases; d != NULL; d = d->d_next) { + for (i = d->d_ihead; i != NULL; i = i->i_bsame) + if (i->i_unit == STAR) + goto foundstar; + continue; + foundstar: + if (ht_lookup(needcnttab, d->d_name)) { + (void)fprintf(stderr, + "config: %s's cannot be *'d until its driver is fixed\n", + d->d_name); + errs++; + continue; + } + for (n = 0; i != NULL; i = i->i_alias) + if (!i->i_collapsed) + n++; + if (n < 1) + panic("badstar() n<1"); + if (n == 1) + continue; + (void)fprintf(stderr, + "config: %d %s*'s in configuration; can only have 1\n", + n, d->d_name); + errs++; + } + return (errs); +} diff --git a/usr.sbin/config.new/mkheaders.c b/usr.sbin/config.new/mkheaders.c new file mode 100644 index 0000000..f627243 --- /dev/null +++ b/usr.sbin/config.new/mkheaders.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratories. + * + * 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. + * + * @(#)mkheaders.c 8.1 (Berkeley) 6/6/93 + */ + +#include +#include +#include +#include +#include +#include +#include "config.h" + +static int emitcnt __P((struct nvlist *)); +static int err __P((const char *, char *, FILE *)); +static char *cntname __P((const char *)); + +/* + * Make headers containing counts, as needed. + */ +int +mkheaders() +{ + register struct files *fi; + + for (fi = allfiles; fi != NULL; fi = fi->fi_next) { + if (fi->fi_flags & FI_HIDDEN) + continue; + if (fi->fi_flags & (FI_NEEDSCOUNT | FI_NEEDSFLAG) && + emitcnt(fi->fi_opt)) + return (1); + } + return (0); +} + +static int +emitcnt(head) + register struct nvlist *head; +{ + register struct nvlist *nv; + register FILE *fp; + register char *fname; + int cnt; + char nam[100]; + char buf[BUFSIZ]; + + (void)sprintf(buf, "%s.h", head->nv_name); + fname = path(buf); + if ((fp = fopen(fname, "r")) == NULL) + goto writeit; + nv = head; + while (fgets(buf, sizeof(buf), fp) != NULL) { + if (nv == NULL) + goto writeit; + if (sscanf(buf, "#define %s %d", nam, &cnt) != 2 || + strcmp(nam, cntname(nv->nv_name)) != 0 || + cnt != nv->nv_int) + goto writeit; + nv = nv->nv_next; + } + if (ferror(fp)) + return (err("read", fname, fp)); + (void)fclose(fp); + if (nv == NULL) + return (0); +writeit: + if ((fp = fopen(fname, "w")) == NULL) { + (void)fprintf(stderr, "config: cannot write %s: %s\n", + fname, strerror(errno)); + return (1); + } + for (nv = head; nv != NULL; nv = nv->nv_next) + if (fprintf(fp, "#define\t%s\t%d\n", + cntname(nv->nv_name), nv->nv_int) < 0) + return (err("writ", fname, fp)); + if (fclose(fp)) + return (err("writ", fname, NULL)); + return (0); +} + +static int +err(what, fname, fp) + const char *what; + char *fname; + FILE *fp; +{ + + (void)fprintf(stderr, "config: error %sing %s: %s\n", + what, fname, strerror(errno)); + if (fp) + (void)fclose(fp); + free(fname); + return (1); +} + +static char * +cntname(src) + register const char *src; +{ + register char *dst, c; + static char buf[100]; + + dst = buf; + *dst++ = 'N'; + while ((c = *src++) != 0) + *dst++ = islower(c) ? toupper(c) : c; + *dst = 0; + return (buf); +} diff --git a/usr.sbin/config.new/mkioconf.c b/usr.sbin/config.new/mkioconf.c new file mode 100644 index 0000000..8b1ebe0 --- /dev/null +++ b/usr.sbin/config.new/mkioconf.c @@ -0,0 +1,395 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratories. + * + * 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. + * + * @(#)mkioconf.c 8.1 (Berkeley) 6/6/93 + */ + +#include +#include +#include +#include +#include +#include "config.h" + +/* + * Make ioconf.c. + */ +static int cforder __P((const void *, const void *)); +static int emitcfdata __P((FILE *)); +static int emitexterns __P((FILE *)); +static int emithdr __P((FILE *)); +static int emitloc __P((FILE *)); +static int emitpseudo __P((FILE *)); +static int emitpv __P((FILE *)); +static int emitroots __P((FILE *)); +static int emitvec __P((FILE *)); +static char *vecname __P((char *, const char *, int)); + +static const char *s_i386; + +#define SEP(pos, max) (((u_int)(pos) % (max)) == 0 ? "\n\t" : " ") + +/* + * NEWLINE can only be used in the emitXXX functions. + * In most cases it can be subsumed into an fprintf. + */ +#define NEWLINE if (putc('\n', fp) < 0) return (1) + +int +mkioconf() +{ + register FILE *fp; + register char *fname; + int v; + + s_i386 = intern("i386"); + + fname = path("ioconf.c"); + qsort(packed, npacked, sizeof *packed, cforder); + if ((fp = fopen(fname, "w")) == NULL) { + (void)fprintf(stderr, "config: cannot write %s: %s\n", + fname, strerror(errno)); + return (1); + } + v = emithdr(fp); + if (v != 0 || emitvec(fp) || emitexterns(fp) || emitloc(fp) || + emitpv(fp) || emitcfdata(fp) || emitroots(fp) || emitpseudo(fp)) { + if (v >= 0) + (void)fprintf(stderr, + "config: error writing %s: %s\n", + fname, strerror(errno)); + (void)fclose(fp); + /* (void)unlink(fname); */ + free(fname); + return (1); + } + (void)fclose(fp); + free(fname); + return (0); +} + +static int +cforder(a, b) + const void *a, *b; +{ + register int n1, n2; + + n1 = (*(struct devi **)a)->i_cfindex; + n2 = (*(struct devi **)b)->i_cfindex; + return (n1 - n2); +} + +static int +emithdr(ofp) + register FILE *ofp; +{ + register FILE *ifp; + register int n; + char ifn[200], buf[BUFSIZ]; + + if (fprintf(ofp, "\ +/*\n\ + * MACHINE GENERATED: DO NOT EDIT\n\ + *\n\ + * ioconf.c, from \"%s\"\n\ + */\n\n", conffile) < 0) + return (1); + (void)sprintf(ifn, "ioconf.incl.%s", machine); + if ((ifp = fopen(ifn, "r")) != NULL) { + while ((n = fread(buf, 1, sizeof(buf), ifp)) > 0) + if (fwrite(buf, 1, n, ofp) != n) + return (1); + if (ferror(ifp)) { + (void)fprintf(stderr, "config: error reading %s: %s\n", + ifn, strerror(errno)); + (void)fclose(ifp); + return (-1); + } + (void)fclose(ifp); + } else { + if (fputs("\ +#include \n\ +#include \n", ofp) < 0) + return (1); + } + return (0); +} + +static int +emitexterns(fp) + register FILE *fp; +{ + register struct devbase *d; + + NEWLINE; + for (d = allbases; d != NULL; d = d->d_next) { + if (d->d_ihead == NULL) + continue; + if (fprintf(fp, "extern struct cfdriver %scd;\n", + d->d_name) < 0) + return (1); + } + NEWLINE; + return (0); +} + +static int +emitloc(fp) + register FILE *fp; +{ + register int i; + + if (fprintf(fp, "\n/* locators */\n\ +static int loc[%d] = {", locators.used) < 0) + return (1); + for (i = 0; i < locators.used; i++) + if (fprintf(fp, "%s%s,", SEP(i, 8), locators.vec[i]) < 0) + return (1); + return (fprintf(fp, "\n};\n") < 0); +} + +/* + * Emit global parents-vector. + */ +static int +emitpv(fp) + register FILE *fp; +{ + register int i; + + if (fprintf(fp, "\n/* parent vectors */\n\ +static short pv[%d] = {", parents.used) < 0) + return (1); + for (i = 0; i < parents.used; i++) + if (fprintf(fp, "%s%d,", SEP(i, 16), parents.vec[i]) < 0) + return (1); + return (fprintf(fp, "\n};\n") < 0); +} + +/* + * Emit the cfdata array. + */ +static int +emitcfdata(fp) + register FILE *fp; +{ + register struct devi **p, *i, **par; + register int unit, v; + register const char *vs, *state, *basename; + register struct nvlist *nv; + register struct attr *a; + char *loc; + char locbuf[20]; + + if (fprintf(fp, "\n\ +#define NORM FSTATE_NOTFOUND\n\ +#define STAR FSTATE_STAR\n\ +\n\ +struct cfdata cfdata[] = {\n\ +\t/* driver unit state loc flags parents ivstubs */\n") < 0) + return (1); + for (p = packed; (i = *p) != NULL; p++) { + /* the description */ + if (fprintf(fp, "/*%3d: %s at ", i->i_cfindex, i->i_name) < 0) + return (1); + par = i->i_parents; + for (v = 0; v < i->i_pvlen; v++) + if (fprintf(fp, "%s%s", v == 0 ? "" : "|", + i->i_parents[v]->i_name) < 0) + return (1); + if (v == 0 && fputs("root", fp) < 0) + return (1); + a = i->i_atattr; + nv = a->a_locs; + for (nv = a->a_locs, v = 0; nv != NULL; nv = nv->nv_next, v++) + if (fprintf(fp, " %s %s", + nv->nv_name, i->i_locs[v]) < 0) + return (1); + if (fputs(" */\n", fp) < 0) + return (-1); + + /* then the actual defining line */ + basename = i->i_base->d_name; + if (i->i_unit == STAR) { + unit = i->i_base->d_umax; + state = "STAR"; + } else { + unit = i->i_unit; + state = "NORM"; + } + if (i->i_ivoff < 0) { + vs = ""; + v = 0; + } else { + vs = "vec+"; + v = i->i_ivoff; + } + if (i->i_locoff >= 0) { + (void)sprintf(locbuf, "loc+%3d", i->i_locoff); + loc = locbuf; + } else + loc = "loc"; + if (fprintf(fp, "\ +\t{&%scd,%s%2d, %s, %7s, %#6x, pv+%2d, %s%d},\n", + basename, strlen(basename) < 3 ? "\t\t" : "\t", unit, + state, loc, i->i_cfflags, i->i_pvoff, vs, v) < 0) + return (1); + } + return (fputs("\t{0}\n};\n", fp) < 0); +} + +/* + * Emit the table of potential roots. + */ +static int +emitroots(fp) + register FILE *fp; +{ + register struct devi **p, *i; + + if (fputs("\nshort cfroots[] = {\n", fp) < 0) + return (1); + for (p = packed; (i = *p) != NULL; p++) { + if (i->i_at != NULL) + continue; + if (i->i_unit != 0 && + (i->i_unit != STAR || i->i_base->d_umax != 0)) + (void)fprintf(stderr, + "config: warning: `%s at root' is not unit 0\n", + i->i_name); + if (fprintf(fp, "\t%2d /* %s */,\n", + i->i_cfindex, i->i_name) < 0) + return (1); + } + return (fputs("\t-1\n};\n", fp) < 0); +} + +/* + * Emit pseudo-device initialization. + */ +static int +emitpseudo(fp) + register FILE *fp; +{ + register struct devi *i; + register struct devbase *d; + + if (fputs("\n/* pseudo-devices */\n", fp) < 0) + return (1); + for (i = allpseudo; i != NULL; i = i->i_next) + if (fprintf(fp, "extern void %sattach __P((int));\n", + i->i_base->d_name) < 0) + return (1); + if (fputs("\nstruct pdevinit pdevinit[] = {\n", fp) < 0) + return (1); + for (i = allpseudo; i != NULL; i = i->i_next) { + d = i->i_base; + if (fprintf(fp, "\t{ %sattach, %d },\n", + d->d_name, d->d_umax) < 0) + return (1); + } + return (fputs("\t{ 0, 0 }\n};\n", fp) < 0); +} + +/* + * Emit interrupt vector declarations, and calculate offsets. + */ +static int +emitvec(fp) + register FILE *fp; +{ + register struct nvlist *head, *nv; + register struct devi **p, *i; + register int j, nvec, unit; + char buf[200]; + + nvec = 0; + for (p = packed; (i = *p) != NULL; p++) { + if ((head = i->i_base->d_vectors) == NULL) + continue; + if ((unit = i->i_unit) == STAR) + panic("emitvec unit==STAR"); + if (nvec == 0) + NEWLINE; + for (j = 0, nv = head; nv != NULL; j++, nv = nv->nv_next) + if (fprintf(fp, + "/* IVEC %s %d */ extern void %s();\n", + nv->nv_name, unit, + vecname(buf, nv->nv_name, unit)) < 0) + return (1); + nvec += j + 1; + } + if (nvec == 0) + return (0); + if (fprintf(fp, "\nstatic void (*vec[%d]) __P((void)) = {", nvec) < 0) + return (1); + nvec = 0; + for (p = packed; (i = *p) != NULL; p++) { + if ((head = i->i_base->d_vectors) == NULL) + continue; + i->i_ivoff = nvec; + unit = i->i_unit; + for (nv = head; nv != NULL; nv = nv->nv_next) + if (fprintf(fp, "%s%s,", + SEP(nvec++, 4), + vecname(buf, nv->nv_name, unit)) < 0) + return (1); + if (fprintf(fp, "%s0,", SEP(nvec++, 4)) < 0) + return (1); + } + return (fputs("\n};\n", fp) < 0); +} + +static char * +vecname(buf, name, unit) + char *buf; + const char *name; + int unit; +{ + + /* @#%* 386 uses a different name format */ + if (machine == s_i386) { + (void)sprintf(buf, "V%s%d", name, unit); + return (buf); + } + (void)sprintf(buf, "X%s%d", name, unit); + return (buf); +} diff --git a/usr.sbin/config.new/mkmakefile.c b/usr.sbin/config.new/mkmakefile.c new file mode 100644 index 0000000..06971a5 --- /dev/null +++ b/usr.sbin/config.new/mkmakefile.c @@ -0,0 +1,364 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratories. + * + * 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. + * + * @(#)mkmakefile.c 8.1 (Berkeley) 6/6/93 + */ + +#include +#include +#include +#include +#include +#include +#include "config.h" + +/* + * Make the Makefile. + */ + +static int emitdefs __P((FILE *)); +static int emitobjs __P((FILE *)); +static int emitcfiles __P((FILE *)); +static int emitsfiles __P((FILE *)); +static int emitfiles __P((FILE *, int)); +static int emitrules __P((FILE *)); +static int emitload __P((FILE *)); + +int +mkmakefile() +{ + register FILE *ifp, *ofp; + register int lineno; + register int (*fn) __P((FILE *)); + register char *ofname; + char line[BUFSIZ], ifname[200]; + + (void)sprintf(ifname, "Makefile.%s", machine); + if ((ifp = fopen(ifname, "r")) == NULL) { + (void)fprintf(stderr, "config: cannot read %s: %s\n", + ifname, strerror(errno)); + return (1); + } + ofname = path("Makefile"); + if ((ofp = fopen(ofname, "w")) == NULL) { + (void)fprintf(stderr, "config: cannot write %s: %s\n", + ofname, strerror(errno)); + free(ofname); + return (1); + } + if (emitdefs(ofp) != 0) + goto wrerror; + lineno = 0; + while (fgets(line, sizeof(line), ifp) != NULL) { + lineno++; + if (line[0] != '%') { + if (fputs(line, ofp) < 0) + goto wrerror; + continue; + } + if (strcmp(line, "%OBJS\n") == 0) + fn = emitobjs; + else if (strcmp(line, "%CFILES\n") == 0) + fn = emitcfiles; + else if (strcmp(line, "%SFILES\n") == 0) + fn = emitsfiles; + else if (strcmp(line, "%RULES\n") == 0) + fn = emitrules; + else if (strcmp(line, "%LOAD\n") == 0) + fn = emitload; + else { + xerror(ifname, lineno, + "unknown %% construct ignored: %s", line); + continue; + } + if ((*fn)(ofp)) + goto wrerror; + } + if (ferror(ifp)) { + (void)fprintf(stderr, + "config: error reading %s (at line %d): %s\n", + ifname, lineno, strerror(errno)); + goto bad; + /* (void)unlink(ofname); */ + free(ofname); + return (1); + } + if (fclose(ofp)) { + ofp = NULL; + goto wrerror; + } + (void)fclose(ifp); + free(ofname); + return (0); +wrerror: + (void)fprintf(stderr, "config: error writing %s: %s\n", + ofname, strerror(errno)); +bad: + if (ofp != NULL) + (void)fclose(ofp); + /* (void)unlink(ofname); */ + free(ofname); + return (1); +} + +static int +emitdefs(fp) + register FILE *fp; +{ + register struct nvlist *nv; + register char *sp; + + if (fputs("IDENT=", fp) < 0) + return (1); + sp = ""; + for (nv = options; nv != NULL; nv = nv->nv_next) { + if (fprintf(fp, "%s-D%s%s%s", sp, nv->nv_name, + nv->nv_str ? "=" : "", nv->nv_str ? nv->nv_str : "") < 0) + return (1); + sp = " "; + } + if (putc('\n', fp) < 0) + return (1); + if (fprintf(fp, "PARAM=-DMAXUSERS=%d\n", maxusers) < 0) + return (1); + for (nv = mkoptions; nv != NULL; nv = nv->nv_next) + if (fprintf(fp, "%s=%s\n", nv->nv_name, nv->nv_str) < 0) + return (1); + return (0); +} + +static int +emitobjs(fp) + register FILE *fp; +{ + register struct files *fi; + register int lpos, len, sp; + + if (fputs("OBJS=", fp) < 0) + return (1); + sp = '\t'; + lpos = 7; + for (fi = allfiles; fi != NULL; fi = fi->fi_next) { + if ((fi->fi_flags & FI_SEL) == 0) + continue; + len = strlen(fi->fi_base) + 2; + if (lpos + len > 72) { + if (fputs(" \\\n", fp) < 0) + return (1); + sp = '\t'; + lpos = 7; + } + if (fprintf(fp, "%c%s.o", sp, fi->fi_base) < 0) + return (1); + lpos += len + 1; + sp = ' '; + } + if (lpos != 7 && putc('\n', fp) < 0) + return (1); + return (0); +} + +static int +emitcfiles(fp) + FILE *fp; +{ + + return (emitfiles(fp, 'c')); +} + +static int +emitsfiles(fp) + FILE *fp; +{ + + return (emitfiles(fp, 's')); +} + +static int +emitfiles(fp, suffix) + register FILE *fp; + int suffix; +{ + register struct files *fi; + register struct config *cf; + register int lpos, len, sp; + char swapname[100]; + + if (fprintf(fp, "%cFILES=", toupper(suffix)) < 0) + return (1); + sp = '\t'; + lpos = 7; + for (fi = allfiles; fi != NULL; fi = fi->fi_next) { + if ((fi->fi_flags & FI_SEL) == 0) + continue; + len = strlen(fi->fi_path); + if (fi->fi_path[len - 1] != suffix) + continue; + if (*fi->fi_path != '/') + len += 3; /* "$S/" */ + if (lpos + len > 72) { + if (fputs(" \\\n", fp) < 0) + return (1); + sp = '\t'; + lpos = 7; + } + if (fprintf(fp, "%c%s%s", sp, *fi->fi_path != '/' ? "$S/" : "", + fi->fi_path) < 0) + return (1); + lpos += len + 1; + sp = ' '; + } + /* + * The allfiles list does not include the configuration-specific + * C source files. These files should be eliminated someday, but + * for now, we have to add them to ${CFILES} (and only ${CFILES}). + */ + if (suffix == 'c') { + for (cf = allcf; cf != NULL; cf = cf->cf_next) { + if (cf->cf_root == NULL) + (void)sprintf(swapname, + "$S/%s/%s/swapgeneric.c", + machine, machine); + else + (void)sprintf(swapname, "swap%s.c", + cf->cf_name); + len = strlen(swapname); + if (lpos + len > 72) { + if (fputs(" \\\n", fp) < 0) + return (1); + sp = '\t'; + lpos = 7; + } + if (fprintf(fp, "%c%s", sp, swapname) < 0) + return (1); + lpos += len + 1; + sp = ' '; + } + } + if (lpos != 7 && putc('\n', fp) < 0) + return (1); + return (0); +} + +/* + * Emit the make-rules. + */ +static int +emitrules(fp) + register FILE *fp; +{ + register struct files *fi; + register const char *cp; + int ch; + char buf[200]; + + for (fi = allfiles; fi != NULL; fi = fi->fi_next) { + if ((fi->fi_flags & FI_SEL) == 0) + continue; + if (fprintf(fp, "%s.o: %s%s\n", fi->fi_base, + *fi->fi_path != '/' ? "$S/" : "", fi->fi_path) < 0) + return (1); + if ((cp = fi->fi_mkrule) == NULL) { + cp = fi->fi_flags & FI_DRIVER ? "DRIVER" : "NORMAL"; + ch = fi->fi_lastc; + if (islower(ch)) + ch = toupper(ch); + (void)sprintf(buf, "${%s_%c%s}", cp, ch, + fi->fi_flags & FI_CONFIGDEP ? "_C" : ""); + cp = buf; + } + if (fprintf(fp, "\t%s\n\n", cp) < 0) + return (1); + } + return (0); +} + +/* + * Emit the load commands. + * + * This function is not to be called `spurt'. + */ +static int +emitload(fp) + register FILE *fp; +{ + register struct config *cf; + register const char *nm, *swname; + int first; + + if (fputs("all:", fp) < 0) + return (1); + for (cf = allcf; cf != NULL; cf = cf->cf_next) { + if (fprintf(fp, " %s", cf->cf_name) < 0) + return (1); + } + if (fputs("\n\n", fp) < 0) + return (1); + for (first = 1, cf = allcf; cf != NULL; cf = cf->cf_next) { + nm = cf->cf_name; + swname = cf->cf_root != NULL ? cf->cf_name : "generic"; + if (fprintf(fp, "%s: ${SYSTEM_DEP} swap%s.o", nm, swname) < 0) + return (1); + if (first) { + if (fputs(" newvers", fp) < 0) + return (1); + first = 0; + } + if (fprintf(fp, "\n\ +\t${SYSTEM_LD_HEAD}\n\ +\t${SYSTEM_LD} swap%s.o\n\ +\t${SYSTEM_LD_TAIL}\n\ +\n\ +swap%s.o: ", swname, swname) < 0) + return (1); + if (cf->cf_root != NULL) { + if (fprintf(fp, "swap%s.c\n", nm) < 0) + return (1); + } else { + if (fprintf(fp, "$S/%s/%s/swapgeneric.c\n", + machine, machine) < 0) + return (1); + } + if (fputs("\t${NORMAL_C}\n\n", fp) < 0) + return (1); + } + return (0); +} diff --git a/usr.sbin/config.new/mkswap.c b/usr.sbin/config.new/mkswap.c new file mode 100644 index 0000000..afea210 --- /dev/null +++ b/usr.sbin/config.new/mkswap.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratories. + * + * 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. + * + * @(#)mkswap.c 8.1 (Berkeley) 6/6/93 + */ + +#include +#include +#include +#include +#include +#include "config.h" + +static int mkoneswap __P((struct config *)); + +/* + * Make the various swap*.c files. Nothing to do for generic swap. + */ +int +mkswap() +{ + register struct config *cf; + + for (cf = allcf; cf != NULL; cf = cf->cf_next) + if (cf->cf_root != NULL && mkoneswap(cf)) + return (1); + return (0); +} + +static int +mkoneswap(cf) + register struct config *cf; +{ + register struct nvlist *nv; + register FILE *fp; + register char *fname; + char buf[200]; + + (void)sprintf(buf, "swap%s.c", cf->cf_name); + fname = path(buf); + if ((fp = fopen(fname, "w")) == NULL) { + (void)fprintf(stderr, "config: cannot write %s: %s\n", + fname, strerror(errno)); + return (1); + } + if (fputs("\ +#include \n\ +#include \n\n", fp) < 0) + goto wrerror; + nv = cf->cf_root; + if (fprintf(fp, "dev_t\trootdev = makedev(%d, %d);\t/* %s */\n", + major(nv->nv_int), minor(nv->nv_int), nv->nv_str) < 0) + goto wrerror; + nv = cf->cf_dump; + if (fprintf(fp, "dev_t\tdumpdev = makedev(%d, %d);\t/* %s */\n", + major(nv->nv_int), minor(nv->nv_int), nv->nv_str) < 0) + goto wrerror; + if (fputs("\nstruct\tswdevt swdevt[] = {\n", fp) < 0) + goto wrerror; + for (nv = cf->cf_swap; nv != NULL; nv = nv->nv_next) + if (fprintf(fp, "\t{ makedev(%d, %d),\t0,\t0 },\t/* %s */\n", + major(nv->nv_int), minor(nv->nv_int), nv->nv_str) < 0) + goto wrerror; + if (fputs("\t{ NODEV, 0, 0 }\n};\n", fp) < 0) + goto wrerror; + if (fclose(fp)) { + fp = NULL; + goto wrerror; + } + free(fname); + return (0); +wrerror: + (void)fprintf(stderr, "config: error writing %s: %s\n", + fname, strerror(errno)); + if (fp != NULL) + (void)fclose(fp); + /* (void)unlink(fname); */ + free(fname); + return (1); +} diff --git a/usr.sbin/config.new/pack.c b/usr.sbin/config.new/pack.c new file mode 100644 index 0000000..8b525ec --- /dev/null +++ b/usr.sbin/config.new/pack.c @@ -0,0 +1,520 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratories. + * + * 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. + * + * @(#)pack.c 8.1 (Berkeley) 6/6/93 + */ + +#include +#include +#include +#include "config.h" + +/* + * Packing. We have three separate kinds of packing here. + * + * First, we pack device instances, to collapse things like + * + * uba0 at sbi0 nexus ? + * uba0 at bi0 nexus ? + * + * into a single instance that is "at sbi0 or bi0". + * + * Second, we pack locators. Given something like + * + * hp0 at mba0 drive 0 + * hp* at mba* drive ? + * ht0 at mba0 drive 0 + * tu0 at ht0 slave 0 + * ht* at mba* drive ? + * tu* at ht* slave ? + * + * (where the default drive and slave numbers are -1), we have three + * locators whose value is 0 and three whose value is -1. Rather than + * emitting six integers, we emit just two. + * + * Finally, we pack parent vectors. This is very much like packing + * locators. Unlike locators, however, parent vectors are always + * terminated by -1 (rather like the way C strings always end with + * a NUL). + * + * When packing locators, we would like to find sequences such as + * {1 2 3} {2 3 4} {3} {4 5} + * and turn this into the flat sequence {1 2 3 4 5}, with each subsequence + * given by the appropriate offset (here 0, 1, 2, and 3 respectively). + * When we pack parent vectors, overlap of this sort is impossible. + * Non-overlapping packing is much easier, and so we use that here + * and miss out on the chance to squeeze the locator sequence optimally. + * (So it goes.) + */ + +typedef int (*vec_cmp_func) __P((const void *, int, int)); + +#define TAILHSIZE 128 +#define PVHASH(i) ((i) & (TAILHSIZE - 1)) +#define LOCHASH(l) (((int)(l) >> 2) & (TAILHSIZE - 1)) +struct tails { + struct tails *t_next; + int t_ends_at; +}; + +static struct tails *tails[TAILHSIZE]; +static int locspace; +static int pvecspace; +static int longest_pvec; + +static void packdevi __P((void)); +static void packlocs __P((void)); +static void packpvec __P((void)); + +static void addparents __P((struct devi *src, struct devi *dst)); +static int nparents __P((struct devi **, struct devbase *, int)); +static int sameas __P((struct devi *, struct devi *)); +static int findvec __P((const void *, int, int, vec_cmp_func, int)); +static int samelocs __P((const void *, int, int)); +static int addlocs __P((const char **, int)); +static int loclencmp __P((const void *, const void *)); +static int samepv __P((const void *, int, int)); +static int addpv __P((short *, int)); +static int pvlencmp __P((const void *, const void *)); +static void resettails __P((void)); + +void +pack() +{ + register struct devi *i; + register int n; + + /* Pack instances and make parent vectors. */ + packdevi(); + + /* + * Now that we know what we have, find upper limits on space + * needed for the loc[] and pv[] tables, and find the longest + * single pvec. The loc and pv table sizes are bounded by + * what we would get if no packing occurred. + */ + locspace = pvecspace = 0; + for (i = alldevi; i != NULL; i = i->i_next) { + if (i->i_collapsed) + continue; + locspace += i->i_atattr->a_loclen; + n = i->i_pvlen + 1; + if (n > longest_pvec) + longest_pvec = n; + pvecspace += n; + } + + /* Allocate and pack loc[]. */ + locators.vec = emalloc(locspace * sizeof(*locators.vec)); + locators.used = 0; + packlocs(); + + /* Allocate and pack pv[]. */ + parents.vec = emalloc(pvecspace * sizeof(*parents.vec)); + parents.used = 0; + packpvec(); +} + +/* + * Pack instances together wherever possible. When everything is + * packed, go back and set up the parents for each. We must do this + * on a second pass because during the first one, we do not know which, + * if any, of the parents will collapse during packing. + */ +void +packdevi() +{ + register struct devi *i, *l, *p; + register struct devbase *d; + register int j, m, n; + + packed = emalloc((ndevi + 1) * sizeof *packed); + n = 0; + for (d = allbases; d != NULL; d = d->d_next) { + /* + * For each instance of each device, add or collapse + * all its aliases. + */ + for (i = d->d_ihead; i != NULL; i = i->i_bsame) { + m = n; + for (l = i; l != NULL; l = l->i_alias) { + l->i_pvlen = 0; + l->i_pvoff = -1; + l->i_locoff = -1; + l->i_ivoff = -1; + /* try to find an equivalent for l */ + for (j = m; j < n; j++) { + p = packed[j]; + if (sameas(l, p)) { + l->i_collapsed = 1; + l->i_cfindex = p->i_cfindex; + goto nextalias; + } + } + /* could not find a suitable alias */ + l->i_collapsed = 0; + l->i_cfindex = n; + l->i_parents = emalloc(sizeof(*l->i_parents)); + l->i_parents[0] = NULL; + packed[n++] = l; + nextalias:; + } + } + } + npacked = n; + packed[n] = NULL; + for (i = alldevi; i != NULL; i = i->i_next) + addparents(i, packed[i->i_cfindex]); +} + +/* + * Return true if two aliases are "the same". In this case, they need + * to have the same config flags and the same locators. + */ +static int +sameas(i1, i2) + register struct devi *i1, *i2; +{ + register const char **p1, **p2; + + if (i1->i_cfflags != i2->i_cfflags) + return (0); + for (p1 = i1->i_locs, p2 = i2->i_locs; *p1 == *p2; p2++) + if (*p1++ == 0) + return (1); + return 0; +} + +/* + * Add the parents associated with "src" to the (presumably uncollapsed) + * instance "dst". + */ +static void +addparents(src, dst) + register struct devi *src, *dst; +{ + register struct nvlist *nv; + register struct devi *i, **p, **q; + register int j, n, old, new, ndup; + + if (dst->i_collapsed) + panic("addparents() i_collapsed"); + + /* Collect up list of parents to add. */ + if (src->i_at == NULL) /* none, 'cuz "at root" */ + return; + if (src->i_atdev != NULL) { + n = nparents(NULL, src->i_atdev, src->i_atunit); + p = emalloc(n * sizeof *p); + if (n == 0) + return; + (void)nparents(p, src->i_atdev, src->i_atunit); + } else { + n = 0; + for (nv = src->i_atattr->a_refs; nv != NULL; nv = nv->nv_next) + n += nparents(NULL, nv->nv_ptr, src->i_atunit); + if (n == 0) + return; + p = emalloc(n * sizeof *p); + n = 0; + for (nv = src->i_atattr->a_refs; nv != NULL; nv = nv->nv_next) + n += nparents(p + n, nv->nv_ptr, src->i_atunit); + } + /* Now elide duplicates. */ + ndup = 0; + for (j = 0; j < n; j++) { + i = p[j]; + for (q = dst->i_parents; *q != NULL; q++) { + if (*q == i) { + ndup++; + p[j] = NULL; + break; + } + } + } + /* Finally, add all the non-duplicates. */ + old = dst->i_pvlen; + new = old + (n - ndup); + if (old > new) + panic("addparents() old > new"); + if (old == new) { + free(p); + return; + } + dst->i_parents = q = erealloc(dst->i_parents, (new + 1) * sizeof(*q)); + dst->i_pvlen = new; + q[new] = NULL; + q += old; + for (j = 0; j < n; j++) + if (p[j] != NULL) + *q++ = p[j]; + free(p); +} + +/* + * Count up parents, and optionally store pointers to each. + */ +static int +nparents(p, dev, unit) + register struct devi **p; + register struct devbase *dev; + register int unit; +{ + register struct devi *i, *l; + register int n; + + n = 0; + /* for each instance ... */ + for (i = dev->d_ihead; i != NULL; i = i->i_bsame) { + /* ... take each un-collapsed alias */ + for (l = i; l != NULL; l = l->i_alias) { + if (!l->i_collapsed && + (unit == WILD || unit == l->i_unit)) { + if (p != NULL) + *p++ = l; + n++; + } + } + } + return (n); +} + +static void +packlocs() +{ + register struct devi **p, *i; + register int l, o; + + qsort(packed, npacked, sizeof *packed, loclencmp); + for (p = packed; (i = *p) != NULL; p++) { + if ((l = i->i_atattr->a_loclen) > 0) { + o = findvec(i->i_locs, LOCHASH(i->i_locs[l - 1]), l, + samelocs, locators.used); + i->i_locoff = o < 0 ? addlocs(i->i_locs, l) : o; + } else + i->i_locoff = -1; + } + resettails(); +} + +static void +packpvec() +{ + register struct devi **p, *i, **par; + register int l, v, o; + register short *vec; + + vec = emalloc(longest_pvec * sizeof(*vec)); + qsort(packed, npacked, sizeof *packed, pvlencmp); + for (p = packed; (i = *p) != NULL; p++) { + l = i->i_pvlen; +if (l > longest_pvec) panic("packpvec"); + par = i->i_parents; + for (v = 0; v < l; v++) + vec[v] = par[v]->i_cfindex; + if (l == 0 || + (o = findvec(vec, PVHASH(vec[l - 1]), l, + samepv, parents.used)) < 0) + o = addpv(vec, l); + i->i_pvoff = o; + } + free(vec); + resettails(); +} + +/* + * Return the index at which the given vector already exists, or -1 + * if it is not anywhere in the current set. If we return -1, we assume + * our caller will add it at the end of the current set, and we make + * sure that next time, we will find it there. + */ +static int +findvec(ptr, hash, len, cmp, nextplace) + const void *ptr; + int hash, len; + vec_cmp_func cmp; + int nextplace; +{ + register struct tails *t, **hp; + register int off; + + hp = &tails[hash]; + for (t = *hp; t != NULL; t = t->t_next) { + off = t->t_ends_at - len; + if (off >= 0 && (*cmp)(ptr, off, len)) + return (off); + } + t = emalloc(sizeof(*t)); + t->t_next = *hp; + *hp = t; + t->t_ends_at = nextplace + len; + return (-1); +} + +/* + * Comparison function for locators. + */ +static int +samelocs(ptr, off, len) + const void *ptr; + int off; + register int len; +{ + register const char **p, **q; + + for (p = &locators.vec[off], q = (const char **)ptr; --len >= 0;) + if (*p++ != *q++) + return (0); /* different */ + return (1); /* same */ +} + +/* + * Add the given locators at the end of the global loc[] table. + */ +static int +addlocs(locs, len) + register const char **locs; + register int len; +{ + register const char **p; + register int ret; + + ret = locators.used; + if ((locators.used = ret + len) > locspace) + panic("addlocs: overrun"); + for (p = &locators.vec[ret]; --len >= 0;) + *p++ = *locs++; + return (ret); +} + +/* + * Comparison function for qsort-by-locator-length, longest first. + * We rashly assume that subtraction of these lengths does not overflow. + */ +static int +loclencmp(a, b) + const void *a, *b; +{ + register int l1, l2; + + l1 = (*(struct devi **)a)->i_atattr->a_loclen; + l2 = (*(struct devi **)b)->i_atattr->a_loclen; + return (l2 - l1); +} + +/* + * Comparison function for parent vectors. + */ +static int +samepv(ptr, off, len) + const void *ptr; + int off; + register int len; +{ + register short *p, *q; + + for (p = &parents.vec[off], q = (short *)ptr; --len >= 0;) + if (*p++ != *q++) + return (0); /* different */ + return (1); /* same */ +} + +/* + * Add the given parent vectors at the end of the global pv[] table. + */ +static int +addpv(pv, len) + register short *pv; + register int len; +{ + register short *p; + register int ret; + static int firstend = -1; + + /* + * If the vector is empty, reuse the first -1. It will be + * there if there are any nonempty vectors at all, since we + * do the longest first. If there are no nonempty vectors, + * something is probably wrong, but we will ignore that here. + */ + if (len == 0 && firstend >= 0) + return (firstend); + len++; /* account for trailing -1 */ + ret = parents.used; + if ((parents.used = ret + len) > pvecspace) + panic("addpv: overrun"); + for (p = &parents.vec[ret]; --len > 0;) + *p++ = *pv++; + *p = -1; + if (firstend < 0) + firstend = parents.used - 1; + return (ret); +} + +/* + * Comparison function for qsort-by-parent-vector-length, longest first. + * We rashly assume that subtraction of these lengths does not overflow. + */ +static int +pvlencmp(a, b) + const void *a, *b; +{ + register int l1, l2; + + l1 = (*(struct devi **)a)->i_pvlen; + l2 = (*(struct devi **)b)->i_pvlen; + return (l2 - l1); +} + +static void +resettails() +{ + register struct tails **p, *t, *next; + register int i; + + for (p = tails, i = TAILHSIZE; --i >= 0; p++) { + for (t = *p; t != NULL; t = next) { + next = t->t_next; + free(t); + } + *p = NULL; + } +} diff --git a/usr.sbin/config.new/scan.l b/usr.sbin/config.new/scan.l new file mode 100644 index 0000000..b7301a3 --- /dev/null +++ b/usr.sbin/config.new/scan.l @@ -0,0 +1,238 @@ +%{ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratories. + * + * 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. + * + * @(#)scan.l 8.1 (Berkeley) 6/6/93 + */ + +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "y.tab.h" + +int yyline; +const char *yyfile; +const char *lastfile; + +int include __P((const char *, int)); + +/* + * Data for returning to previous files from include files. + */ +struct incl { + struct incl *in_prev; /* previous includes in effect, if any */ + YY_BUFFER_STATE in_buf; /* previous lex state */ + const char *in_fname; /* previous file name */ + int in_lineno; /* previous line number */ + int in_preveof; /* previous eoftoken */ +}; +static struct incl *incl; +static int eoftoken; /* current EOF token */ +static void endinclude __P((void)); + +#define yywrap() 1 + +%} + +PATH [-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]* +WORD [A-Za-z_][-A-Za-z_0-9]* + +%% + + /* plain keywords */ +and { return AND; } +at { return AT; } +compile-with { return COMPILE_WITH; } +config { return CONFIG; } +define { return DEFINE; } +device { return DEVICE; } +dumps { return DUMPS; } +flags { return FLAGS; } +file { return XFILE; } +include { return INCLUDE; } +machine { return XMACHINE; } +major { return MAJOR; } +makeoptions { return MAKEOPTIONS; } +maxusers { return MAXUSERS; } +minor { return MINOR; } +on { return ON; } +options { return OPTIONS; } +"pseudo-device" { return PSEUDO_DEVICE; } +root { return ROOT; } +swap { return SWAP; } +vector { return VECTOR; } + + /* keywords with values */ +config-dependent { yylval.val = FI_CONFIGDEP; return FFLAG; } +device-driver { yylval.val = FI_DRIVER; return FFLAG; } +needs-count { yylval.val = FI_NEEDSCOUNT; return FFLAG; } +needs-flag { yylval.val = FI_NEEDSFLAG; return FFLAG; } + + /* all the rest */ +{PATH} { yylval.str = intern(yytext); return PATHNAME; } +{WORD} { yylval.str = intern(yytext); return WORD; } + +\"[^"]+/\" { + yylval.str = intern(yytext + 1); + (void)input(); /* eat closing quote */ + return WORD; + } +0[0-7]* { + yylval.val = strtol(yytext, NULL, 8); + return NUMBER; + } +0[xX][0-9a-fA-F]+ { + yylval.val = strtol(yytext + 2, NULL, 16); + return NUMBER; + } +[1-9][0-9]* { + yylval.val = strtol(yytext, NULL, 10); + return NUMBER; + } +\n/[ \t] { + yyline++; + } +\n { + yyline++; + return '\n'; + } +#.* { /* ignored (comment) */; } +[ \t]* { /* ignored (white space) */; } +. { return yytext[0]; } +<> { + int tok; + + tok = eoftoken; + eoftoken = YY_NULL; + if (incl != NULL) + endinclude(); + return (tok); + } + +%% + +/* + * Open the "main" file (conffile). + */ +int +firstfile(fname) + const char *fname; +{ + + if ((yyin = fopen(fname, "r")) == NULL) + return (-1); + yyfile = conffile = fname; + yyline = 1; + eoftoken = YY_NULL; + return (0); +} + +/* + * Open the named file for inclusion at the current point. Returns 0 on + * success (file opened and previous state pushed), nonzero on failure + * (fopen failed, complaint made). The `ateof' parameter controls the + * token to be returned at the end of the include file (typically '\n' + * or ENDFILE). + */ +int +include(fname, ateof) + const char *fname; + int ateof; +{ + register FILE *fp; + register struct incl *in; + + if ((fp = fopen(fname, "r")) == NULL) { + error("cannot open %s for reading: %s\n", + fname, strerror(errno)); + return (-1); + } + in = emalloc(sizeof *in); + in->in_prev = incl; + in->in_buf = YY_CURRENT_BUFFER; + in->in_fname = yyfile; + in->in_lineno = yyline; + in->in_preveof = eoftoken; + incl = in; + yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE)); + yyfile = intern(fname); + yyline = 1; + eoftoken = ateof; + return (0); +} + +/* + * Terminate the most recent inclusion. + */ +static void +endinclude() +{ + register struct incl *in; + + if ((in = incl) == NULL) + panic("endinclude"); + incl = in->in_prev; + lastfile = yyfile; + yy_delete_buffer(YY_CURRENT_BUFFER); + (void)fclose(yyin); + yy_switch_to_buffer(in->in_buf); + yyfile = in->in_fname; + yyline = in->in_lineno; + eoftoken = in->in_preveof; + free(in); +} + +/* + * Return the current line number. If yacc has looked ahead and caused + * us to consume a newline, we have to subtract one. yychar is yacc's + * token lookahead, so we can tell. + */ +int +currentline() +{ + extern int yychar; + + return (yyline - (yychar == '\n')); +} diff --git a/usr.sbin/config.new/sem.c b/usr.sbin/config.new/sem.c new file mode 100644 index 0000000..aa60169 --- /dev/null +++ b/usr.sbin/config.new/sem.c @@ -0,0 +1,974 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratories. + * + * 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. + * + * @(#)sem.c 8.1 (Berkeley) 6/6/93 + */ + +#include +#include +#include +#include +#include +#include "config.h" +#include "sem.h" + +/* + * config semantics. + */ + +#define NAMESIZE 100 /* local name buffers */ + +static const char *s_generic; +static const char *s_qmark; + +static struct hashtab *attrtab; /* for attribute lookup */ +static struct hashtab *cfhashtab; /* for config lookup */ +static struct hashtab *devitab; /* etc */ + +static struct attr errattr; +static struct devbase errdev; +static struct devbase **nextbase; +static struct config **nextcf; +static struct devi **nextdevi; +static struct devi **nextpseudo; + +static int has_errobj __P((struct nvlist *, void *)); +static struct nvlist *addtoattr __P((struct nvlist *, struct devbase *)); +static int exclude __P((struct nvlist *, const char *, const char *)); +static int resolve __P((struct nvlist **, const char *, const char *, + struct nvlist *, int)); +static int lresolve __P((struct nvlist **, const char *, const char *, + struct nvlist *, int)); +static struct devi *newdevi __P((const char *, int, struct devbase *d)); +static struct devi *getdevi __P((const char *)); +static const char *concat __P((const char *, int)); +static int split __P((const char *, size_t, char *, size_t, int *)); +static void selectbase __P((struct devbase *)); +static int onlist __P((struct nvlist *, void *)); +static const char **fixloc __P((const char *, struct attr *, struct nvlist *)); + +void +initsem() +{ + + attrtab = ht_new(); + errattr.a_name = ""; + + allbases = NULL; + nextbase = &allbases; + + cfhashtab = ht_new(); + allcf = NULL; + nextcf = &allcf; + + devitab = ht_new(); + alldevi = NULL; + nextdevi = &alldevi; + errdev.d_name = ""; + + allpseudo = NULL; + nextpseudo = &allpseudo; + + s_generic = intern("generic"); + s_qmark = intern("?"); +} + +void +enddefs(fname) + const char *fname; +{ + register struct devbase *dev; + + for (dev = allbases; dev != NULL; dev = dev->d_next) { + if (!dev->d_isdef) { + (void)fprintf(stderr, + "%s: device `%s' used but not defined\n", + fname, dev->d_name); + errors++; + continue; + } + } + if (errors) { + (void)fprintf(stderr, "*** Stop.\n"); + exit(1); + } +} + +void +setdefmaxusers(min, def, max) + int min, def, max; +{ + + if (min < 1 || min > def || def > max) + error("maxusers must have 1 <= min <= default <= max"); + else { + minmaxusers = min; + defmaxusers = def; + maxmaxusers = max; + } +} + +void +setmaxusers(n) + int n; +{ + + if (maxusers != 0) { + error("duplicate maxusers parameter"); + return; + } + maxusers = n; + if (n < minmaxusers) { + error("warning: minimum of %d maxusers assumed\n", minmaxusers); + errors--; /* take it away */ + maxusers = minmaxusers; + } else if (n > maxmaxusers) { + error("warning: maxusers (%d) > %d", n, maxmaxusers); + errors--; + } +} + +/* + * Define an attribute, optionally with an interface (a locator list). + * Since an empty locator list is logically different from "no interface", + * all locator lists include a dummy head node, which we discard here. + */ +int +defattr(name, locs) + const char *name; + struct nvlist *locs; +{ + register struct attr *a; + register struct nvlist *nv; + register int len; + + a = emalloc(sizeof *a); + if (ht_insert(attrtab, name, a)) { + free(a); + error("attribute `%s' already defined", name); + nvfreel(locs); + return (1); + } + a->a_name = name; + if (locs != NULL) { + a->a_iattr = 1; + a->a_locs = locs->nv_next; + nvfree(locs); + } else { + a->a_iattr = 0; + a->a_locs = NULL; + } + len = 0; + for (nv = a->a_locs; nv != NULL; nv = nv->nv_next) + len++; + a->a_loclen = len; + a->a_devs = NULL; + a->a_refs = NULL; + return (0); +} + +/* + * Return true if the given `error object' is embedded in the given + * pointer list. + */ +static int +has_errobj(nv, obj) + register struct nvlist *nv; + register void *obj; +{ + + for (; nv != NULL; nv = nv->nv_next) + if (nv->nv_ptr == obj) + return (1); + return (0); +} + +/* + * Add a device base to a list in an attribute (actually, to any list). + * Note that this does not check for duplicates, and does reverse the + * list order, but no one cares anyway. + */ +static struct nvlist * +addtoattr(l, dev) + register struct nvlist *l; + register struct devbase *dev; +{ + register struct nvlist *n; + + n = newnv(NULL, NULL, dev, 0); + n->nv_next = l; + return (n); +} + +/* + * Device a device, giving its allowable parent attachments, if any. + * This may (or may not) also define an interface attribute and/or refer + * to existing attributes. There may be a list of vectors. + */ +void +defdev(dev, ispseudo, atlist, vectors, loclist, attrs) + register struct devbase *dev; + int ispseudo; + struct nvlist *atlist, *vectors, *loclist, *attrs; +{ + register struct nvlist *nv; + register struct attr *a; + + if (dev == &errdev) + goto bad; + if (dev->d_isdef) { + error("redefinition of `%s'", dev->d_name); + goto bad; + } + dev->d_isdef = 1; + if (has_errobj(attrs, &errattr)) + goto bad; + + /* + * Handle implicit attribute definition from locator list. Do + * this before scanning the `at' list so that we can have, e.g.: + * device foo at other, foo { slot = -1 } + * (where you can plug in a foo-bus extender to a foo-bus). + */ + if (loclist != NULL) { + nv = loclist; + loclist = NULL; /* defattr disposes of them for us */ + if (defattr(dev->d_name, nv)) + goto bad; + nv = newnv(dev->d_name, NULL, getattr(dev->d_name), 0); + nv->nv_next = attrs; + attrs = nv; + } + + /* Committed! Set up fields. */ + dev->d_ispseudo = ispseudo; + dev->d_atlist = atlist; + dev->d_vectors = vectors; + dev->d_attrs = attrs; + + /* + * Turn the `at' list into interface attributes (map each + * nv_name to an attribute, or to NULL for root), and add + * this device to those attributes, so that children can + * be listed at this particular device if they are supported + * by that attribute. + */ + for (nv = atlist; nv != NULL; nv = nv->nv_next) { + if (nv->nv_name == NULL) { + nv->nv_ptr = NULL; /* at root */ + continue; + } + nv->nv_ptr = a = getattr(nv->nv_name); + if (a == &errattr) + continue; /* already complained */ + if (!a->a_iattr) + error("%s cannot be at plain attribute `%s'", + dev->d_name, a->a_name); + else + a->a_devs = addtoattr(a->a_devs, dev); + } + + /* + * For each interface attribute this device refers to, add this + * device to its reference list. This makes, e.g., finding all + * "scsi"s easier. + */ + for (nv = attrs; nv != NULL; nv = nv->nv_next) { + a = nv->nv_ptr; + if (a->a_iattr) + a->a_refs = addtoattr(a->a_refs, dev); + } + return; +bad: + nvfreel(atlist); + nvfreel(vectors); + nvfreel(loclist); + nvfreel(attrs); +} + +/* + * Look up a devbase. Also makes sure it is a reasonable name, + * i.e., does not end in a digit or contain special characters. + */ +struct devbase * +getdevbase(name) + const char *name; +{ + register u_char *p; + register struct devbase *dev; + + p = (u_char *)name; + if (!isalpha(*p)) + goto badname; + while (*++p) { + if (!isalnum(*p) && *p != '_') + goto badname; + } + if (isdigit(*--p)) { +badname: + error("bad device base name `%s'", name); + return (&errdev); + } + dev = ht_lookup(devbasetab, name); + if (dev == NULL) { + dev = emalloc(sizeof *dev); + dev->d_name = name; + dev->d_next = NULL; + dev->d_isdef = 0; + dev->d_major = NODEV; + dev->d_atlist = NULL; + dev->d_vectors = NULL; + dev->d_attrs = NULL; + dev->d_ihead = NULL; + dev->d_ipp = &dev->d_ihead; + dev->d_umax = 0; + *nextbase = dev; + nextbase = &dev->d_next; + if (ht_insert(devbasetab, name, dev)) + panic("getdevbase(%s)", name); + } + return (dev); +} + +/* + * Look up an attribute. + */ +struct attr * +getattr(name) + const char *name; +{ + struct attr *a; + + if ((a = ht_lookup(attrtab, name)) == NULL) { + error("undefined attribute `%s'", name); + a = &errattr; + } + return (a); +} + +/* + * Set the major device number for a device, so that it can be used + * as a root/swap/dumps "on" device in a configuration. + */ +void +setmajor(d, n) + struct devbase *d; + int n; +{ + + if (d != &errdev && d->d_major != NODEV) + error("device `%s' is already major %d", + d->d_name, d->d_major); + else + d->d_major = n; +} + +#define ABS(x) ((x) < 0 ? -(x) : (x)) + +static int +exclude(nv, name, what) + struct nvlist *nv; + const char *name, *what; +{ + + if (nv != NULL) { + error("%s: swap generic must not specify %s", name, what); + return (1); + } + return (0); +} + +/* + * Map things like "ra0b" => makedev(major("ra"), 0*8 + 'b'-'a'). + * Handle the case where the device number is given but there is no + * corresponding name, and map NULL to the default. + */ +static int +resolve(nvp, name, what, dflt, part) + register struct nvlist **nvp; + const char *name, *what; + struct nvlist *dflt; + register int part; +{ + register struct nvlist *nv; + register struct devbase *dev; + register const char *cp; + register int maj, min, l; + int unit; + char buf[NAMESIZE]; + + if ((u_int)(part -= 'a') >= 7) + panic("resolve"); + if ((nv = *nvp) == NULL) { + /* + * Apply default. Easiest to do this by number. + */ + maj = major(dflt->nv_int); + min = (minor(dflt->nv_int) & ~7) | part; + *nvp = nv = newnv(NULL, NULL, NULL, makedev(maj, min)); + } + if (nv->nv_int != NODEV) { + /* + * By the numbers. Find the appropriate major number + * to make a name. + */ + maj = major(nv->nv_int); + min = minor(nv->nv_int); + for (dev = allbases; dev != NULL; dev = dev->d_next) + if (dev->d_major == maj) + break; + if (dev == NULL) + (void)sprintf(buf, "<%d/%d>", maj, min); + else + (void)sprintf(buf, "%s%d%c", dev->d_name, + min >> 3, (min & 7) + 'a'); + nv->nv_str = intern(buf); + return (0); + } + + /* + * The normal case: things like "ra2b". Check for partition + * suffix, remove it if there, and split into name ("ra") and + * unit (2). + */ + l = strlen(nv->nv_str); + cp = &nv->nv_str[l]; + if (l > 1 && *--cp >= 'a' && *cp <= 'h' && isdigit(cp[-1])) { + l--; + part = *cp - 'a'; + } + cp = nv->nv_str; + if (split(cp, l, buf, sizeof buf, &unit)) { + error("%s: invalid %s device name `%s'", name, what, cp); + return (1); + } + dev = ht_lookup(devbasetab, intern(buf)); + if (dev == NULL || dev->d_major == NODEV) { + error("%s: can't make %s device from `%s'", + name, what, nv->nv_str); + return (1); + } + nv->nv_name = dev->d_name; + nv->nv_int = makedev(dev->d_major, unit * 8 + part); + return (0); +} + +static int +lresolve(nvp, name, what, dflt, part) + register struct nvlist **nvp; + const char *name, *what; + struct nvlist *dflt; + int part; +{ + int err; + + while ((err = resolve(nvp, name, what, dflt, part)) == 0 && + (*nvp)->nv_next != NULL) + nvp = &(*nvp)->nv_next; + return (err); +} + +/* + * Add a completed configuration to the list. + */ +void +addconf(cf0) + register struct config *cf0; +{ + register struct config *cf; + register struct nvlist *nv; + const char *name; + + name = cf0->cf_name; + cf = emalloc(sizeof *cf); + if (ht_insert(cfhashtab, name, cf)) { + error("configuration `%s' already defined", name); + free(cf); + goto bad; + } + *cf = *cf0; + + /* + * Look for "swap generic". + */ + for (nv = cf->cf_swap; nv != NULL; nv = nv->nv_next) + if (nv->nv_str == s_generic) + break; + if (nv != NULL) { + /* + * Make sure no root or dump device specified, and no + * other swap devices. Note single | here (check all). + */ + nv = cf->cf_swap; + if (exclude(cf->cf_root, name, "root device") | + exclude(nv->nv_next, name, "additional swap devices") | + exclude(cf->cf_dump, name, "dump device")) + goto bad; + } else { + nv = cf->cf_root; + if (nv == NULL) { + error("%s: no root device specified", name); + goto bad; + } + if (resolve(&cf->cf_root, name, "root", nv, 'a') | + lresolve(&cf->cf_swap, name, "swap", nv, 'b') | + resolve(&cf->cf_dump, name, "dumps", nv, 'b')) + goto bad; + } + *nextcf = cf; + nextcf = &cf->cf_next; + return; +bad: + nvfreel(cf0->cf_root); + nvfreel(cf0->cf_swap); + nvfreel(cf0->cf_dump); +} + +void +setconf(npp, what, v) + register struct nvlist **npp; + const char *what; + struct nvlist *v; +{ + + if (*npp != NULL) { + error("duplicate %s specification", what); + nvfreel(v); + } else + *npp = v; +} + +static struct devi * +newdevi(name, unit, d) + const char *name; + int unit; + struct devbase *d; +{ + register struct devi *i; + + i = emalloc(sizeof *i); + i->i_name = name; + i->i_unit = unit; + i->i_base = d; + i->i_next = NULL; + i->i_bsame = NULL; + i->i_alias = NULL; + i->i_at = NULL; + i->i_atattr = NULL; + i->i_atdev = NULL; + i->i_locs = NULL; + i->i_cfflags = 0; + i->i_lineno = currentline(); + if (unit >= d->d_umax) + d->d_umax = unit + 1; + return (i); +} + +/* + * Add the named device as attaching to the named attribute (or perhaps + * another device instead) plus unit number. + */ +void +adddev(name, at, loclist, flags) + const char *name, *at; + struct nvlist *loclist; + int flags; +{ + register struct devi *i; /* the new instance */ + register struct attr *attr; /* attribute that allows attach */ + register struct devbase *ib; /* i->i_base */ + register struct devbase *ab; /* not NULL => at another dev */ + register struct nvlist *nv; + const char *cp; + int atunit; + char atbuf[NAMESIZE]; + + ab = NULL; + if (at == NULL) { + /* "at root" */ + if ((i = getdevi(name)) == NULL) + goto bad; + /* + * Must warn about i_unit > 0 later, after taking care of + * the STAR cases (we could do non-star's here but why + * bother?). Make sure this device can be at root. + */ + ib = i->i_base; + if (!onlist(ib->d_atlist, NULL)) { + error("%s's cannot attach to the root", ib->d_name); + goto bad; + } + attr = &errattr; /* a convenient "empty" attr */ + } else { + if (split(at, strlen(at), atbuf, sizeof atbuf, &atunit)) { + error("invalid attachment name `%s'", at); + /* (void)getdevi(name); -- ??? */ + goto bad; + } + if ((i = getdevi(name)) == NULL) + goto bad; + ib = i->i_base; + cp = intern(atbuf); + if ((attr = ht_lookup(attrtab, cp)) == NULL) { + /* + * Have to work a bit harder to see whether we have + * something like "tg0 at esp0" (where esp is merely + * not an attribute) or "tg0 at nonesuch0" (where + * nonesuch is not even a device). + */ + if ((ab = ht_lookup(devbasetab, cp)) == NULL) { + error("%s at %s: `%s' unknown", + name, at, atbuf); + goto bad; + } + /* + * See if the named parent carries an attribute + * that allows it to supervise device ib. + */ + for (nv = ab->d_attrs; nv != NULL; nv = nv->nv_next) { + attr = nv->nv_ptr; + if (onlist(attr->a_devs, ib)) + goto ok; + } + attr = &errattr;/* now onlist below will fail */ + } + if (!onlist(attr->a_devs, ib)) { + error("%s's cannot attach to %s's", ib->d_name, atbuf); + goto bad; + } + } +ok: + if ((i->i_locs = fixloc(name, attr, loclist)) == NULL) + goto bad; + if (i->i_unit == STAR && ib->d_vectors != NULL) { + error("%s's cannot be *'d as they have preset vectors", + ib->d_name); + goto bad; + } + i->i_at = at; + i->i_atattr = attr; + i->i_atdev = ab; + i->i_atunit = atunit; + i->i_cfflags = flags; + selectbase(ib); + /* all done, fall into ... */ +bad: + nvfreel(loclist); + return; +} + +void +addpseudo(name, number) + const char *name; + int number; +{ + register struct devbase *d; + register struct devi *i; + + d = ht_lookup(devbasetab, name); + if (d == NULL) { + error("undefined pseudo-device %s", name); + return; + } + if (!d->d_ispseudo) { + error("%s is a real device, not a pseudo-device", name); + return; + } + if (ht_lookup(devitab, name) != NULL) { + error("`%s' already defined", name); + return; + } + i = newdevi(name, number - 1, d); /* foo 16 => "foo0..foo15" */ + if (ht_insert(devitab, name, i)) + panic("addpseudo(%s)", name); + selectbase(d); + *nextpseudo = i; + nextpseudo = &i->i_next; + npseudo++; +} + +/* + * Define a new instance of a specific device. + */ +static struct devi * +getdevi(name) + const char *name; +{ + register struct devi *i, *firsti; + register struct devbase *d; + int unit; + char base[NAMESIZE]; + + if (split(name, strlen(name), base, sizeof base, &unit)) { + error("invalid device name `%s'", name); + return (NULL); + } + d = ht_lookup(devbasetab, intern(base)); + if (d == NULL) { + error("%s: unknown device `%s'", name, base); + return (NULL); + } + if (d->d_ispseudo) { + error("%s: %s is a pseudo-device", name, base); + return (NULL); + } + firsti = ht_lookup(devitab, name); + i = newdevi(name, unit, d); + if (firsti == NULL) { + if (ht_insert(devitab, name, i)) + panic("getdevi(%s)", name); + *d->d_ipp = i; + d->d_ipp = &i->i_bsame; + } else { + while (firsti->i_alias) + firsti = firsti->i_alias; + firsti->i_alias = i; + } + *nextdevi = i; + nextdevi = &i->i_next; + ndevi++; + return (i); +} + +static const char * +concat(name, c) + const char *name; + int c; +{ + register int len; + char buf[NAMESIZE]; + + len = strlen(name); + if (len + 2 > sizeof(buf)) { + error("device name `%s%c' too long", name, c); + len = sizeof(buf) - 2; + } + bcopy(name, buf, len); + buf[len] = c; + buf[len + 1] = 0; + return (intern(buf)); +} + +const char * +starref(name) + const char *name; +{ + + return (concat(name, '*')); +} + +const char * +wildref(name) + const char *name; +{ + + return (concat(name, '?')); +} + +/* + * Split a name like "foo0" into base name (foo) and unit number (0). + * Return 0 on success. To make this useful for names like "foo0a", + * the length of the "foo0" part is one of the arguments. + */ +static int +split(name, nlen, base, bsize, aunit) + register const char *name; + size_t nlen; + char *base; + size_t bsize; + int *aunit; +{ + register const char *cp; + register int c, l; + + l = nlen; + if (l < 2 || l >= bsize || isdigit(*name)) + return (1); + c = (u_char)name[--l]; + if (!isdigit(c)) { + if (c == '*') + *aunit = STAR; + else if (c == '?') + *aunit = WILD; + else + return (1); + } else { + cp = &name[l]; + while (isdigit(cp[-1])) + l--, cp--; + *aunit = atoi(cp); + } + bcopy(name, base, l); + base[l] = 0; + return (0); +} + +/* + * We have an instance of the base foo, so select it and all its + * attributes for "optional foo". + */ +static void +selectbase(d) + register struct devbase *d; +{ + register struct attr *a; + register struct nvlist *nv; + + (void)ht_insert(selecttab, d->d_name, (char *)d->d_name); + for (nv = d->d_attrs; nv != NULL; nv = nv->nv_next) { + a = nv->nv_ptr; + (void)ht_insert(selecttab, a->a_name, (char *)a->a_name); + } +} + +/* + * Is the given pointer on the given list of pointers? + */ +static int +onlist(nv, ptr) + register struct nvlist *nv; + register void *ptr; +{ + for (; nv != NULL; nv = nv->nv_next) + if (nv->nv_ptr == ptr) + return (1); + return (0); +} + +static char * +extend(p, name) + register char *p; + const char *name; +{ + register int l; + + l = strlen(name); + bcopy(name, p, l); + p += l; + *p++ = ','; + *p++ = ' '; + return (p); +} + +/* + * Check that we got all required locators, and default any that are + * given as "?" and have defaults. Return 0 on success. + */ +static const char ** +fixloc(name, attr, got) + const char *name; + register struct attr *attr; + register struct nvlist *got; +{ + register struct nvlist *m, *n; + register int ord; + register const char **lp; + int nmissing, nextra, nnodefault; + char *mp, *ep, *ndp; + char missing[1000], extra[1000], nodefault[1000]; + static const char *nullvec[1]; + + /* + * Look for all required locators, and number the given ones + * according to the required order. While we are numbering, + * set default values for defaulted locators. + */ + if (attr->a_loclen == 0) /* e.g., "at root" */ + lp = nullvec; + else + lp = emalloc((attr->a_loclen + 1) * sizeof(const char *)); + for (n = got; n != NULL; n = n->nv_next) + n->nv_int = -1; + nmissing = 0; + mp = missing; + /* yes, this is O(mn), but m and n should be small */ + for (ord = 0, m = attr->a_locs; m != NULL; m = m->nv_next, ord++) { + for (n = got; n != NULL; n = n->nv_next) { + if (n->nv_name == m->nv_name) { + n->nv_int = ord; + break; + } + } + if (n == NULL && m->nv_int == 0) { + nmissing++; + mp = extend(mp, m->nv_name); + } + lp[ord] = m->nv_str; + } + if (ord != attr->a_loclen) + panic("fixloc"); + lp[ord] = NULL; + nextra = 0; + ep = extra; + nnodefault = 0; + ndp = nodefault; + for (n = got; n != NULL; n = n->nv_next) { + if (n->nv_int >= 0) { + if (n->nv_str != NULL) + lp[n->nv_int] = n->nv_str; + else if (lp[n->nv_int] == NULL) { + nnodefault++; + ndp = extend(ndp, n->nv_name); + } + } else { + nextra++; + ep = extend(ep, n->nv_name); + } + } + if (nextra) { + ep[-2] = 0; /* kill ", " */ + error("%s: extraneous locator%s: %s", + name, nextra > 1 ? "s" : "", extra); + } + if (nmissing) { + mp[-2] = 0; + error("%s: must specify %s", name, missing); + } + if (nnodefault) { + ndp[-2] = 0; + error("%s: cannot wildcard %s", name, nodefault); + } + if (nmissing || nnodefault) { + free(lp); + lp = NULL; + } + return (lp); +} diff --git a/usr.sbin/config.new/sem.h b/usr.sbin/config.new/sem.h new file mode 100644 index 0000000..14d6c2b --- /dev/null +++ b/usr.sbin/config.new/sem.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratories. + * + * 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. + * + * @(#)sem.h 8.1 (Berkeley) 6/6/93 + */ + +void enddefs __P((const char *)); + +void setdefmaxusers __P((int, int, int)); +void setmaxusers __P((int)); +int defattr __P((const char *, struct nvlist *)); +void defdev __P((struct devbase *, int, struct nvlist *, + struct nvlist *, struct nvlist *, struct nvlist *)); +struct devbase *getdevbase __P((const char *name)); +struct attr *getattr __P((const char *name)); +void setmajor __P((struct devbase *d, int n)); +void addconf __P((struct config *)); +void setconf __P((struct nvlist **, const char *, struct nvlist *)); +void adddev __P((const char *, const char *, struct nvlist *, int)); +void addpseudo __P((const char *name, int number)); +const char *ref __P((const char *name)); +const char *starref __P((const char *name)); +const char *wildref __P((const char *name)); diff --git a/usr.sbin/config.new/util.c b/usr.sbin/config.new/util.c new file mode 100644 index 0000000..6ef37db --- /dev/null +++ b/usr.sbin/config.new/util.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratories. + * + * 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. + * + * @(#)util.c 8.1 (Berkeley) 6/6/93 + */ + +#include +#include +#include +#if __STDC__ +#include +#else +#include +#endif +#include "config.h" + +static void nomem __P((void)); +static void vxerror __P((const char *, int, const char *, va_list)); + +/* + * Malloc, with abort on error. + */ +void * +emalloc(size) + size_t size; +{ + void *p; + + if ((p = malloc(size)) == NULL) + nomem(); + return (p); +} + +/* + * Realloc, with abort on error. + */ +void * +erealloc(p, size) + void *p; + size_t size; +{ + + if ((p = realloc(p, size)) == NULL) + nomem(); + return (p); +} + +static void +nomem() +{ + + (void)fprintf(stderr, "config: out of memory\n"); + exit(1); +} + +/* + * Prepend the compilation directory to a file name. + */ +char * +path(file) + const char *file; +{ + register char *cp; +#define CDIR "../../compile/" + + if (file == NULL) { + cp = emalloc(sizeof(CDIR) + strlen(confdirbase)); + (void)sprintf(cp, "%s%s", CDIR, confdirbase); + } else { + cp = emalloc(sizeof(CDIR) + strlen(confdirbase) + 1 + + strlen(file)); + (void)sprintf(cp, "%s%s/%s", CDIR, confdirbase, file); + } + return (cp); +} + +static struct nvlist *nvhead; + +struct nvlist * +newnv(name, str, ptr, i) + const char *name, *str; + void *ptr; + int i; +{ + register struct nvlist *nv; + + if ((nv = nvhead) == NULL) + nv = emalloc(sizeof(*nv)); + else + nvhead = nv->nv_next; + nv->nv_next = NULL; + nv->nv_name = name; + if (ptr == NULL) + nv->nv_str = str; + else { + if (str != NULL) + panic("newnv"); + nv->nv_ptr = ptr; + } + nv->nv_int = i; + return (nv); +} + +/* + * Free an nvlist structure (just one). + */ +void +nvfree(nv) + register struct nvlist *nv; +{ + + nv->nv_next = nvhead; + nvhead = nv; +} + +/* + * Free an nvlist (the whole list). + */ +void +nvfreel(nv) + register struct nvlist *nv; +{ + register struct nvlist *next; + + for (; nv != NULL; nv = next) { + next = nv->nv_next; + nv->nv_next = nvhead; + nvhead = nv; + } +} + +/* + * External (config file) error. Complain, using current file + * and line number. + */ +void +#if __STDC__ +error(const char *fmt, ...) +#else +error(fmt, va_alist) + const char *fmt; + va_dcl +#endif +{ + va_list ap; + extern const char *yyfile; + +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + vxerror(yyfile, currentline(), fmt, ap); + va_end(ap); +} + +/* + * Delayed config file error (i.e., something was wrong but we could not + * find out about it until later). + */ +void +#if __STDC__ +xerror(const char *file, int line, const char *fmt, ...) +#else +xerror(file, line, fmt, va_alist) + const char *file; + int line; + const char *fmt; + va_dcl +#endif +{ + va_list ap; + +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + vxerror(file, line, fmt, ap); + va_end(ap); +} + +/* + * Internal form of error() and xerror(). + */ +static void +vxerror(file, line, fmt, ap) + const char *file; + int line; + const char *fmt; + va_list ap; +{ + + (void)fprintf(stderr, "%s:%d: ", file, line); + (void)vfprintf(stderr, fmt, ap); + (void)putc('\n', stderr); + errors++; +} + +/* + * Internal error, abort. + */ +__dead void +#if __STDC__ +panic(const char *fmt, ...) +#else +panic(fmt, va_alist) + const char *fmt; + va_dcl +#endif +{ + va_list ap; + +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)fprintf(stderr, "config: panic: "); + (void)vfprintf(stderr, fmt, ap); + (void)putc('\n', stderr); + va_end(ap); + exit(2); +} diff --git a/usr.sbin/config/Makefile b/usr.sbin/config/Makefile new file mode 100644 index 0000000..d21a5c3 --- /dev/null +++ b/usr.sbin/config/Makefile @@ -0,0 +1,12 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= config +CFLAGS+=-I. -I${.CURDIR} +SRCS= config.c main.c lang.c mkioconf.c mkmakefile.c mkglue.c mkheaders.c \ + mkswapconf.c +MAN8= config.0 +DPADD= ${LIBL} +LDADD= -ll +CLEANFILES+=y.tab.h lang.c config.c y.tab.c + +.include diff --git a/usr.sbin/config/SMM.doc/0.t b/usr.sbin/config/SMM.doc/0.t new file mode 100644 index 0000000..ae5bf77 --- /dev/null +++ b/usr.sbin/config/SMM.doc/0.t @@ -0,0 +1,88 @@ +.\" 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. +.\" +.\" @(#)0.t 8.1 (Berkeley) 7/5/93 +.\" +.bd S B 3 +.de UX +.ie \\n(GA>0 \\$2UNIX\\$1 +.el \{\ +.if n \\$2UNIX\\$1* +.if t \\$2UNIX\\$1\\f1\(dg\\fP +.FS +.if n *UNIX +.if t \(dgUNIX +.ie \\$3=1 is a Footnote of Bell Laboratories. +.el is a Trademark of Bell Laboratories. +.FE +.nr GA 1\} +.. +.de BR +\fB\\$1\fP\\$2 +.. +.TL +Building 4.4BSD Kernels with Config +.AU +Samuel J. Leffler and Michael J. Karels +.AI +Computer Systems Research Group +Department of Electrical Engineering and Computer Science +University of California, Berkeley +Berkeley, California 94720 +.de IR +\fI\\$1\fP\\$2 +.. +.de DT +.TA 8 16 24 32 40 48 56 64 72 80 +.. +.AB +.PP +This document describes the use of +\fIconfig\fP\|(8) to configure and create bootable +4.4BSD system images. +It discusses the structure of system +configuration files and how to configure +systems with non-standard hardware configurations. +Sections describing the preferred way to +add new code to the system and how the system's autoconfiguration +process operates are included. An appendix +contains a summary of the rules used by the system +in calculating the size of system data structures, +and also indicates some of the standard system size +limitations (and how to change them). +Other configuration options are also listed. +.sp +.LP +Revised July 5, 1993 +.AE +.LP +.OH 'Building 4.4BSD Kernels with Config''SMM:2-%' +.EH 'SMM:2-%''Building 4.4BSD Kernels with Config' diff --git a/usr.sbin/config/SMM.doc/1.t b/usr.sbin/config/SMM.doc/1.t new file mode 100644 index 0000000..453041b --- /dev/null +++ b/usr.sbin/config/SMM.doc/1.t @@ -0,0 +1,61 @@ +.\" 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. +.\" +.\" @(#)1.t 8.1 (Berkeley) 6/8/93 +.\" +.\".ds RH Introduction +.ne 2i +.sp 3 +.NH +INTRODUCTION +.PP +.I Config +is a tool used in building 4.4BSD system images (the UNIX kernel). +It takes a file describing a system's tunable parameters and +hardware support, and generates a collection +of files which are then used to build a copy of UNIX appropriate +to that configuration. +.I Config +simplifies system maintenance by isolating system dependencies +in a single, easy to understand, file. +.PP +This document describes the content and +format of system configuration +files and the rules which must be followed when creating +these files. Example configuration files are constructed +and discussed. +.PP +Later sections suggest guidelines to be used in modifying +system source and explain some of the inner workings of the +autoconfiguration process. Appendix D summarizes the rules +used in calculating the most important system data structures +and indicates some inherent system data structure size +limitations (and how to go about modifying them). diff --git a/usr.sbin/config/SMM.doc/2.t b/usr.sbin/config/SMM.doc/2.t new file mode 100644 index 0000000..34e6b63 --- /dev/null +++ b/usr.sbin/config/SMM.doc/2.t @@ -0,0 +1,188 @@ +.\" 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. +.\" +.\" @(#)2.t 8.1 (Berkeley) 6/8/93 +.\" +.\".ds RH "Configuration File Contents +.ne 2i +.NH +CONFIGURATION FILE CONTENTS +.PP +A system configuration must include at least the following +pieces of information: +.IP \(bu 3 +machine type +.IP \(bu 3 +cpu type +.IP \(bu 3 +system identification +.IP \(bu 3 +timezone +.IP \(bu 3 +maximum number of users +.IP \(bu 3 +location of the root file system +.IP \(bu 3 +available hardware +.PP +.I Config +allows multiple system images to be generated from a single +configuration description. Each system image is configured +for identical hardware, but may have different locations for the root +file system and, possibly, other system devices. +.NH 2 +Machine type +.PP +The +.I "machine type" +indicates if the system is going to operate on a DEC VAX-11\(dg computer, +.FS +\(dg DEC, VAX, UNIBUS, MASSBUS and MicroVAX are trademarks of Digital +Equipment Corporation. +.FE +or some other machine on which 4.4BSD operates. The machine type +is used to locate certain data files which are machine specific, and +also to select rules used in constructing the resultant +configuration files. +.NH 2 +Cpu type +.PP +The +.I "cpu type" +indicates which, of possibly many, cpu's the system is to operate on. +For example, if the system is being configured for a VAX-11, it could +be running on a VAX 8600, VAX-11/780, VAX-11/750, VAX-11/730 or MicroVAX II. +(Other VAX cpu types, including the 8650, 785 and 725, are configured using +the cpu designation for compatible machines introduced earlier.) +Specifying +more than one cpu type implies that the system should be configured to run +on any of the cpu's specified. For some types of machines this is not +possible and +.I config +will print a diagnostic indicating such. +.NH 2 +System identification +.PP +The +.I "system identification" +is a moniker attached to the system, and often the machine on which the +system is to run. For example, at Berkeley we have machines named Ernie +(Co-VAX), Kim (No-VAX), and so on. The system identifier selected is used to +create a global C ``#define'' which may be used to isolate system dependent +pieces of code in the kernel. For example, Ernie's Varian driver used +to be special cased because its interrupt vectors were wired together. The +code in the driver which understood how to handle this non-standard hardware +configuration was conditionally compiled in only if the system +was for Ernie. +.PP +The system identifier ``GENERIC'' is given to a system which +will run on any cpu of a particular machine type; it should not +otherwise be used for a system identifier. +.NH 2 +Timezone +.PP +The timezone in which the system is to run is used to define the +information returned by the \fIgettimeofday\fP\|(2) +system call. This value is specified as the number of hours east +or west of GMT. Negative numbers indicate a value east of GMT. +The timezone specification may also indicate the +type of daylight savings time rules to be applied. +.NH 2 +Maximum number of users +.PP +The system allocates many system data structures at boot time +based on the maximum number of users the system will support. +This number is normally between 8 and 40, depending +on the hardware and expected job mix. The rules +used to calculate system data structures are discussed in +Appendix D. +.NH 2 +Root file system location +.PP +When the system boots it must know the location of +the root of the file system +tree. This location and the part(s) of the disk(s) to be used +for paging and swapping must be specified in order to create +a complete configuration description. +.I Config +uses many rules to calculate default locations for these items; +these are described in Appendix B. +.PP +When a generic system is configured, the root file system is left +undefined until the system is booted. In this case, the root file +system need not be specified, only that the system is a generic system. +.NH 2 +Hardware devices +.PP +When the system boots it goes through an +.I autoconfiguration +phase. During this period, the system searches for all +those hardware devices +which the system builder has indicated might be present. This probing +sequence requires certain pieces of information such as register +addresses, bus interconnects, etc. A system's hardware may be configured +in a very flexible manner or be specified without any flexibility +whatsoever. Most people do not configure hardware devices into the +system unless they are currently present on the machine, expect +them to be present in the near future, or are simply guarding +against a hardware +failure somewhere else at the site (it is often wise to configure in +extra disks in case an emergency requires moving one off a machine which +has hardware problems). +.PP +The specification of hardware devices usually occupies the majority of +the configuration file. As such, a large portion of this document will +be spent understanding it. Section 6.3 contains a description of +the autoconfiguration process, as it applies to those planning to +write, or modify existing, device drivers. +.NH 2 +Pseudo devices +.PP +Several system facilities are configured in a manner like that used +for hardware devices although they are not associated with specific hardware. +These system options are configured as +.IR pseudo-devices . +Some pseudo devices allow an optional parameter that sets the limit +on the number of instances of the device that are active simultaneously. +.NH 2 +System options +.PP +Other than the mandatory pieces of information described above, it +is also possible to include various optional system facilities +or to modify system behavior and/or limits. +For example, 4.4BSD can be configured to support binary compatibility for +programs built under 4.3BSD. Also, optional support is provided +for disk quotas and tracing the performance of the virtual memory +subsystem. Any optional facilities to be configured into +the system are specified in the configuration file. The resultant +files generated by +.I config +will automatically include the necessary pieces of the system. diff --git a/usr.sbin/config/SMM.doc/3.t b/usr.sbin/config/SMM.doc/3.t new file mode 100644 index 0000000..cbb904f --- /dev/null +++ b/usr.sbin/config/SMM.doc/3.t @@ -0,0 +1,299 @@ +.\" 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. +.\" +.\" @(#)3.t 8.1 (Berkeley) 6/8/93 +.\" +.\".ds RH "System Building Process +.ne 2i +.NH +SYSTEM BUILDING PROCESS +.PP +In this section we consider the steps necessary to build a bootable system +image. We assume the system source is located in the ``/sys'' directory +and that, initially, the system is being configured from source code. +.PP +Under normal circumstances there are 5 steps in building a system. +.IP 1) 3 +Create a configuration file for the system. +.IP 2) 3 +Make a directory for the system to be constructed in. +.IP 3) 3 +Run +.I config +on the configuration file to generate the files required +to compile and load the system image. +.IP 4) +Construct the source code interdependency rules for the +configured system with +.I make depend +using +.IR make (1). +.IP 5) +Compile and load the system with +.IR make . +.PP +Steps 1 and 2 are usually done only once. When a system configuration +changes it usually suffices to just run +.I config +on the modified configuration file, rebuild the source code dependencies, +and remake the system. Sometimes, +however, configuration dependencies may not be noticed in which case +it is necessary to clean out the relocatable object files saved +in the system's directory; this will be discussed later. +.NH 2 +Creating a configuration file +.PP +Configuration files normally reside in the directory ``/sys/conf''. +A configuration file is most easily constructed by copying an +existing configuration file and modifying it. The 4.4BSD distribution +contains a number of configuration files for machines at Berkeley; +one may be suitable or, in worst case, a copy +of the generic configuration file may be edited. +.PP +The configuration file must have the same name as the directory in +which the configured system is to be built. +Further, +.I config +assumes this directory is located in the parent directory of +the directory in which it +is run. For example, the generic +system has a configuration file ``/sys/conf/GENERIC'' and an accompanying +directory named ``/sys/GENERIC''. +Although it is not required that the system sources and configuration +files reside in ``/sys,'' the configuration and compilation procedure +depends on the relative locations of directories within that hierarchy, +as most of the system code and the files created by +.I config +use pathnames of the form ``../''. +If the system files are not located in ``/sys,'' +it is desirable to make a symbolic link there for use in installation +of other parts of the system that share files with the kernel. +.PP +When building the configuration file, be sure to include the items +described in section 2. In particular, the machine type, +cpu type, timezone, system identifier, maximum users, and root device +must be specified. The specification of the hardware present may take +a bit of work; particularly if your hardware is configured at non-standard +places (e.g. device registers located at funny places or devices not +supported by the system). Section 4 of this document +gives a detailed description of the configuration file syntax, +section 5 explains some sample configuration files, and +section 6 discusses how to add new devices to +the system. If the devices to be configured are not already +described in one of the existing configuration files you should check +the manual pages in section 4 of the UNIX Programmers Manual. For each +supported device, the manual page synopsis entry gives a +sample configuration line. +.PP +Once the configuration file is complete, run it through +.I config +and look for any errors. Never try and use a system which +.I config +has complained about; the results are unpredictable. +For the most part, +.IR config 's +error diagnostics are self explanatory. It may be the case that +the line numbers given with the error messages are off by one. +.PP +A successful run of +.I config +on your configuration file will generate a number of files in +the configuration directory. These files are: +.IP \(bu 3 +A file to be used by \fImake\fP\|(1) +in compiling and loading the system, +.IR Makefile . +.IP \(bu 3 +One file for each possible system image for this machine, +.IR swapxxx.c , +where +.I xxx +is the name of the system image, +which describes where swapping, the root file system, and other +miscellaneous system devices are located. +.IP \(bu 3 +A collection of header files, one per possible device the +system supports, which define the hardware configured. +.IP \(bu 3 +A file containing the I/O configuration tables used by the system +during its +.I autoconfiguration +phase, +.IR ioconf.c . +.IP \(bu 3 +An assembly language file of interrupt vectors which +connect interrupts from the machine's external buses to the main +system path for handling interrupts, +and a file that contains counters and names for the interrupt vectors. +.PP +Unless you have reason to doubt +.IR config , +or are curious how the system's autoconfiguration scheme +works, you should never have to look at any of these files. +.NH 2 +Constructing source code dependencies +.PP +When +.I config +is done generating the files needed to compile and link your system it +will terminate with a message of the form ``Don't forget to run make depend''. +This is a reminder that you should change over to the configuration +directory for the system just configured and type ``make depend'' +to build the rules used by +.I make +to recognize interdependencies in the system source code. +This will insure that any changes to a piece of the system +source code will result in the proper modules being recompiled +the next time +.I make +is run. +.PP +This step is particularly important if your site makes changes +to the system include files. The rules generated specify which source code +files are dependent on which include files. Without these rules, +.I make +will not recognize when it must rebuild modules +due to the modification of a system header file. +The dependency rules are generated by a pass of the C preprocessor +and reflect the global system options. +This step must be repeated when the configuration file is changed +and +.I config +is used to regenerate the system makefile. +.NH 2 +Building the system +.PP +The makefile constructed by +.I config +should allow a new system to be rebuilt by simply typing ``make image-name''. +For example, if you have named your bootable system image ``vmunix'', +then ``make vmunix'' +will generate a bootable image named ``vmunix''. Alternate system image names +are used when the root file system location and/or swapping configuration +is done in more than one way. The makefile which +.I config +creates has entry points for each system image defined in +the configuration file. +Thus, if you have configured ``vmunix'' to be a system with the root file +system on an ``hp'' device and ``hkvmunix'' to be a system with the root +file system on an ``hk'' device, then ``make vmunix hkvmunix'' will generate +binary images for each. +As the system will generally use the disk from which it is loaded +as the root filesystem, separate system images are only required +to support different swap configurations. +.PP +Note that the name of a bootable image is different from the system +identifier. All bootable images are configured for the same system; +only the information about the root file system and paging devices differ. +(This is described in more detail in section 4.) +.PP +The last step in the system building process is to rearrange certain commonly +used symbols in the symbol table of the system image; the makefile +generated by +.I config +does this automatically for you. +This is advantageous for programs such as +\fInetstat\fP\|(1) and \fIvmstat\fP\|(1), +which run much faster when the symbols they need are located at +the front of the symbol table. +Remember also that many programs expect +the currently executing system to be named ``/vmunix''. If you install +a new system and name it something other than ``/vmunix'', many programs +are likely to give strange results. +.NH 2 +Sharing object modules +.PP +If you have many systems which are all built on a single machine +there are at least two approaches to saving time in building system +images. The best way is to have a single system image which is run on +all machines. This is attractive since it minimizes disk space used +and time required to rebuild systems after making changes. However, +it is often the case that one or more systems will require a separately +configured system image. This may be due to limited memory (building +a system with many unused device drivers can be expensive), or to +configuration requirements (one machine may be a development machine +where disk quotas are not needed, while another is a production machine +where they are), etc. In these cases it is possible +for common systems to share relocatable object modules which are not +configuration dependent; most of the modules in the directory ``/sys/sys'' +are of this sort. +.PP +To share object modules, a generic system should be built. Then, for +each system configure the system as before, but before recompiling and +linking the system, type ``make links'' in the system compilation directory. +This will cause the system +to be searched for source modules which are safe to share between systems +and generate symbolic links in the current directory to the appropriate +object modules in the directory ``../GENERIC''. A shell script, +``makelinks'' is generated with this request and may be checked for +correctness. The file ``/sys/conf/defines'' contains a list of symbols +which we believe are safe to ignore when checking the source code +for modules which may be shared. Note that this list includes the definitions +used to conditionally compile in the virtual memory tracing facilities, and +the trace point support used only rarely (even at Berkeley). +It may be necessary +to modify this file to reflect local needs. Note further that +interdependencies which are not directly visible +in the source code are not caught. This means that if you place +per-system dependencies in an include file, they will not be recognized +and the shared code may be selected in an unexpected fashion. +.NH 2 +Building profiled systems +.PP +It is simple to configure a system which will automatically +collect profiling information as it operates. The profiling data +may be collected with \fIkgmon\fP\|(8) and processed with +\fIgprof\fP\|(1) +to obtain information regarding the system's operation. Profiled +systems maintain histograms of the program counter as well as the +number of invocations of each routine. The \fIgprof\fP +command will also generate a dynamic call graph of the executing +system and propagate time spent in each routine along the arcs +of the call graph (consult the \fIgprof\fP documentation for elaboration). +The program counter sampling can be driven by the system clock, or +if you have an alternate real time clock, this can be used. The +latter is highly recommended, as use of the system clock will result +in statistical anomalies, and time spent in the clock routine will +not be accurately attributed. +.PP +To configure a profiled system, the +.B \-p +option should be supplied to \fIconfig\fP. +A profiled system is about 5-10% larger in its text space due to +the calls to count the subroutine invocations. When the system +executes, the profiling data is stored in a buffer which is 1.2 +times the size of the text space. The overhead for running a +profiled system varies; under normal load we see anywhere from 5-25% +of the system time spent in the profiling code. +.PP +Note that systems configured for profiling should not be shared as +described above unless all the other shared systems are also to be +profiled. diff --git a/usr.sbin/config/SMM.doc/4.t b/usr.sbin/config/SMM.doc/4.t new file mode 100644 index 0000000..d267799 --- /dev/null +++ b/usr.sbin/config/SMM.doc/4.t @@ -0,0 +1,442 @@ +.\" 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. +.\" +.\" @(#)4.t 8.1 (Berkeley) 6/8/93 +.\" +.\".ds RH "Configuration File Syntax +.ne 2i +.NH +CONFIGURATION FILE SYNTAX +.PP +In this section we consider the specific rules used in writing +a configuration file. A complete grammar for the input language +can be found in Appendix A and may be of use if you should have +problems with syntax errors. +.PP +A configuration file is broken up into three logical pieces: +.IP \(bu 3 +configuration parameters global to all system images +specified in the configuration file, +.IP \(bu 3 +parameters specific to each +system image to be generated, and +.IP \(bu 3 +device specifications. +.NH 2 +Global configuration parameters +.PP +The global configuration parameters are the type of machine, +cpu types, options, timezone, system identifier, and maximum users. +Each is specified with a separate line in the configuration file. +.IP "\fBmachine\fP \fItype\fP" +.br +The system is to run on the machine type specified. No more than +one machine type can appear in the configuration file. Legal values +are +.B vax +and +\fBsun\fP. +.IP "\fBcpu\fP ``\fItype\fP''" +.br +This system is to run on the cpu type specified. +More than one cpu type specification +can appear in a configuration file. +Legal types for a +.B vax +machine are +\fBVAX8600\fP, \fBVAX780\fP, \fBVAX750\fP, +\fBVAX730\fP +and +\fBVAX630\fP (MicroVAX II). +The 8650 is listed as an 8600, the 785 as a 780, and a 725 as a 730. +.IP "\fBoptions\fP \fIoptionlist\fP" +.br +Compile the listed optional code into the system. +Options in this list are separated by commas. +Possible options are listed at the top of the generic makefile. +A line of the form ``options FUNNY,HAHA'' generates global ``#define''s +\-DFUNNY \-DHAHA in the resultant makefile. +An option may be given a value by following its name with ``\fB=\fP'', +then the value enclosed in (double) quotes. +The following are major options are currently in use: +COMPAT (include code for compatibility with 4.1BSD binaries), +INET (Internet communication protocols), +NS (Xerox NS communication protocols), +and +QUOTA (enable disk quotas). +Other kernel options controlling system sizes and limits +are listed in Appendix D; +options for the network are found in Appendix E. +There are additional options which are associated with certain +peripheral devices; those are listed in the Synopsis section +of the manual page for the device. +.IP "\fBmakeoptions\fP \fIoptionlist\fP" +.br +Options that are used within the system makefile +and evaluated by +.I make +are listed as +.IR makeoptions . +Options are listed with their values with the form +``makeoptions name=value,name2=value2.'' +The values must be enclosed in double quotes if they include numerals +or begin with a dash. +.IP "\fBtimezone\fP \fInumber\fP [ \fBdst\fP [ \fInumber\fP ] ]" +.br +Specifies the timezone used by the system. This is measured in the +number of hours your timezone is west of GMT. +EST is 5 hours west of GMT, PST is 8. Negative numbers +indicate hours east of GMT. If you specify +\fBdst\fP, the system will operate under daylight savings time. +An optional integer or floating point number may be included +to specify a particular daylight saving time correction algorithm; +the default value is 1, indicating the United States. +Other values are: 2 (Australian style), 3 (Western European), +4 (Middle European), and 5 (Eastern European). See +\fIgettimeofday\fP\|(2) and \fIctime\fP\|(3) for more information. +.IP "\fBident\fP \fIname\fP" +.br +This system is to be known as +.IR name . +This is usually a cute name like ERNIE (short for Ernie Co-Vax) or +VAXWELL (for Vaxwell Smart). +This value is defined for use in conditional compilation, +and is also used to locate an optional list of source files specific +to this system. +.IP "\fBmaxusers\fP \fInumber\fP" +.br +The maximum expected number of simultaneously active user on this system is +.IR number . +This number is used to size several system data structures. +.NH 2 +System image parameters +.PP +Multiple bootable images may be specified in a single configuration +file. The systems will have the same global configuration parameters +and devices, but the location of the root file system and other +system specific devices may be different. A system image is specified +with a ``config'' line: +.IP +\fBconfig\fP\ \fIsysname\fP\ \fIconfig-clauses\fP +.LP +The +.I sysname +field is the name given to the loaded system image; almost everyone +names their standard system image ``vmunix''. The configuration clauses +are one or more specifications indicating where the root file system +is located and the number and location of paging devices. +The device used by the system to process argument lists during +.IR execve (2) +calls may also be specified, though in practice this is almost +always selected by +.I config +using one of its rules for selecting default locations for +system devices. +.PP +A configuration clause is one of the following +.IP +.nf +\fBroot\fP [ \fBon\fP ] \fIroot-device\fP +\fBswap\fP [ \fBon\fP ] \fIswap-device\fP [ \fBand\fP \fIswap-device\fP ] ... +\fBdumps\fP [ \fBon\fP ] \fIdump-device\fP +\fBargs\fP [ \fBon\fP ] \fIarg-device\fP +.LP +(the ``on'' is optional.) Multiple configuration clauses +are separated by white space; +.I config +allows specifications to be continued across multiple lines +by beginning the continuation line with a tab character. +The ``root'' clause specifies where the root file system +is located, the ``swap'' clause indicates swapping and paging +area(s), the ``dumps'' clause can be used to force system dumps +to be taken on a particular device, and the ``args'' clause +can be used to specify that argument list processing for +.I execve +should be done on a particular device. +.PP +The device names supplied in the clauses may be fully specified +as a device, unit, and file system partition; or underspecified +in which case +.I config +will use builtin rules to select default unit numbers and file +system partitions. The defaulting rules are a bit complicated +as they are dependent on the overall system configuration. +For example, the swap area need not be specified at all if +the root device is specified; in this case the swap area is +placed in the ``b'' partition of the same disk where the root +file system is located. Appendix B contains a complete list +of the defaulting rules used in selecting system configuration +devices. +.PP +The device names are translated to the +appropriate major and minor device +numbers on a per-machine basis. A file, +``/sys/conf/devices.machine'' (where ``machine'' +is the machine type specified in the configuration file), +is used to map a device name to its major block device number. +The minor device number is calculated using the standard +disk partitioning rules: on unit 0, partition ``a'' is minor device +0, partition ``b'' is minor device 1, and so on; for units +other than 0, add 8 times the unit number to get the minor +device. +.PP +If the default mapping of device name to major/minor device +number is incorrect for your configuration, it can be replaced +by an explicit specification of the major/minor device. +This is done by substituting +.IP +\fBmajor\fP \fIx\fP \fBminor\fP \fIy\fP +.LP +where the device name would normally be found. For example, +.IP +.nf +\fBconfig\fP vmunix \fBroot\fP \fBon\fP \fBmajor\fP 99 \fBminor\fP 1 +.fi +.PP +Normally, the areas configured for swap space are sized by the system +at boot time. If a non-standard size is to be used for one +or more swap areas (less than the full partition), +this can also be specified. To do this, the +device name specified for a swap area should have a ``size'' +specification appended. For example, +.IP +.nf +\fBconfig\fP vmunix \fBroot\fP \fBon\fP hp0 \fBswap\fP \fBon\fP hp0b \fBsize\fP 1200 +.fi +.LP +would force swapping to be done in partition ``b'' of ``hp0'' and +the swap partition size would be set to 1200 sectors. A swap area +sized larger than the associated disk partition is trimmed to the +partition size. +.PP +To create a generic configuration, only the clause ``swap generic'' +should be specified; any extra clauses will cause an error. +.NH 2 +Device specifications +.PP +Each device attached to a machine must be specified +to +.I config +so that the system generated will know to probe for it during +the autoconfiguration process carried out at boot time. Hardware +specified in the configuration need not actually be present on +the machine where the generated system is to be run. Only the +hardware actually found at boot time will be used by the system. +.PP +The specification of hardware devices in the configuration file +parallels the interconnection hierarchy of the machine to be +configured. On the VAX, this means that a configuration file must +indicate what MASSBUS and UNIBUS adapters are present, and to +which \fInexi\fP they might be connected.* +.FS +* While VAX-11/750's and VAX-11/730 do not actually have +nexi, the system treats them as having +.I "simulated nexi" +to simplify device configuration. +.FE +Similarly, devices +and controllers must be indicated as possibly being connected +to one or more adapters. A device description may provide a +complete definition of the possible configuration parameters +or it may leave certain parameters undefined and make the system +probe for all the possible values. The latter allows a single +device configuration list to match many possible physical +configurations. For example, a disk may be indicated as present +at UNIBUS adapter 0, or at any UNIBUS adapter which the system +locates at boot time. The latter scheme, termed +.IR wildcarding , +allows more flexibility in the physical configuration of a system; +if a disk must be moved around for some reason, the system will +still locate it at the alternate location. +.PP +A device specification takes one of the following forms: +.IP +.nf +\fBmaster\fP \fIdevice-name\fP \fIdevice-info\fP +\fBcontroller\fP \fIdevice-name\fP \fIdevice-info\fP [ \fIinterrupt-spec\fP ] +\fBdevice\fP \fIdevice-name\fP \fIdevice-info\fP \fIinterrupt-spec\fP +\fBdisk\fP \fIdevice-name\fP \fIdevice-info\fP +\fBtape\fP \fIdevice-name\fP \fIdevice-info\fP +.fi +.LP +A ``master'' is a MASSBUS tape controller; a ``controller'' is a +disk controller, a UNIBUS tape controller, a MASSBUS adapter, or +a UNIBUS adapter. A ``device'' is an autonomous device which +connects directly to a UNIBUS adapter (as opposed to something +like a disk which connects through a disk controller). ``Disk'' +and ``tape'' identify disk drives and tape drives connected to +a ``controller'' or ``master.'' +.PP +The +.I device-name +is one of the standard device names, as +indicated in section 4 of the UNIX Programmers Manual, +concatenated with the +.I logical +unit number to be assigned the device (the +.I logical +unit number may be different than the +.I physical +unit number indicated on the front of something +like a disk; the +.I logical +unit number is used to refer to the UNIX device, not +the physical unit number). For example, ``hp0'' is logical +unit 0 of a MASSBUS storage device, even though it might +be physical unit 3 on MASSBUS adapter 1. +.PP +The +.I device-info +clause specifies how the hardware is +connected in the interconnection hierarchy. On the VAX, +UNIBUS and MASSBUS adapters are connected to the internal +system bus through +a \fInexus\fP. +Thus, one of the following +specifications would be used: +.IP +.ta 1.5i 2.5i 4.0i +.nf +\fBcontroller\fP mba0 \fBat\fP \fBnexus\fP \fIx\fP +\fBcontroller\fP uba0 \fBat\fP \fBnexus\fP \fIx\fP +.fi +.LP +To tie a controller to a specific nexus, ``x'' would be supplied +as the number of that nexus; otherwise ``x'' may be specified as +``?'', in which +case the system will probe all nexi present looking +for the specified controller. +.PP +The remaining interconnections on the VAX are: +.IP \(bu 3 +a controller +may be connected to another controller (e.g. a disk controller attached +to a UNIBUS adapter), +.IP \(bu 3 +a master is always attached to a controller (a MASSBUS adapter), +.IP \(bu 3 +a tape is always attached to a master (for MASSBUS +tape drives), +.IP \(bu 3 +a disk is always attached to a controller, and +.IP \(bu 3 +devices +are always attached to controllers (e.g. UNIBUS controllers attached +to UNIBUS adapters). +.LP +The following lines give an example of each of these interconnections: +.IP +.ta 1.5i 2.5i 4.0i +.nf +\fBcontroller\fP hk0 \fBat\fP uba0 ... +\fBmaster\fP ht0 \fBat\fP mba0 ... +\fBdisk\fP hp0 \fBat\fP mba0 ... +\fBtape\fP tu0 \fBat\fP ht0 ... +\fBdisk\fP rk1 \fBat\fP hk0 ... +\fBdevice\fP dz0 \fBat\fP uba0 ... +.fi +.LP +Any piece of hardware which may be connected to a specific +controller may also be wildcarded across multiple controllers. +.PP +The final piece of information needed by the system to configure +devices is some indication of where or how a device will interrupt. +For tapes and disks, simply specifying the \fIslave\fP or \fIdrive\fP +number is sufficient to locate the control status register for the +device. +\fIDrive\fP numbers may be wildcarded +on MASSBUS devices, but not on disks on a UNIBUS controller. +For controllers, the control status register must be +given explicitly, as well the number of interrupt vectors used and +the names of the routines to which they should be bound. +Thus the example lines given above might be completed as: +.IP +.ta 1.5i 2.5i 4.0i +.nf +\fBcontroller\fP hk0 \fBat\fP uba0 \fBcsr\fP 0177440 \fBvector\fP rkintr +\fBmaster\fP ht0 \fBat\fP mba0 \fBdrive\fP 0 +\fBdisk\fP hp0 \fBat\fP mba0 \fBdrive\fP ? +\fBtape\fP tu0 \fBat\fP ht0 \fBslave\fP 0 +\fBdisk\fP rk1 \fBat\fP hk0 \fBdrive\fP 1 +\fBdevice\fP dz0 \fBat\fP uba0 \fBcsr\fP 0160100 \fBvector\fP dzrint dzxint +.fi +.PP +Certain device drivers require extra information passed to them +at boot time to tailor their operation to the actual hardware present. +The line printer driver, for example, needs to know how many columns +are present on each non-standard line printer (i.e. a line printer +with other than 80 columns). The drivers for the terminal multiplexors +need to know which lines are attached to modem lines so that no one will +be allowed to use them unless a connection is present. For this reason, +one last parameter may be specified to a +.IR device , +a +.I flags +field. It has the syntax +.IP +\fBflags\fP \fInumber\fP +.LP +and is usually placed after the +.I csr +specification. The +.I number +is passed directly to the associated driver. The manual pages +in section 4 should be consulted to determine how each driver +uses this value (if at all). +Communications interface drivers commonly use the flags +to indicate whether modem control signals are in use. +.PP +The exact syntax for each specific device is given in the Synopsis +section of its manual page in section 4 of the manual. +.NH 2 +Pseudo-devices +.PP +A number of drivers and software subsystems +are treated like device drivers without any associated hardware. +To include any of these pieces, a ``pseudo-device'' specification +must be used. A specification for a pseudo device takes the form +.IP +.DT +.nf +\fBpseudo-device\fP \fIdevice-name\fP [ \fIhowmany\fP ] +.fi +.PP +Examples of pseudo devices are +\fBpty\fP, the pseudo terminal driver (where the optional +.I howmany +value indicates the number of pseudo terminals to configure, 32 default), +and \fBloop\fP, the software loopback network pseudo-interface. +Other pseudo devices for the network include +\fBimp\fP (required when a CSS or ACC imp is configured) +and \fBether\fP (used by the Address Resolution Protocol +on 10 Mb/sec Ethernets). +More information on configuring each of these can also be found +in section 4 of the manual. diff --git a/usr.sbin/config/SMM.doc/5.t b/usr.sbin/config/SMM.doc/5.t new file mode 100644 index 0000000..3a0f449 --- /dev/null +++ b/usr.sbin/config/SMM.doc/5.t @@ -0,0 +1,271 @@ +.\" 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. +.\" +.\" @(#)5.t 8.1 (Berkeley) 6/8/93 +.\" +.\".ds RH "Sample Configuration Files +.ne 2i +.NH +SAMPLE CONFIGURATION FILES +.PP +In this section we will consider how to configure a +sample VAX-11/780 system on which the hardware can be +reconfigured to guard against various hardware mishaps. +We then study the rules needed to configure a VAX-11/750 +to run in a networking environment. +.NH 2 +VAX-11/780 System +.PP +Our VAX-11/780 is configured with hardware +recommended in the document ``Hints on Configuring a VAX for 4.2BSD'' +(this is one of the high-end configurations). +Table 1 lists the pertinent hardware to be configured. +.DS B +.TS +box; +l | l | l | l | l +l | l | l | l | l. +Item Vendor Connection Name Reference +_ +cpu DEC VAX780 +MASSBUS controller Emulex nexus ? mba0 hp(4) +disk Fujitsu mba0 hp0 +disk Fujitsu mba0 hp1 +MASSBUS controller Emulex nexus ? mba1 +disk Fujitsu mba1 hp2 +disk Fujitsu mba1 hp3 +UNIBUS adapter DEC nexus ? +tape controller Emulex uba0 tm0 tm(4) +tape drive Kennedy tm0 te0 +tape drive Kennedy tm0 te1 +terminal multiplexor Emulex uba0 dh0 dh(4) +terminal multiplexor Emulex uba0 dh1 +terminal multiplexor Emulex uba0 dh2 +.TE +.DE +.ce +Table 1. VAX-11/780 Hardware support. +.LP +We will call this machine ANSEL and construct a configuration +file one step at a time. +.PP +The first step is to fill in the global configuration parameters. +The machine is a VAX, so the +.I "machine type" +is ``vax''. We will assume this system will +run only on this one processor, so the +.I "cpu type" +is ``VAX780''. The options are empty since this is going to +be a ``vanilla'' VAX. The system identifier, as mentioned before, +is ``ANSEL,'' and the maximum number of users we plan to support is +about 40. Thus the beginning of the configuration file looks like +this: +.DS +.ta 1.5i 2.5i 4.0i +# +# ANSEL VAX (a picture perfect machine) +# +machine vax +cpu VAX780 +timezone 8 dst +ident ANSEL +maxusers 40 +.DE +.PP +To this we must then add the specifications for three +system images. The first will be our standard system with the +root on ``hp0'' and swapping on the same drive as the root. +The second will have the root file system in the same location, +but swap space interleaved among drives on each controller. +Finally, the third will be a generic system, +to allow us to boot off any of the four disk drives. +.DS +.ta 1.5i 2.5i +config vmunix root on hp0 +config hpvmunix root on hp0 swap on hp0 and hp2 +config genvmunix swap generic +.DE +.PP +Finally, the hardware must be specified. Let us first just try +transcribing the information from Table 1. +.DS +.ta 1.5i 2.5i 4.0i +controller mba0 at nexus ? +disk hp0 at mba0 disk 0 +disk hp1 at mba0 disk 1 +controller mba1 at nexus ? +disk hp2 at mba1 disk 2 +disk hp3 at mba1 disk 3 +controller uba0 at nexus ? +controller tm0 at uba0 csr 0172520 vector tmintr +tape te0 at tm0 drive 0 +tape te1 at tm0 drive 1 +device dh0 at uba0 csr 0160020 vector dhrint dhxint +device dm0 at uba0 csr 0170500 vector dmintr +device dh1 at uba0 csr 0160040 vector dhrint dhxint +device dh2 at uba0 csr 0160060 vector dhrint dhxint +.DE +.LP +(Oh, I forgot to mention one panel of the terminal multiplexor +has modem control, thus the ``dm0'' device.) +.PP +This will suffice, but leaves us with little flexibility. Suppose +our first disk controller were to break. We would like to recable the +drives normally on the second controller so that all our disks could +still be used without reconfiguring the system. To do this we wildcard +the MASSBUS adapter connections and also the slave numbers. Further, +we wildcard the UNIBUS adapter connections in case we decide some time +in the future to purchase another adapter to offload the single UNIBUS +we currently have. The revised device specifications would then be: +.DS +.ta 1.5i 2.5i 4.0i +controller mba0 at nexus ? +disk hp0 at mba? disk ? +disk hp1 at mba? disk ? +controller mba1 at nexus ? +disk hp2 at mba? disk ? +disk hp3 at mba? disk ? +controller uba0 at nexus ? +controller tm0 at uba? csr 0172520 vector tmintr +tape te0 at tm0 drive 0 +tape te1 at tm0 drive 1 +device dh0 at uba? csr 0160020 vector dhrint dhxint +device dm0 at uba? csr 0170500 vector dmintr +device dh1 at uba? csr 0160040 vector dhrint dhxint +device dh2 at uba? csr 0160060 vector dhrint dhxint +.DE +.LP +The completed configuration file for ANSEL is shown in Appendix C. +.NH 2 +VAX-11/750 with network support +.PP +Our VAX-11/750 system will be located on two 10Mb/s Ethernet +local area networks and also the DARPA Internet. The system +will have a MASSBUS drive for the root file system and two +UNIBUS drives. Paging is interleaved among all three drives. +We have sold our standard DEC terminal multiplexors since this +machine will be accessed solely through the network. This +machine is not intended to have a large user community, it +does not have a great deal of memory. First the global parameters: +.DS +.ta 1.5i 2.5i 4.0i +# +# UCBVAX (Gateway to the world) +# +machine vax +cpu "VAX780" +cpu "VAX750" +ident UCBVAX +timezone 8 dst +maxusers 32 +options INET +options NS +.DE +.PP +The multiple cpu types allow us to replace UCBVAX with a +more powerful cpu without reconfiguring the system. The +value of 32 given for the maximum number of users is done to +force the system data structures to be over-allocated. That +is desirable on this machine because, while it is not expected +to support many users, it is expected to perform a great deal +of work. +The ``INET'' indicates that we plan to use the +DARPA standard Internet protocols on this machine, +and ``NS'' also includes support for Xerox NS protocols. +Note that unlike 4.2BSD configuration files, +the network protocol options do not require corresponding pseudo devices. +.PP +The system images and disks are configured next. +.DS +.ta 1.5i 2.5i 4.0i +config vmunix root on hp swap on hp and rk0 and rk1 +config upvmunix root on up +config hkvmunix root on hk swap on rk0 and rk1 + +controller mba0 at nexus ? +controller uba0 at nexus ? +disk hp0 at mba? drive 0 +disk hp1 at mba? drive 1 +controller sc0 at uba? csr 0176700 vector upintr +disk up0 at sc0 drive 0 +disk up1 at sc0 drive 1 +controller hk0 at uba? csr 0177440 vector rkintr +disk rk0 at hk0 drive 0 +disk rk1 at hk0 drive 1 +.DE +.PP +UCBVAX requires heavy interleaving of its paging area to keep up +with all the mail traffic it handles. The limiting factor on this +system's performance is usually the number of disk arms, as opposed +to memory or cpu cycles. The extra UNIBUS controller, ``sc0'', +is in case the MASSBUS controller breaks and a spare controller +must be installed (most of our old UNIBUS controllers have been +replaced with the newer MASSBUS controllers, so we have a number +of these around as spares). +.PP +Finally, we add in the network devices. +Pseudo terminals are needed to allow users to +log in across the network (remember the only hardwired terminal +is the console). +The software loopback device is used for on-machine communications. +The connection to the Internet is through +an IMP, this requires yet another +.I pseudo-device +(in addition to the actual hardware device used by the +IMP software). And, finally, there are the two Ethernet devices. +These use a special protocol, the Address Resolution Protocol (ARP), +to map between Internet and Ethernet addresses. Thus, yet another +.I pseudo-device +is needed. The additional device specifications are show below. +.DS +.ta 1.5i 2.5i 4.0i +pseudo-device pty +pseudo-device loop +pseudo-device imp +device acc0 at uba? csr 0167600 vector accrint accxint +pseudo-device ether +device ec0 at uba? csr 0164330 vector ecrint eccollide ecxint +device il0 at uba? csr 0164000 vector ilrint ilcint +.DE +.LP +The completed configuration file for UCBVAX is shown in Appendix C. +.NH 2 +Miscellaneous comments +.PP +It should be noted in these examples that neither system was +configured to use disk quotas or the 4.1BSD compatibility mode. +To use these optional facilities, and others, we would probably +clean out our current configuration, reconfigure the system, then +recompile and relink the system image(s). This could, of course, +be avoided by figuring out which relocatable object files are +affected by the reconfiguration, then reconfiguring and recompiling +only those files affected by the configuration change. This technique +should be used carefully. diff --git a/usr.sbin/config/SMM.doc/6.t b/usr.sbin/config/SMM.doc/6.t new file mode 100644 index 0000000..f02baed --- /dev/null +++ b/usr.sbin/config/SMM.doc/6.t @@ -0,0 +1,239 @@ +.\" 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. +.\" +.\" @(#)6.t 8.1 (Berkeley) 6/8/93 +.\" +.\".ds RH "Adding New Devices +.ne 2i +.NH +ADDING NEW SYSTEM SOFTWARE +.PP +This section is not for the novice, it describes +some of the inner workings of the configuration process as +well as the pertinent parts of the system autoconfiguration process. +It is intended to give +those people who intend to install new device drivers and/or +other system facilities sufficient information to do so in the +manner which will allow others to easily share the changes. +.PP +This section is broken into four parts: +.IP \(bu 3 +general guidelines to be followed in modifying system code, +.IP \(bu 3 +how to add non-standard system facilities to 4.4BSD, +.IP \(bu 3 +how to add a device driver to 4.4BSD, and +.NH 2 +Modifying system code +.PP +If you wish to make site-specific modifications to the system +it is best to bracket them with +.DS +#ifdef SITENAME +\&... +#endif +.DE +to allow your source to be easily distributed to others, and +also to simplify \fIdiff\fP\|(1) listings. If you choose not +to use a source code control system (e.g. SCCS, RCS), and +perhaps even if you do, it is +recommended that you save the old code with something +of the form: +.DS +#ifndef SITENAME +\&... +#endif +.DE +We try to isolate our site-dependent code in individual files +which may be configured with pseudo-device specifications. +.PP +Indicate machine-specific code with ``#ifdef vax'' (or other machine, +as appropriate). +4.4BSD underwent extensive work to make it extremely portable to +machines with similar architectures\- you may someday find +yourself trying to use a single copy of the source code on +multiple machines. +.NH 2 +Adding non-standard system facilities +.PP +This section considers the work needed to augment +.IR config 's +data base files for non-standard system facilities. +.I Config +uses a set of files that list the source modules that may be required +when building a system. +The data bases are taken from the directory in which +.I config +is run, normally /sys/conf. +Three such files may be used: +.IR files , +.IR files .machine, +and +.IR files .ident. +The first is common to all systems, +the second contains files unique to a single machine type, +and the third is an optional list of modules for use on a specific machine. +This last file may override specifications in the first two. +The format of the +.I files +file has grown somewhat complex over time. Entries are normally of +the form +.IP +.nf +.DT +\fIdir/source.c\fP \fItype\fP \fIoption-list\fP \fImodifiers\fP +.LP +for example, +.IP +.nf +.DT +\fIvaxuba/foo.c\fP \fBoptional\fP foo \fBdevice-driver\fP +.LP +The +.I type +is one of +.B standard +or +.BR optional . +Files marked as standard are included in all system configurations. +Optional file specifications include a list of one or more system +options that together require the inclusion of this module. +The options in the list may be either names of devices that may +be in the configuration file, +or the names of system options that may be defined. +An optional file may be listed multiple times with different options; +if all of the options for any of the entries are satisfied, +the module is included. +.PP +If a file is specified as a +.IR device-driver , +any special compilation options for device drivers will be invoked. +On the VAX this results in the use of the +.B \-i +option for the C optimizer. This is required when pointer references +are made to memory locations in the VAX I/O address space. +.PP +Two other optional keywords modify the usage of the file. +.I Config +understands that certain files are used especially for +kernel profiling. These files are indicated in the +.I files +files with a +.I profiling-routine +keyword. For example, the current profiling subroutines +are sequestered off in a separate file with the following +entry: +.IP +.nf +.DT +\fIsys/subr_mcount.c\fP \fBoptional\fP \fBprofiling-routine\fP +.fi +.LP +The +.I profiling-routine +keyword forces +.I config +not to compile the source file with the +.B \-pg +option. +.PP +The second keyword which can be of use is the +.I config-dependent +keyword. This causes +.I config +to compile the indicated module with the global configuration +parameters. This allows certain modules, such as +.I machdep.c +to size system data structures based on the maximum number +of users configured for the system. +.NH 2 +Adding device drivers to 4.4BSD +.PP +The I/O system and +.I config +have been designed to easily allow new device support to be added. +The system source directories are organized as follows: +.DS +.TS +lw(1.0i) l. +/sys/h machine independent include files +/sys/sys machine-independent system source files +/sys/conf site configuration files and basic templates +/sys/net network-protocol-independent, but network-related code +/sys/netinet DARPA Internet code +/sys/netimp IMP support code +/sys/netns Xerox NS code +/sys/vax VAX-specific mainline code +/sys/vaxif VAX network interface code +/sys/vaxmba VAX MASSBUS device drivers and related code +/sys/vaxuba VAX UNIBUS device drivers and related code +.TE +.DE +.PP +Existing block and character device drivers for the VAX +reside in ``/sys/vax'', ``/sys/vaxmba'', and ``/sys/vaxuba''. Network +interface drivers reside in ``/sys/vaxif''. Any new device +drivers should be placed in the appropriate source code directory +and named so as not to conflict with existing devices. +Normally, definitions for things like device registers are placed in +a separate file in the same directory. For example, the ``dh'' +device driver is named ``dh.c'' and its associated include file is +named ``dhreg.h''. +.PP +Once the source for the device driver has been placed in a directory, +the file ``/sys/conf/files.machine'', and possibly +``/sys/conf/devices.machine'' should be modified. The +.I files +files in the conf directory contain a line for each C source or binary-only +file in the system. Those files which are machine independent are +located in ``/sys/conf/files,'' while machine specific files +are in ``/sys/conf/files.machine.'' The ``devices.machine'' file +is used to map device names to major block device numbers. If the device +driver being added provides support for a new disk +you will want to modify this file (the format is obvious). +.PP +In addition to including the driver in the +.I files +file, it must also be added to the device configuration tables. These +are located in ``/sys/vax/conf.c'', or similar for machines other than +the VAX. If you don't understand what to add to this file, you should +study an entry for an existing driver. +Remember that the position in the +device table specifies the major device number. +The block major number is needed in the ``devices.machine'' file +if the device is a disk. +.PP +With the configuration information in place, your configuration +file appropriately modified, and a system reconfigured and rebooted +you should incorporate the shell commands needed to install the special +files in the file system to the file ``/dev/MAKEDEV'' or +``/dev/MAKEDEV.local''. This is discussed in the document ``Installing +and Operating 4.4BSD''. diff --git a/usr.sbin/config/SMM.doc/Makefile b/usr.sbin/config/SMM.doc/Makefile new file mode 100644 index 0000000..3a2f188 --- /dev/null +++ b/usr.sbin/config/SMM.doc/Makefile @@ -0,0 +1,10 @@ +# @(#)Makefile 8.1 (Berkeley) 6/8/93 + +DIR= smm/02.config +SRCS= 0.t 1.t 2.t 3.t 4.t 5.t 6.t a.t b.t c.t d.t e.t +MACROS= -ms + +paper.ps: ${SRCS} + ${TBL} ${SRCS} | ${ROFF} > ${.TARGET} + +.include diff --git a/usr.sbin/config/SMM.doc/a.t b/usr.sbin/config/SMM.doc/a.t new file mode 100644 index 0000000..dfcb954 --- /dev/null +++ b/usr.sbin/config/SMM.doc/a.t @@ -0,0 +1,162 @@ +.\" 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. +.\" +.\" @(#)a.t 8.1 (Berkeley) 6/8/93 +.\" +.\".ds RH "Configuration File Grammar +.bp +.LG +.B +.ce +APPENDIX A. CONFIGURATION FILE GRAMMAR +.sp +.R +.NL +.PP +The following grammar is a compressed form of the actual +\fIyacc\fP\|(1) grammar used by +.I config +to parse configuration files. +Terminal symbols are shown all in upper case, literals +are emboldened; optional clauses are enclosed in brackets, ``['' +and ``]''; zero or more instantiations are denoted with ``*''. +.sp +.nf +.DT +Configuration ::= [ Spec \fB;\fP ]* + +Spec ::= Config_spec + | Device_spec + | \fBtrace\fP + | /* lambda */ + +/* configuration specifications */ + +Config_spec ::= \fBmachine\fP ID + | \fBcpu\fP ID + | \fBoptions\fP Opt_list + | \fBident\fP ID + | System_spec + | \fBtimezone\fP [ \fB\-\fP ] NUMBER [ \fBdst\fP [ NUMBER ] ] + | \fBtimezone\fP [ \fB\-\fP ] FPNUMBER [ \fBdst\fP [ NUMBER ] ] + | \fBmaxusers\fP NUMBER + +/* system configuration specifications */ + +System_spec ::= \fBconfig\fP ID System_parameter [ System_parameter ]* + +System_parameter ::= swap_spec | root_spec | dump_spec | arg_spec + +swap_spec ::= \fBswap\fP [ \fBon\fP ] swap_dev [ \fBand\fP swap_dev ]* + +swap_dev ::= dev_spec [ \fBsize\fP NUMBER ] + +root_spec ::= \fBroot\fP [ \fBon\fP ] dev_spec + +dump_spec ::= \fBdumps\fP [ \fBon\fP ] dev_spec + +arg_spec ::= \fBargs\fP [ \fBon\fP ] dev_spec + +dev_spec ::= dev_name | major_minor + +major_minor ::= \fBmajor\fP NUMBER \fBminor\fP NUMBER + +dev_name ::= ID [ NUMBER [ ID ] ] + +/* option specifications */ + +Opt_list ::= Option [ \fB,\fP Option ]* + +Option ::= ID [ \fB=\fP Opt_value ] + +Opt_value ::= ID | NUMBER + +Mkopt_list ::= Mkoption [ \fB,\fP Mkoption ]* + +Mkoption ::= ID \fB=\fP Opt_value + +/* device specifications */ + +Device_spec ::= \fBdevice\fP Dev_name Dev_info Int_spec + | \fBmaster\fP Dev_name Dev_info + | \fBdisk\fP Dev_name Dev_info + | \fBtape\fP Dev_name Dev_info + | \fBcontroller\fP Dev_name Dev_info [ Int_spec ] + | \fBpseudo-device\fP Dev [ NUMBER ] + +Dev_name ::= Dev NUMBER + +Dev ::= \fBuba\fP | \fBmba\fP | ID + +Dev_info ::= Con_info [ Info ]* + +Con_info ::= \fBat\fP Dev NUMBER + | \fBat\fP \fBnexus\fP NUMBER + +Info ::= \fBcsr\fP NUMBER + | \fBdrive\fP NUMBER + | \fBslave\fP NUMBER + | \fBflags\fP NUMBER + +Int_spec ::= \fBvector\fP ID [ ID ]* + | \fBpriority\fP NUMBER +.fi +.sp +.SH +Lexical Conventions +.LP +The terminal symbols are loosely defined as: +.IP ID +.br +One or more alphabetics, either upper or lower case, and underscore, +``_''. +.IP NUMBER +.br +Approximately the C language specification for an integer number. +That is, a leading ``0x'' indicates a hexadecimal value, +a leading ``0'' indicates an octal value, otherwise the number is +expected to be a decimal value. Hexadecimal numbers may use either +upper or lower case alphabetics. +.IP FPNUMBER +.br +A floating point number without exponent. That is a number of the +form ``nnn.ddd'', where the fractional component is optional. +.LP +In special instances a question mark, ``?'', can be substituted for +a ``NUMBER'' token. This is used to effect wildcarding in device +interconnection specifications. +.LP +Comments in configuration files are indicated by a ``#'' character +at the beginning of the line; the remainder of the line is discarded. +.LP +A specification +is interpreted as a continuation of the previous line +if the first character of the line is tab. diff --git a/usr.sbin/config/SMM.doc/b.t b/usr.sbin/config/SMM.doc/b.t new file mode 100644 index 0000000..7281610 --- /dev/null +++ b/usr.sbin/config/SMM.doc/b.t @@ -0,0 +1,137 @@ +.\" 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. +.\" +.\" @(#)b.t 8.1 (Berkeley) 6/8/93 +.\" +.\".ds RH "Device Defaulting Rules +.bp +.LG +.B +.ce +APPENDIX B. RULES FOR DEFAULTING SYSTEM DEVICES +.sp +.R +.NL +.PP +When \fIconfig\fP processes a ``config'' rule which does +not fully specify the location of the root file system, +paging area(s), device for system dumps, and device for +argument list processing it applies a set of rules to +define those values left unspecified. The following list +of rules are used in defaulting system devices. +.IP 1) 3 +If a root device is not specified, the swap +specification must indicate a ``generic'' system is to be built. +.IP 2) 3 +If the root device does not specify a unit number, it +defaults to unit 0. +.IP 3) 3 +If the root device does not include a partition specification, +it defaults to the ``a'' partition. +.IP 4) 3 +If no swap area is specified, it defaults to the ``b'' +partition of the root device. +.IP 5) 3 +If no device is specified for processing argument lists, the +first swap partition is selected. +.IP 6) 3 +If no device is chosen for system dumps, the first swap +partition is selected (see below to find out where dumps are +placed within the partition). +.PP +The following table summarizes the default partitions selected +when a device specification is incomplete, e.g. ``hp0''. +.DS +.TS +l l. +Type Partition +_ +root ``a'' +swap ``b'' +args ``b'' +dumps ``b'' +.TE +.DE +.SH +Multiple swap/paging areas +.PP +When multiple swap partitions are specified, the system treats the +first specified as a ``primary'' swap area which is always used. +The remaining partitions are then interleaved into the paging +system at the time a +.IR swapon (2) +system call is made. This is normally done at boot time with +a call to +.IR swapon (8) +from the /etc/rc file. +.SH +System dumps +.PP +System dumps are automatically taken after a system crash, +provided the device driver for the ``dumps'' device supports +this. The dump contains the contents of memory, but not +the swap areas. Normally the dump device is a disk in +which case the information is copied to a location at the +back of the partition. The dump is placed in the back of the +partition because the primary swap and dump device are commonly +the same device and this allows the system to be rebooted without +immediately overwriting the saved information. When a dump has +occurred, the system variable \fIdumpsize\fP +is set to a non-zero value indicating the size (in bytes) of +the dump. The \fIsavecore\fP\|(8) +program then copies the information from the dump partition to +a file in a ``crash'' directory and also makes a copy of the +system which was running at the time of the crash (usually +``/vmunix''). The offset to the system dump is defined in the +system variable \fIdumplo\fP (a sector offset from +the front of the dump partition). The +.I savecore +program operates by reading the contents of \fIdumplo\fP, \fIdumpdev\fP, +and \fIdumpmagic\fP from /dev/kmem, then comparing the value +of \fIdumpmagic\fP read from /dev/kmem to that located in +corresponding location in the dump area of the dump partition. +If a match is found, +.I savecore +assumes a crash occurred and reads \fIdumpsize\fP from the dump area +of the dump partition. This value is then used in copying the +system dump. Refer to +\fIsavecore\fP\|(8) +for more information about its operation. +.PP +The value \fIdumplo\fP is calculated to be +.DS +\fIdumpdev-size\fP \- \fImemsize\fP +.DE +where \fIdumpdev-size\fP is the size of the disk partition +where system dumps are to be placed, and +\fImemsize\fP is the size of physical memory. +If the disk partition is not large enough to hold a full +dump, \fIdumplo\fP is set to 0 (the start of the partition). diff --git a/usr.sbin/config/SMM.doc/c.t b/usr.sbin/config/SMM.doc/c.t new file mode 100644 index 0000000..0f28fda --- /dev/null +++ b/usr.sbin/config/SMM.doc/c.t @@ -0,0 +1,109 @@ +.\" 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. +.\" +.\" @(#)c.t 8.1 (Berkeley) 6/8/93 +.\" +.\".ds RH "Sample Config Files +.bp +.LG +.B +.ce +APPENDIX C. SAMPLE CONFIGURATION FILES +.sp +.R +.NL +.PP +The following configuration files are developed in section 5; +they are included here for completeness. +.sp 2 +.nf +.ta 1.5i 2.5i 4.0i +# +# ANSEL VAX (a picture perfect machine) +# +machine vax +cpu VAX780 +timezone 8 dst +ident ANSEL +maxusers 40 + +config vmunix root on hp0 +config hpvmunix root on hp0 swap on hp0 and hp2 +config genvmunix swap generic + +controller mba0 at nexus ? +disk hp0 at mba? disk ? +disk hp1 at mba? disk ? +controller mba1 at nexus ? +disk hp2 at mba? disk ? +disk hp3 at mba? disk ? +controller uba0 at nexus ? +controller tm0 at uba? csr 0172520 vector tmintr +tape te0 at tm0 drive 0 +tape te1 at tm0 drive 1 +device dh0 at uba? csr 0160020 vector dhrint dhxint +device dm0 at uba? csr 0170500 vector dmintr +device dh1 at uba? csr 0160040 vector dhrint dhxint +device dh2 at uba? csr 0160060 vector dhrint dhxint +.bp +# +# UCBVAX - Gateway to the world +# +machine vax +cpu "VAX780" +cpu "VAX750" +ident UCBVAX +timezone 8 dst +maxusers 32 +options INET +options NS + +config vmunix root on hp swap on hp and rk0 and rk1 +config upvmunix root on up +config hkvmunix root on hk swap on rk0 and rk1 + +controller mba0 at nexus ? +controller uba0 at nexus ? +disk hp0 at mba? drive 0 +disk hp1 at mba? drive 1 +controller sc0 at uba? csr 0176700 vector upintr +disk up0 at sc0 drive 0 +disk up1 at sc0 drive 1 +controller hk0 at uba? csr 0177440 vector rkintr +disk rk0 at hk0 drive 0 +disk rk1 at hk0 drive 1 +pseudo-device pty +pseudo-device loop +pseudo-device imp +device acc0 at uba? csr 0167600 vector accrint accxint +pseudo-device ether +device ec0 at uba? csr 0164330 vector ecrint eccollide ecxint +device il0 at uba? csr 0164000 vector ilrint ilcint diff --git a/usr.sbin/config/SMM.doc/d.t b/usr.sbin/config/SMM.doc/d.t new file mode 100644 index 0000000..db9ab80 --- /dev/null +++ b/usr.sbin/config/SMM.doc/d.t @@ -0,0 +1,272 @@ +.\" 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. +.\" +.\" @(#)d.t 8.1 (Berkeley) 6/8/93 +.\" +.\".ds RH "Data Structure Sizing Rules +.bp +.LG +.B +.ce +APPENDIX D. VAX KERNEL DATA STRUCTURE SIZING RULES +.sp +.R +.NL +.PP +Certain system data structures are sized at compile time +according to the maximum number of simultaneous users expected, +while others are calculated at boot time based on the +physical resources present, e.g. memory. This appendix lists +both sets of rules and also includes some hints on changing +built-in limitations on certain data structures. +.SH +Compile time rules +.PP +The file \fI/sys/conf\|/param.c\fP contains the definitions of +almost all data structures sized at compile time. This file +is copied into the directory of each configured system to allow +configuration-dependent rules and values to be maintained. +(Each copy normally depends on the copy in /sys/conf, +and global modifications cause the file to be recopied unless +the makefile is modified.) +The rules implied by its contents are summarized below (here +MAXUSERS refers to the value defined in the configuration file +in the ``maxusers'' rule). +Most limits are computed at compile time and stored in global variables +for use by other modules; they may generally be patched in the system +binary image before rebooting to test new values. +.IP \fBnproc\fP +.br +The maximum number of processes which may be running at any time. +It is referred to in other calculations as NPROC and is defined to be +.DS +20 + 8 * MAXUSERS +.DE +.IP \fBntext\fP +.br +The maximum number of active shared text segments. +The constant is intended to allow for network servers and common commands +that remain in the table. +It is defined as +.DS +36 + MAXUSERS. +.DE +.IP \fBninode\fP +.br +The maximum number of files in the file system which may be +active at any time. This includes files in use by users, as +well as directory files being read or written by the system +and files associated with bound sockets in the UNIX IPC domain. +It is defined as +.DS +(NPROC + 16 + MAXUSERS) + 32 +.DE +.IP \fBnfile\fP +.br +The number of ``file table'' structures. One file +table structure is used for each open, unshared, file descriptor. +Multiple file descriptors may reference a single file table +entry when they are created through a \fIdup\fP call, or as the +result of a \fIfork\fP. This is defined to be +.DS +16 * (NPROC + 16 + MAXUSERS) / 10 + 32 +.DE +.IP \fBncallout\fP +.br +The number of ``callout'' structures. One callout +structure is used per internal system event handled with +a timeout. Timeouts are used for terminal delays, +watchdog routines in device drivers, protocol timeout processing, etc. +This is defined as +.DS +16 + NPROC +.DE +.IP \fBnclist\fP +.br +The number of ``c-list'' structures. C-list structures are +used in terminal I/O, and currently each holds 60 characters. +Their number is defined as +.DS +60 + 12 * MAXUSERS +.DE +.IP \fBnmbclusters\fP +.br +The maximum number of pages which may be allocated by the network. +This is defined as 256 (a quarter megabyte of memory) in /sys/h/mbuf.h. +In practice, the network rarely uses this much memory. It starts off +by allocating 8 kilobytes of memory, then requesting more as +required. This value represents an upper bound. +.IP \fBnquota\fP +.br +The number of ``quota'' structures allocated. Quota structures +are present only when disc quotas are configured in the system. One +quota structure is kept per user. This is defined to be +.DS +(MAXUSERS * 9) / 7 + 3 +.DE +.IP \fBndquot\fP +.br +The number of ``dquot'' structures allocated. Dquot structures +are present only when disc quotas are configured in the system. +One dquot structure is required per user, per active file system quota. +That is, when a user manipulates a file on a file system on which +quotas are enabled, the information regarding the user's quotas on +that file system must be in-core. This information is cached, so +that not all information must be present in-core all the time. +This is defined as +.DS +NINODE + (MAXUSERS * NMOUNT) / 4 +.DE +where NMOUNT is the maximum number of mountable file systems. +.LP +In addition to the above values, the system page tables (used to +map virtual memory in the kernel's address space) are sized at +compile time by the SYSPTSIZE definition in the file /sys/vax/vmparam.h. +This is defined to be +.DS +20 + MAXUSERS +.DE +pages of page tables. +Its definition affects +the size of many data structures allocated at boot time because +it constrains the amount of virtual memory which may be addressed +by the running system. This is often the limiting factor +in the size of the buffer cache, in which case a message is printed +when the system configures at boot time. +.SH +Run-time calculations +.PP +The most important data structures sized at run-time are those used in +the buffer cache. Allocation is done by allocating physical memory +(and system virtual memory) immediately after the system +has been started up; look in the file /sys/vax/machdep.c. +The amount of physical memory which may be allocated to the buffer +cache is constrained by the size of the system page tables, among +other things. While the system may calculate +a large amount of memory to be allocated to the buffer cache, +if the system page +table is too small to map this physical +memory into the virtual address space +of the system, only as much as can be mapped will be used. +.PP +The buffer cache is comprised of a number of ``buffer headers'' +and a pool of pages attached to these headers. Buffer headers +are divided into two categories: those used for swapping and +paging, and those used for normal file I/O. The system tries +to allocate 10% of the first two megabytes and 5% of the remaining +available physical memory for the buffer +cache (where \fIavailable\fP does not count that space occupied by +the system's text and data segments). If this results in fewer +than 16 pages of memory allocated, then 16 pages are allocated. +This value is kept in the initialized variable \fIbufpages\fP +so that it may be patched in the binary image (to allow tuning +without recompiling the system), +or the default may be overridden with a configuration-file option. +For example, the option \fBoptions BUFPAGES="3200"\fP +causes 3200 pages (3.2M bytes) to be used by the buffer cache. +A sufficient number of file I/O buffer headers are then allocated +to allow each to hold 2 pages each. +Each buffer maps 8K bytes. +If the number of buffer pages is larger than can be mapped +by the buffer headers, the number of pages is reduced. +The number of buffer headers allocated +is stored in the global variable \fInbuf\fP, +which may be patched before the system is booted. +The system option \fBoptions NBUF="1000"\fP forces the allocation +of 1000 buffer headers. +Half as many swap I/O buffer headers as file I/O buffers +are allocated, +but no more than 256. +.SH +System size limitations +.PP +As distributed, the sum of the virtual sizes of the core-resident +processes is limited to 256M bytes. The size of the text +segment of a single process is currently limited to 6M bytes. +It may be increased to no greater than the data segment size limit +(see below) by redefining MAXTSIZ. +This may be done with a configuration file option, +e.g. \fBoptions MAXTSIZ="(10*1024*1024)"\fP +to set the limit to 10 million bytes. +Other per-process limits discussed here may be changed with similar options +with names given in parentheses. +Soft, user-changeable limits are set to 512K bytes for stack (DFLSSIZ) +and 6M bytes for the data segment (DFLDSIZ) by default; +these may be increased up to the hard limit +with the \fIsetrlimit\fP\|(2) system call. +The data and stack segment size hard limits are set by a system configuration +option to one of 17M, 33M or 64M bytes. +One of these sizes is chosen based on the definition of MAXDSIZ; +with no option, the limit is 17M bytes; with an option +\fBoptions MAXDSIZ="(32*1024*1024)"\fP (or any value between 17M and 33M), +the limit is increased to 33M bytes, and values larger than 33M +result in a limit of 64M bytes. +You must be careful in doing this that you have adequate paging space. +As normally configured , the system has 16M or 32M bytes per paging area, +depending on disk size. +The best way to get more space is to provide multiple, thereby +interleaved, paging areas. +Increasing the virtual memory limits results in interleaving of +swap space in larger sections (from 500K bytes to 1M or 2M bytes). +.PP +By default, the virtual memory system allocates enough memory +for system page tables mapping user page tables +to allow 256 megabytes of simultaneous active virtual memory. +That is, the sum of the virtual memory sizes of all (completely- or partially-) +resident processes can not exceed this limit. +If the limit is exceeded, some process(es) must be swapped out. +To increase the amount of resident virtual space possible, +you can alter the constant USRPTSIZE (in +/sys/vax/vmparam.h). +Each page of system page tables allows 8 megabytes of user virtual memory. +.PP +Because the file system block numbers are stored in +page table \fIpg_blkno\fP +entries, the maximum size of a file system is limited to +2^24 1024 byte blocks. Thus no file system can be larger than 8 gigabytes. +.PP +The number of mountable file systems is set at 20 by the definition +of NMOUNT in /sys/h/param.h. +This should be sufficient; if not, the value can be increased up to 255. +If you have many disks, it makes sense to make some of +them single file systems, and the paging areas don't count in this total. +.PP +The limit to the number of files that a process may have open simultaneously +is set to 64. +This limit is set by the NOFILE definition in /sys/h/param.h. +It may be increased arbitrarily, with the caveat that the user structure +expands by 5 bytes for each file, and thus UPAGES (/sys/vax/machparam.h) +must be increased accordingly. +.PP +The amount of physical memory is currently limited to 64 Mb +by the size of the index fields in the core-map (/sys/h/cmap.h). +The limit may be increased by following instructions in that file +to enlarge those fields. diff --git a/usr.sbin/config/SMM.doc/e.t b/usr.sbin/config/SMM.doc/e.t new file mode 100644 index 0000000..0a9505b --- /dev/null +++ b/usr.sbin/config/SMM.doc/e.t @@ -0,0 +1,114 @@ +.\" 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. +.\" +.\" @(#)e.t 8.1 (Berkeley) 6/8/93 +.\" +.\".ds RH "Network configuration options +.bp +.LG +.B +.ce +APPENDIX E. NETWORK CONFIGURATION OPTIONS +.sp +.R +.NL +.PP +The network support in the kernel is self-configuring +according to the protocol support options (INET and NS) and the network +hardware discovered during autoconfiguration. +There are several changes that may be made to customize network behavior +due to local restrictions. +Within the Internet protocol routines, the following options +set in the system configuration file are supported: +.IP \fBGATEWAY\fP +.br +The machine is to be used as a gateway. +This option currently makes only minor changes. +First, the size of the network routing hash table is increased. +Secondly, machines that have only a single hardware network interface +will not forward IP packets; without this option, they will also refrain +from sending any error indication to the source of unforwardable packets. +Gateways with only a single interface are assumed to have missing +or broken interfaces, and will return ICMP unreachable errors to hosts +sending them packets to be forwarded. +.IP \fBTCP_COMPAT_42\fP +.br +This option forces the system to limit its initial TCP sequence numbers +to positive numbers. +Without this option, 4.4BSD systems may have problems with TCP connections +to 4.2BSD systems that connect but never transfer data. +The problem is a bug in the 4.2BSD TCP. +.IP \fBIPFORWARDING\fP +.br +Normally, 4.4BSD machines with multiple network interfaces +will forward IP packets received that should be resent to another host. +If the line ``options IPFORWARDING="0"'' is in the system configuration +file, IP packet forwarding will be disabled. +.IP \fBIPSENDREDIRECTS\fP +.br +When forwarding IP packets, 4.4BSD IP will note when a packet is forwarded +using the same interface on which it arrived. +When this is noted, if the source machine is on the directly-attached +network, an ICMP redirect is sent to the source host. +If the packet was forwarded using a route to a host or to a subnet, +a host redirect is sent, otherwise a network redirect is sent. +The generation of redirects may be inhibited with the configuration +option ``options IPSENDREDIRECTS="0".'' +.br +.IP \fBSUBNETSARELOCAL\fP +TCP calculates a maximum segment size to use for each connection, +and sends no datagrams larger than that size. +This size will be no larger than that supported on the outgoing +interface. +Furthermore, if the destination is not on the local network, +the size will be no larger than 576 bytes. +For this test, other subnets of a directly-connected subnetted +network are considered to be local unless the line +``options SUBNETSARELOCAL="0"'' is used in the system configuration file. +.LP +The following options are supported by the Xerox NS protocols: +.IP \fBNSIP\fP +.br +This option allows NS IDP datagrams to be encapsulated in Internet IP +packets for transmission to a collaborating NSIP host. +This may be used to pass IDP packets through IP-only link layer networks. +See +.IR nsip (4P) +for details. +.IP \fBTHREEWAYSHAKE\fP +.br +The NS Sequenced Packet Protocol does not require a three-way handshake +before considering a connection to be in the established state. +(A three-way handshake consists of a connection request, an acknowledgement +of the request along with a symmetrical opening indication, +and then an acknowledgement of the reciprocal opening packet.) +This option forces a three-way handshake before data may be transmitted +on Sequenced Packet sockets. diff --git a/usr.sbin/config/SMM.doc/spell.ok b/usr.sbin/config/SMM.doc/spell.ok new file mode 100644 index 0000000..4132452 --- /dev/null +++ b/usr.sbin/config/SMM.doc/spell.ok @@ -0,0 +1,306 @@ +ACC +ANSEL +ARP +Autoconfiguration +BUFPAGES +CANTWAIT +CH +COMPAT +CSS +Co +Config +Config''SMM:2 +DCLR +DFLDSIZ +DFLSSIZ +DFUNNY +DHAHA +DMA +Dev +Dquot +ECC +EMULEX +Emulex +Ethernet +FPNUMBER +FUNNY,HAHA +HAVEBDP +ICMP +IDP +IE +INET +IP +IPC +IPFORWARDING +IPL +IPSENDREDIRECTS +Info +Karels +LH +Leffler +MAKEDEV +MAKEDEV.local +MASSBUS +MAXDSIZ +MAXTSIZ +Makefile +Mb +MicroVAX +Mkopt +Mkoption +NBUF +NEED16 +NEEDBDP +NINODE +NMOUNT +NOFILE +NPROC +NS +NSC +NSIP +NUP +PST +RCS +RDY +RH +RK07 +RK611 +SCCS +SITENAME +SMM:2 +SUBNETSARELOCAL +SYSPTSIZE +TCP +THREEWAYSHAKE +Timezone +UCBVAX +UDP +UNIBUS +UPAGES +UPCS2 +USRPTSIZE +VAX +VAX630 +VAX730 +VAX750 +VAX780 +VAX8600 +VAXWELL +VAXen +Vax +Vaxwell +acc0 +accrint +accxint +addr +arg +args +assym.s +autoconfiguration +autoconfigure +autoconfigured +backpointer +badaddr +blkno +br +br5 +buf +bufpages +buses +caddr +callout +catchall +cmap.h +cmd +conf +conf.c +config +csr +ct.c +ctlr +cvec +datagrams +define''s +dev +devices.machine +dgo +dh.c +dh0 +dh1 +dh2 +dhreg.h +dhrint +dhxint +dinfo +dk +dk.h +dm0 +dmintr +dname +dquot +dst +dumpdev +dumplo +dumpmagic +dumpsize +dz.c +dz0 +dzrint +dzxint +ec0 +eccollide +ecrint +ecxint +endif +es +files.machine +filesystem +foo +foo.c +genvmunix +gettimeofday +gigabytes +gprof +hardwired +hd +hk +hk0 +hkvmunix +howmany +hp0 +hp0b +hp1 +hp2 +hp3 +hpvmunix +ht0 +hz +ident +ifdef +ifndef +il0 +ilcint +ilrint +info +intr +ioconf.c +kgmon +linterrs +loopback +machdep.c +machparam.h +makefile +makelinks +makeoptions +maxusers +mba +mba0 +mba1 +mbuf.h +mcount.c +memsize +minfo +mname +moniker +mspw +nbuf +ncallout +nclist +ndquot +ndrive +netimp +netinet +netns +netstat +nexi +nexus +nfile +ninode +nmbclusters +nnn.ddd +nproc +nquota +nsip +ntext +optionlist +param.c +param.h +pathnames +pg +physaddr +pty +rc +reg +rk.c +rk0 +rk1 +rkintr +savecore +sc +sc0 +sc1 +scdriver +setrlimit +sizeof +softc +source.c +subr +swapxxx.c +sysname +te0 +te1 +timezone +tm0 +tmintr +tu0 +uba +uba.c +uba0 +ubago +uballoc +ubamem +ubanum +ubareg.h +ubarelse +ubavar.h +ubglue.s +ubinfo +ud +ui +um +up.c +up0 +up1 +up2 +upaddr +upattach +upba +upcs1 +upcs2 +updevice +updgo +updinfo +updtab +upintr +upip +upmaptype +upminfo +upprobe +upslave +upstd +upvmunix +upwatch +upwstart +value,name2 +value2 +vax +vaxif +vaxmba +vaxuba +vmparam.h +vmunix +wildcard +wildcarded +wildcarding +xclu +xxx diff --git a/usr.sbin/config/config.8 b/usr.sbin/config/config.8 new file mode 100644 index 0000000..aef26a2 --- /dev/null +++ b/usr.sbin/config/config.8 @@ -0,0 +1,174 @@ +.\" Copyright (c) 1980, 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. +.\" +.\" @(#)config.8 8.2 (Berkeley) 4/19/94 +.\" +.Dd April 19, 1994 +.Dt CONFIG 8 +.Os BSD 4 +.Sh NAME +.Nm config +.Nd build system configuration files +.Sh SYNOPSIS +.Nm config +.Op Fl p +.Ar system_name +.Sh DESCRIPTION +.Pp +This is the old version of the +.Nm config +program. +It understands the old autoconfiguration scheme +used on the HP300, DECstation, and derivative platforms. +The new version of config is used with the +SPARC and i386 platforms. +Only the version of +.Nm config +applicable to the architecture that you are running +will be installed on your machine. +.Pp +.Nm Config +builds a set of system configuration files from the file +.Ar SYSTEM_NAME +which describes +the system to configure. +A second file +tells +.Nm config +what files are needed to generate a system and +can be augmented by configuration specific set of files +that give alternate files for a specific machine. +(see the +.Sx FILES +section below) +.Pp +Available option and operand: +.Pp +.Bl -tag -width SYSTEM_NAME +.It Fl p +If the +.Fl p +option is supplied, +.Nm config +will configure a system for profiling; for example, +.Xr kgmon 8 +and +.Xr gprof 1 . +.It Ar SYSTEM_NAME +specifies the name of the system configuration file +containing device specifications, configuration options +and other system parameters for one system configuration. +.El +.Pp +.Nm Config +should be run from the +.Pa conf +subdirectory of the system source (usually +.Pa /sys/conf ) . +.Nm Config +assumes the directory +.Pa ../SYSTEM_NAME +exists and places all output files there. +The output of +.Nm config +consists of a number of files; for the +.Tn VAX , +they are: +.Pa ioconf.c , +a description +of what I/O devices are attached to the system; +.Pa ubglue.s , +a set of interrupt service routines for devices +attached to the +.Tn UNIBUS ; +.Pa ubvec.s , +offsets into a structure used for counting per-device interrupts; +.Pa Makefile , +used by +.Xr make 1 +in building the system; +header files, +definitions of +the number of various devices that will be compiled into the system; +swap configuration files, +definitions for +the disk areas to be used for swapping, the root file system, +argument processing, and system dumps. +.Pp +After running +.Nm config , +it is necessary to run +.Dq Li make depend +in the directory where the new makefile +was created. +.Nm Config +prints a reminder of this when it completes. +.Pp +If any other error messages are produced by +.Nm config , +the problems in the configuration file should be corrected and +.Nm config +should be run again. +Attempts to compile a system that had configuration errors +are likely to fail. +.Sh FILES +.Bl -tag -width /sys/conf/Makefile.vax -compact +.It Pa /sys/conf/Makefile.vax +generic makefile for the +.Tn VAX +.It Pa /sys/conf/files +list of common files system is built from +.It Pa /sys/conf/files.vax +list of +.Tn VAX +specific files +.It Pa /sys/conf/devices.vax +name to major device mapping file for the +.Tn VAX +.It Pa /sys/conf/files. Ns Em ERNIE +list of files specific to +.Em ERNIE +system +.El +.Sh SEE ALSO +The SYNOPSIS portion of each device in section 4. +.Rs +.%T "Building 4.3 BSD UNIX System with Config" +.Re +.sp +.Xr config.new 8 +.Sh BUGS +The line numbers reported in error messages are usually off by one. +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.1 . diff --git a/usr.sbin/config/config.h b/usr.sbin/config/config.h new file mode 100644 index 0000000..6cd4d7f --- /dev/null +++ b/usr.sbin/config/config.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 1980, 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. + * + * @(#)config.h 8.1 (Berkeley) 6/6/93 + */ + +/* + * Config. + */ +#include +#include +#include + +#define NODEV ((dev_t)-1) + +struct file_list { + struct file_list *f_next; + char *f_fn; /* the name */ + u_char f_type; /* see below */ + u_char f_flags; /* see below */ + char *f_special; /* special make rule if present */ + char *f_needs; + /* + * Random values: + * swap space parameters for swap areas + * root device, etc. for system specifications + */ + union { + struct { /* when swap specification */ + dev_t fuw_swapdev; + int fuw_swapsize; + int fuw_swapflag; + } fuw; + struct { /* when system specification */ + dev_t fus_rootdev; + dev_t fus_dumpdev; + } fus; + struct { /* when component dev specification */ + dev_t fup_compdev; + int fup_compinfo; + } fup; + } fun; +#define f_swapdev fun.fuw.fuw_swapdev +#define f_swapsize fun.fuw.fuw_swapsize +#define f_swapflag fun.fuw.fuw_swapflag +#define f_rootdev fun.fus.fus_rootdev +#define f_dumpdev fun.fus.fus_dumpdev +#define f_compdev fun.fup.fup_compdev +#define f_compinfo fun.fup.fup_compinfo +}; + +/* + * Types. + */ +#define DRIVER 1 +#define NORMAL 2 +#define INVISIBLE 3 +#define PROFILING 4 +#define SYSTEMSPEC 5 +#define SWAPSPEC 6 +#define COMPDEVICE 7 +#define COMPSPEC 8 + +/* + * Attributes (flags). + */ +#define CONFIGDEP 1 + +struct idlst { + char *id; + struct idlst *id_next; +}; + +struct device { + int d_type; /* CONTROLLER, DEVICE, bus adaptor */ + struct device *d_conn; /* what it is connected to */ + char *d_name; /* name of device (e.g. rk11) */ + struct idlst *d_vec; /* interrupt vectors */ + int d_pri; /* interrupt priority */ + int d_addr; /* address of csr */ + int d_unit; /* unit number */ + int d_drive; /* drive number */ + int d_slave; /* slave number */ +#define QUES -1 /* -1 means '?' */ +#define UNKNOWN -2 /* -2 means not set yet */ + int d_dk; /* if init 1 set to number for iostat */ + int d_flags; /* flags for device init */ + char *d_port; /* io port base manifest constant */ + int d_portn; /* io port base (if number not manifest) */ + char *d_mask; /* interrupt mask */ + int d_maddr; /* io memory base */ + int d_msize; /* io memory size */ + int d_drq; /* DMA request */ + int d_irq; /* interrupt request */ + struct device *d_next; /* Next one in list */ +}; +#define TO_NEXUS (struct device *)-1 +#define TO_VBA (struct device *)-2 + +struct config { + char *c_dev; + char *s_sysname; +}; + +/* + * Config has a global notion of which machine type is + * being used. It uses the name of the machine in choosing + * files and directories. Thus if the name of the machine is ``vax'', + * it will build from ``Makefile.vax'' and use ``../vax/inline'' + * in the makerules, etc. + */ +int machine; +char *machinename; +#define MACHINE_VAX 1 +#define MACHINE_TAHOE 2 +#define MACHINE_HP300 3 +#define MACHINE_I386 4 +#define MACHINE_MIPS 5 +#define MACHINE_PMAX 6 +#define MACHINE_LUNA68K 7 +#define MACHINE_NEWS3400 8 + +/* + * For each machine, a set of CPU's may be specified as supported. + * These and the options (below) are put in the C flags in the makefile. + */ +struct cputype { + char *cpu_name; + struct cputype *cpu_next; +} *cputype; + +/* + * A set of options may also be specified which are like CPU types, + * but which may also specify values for the options. + * A separate set of options may be defined for make-style options. + */ +struct opt { + char *op_name; + char *op_value; + struct opt *op_next; +} *opt, *mkopt; + +char *ident; +char *ns(); +char *tc(); +char *qu(); +char *get_word(); +char *get_quoted_word(); +char *path(); +char *raise(); + +int do_trace; + +#if MACHINE_VAX +int seen_mba, seen_uba; +#endif +#if MACHINE_TAHOE +int seen_vba; +#endif +#if MACHINE_I386 +int seen_isa; +#endif +int seen_cd; + +struct device *connect(); +struct device *dtab; +dev_t nametodev(); +char *devtoname(); + +char errbuf[80]; +int yyline; + +struct file_list *ftab, *conf_list, **confp, *comp_list, **compp; + +int zone, hadtz; +int dst; +int hz; +int profiling; +int debugging; + +int maxusers; + +#define eq(a,b) (!strcmp(a,b)) diff --git a/usr.sbin/config/config.y b/usr.sbin/config/config.y new file mode 100644 index 0000000..6784d9e --- /dev/null +++ b/usr.sbin/config/config.y @@ -0,0 +1,1109 @@ +%union { + char *str; + int val; + struct file_list *file; + struct idlst *lst; +} + +%token AND +%token ANY +%token ARGS +%token AT +%token BIO +%token COMMA +%token CONFIG +%token CONTROLLER +%token CPU +%token CSR +%token DEVICE +%token DISK +%token DRIVE +%token DRQ +%token DST +%token DUMPS +%token EQUALS +%token FLAGS +%token HZ +%token IDENT +%token INTERLEAVE +%token IOMEM +%token IOSIZ +%token IRQ +%token MACHINE +%token MAJOR +%token MASTER +%token MAXUSERS +%token MINOR +%token MINUS +%token NET +%token NEXUS +%token ON +%token OPTIONS +%token MAKEOPTIONS +%token PORT +%token PRIORITY +%token PSEUDO_DEVICE +%token ROOT +%token SEMICOLON +%token SEQUENTIAL +%token SIZE +%token SLAVE +%token SWAP +%token TIMEZONE +%token TTY +%token TRACE +%token VECTOR + +%token ID +%token NUMBER +%token FPNUMBER + +%type Save_id +%type Opt_value +%type Dev +%type Id_list +%type optional_size +%type optional_sflag +%type device_name +%type major_minor +%type arg_device_spec +%type root_device_spec +%type dump_device_spec +%type swap_device_spec +%type comp_device_spec + +%{ + +/* + * 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. + * + * @(#)config.y 8.1 (Berkeley) 6/6/93 + */ + +#include "config.h" +#include +#include + +struct device cur; +struct device *curp = 0; +char *temp_id; +char *val_id; + +%} +%% +Configuration: + Many_specs + = { verifysystemspecs(); } + ; + +Many_specs: + Many_specs Spec + | + /* lambda */ + ; + +Spec: + Device_spec SEMICOLON + = { newdev(&cur); } | + Config_spec SEMICOLON + | + TRACE SEMICOLON + = { do_trace = !do_trace; } | + SEMICOLON + | + error SEMICOLON + ; + +Config_spec: + MACHINE Save_id + = { + if (!strcmp($2, "vax")) { + machine = MACHINE_VAX; + machinename = "vax"; + } else if (!strcmp($2, "tahoe")) { + machine = MACHINE_TAHOE; + machinename = "tahoe"; + } else if (!strcmp($2, "hp300")) { + machine = MACHINE_HP300; + machinename = "hp300"; + } else if (!strcmp($2, "i386")) { + machine = MACHINE_I386; + machinename = "i386"; + } else if (!strcmp($2, "mips")) { + machine = MACHINE_MIPS; + machinename = "mips"; + } else if (!strcmp($2, "pmax")) { + machine = MACHINE_PMAX; + machinename = "pmax"; + } else if (!strcmp($2, "luna68k")) { + machine = MACHINE_LUNA68K; + machinename = "luna68k"; + } else if (!strcmp($2, "news3400")) { + machine = MACHINE_NEWS3400; + machinename = "news3400"; + } else + yyerror("Unknown machine type"); + } | + CPU Save_id + = { + struct cputype *cp = + (struct cputype *)malloc(sizeof (struct cputype)); + cp->cpu_name = ns($2); + cp->cpu_next = cputype; + cputype = cp; + free(temp_id); + } | + OPTIONS Opt_list + | + MAKEOPTIONS Mkopt_list + | + IDENT ID + = { ident = ns($2); } | + System_spec + | + HZ NUMBER + = { hz = $2; }| + TIMEZONE NUMBER + = { zone = 60 * $2; check_tz(); } | + TIMEZONE NUMBER DST NUMBER + = { zone = 60 * $2; dst = $4; check_tz(); } | + TIMEZONE NUMBER DST + = { zone = 60 * $2; dst = 1; check_tz(); } | + TIMEZONE FPNUMBER + = { zone = $2; check_tz(); } | + TIMEZONE FPNUMBER DST NUMBER + = { zone = $2; dst = $4; check_tz(); } | + TIMEZONE FPNUMBER DST + = { zone = $2; dst = 1; check_tz(); } | + TIMEZONE MINUS NUMBER + = { zone = -60 * $3; check_tz(); } | + TIMEZONE MINUS NUMBER DST NUMBER + = { zone = -60 * $3; dst = $5; check_tz(); } | + TIMEZONE MINUS NUMBER DST + = { zone = -60 * $3; dst = 1; check_tz(); } | + TIMEZONE MINUS FPNUMBER + = { zone = -$3; check_tz(); } | + TIMEZONE MINUS FPNUMBER DST NUMBER + = { zone = -$3; dst = $5; check_tz(); } | + TIMEZONE MINUS FPNUMBER DST + = { zone = -$3; dst = 1; check_tz(); } | + MAXUSERS NUMBER + = { maxusers = $2; }; + +System_spec: + System_id System_parameter_list + = { checksystemspec(*confp); } + ; + +System_id: + CONFIG Save_id + = { mkconf($2); } + ; + +System_parameter_list: + System_parameter_list System_parameter + | System_parameter + ; + +System_parameter: + swap_spec + | root_spec + | dump_spec + | arg_spec + ; + +swap_spec: + SWAP optional_on swap_device_list + ; + +swap_device_list: + swap_device_list AND swap_device + | swap_device + ; + +swap_device: + swap_device_spec optional_size optional_sflag + = { mkswap(*confp, $1, $2, $3); } + ; + +swap_device_spec: + device_name + = { + struct file_list *fl = newflist(SWAPSPEC); + + if (eq($1, "generic")) + fl->f_fn = $1; + else { + fl->f_swapdev = nametodev($1, 0, 'b'); + fl->f_fn = devtoname(fl->f_swapdev); + } + $$ = fl; + } + | major_minor + = { + struct file_list *fl = newflist(SWAPSPEC); + + fl->f_swapdev = $1; + fl->f_fn = devtoname($1); + $$ = fl; + } + ; + +root_spec: + ROOT optional_on root_device_spec + = { + struct file_list *fl = *confp; + + if (fl && fl->f_rootdev != NODEV) + yyerror("extraneous root device specification"); + else + fl->f_rootdev = $3; + } + ; + +root_device_spec: + device_name + = { $$ = nametodev($1, 0, 'a'); } + | major_minor + ; + +dump_spec: + DUMPS optional_on dump_device_spec + = { + struct file_list *fl = *confp; + + if (fl && fl->f_dumpdev != NODEV) + yyerror("extraneous dump device specification"); + else + fl->f_dumpdev = $3; + } + + ; + +dump_device_spec: + device_name + = { $$ = nametodev($1, 0, 'b'); } + | major_minor + ; + +arg_spec: + ARGS optional_on arg_device_spec + = { yyerror("arg device specification obsolete, ignored"); } + ; + +arg_device_spec: + device_name + = { $$ = nametodev($1, 0, 'b'); } + | major_minor + ; + +major_minor: + MAJOR NUMBER MINOR NUMBER + = { $$ = makedev($2, $4); } + ; + +optional_on: + ON + | /* empty */ + ; + +optional_size: + SIZE NUMBER + = { $$ = $2; } + | /* empty */ + = { $$ = 0; } + ; + +optional_sflag: + SEQUENTIAL + = { $$ = 2; } + | /* empty */ + = { $$ = 0; } + ; + +device_name: + Save_id + = { $$ = $1; } + | Save_id NUMBER + = { + char buf[80]; + + (void) sprintf(buf, "%s%d", $1, $2); + $$ = ns(buf); free($1); + } + | Save_id NUMBER ID + = { + char buf[80]; + + (void) sprintf(buf, "%s%d%s", $1, $2, $3); + $$ = ns(buf); free($1); + } + ; + +Opt_list: + Opt_list COMMA Option + | + Option + ; + +Option: + Save_id + = { + struct opt *op = (struct opt *)malloc(sizeof (struct opt)); + op->op_name = ns($1); + op->op_next = opt; + op->op_value = 0; + opt = op; + free(temp_id); + } | + Save_id EQUALS Opt_value + = { + struct opt *op = (struct opt *)malloc(sizeof (struct opt)); + op->op_name = ns($1); + op->op_next = opt; + op->op_value = ns($3); + opt = op; + free(temp_id); + free(val_id); + } ; + +Opt_value: + ID + = { $$ = val_id = ns($1); } | + NUMBER + = { + char nb[16]; + (void) sprintf(nb, "%d", $1); + $$ = val_id = ns(nb); + } ; + + +Save_id: + ID + = { $$ = temp_id = ns($1); } + ; + +Mkopt_list: + Mkopt_list COMMA Mkoption + | + Mkoption + ; + +Mkoption: + Save_id EQUALS Opt_value + = { + struct opt *op = (struct opt *)malloc(sizeof (struct opt)); + op->op_name = ns($1); + op->op_next = mkopt; + op->op_value = ns($3); + mkopt = op; + free(temp_id); + free(val_id); + } ; + +Dev: + ID + = { $$ = ns($1); } + ; + +Device_spec: + DEVICE Dev_name Dev_info Int_spec + = { cur.d_type = DEVICE; } | + MASTER Dev_name Dev_info Int_spec + = { cur.d_type = MASTER; } | + DISK Dev_name Dev_info Int_spec + = { cur.d_dk = 1; cur.d_type = DEVICE; } | + CONTROLLER Dev_name Dev_info Int_spec + = { cur.d_type = CONTROLLER; } | + PSEUDO_DEVICE Init_dev Dev + = { + cur.d_name = $3; + cur.d_type = PSEUDO_DEVICE; + } | + PSEUDO_DEVICE Init_dev Dev NUMBER + = { + cur.d_name = $3; + cur.d_type = PSEUDO_DEVICE; + cur.d_slave = $4; + } | + PSEUDO_DEVICE Dev_name Cdev_init Cdev_info + = { + if (!eq(cur.d_name, "cd")) + yyerror("improper spec for pseudo-device"); + seen_cd = 1; + cur.d_type = DEVICE; + verifycomp(*compp); + }; + +Cdev_init: + /* lambda */ + = { mkcomp(&cur); }; + +Cdev_info: + optional_on comp_device_list comp_option_list + ; + +comp_device_list: + comp_device_list AND comp_device + | comp_device + ; + +comp_device: + comp_device_spec + = { addcomp(*compp, $1); } + ; + +comp_device_spec: + device_name + = { + struct file_list *fl = newflist(COMPSPEC); + + fl->f_compdev = nametodev($1, 0, 'c'); + fl->f_fn = devtoname(fl->f_compdev); + $$ = fl; + } + | major_minor + = { + struct file_list *fl = newflist(COMPSPEC); + + fl->f_compdev = $1; + fl->f_fn = devtoname($1); + $$ = fl; + } + ; + +comp_option_list: + comp_option_list comp_option + | + /* lambda */ + ; + +comp_option: + INTERLEAVE NUMBER + = { cur.d_pri = $2; } | + FLAGS NUMBER + = { cur.d_flags = $2; }; + +Dev_name: + Init_dev Dev NUMBER + = { + cur.d_name = $2; + if (eq($2, "mba")) + seen_mba = 1; + else if (eq($2, "uba")) + seen_uba = 1; + else if (eq($2, "vba")) + seen_vba = 1; + else if (eq($2, "isa")) + seen_isa = 1; + cur.d_unit = $3; + }; + +Init_dev: + /* lambda */ + = { init_dev(&cur); }; + +Dev_info: + Con_info Info_list + | + /* lambda */ + ; + +Con_info: + AT Dev NUMBER + = { + if (eq(cur.d_name, "mba") || eq(cur.d_name, "uba")) { + (void) sprintf(errbuf, + "%s must be connected to a nexus", cur.d_name); + yyerror(errbuf); + } + cur.d_conn = connect($2, $3); + } | + AT NEXUS NUMBER + = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; }; + +Info_list: + Info_list Info + | + /* lambda */ + ; + +Info: + CSR NUMBER + = { cur.d_addr = $2; } | + DRIVE NUMBER + = { cur.d_drive = $2; } | + SLAVE NUMBER + = { + if (cur.d_conn != 0 && cur.d_conn != TO_NEXUS && + cur.d_conn->d_type == MASTER) + cur.d_slave = $2; + else + yyerror("can't specify slave--not to master"); + } | + IRQ NUMBER + = { cur.d_irq = $2; } | + DRQ NUMBER + = { cur.d_drq = $2; } | + IOMEM NUMBER + = { cur.d_maddr = $2; } | + IOSIZ NUMBER + = { cur.d_msize = $2; } | + PORT device_name + = { cur.d_port = ns($2); } | + PORT NUMBER + = { cur.d_portn = $2; } | + TTY + = { cur.d_mask = "tty"; } | + BIO + = { cur.d_mask = "bio"; } | + NET + = { cur.d_mask = "net"; } | + FLAGS NUMBER + = { cur.d_flags = $2; }; + +Int_spec: + VECTOR Id_list + = { cur.d_vec = $2; } | + PRIORITY NUMBER + = { cur.d_pri = $2; } | + /* lambda */ + ; + +Id_list: + Save_id + = { + struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst)); + a->id = $1; a->id_next = 0; $$ = a; + } | + Save_id Id_list = + { + struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst)); + a->id = $1; a->id_next = $2; $$ = a; + }; + +%% + +yyerror(s) + char *s; +{ + + fprintf(stderr, "config: line %d: %s\n", yyline + 1, s); +} + +/* + * return the passed string in a new space + */ +char * +ns(str) + register char *str; +{ + register char *cp; + + cp = malloc((unsigned)(strlen(str)+1)); + (void) strcpy(cp, str); + return (cp); +} + +/* + * add a device to the list of devices + */ +newdev(dp) + register struct device *dp; +{ + register struct device *np; + + np = (struct device *) malloc(sizeof *np); + *np = *dp; + np->d_next = 0; + if (curp == 0) + dtab = np; + else + curp->d_next = np; + curp = np; +} + +/* + * note that a configuration should be made + */ +mkconf(sysname) + char *sysname; +{ + register struct file_list *fl, **flp; + + fl = (struct file_list *) malloc(sizeof *fl); + fl->f_type = SYSTEMSPEC; + fl->f_needs = sysname; + fl->f_rootdev = NODEV; + fl->f_dumpdev = NODEV; + fl->f_fn = 0; + fl->f_next = 0; + for (flp = confp; *flp; flp = &(*flp)->f_next) + ; + *flp = fl; + confp = flp; +} + +struct file_list * +newflist(ftype) + u_char ftype; +{ + struct file_list *fl = (struct file_list *)malloc(sizeof (*fl)); + + fl->f_type = ftype; + fl->f_next = 0; + fl->f_swapdev = NODEV; + fl->f_swapsize = 0; + fl->f_needs = 0; + fl->f_fn = 0; + return (fl); +} + +/* + * Add a swap device to the system's configuration + */ +mkswap(system, fl, size, flag) + struct file_list *system, *fl; + int size, flag; +{ + register struct file_list **flp; + char name[80]; + + if (system == 0 || system->f_type != SYSTEMSPEC) { + yyerror("\"swap\" spec precedes \"config\" specification"); + return; + } + if (size < 0) { + yyerror("illegal swap partition size"); + return; + } + /* + * Append swap description to the end of the list. + */ + flp = &system->f_next; + for (; *flp && (*flp)->f_type == SWAPSPEC; flp = &(*flp)->f_next) + ; + fl->f_next = *flp; + *flp = fl; + fl->f_swapsize = size; + fl->f_swapflag = flag; + /* + * If first swap device for this system, + * set up f_fn field to insure swap + * files are created with unique names. + */ + if (system->f_fn) + return; + if (eq(fl->f_fn, "generic")) + system->f_fn = ns(fl->f_fn); + else + system->f_fn = ns(system->f_needs); +} + +mkcomp(dp) + register struct device *dp; +{ + register struct file_list *fl, **flp; + char buf[80]; + + fl = (struct file_list *) malloc(sizeof *fl); + fl->f_type = COMPDEVICE; + fl->f_compinfo = dp->d_unit; + fl->f_fn = ns(dp->d_name); + (void) sprintf(buf, "%s%d", dp->d_name, dp->d_unit); + fl->f_needs = ns(buf); + fl->f_next = 0; + for (flp = compp; *flp; flp = &(*flp)->f_next) + ; + *flp = fl; + compp = flp; +} + +addcomp(compdev, fl) + struct file_list *compdev, *fl; +{ + register struct file_list **flp; + char name[80]; + + if (compdev == 0 || compdev->f_type != COMPDEVICE) { + yyerror("component spec precedes device specification"); + return; + } + /* + * Append description to the end of the list. + */ + flp = &compdev->f_next; + for (; *flp && (*flp)->f_type == COMPSPEC; flp = &(*flp)->f_next) + ; + fl->f_next = *flp; + *flp = fl; +} + +/* + * find the pointer to connect to the given device and number. + * returns 0 if no such device and prints an error message + */ +struct device * +connect(dev, num) + register char *dev; + register int num; +{ + register struct device *dp; + struct device *huhcon(); + + if (num == QUES) + return (huhcon(dev)); + for (dp = dtab; dp != 0; dp = dp->d_next) { + if ((num != dp->d_unit) || !eq(dev, dp->d_name)) + continue; + if (dp->d_type != CONTROLLER && dp->d_type != MASTER) { + (void) sprintf(errbuf, + "%s connected to non-controller", dev); + yyerror(errbuf); + return (0); + } + return (dp); + } + (void) sprintf(errbuf, "%s %d not defined", dev, num); + yyerror(errbuf); + return (0); +} + +/* + * connect to an unspecific thing + */ +struct device * +huhcon(dev) + register char *dev; +{ + register struct device *dp, *dcp; + struct device rdev; + int oldtype; + + /* + * First make certain that there are some of these to wildcard on + */ + for (dp = dtab; dp != 0; dp = dp->d_next) + if (eq(dp->d_name, dev)) + break; + if (dp == 0) { + (void) sprintf(errbuf, "no %s's to wildcard", dev); + yyerror(errbuf); + return (0); + } + oldtype = dp->d_type; + dcp = dp->d_conn; + /* + * Now see if there is already a wildcard entry for this device + * (e.g. Search for a "uba ?") + */ + for (; dp != 0; dp = dp->d_next) + if (eq(dev, dp->d_name) && dp->d_unit == -1) + break; + /* + * If there isn't, make one because everything needs to be connected + * to something. + */ + if (dp == 0) { + dp = &rdev; + init_dev(dp); + dp->d_unit = QUES; + dp->d_name = ns(dev); + dp->d_type = oldtype; + newdev(dp); + dp = curp; + /* + * Connect it to the same thing that other similar things are + * connected to, but make sure it is a wildcard unit + * (e.g. up connected to sc ?, here we make connect sc? to a + * uba?). If other things like this are on the NEXUS or + * if they aren't connected to anything, then make the same + * connection, else call ourself to connect to another + * unspecific device. + */ + if (dcp == TO_NEXUS || dcp == 0) + dp->d_conn = dcp; + else + dp->d_conn = connect(dcp->d_name, QUES); + } + return (dp); +} + +init_dev(dp) + register struct device *dp; +{ + + dp->d_name = "OHNO!!!"; + dp->d_type = DEVICE; + dp->d_conn = 0; + dp->d_vec = 0; + dp->d_addr = dp->d_flags = dp->d_dk = 0; + dp->d_pri = -1; + dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN; + dp->d_port = (char *)0; + dp->d_portn = 0; + dp->d_irq = -1; + dp->d_drq = -1; + dp->d_maddr = 0; + dp->d_msize = 0; + dp->d_mask = "null"; +} + +/* + * make certain that this is a reasonable type of thing to connect to a nexus + */ +check_nexus(dev, num) + register struct device *dev; + int num; +{ + + switch (machine) { + + case MACHINE_VAX: + if (!eq(dev->d_name, "uba") && !eq(dev->d_name, "mba") && + !eq(dev->d_name, "bi")) + yyerror("only uba's, mba's, and bi's should be connected to the nexus"); + if (num != QUES) + yyerror("can't give specific nexus numbers"); + break; + + case MACHINE_TAHOE: + if (!eq(dev->d_name, "vba")) + yyerror("only vba's should be connected to the nexus"); + break; + + case MACHINE_HP300: + case MACHINE_LUNA68K: + if (num != QUES) + dev->d_addr = num; + break; + + case MACHINE_I386: + if (!eq(dev->d_name, "isa")) + yyerror("only isa's should be connected to the nexus"); + break; + + case MACHINE_NEWS3400: + if (!eq(dev->d_name, "iop") && !eq(dev->d_name, "hb") && + !eq(dev->d_name, "vme")) + yyerror("only iop's, hb's and vme's should be connected to the nexus"); + break; + } +} + +/* + * Check the timezone to make certain it is sensible + */ + +check_tz() +{ + if (abs(zone) > 12 * 60) + yyerror("timezone is unreasonable"); + else + hadtz = 1; +} + +/* + * Check system specification and apply defaulting + * rules on root, argument, dump, and swap devices. + */ +checksystemspec(fl) + register struct file_list *fl; +{ + char buf[BUFSIZ]; + register struct file_list *swap; + int generic; + + if (fl == 0 || fl->f_type != SYSTEMSPEC) { + yyerror("internal error, bad system specification"); + exit(1); + } + swap = fl->f_next; + generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic"); + if (fl->f_rootdev == NODEV && !generic) { + yyerror("no root device specified"); + exit(1); + } + /* + * Default swap area to be in 'b' partition of root's + * device. If root specified to be other than on 'a' + * partition, give warning, something probably amiss. + */ + if (swap == 0 || swap->f_type != SWAPSPEC) { + dev_t dev; + + swap = newflist(SWAPSPEC); + dev = fl->f_rootdev; + if (minor(dev) & 07) { + (void) sprintf(buf, +"Warning, swap defaulted to 'b' partition with root on '%c' partition", + (minor(dev) & 07) + 'a'); + yyerror(buf); + } + swap->f_swapdev = + makedev(major(dev), (minor(dev) &~ 07) | ('b' - 'a')); + swap->f_fn = devtoname(swap->f_swapdev); + mkswap(fl, swap, 0); + } + /* + * Make sure a generic swap isn't specified, along with + * other stuff (user must really be confused). + */ + if (generic) { + if (fl->f_rootdev != NODEV) + yyerror("root device specified with generic swap"); + if (fl->f_dumpdev != NODEV) + yyerror("dump device specified with generic swap"); + return; + } + /* + * Default dump device and warn if place is not a + * swap area. + */ + if (fl->f_dumpdev == NODEV) + fl->f_dumpdev = swap->f_swapdev; + if (fl->f_dumpdev != swap->f_swapdev) { + struct file_list *p = swap->f_next; + + for (; p && p->f_type == SWAPSPEC; p = p->f_next) + if (fl->f_dumpdev == p->f_swapdev) + return; + (void) sprintf(buf, + "Warning: dump device is not a swap partition"); + yyerror(buf); + } +} + +/* + * Verify all devices specified in the system specification + * are present in the device specifications. + */ +verifysystemspecs() +{ + register struct file_list *fl; + dev_t checked[50], *verifyswap(); + register dev_t *pchecked = checked; + + for (fl = conf_list; fl; fl = fl->f_next) { + if (fl->f_type != SYSTEMSPEC) + continue; + if (!finddev(fl->f_rootdev)) + deverror(fl->f_needs, "root"); + *pchecked++ = fl->f_rootdev; + pchecked = verifyswap(fl->f_next, checked, pchecked); +#define samedev(dev1, dev2) \ + ((minor(dev1) &~ 07) != (minor(dev2) &~ 07)) + if (!alreadychecked(fl->f_dumpdev, checked, pchecked)) { + if (!finddev(fl->f_dumpdev)) + deverror(fl->f_needs, "dump"); + *pchecked++ = fl->f_dumpdev; + } + } +} + +/* + * Do as above, but for swap devices. + */ +dev_t * +verifyswap(fl, checked, pchecked) + register struct file_list *fl; + dev_t checked[]; + register dev_t *pchecked; +{ + + for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) { + if (eq(fl->f_fn, "generic")) + continue; + if (alreadychecked(fl->f_swapdev, checked, pchecked)) + continue; + if (!finddev(fl->f_swapdev)) + fprintf(stderr, + "config: swap device %s not configured", fl->f_fn); + *pchecked++ = fl->f_swapdev; + } + return (pchecked); +} + +/* + * Verify that components of a compound device have themselves been config'ed + */ +verifycomp(fl) + register struct file_list *fl; +{ + char *dname = fl->f_needs; + + for (fl = fl->f_next; fl; fl = fl->f_next) { + if (fl->f_type != COMPSPEC || finddev(fl->f_compdev)) + continue; + fprintf(stderr, + "config: %s: component device %s not configured\n", + dname, fl->f_needs); + } +} + +/* + * Has a device already been checked + * for it's existence in the configuration? + */ +alreadychecked(dev, list, last) + dev_t dev, list[]; + register dev_t *last; +{ + register dev_t *p; + + for (p = list; p < last; p++) + if (samedev(*p, dev)) + return (1); + return (0); +} + +deverror(systemname, devtype) + char *systemname, *devtype; +{ + + fprintf(stderr, "config: %s: %s device not configured\n", + systemname, devtype); +} + +/* + * Look for the device in the list of + * configured hardware devices. Must + * take into account stuff wildcarded. + */ +/*ARGSUSED*/ +finddev(dev) + dev_t dev; +{ + + /* punt on this right now */ + return (1); +} diff --git a/usr.sbin/config/lang.l b/usr.sbin/config/lang.l new file mode 100644 index 0000000..535ffcd --- /dev/null +++ b/usr.sbin/config/lang.l @@ -0,0 +1,215 @@ +%{ +/*- + * Copyright (c) 1980, 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. + * + * @(#)lang.l 8.1 (Berkeley) 6/6/93 + */ + +#include +#include "y.tab.h" +#include "config.h" + +#define tprintf if (do_trace) printf + +/* + * Key word table + */ + +struct kt { + char *kt_name; + int kt_val; +} key_words[] = { + { "and", AND }, + { "args", ARGS }, + { "at", AT }, +#if MACHINE_I386 + { "bio", BIO }, +#endif MACHINE_I386 + { "config", CONFIG }, + { "controller", CONTROLLER }, + { "cpu", CPU }, + { "csr", CSR }, + { "device", DEVICE }, + { "disk", DISK }, + { "drive", DRIVE }, +#if MACHINE_I386 + { "drq", DRQ }, +#endif MACHINE_I386 + { "dst", DST }, + { "dumps", DUMPS }, + { "flags", FLAGS }, + { "hz", HZ }, + { "ident", IDENT }, + { "interleave", INTERLEAVE }, +#if MACHINE_I386 + { "iomem", IOMEM }, + { "iosiz", IOSIZ }, + { "irq", IRQ }, +#endif MACHINE_I386 + { "machine", MACHINE }, + { "major", MAJOR }, + { "makeoptions", MAKEOPTIONS }, + { "master", MASTER }, + { "maxusers", MAXUSERS }, + { "minor", MINOR }, +#if MACHINE_I386 + { "net", NET }, +#endif MACHINE_I386 + { "nexus", NEXUS }, + { "on", ON }, + { "options", OPTIONS }, +#if MACHINE_I386 + { "port", PORT }, +#endif MACHINE_I386 + { "priority", PRIORITY }, + { "pseudo-device",PSEUDO_DEVICE }, + { "root", ROOT }, +#if MACHINE_HP300 || MACHINE_LUNA68K + { "scode", NEXUS }, +#endif + { "sequential", SEQUENTIAL }, + { "size", SIZE }, + { "slave", SLAVE }, + { "swap", SWAP }, + { "tape", DEVICE }, +#if MACHINE_I386 + { "tty", TTY }, +#endif MACHINE_I386 + { "timezone", TIMEZONE }, + { "trace", TRACE }, + { "vector", VECTOR }, + { 0, 0 }, +}; +%} +WORD [A-Za-z_][-A-Za-z_]* +%% +{WORD} { + int i; + + if ((i = kw_lookup(yytext)) == -1) + { + yylval.str = yytext; + tprintf("id(%s) ", yytext); + return ID; + } + tprintf("(%s) ", yytext); + return i; + } +\"[^"]+\" { + yytext[strlen(yytext)-1] = '\0'; + yylval.str = yytext + 1; + return ID; + } +0[0-7]* { + yylval.val = octal(yytext); + tprintf("#O:%o ", yylval.val); + return NUMBER; + } +0x[0-9a-fA-F]+ { + yylval.val = hex(yytext); + tprintf("#X:%x ", yylval.val); + return NUMBER; + } +[1-9][0-9]* { + yylval.val = atoi(yytext); + tprintf("#D:%d ", yylval.val); + return NUMBER; + } +[0-9]"."[0-9]* { + double atof(); + yylval.val = (int) (60 * atof(yytext) + 0.5); + return FPNUMBER; + } +"-" { + return MINUS; + } +"?" { + yylval.val = -1; + tprintf("? "); + return NUMBER; + } +\n/[ \t] { + yyline++; + tprintf("\n... "); + } +\n { + yyline++; + tprintf("\n"); + return SEMICOLON; + } +#.* { /* Ignored (comment) */; } +[ \t]* { /* Ignored (white space) */; } +";" { return SEMICOLON; } +"," { return COMMA; } +"=" { return EQUALS; } +"@" { return AT; } +. { return yytext[0]; } + +%% +/* + * kw_lookup + * Look up a string in the keyword table. Returns a -1 if the + * string is not a keyword otherwise it returns the keyword number + */ + +kw_lookup(word) +register char *word; +{ + register struct kt *kp; + + for (kp = key_words; kp->kt_name != 0; kp++) + if (eq(word, kp->kt_name)) + return kp->kt_val; + return -1; +} + +/* + * Number conversion routines + */ + +octal(str) +char *str; +{ + int num; + + (void) sscanf(str, "%o", &num); + return num; +} + +hex(str) +char *str; +{ + int num; + + (void) sscanf(str+2, "%x", &num); + return num; +} diff --git a/usr.sbin/config/main.c b/usr.sbin/config/main.c new file mode 100644 index 0000000..37030f0 --- /dev/null +++ b/usr.sbin/config/main.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 1980, 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) 1980, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include "y.tab.h" +#include "config.h" + +static char *PREFIX; + +/* + * Config builds a set of files for building a UNIX + * system given a description of the desired system. + */ +main(argc, argv) + int argc; + char **argv; +{ + + extern char *optarg; + extern int optind; + struct stat buf; + int ch; + char *p; + + while ((ch = getopt(argc, argv, "gp")) != EOF) + switch (ch) { + case 'g': + debugging++; + break; + case 'p': + profiling++; + break; + case '?': + default: + goto usage; + } + argc -= optind; + argv += optind; + + if (argc != 1) { +usage: fputs("usage: config [-gp] sysname\n", stderr); + exit(1); + } + + if (freopen(PREFIX = *argv, "r", stdin) == NULL) { + perror(PREFIX); + exit(2); + } + if (stat(p = path((char *)NULL), &buf)) { + if (mkdir(p, 0777)) { + perror(p); + exit(2); + } + } + else if ((buf.st_mode & S_IFMT) != S_IFDIR) { + fprintf(stderr, "config: %s isn't a directory.\n", p); + exit(2); + } + + dtab = NULL; + confp = &conf_list; + compp = &comp_list; + if (yyparse()) + exit(3); + switch (machine) { + + case MACHINE_VAX: + vax_ioconf(); /* Print ioconf.c */ + ubglue(); /* Create ubglue.s */ + break; + + case MACHINE_TAHOE: + tahoe_ioconf(); + vbglue(); + break; + + case MACHINE_HP300: + case MACHINE_LUNA68K: + hp300_ioconf(); + hpglue(); + break; + + case MACHINE_I386: + i386_ioconf(); /* Print ioconf.c */ + vector(); /* Create vector.s */ + break; + + case MACHINE_MIPS: + case MACHINE_PMAX: + pmax_ioconf(); + break; + + case MACHINE_NEWS3400: + news_ioconf(); + break; + + default: + printf("Specify machine type, e.g. ``machine vax''\n"); + exit(1); + } + /* + * make symbolic links in compilation directory + * for "sys" (to make genassym.c work along with #include ) + * and similarly for "machine". + */ + { + char xxx[80]; + + (void) sprintf(xxx, "../../%s/include", machinename); + (void) symlink(xxx, path("machine")); + } + makefile(); /* build Makefile */ + headers(); /* make a lot of .h files */ + swapconf(); /* swap config files */ + printf("Don't forget to run \"make depend\"\n"); + exit(0); +} + +/* + * get_word + * returns EOF on end of file + * NULL on end of line + * pointer to the word otherwise + */ +char * +get_word(fp) + register FILE *fp; +{ + static char line[80]; + register int ch; + register char *cp; + + while ((ch = getc(fp)) != EOF) + if (ch != ' ' && ch != '\t') + break; + if (ch == EOF) + return ((char *)EOF); + if (ch == '\n') + return (NULL); + cp = line; + *cp++ = ch; + while ((ch = getc(fp)) != EOF) { + if (isspace(ch)) + break; + *cp++ = ch; + } + *cp = 0; + if (ch == EOF) + return ((char *)EOF); + (void) ungetc(ch, fp); + return (line); +} + +/* + * get_quoted_word + * like get_word but will accept something in double or single quotes + * (to allow embedded spaces). + */ +char * +get_quoted_word(fp) + register FILE *fp; +{ + static char line[256]; + register int ch; + register char *cp; + + while ((ch = getc(fp)) != EOF) + if (ch != ' ' && ch != '\t') + break; + if (ch == EOF) + return ((char *)EOF); + if (ch == '\n') + return (NULL); + cp = line; + if (ch == '"' || ch == '\'') { + register int quote = ch; + + while ((ch = getc(fp)) != EOF) { + if (ch == quote) + break; + if (ch == '\n') { + *cp = 0; + printf("config: missing quote reading `%s'\n", + line); + exit(2); + } + *cp++ = ch; + } + } else { + *cp++ = ch; + while ((ch = getc(fp)) != EOF) { + if (isspace(ch)) + break; + *cp++ = ch; + } + if (ch != EOF) + (void) ungetc(ch, fp); + } + *cp = 0; + if (ch == EOF) + return ((char *)EOF); + return (line); +} + +/* + * prepend the path to a filename + */ +char * +path(file) + char *file; +{ + register char *cp; + +#define CDIR "../../compile/" + cp = malloc((unsigned int)(sizeof(CDIR) + strlen(PREFIX) + + (file ? strlen(file) : 0) + 2)); + (void) strcpy(cp, CDIR); + (void) strcat(cp, PREFIX); + if (file) { + (void) strcat(cp, "/"); + (void) strcat(cp, file); + } + return (cp); +} diff --git a/usr.sbin/config/mkglue.c b/usr.sbin/config/mkglue.c new file mode 100644 index 0000000..e738515 --- /dev/null +++ b/usr.sbin/config/mkglue.c @@ -0,0 +1,400 @@ +/* + * Copyright (c) 1980, 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[] = "@(#)mkglue.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Make the bus adaptor interrupt glue files. + */ +#include +#include "config.h" +#include "y.tab.h" +#include + +/* + * Create the UNIBUS interrupt vector glue file. + */ +ubglue() +{ + register FILE *fp, *gp; + register struct device *dp, *mp; + + fp = fopen(path("ubglue.s"), "w"); + if (fp == 0) { + perror(path("ubglue.s")); + exit(1); + } + gp = fopen(path("ubvec.s"), "w"); + if (gp == 0) { + perror(path("ubvec.s")); + exit(1); + } + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (mp != 0 && mp != (struct device *)-1 && + !eq(mp->d_name, "mba")) { + struct idlst *id, *id2; + + for (id = dp->d_vec; id; id = id->id_next) { + for (id2 = dp->d_vec; id2; id2 = id2->id_next) { + if (id2 == id) { + dump_ubavec(fp, id->id, + dp->d_unit); + break; + } + if (!strcmp(id->id, id2->id)) + break; + } + } + } + } + dump_std(fp, gp); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (mp != 0 && mp != (struct device *)-1 && + !eq(mp->d_name, "mba")) { + struct idlst *id, *id2; + + for (id = dp->d_vec; id; id = id->id_next) { + for (id2 = dp->d_vec; id2; id2 = id2->id_next) { + if (id2 == id) { + dump_intname(fp, id->id, + dp->d_unit); + break; + } + if (!strcmp(id->id, id2->id)) + break; + } + } + } + } + dump_ctrs(fp); + (void) fclose(fp); + (void) fclose(gp); +} + +static int cntcnt = 0; /* number of interrupt counters allocated */ + +/* + * Print a UNIBUS interrupt vector. + */ +dump_ubavec(fp, vector, number) + register FILE *fp; + char *vector; + int number; +{ + char nbuf[80]; + register char *v = nbuf; + + (void) sprintf(v, "%s%d", vector, number); + fprintf(fp, "\t.globl\t_X%s\n\t.align\t2\n_X%s:\n\tpushr\t$0x3f\n", + v, v); + fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++); + if (strncmp(vector, "dzx", 3) == 0) + fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdzdma\n\n", number); + else if (strncmp(vector, "dpx", 3) == 0) + fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdpxdma\n\n", number); + else if (strncmp(vector, "dpr", 3) == 0) + fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdprdma\n\n", number); + else { + if (strncmp(vector, "uur", 3) == 0) { + fprintf(fp, "#ifdef UUDMA\n"); + fprintf(fp, "\tmovl\t$%d,r0\n\tjsb\tuudma\n", number); + fprintf(fp, "#endif\n"); + } + fprintf(fp, "\tpushl\t$%d\n", number); + fprintf(fp, "\tcalls\t$1,_%s\n\tpopr\t$0x3f\n", vector); + fprintf(fp, "\tincl\t_cnt+V_INTR\n\trei\n\n"); + } +} + +/* + * Create the VERSAbus interrupt vector glue file. + */ +vbglue() +{ + register FILE *fp, *gp; + register struct device *dp, *mp; + + fp = fopen(path("vbglue.s"), "w"); + if (fp == 0) { + perror(path("vbglue.s")); + exit(1); + } + gp = fopen(path("vbvec.s"), "w"); + if (gp == 0) { + perror(path("vbvec.s")); + exit(1); + } + for (dp = dtab; dp != 0; dp = dp->d_next) { + struct idlst *id, *id2; + + mp = dp->d_conn; + if (mp == 0 || mp == (struct device *)-1 || + eq(mp->d_name, "mba")) + continue; + for (id = dp->d_vec; id; id = id->id_next) + for (id2 = dp->d_vec; id2; id2 = id2->id_next) { + if (id == id2) { + dump_vbavec(fp, id->id, dp->d_unit); + break; + } + if (eq(id->id, id2->id)) + break; + } + } + dump_std(fp, gp); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (mp != 0 && mp != (struct device *)-1 && + !eq(mp->d_name, "mba")) { + struct idlst *id, *id2; + + for (id = dp->d_vec; id; id = id->id_next) { + for (id2 = dp->d_vec; id2; id2 = id2->id_next) { + if (id2 == id) { + dump_intname(fp, id->id, + dp->d_unit); + break; + } + if (eq(id->id, id2->id)) + break; + } + } + } + } + dump_ctrs(fp); + (void) fclose(fp); + (void) fclose(gp); +} + +/* + * Print a VERSAbus interrupt vector + */ +dump_vbavec(fp, vector, number) + register FILE *fp; + char *vector; + int number; +{ + char nbuf[80]; + register char *v = nbuf; + + (void) sprintf(v, "%s%d", vector, number); + fprintf(fp, "SCBVEC(%s):\n", v); + fprintf(fp, "\tCHECK_SFE(4)\n"); + fprintf(fp, "\tSAVE_FPSTAT(4)\n"); + fprintf(fp, "\tPUSHR\n"); + fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++); + fprintf(fp, "\tpushl\t$%d\n", number); + fprintf(fp, "\tcallf\t$8,_%s\n", vector); + fprintf(fp, "\tincl\t_cnt+V_INTR\n"); + fprintf(fp, "\tPOPR\n"); + fprintf(fp, "\tREST_FPSTAT\n"); + fprintf(fp, "\trei\n\n"); +} + +/* + * HP9000/300 interrupts are auto-vectored. + * Code is hardwired in locore.s + */ +hpglue() {} + +static char *vaxinames[] = { + "clock", "cnr", "cnx", "tur", "tux", + "mba0", "mba1", "mba2", "mba3", + "uba0", "uba1", "uba2", "uba3" +}; +static char *tahoeinames[] = { + "clock", "cnr", "cnx", "rmtr", "rmtx", "buserr", +}; +static struct stdintrs { + char **si_names; /* list of standard interrupt names */ + int si_n; /* number of such names */ +} stdintrs[] = { + { vaxinames, sizeof (vaxinames) / sizeof (vaxinames[0]) }, + { tahoeinames, (sizeof (tahoeinames) / sizeof (tahoeinames[0])) } +}; +/* + * Start the interrupt name table with the names + * of the standard vectors not directly associated + * with a bus. Also, dump the defines needed to + * reference the associated counters into a separate + * file which is prepended to locore.s. + */ +dump_std(fp, gp) + register FILE *fp, *gp; +{ + register struct stdintrs *si = &stdintrs[machine-1]; + register char **cpp; + register int i; + + fprintf(fp, "\n\t.globl\t_intrnames\n"); + fprintf(fp, "\n\t.globl\t_eintrnames\n"); + fprintf(fp, "\t.data\n"); + fprintf(fp, "_intrnames:\n"); + cpp = si->si_names; + for (i = 0; i < si->si_n; i++) { + register char *cp, *tp; + char buf[80]; + + cp = *cpp; + if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') { + cp += 3; + if (*cp == 'r') + cp++; + } + for (tp = buf; *cp; cp++) + if (islower(*cp)) + *tp++ = toupper(*cp); + else + *tp++ = *cp; + *tp = '\0'; + fprintf(gp, "#define\tI_%s\t%d\n", buf, i*sizeof (long)); + fprintf(fp, "\t.asciz\t\"%s\"\n", *cpp); + cpp++; + } +} + +dump_intname(fp, vector, number) + register FILE *fp; + char *vector; + int number; +{ + register char *cp = vector; + + fprintf(fp, "\t.asciz\t\""); + /* + * Skip any "int" or "intr" in the name. + */ + while (*cp) + if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') { + cp += 3; + if (*cp == 'r') + cp++; + } else { + putc(*cp, fp); + cp++; + } + fprintf(fp, "%d\"\n", number); +} + +/* + * Reserve space for the interrupt counters. + */ +dump_ctrs(fp) + register FILE *fp; +{ + struct stdintrs *si = &stdintrs[machine-1]; + + fprintf(fp, "_eintrnames:\n"); + fprintf(fp, "\n\t.globl\t_intrcnt\n"); + fprintf(fp, "\n\t.globl\t_eintrcnt\n"); + fprintf(fp, "\t.align 2\n"); + fprintf(fp, "_intrcnt:\n"); + fprintf(fp, "\t.space\t4 * %d\n", si->si_n); + fprintf(fp, "_fltintrcnt:\n"); + fprintf(fp, "\t.space\t4 * %d\n", cntcnt); + fprintf(fp, "_eintrcnt:\n\n"); + fprintf(fp, "\t.text\n"); +} + +/* + * Create the ISA interrupt vector glue file. + */ +vector() { + register FILE *fp, *gp; + register struct device *dp, *mp; + int count; + + fp = fopen(path("vector.s"), "w"); + if (fp == 0) { + perror(path("vector.s")); + exit(1); + } + fprintf(fp,"\ +/*\n\ + * AT/386\n\ + * Interrupt vector routines\n\ + * Generated by config program\n\ + */ \n\ +\n\ +#include \"i386/isa/isa.h\"\n\ +#include \"i386/isa/icu.h\"\n\ +\n\ +#define VEC(name) .align 4; .globl _V/**/name; _V/**/name:\n\n"); + + fprintf(fp,"\ + .globl _hardclock\n\ +VEC(clk)\n\ + INTR1(0, _highmask, 0)\n\ + call _hardclock \n\ + INTREXIT1\n\n\n"); + + count=0; + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (mp != 0 && /* mp != (struct device *)-1 &&*/ + eq(mp->d_name, "isa")) { + struct idlst *id, *id2; + + for (id = dp->d_vec; id; id = id->id_next) { + for (id2 = dp->d_vec; id2; id2 = id2->id_next) { + if (id2 == id) { + if(dp->d_irq == -1) continue; + fprintf(fp,"\t.globl _%s, _%s%dmask\n\t.data\n", + id->id, dp->d_name, dp->d_unit); + fprintf(fp,"_%s%dmask:\t.long 0\n\t.text\n", + dp->d_name, dp->d_unit); + fprintf(fp,"VEC(%s%d)\n\tINTR%d(%d, ", + dp->d_name, dp->d_unit, + dp->d_irq / 8 + 1, dp->d_unit); + if(eq(dp->d_mask,"null")) + fprintf(fp,"_%s%dmask, ", + dp->d_name, dp->d_unit); + else + fprintf(fp,"_%smask, ", + dp->d_mask); + fprintf(fp,"%d)\n\tcall\t_%s\n\tINTREXIT%d\n\n\n", + ++count, id->id, (dp->d_irq > 7)?2:1); + break; + } + if (!strcmp(id->id, id2->id)) + break; + } + } + } + } + (void) fclose(fp); +} diff --git a/usr.sbin/config/mkheaders.c b/usr.sbin/config/mkheaders.c new file mode 100644 index 0000000..7929987 --- /dev/null +++ b/usr.sbin/config/mkheaders.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 1980, 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[] = "@(#)mkheaders.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Make all the .h files for the optional entries + */ + +#include +#include +#include "config.h" +#include "y.tab.h" + +headers() +{ + register struct file_list *fl; + + for (fl = ftab; fl != 0; fl = fl->f_next) + if (fl->f_needs != 0) + do_count(fl->f_needs, fl->f_needs, 1); +} + +/* + * count all the devices of a certain type and recurse to count + * whatever the device is connected to + */ +do_count(dev, hname, search) + register char *dev, *hname; + int search; +{ + register struct device *dp, *mp; + register int count, hicount; + + /* + * After this loop, "count" will be the actual number of units, + * and "hicount" will be the highest unit declared. do_header() + * must use this higher of these values. + */ + for (hicount = count = 0, dp = dtab; dp != 0; dp = dp->d_next) + if (dp->d_unit != -1 && eq(dp->d_name, dev)) { + if (dp->d_type == PSEUDO_DEVICE) { + count = + dp->d_slave != UNKNOWN ? dp->d_slave : 1; + break; + } + count++; + /* + * Allow holes in unit numbering, + * assumption is unit numbering starts + * at zero. + */ + if (dp->d_unit + 1 > hicount) + hicount = dp->d_unit + 1; + if (search) { + mp = dp->d_conn; + if (mp != 0 && mp != TO_NEXUS && + mp->d_conn != 0 && mp->d_conn != TO_NEXUS) { + do_count(mp->d_name, hname, 0); + search = 0; + } + } + } + do_header(dev, hname, count > hicount ? count : hicount); +} + +do_header(dev, hname, count) + char *dev, *hname; + int count; +{ + char *file, *name, *inw, *toheader(), *tomacro(); + struct file_list *fl, *fl_head, *tflp; + FILE *inf, *outf; + int inc, oldcount; + + file = toheader(hname); + name = tomacro(dev); + inf = fopen(file, "r"); + oldcount = -1; + if (inf == 0) { + outf = fopen(file, "w"); + if (outf == 0) { + perror(file); + exit(1); + } + fprintf(outf, "#define %s %d\n", name, count); + (void) fclose(outf); + return; + } + fl_head = NULL; + for (;;) { + char *cp; + if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) + break; + if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) + break; + inw = ns(inw); + cp = get_word(inf); + if (cp == 0 || cp == (char *)EOF) + break; + inc = atoi(cp); + if (eq(inw, name)) { + oldcount = inc; + inc = count; + } + cp = get_word(inf); + if (cp == (char *)EOF) + break; + fl = (struct file_list *) malloc(sizeof *fl); + bzero(fl, sizeof(*fl)); + fl->f_fn = inw; + fl->f_type = inc; + fl->f_next = fl_head; + fl_head = fl; + } + (void) fclose(inf); + if (count == oldcount) { + for (fl = fl_head; fl != NULL; fl = tflp) { + tflp = fl->f_next; + free(fl); + } + return; + } + if (oldcount == -1) { + fl = (struct file_list *) malloc(sizeof *fl); + bzero(fl, sizeof(*fl)); + fl->f_fn = name; + fl->f_type = count; + fl->f_next = fl_head; + fl_head = fl; + } + outf = fopen(file, "w"); + if (outf == 0) { + perror(file); + exit(1); + } + for (fl = fl_head; fl != NULL; fl = tflp) { + fprintf(outf, + "#define %s %u\n", fl->f_fn, count ? fl->f_type : 0); + tflp = fl->f_next; + free(fl); + } + (void) fclose(outf); +} + +/* + * convert a dev name to a .h file name + */ +char * +toheader(dev) + char *dev; +{ + static char hbuf[80]; + + (void) strcpy(hbuf, path(dev)); + (void) strcat(hbuf, ".h"); + return (hbuf); +} + +/* + * convert a dev name to a macro name + */ +char *tomacro(dev) + register char *dev; +{ + static char mbuf[20]; + register char *cp; + + cp = mbuf; + *cp++ = 'N'; + while (*dev) + *cp++ = islower(*dev) ? toupper(*dev++) : *dev++; + *cp++ = 0; + return (mbuf); +} diff --git a/usr.sbin/config/mkioconf.c b/usr.sbin/config/mkioconf.c new file mode 100644 index 0000000..394ca7e --- /dev/null +++ b/usr.sbin/config/mkioconf.c @@ -0,0 +1,1085 @@ +/* + * Copyright (c) 1980, 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[] = "@(#)mkioconf.c 8.2 (Berkeley) 1/21/94"; +#endif /* not lint */ + +#include +#include "y.tab.h" +#include "config.h" + +/* + * build the ioconf.c file + */ +char *qu(); +char *intv(); +char *wnum(); +void pseudo_ioconf(); + +#if MACHINE_VAX +vax_ioconf() +{ + register struct device *dp, *mp, *np; + register int uba_n, slave; + FILE *fp; + + fp = fopen(path("ioconf.c"), "w"); + if (fp == 0) { + perror(path("ioconf.c")); + exit(1); + } + fprintf(fp, "#include \"vax/include/pte.h\"\n"); + fprintf(fp, "#include \"sys/param.h\"\n"); + fprintf(fp, "#include \"sys/buf.h\"\n"); + fprintf(fp, "#include \"sys/map.h\"\n"); + fprintf(fp, "\n"); + fprintf(fp, "#include \"vax/mba/mbavar.h\"\n"); + fprintf(fp, "#include \"vax/uba/ubavar.h\"\n\n"); + fprintf(fp, "\n"); + fprintf(fp, "#define C (caddr_t)\n\n"); + /* + * First print the mba initialization structures + */ + if (seen_mba) { + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (mp == 0 || mp == TO_NEXUS || + !eq(mp->d_name, "mba")) + continue; + fprintf(fp, "extern struct mba_driver %sdriver;\n", + dp->d_name); + } + fprintf(fp, "\nstruct mba_device mbdinit[] = {\n"); + fprintf(fp, "\t/* Device, Unit, Mba, Drive, Dk */\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (dp->d_unit == QUES || mp == 0 || + mp == TO_NEXUS || !eq(mp->d_name, "mba")) + continue; + if (dp->d_addr) { + printf("can't specify csr address on mba for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_vec != 0) { + printf("can't specify vector for %s%d on mba\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_drive == UNKNOWN) { + printf("drive not specified for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_slave != UNKNOWN) { + printf("can't specify slave number for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + fprintf(fp, "\t{ &%sdriver, %d, %s,", + dp->d_name, dp->d_unit, qu(mp->d_unit)); + fprintf(fp, " %s, %d },\n", + qu(dp->d_drive), dp->d_dk); + } + fprintf(fp, "\t0\n};\n\n"); + /* + * Print the mbsinit structure + * Driver Controller Unit Slave + */ + fprintf(fp, "struct mba_slave mbsinit [] = {\n"); + fprintf(fp, "\t/* Driver, Ctlr, Unit, Slave */\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + /* + * All slaves are connected to something which + * is connected to the massbus. + */ + if ((mp = dp->d_conn) == 0 || mp == TO_NEXUS) + continue; + np = mp->d_conn; + if (np == 0 || np == TO_NEXUS || + !eq(np->d_name, "mba")) + continue; + fprintf(fp, "\t{ &%sdriver, %s", + mp->d_name, qu(mp->d_unit)); + fprintf(fp, ", %2d, %s },\n", + dp->d_unit, qu(dp->d_slave)); + } + fprintf(fp, "\t0\n};\n\n"); + } + /* + * Now generate interrupt vectors for the unibus + */ + for (dp = dtab; dp != 0; dp = dp->d_next) { + if (dp->d_vec != 0) { + struct idlst *ip; + mp = dp->d_conn; + if (mp == 0 || mp == TO_NEXUS || + (!eq(mp->d_name, "uba") && !eq(mp->d_name, "bi"))) + continue; + fprintf(fp, + "extern struct uba_driver %sdriver;\n", + dp->d_name); + fprintf(fp, "extern "); + ip = dp->d_vec; + for (;;) { + fprintf(fp, "X%s%d()", ip->id, dp->d_unit); + ip = ip->id_next; + if (ip == 0) + break; + fprintf(fp, ", "); + } + fprintf(fp, ";\n"); + fprintf(fp, "int\t (*%sint%d[])() = { ", dp->d_name, + dp->d_unit); + ip = dp->d_vec; + for (;;) { + fprintf(fp, "X%s%d", ip->id, dp->d_unit); + ip = ip->id_next; + if (ip == 0) + break; + fprintf(fp, ", "); + } + fprintf(fp, ", 0 } ;\n"); + } + } + fprintf(fp, "\nstruct uba_ctlr ubminit[] = {\n"); + fprintf(fp, "/*\t driver,\tctlr,\tubanum,\talive,\tintr,\taddr */\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 || + !eq(mp->d_name, "uba")) + continue; + if (dp->d_vec == 0) { + printf("must specify vector for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_addr == 0) { + printf("must specify csr address for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { + printf("drives need their own entries; dont "); + printf("specify drive or slave for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_flags) { + printf("controllers (e.g. %s%d) ", + dp->d_name, dp->d_unit); + printf("don't have flags, only devices do\n"); + continue; + } + fprintf(fp, + "\t{ &%sdriver,\t%d,\t%s,\t0,\t%sint%d, C 0%o },\n", + dp->d_name, dp->d_unit, qu(mp->d_unit), + dp->d_name, dp->d_unit, dp->d_addr); + } + fprintf(fp, "\t0\n};\n"); +/* unibus devices */ + fprintf(fp, "\nstruct uba_device ubdinit[] = {\n"); + fprintf(fp, +"\t/* driver, unit, ctlr, ubanum, slave, intr, addr, dk, flags*/\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 || + mp == TO_NEXUS || mp->d_type == MASTER || + eq(mp->d_name, "mba")) + continue; + np = mp->d_conn; + if (np != 0 && np != TO_NEXUS && eq(np->d_name, "mba")) + continue; + np = 0; + if (eq(mp->d_name, "uba")) { + if (dp->d_vec == 0) { + printf("must specify vector for device %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_addr == 0) { + printf("must specify csr for device %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { + printf("drives/slaves can be specified "); + printf("only for controllers, "); + printf("not for device %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + uba_n = mp->d_unit; + slave = QUES; + } else { + if ((np = mp->d_conn) == 0) { + printf("%s%d isn't connected to anything ", + mp->d_name, mp->d_unit); + printf(", so %s%d is unattached\n", + dp->d_name, dp->d_unit); + continue; + } + uba_n = np->d_unit; + if (dp->d_drive == UNKNOWN) { + printf("must specify ``drive number'' "); + printf("for %s%d\n", dp->d_name, dp->d_unit); + continue; + } + /* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */ + /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */ + if (dp->d_slave != UNKNOWN) { + printf("slave numbers should be given only "); + printf("for massbus tapes, not for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_vec != 0) { + printf("interrupt vectors should not be "); + printf("given for drive %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_addr != 0) { + printf("csr addresses should be given only "); + printf("on controllers, not on %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + slave = dp->d_drive; + } + fprintf(fp, "\t{ &%sdriver, %2d, %s,", + eq(mp->d_name, "uba") ? dp->d_name : mp->d_name, dp->d_unit, + eq(mp->d_name, "uba") ? " -1" : qu(mp->d_unit)); + fprintf(fp, " %s, %2d, %s, C 0%-6o, %d, 0x%x },\n", + qu(uba_n), slave, intv(dp), dp->d_addr, dp->d_dk, + dp->d_flags); + } + fprintf(fp, "\t0\n};\n"); + pseudo_ioconf(fp); + (void) fclose(fp); +} +#endif + +#if MACHINE_TAHOE +tahoe_ioconf() +{ + register struct device *dp, *mp, *np; + register int vba_n, slave; + FILE *fp; + + fp = fopen(path("ioconf.c"), "w"); + if (fp == 0) { + perror(path("ioconf.c")); + exit(1); + } + fprintf(fp, "#include \"sys/param.h\"\n"); + fprintf(fp, "#include \"tahoe/include/pte.h\"\n"); + fprintf(fp, "#include \"sys/buf.h\"\n"); + fprintf(fp, "#include \"sys/map.h\"\n"); + fprintf(fp, "\n"); + fprintf(fp, "#include \"tahoe/vba/vbavar.h\"\n"); + fprintf(fp, "\n"); + fprintf(fp, "#define C (caddr_t)\n\n"); + /* + * Now generate interrupt vectors for the versabus + */ + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (mp == 0 || mp == TO_NEXUS || !eq(mp->d_name, "vba")) + continue; + if (dp->d_vec != 0) { + struct idlst *ip; + fprintf(fp, + "extern struct vba_driver %sdriver;\n", + dp->d_name); + fprintf(fp, "extern "); + ip = dp->d_vec; + for (;;) { + fprintf(fp, "X%s%d()", ip->id, dp->d_unit); + ip = ip->id_next; + if (ip == 0) + break; + fprintf(fp, ", "); + } + fprintf(fp, ";\n"); + fprintf(fp, "int\t (*%sint%d[])() = { ", dp->d_name, + dp->d_unit); + ip = dp->d_vec; + for (;;) { + fprintf(fp, "X%s%d", ip->id, dp->d_unit); + ip = ip->id_next; + if (ip == 0) + break; + fprintf(fp, ", "); + } + fprintf(fp, ", 0 } ;\n"); + } else if (dp->d_type == DRIVER) /* devices w/o interrupts */ + fprintf(fp, + "extern struct vba_driver %sdriver;\n", + dp->d_name); + } + fprintf(fp, "\nstruct vba_ctlr vbminit[] = {\n"); + fprintf(fp, "/*\t driver,\tctlr,\tvbanum,\talive,\tintr,\taddr */\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 || + !eq(mp->d_name, "vba")) + continue; + if (dp->d_vec == 0) { + printf("must specify vector for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_addr == 0) { + printf("must specify csr address for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { + printf("drives need their own entries; dont "); + printf("specify drive or slave for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_flags) { + printf("controllers (e.g. %s%d) ", + dp->d_name, dp->d_unit); + printf("don't have flags, only devices do\n"); + continue; + } + fprintf(fp, + "\t{ &%sdriver,\t%d,\t%s,\t0,\t%sint%d, C 0x%x },\n", + dp->d_name, dp->d_unit, qu(mp->d_unit), + dp->d_name, dp->d_unit, dp->d_addr); + } + fprintf(fp, "\t0\n};\n"); +/* versabus devices */ + fprintf(fp, "\nstruct vba_device vbdinit[] = {\n"); + fprintf(fp, +"\t/* driver, unit, ctlr, vbanum, slave, intr, addr, dk, flags*/\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 || + mp == TO_NEXUS || mp->d_type == MASTER || + eq(mp->d_name, "mba")) + continue; + np = mp->d_conn; + if (np != 0 && np != TO_NEXUS && eq(np->d_name, "mba")) + continue; + np = 0; + if (eq(mp->d_name, "vba")) { + if (dp->d_vec == 0) + printf( + "Warning, no interrupt vector specified for device %s%d\n", + dp->d_name, dp->d_unit); + if (dp->d_addr == 0) { + printf("must specify csr for device %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { + printf("drives/slaves can be specified "); + printf("only for controllers, "); + printf("not for device %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + vba_n = mp->d_unit; + slave = QUES; + } else { + if ((np = mp->d_conn) == 0) { + printf("%s%d isn't connected to anything ", + mp->d_name, mp->d_unit); + printf(", so %s%d is unattached\n", + dp->d_name, dp->d_unit); + continue; + } + vba_n = np->d_unit; + if (dp->d_drive == UNKNOWN) { + printf("must specify ``drive number'' "); + printf("for %s%d\n", dp->d_name, dp->d_unit); + continue; + } + /* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */ + /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */ + if (dp->d_slave != UNKNOWN) { + printf("slave numbers should be given only "); + printf("for massbus tapes, not for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_vec != 0) { + printf("interrupt vectors should not be "); + printf("given for drive %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_addr != 0) { + printf("csr addresses should be given only "); + printf("on controllers, not on %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + slave = dp->d_drive; + } + fprintf(fp, "\t{ &%sdriver, %2d, %s,", + eq(mp->d_name, "vba") ? dp->d_name : mp->d_name, dp->d_unit, + eq(mp->d_name, "vba") ? " -1" : qu(mp->d_unit)); + fprintf(fp, " %s, %2d, %s, C 0x%-6x, %d, 0x%x },\n", + qu(vba_n), slave, intv(dp), dp->d_addr, dp->d_dk, + dp->d_flags); + } + fprintf(fp, "\t0\n};\n"); + pseudo_ioconf(fp); + (void) fclose(fp); +} +#endif + +#if MACHINE_HP300 || MACHINE_LUNA68K +hp300_ioconf() +{ + register struct device *dp, *mp; + register int hpib, slave; + FILE *fp; + + fp = fopen(path("ioconf.c"), "w"); + if (fp == 0) { + perror(path("ioconf.c")); + exit(1); + } + fprintf(fp, "#include \"sys/param.h\"\n"); + fprintf(fp, "#include \"sys/buf.h\"\n"); + fprintf(fp, "#include \"sys/map.h\"\n"); + fprintf(fp, "\n"); + if (machine == MACHINE_HP300) + fprintf(fp, "#include \"hp/dev/device.h\"\n\n"); + else + fprintf(fp, "#include \"luna68k/dev/device.h\"\n\n"); + fprintf(fp, "\n"); + fprintf(fp, "#define C (caddr_t)\n"); + fprintf(fp, "#define D (struct driver *)\n\n"); + /* + * First print the hpib controller initialization structures + */ + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (dp->d_unit == QUES || mp == 0) + continue; + fprintf(fp, "extern struct driver %sdriver;\n", dp->d_name); + } + fprintf(fp, "\nstruct hp_ctlr hp_cinit[] = {\n"); + fprintf(fp, "/*\tdriver,\t\tunit,\talive,\taddr,\tflags */\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (dp->d_unit == QUES || + dp->d_type != MASTER && dp->d_type != CONTROLLER) + continue; + if (mp != TO_NEXUS) { + printf("%s%s must be attached to an sc (nexus)\n", + dp->d_name, wnum(dp->d_unit)); + continue; + } + if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { + printf("can't specify drive/slave for %s%s\n", + dp->d_name, wnum(dp->d_unit)); + continue; + } + fprintf(fp, + "\t{ &%sdriver,\t%d,\t0,\tC 0x%x,\t0x%x },\n", + dp->d_name, dp->d_unit, dp->d_addr, dp->d_flags); + } + fprintf(fp, "\t0\n};\n"); +/* devices */ + fprintf(fp, "\nstruct hp_device hp_dinit[] = {\n"); + fprintf(fp, + "/*driver,\tcdriver,\tunit,\tctlr,\tslave,\taddr,\tdk,\tflags*/\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (mp == 0 || dp->d_type != DEVICE || hpbadslave(mp, dp)) + continue; + if (mp == TO_NEXUS) { + if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { + printf("can't specify drive/slave for %s%s\n", + dp->d_name, wnum(dp->d_unit)); + continue; + } + slave = QUES; + hpib = QUES; + } else { + if (dp->d_addr != 0) { + printf("can't specify sc for device %s%s\n", + dp->d_name, wnum(dp->d_unit)); + continue; + } + if (mp->d_type == CONTROLLER) { + if (dp->d_drive == UNKNOWN) { + printf("must specify drive for %s%s\n", + dp->d_name, wnum(dp->d_unit)); + continue; + } + slave = dp->d_drive; + } else { + if (dp->d_slave == UNKNOWN) { + printf("must specify slave for %s%s\n", + dp->d_name, wnum(dp->d_unit)); + continue; + } + slave = dp->d_slave; + } + hpib = mp->d_unit; + } + fprintf(fp, "{ &%sdriver,\t", dp->d_name); + if (mp == TO_NEXUS) + fprintf(fp, "D 0x0,\t"); + else + fprintf(fp, "&%sdriver,", mp->d_name); + fprintf(fp, "\t%d,\t%d,\t%d,\tC 0x%x,\t%d,\t0x%x },\n", + dp->d_unit, hpib, slave, + dp->d_addr, dp->d_dk, dp->d_flags); + } + fprintf(fp, "0\n};\n"); + pseudo_ioconf(fp); + (void) fclose(fp); +} + +#define ishpibdev(n) (eq(n,"rd") || eq(n,"ct") || eq(n,"mt") || eq(n,"ppi")) +#define isscsidev(n) (eq(n,"sd") || eq(n,"st") || eq(n,"ac")) + +hpbadslave(mp, dp) + register struct device *dp, *mp; +{ + + if (mp == TO_NEXUS && ishpibdev(dp->d_name) || + mp != TO_NEXUS && eq(mp->d_name, "hpib") && + !ishpibdev(dp->d_name)) { + printf("%s%s must be attached to an hpib\n", + dp->d_name, wnum(dp->d_unit)); + return (1); + } + if (mp == TO_NEXUS && isscsidev(dp->d_name) || + mp != TO_NEXUS && eq(mp->d_name, "scsi") && + !isscsidev(dp->d_name)) { + printf("%s%s must be attached to a scsi\n", + dp->d_name, wnum(dp->d_unit)); + return (1); + } + return (0); +} +#endif + +#if MACHINE_I386 +char *sirq(); + +i386_ioconf() +{ + register struct device *dp, *mp, *np; + register int uba_n, slave; + FILE *fp; + + fp = fopen(path("ioconf.c"), "w"); + if (fp == 0) { + perror(path("ioconf.c")); + exit(1); + } + fprintf(fp, "/*\n"); + fprintf(fp, " * ioconf.c \n"); + fprintf(fp, " * Generated by config program\n"); + fprintf(fp, " */\n\n"); + fprintf(fp, "#include \"machine/pte.h\"\n"); + fprintf(fp, "#include \"sys/param.h\"\n"); + fprintf(fp, "#include \"sys/buf.h\"\n"); + fprintf(fp, "#include \"sys/map.h\"\n"); + fprintf(fp, "\n"); + fprintf(fp, "#define V(s) __CONCAT(V,s)\n"); + fprintf(fp, "#define C (caddr_t)\n\n"); + /* + * First print the isa initialization structures + */ + if (seen_isa) { + + fprintf(fp, "/*\n"); + fprintf(fp, " * ISA devices\n"); + fprintf(fp, " */\n\n"); + fprintf(fp, "#include \"i386/isa/isa_device.h\"\n"); + fprintf(fp, "#include \"i386/isa/isa.h\"\n"); + fprintf(fp, "#include \"i386/isa/icu.h\"\n\n"); + + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (mp == 0 || mp == TO_NEXUS || + !eq(mp->d_name, "isa")) + continue; + fprintf(fp, +"extern struct isa_driver %sdriver; extern V(%s%d)();\n", + dp->d_name, dp->d_name, dp->d_unit); + } + fprintf(fp, "\nstruct isa_device isa_devtab_bio[] = {\n"); + fprintf(fp, "\ +/* driver iobase irq drq maddr msiz intr unit */\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (dp->d_unit == QUES || mp == 0 || + mp == TO_NEXUS || !eq(mp->d_name, "isa")) + continue; + if (!eq(dp->d_mask, "bio")) continue; + if (dp->d_port) + fprintf(fp, "{ &%sdriver, %8.8s,", dp->d_name, dp->d_port); + else + fprintf(fp, "{ &%sdriver, 0x%03x,", dp->d_name, dp->d_portn); + fprintf(fp, " %5.5s, %2d, C 0x%05X, %5d, V(%s%d), %2d },\n", + sirq(dp->d_irq), dp->d_drq, dp->d_maddr, + dp->d_msize, dp->d_name, dp->d_unit, dp->d_unit); + } + fprintf(fp, "0\n};\n"); + + fprintf(fp, "struct isa_device isa_devtab_tty[] = {\n"); + fprintf(fp, "\ +/* driver iobase irq drq maddr msiz intr unit */\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (dp->d_unit == QUES || mp == 0 || + mp == TO_NEXUS || !eq(mp->d_name, "isa")) + continue; + if (!eq(dp->d_mask, "tty")) continue; + if (dp->d_port) + fprintf(fp, "{ &%sdriver, %8.8s,", dp->d_name, dp->d_port); + else + fprintf(fp, "{ &%sdriver, 0x%03x,", dp->d_name, dp->d_portn); + fprintf(fp, " %5.5s, %2d, C 0x%05X, %5d, V(%s%d), %2d },\n", + sirq(dp->d_irq), dp->d_drq, dp->d_maddr, + dp->d_msize, dp->d_name, dp->d_unit, dp->d_unit); + } + fprintf(fp, "0\n};\n\n"); + + fprintf(fp, "struct isa_device isa_devtab_net[] = {\n"); + fprintf(fp, "\ +/* driver iobase irq drq maddr msiz intr unit */\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (dp->d_unit == QUES || mp == 0 || + mp == TO_NEXUS || !eq(mp->d_name, "isa")) + continue; + if (!eq(dp->d_mask, "net")) continue; + if (dp->d_port) + fprintf(fp, "{ &%sdriver, %8.8s,", dp->d_name, dp->d_port); + else + fprintf(fp, "{ &%sdriver, 0x%03x,", dp->d_name, dp->d_portn); + fprintf(fp, " %5.5s, %2d, C 0x%05X, %5d, V(%s%d), %2d },\n", + sirq(dp->d_irq), dp->d_drq, dp->d_maddr, + dp->d_msize, dp->d_name, dp->d_unit, dp->d_unit); + } + fprintf(fp, "0\n};\n\n"); + + fprintf(fp, "struct isa_device isa_devtab_null[] = {\n"); + fprintf(fp, "\ +/* driver iobase irq drq maddr msiz intr unit */\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (dp->d_unit == QUES || mp == 0 || + mp == TO_NEXUS || !eq(mp->d_name, "isa")) + continue; + if (!eq(dp->d_mask, "null")) continue; + if (dp->d_port) + fprintf(fp, "{ &%sdriver, %8.8s,", dp->d_name, dp->d_port); + else + fprintf(fp, "{ &%sdriver, 0x%03x,", dp->d_name, dp->d_portn); + fprintf(fp, " %5.5s, %2d, C 0x%05X, %5d, V(%s%d), %2d },\n", + sirq(dp->d_irq), dp->d_drq, dp->d_maddr, + dp->d_msize, dp->d_name, dp->d_unit, dp->d_unit); + } + fprintf(fp, "0\n};\n\n"); + } + pseudo_ioconf(fp); + (void) fclose(fp); +} + +char * +sirq(num) +{ + + if (num == -1) + return ("0"); + sprintf(errbuf, "IRQ%d", num); + return (errbuf); +} +#endif + +#if MACHINE_PMAX +pmax_ioconf() +{ + register struct device *dp, *mp; + FILE *fp; + + fp = fopen(path("ioconf.c"), "w"); + if (fp == 0) { + perror(path("ioconf.c")); + exit(1); + } + fprintf(fp, "#include \"sys/types.h\"\n"); + fprintf(fp, "#include \"sys/time.h\"\n"); + fprintf(fp, "#include \"pmax/dev/device.h\"\n\n"); + fprintf(fp, "#define C (char *)\n\n"); + + /* print controller initialization structures */ + for (dp = dtab; dp != 0; dp = dp->d_next) { + if (dp->d_type == PSEUDO_DEVICE) + continue; + fprintf(fp, "extern struct driver %sdriver;\n", dp->d_name); + } + fprintf(fp, "\nstruct pmax_ctlr pmax_cinit[] = {\n"); + fprintf(fp, "/*\tdriver,\t\tunit,\taddr,\t\tpri,\tflags */\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + if (dp->d_type != CONTROLLER && dp->d_type != MASTER) + continue; + if (dp->d_conn != TO_NEXUS) { + printf("%s%s must be attached to a nexus (internal bus)\n", + dp->d_name, wnum(dp->d_unit)); + continue; + } + if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { + printf("can't specify drive/slave for %s%s\n", + dp->d_name, wnum(dp->d_unit)); + continue; + } + if (dp->d_unit == UNKNOWN || dp->d_unit == QUES) + dp->d_unit = 0; + fprintf(fp, + "\t{ &%sdriver,\t%d,\tC 0x%x,\t%d,\t0x%x },\n", + dp->d_name, dp->d_unit, dp->d_addr, dp->d_pri, + dp->d_flags); + } + fprintf(fp, "\t0\n};\n"); + + /* print devices connected to other controllers */ + fprintf(fp, "\nstruct scsi_device scsi_dinit[] = {\n"); + fprintf(fp, + "/*driver,\tcdriver,\tunit,\tctlr,\tdrive,\tslave,\tdk,\tflags*/\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + if (dp->d_type == CONTROLLER || dp->d_type == MASTER || + dp->d_type == PSEUDO_DEVICE) + continue; + mp = dp->d_conn; + if (mp == 0 || + !eq(mp->d_name, "asc") && !eq(mp->d_name, "sii")) { + printf("%s%s: devices must be attached to a SCSI (asc or sii) controller\n", + dp->d_name, wnum(dp->d_unit)); + continue; + } + if ((unsigned)dp->d_drive > 6) { + printf("%s%s: SCSI drive must be in the range 0..6\n", + dp->d_name, wnum(dp->d_unit)); + continue; + } + /* may want to allow QUES later */ + if ((unsigned)dp->d_slave > 7) { + printf("%s%s: SCSI slave (LUN) must be in the range 0..7\n", + dp->d_name, wnum(dp->d_unit)); + continue; + } + fprintf(fp, "{ &%sdriver,\t&%sdriver,", dp->d_name, mp->d_name); + fprintf(fp, "\t%d,\t%d,\t%d,\t%d,\t%d,\t0x%x },\n", + dp->d_unit, mp->d_unit, dp->d_drive, dp->d_slave, + dp->d_dk, dp->d_flags); + } + fprintf(fp, "0\n};\n"); + pseudo_ioconf(fp); + (void) fclose(fp); +} +#endif + +#if MACHINE_NEWS3400 +int have_iop = 0; +int have_hb = 0; +int have_vme = 0; + +news_ioconf() +{ + register struct device *dp, *mp; + register int slave; + FILE *fp; + + fp = fopen(path("ioconf.c"), "w"); + if (fp == 0) { + perror(path("ioconf.c")); + exit(1); + } + fprintf(fp, "#include \"sys/param.h\"\n"); + fprintf(fp, "#include \"sys/buf.h\"\n"); + fprintf(fp, "#include \"sys/map.h\"\n"); + fprintf(fp, "#include \"vm/vm.h\"\n"); + fprintf(fp, "#include \"iop.h\"\n"); + fprintf(fp, "#include \"hb.h\"\n"); + fprintf(fp, "\n"); + fprintf(fp, "#if NIOP > 0\n"); + fprintf(fp, "#include \"news3400/iop/iopvar.h\"\n"); + fprintf(fp, "#endif\n"); + fprintf(fp, "#if NHB > 0\n"); + fprintf(fp, "#include \"news3400/hbdev/hbvar.h\"\n"); + fprintf(fp, "#endif\n"); + fprintf(fp, "\n"); + fprintf(fp, "#define C (caddr_t)\n\n"); + fprintf(fp, "\n"); + +/* BEGIN HB */ + fprintf(fp, "#if NHB > 0\n"); + /* + * Now generate interrupt vectors for the HYPER-BUS + */ + for (dp = dtab; dp != 0; dp = dp->d_next) { + if (dp->d_pri >= 0) { + mp = dp->d_conn; + if (mp == 0 || mp == TO_NEXUS || + !eq(mp->d_name, "hb")) + continue; + fprintf(fp, "extern struct hb_driver %sdriver;\n", + dp->d_name); + have_hb++; + } + } + /* + * Now spew forth the hb_cinfo structure + */ + fprintf(fp, "\nstruct hb_ctlr hminit[] = {\n"); + fprintf(fp, "/*\t driver,\tctlr,\talive,\taddr,\tintpri */\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if ((dp->d_type != MASTER && dp->d_type != CONTROLLER) + || mp == TO_NEXUS || mp == 0 || + !eq(mp->d_name, "hb")) + continue; + if (dp->d_pri < 0) { + printf("must specify priority for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { + printf("drives need their own entries; "); + printf("dont specify drive or slave for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_flags) { + printf("controllers (e.g. %s%d) don't have flags, "); + printf("only devices do\n", + dp->d_name, dp->d_unit); + continue; + } + fprintf(fp, "\t{ &%sdriver,\t%d,\t0,\tC 0x%x,\t%d },\n", + dp->d_name, dp->d_unit, dp->d_addr, dp->d_pri); + } + fprintf(fp, "\t0\n};\n"); + /* + * Now we go for the hb_device stuff + */ + fprintf(fp, "\nstruct hb_device hdinit[] = {\n"); + fprintf(fp, +"\t/* driver, unit, ctlr, slave, addr, pri, dk, flags*/\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 || + mp == TO_NEXUS || /* mp->d_type == MASTER || */ + eq(mp->d_name, "iop") || eq(mp->d_name, "vme")) + continue; + if (eq(mp->d_name, "hb")) { + if (dp->d_pri < 0) { + printf("must specify vector for device %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) { + printf("drives/slaves can be specified only "); + printf("for controllers, not for device %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + slave = QUES; + } else { + if (mp->d_conn == 0) { + printf("%s%d isn't connected to anything, ", + mp->d_name, mp->d_unit); + printf("so %s%d is unattached\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_drive == UNKNOWN) { + printf("must specify ``drive number'' for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + /* NOTE THAT ON THE IOP ``drive'' IS STORED IN */ + /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */ + if (dp->d_slave != UNKNOWN) { + printf("slave numbers should be given only "); + printf("for massbus tapes, not for %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_pri >= 0) { + printf("interrupt priority should not be "); + printf("given for drive %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + if (dp->d_addr != 0) { + printf("csr addresses should be given only"); + printf("on controllers, not on %s%d\n", + dp->d_name, dp->d_unit); + continue; + } + slave = dp->d_drive; + } + fprintf(fp, +"\t{ &%sdriver, %2d, %s, %2d, C 0x%x, %d, %d, 0x%x },\n", + eq(mp->d_name, "hb") ? dp->d_name : mp->d_name, dp->d_unit, + eq(mp->d_name, "hb") ? " -1" : qu(mp->d_unit), + slave, dp->d_addr, dp->d_pri, dp->d_dk, dp->d_flags); + } + fprintf(fp, "\t0\n};\n\n"); + fprintf(fp, "#endif\n\n"); +/* END HB */ + pseudo_ioconf(fp); + (void) fclose(fp); +} +#endif + +char * +intv(dev) + register struct device *dev; +{ + static char buf[20]; + + if (dev->d_vec == 0) + return (" 0"); + (void) sprintf(buf, "%sint%d", dev->d_name, dev->d_unit); + return (buf); +} + +char * +qu(num) +{ + + if (num == QUES) + return ("'?'"); + if (num == UNKNOWN) + return (" -1"); + (void) sprintf(errbuf, "%3d", num); + return (errbuf); +} + +char * +wnum(num) +{ + + if (num == QUES || num == UNKNOWN) + return ("?"); + (void) sprintf(errbuf, "%d", num); + return (errbuf); +} + +void +pseudo_ioconf(fp) + register FILE *fp; +{ + register struct device *dp; + + (void)fprintf(fp, "\n#include \n\n"); + for (dp = dtab; dp != NULL; dp = dp->d_next) + if (dp->d_type == PSEUDO_DEVICE) + (void)fprintf(fp, "extern void %sattach __P((int));\n", + dp->d_name); + /* + * XXX concatonated disks are pseudo-devices but appear as DEVICEs + * since they don't adhere to normal pseudo-device conventions + * (i.e. one entry with total count in d_slave). + */ + if (seen_cd) + (void)fprintf(fp, "extern void cdattach __P((int));\n"); + /* XXX temporary for HP300, others */ + (void)fprintf(fp, "\n#include /* XXX */\n"); + (void)fprintf(fp, "#define etherattach (void (*)__P((int)))nullop\n"); + (void)fprintf(fp, "#define iteattach (void (*) __P((int)))nullop\n"); + (void)fprintf(fp, "\nstruct pdevinit pdevinit[] = {\n"); + for (dp = dtab; dp != NULL; dp = dp->d_next) + if (dp->d_type == PSEUDO_DEVICE) + (void)fprintf(fp, "\t{ %sattach, %d },\n", dp->d_name, + dp->d_slave > 0 ? dp->d_slave : 1); + /* + * XXX count up cds and put out an entry + */ + if (seen_cd) { + struct file_list *fl; + int cdmax = -1; + + for (fl = comp_list; fl != NULL; fl = fl->f_next) + if (fl->f_type == COMPDEVICE && fl->f_compinfo > cdmax) + cdmax = fl->f_compinfo; + (void)fprintf(fp, "\t{ cdattach, %d },\n", cdmax+1); + } + (void)fprintf(fp, "\t{ 0, 0 }\n};\n"); + if (seen_cd) + comp_config(fp); +} + +comp_config(fp) + FILE *fp; +{ + register struct file_list *fl; + register struct device *dp; + + fprintf(fp, "\n#include \"dev/cdvar.h\"\n"); + fprintf(fp, "\nstruct cddevice cddevice[] = {\n"); + fprintf(fp, "/*\tunit\tileave\tflags\tdk\tdevs\t\t\t\t*/\n"); + + fl = comp_list; + while (fl) { + if (fl->f_type != COMPDEVICE) { + fl = fl->f_next; + continue; + } + for (dp = dtab; dp != 0; dp = dp->d_next) + if (dp->d_type == DEVICE && + eq(dp->d_name, fl->f_fn) && + dp->d_unit == fl->f_compinfo) + break; + if (dp == 0) + continue; + fprintf(fp, "\t%d,\t%d,\t%d,\t%d,\t{", + dp->d_unit, dp->d_pri < 0 ? 0 : dp->d_pri, + dp->d_flags, 1); + for (fl = fl->f_next; fl->f_type == COMPSPEC; fl = fl->f_next) + fprintf(fp, " 0x%x,", fl->f_compdev); + fprintf(fp, " NODEV },\n"); + } + fprintf(fp, "\t-1,\t0,\t0,\t0,\t{ 0 },\n};\n"); +} diff --git a/usr.sbin/config/mkmakefile.c b/usr.sbin/config/mkmakefile.c new file mode 100644 index 0000000..fed803d --- /dev/null +++ b/usr.sbin/config/mkmakefile.c @@ -0,0 +1,623 @@ +/* + * Copyright (c) 1993, 19801990 + * 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[] = "@(#)mkmakefile.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Build the makefile for the system, from + * the information in the files files and the + * additional files for the machine being compiled to. + */ + +#include +#include +#include "y.tab.h" +#include "config.h" + +#define next_word(fp, wd) \ + { register char *word = get_word(fp); \ + if (word == (char *)EOF) \ + return; \ + else \ + wd = word; \ + } +#define next_quoted_word(fp, wd) \ + { register char *word = get_quoted_word(fp); \ + if (word == (char *)EOF) \ + return; \ + else \ + wd = word; \ + } + +static struct file_list *fcur; +char *tail(); + +/* + * Lookup a file, by name. + */ +struct file_list * +fl_lookup(file) + register char *file; +{ + register struct file_list *fp; + + for (fp = ftab ; fp != 0; fp = fp->f_next) { + if (eq(fp->f_fn, file)) + return (fp); + } + return (0); +} + +/* + * Lookup a file, by final component name. + */ +struct file_list * +fltail_lookup(file) + register char *file; +{ + register struct file_list *fp; + + for (fp = ftab ; fp != 0; fp = fp->f_next) { + if (eq(tail(fp->f_fn), tail(file))) + return (fp); + } + return (0); +} + +/* + * Make a new file list entry + */ +struct file_list * +new_fent() +{ + register struct file_list *fp; + + fp = (struct file_list *) malloc(sizeof *fp); + bzero(fp, sizeof *fp); + if (fcur == 0) + fcur = ftab = fp; + else + fcur->f_next = fp; + fcur = fp; + return (fp); +} + +static struct users { + int u_default; + int u_min; + int u_max; +} users[] = { + { 24, 8, 1024 }, /* MACHINE_VAX */ + { 4, 2, 128 }, /* MACHINE_TAHOE */ + { 8, 2, 64 }, /* MACHINE_HP300 */ + { 8, 2, 64 }, /* MACHINE_I386 */ + { 8, 2, 64 }, /* MACHINE_MIPS */ + { 8, 2, 64 }, /* MACHINE_PMAX */ + { 8, 2, 64 }, /* MACHINE_LUNA68K */ + { 8, 2, 64 }, /* MACHINE_NEWS3400 */ +}; +#define NUSERS (sizeof (users) / sizeof (users[0])) + +/* + * Build the makefile from the skeleton + */ +makefile() +{ + FILE *ifp, *ofp; + char line[BUFSIZ]; + struct opt *op; + struct users *up; + + read_files(); + strcpy(line, "Makefile."); + (void) strcat(line, machinename); + ifp = fopen(line, "r"); + if (ifp == 0) { + perror(line); + exit(1); + } + ofp = fopen(path("Makefile"), "w"); + if (ofp == 0) { + perror(path("Makefile")); + exit(1); + } + fprintf(ofp, "IDENT=-D%s", raise(ident)); + if (profiling) + fprintf(ofp, " -DGPROF"); + if (cputype == 0) { + printf("cpu type must be specified\n"); + exit(1); + } + { struct cputype *cp; + for (cp = cputype; cp; cp = cp->cpu_next) + fprintf(ofp, " -D%s", cp->cpu_name); + } + for (op = opt; op; op = op->op_next) + if (op->op_value) + fprintf(ofp, " -D%s=\"%s\"", op->op_name, op->op_value); + else + fprintf(ofp, " -D%s", op->op_name); + fprintf(ofp, "\n"); + if (hadtz == 0) + printf("timezone not specified; gmt assumed\n"); + if ((unsigned)machine > NUSERS) { + printf("maxusers config info isn't present, using vax\n"); + up = &users[MACHINE_VAX-1]; + } else + up = &users[machine-1]; + if (maxusers == 0) { + printf("maxusers not specified; %d assumed\n", up->u_default); + maxusers = up->u_default; + } else if (maxusers < up->u_min) { + printf("minimum of %d maxusers assumed\n", up->u_min); + maxusers = up->u_min; + } else if (maxusers > up->u_max) + printf("warning: maxusers > %d (%d)\n", up->u_max, maxusers); + fprintf(ofp, "PARAM=-DTIMEZONE=%d -DDST=%d -DMAXUSERS=%d", + zone, dst, maxusers); + if (hz > 0) + fprintf(ofp, " -DHZ=%d", hz); + fprintf(ofp, "\n"); + for (op = mkopt; op; op = op->op_next) + fprintf(ofp, "%s=%s\n", op->op_name, op->op_value); + if (debugging) + fprintf(ofp, "DEBUG=-g\n"); + if (profiling) + fprintf(ofp, "PROF=-pg\n"); + while (fgets(line, BUFSIZ, ifp) != 0) { + if (*line != '%') { + fprintf(ofp, "%s", line); + continue; + } + if (eq(line, "%OBJS\n")) + do_objs(ofp); + else if (eq(line, "%CFILES\n")) + do_cfiles(ofp); + else if (eq(line, "%RULES\n")) + do_rules(ofp); + else if (eq(line, "%LOAD\n")) + do_load(ofp); + else + fprintf(stderr, + "Unknown %% construct in generic makefile: %s", + line); + } + (void) fclose(ifp); + (void) fclose(ofp); +} + +/* + * Read in the information about files used in making the system. + * Store it in the ftab linked list. + */ +read_files() +{ + FILE *fp; + register struct file_list *tp, *pf; + register struct device *dp; + struct device *save_dp; + register struct opt *op; + char *wd, *this, *needs, *special; + char fname[32]; + int nreqs, first = 1, configdep, isdup, std, filetype; + + ftab = 0; + (void) strcpy(fname, "../../conf/files"); +openit: + fp = fopen(fname, "r"); + if (fp == 0) { + perror(fname); + exit(1); + } +next: + /* + * filename [ standard | optional ] [ config-dependent ] + * [ dev* | profiling-routine ] [ device-driver] + * [ compile-with "compile rule" ] + */ + wd = get_word(fp); + if (wd == (char *)EOF) { + (void) fclose(fp); + if (first == 1) { + (void) sprintf(fname, "files.%s", machinename); + first++; + goto openit; + } + if (first == 2) { + (void) sprintf(fname, "files.%s", raise(ident)); + first++; + fp = fopen(fname, "r"); + if (fp != 0) + goto next; + } + return; + } + if (wd == 0) + goto next; + this = ns(wd); + next_word(fp, wd); + if (wd == 0) { + printf("%s: No type for %s.\n", + fname, this); + exit(1); + } + if ((pf = fl_lookup(this)) && (pf->f_type != INVISIBLE || pf->f_flags)) + isdup = 1; + else + isdup = 0; + tp = 0; + if (first == 3 && (tp = fltail_lookup(this)) != 0) + printf("%s: Local file %s overrides %s.\n", + fname, this, tp->f_fn); + nreqs = 0; + special = 0; + configdep = 0; + needs = 0; + std = 0; + filetype = NORMAL; + if (eq(wd, "standard")) + std = 1; + else if (!eq(wd, "optional")) { + printf("%s: %s must be optional or standard\n", fname, this); + exit(1); + } +nextparam: + next_word(fp, wd); + if (wd == 0) + goto doneparam; + if (eq(wd, "config-dependent")) { + configdep++; + goto nextparam; + } + if (eq(wd, "compile-with")) { + next_quoted_word(fp, wd); + if (wd == 0) { + printf("%s: %s missing compile command string.\n", + fname); + exit(1); + } + special = ns(wd); + goto nextparam; + } + nreqs++; + if (eq(wd, "device-driver")) { + filetype = DRIVER; + goto nextparam; + } + if (eq(wd, "profiling-routine")) { + filetype = PROFILING; + goto nextparam; + } + if (needs == 0 && nreqs == 1) + needs = ns(wd); + if (isdup) + goto invis; + for (dp = dtab; dp != 0; save_dp = dp, dp = dp->d_next) + if (eq(dp->d_name, wd)) { + if (std && dp->d_type == PSEUDO_DEVICE && + dp->d_slave <= 0) + dp->d_slave = 1; + goto nextparam; + } + if (std) { + dp = (struct device *) malloc(sizeof *dp); + init_dev(dp); + dp->d_name = ns(wd); + dp->d_type = PSEUDO_DEVICE; + dp->d_slave = 1; + save_dp->d_next = dp; + goto nextparam; + } + for (op = opt; op != 0; op = op->op_next) + if (op->op_value == 0 && opteq(op->op_name, wd)) { + if (nreqs == 1) { + free(needs); + needs = 0; + } + goto nextparam; + } +invis: + while ((wd = get_word(fp)) != 0) + ; + if (tp == 0) + tp = new_fent(); + tp->f_fn = this; + tp->f_type = INVISIBLE; + tp->f_needs = needs; + tp->f_flags = isdup; + tp->f_special = special; + goto next; + +doneparam: + if (std == 0 && nreqs == 0) { + printf("%s: what is %s optional on?\n", + fname, this); + exit(1); + } + +save: + if (wd) { + printf("%s: syntax error describing %s\n", + fname, this); + exit(1); + } + if (filetype == PROFILING && profiling == 0) + goto next; + if (tp == 0) + tp = new_fent(); + tp->f_fn = this; + tp->f_type = filetype; + tp->f_flags = 0; + if (configdep) + tp->f_flags |= CONFIGDEP; + tp->f_needs = needs; + tp->f_special = special; + if (pf && pf->f_type == INVISIBLE) + pf->f_flags = 1; /* mark as duplicate */ + goto next; +} + +opteq(cp, dp) + char *cp, *dp; +{ + char c, d; + + for (; ; cp++, dp++) { + if (*cp != *dp) { + c = isupper(*cp) ? tolower(*cp) : *cp; + d = isupper(*dp) ? tolower(*dp) : *dp; + if (c != d) + return (0); + } + if (*cp == 0) + return (1); + } +} + +do_objs(fp) + FILE *fp; +{ + register struct file_list *tp, *fl; + register int lpos, len; + register char *cp, och, *sp; + char swapname[32]; + + fprintf(fp, "OBJS="); + lpos = 6; + for (tp = ftab; tp != 0; tp = tp->f_next) { + if (tp->f_type == INVISIBLE) + continue; + sp = tail(tp->f_fn); + for (fl = conf_list; fl; fl = fl->f_next) { + if (fl->f_type != SWAPSPEC) + continue; + (void) sprintf(swapname, "swap%s.c", fl->f_fn); + if (eq(sp, swapname)) + goto cont; + } + cp = sp + (len = strlen(sp)) - 1; + och = *cp; + *cp = 'o'; + if (len + lpos > 72) { + lpos = 8; + fprintf(fp, "\\\n\t"); + } + fprintf(fp, "%s ", sp); + lpos += len + 1; + *cp = och; +cont: + ; + } + if (lpos != 8) + putc('\n', fp); +} + +do_cfiles(fp) + FILE *fp; +{ + register struct file_list *tp, *fl; + register int lpos, len; + char swapname[32]; + + fputs("CFILES=", fp); + lpos = 8; + for (tp = ftab; tp; tp = tp->f_next) + if (tp->f_type != INVISIBLE) { + len = strlen(tp->f_fn); + if (tp->f_fn[len - 1] != 'c') + continue; + if ((len = 3 + len) + lpos > 72) { + lpos = 8; + fputs("\\\n\t", fp); + } + fprintf(fp, "$S/%s ", tp->f_fn); + lpos += len + 1; + } + for (fl = conf_list; fl; fl = fl->f_next) + if (fl->f_type == SYSTEMSPEC) { + (void) sprintf(swapname, "swap%s.c", fl->f_fn); + if ((len = 3 + strlen(swapname)) + lpos > 72) { + lpos = 8; + fputs("\\\n\t", fp); + } + if (eq(fl->f_fn, "generic")) + fprintf(fp, "$S/%s/%s/%s ", + machinename, machinename, swapname); + else + fprintf(fp, "%s ", swapname); + lpos += len + 1; + } + if (lpos != 8) + putc('\n', fp); +} + +char * +tail(fn) + char *fn; +{ + register char *cp; + + cp = rindex(fn, '/'); + if (cp == 0) + return (fn); + return (cp+1); +} + +/* + * Create the makerules for each file + * which is part of the system. + * Devices are processed with the special c2 option -i + * which avoids any problem areas with i/o addressing + * (e.g. for the VAX); assembler files are processed by as. + */ +do_rules(f) + FILE *f; +{ + register char *cp, *np, och, *tp; + register struct file_list *ftp; + char *special; + + for (ftp = ftab; ftp != 0; ftp = ftp->f_next) { + if (ftp->f_type == INVISIBLE) + continue; + cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1; + och = *cp; + *cp = '\0'; + if (och == 'o') { + fprintf(f, "%so:\n\t-cp $S/%so .\n\n", tail(np), np); + continue; + } + fprintf(f, "%so: $S/%s%c\n", tail(np), np, och); + tp = tail(np); + special = ftp->f_special; + if (special == 0) { + char *ftype; + static char cmd[128]; + + switch (ftp->f_type) { + + case NORMAL: + ftype = "NORMAL"; + break; + + case DRIVER: + ftype = "DRIVER"; + break; + + case PROFILING: + if (!profiling) + continue; + ftype = "PROFILE"; + break; + + default: + printf("config: don't know rules for %s\n", np); + break; + } + (void)sprintf(cmd, "${%s_%c%s}", ftype, toupper(och), + ftp->f_flags & CONFIGDEP? "_C" : ""); + special = cmd; + } + *cp = och; + fprintf(f, "\t%s\n\n", special); + } +} + +/* + * Create the load strings + */ +do_load(f) + register FILE *f; +{ + register struct file_list *fl; + register int first; + struct file_list *do_systemspec(); + + for (first = 1, fl = conf_list; fl; first = 0) + fl = fl->f_type == SYSTEMSPEC ? + do_systemspec(f, fl, first) : fl->f_next; + fputs("all:", f); + for (fl = conf_list; fl; fl = fl->f_next) + if (fl->f_type == SYSTEMSPEC) + fprintf(f, " %s", fl->f_needs); + putc('\n', f); +} + +struct file_list * +do_systemspec(f, fl, first) + FILE *f; + register struct file_list *fl; + int first; +{ + + fprintf(f, "%s: ${SYSTEM_DEP} swap%s.o", fl->f_needs, fl->f_fn); + if (first) + fprintf(f, " newvers"); + fprintf(f, "\n\t${SYSTEM_LD_HEAD}\n"); + fprintf(f, "\t${SYSTEM_LD} swap%s.o\n", fl->f_fn); + fprintf(f, "\t${SYSTEM_LD_TAIL}\n\n"); + do_swapspec(f, fl->f_fn); + for (fl = fl->f_next; fl; fl = fl->f_next) + if (fl->f_type != SWAPSPEC) + break; + return (fl); +} + +do_swapspec(f, name) + FILE *f; + register char *name; +{ + + if (!eq(name, "generic")) + fprintf(f, "swap%s.o: swap%s.c\n", name, name); + else + fprintf(f, "swapgeneric.o: $S/%s/%s/swapgeneric.c\n", + machinename, machinename); + fprintf(f, "\t${NORMAL_C}\n\n"); +} + +char * +raise(str) + register char *str; +{ + register char *cp = str; + + while (*str) { + if (islower(*str)) + *str = toupper(*str); + str++; + } + return (cp); +} diff --git a/usr.sbin/config/mkswapconf.c b/usr.sbin/config/mkswapconf.c new file mode 100644 index 0000000..e499973 --- /dev/null +++ b/usr.sbin/config/mkswapconf.c @@ -0,0 +1,216 @@ +/* + * Copyright (c) 1980, 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[] = "@(#)mkswapconf.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Build a swap configuration file. + */ +#include "config.h" + +#include +#include + +swapconf() +{ + register struct file_list *fl; + struct file_list *do_swap(); + + fl = conf_list; + while (fl) { + if (fl->f_type != SYSTEMSPEC) { + fl = fl->f_next; + continue; + } + fl = do_swap(fl); + } +} + +struct file_list * +do_swap(fl) + register struct file_list *fl; +{ + FILE *fp; + char swapname[80]; + register struct file_list *swap; + dev_t dev; + + if (eq(fl->f_fn, "generic")) { + fl = fl->f_next; + return (fl->f_next); + } + (void) sprintf(swapname, "swap%s.c", fl->f_fn); + fp = fopen(path(swapname), "w"); + if (fp == 0) { + perror(path(swapname)); + exit(1); + } + fprintf(fp, "#include \"sys/param.h\"\n"); + fprintf(fp, "#include \"sys/conf.h\"\n"); + fprintf(fp, "\n"); + /* + * If there aren't any swap devices + * specified, just return, the error + * has already been noted. + */ + swap = fl->f_next; + if (swap == 0 || swap->f_type != SWAPSPEC) { + (void) unlink(path(swapname)); + fclose(fp); + return (swap); + } + fprintf(fp, "dev_t\trootdev = makedev(%d, %d);\n", + major(fl->f_rootdev), minor(fl->f_rootdev)); + fprintf(fp, "dev_t\tdumpdev = makedev(%d, %d);\n", + major(fl->f_dumpdev), minor(fl->f_dumpdev)); + fprintf(fp, "\n"); + fprintf(fp, "struct\tswdevt swdevt[] = {\n"); + do { + dev = swap->f_swapdev; + fprintf(fp, "\t{ makedev(%d, %d),\t%d,\t%d },\t/* %s */\n", + major(dev), minor(dev), swap->f_swapflag, + swap->f_swapsize, swap->f_fn); + swap = swap->f_next; + } while (swap && swap->f_type == SWAPSPEC); + fprintf(fp, "\t{ NODEV, 0, 0 }\n"); + fprintf(fp, "};\n"); + fclose(fp); + return (swap); +} + +static int devtablenotread = 1; +static struct devdescription { + char *dev_name; + int dev_major; + struct devdescription *dev_next; +} *devtable; + +/* + * Given a device name specification figure out: + * major device number + * partition + * device name + * unit number + * This is a hack, but the system still thinks in + * terms of major/minor instead of string names. + */ +dev_t +nametodev(name, defunit, defpartition) + char *name; + int defunit; + char defpartition; +{ + char *cp, partition; + int unit; + register struct devdescription *dp; + + cp = name; + if (cp == 0) { + fprintf(stderr, "config: internal error, nametodev\n"); + exit(1); + } + while (*cp && !isdigit(*cp)) + cp++; + unit = *cp ? atoi(cp) : defunit; + if (unit < 0 || unit > 31) { + fprintf(stderr, +"config: %s: invalid device specification, unit out of range\n", name); + unit = defunit; /* carry on more checking */ + } + if (*cp) { + *cp++ = '\0'; + while (*cp && isdigit(*cp)) + cp++; + } + partition = *cp ? *cp : defpartition; + if (partition < 'a' || partition > 'h') { + fprintf(stderr, +"config: %c: invalid device specification, bad partition\n", *cp); + partition = defpartition; /* carry on */ + } + if (devtablenotread) + initdevtable(); + for (dp = devtable; dp; dp = dp->dev_next) + if (eq(name, dp->dev_name)) + break; + if (dp == 0) { + fprintf(stderr, "config: %s: unknown device\n", name); + return (NODEV); + } + return (makedev(dp->dev_major, (unit << 3) + (partition - 'a'))); +} + +char * +devtoname(dev) + dev_t dev; +{ + char buf[80]; + register struct devdescription *dp; + + if (devtablenotread) + initdevtable(); + for (dp = devtable; dp; dp = dp->dev_next) + if (major(dev) == dp->dev_major) + break; + if (dp == 0) + dp = devtable; + (void) sprintf(buf, "%s%d%c", dp->dev_name, + minor(dev) >> 3, (minor(dev) & 07) + 'a'); + return (ns(buf)); +} + +initdevtable() +{ + char buf[BUFSIZ]; + int maj; + register struct devdescription **dp = &devtable; + FILE *fp; + + (void) sprintf(buf, "../conf/devices.%s", machinename); + fp = fopen(buf, "r"); + if (fp == NULL) { + fprintf(stderr, "config: can't open %s\n", buf); + exit(1); + } + while (fscanf(fp, "%s\t%d\n", buf, &maj) == 2) { + *dp = (struct devdescription *)malloc(sizeof (**dp)); + (*dp)->dev_name = ns(buf); + (*dp)->dev_major = maj; + dp = &(*dp)->dev_next; + } + *dp = 0; + fclose(fp); + devtablenotread = 0; +} diff --git a/usr.sbin/config/mkubglue.c b/usr.sbin/config/mkubglue.c new file mode 100644 index 0000000..7d2b3d4 --- /dev/null +++ b/usr.sbin/config/mkubglue.c @@ -0,0 +1,196 @@ +/*- + * Copyright (c) 1980, 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[] = "@(#)mkubglue.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Make the uba interrupt file ubglue.s + */ +#include +#include "config.h" +#include "y.tab.h" + +ubglue() +{ + register FILE *fp; + register struct device *dp, *mp; + + fp = fopen(path("ubglue.s"), "w"); + if (fp == 0) { + perror(path("ubglue.s")); + exit(1); + } + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (mp != 0 && mp != (struct device *)-1 && + !eq(mp->d_name, "mba")) { + struct idlst *id, *id2; + + for (id = dp->d_vec; id; id = id->id_next) { + for (id2 = dp->d_vec; id2; id2 = id2->id_next) { + if (id2 == id) { + dump_vec(fp, id->id, dp->d_unit); + break; + } + if (!strcmp(id->id, id2->id)) + break; + } + } + } + } + dump_std(fp); + for (dp = dtab; dp != 0; dp = dp->d_next) { + mp = dp->d_conn; + if (mp != 0 && mp != (struct device *)-1 && + !eq(mp->d_name, "mba")) { + struct idlst *id, *id2; + + for (id = dp->d_vec; id; id = id->id_next) { + for (id2 = dp->d_vec; id2; id2 = id2->id_next) { + if (id2 == id) { + dump_intname(fp, id->id, + dp->d_unit); + break; + } + if (!strcmp(id->id, id2->id)) + break; + } + } + } + } + dump_ctrs(fp); + (void) fclose(fp); +} + +static int cntcnt = 0; /* number of interrupt counters allocated */ + +/* + * print an interrupt vector + */ +dump_vec(fp, vector, number) + register FILE *fp; + char *vector; + int number; +{ + char nbuf[80]; + register char *v = nbuf; + + (void) sprintf(v, "%s%d", vector, number); + fprintf(fp, "\t.globl\t_X%s\n\t.align\t2\n_X%s:\n\tpushr\t$0x3f\n", + v, v); + fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++); + if (strncmp(vector, "dzx", 3) == 0) + fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdzdma\n\n", number); + else if (strncmp(vector, "dpx", 3) == 0) + fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdpxdma\n\n", number); + else if (strncmp(vector, "dpr", 3) == 0) + fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdprdma\n\n", number); + else { + if (strncmp(vector, "uur", 3) == 0) { + fprintf(fp, "#ifdef UUDMA\n"); + fprintf(fp, "\tmovl\t$%d,r0\n\tjsb\tuudma\n", number); + fprintf(fp, "#endif\n"); + } + fprintf(fp, "\tpushl\t$%d\n", number); + fprintf(fp, "\tcalls\t$1,_%s\n\tpopr\t$0x3f\n", vector); + fprintf(fp, "\tincl\t_cnt+V_INTR\n\trei\n\n"); + } +} + +/* + * Start the interrupt name table with the names + * of the standard vectors not on the unibus. + * The number and order of these names should correspond + * with the definitions in scb.s. + */ +dump_std(fp) + register FILE *fp; +{ + fprintf(fp, "\n\t.globl\t_intrnames\n"); + fprintf(fp, "\n\t.globl\t_eintrnames\n"); + fprintf(fp, "\t.data\n"); + fprintf(fp, "_intrnames:\n"); + fprintf(fp, "\t.asciz\t\"clock\"\n"); + fprintf(fp, "\t.asciz\t\"cnr\"\n"); + fprintf(fp, "\t.asciz\t\"cnx\"\n"); + fprintf(fp, "\t.asciz\t\"tur\"\n"); + fprintf(fp, "\t.asciz\t\"tux\"\n"); + fprintf(fp, "\t.asciz\t\"mba0\"\n"); + fprintf(fp, "\t.asciz\t\"mba1\"\n"); + fprintf(fp, "\t.asciz\t\"mba2\"\n"); + fprintf(fp, "\t.asciz\t\"mba3\"\n"); + fprintf(fp, "\t.asciz\t\"uba0\"\n"); + fprintf(fp, "\t.asciz\t\"uba1\"\n"); + fprintf(fp, "\t.asciz\t\"uba2\"\n"); + fprintf(fp, "\t.asciz\t\"uba3\"\n"); +#define I_FIXED 13 /* number of names above */ +} + +dump_intname(fp, vector, number) + register FILE *fp; + char *vector; + int number; +{ + register char *cp = vector; + + fprintf(fp, "\t.asciz\t\""); + /* + * Skip any "int" or "intr" in the name. + */ + while (*cp) + if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') { + cp += 3; + if (*cp == 'r') + cp++; + } else { + putc(*cp, fp); + cp++; + } + fprintf(fp, "%d\"\n", number); +} + +dump_ctrs(fp) + register FILE *fp; +{ + fprintf(fp, "_eintrnames:\n"); + fprintf(fp, "\n\t.globl\t_intrcnt\n"); + fprintf(fp, "\n\t.globl\t_eintrcnt\n"); + fprintf(fp, "_intrcnt:\n", I_FIXED); + fprintf(fp, "\t.space\t4 * %d\n", I_FIXED); + fprintf(fp, "_fltintrcnt:\n", cntcnt); + fprintf(fp, "\t.space\t4 * %d\n", cntcnt); + fprintf(fp, "_eintrcnt:\n\n"); + fprintf(fp, "\t.text\n"); +} diff --git a/usr.sbin/dev_mkdb/Makefile b/usr.sbin/dev_mkdb/Makefile new file mode 100644 index 0000000..29c24f4 --- /dev/null +++ b/usr.sbin/dev_mkdb/Makefile @@ -0,0 +1,6 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= dev_mkdb +MAN8= dev_mkdb.0 + +.include diff --git a/usr.sbin/dev_mkdb/dev_mkdb.8 b/usr.sbin/dev_mkdb/dev_mkdb.8 new file mode 100644 index 0000000..9369b2b --- /dev/null +++ b/usr.sbin/dev_mkdb/dev_mkdb.8 @@ -0,0 +1,81 @@ +.\" 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. +.\" +.\" @(#)dev_mkdb.8 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Os +.Dt DEV_MKDB 8 +.Sh NAME +.Nm dev_mkdb +.Nd create +.Pa /dev +database +.Sh SYNOPSIS +.Nm dev_mkdb +.Sh DESCRIPTION +The +.Nm dev_mkdb +command creates a +.Xr db 3 +hash access method database in +.Dq Pa /var/run/dev.db +which contains the names of all of the character and block special +files in the +.Dq Pa /dev +directory, using the file type and the +.Fa st_rdev +field as the key. +.Pp +Keys are a structure containing a mode_t followed by a dev_t, +with any padding zero'd out. +The former is the type of the file (st_mode & S_IFMT), +the latter is the st_rdev field. +.Sh FILES +.Bl -tag -width /var/run/dev.db -compact +.It Pa /dev +Device directory. +.It Pa /var/run/dev.db +Database file. +.El +.Sh SEE ALSO +.Xr ps 1 , +.Xr stat 2 , +.Xr db 3 , +.Xr devname 3 , +.Xr kvm_nlist 3 , +.Xr ttyname 3 , +.Xr kvm_mkdb 8 +.Sh HISTORY +The +.Nm dev_mkdb +command appeared in +.Bx 4.4 . diff --git a/usr.sbin/dev_mkdb/dev_mkdb.c b/usr.sbin/dev_mkdb/dev_mkdb.c new file mode 100644 index 0000000..682c041 --- /dev/null +++ b/usr.sbin/dev_mkdb/dev_mkdb.c @@ -0,0 +1,181 @@ +/*- + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1990, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)dev_mkdb.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include + +#include +#undef DIRBLKSIZ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void err __P((const char *, ...)); +void usage __P((void)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + register DIR *dirp; + register struct dirent *dp; + struct stat sb; + struct { + mode_t type; + dev_t dev; + } bkey; + DB *db; + DBT data, key; + int ch; + u_char buf[MAXNAMLEN + 1]; + char dbtmp[MAXPATHLEN + 1], dbname[MAXPATHLEN + 1]; + + while ((ch = getopt(argc, argv, "")) != EOF) + switch((char)ch) { + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc > 0) + usage(); + + if (chdir(_PATH_DEV)) + err("%s: %s", _PATH_DEV, strerror(errno)); + + dirp = opendir("."); + + (void)snprintf(dbtmp, sizeof(dbtmp), "%sdev.tmp", _PATH_VARRUN); + (void)snprintf(dbname, sizeof(dbtmp), "%sdev.db", _PATH_VARRUN); + db = dbopen(dbtmp, O_CREAT|O_EXLOCK|O_RDWR|O_TRUNC, + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, DB_HASH, NULL); + if (db == NULL) + err("%s: %s", dbtmp, strerror(errno)); + + /* + * Keys are a mode_t followed by a dev_t. The former is the type of + * the file (mode & S_IFMT), the latter is the st_rdev field. Note + * that the structure may contain padding, so we have to clear it + * out here. + */ + bzero(&bkey, sizeof(bkey)); + key.data = &bkey; + key.size = sizeof(bkey); + data.data = buf; + while (dp = readdir(dirp)) { + if (lstat(dp->d_name, &sb)) { + (void)fprintf(stderr, + "dev_mkdb: %s: %s\n", dp->d_name, strerror(errno)); + continue; + } + + /* Create the key. */ + if (S_ISCHR(sb.st_mode)) + bkey.type = S_IFCHR; + else if (S_ISBLK(sb.st_mode)) + bkey.type = S_IFBLK; + else + continue; + bkey.dev = sb.st_rdev; + + /* + * Create the data; nul terminate the name so caller doesn't + * have to. + */ + bcopy(dp->d_name, buf, dp->d_namlen); + buf[dp->d_namlen] = '\0'; + data.size = dp->d_namlen + 1; + if ((db->put)(db, &key, &data, 0)) + err("dbput %s: %s\n", dbtmp, strerror(errno)); + } + (void)(db->close)(db); + if (rename(dbtmp, dbname)) + err("rename %s to %s: %s", dbtmp, dbname, strerror(errno)); + exit(0); +} + +void +usage() +{ + (void)fprintf(stderr, "usage: dev_mkdb\n"); + exit(1); +} + +#if __STDC__ +#include +#else +#include +#endif + +void +#if __STDC__ +err(const char *fmt, ...) +#else +err(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)fprintf(stderr, "dev_mkdb: "); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + (void)fprintf(stderr, "\n"); + exit(1); + /* NOTREACHED */ +} diff --git a/usr.sbin/diskpart/Makefile b/usr.sbin/diskpart/Makefile new file mode 100644 index 0000000..3f24518 --- /dev/null +++ b/usr.sbin/diskpart/Makefile @@ -0,0 +1,6 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= diskpart +MAN8= diskpart.0 + +.include diff --git a/usr.sbin/diskpart/diskpart.8 b/usr.sbin/diskpart/diskpart.8 new file mode 100644 index 0000000..0b02de2 --- /dev/null +++ b/usr.sbin/diskpart/diskpart.8 @@ -0,0 +1,143 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" @(#)diskpart.8 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt DISKPART 8 +.Os BSD 4 +.Sh NAME +.Nm diskpart +.Nd calculate default disk partition sizes +.Sh SYNOPSIS +.Nm diskpart +.Op Fl p +.Op Fl d +.Op Fl s Ar size +.Ar disk-type +.Sh DESCRIPTION +.Nm Diskpart +is used to calculate the disk partition sizes based on the +default rules used at Berkeley. +.Pp +Available options and operands: +.Bl -tag -width Fl +.It Fl p +Tables suitable for inclusion in a device driver +are produced. +.It Fl d +An entry suitable for inclusion in the disk +description file +.Pa /etc/disktab +is generated; for example, +.Xr disktab 5 . +.It Fl s Ar size +The size of the disk may be limited to +.Ar size +with the +.Fl s +option. +.El +.Pp +On disks that use +.Xr bad144 8 +type of +bad-sector forwarding, +space is normally left in the last partition on the disk +for a bad sector forwarding table, although this space +is not reflected in the tables produced. The space reserved +is one track for the replicated copies of the table and +sufficient tracks to hold a pool of 126 sectors to which bad sectors +are mapped. For more information, see +.Xr bad144 8 . +The +.Fl s +option is intended for other controllers which reserve some space at the end +of the disk for bad-sector replacements or other control areas, +even if not a multiple of cylinders. +.Pp +The disk partition sizes are based on the total amount of +space on the disk as given in the table below (all values +are supplied in units of sectors). The +.Ql c +partition +is, by convention, used to access the entire physical disk. +The device driver tables include +the space reserved for the bad sector forwarding table in the +.Ql c +partition; +those used in the disktab and default formats exclude reserved tracks. +In normal operation, either the +.Ql g +partition is used, or the +.Ql d , +.Ql e , +and +.Ql f +partitions are used. The +.Ql g +and +.Ql f +partitions +are variable-sized, occupying whatever space remains after allocation +of the fixed sized partitions. +If the disk is smaller than 20 Megabytes, then +.Nm diskpart +aborts with the message +.Dq Li disk too small, calculate by hand . +.Bl -column Partition 20-60\ MB 61-205\ MB 206-355\ MB 356+\ MB +Partition 20-60 MB 61-205 MB 206-355 MB 356+ MB +a 15884 15884 15884 15884 +b 10032 33440 33440 66880 +d 15884 15884 15884 15884 +e unused 55936 55936 307200 +h unused unused 291346 291346 +.El +.Pp +If an unknown disk type is specified, +.Nm diskpart +will prompt for the required disk geometry information. +.Sh SEE ALSO +.Xr disktab 5 , +.Xr bad144 8 +.Sh BUGS +Most default partition sizes are based on historical artifacts +(like the RP06), and may result in unsatisfactory layouts. +.Pp +When using the +.Fl d +flag, alternate disk names are not included +in the output. +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.2 . diff --git a/usr.sbin/diskpart/diskpart.c b/usr.sbin/diskpart/diskpart.c new file mode 100644 index 0000000..c89d0f1 --- /dev/null +++ b/usr.sbin/diskpart/diskpart.c @@ -0,0 +1,474 @@ +/* + * Copyright (c) 1983, 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) 1983, 1988, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)diskpart.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Program to calculate standard disk partition sizes. + */ +#include +#define DKTYPENAMES +#include + +#include +#include + +#define for_now /* show all of `c' partition for disklabel */ +#define NPARTITIONS 8 +#define PART(x) (x - 'a') + +/* + * Default partition sizes, where they exist. + */ +#define NDEFAULTS 4 +int defpart[NDEFAULTS][NPARTITIONS] = { + { 15884, 66880, 0, 15884, 307200, 0, 0, 291346 }, /* ~ 356+ Mbytes */ + { 15884, 33440, 0, 15884, 55936, 0, 0, 291346 }, /* ~ 206-355 Mbytes */ + { 15884, 33440, 0, 15884, 55936, 0, 0, 0 }, /* ~ 61-205 Mbytes */ + { 15884, 10032, 0, 15884, 0, 0, 0, 0 }, /* ~ 20-60 Mbytes */ +}; + +/* + * Each array defines a layout for a disk; + * that is, the collection of partitions totally + * covers the physical space on a disk. + */ +#define NLAYOUTS 3 +char layouts[NLAYOUTS][NPARTITIONS] = { + { 'a', 'b', 'h', 'g' }, + { 'a', 'b', 'h', 'd', 'e', 'f' }, + { 'c' }, +}; + +/* + * Default disk block and disk block fragment + * sizes for each file system. Those file systems + * with zero block and frag sizes are special cases + * (e.g. swap areas or for access to the entire device). + */ +struct partition defparam[NPARTITIONS] = { + { 0, 0, 1024, FS_UNUSED, 8, 0 }, /* a */ + { 0, 0, 1024, FS_SWAP, 8, 0 }, /* b */ + { 0, 0, 1024, FS_UNUSED, 8, 0 }, /* c */ + { 0, 0, 512, FS_UNUSED, 8, 0 }, /* d */ + { 0, 0, 1024, FS_UNUSED, 8, 0 }, /* e */ + { 0, 0, 1024, FS_UNUSED, 8, 0 }, /* f */ + { 0, 0, 1024, FS_UNUSED, 8, 0 }, /* g */ + { 0, 0, 1024, FS_UNUSED, 8, 0 } /* h */ +}; + +/* + * Each disk has some space reserved for a bad sector + * forwarding table. DEC standard 144 uses the first + * 5 even numbered sectors in the last track of the + * last cylinder for replicated storage of the bad sector + * table; another 126 sectors past this is needed as a + * pool of replacement sectors. + */ +int badsecttable = 126; /* # sectors */ + +int pflag; /* print device driver partition tables */ +int dflag; /* print disktab entry */ + +struct disklabel *promptfordisk(); + +main(argc, argv) + int argc; + char *argv[]; +{ + struct disklabel *dp; + register int curcyl, spc, def, part, layout, j; + int threshhold, numcyls[NPARTITIONS], startcyl[NPARTITIONS]; + int totsize = 0; + char *lp, *tyname; + + argc--, argv++; + if (argc < 1) { + fprintf(stderr, + "usage: disktab [ -p ] [ -d ] [ -s size ] disk-type\n"); + exit(1); + } + if (argc > 0 && strcmp(*argv, "-p") == 0) { + pflag++; + argc--, argv++; + } + if (argc > 0 && strcmp(*argv, "-d") == 0) { + dflag++; + argc--, argv++; + } + if (argc > 1 && strcmp(*argv, "-s") == 0) { + totsize = atoi(argv[1]); + argc += 2, argv += 2; + } + dp = getdiskbyname(*argv); + if (dp == NULL) { + if (isatty(0)) + dp = promptfordisk(*argv); + if (dp == NULL) { + fprintf(stderr, "%s: unknown disk type\n", *argv); + exit(2); + } + } else { + if (dp->d_flags & D_REMOVABLE) + tyname = "removable"; + else if (dp->d_flags & D_RAMDISK) + tyname = "simulated"; + else + tyname = "winchester"; + } + spc = dp->d_secpercyl; + /* + * Bad sector table contains one track for the replicated + * copies of the table and enough full tracks preceding + * the last track to hold the pool of free blocks to which + * bad sectors are mapped. + * If disk size was specified explicitly, use specified size. + */ + if (dp->d_type == DTYPE_SMD && dp->d_flags & D_BADSECT && + totsize == 0) { + badsecttable = dp->d_nsectors + + roundup(badsecttable, dp->d_nsectors); + threshhold = howmany(spc, badsecttable); + } else { + badsecttable = 0; + threshhold = 0; + } + /* + * If disk size was specified, recompute number of cylinders + * that may be used, and set badsecttable to any remaining + * fraction of the last cylinder. + */ + if (totsize != 0) { + dp->d_ncylinders = howmany(totsize, spc); + badsecttable = spc * dp->d_ncylinders - totsize; + } + + /* + * Figure out if disk is large enough for + * expanded swap area and 'd', 'e', and 'f' + * partitions. Otherwise, use smaller defaults + * based on RK07. + */ + for (def = 0; def < NDEFAULTS; def++) { + curcyl = 0; + for (part = PART('a'); part < NPARTITIONS; part++) + curcyl += howmany(defpart[def][part], spc); + if (curcyl < dp->d_ncylinders - threshhold) + break; + } + if (def >= NDEFAULTS) { + fprintf(stderr, "%s: disk too small, calculate by hand\n", + *argv); + exit(3); + } + + /* + * Calculate number of cylinders allocated to each disk + * partition. We may waste a bit of space here, but it's + * in the interest of (very backward) compatibility + * (for mixed disk systems). + */ + for (curcyl = 0, part = PART('a'); part < NPARTITIONS; part++) { + numcyls[part] = 0; + if (defpart[def][part] != 0) { + numcyls[part] = howmany(defpart[def][part], spc); + curcyl += numcyls[part]; + } + } + numcyls[PART('f')] = dp->d_ncylinders - curcyl; + numcyls[PART('g')] = + numcyls[PART('d')] + numcyls[PART('e')] + numcyls[PART('f')]; + numcyls[PART('c')] = dp->d_ncylinders; + defpart[def][PART('f')] = numcyls[PART('f')] * spc - badsecttable; + defpart[def][PART('g')] = numcyls[PART('g')] * spc - badsecttable; + defpart[def][PART('c')] = numcyls[PART('c')] * spc; +#ifndef for_now + if (totsize || !pflag) +#else + if (totsize) +#endif + defpart[def][PART('c')] -= badsecttable; + + /* + * Calculate starting cylinder number for each partition. + * Note the 'h' partition is physically located before the + * 'g' or 'd' partition. This is reflected in the layout + * arrays defined above. + */ + for (layout = 0; layout < NLAYOUTS; layout++) { + curcyl = 0; + for (lp = layouts[layout]; *lp != 0; lp++) { + startcyl[PART(*lp)] = curcyl; + curcyl += numcyls[PART(*lp)]; + } + } + + if (pflag) { + printf("}, %s_sizes[%d] = {\n", dp->d_typename, NPARTITIONS); + for (part = PART('a'); part < NPARTITIONS; part++) { + if (numcyls[part] == 0) { + printf("\t0,\t0,\n"); + continue; + } + if (dp->d_type != DTYPE_MSCP) { + printf("\t%d,\t%d,\t\t/* %c=cyl %d thru %d */\n", + defpart[def][part], startcyl[part], + 'A' + part, startcyl[part], + startcyl[part] + numcyls[part] - 1); + continue; + } + printf("\t%d,\t%d,\t\t/* %c=sectors %d thru %d */\n", + defpart[def][part], spc * startcyl[part], + 'A' + part, spc * startcyl[part], + spc * startcyl[part] + defpart[def][part] - 1); + } + exit(0); + } + if (dflag) { + int nparts; + + /* + * In case the disk is in the ``in-between'' range + * where the 'g' partition is smaller than the 'h' + * partition, reverse the frag sizes so the /usr partition + * is always set up with a frag size larger than the + * user's partition. + */ + if (defpart[def][PART('g')] < defpart[def][PART('h')]) { + int temp; + + temp = defparam[PART('h')].p_fsize; + defparam[PART('h')].p_fsize = + defparam[PART('g')].p_fsize; + defparam[PART('g')].p_fsize = temp; + } + printf("%s:\\\n", dp->d_typename); + printf("\t:ty=%s:ns#%d:nt#%d:nc#%d:", tyname, + dp->d_nsectors, dp->d_ntracks, dp->d_ncylinders); + if (dp->d_secpercyl != dp->d_nsectors * dp->d_ntracks) + printf("sc#%d:", dp->d_secpercyl); + if (dp->d_type == DTYPE_SMD && dp->d_flags & D_BADSECT) + printf("sf:"); + printf("\\\n\t:dt=%s:", dktypenames[dp->d_type]); + for (part = NDDATA - 1; part >= 0; part--) + if (dp->d_drivedata[part]) + break; + for (j = 0; j <= part; j++) + printf("d%d#%d:", j, dp->d_drivedata[j]); + printf("\\\n"); + for (nparts = 0, part = PART('a'); part < NPARTITIONS; part++) + if (defpart[def][part] != 0) + nparts++; + for (part = PART('a'); part < NPARTITIONS; part++) { + if (defpart[def][part] == 0) + continue; + printf("\t:p%c#%d:", 'a' + part, defpart[def][part]); + printf("o%c#%d:b%c#%d:f%c#%d:", + 'a' + part, spc * startcyl[part], + 'a' + part, + defparam[part].p_frag * defparam[part].p_fsize, + 'a' + part, defparam[part].p_fsize); + if (defparam[part].p_fstype == FS_SWAP) + printf("t%c=swap:", 'a' + part); + nparts--; + printf("%s\n", nparts > 0 ? "\\" : ""); + } +#ifdef for_now + defpart[def][PART('c')] -= badsecttable; + part = PART('c'); + printf("#\t:p%c#%d:", 'a' + part, defpart[def][part]); + printf("o%c#%d:b%c#%d:f%c#%d:\n", + 'a' + part, spc * startcyl[part], + 'a' + part, + defparam[part].p_frag * defparam[part].p_fsize, + 'a' + part, defparam[part].p_fsize); +#endif + exit(0); + } + printf("%s: #sectors/track=%d, #tracks/cylinder=%d #cylinders=%d\n", + dp->d_typename, dp->d_nsectors, dp->d_ntracks, + dp->d_ncylinders); + printf("\n Partition\t Size\t Offset\t Range\n"); + for (part = PART('a'); part < NPARTITIONS; part++) { + printf("\t%c\t", 'a' + part); + if (numcyls[part] == 0) { + printf(" unused\n"); + continue; + } + printf("%7d\t%7d\t%4d - %d%s\n", + defpart[def][part], startcyl[part] * spc, + startcyl[part], startcyl[part] + numcyls[part] - 1, + defpart[def][part] % spc ? "*" : ""); + } +} + +struct disklabel disk; + +struct field { + char *f_name; + char *f_defaults; + u_long *f_location; +} fields[] = { + { "sector size", "512", &disk.d_secsize }, + { "#sectors/track", 0, &disk.d_nsectors }, + { "#tracks/cylinder", 0, &disk.d_ntracks }, + { "#cylinders", 0, &disk.d_ncylinders }, + { 0, 0, 0 }, +}; + +struct disklabel * +promptfordisk(name) + char *name; +{ + register struct disklabel *dp = &disk; + register struct field *fp; + register i; + char buf[BUFSIZ], **tp, *cp, *gets(); + + strncpy(dp->d_typename, name, sizeof(dp->d_typename)); + fprintf(stderr, + "%s: unknown disk type, want to supply parameters (y/n)? ", + name); + (void) gets(buf); + if (*buf != 'y') + return ((struct disklabel *)0); + for (;;) { + fprintf(stderr, "Disk/controller type (%s)? ", dktypenames[1]); + (void) gets(buf); + if (buf[0] == 0) + dp->d_type = 1; + else + dp->d_type = gettype(buf, dktypenames); + if (dp->d_type >= 0) + break; + fprintf(stderr, "%s: unrecognized controller type\n", buf); + fprintf(stderr, "use one of:\n", buf); + for (tp = dktypenames; *tp; tp++) + if (index(*tp, ' ') == 0) + fprintf(stderr, "\t%s\n", *tp); + } +gettype: + dp->d_flags = 0; + fprintf(stderr, "type (winchester|removable|simulated)? "); + (void) gets(buf); + if (strcmp(buf, "removable") == 0) + dp->d_flags = D_REMOVABLE; + else if (strcmp(buf, "simulated") == 0) + dp->d_flags = D_RAMDISK; + else if (strcmp(buf, "winchester")) { + fprintf(stderr, "%s: bad disk type\n", buf); + goto gettype; + } + strncpy(dp->d_typename, buf, sizeof(dp->d_typename)); + fprintf(stderr, "(type to get default value, if only one)\n"); + if (dp->d_type == DTYPE_SMD) + fprintf(stderr, "Do %ss support bad144 bad block forwarding (yes)? ", + dp->d_typename); + (void) gets(buf); + if (*buf != 'n') + dp->d_flags |= D_BADSECT; + for (fp = fields; fp->f_name != NULL; fp++) { +again: + fprintf(stderr, "%s ", fp->f_name); + if (fp->f_defaults != NULL) + fprintf(stderr, "(%s)", fp->f_defaults); + fprintf(stderr, "? "); + cp = gets(buf); + if (*cp == '\0') { + if (fp->f_defaults == NULL) { + fprintf(stderr, "no default value\n"); + goto again; + } + cp = fp->f_defaults; + } + *fp->f_location = atol(cp); + if (*fp->f_location == 0) { + fprintf(stderr, "%s: bad value\n", cp); + goto again; + } + } + fprintf(stderr, "sectors/cylinder (%d)? ", + dp->d_nsectors * dp->d_ntracks); + (void) gets(buf); + if (buf[0] == 0) + dp->d_secpercyl = dp->d_nsectors * dp->d_ntracks; + else + dp->d_secpercyl = atol(buf); + fprintf(stderr, "Drive-type-specific parameters, to terminate:\n"); + for (i = 0; i < NDDATA; i++) { + fprintf(stderr, "d%d? ", i); + (void) gets(buf); + if (buf[0] == 0) + break; + dp->d_drivedata[i] = atol(buf); + } + return (dp); +} + +gettype(t, names) + char *t; + char **names; +{ + register char **nm; + + for (nm = names; *nm; nm++) + if (ustrcmp(t, *nm) == 0) + return (nm - names); + if (isdigit(*t)) + return (atoi(t)); + return (-1); +} + +ustrcmp(s1, s2) + register char *s1, *s2; +{ +#define lower(c) (islower(c) ? (c) : tolower(c)) + + for (; *s1; s1++, s2++) { + if (*s1 == *s2) + continue; + if (isalpha(*s1) && isalpha(*s2) && + lower(*s1) == lower(*s2)) + continue; + return (*s2 - *s1); + } + return (0); +} diff --git a/usr.sbin/edquota/Makefile b/usr.sbin/edquota/Makefile new file mode 100644 index 0000000..38fa90c --- /dev/null +++ b/usr.sbin/edquota/Makefile @@ -0,0 +1,6 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= edquota +MAN8= edquota.0 + +.include diff --git a/usr.sbin/edquota/edquota.8 b/usr.sbin/edquota/edquota.8 new file mode 100644 index 0000000..f5bf705 --- /dev/null +++ b/usr.sbin/edquota/edquota.8 @@ -0,0 +1,150 @@ +.\" Copyright (c) 1983, 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Robert Elz at The University of Melbourne. +.\" +.\" 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. +.\" +.\" @(#)edquota.8 8.1 (Berkeley) 6/6/93 +.\" +.TH EDQUOTA 8 "June 6, 1993" +.UC 5 +.SH NAME +edquota \- edit user quotas +.SH SYNOPSIS +.B edquota +[ +.I \-u +] [ +.I \-p +proto-username +] +username ... +.br +.B edquota +.I \-g +[ +.I \-p +proto-groupname +] +groupname ... +.br +.B edquota +.I -t +[ +.I -u +] +.br +.B edquota +.I -t +.I -g +.br +.SH DESCRIPTION +.I Edquota +is a quota editor. +By default, or if the \fI-u\fP flag is specified, +one or more users may be specified on the command line. +For each user a temporary file is created +with an ASCII representation of the current +disk quotas for that user. +The list of filesystems with user quotas is determined from +.IR /etc/fstab . +An editor is invoked on the ASCII file. +The editor invoked is +.IR vi (1) +unless the environment variable EDITOR specifies otherwise. +.PP +The quotas may then be modified, new quotas added, etc. +Setting a quota to zero indicates that no quota should be imposed. +Setting a hard limit to one indicates that no allocations should +be permitted. +Setting a soft limit to one with a hard limit of zero +indicates that allocations should be permitted on +only a temporary basis (see \fI-t\fP below). +The current usage information in the file is for informational purposes; +only the hard and soft limits can be changed. +.PP +On leaving the editor, +.I edquota +reads the temporary file and modifies the binary +quota files to reflect the changes made. +.PP +If the +.B \-p +option is specified, +.I edquota +will duplicate the quotas of the prototypical user +specified for each user specified. +This is the normal mechanism used to +initialize quotas for groups of users. +.PP +If the \fI-g\fP flag is specified, +.I edquota +is invoked to edit the quotas of +one or more groups specified on the command line. +The \fI-p\fP flag can be specified in conjunction with +the \fI-g\fP flag to specify a prototypical group +to be duplicated among the listed set of groups. +.PP +Users are permitted to exceed their soft limits +for a grace period that may be specified per filesystem. +Once the grace period has expired, +the soft limit is enforced as a hard limit. +The default grace period for a filesystem is specified in +.IR /usr/include/ufs/quota.h . +The \fI-t\fP flag can be used to change the grace period. +By default, or when invoked with the \fI-u\fP flag, +the grace period is set for all the filesystems with user +quotas specified in +.IR /etc/fstab . +When invoked with the \fI-g\fP flag the grace period is +set for all the filesystems with group quotas specified in +.IR /etc/fstab . +The grace period may be specified in days, hours, minutes, or seconds. +Setting a grace period to zero indicates that the default +grace period should be imposed. +Setting a grace period to one second indicates that no +grace period should be granted. +.PP +Only the super-user may edit quotas. +.SH FILES +.DT +\fIquota.user\fP at the filesystem root with user quotas +.br +\fIquota.group\fP at the filesystem root with group quotas +.br +/etc/fstab to find filesystem names and locations +.SH SEE ALSO +quota(1), +quotactl(2), +fstab(5), +quotacheck(8), quotaon(8), repquota(8) +.SH DIAGNOSTICS +Various messages about inaccessible files; self-explanatory. diff --git a/usr.sbin/edquota/edquota.c b/usr.sbin/edquota/edquota.c new file mode 100644 index 0000000..3646720 --- /dev/null +++ b/usr.sbin/edquota/edquota.c @@ -0,0 +1,722 @@ +/* + * Copyright (c) 1980, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Robert Elz at The University of Melbourne. + * + * 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) 1980, 1990, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)edquota.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Disk quota editor. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pathnames.h" + +char *qfname = QUOTAFILENAME; +char *qfextension[] = INITQFNAMES; +char *quotagroup = QUOTAGROUP; +char tmpfil[] = _PATH_TMP; + +struct quotause { + struct quotause *next; + long flags; + struct dqblk dqblk; + char fsname[MAXPATHLEN + 1]; + char qfname[1]; /* actually longer */ +} *getprivs(); +#define FOUND 0x01 + +main(argc, argv) + register char **argv; + int argc; +{ + register struct quotause *qup, *protoprivs, *curprivs; + extern char *optarg; + extern int optind; + register long id, protoid; + register int quotatype, tmpfd; + char *protoname, ch; + int tflag = 0, pflag = 0; + + if (argc < 2) + usage(); + if (getuid()) { + fprintf(stderr, "edquota: permission denied\n"); + exit(1); + } + quotatype = USRQUOTA; + while ((ch = getopt(argc, argv, "ugtp:")) != EOF) { + switch(ch) { + case 'p': + protoname = optarg; + pflag++; + break; + case 'g': + quotatype = GRPQUOTA; + break; + case 'u': + quotatype = USRQUOTA; + break; + case 't': + tflag++; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + if (pflag) { + if ((protoid = getentry(protoname, quotatype)) == -1) + exit(1); + protoprivs = getprivs(protoid, quotatype); + for (qup = protoprivs; qup; qup = qup->next) { + qup->dqblk.dqb_btime = 0; + qup->dqblk.dqb_itime = 0; + } + while (argc-- > 0) { + if ((id = getentry(*argv++, quotatype)) < 0) + continue; + putprivs(id, quotatype, protoprivs); + } + exit(0); + } + tmpfd = mkstemp(tmpfil); + fchown(tmpfd, getuid(), getgid()); + if (tflag) { + protoprivs = getprivs(0, quotatype); + if (writetimes(protoprivs, tmpfd, quotatype) == 0) + exit(1); + if (editit(tmpfil) && readtimes(protoprivs, tmpfd)) + putprivs(0, quotatype, protoprivs); + freeprivs(protoprivs); + exit(0); + } + for ( ; argc > 0; argc--, argv++) { + if ((id = getentry(*argv, quotatype)) == -1) + continue; + curprivs = getprivs(id, quotatype); + if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0) + continue; + if (editit(tmpfil) && readprivs(curprivs, tmpfd)) + putprivs(id, quotatype, curprivs); + freeprivs(curprivs); + } + close(tmpfd); + unlink(tmpfil); + exit(0); +} + +usage() +{ + fprintf(stderr, "%s%s%s%s", + "Usage: edquota [-u] [-p username] username ...\n", + "\tedquota -g [-p groupname] groupname ...\n", + "\tedquota [-u] -t\n", "\tedquota -g -t\n"); + exit(1); +} + +/* + * This routine converts a name for a particular quota type to + * an identifier. This routine must agree with the kernel routine + * getinoquota as to the interpretation of quota types. + */ +getentry(name, quotatype) + char *name; + int quotatype; +{ + struct passwd *pw; + struct group *gr; + + if (alldigits(name)) + return (atoi(name)); + switch(quotatype) { + case USRQUOTA: + if (pw = getpwnam(name)) + return (pw->pw_uid); + fprintf(stderr, "%s: no such user\n", name); + break; + case GRPQUOTA: + if (gr = getgrnam(name)) + return (gr->gr_gid); + fprintf(stderr, "%s: no such group\n", name); + break; + default: + fprintf(stderr, "%d: unknown quota type\n", quotatype); + break; + } + sleep(1); + return (-1); +} + +/* + * Collect the requested quota information. + */ +struct quotause * +getprivs(id, quotatype) + register long id; + int quotatype; +{ + register struct fstab *fs; + register struct quotause *qup, *quptail; + struct quotause *quphead; + int qcmd, qupsize, fd; + char *qfpathname; + static int warned = 0; + extern int errno; + + setfsent(); + quphead = (struct quotause *)0; + qcmd = QCMD(Q_GETQUOTA, quotatype); + while (fs = getfsent()) { + if (strcmp(fs->fs_vfstype, "ufs")) + continue; + if (!hasquota(fs, quotatype, &qfpathname)) + continue; + qupsize = sizeof(*qup) + strlen(qfpathname); + if ((qup = (struct quotause *)malloc(qupsize)) == NULL) { + fprintf(stderr, "edquota: out of memory\n"); + exit(2); + } + if (quotactl(fs->fs_file, qcmd, id, &qup->dqblk) != 0) { + if (errno == EOPNOTSUPP && !warned) { + warned++; + fprintf(stderr, "Warning: %s\n", + "Quotas are not compiled into this kernel"); + sleep(3); + } + if ((fd = open(qfpathname, O_RDONLY)) < 0) { + fd = open(qfpathname, O_RDWR|O_CREAT, 0640); + if (fd < 0 && errno != ENOENT) { + perror(qfpathname); + free(qup); + continue; + } + fprintf(stderr, "Creating quota file %s\n", + qfpathname); + sleep(3); + (void) fchown(fd, getuid(), + getentry(quotagroup, GRPQUOTA)); + (void) fchmod(fd, 0640); + } + lseek(fd, (long)(id * sizeof(struct dqblk)), L_SET); + switch (read(fd, &qup->dqblk, sizeof(struct dqblk))) { + case 0: /* EOF */ + /* + * Convert implicit 0 quota (EOF) + * into an explicit one (zero'ed dqblk) + */ + bzero((caddr_t)&qup->dqblk, + sizeof(struct dqblk)); + break; + + case sizeof(struct dqblk): /* OK */ + break; + + default: /* ERROR */ + fprintf(stderr, "edquota: read error in "); + perror(qfpathname); + close(fd); + free(qup); + continue; + } + close(fd); + } + strcpy(qup->qfname, qfpathname); + strcpy(qup->fsname, fs->fs_file); + if (quphead == NULL) + quphead = qup; + else + quptail->next = qup; + quptail = qup; + qup->next = 0; + } + endfsent(); + return (quphead); +} + +/* + * Store the requested quota information. + */ +putprivs(id, quotatype, quplist) + long id; + int quotatype; + struct quotause *quplist; +{ + register struct quotause *qup; + int qcmd, fd; + + qcmd = QCMD(Q_SETQUOTA, quotatype); + for (qup = quplist; qup; qup = qup->next) { + if (quotactl(qup->fsname, qcmd, id, &qup->dqblk) == 0) + continue; + if ((fd = open(qup->qfname, O_WRONLY)) < 0) { + perror(qup->qfname); + } else { + lseek(fd, (long)id * (long)sizeof (struct dqblk), 0); + if (write(fd, &qup->dqblk, sizeof (struct dqblk)) != + sizeof (struct dqblk)) { + fprintf(stderr, "edquota: "); + perror(qup->qfname); + } + close(fd); + } + } +} + +/* + * Take a list of priviledges and get it edited. + */ +editit(tmpfile) + char *tmpfile; +{ + long omask; + int pid, stat; + extern char *getenv(); + + omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP)); + top: + if ((pid = fork()) < 0) { + extern errno; + + if (errno == EPROCLIM) { + fprintf(stderr, "You have too many processes\n"); + return(0); + } + if (errno == EAGAIN) { + sleep(1); + goto top; + } + perror("fork"); + return (0); + } + if (pid == 0) { + register char *ed; + + sigsetmask(omask); + setgid(getgid()); + setuid(getuid()); + if ((ed = getenv("EDITOR")) == (char *)0) + ed = _PATH_VI; + execlp(ed, ed, tmpfile, 0); + perror(ed); + exit(1); + } + waitpid(pid, &stat, 0); + sigsetmask(omask); + if (!WIFEXITED(stat) || WEXITSTATUS(stat) != 0) + return (0); + return (1); +} + +/* + * Convert a quotause list to an ASCII file. + */ +writeprivs(quplist, outfd, name, quotatype) + struct quotause *quplist; + int outfd; + char *name; + int quotatype; +{ + register struct quotause *qup; + FILE *fd; + + ftruncate(outfd, 0); + lseek(outfd, 0, L_SET); + if ((fd = fdopen(dup(outfd), "w")) == NULL) { + fprintf(stderr, "edquota: "); + perror(tmpfil); + exit(1); + } + fprintf(fd, "Quotas for %s %s:\n", qfextension[quotatype], name); + for (qup = quplist; qup; qup = qup->next) { + fprintf(fd, "%s: %s %d, limits (soft = %d, hard = %d)\n", + qup->fsname, "blocks in use:", + dbtob(qup->dqblk.dqb_curblocks) / 1024, + dbtob(qup->dqblk.dqb_bsoftlimit) / 1024, + dbtob(qup->dqblk.dqb_bhardlimit) / 1024); + fprintf(fd, "%s %d, limits (soft = %d, hard = %d)\n", + "\tinodes in use:", qup->dqblk.dqb_curinodes, + qup->dqblk.dqb_isoftlimit, qup->dqblk.dqb_ihardlimit); + } + fclose(fd); + return (1); +} + +/* + * Merge changes to an ASCII file into a quotause list. + */ +readprivs(quplist, infd) + struct quotause *quplist; + int infd; +{ + register struct quotause *qup; + FILE *fd; + int cnt; + register char *cp; + struct dqblk dqblk; + char *fsp, line1[BUFSIZ], line2[BUFSIZ]; + + lseek(infd, 0, L_SET); + fd = fdopen(dup(infd), "r"); + if (fd == NULL) { + fprintf(stderr, "Can't re-read temp file!!\n"); + return (0); + } + /* + * Discard title line, then read pairs of lines to process. + */ + (void) fgets(line1, sizeof (line1), fd); + while (fgets(line1, sizeof (line1), fd) != NULL && + fgets(line2, sizeof (line2), fd) != NULL) { + if ((fsp = strtok(line1, " \t:")) == NULL) { + fprintf(stderr, "%s: bad format\n", line1); + return (0); + } + if ((cp = strtok((char *)0, "\n")) == NULL) { + fprintf(stderr, "%s: %s: bad format\n", fsp, + &fsp[strlen(fsp) + 1]); + return (0); + } + cnt = sscanf(cp, + " blocks in use: %d, limits (soft = %d, hard = %d)", + &dqblk.dqb_curblocks, &dqblk.dqb_bsoftlimit, + &dqblk.dqb_bhardlimit); + if (cnt != 3) { + fprintf(stderr, "%s:%s: bad format\n", fsp, cp); + return (0); + } + dqblk.dqb_curblocks = btodb(dqblk.dqb_curblocks * 1024); + dqblk.dqb_bsoftlimit = btodb(dqblk.dqb_bsoftlimit * 1024); + dqblk.dqb_bhardlimit = btodb(dqblk.dqb_bhardlimit * 1024); + if ((cp = strtok(line2, "\n")) == NULL) { + fprintf(stderr, "%s: %s: bad format\n", fsp, line2); + return (0); + } + cnt = sscanf(cp, + "\tinodes in use: %d, limits (soft = %d, hard = %d)", + &dqblk.dqb_curinodes, &dqblk.dqb_isoftlimit, + &dqblk.dqb_ihardlimit); + if (cnt != 3) { + fprintf(stderr, "%s: %s: bad format\n", fsp, line2); + return (0); + } + for (qup = quplist; qup; qup = qup->next) { + if (strcmp(fsp, qup->fsname)) + continue; + /* + * Cause time limit to be reset when the quota + * is next used if previously had no soft limit + * or were under it, but now have a soft limit + * and are over it. + */ + if (dqblk.dqb_bsoftlimit && + qup->dqblk.dqb_curblocks >= dqblk.dqb_bsoftlimit && + (qup->dqblk.dqb_bsoftlimit == 0 || + qup->dqblk.dqb_curblocks < + qup->dqblk.dqb_bsoftlimit)) + qup->dqblk.dqb_btime = 0; + if (dqblk.dqb_isoftlimit && + qup->dqblk.dqb_curinodes >= dqblk.dqb_isoftlimit && + (qup->dqblk.dqb_isoftlimit == 0 || + qup->dqblk.dqb_curinodes < + qup->dqblk.dqb_isoftlimit)) + qup->dqblk.dqb_itime = 0; + qup->dqblk.dqb_bsoftlimit = dqblk.dqb_bsoftlimit; + qup->dqblk.dqb_bhardlimit = dqblk.dqb_bhardlimit; + qup->dqblk.dqb_isoftlimit = dqblk.dqb_isoftlimit; + qup->dqblk.dqb_ihardlimit = dqblk.dqb_ihardlimit; + qup->flags |= FOUND; + if (dqblk.dqb_curblocks == qup->dqblk.dqb_curblocks && + dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes) + break; + fprintf(stderr, + "%s: cannot change current allocation\n", fsp); + break; + } + } + fclose(fd); + /* + * Disable quotas for any filesystems that have not been found. + */ + for (qup = quplist; qup; qup = qup->next) { + if (qup->flags & FOUND) { + qup->flags &= ~FOUND; + continue; + } + qup->dqblk.dqb_bsoftlimit = 0; + qup->dqblk.dqb_bhardlimit = 0; + qup->dqblk.dqb_isoftlimit = 0; + qup->dqblk.dqb_ihardlimit = 0; + } + return (1); +} + +/* + * Convert a quotause list to an ASCII file of grace times. + */ +writetimes(quplist, outfd, quotatype) + struct quotause *quplist; + int outfd; + int quotatype; +{ + register struct quotause *qup; + char *cvtstoa(); + FILE *fd; + + ftruncate(outfd, 0); + lseek(outfd, 0, L_SET); + if ((fd = fdopen(dup(outfd), "w")) == NULL) { + fprintf(stderr, "edquota: "); + perror(tmpfil); + exit(1); + } + fprintf(fd, "Time units may be: days, hours, minutes, or seconds\n"); + fprintf(fd, "Grace period before enforcing soft limits for %ss:\n", + qfextension[quotatype]); + for (qup = quplist; qup; qup = qup->next) { + fprintf(fd, "%s: block grace period: %s, ", + qup->fsname, cvtstoa(qup->dqblk.dqb_btime)); + fprintf(fd, "file grace period: %s\n", + cvtstoa(qup->dqblk.dqb_itime)); + } + fclose(fd); + return (1); +} + +/* + * Merge changes of grace times in an ASCII file into a quotause list. + */ +readtimes(quplist, infd) + struct quotause *quplist; + int infd; +{ + register struct quotause *qup; + FILE *fd; + int cnt; + register char *cp; + time_t itime, btime, iseconds, bseconds; + char *fsp, bunits[10], iunits[10], line1[BUFSIZ]; + + lseek(infd, 0, L_SET); + fd = fdopen(dup(infd), "r"); + if (fd == NULL) { + fprintf(stderr, "Can't re-read temp file!!\n"); + return (0); + } + /* + * Discard two title lines, then read lines to process. + */ + (void) fgets(line1, sizeof (line1), fd); + (void) fgets(line1, sizeof (line1), fd); + while (fgets(line1, sizeof (line1), fd) != NULL) { + if ((fsp = strtok(line1, " \t:")) == NULL) { + fprintf(stderr, "%s: bad format\n", line1); + return (0); + } + if ((cp = strtok((char *)0, "\n")) == NULL) { + fprintf(stderr, "%s: %s: bad format\n", fsp, + &fsp[strlen(fsp) + 1]); + return (0); + } + cnt = sscanf(cp, + " block grace period: %d %s file grace period: %d %s", + &btime, bunits, &itime, iunits); + if (cnt != 4) { + fprintf(stderr, "%s:%s: bad format\n", fsp, cp); + return (0); + } + if (cvtatos(btime, bunits, &bseconds) == 0) + return (0); + if (cvtatos(itime, iunits, &iseconds) == 0) + return (0); + for (qup = quplist; qup; qup = qup->next) { + if (strcmp(fsp, qup->fsname)) + continue; + qup->dqblk.dqb_btime = bseconds; + qup->dqblk.dqb_itime = iseconds; + qup->flags |= FOUND; + break; + } + } + fclose(fd); + /* + * reset default grace periods for any filesystems + * that have not been found. + */ + for (qup = quplist; qup; qup = qup->next) { + if (qup->flags & FOUND) { + qup->flags &= ~FOUND; + continue; + } + qup->dqblk.dqb_btime = 0; + qup->dqblk.dqb_itime = 0; + } + return (1); +} + +/* + * Convert seconds to ASCII times. + */ +char * +cvtstoa(time) + time_t time; +{ + static char buf[20]; + + if (time % (24 * 60 * 60) == 0) { + time /= 24 * 60 * 60; + sprintf(buf, "%d day%s", time, time == 1 ? "" : "s"); + } else if (time % (60 * 60) == 0) { + time /= 60 * 60; + sprintf(buf, "%d hour%s", time, time == 1 ? "" : "s"); + } else if (time % 60 == 0) { + time /= 60; + sprintf(buf, "%d minute%s", time, time == 1 ? "" : "s"); + } else + sprintf(buf, "%d second%s", time, time == 1 ? "" : "s"); + return (buf); +} + +/* + * Convert ASCII input times to seconds. + */ +cvtatos(time, units, seconds) + time_t time; + char *units; + time_t *seconds; +{ + + if (bcmp(units, "second", 6) == 0) + *seconds = time; + else if (bcmp(units, "minute", 6) == 0) + *seconds = time * 60; + else if (bcmp(units, "hour", 4) == 0) + *seconds = time * 60 * 60; + else if (bcmp(units, "day", 3) == 0) + *seconds = time * 24 * 60 * 60; + else { + printf("%s: bad units, specify %s\n", units, + "days, hours, minutes, or seconds"); + return (0); + } + return (1); +} + +/* + * Free a list of quotause structures. + */ +freeprivs(quplist) + struct quotause *quplist; +{ + register struct quotause *qup, *nextqup; + + for (qup = quplist; qup; qup = nextqup) { + nextqup = qup->next; + free(qup); + } +} + +/* + * Check whether a string is completely composed of digits. + */ +alldigits(s) + register char *s; +{ + register c; + + c = *s++; + do { + if (!isdigit(c)) + return (0); + } while (c = *s++); + return (1); +} + +/* + * Check to see if a particular quota is to be enabled. + */ +hasquota(fs, type, qfnamep) + register struct fstab *fs; + int type; + char **qfnamep; +{ + register char *opt; + char *cp, *index(), *strtok(); + static char initname, usrname[100], grpname[100]; + static char buf[BUFSIZ]; + + if (!initname) { + sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname); + sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname); + initname = 1; + } + strcpy(buf, fs->fs_mntops); + for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { + if (cp = index(opt, '=')) + *cp++ = '\0'; + if (type == USRQUOTA && strcmp(opt, usrname) == 0) + break; + if (type == GRPQUOTA && strcmp(opt, grpname) == 0) + break; + } + if (!opt) + return (0); + if (cp) { + *qfnamep = cp; + return (1); + } + (void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]); + *qfnamep = buf; + return (1); +} diff --git a/usr.sbin/edquota/pathnames.h b/usr.sbin/edquota/pathnames.h new file mode 100644 index 0000000..92546f7 --- /dev/null +++ b/usr.sbin/edquota/pathnames.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1989, 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.1 (Berkeley) 6/6/93 + */ + +#include + +#undef _PATH_TMP +#define _PATH_TMP "/tmp/EdP.aXXXXX" diff --git a/usr.sbin/eeprom/Makefile b/usr.sbin/eeprom/Makefile new file mode 100644 index 0000000..389a137 --- /dev/null +++ b/usr.sbin/eeprom/Makefile @@ -0,0 +1,6 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= eeprom +MAN8= eeprom.0 + +.include diff --git a/usr.sbin/eeprom/eeprom.8 b/usr.sbin/eeprom/eeprom.8 new file mode 100644 index 0000000..07c3969 --- /dev/null +++ b/usr.sbin/eeprom/eeprom.8 @@ -0,0 +1,69 @@ +.\" Copyright (c) 1992, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This software was developed by the Computer Systems Engineering group +.\" at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and +.\" contributed to Berkeley. +.\" +.\" 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. +.\" +.\" @(#)eeprom.8 8.1 (Berkeley) 6/9/93 +.\" +.Dd June 9, 1993 +.Dt EEPROM 8 +.Os BSD 4.4 +.Sh NAME +.Nm eeprom +.Nd openprom control utility +.Sh SYNOPSIS +.Nm eeprom +.Op Ar name Ar ... +.Op Ar name=value Ar ... +.Sh DESCRIPTION +The +.Nm +utility +is used to display +and modify options fields in the SPARCstation openprom. +.Pp +When invoked with no arguments, +.Nm +display the values of all options. Otherwise, fields are displayed or +set (in the order specified on the command line). +.Sh FILES +.Bl -tag -width /dev/openprom -compact +.It Pa /dev/openprom +the openprom device +.El +.Sh SEE ALSO +.Xr openprom 4 +.Sh HISTORY +The +.Nm eeprom +utility first appeared in 4.4BSD. diff --git a/usr.sbin/eeprom/eeprom.c b/usr.sbin/eeprom/eeprom.c new file mode 100644 index 0000000..2015fed --- /dev/null +++ b/usr.sbin/eeprom/eeprom.c @@ -0,0 +1,204 @@ +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratory. + * + * 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) 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)eeprom.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * eeprom - openprom control utility + * + * usage: + * + * eeprom [field] [field=value] + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "pathnames.h" + +static char openprom[] = _PATH_OPENPROM; +static char usage[] = "usage: %s [field] [field=value]\n"; + +int +main(argc, argv) + int argc; + char **argv; +{ + register char *cp; + register int i, op, fd, flags, status; + register struct opiocdesc *dp; + struct opiocdesc desc; + char buf[1024], buf2[sizeof(buf)]; + char *prog, *name; + + /* Determine simple program name for error messages */ + if (cp = rindex(argv[0], '/')) + prog = cp + 1; + else + prog = argv[0]; + + /* Parse flags */ + opterr = 0; + while ((op = getopt(argc, argv, "")) != EOF) + switch (op) { + + default: + (void) fprintf(stderr, usage, prog); + exit(1); + } + + argc -= optind; + argv += optind; + + /* Determine flags and open device */ + flags = O_RDONLY; + for (i = 0; i < argc; ++i) + if (index(argv[i], '=') != NULL) { + flags = O_RDWR; + break; + } + if ((fd = open(openprom, flags, 0)) < 0) { + fprintf(stderr, "%s: open %s: %s\n", + prog, openprom, strerror(errno)); + exit(1); + } + + dp = &desc; + bzero(dp, sizeof(*dp)); + if (ioctl(fd, OPIOCGETOPTNODE, &dp->op_nodeid) < 0) { + fprintf(stderr, "%s: get optionsnode: %s\n", + prog, strerror(errno)); + exit(1); + } + + if (argc <= 0) { + /* Prime the pump with a zero length name */ + dp->op_name = buf; + dp->op_name[0] = '\0'; + dp->op_namelen = 0; + dp->op_buf = buf2; + for (;;) { + /* Get the next property name */ + dp->op_buflen = sizeof(buf); + if (ioctl(fd, OPIOCNEXTPROP, dp) < 0) { + fprintf(stderr, "%s: get next: %s\n", + prog, strerror(errno)); + exit(1); + } + + /* Zero length name means we're done */ + if (dp->op_buflen <= 0) + break; + + /* Clever hack, swap buffers */ + cp = dp->op_buf; + dp->op_buf = dp->op_name; + dp->op_name = cp; + dp->op_namelen = dp->op_buflen; + + /* Get the value */ + dp->op_buflen = sizeof(buf); + if (ioctl(fd, OPIOCGET, dp) < 0) { + fprintf(stderr, "%s: get \"%s\": %s\n", + prog, cp, strerror(errno)); + exit(1); + } + printf("%.*s=%.*s\n", dp->op_namelen, dp->op_name, + dp->op_buflen, dp->op_buf); + } + exit(0); + } + + status = 0; + for (i = 0; i < argc; ++i) { + dp->op_name = name = argv[i]; + cp = index(name, '='); + if (cp) { + *cp++ = '\0'; + dp->op_buf = cp; + dp->op_buflen = strlen(dp->op_buf); + } else { + dp->op_buf = buf; + dp->op_buflen = sizeof(buf); + } + dp->op_namelen = strlen(name); + if (ioctl(fd, cp ? OPIOCSET : OPIOCGET, dp) < 0) { + fprintf(stderr, "%s: %s \"%s\": %s\n", + prog, cp ? "set" : "get", name, strerror(errno)); + status |= 1; + continue; + } + + /* If setting an entry, we're done */ + if (cp) + continue; + if (dp->op_buflen < 0) { + fprintf(stderr, "%s: \"%s\" not found\n", prog, name); + status |= 1; + continue; + } + if (dp->op_buflen >= sizeof(buf)) { + fprintf(stderr, "%s: \"%s\" truncated\n", prog, name); + status |= 1; + /* fall thorugh and print truncated value */ + } + printf("%s=%.*s\n", name, dp->op_buflen, buf); + } + + exit(status); +} diff --git a/usr.sbin/eeprom/pathnames.h b/usr.sbin/eeprom/pathnames.h new file mode 100644 index 0000000..8df60ce --- /dev/null +++ b/usr.sbin/eeprom/pathnames.h @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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, Lawrence Berkeley Laboratory. + * + * 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.1 (Berkeley) 6/6/93 + */ + +#define _PATH_OPENPROM "/dev/openprom" diff --git a/usr.sbin/inetd/Makefile b/usr.sbin/inetd/Makefile new file mode 100644 index 0000000..964b00d --- /dev/null +++ b/usr.sbin/inetd/Makefile @@ -0,0 +1,7 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= inetd +MAN8= inetd.0 +MLINKS= inetd.8 inetd.5 + +.include diff --git a/usr.sbin/inetd/inetd.8 b/usr.sbin/inetd/inetd.8 new file mode 100644 index 0000000..5fe5711 --- /dev/null +++ b/usr.sbin/inetd/inetd.8 @@ -0,0 +1,375 @@ +.\" Copyright (c) 1985, 1991, 1993, 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. +.\" +.\" @(#)inetd.8 8.3 (Berkeley) 4/13/94 +.\" +.Dd April 13, 1994 +.Dt INETD 8 +.Os BSD 4.4 +.Sh NAME +.Nm inetd +.Nd internet +.Dq super-server +.Sh SYNOPSIS +.Nm inetd +.Op Fl d +.Op Fl R Ar rate +.Op Ar configuration file +.Sh DESCRIPTION +The +.Nm inetd +program +should be run at boot time by +.Pa /etc/rc +(see +.Xr rc 8 ) . +It then listens for connections on certain +internet sockets. When a connection is found on one +of its sockets, it decides what service the socket +corresponds to, and invokes a program to service the request. +The server program is invoked with the service socket +as its standard input, output and error descriptors. +After the program is +finished, +.Nm inetd +continues to listen on the socket (except in some cases which +will be described below). Essentially, +.Nm inetd +allows running one daemon to invoke several others, +reducing load on the system. +.Pp +The options available for +.Nm inetd: +.Bl -tag -width Ds +.It Fl d +Turns on debugging. +.It Fl R Ar rate +Specifies the maximum number of times a service can be invoked +in one minute; the default is 1000. +.El +.Pp +Upon execution, +.Nm inetd +reads its configuration information from a configuration +file which, by default, is +.Pa /etc/inetd.conf . +There must be an entry for each field of the configuration +file, with entries for each field separated by a tab or +a space. Comments are denoted by a ``#'' at the beginning +of a line. There must be an entry for each field. The +fields of the configuration file are as follows: +.Pp +.Bd -unfilled -offset indent -compact +service name +socket type +protocol +wait/nowait +user +server program +server program arguments +.Ed +.Pp +There are two types of services that +.Nm inetd +can start: standard and TCPMUX. +A standard service has a well-known port assigned to it; +it may be a service that implements an official Internet standard or is a +BSD-specific service. +As described in +.Tn RFC 1078 , +TCPMUX services are nonstandard services that do not have a +well-known port assigned to them. +They are invoked from +.Nm inetd +when a program connects to the +.Dq tcpmux +well-known port and specifies +the service name. +This feature is useful for adding locally-developed servers. +.Pp +The +.Em service-name +entry is the name of a valid service in +the file +.Pa /etc/services . +For +.Dq internal +services (discussed below), the service +name +.Em must +be the official name of the service (that is, the first entry in +.Pa /etc/services ) . +For TCPMUX services, the value of the +.Em service-name +field consists of the string +.Dq tcpmux +followed by a slash and the +locally-chosen service name. +The service names listed in +.Pa /etc/services +and the name +.Dq help +are reserved. +Try to choose unique names for your TCPMUX services by prefixing them with +your organization's name and suffixing them with a version number. +.Pp +The +.Em socket-type +should be one of +.Dq stream , +.Dq dgram , +.Dq raw , +.Dq rdm , +or +.Dq seqpacket , +depending on whether the socket is a stream, datagram, raw, +reliably delivered message, or sequenced packet socket. +TCPMUX services must use +.Dq stream . +.Pp +The +.Em protocol +must be a valid protocol as given in +.Pa /etc/protocols . +Examples might be +.Dq tcp +or +.Dq udp . +TCPMUX services must use +.Dq tcp . +.Pp +The +.Em wait/nowait +entry specifies whether the server that is invoked by inetd will take over +the socket associated with the service access point, and thus whether +.Nm inetd +should wait for the server to exit before listening for new service +requests. +Datagram servers must use +.Dq wait , +as they are always invoked with the original datagram socket bound +to the specified service address. +These servers must read at least one datagram from the socket +before exiting. +If a datagram server connects +to its peer, freeing the socket so +.Nm inetd +can received further messages on the socket, it is said to be +a +.Dq multi-threaded +server; +it should read one datagram from the socket and create a new socket +connected to the peer. +It should fork, and the parent should then exit +to allow +.Nm inetd +to check for new service requests to spawn new servers. +Datagram servers which process all incoming datagrams +on a socket and eventually time out are said to be +.Dq single-threaded . +.Xr Comsat 8 , +.Pq Xr biff 1 +and +.Xr talkd 8 +are both examples of the latter type of +datagram server. +.Xr Tftpd 8 +is an example of a multi-threaded datagram server. +.Pp +Servers using stream sockets generally are multi-threaded and +use the +.Dq nowait +entry. +Connection requests for these services are accepted by +.Nm inetd , +and the server is given only the newly-accepted socket connected +to a client of the service. +Most stream-based services operate in this manner. +Stream-based servers that use +.Dq wait +are started with the listening service socket, and must accept +at least one connection request before exiting. +Such a server would normally accept and process incoming connection +requests until a timeout. +TCPMUX services must use +.Dq nowait . +.Pp +The +.Em user +entry should contain the user name of the user as whom the server +should run. This allows for servers to be given less permission +than root. +.Pp +The +.Em server-program +entry should contain the pathname of the program which is to be +executed by +.Nm inetd +when a request is found on its socket. If +.Nm inetd +provides this service internally, this entry should +be +.Dq internal . +.Pp +The +.Em server program arguments +should be just as arguments +normally are, starting with argv[0], which is the name of +the program. If the service is provided internally, the +word +.Dq internal +should take the place of this entry. +.Pp +The +.Nm inetd +program +provides several +.Dq trivial +services internally by use of +routines within itself. These services are +.Dq echo , +.Dq discard , +.Dq chargen +(character generator), +.Dq daytime +(human readable time), and +.Dq time +(machine readable time, +in the form of the number of seconds since midnight, January +1, 1900). All of these services are tcp based. For +details of these services, consult the appropriate +.Tn RFC +from the Network Information Center. +.Pp +The +.Nm inetd +program +rereads its configuration file when it receives a hangup signal, +.Dv SIGHUP . +Services may be added, deleted or modified when the configuration file +is reread. +.Sh TCPMUX +.Pp +.Tn RFC 1078 +describes the TCPMUX protocol: +``A TCP client connects to a foreign host on TCP port 1. It sends the +service name followed by a carriage-return line-feed . The +service name is never case sensitive. The server replies with a +single character indicating positive (+) or negative (\-) +acknowledgment, immediately followed by an optional message of +explanation, terminated with a . If the reply was positive, +the selected protocol begins; otherwise the connection is closed.'' +The program is passed the TCP connection as file descriptors 0 and 1. +.Pp +If the TCPMUX service name begins with a ``+'', +.Nm inetd +returns the positive reply for the program. +This allows you to invoke programs that use stdin/stdout +without putting any special server code in them. +.Pp +The special service name +.Dq help +causes +.Nm inetd +to list TCPMUX services in +.Pa inetd.conf . +.Sh "EXAMPLES" +.Pp +Here are several example service entries for the various types of services: +.Bd -literal +ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l +ntalk dgram udp wait root /usr/libexec/ntalkd ntalkd +tcpmux/+date stream tcp nowait guest /bin/date date +tcpmux/phonebook stream tcp nowait guest /usr/local/bin/phonebook phonebook +.Ed +.Sh "ERROR MESSAGES" +The +.Nm inetd +server +logs error messages using +.Xr syslog 3 . +Important error messages and their explanations are: +.Bd -literal +\fIservice\fP/\fIprotocol\fP server failing (looping), service terminated. +.Ed +The number of requests for the specified service in the past minute +exceeded the limit. The limit exists to prevent a broken program +or a malicious user from swamping the system. +This message may occur for several reasons: +1) there are lots of hosts requesting the service within a short time period, +2) a 'broken' client program is requesting the service too frequently, +3) a malicious user is running a program to invoke the service in +a 'denial of service' attack, or +4) the invoked service program has an error that causes clients +to retry quickly. +Use the +.Op Fl R +option, +as described above, to change the rate limit. +Once the limit is reached, the service will be +reenabled automatically in 10 minutes. +.sp +.Bd -literal +\fIservice\fP/\fIprotocol\fP: No such user '\fIuser\fP', service ignored +\fIservice\fP/\fIprotocol\fP: getpwnam: \fIuser\fP: No such user +.Ed +No entry for +.Em user +exists in the +.Pa passwd +file. The first message +occurs when +.Nm inetd +(re)reads the configuration file. The second message occurs when the +service is invoked. +.sp +.Bd -literal +\fIservice\fP: can't set uid \fInumber\fP +\fIservice\fP: can't set gid \fInumber\fP +.Ed +The user or group ID for the entry's +.Em user +is invalid. +.Sh SEE ALSO +.Xr comsat 8 , +.Xr fingerd 8 , +.Xr ftpd 8 , +.Xr rexecd 8 , +.Xr rlogind 8 , +.Xr rshd 8 , +.Xr telnetd 8 , +.Xr tftpd 8 +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.3 . +TCPMUX is based on code and documentation by Mark Lottor. diff --git a/usr.sbin/inetd/inetd.c b/usr.sbin/inetd/inetd.c new file mode 100644 index 0000000..50dfb43 --- /dev/null +++ b/usr.sbin/inetd/inetd.c @@ -0,0 +1,1255 @@ +/* + * Copyright (c) 1983, 1991, 1993, 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1991, 1993, 1994\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)inetd.c 8.4 (Berkeley) 4/13/94"; +#endif /* not lint */ + +/* + * Inetd - Internet super-server + * + * This program invokes all internet services as needed. Connection-oriented + * services are invoked each time a connection is made, by creating a process. + * This process is passed the connection as file descriptor 0 and is expected + * to do a getpeername to find out the source host and port. + * + * Datagram oriented services are invoked when a datagram + * arrives; a process is created and passed a pending message + * on file descriptor 0. Datagram servers may either connect + * to their peer, freeing up the original socket for inetd + * to receive further messages on, or ``take over the socket'', + * processing all arriving datagrams and, eventually, timing + * out. The first type of server is said to be ``multi-threaded''; + * the second type of server ``single-threaded''. + * + * Inetd uses a configuration file which is read at startup + * and, possibly, at some later time in response to a hangup signal. + * The configuration file is ``free format'' with fields given in the + * order shown below. Continuation lines for an entry must being with + * a space or tab. All fields must be present in each entry. + * + * service name must be in /etc/services or must + * name a tcpmux service + * socket type stream/dgram/raw/rdm/seqpacket + * protocol must be in /etc/protocols + * wait/nowait single-threaded/multi-threaded + * user user to run daemon as + * server program full path name + * server program arguments maximum of MAXARGS (20) + * + * TCP services without official port numbers are handled with the + * RFC1078-based tcpmux internal service. Tcpmux listens on port 1 for + * requests. When a connection is made from a foreign host, the service + * requested is passed to tcpmux, which looks it up in the servtab list + * and returns the proper entry for the service. Tcpmux returns a + * negative reply if the service doesn't exist, otherwise the invoked + * server is expected to return the positive reply if the service type in + * inetd.conf file has the prefix "tcpmux/". If the service type has the + * prefix "tcpmux/+", tcpmux will return the positive reply for the + * process; this is for compatibility with older server code, and also + * allows you to invoke programs that use stdin/stdout without putting any + * special server code in them. Services that use tcpmux are "nowait" + * because they do not have a well-known port and hence cannot listen + * for new requests. + * + * Comment lines are indicated by a `#' in column 1. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pathnames.h" + +#define TOOMANY 40 /* don't start more than TOOMANY */ +#define CNT_INTVL 60 /* servers in CNT_INTVL sec. */ +#define RETRYTIME (60*10) /* retry after bind or server fail */ + +#define SIGBLOCK (sigmask(SIGCHLD)|sigmask(SIGHUP)|sigmask(SIGALRM)) + + +int debug = 0; +int nsock, maxsock; +fd_set allsock; +int options; +int timingout; +int toomany = TOOMANY; +struct servent *sp; + +struct servtab { + char *se_service; /* name of service */ + int se_socktype; /* type of socket to use */ + char *se_proto; /* protocol used */ + short se_wait; /* single threaded server */ + short se_checked; /* looked at during merge */ + char *se_user; /* user name to run as */ + struct biltin *se_bi; /* if built-in, description */ + char *se_server; /* server program */ +#define MAXARGV 20 + char *se_argv[MAXARGV+1]; /* program arguments */ + int se_fd; /* open descriptor */ + int se_type; /* type */ + struct sockaddr_in se_ctrladdr;/* bound address */ + int se_count; /* number started since se_time */ + struct timeval se_time; /* start of se_count */ + struct servtab *se_next; +} *servtab; + +#define NORM_TYPE 0 +#define MUX_TYPE 1 +#define MUXPLUS_TYPE 2 +#define ISMUX(sep) (((sep)->se_type == MUX_TYPE) || \ + ((sep)->se_type == MUXPLUS_TYPE)) +#define ISMUXPLUS(sep) ((sep)->se_type == MUXPLUS_TYPE) + + +void chargen_dg __P((int, struct servtab *)); +void chargen_stream __P((int, struct servtab *)); +void close_sep __P((struct servtab *)); +void config __P((int)); +void daytime_dg __P((int, struct servtab *)); +void daytime_stream __P((int, struct servtab *)); +void discard_dg __P((int, struct servtab *)); +void discard_stream __P((int, struct servtab *)); +void echo_dg __P((int, struct servtab *)); +void echo_stream __P((int, struct servtab *)); +void endconfig __P((void)); +struct servtab *enter __P((struct servtab *)); +void freeconfig __P((struct servtab *)); +struct servtab *getconfigent __P((void)); +void machtime_dg __P((int, struct servtab *)); +void machtime_stream __P((int, struct servtab *)); +char *newstr __P((char *)); +char *nextline __P((FILE *)); +void print_service __P((char *, struct servtab *)); +void reapchild __P((int)); +void retry __P((int)); +int setconfig __P((void)); +void setup __P((struct servtab *)); +char *sskip __P((char **)); +char *skip __P((char **)); +struct servtab *tcpmux __P((int)); + +struct biltin { + char *bi_service; /* internally provided service name */ + int bi_socktype; /* type of socket supported */ + short bi_fork; /* 1 if should fork before call */ + short bi_wait; /* 1 if should wait for child */ + void (*bi_fn)(); /* function which performs it */ +} biltins[] = { + /* Echo received data */ + { "echo", SOCK_STREAM, 1, 0, echo_stream }, + { "echo", SOCK_DGRAM, 0, 0, echo_dg }, + + /* Internet /dev/null */ + { "discard", SOCK_STREAM, 1, 0, discard_stream }, + { "discard", SOCK_DGRAM, 0, 0, discard_dg }, + + /* Return 32 bit time since 1970 */ + { "time", SOCK_STREAM, 0, 0, machtime_stream }, + { "time", SOCK_DGRAM, 0, 0, machtime_dg }, + + /* Return human-readable time */ + { "daytime", SOCK_STREAM, 0, 0, daytime_stream }, + { "daytime", SOCK_DGRAM, 0, 0, daytime_dg }, + + /* Familiar character generator */ + { "chargen", SOCK_STREAM, 1, 0, chargen_stream }, + { "chargen", SOCK_DGRAM, 0, 0, chargen_dg }, + + { "tcpmux", SOCK_STREAM, 1, 0, (void (*)())tcpmux }, + + { NULL } +}; + +#define NUMINT (sizeof(intab) / sizeof(struct inent)) +char *CONFIG = _PATH_INETDCONF; +char **Argv; +char *LastArg; + +int +main(argc, argv, envp) + int argc; + char *argv[], *envp[]; +{ + struct servtab *sep; + struct passwd *pwd; + struct sigvec sv; + int tmpint, ch, dofork; + pid_t pid; + char buf[50]; + + Argv = argv; + if (envp == 0 || *envp == 0) + envp = argv; + while (*envp) + envp++; + LastArg = envp[-1] + strlen(envp[-1]); + + openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON); + + while ((ch = getopt(argc, argv, "dR:")) != EOF) + switch(ch) { + case 'd': + debug = 1; + options |= SO_DEBUG; + break; + case 'R': { /* invocation rate */ + char *p; + + tmpint = strtol(optarg, &p, 0); + if (tmpint < 1 || *p) + syslog(LOG_ERR, + "-R %s: bad value for service invocation rate", + optarg); + else + toomany = tmpint; + break; + } + case '?': + default: + syslog(LOG_ERR, + "usage: inetd [-d] [-R rate] [conf-file]"); + exit(1); + } + argc -= optind; + argv += optind; + + if (argc > 0) + CONFIG = argv[0]; + if (debug == 0) { + daemon(0, 0); + } + memset(&sv, 0, sizeof(sv)); + sv.sv_mask = SIGBLOCK; + sv.sv_handler = retry; + sigvec(SIGALRM, &sv, (struct sigvec *)0); + config(SIGHUP); + sv.sv_handler = config; + sigvec(SIGHUP, &sv, (struct sigvec *)0); + sv.sv_handler = reapchild; + sigvec(SIGCHLD, &sv, (struct sigvec *)0); + + { + /* space for daemons to overwrite environment for ps */ +#define DUMMYSIZE 100 + char dummy[DUMMYSIZE]; + + (void)memset(dummy, 'x', sizeof(DUMMYSIZE) - 1); + dummy[DUMMYSIZE - 1] = '\0'; + (void)setenv("inetd_dummy", dummy, 1); + } + + for (;;) { + int n, ctrl; + fd_set readable; + + if (nsock == 0) { + (void) sigblock(SIGBLOCK); + while (nsock == 0) + sigpause(0L); + (void) sigsetmask(0L); + } + readable = allsock; + if ((n = select(maxsock + 1, &readable, (fd_set *)0, + (fd_set *)0, (struct timeval *)0)) <= 0) { + if (n < 0 && errno != EINTR) + syslog(LOG_WARNING, "select: %m"); + sleep(1); + continue; + } + for (sep = servtab; n && sep; sep = sep->se_next) + if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, &readable)) { + n--; + if (debug) + fprintf(stderr, "someone wants %s\n", + sep->se_service); + if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) { + ctrl = accept(sep->se_fd, (struct sockaddr *)0, + (int *)0); + if (debug) + fprintf(stderr, "accept, ctrl %d\n", ctrl); + if (ctrl < 0) { + if (errno != EINTR) + syslog(LOG_WARNING, + "accept (for %s): %m", + sep->se_service); + continue; + } + /* + * Call tcpmux to find the real service to exec. + */ + if (sep->se_bi && + sep->se_bi->bi_fn == (void (*)()) tcpmux) { + sep = tcpmux(ctrl); + if (sep == NULL) { + close(ctrl); + continue; + } + } + } else + ctrl = sep->se_fd; + (void) sigblock(SIGBLOCK); + pid = 0; + dofork = (sep->se_bi == 0 || sep->se_bi->bi_fork); + if (dofork) { + if (sep->se_count++ == 0) + (void)gettimeofday(&sep->se_time, + (struct timezone *)0); + else if (sep->se_count >= toomany) { + struct timeval now; + + (void)gettimeofday(&now, (struct timezone *)0); + if (now.tv_sec - sep->se_time.tv_sec > + CNT_INTVL) { + sep->se_time = now; + sep->se_count = 1; + } else { + syslog(LOG_ERR, + "%s/%s server failing (looping), service terminated", + sep->se_service, sep->se_proto); + close_sep(sep); + sigsetmask(0L); + if (!timingout) { + timingout = 1; + alarm(RETRYTIME); + } + continue; + } + } + pid = fork(); + } + if (pid < 0) { + syslog(LOG_ERR, "fork: %m"); + if (!sep->se_wait && + sep->se_socktype == SOCK_STREAM) + close(ctrl); + sigsetmask(0L); + sleep(1); + continue; + } + if (pid && sep->se_wait) { + sep->se_wait = pid; + if (sep->se_fd >= 0) { + FD_CLR(sep->se_fd, &allsock); + nsock--; + } + } + sigsetmask(0L); + if (pid == 0) { + if (debug && dofork) + setsid(); + if (dofork) { + if (debug) + fprintf(stderr, "+ Closing from %d\n", + maxsock); + for (tmpint = maxsock; tmpint > 2; tmpint--) + if (tmpint != ctrl) + close(tmpint); + } + if (sep->se_bi) + (*sep->se_bi->bi_fn)(ctrl, sep); + else { + if (debug) + fprintf(stderr, "%d execl %s\n", + getpid(), sep->se_server); + dup2(ctrl, 0); + close(ctrl); + dup2(0, 1); + dup2(0, 2); + if ((pwd = getpwnam(sep->se_user)) == NULL) { + syslog(LOG_ERR, + "%s/%s: %s: No such user", + sep->se_service, sep->se_proto, + sep->se_user); + if (sep->se_socktype != SOCK_STREAM) + recv(0, buf, sizeof (buf), 0); + _exit(1); + } + if (pwd->pw_uid) { + if (setgid(pwd->pw_gid) < 0) { + syslog(LOG_ERR, + "%s: can't set gid %d: %m", + sep->se_service, pwd->pw_gid); + _exit(1); + } + (void) initgroups(pwd->pw_name, + pwd->pw_gid); + if (setuid(pwd->pw_uid) < 0) { + syslog(LOG_ERR, + "%s: can't set uid %d: %m", + sep->se_service, pwd->pw_uid); + _exit(1); + } + } + execv(sep->se_server, sep->se_argv); + if (sep->se_socktype != SOCK_STREAM) + recv(0, buf, sizeof (buf), 0); + syslog(LOG_ERR, + "cannot execute %s: %m", sep->se_server); + _exit(1); + } + } + if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) + close(ctrl); + } + } +} + +void +reapchild(signo) + int signo; +{ + int status; + pid_t pid; + struct servtab *sep; + + for (;;) { + pid = wait3(&status, WNOHANG, (struct rusage *)0); + if (pid <= 0) + break; + if (debug) + fprintf(stderr, "%d reaped, status %#x\n", + pid, status); + for (sep = servtab; sep; sep = sep->se_next) + if (sep->se_wait == pid) { + if (status) + syslog(LOG_WARNING, + "%s: exit status 0x%x", + sep->se_server, status); + if (debug) + fprintf(stderr, "restored %s, fd %d\n", + sep->se_service, sep->se_fd); + FD_SET(sep->se_fd, &allsock); + nsock++; + sep->se_wait = 1; + } + } +} + +void +config(signo) + int signo; +{ + struct servtab *sep, *cp, **sepp; + struct passwd *pwd; + long omask; + + if (!setconfig()) { + syslog(LOG_ERR, "%s: %m", CONFIG); + return; + } + for (sep = servtab; sep; sep = sep->se_next) + sep->se_checked = 0; + while (cp = getconfigent()) { + if ((pwd = getpwnam(cp->se_user)) == NULL) { + syslog(LOG_ERR, + "%s/%s: No such user '%s', service ignored", + cp->se_service, cp->se_proto, cp->se_user); + continue; + } + for (sep = servtab; sep; sep = sep->se_next) + if (strcmp(sep->se_service, cp->se_service) == 0 && + strcmp(sep->se_proto, cp->se_proto) == 0) + break; + if (sep != 0) { + int i; + + omask = sigblock(SIGBLOCK); + /* + * sep->se_wait may be holding the pid of a daemon + * that we're waiting for. If so, don't overwrite + * it unless the config file explicitly says don't + * wait. + */ + if (cp->se_bi == 0 && + (sep->se_wait == 1 || cp->se_wait == 0)) + sep->se_wait = cp->se_wait; +#define SWAP(a, b) { char *c = a; a = b; b = c; } + if (cp->se_user) + SWAP(sep->se_user, cp->se_user); + if (cp->se_server) + SWAP(sep->se_server, cp->se_server); + for (i = 0; i < MAXARGV; i++) + SWAP(sep->se_argv[i], cp->se_argv[i]); + sigsetmask(omask); + freeconfig(cp); + if (debug) + print_service("REDO", sep); + } else { + sep = enter(cp); + if (debug) + print_service("ADD ", sep); + } + sep->se_checked = 1; + if (ISMUX(sep)) { + sep->se_fd = -1; + continue; + } + sp = getservbyname(sep->se_service, sep->se_proto); + if (sp == 0) { + syslog(LOG_ERR, "%s/%s: unknown service", + sep->se_service, sep->se_proto); + sep->se_checked = 0; + continue; + } + if (sp->s_port != sep->se_ctrladdr.sin_port) { + sep->se_ctrladdr.sin_family = AF_INET; + sep->se_ctrladdr.sin_port = sp->s_port; + if (sep->se_fd >= 0) + close_sep(sep); + } + if (sep->se_fd == -1) + setup(sep); + } + endconfig(); + /* + * Purge anything not looked at above. + */ + omask = sigblock(SIGBLOCK); + sepp = &servtab; + while (sep = *sepp) { + if (sep->se_checked) { + sepp = &sep->se_next; + continue; + } + *sepp = sep->se_next; + if (sep->se_fd >= 0) + close_sep(sep); + if (debug) + print_service("FREE", sep); + freeconfig(sep); + free((char *)sep); + } + (void) sigsetmask(omask); +} + +void +retry(signo) + int signo; +{ + struct servtab *sep; + + timingout = 0; + for (sep = servtab; sep; sep = sep->se_next) + if (sep->se_fd == -1) + setup(sep); +} + +void +setup(sep) + struct servtab *sep; +{ + int on = 1; + + if ((sep->se_fd = socket(AF_INET, sep->se_socktype, 0)) < 0) { + if (debug) + fprintf(stderr, "socket failed on %s/%s: %s\n", + sep->se_service, sep->se_proto, + strerror(errno)); + syslog(LOG_ERR, "%s/%s: socket: %m", + sep->se_service, sep->se_proto); + return; + } +#define turnon(fd, opt) \ +setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on)) + if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) && + turnon(sep->se_fd, SO_DEBUG) < 0) + syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m"); + if (turnon(sep->se_fd, SO_REUSEADDR) < 0) + syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m"); +#undef turnon + if (bind(sep->se_fd, (struct sockaddr *)&sep->se_ctrladdr, + sizeof (sep->se_ctrladdr)) < 0) { + if (debug) + fprintf(stderr, "bind failed on %s/%s: %s\n", + sep->se_service, sep->se_proto, + strerror(errno)); + syslog(LOG_ERR, "%s/%s: bind: %m", + sep->se_service, sep->se_proto); + (void) close(sep->se_fd); + sep->se_fd = -1; + if (!timingout) { + timingout = 1; + alarm(RETRYTIME); + } + return; + } + if (sep->se_socktype == SOCK_STREAM) + listen(sep->se_fd, 10); + FD_SET(sep->se_fd, &allsock); + nsock++; + if (sep->se_fd > maxsock) + maxsock = sep->se_fd; + if (debug) { + fprintf(stderr, "registered %s on %d\n", + sep->se_server, sep->se_fd); + } +} + +/* + * Finish with a service and its socket. + */ +void +close_sep(sep) + struct servtab *sep; +{ + if (sep->se_fd >= 0) { + nsock--; + FD_CLR(sep->se_fd, &allsock); + (void) close(sep->se_fd); + sep->se_fd = -1; + } + sep->se_count = 0; + /* + * Don't keep the pid of this running deamon: when reapchild() + * reaps this pid, it would erroneously increment nsock. + */ + if (sep->se_wait > 1) + sep->se_wait = 1; +} + +struct servtab * +enter(cp) + struct servtab *cp; +{ + struct servtab *sep; + long omask; + + sep = (struct servtab *)malloc(sizeof (*sep)); + if (sep == (struct servtab *)0) { + syslog(LOG_ERR, "Out of memory."); + exit(-1); + } + *sep = *cp; + sep->se_fd = -1; + omask = sigblock(SIGBLOCK); + sep->se_next = servtab; + servtab = sep; + sigsetmask(omask); + return (sep); +} + +FILE *fconfig = NULL; +struct servtab serv; +char line[LINE_MAX]; + +int +setconfig() +{ + + if (fconfig != NULL) { + fseek(fconfig, 0L, SEEK_SET); + return (1); + } + fconfig = fopen(CONFIG, "r"); + return (fconfig != NULL); +} + +void +endconfig() +{ + if (fconfig) { + (void) fclose(fconfig); + fconfig = NULL; + } +} + +struct servtab * +getconfigent() +{ + struct servtab *sep = &serv; + int argc; + char *cp, *arg; + static char TCPMUX_TOKEN[] = "tcpmux/"; +#define MUX_LEN (sizeof(TCPMUX_TOKEN)-1) + +more: + while ((cp = nextline(fconfig)) && (*cp == '#' || *cp == '\0')) + ; + if (cp == NULL) + return ((struct servtab *)0); + /* + * clear the static buffer, since some fields (se_ctrladdr, + * for example) don't get initialized here. + */ + memset((caddr_t)sep, 0, sizeof *sep); + arg = skip(&cp); + if (cp == NULL) { + /* got an empty line containing just blanks/tabs. */ + goto more; + } + if (strncmp(arg, TCPMUX_TOKEN, MUX_LEN) == 0) { + char *c = arg + MUX_LEN; + if (*c == '+') { + sep->se_type = MUXPLUS_TYPE; + c++; + } else + sep->se_type = MUX_TYPE; + sep->se_service = newstr(c); + } else { + sep->se_service = newstr(arg); + sep->se_type = NORM_TYPE; + } + arg = sskip(&cp); + if (strcmp(arg, "stream") == 0) + sep->se_socktype = SOCK_STREAM; + else if (strcmp(arg, "dgram") == 0) + sep->se_socktype = SOCK_DGRAM; + else if (strcmp(arg, "rdm") == 0) + sep->se_socktype = SOCK_RDM; + else if (strcmp(arg, "seqpacket") == 0) + sep->se_socktype = SOCK_SEQPACKET; + else if (strcmp(arg, "raw") == 0) + sep->se_socktype = SOCK_RAW; + else + sep->se_socktype = -1; + sep->se_proto = newstr(sskip(&cp)); + arg = sskip(&cp); + sep->se_wait = strcmp(arg, "wait") == 0; + if (ISMUX(sep)) { + /* + * Silently enforce "nowait" for TCPMUX services since + * they don't have an assigned port to listen on. + */ + sep->se_wait = 0; + + if (strcmp(sep->se_proto, "tcp")) { + syslog(LOG_ERR, + "%s: bad protocol for tcpmux service %s", + CONFIG, sep->se_service); + goto more; + } + if (sep->se_socktype != SOCK_STREAM) { + syslog(LOG_ERR, + "%s: bad socket type for tcpmux service %s", + CONFIG, sep->se_service); + goto more; + } + } + sep->se_user = newstr(sskip(&cp)); + sep->se_server = newstr(sskip(&cp)); + if (strcmp(sep->se_server, "internal") == 0) { + struct biltin *bi; + + for (bi = biltins; bi->bi_service; bi++) + if (bi->bi_socktype == sep->se_socktype && + strcmp(bi->bi_service, sep->se_service) == 0) + break; + if (bi->bi_service == 0) { + syslog(LOG_ERR, "internal service %s unknown", + sep->se_service); + goto more; + } + sep->se_bi = bi; + sep->se_wait = bi->bi_wait; + } else + sep->se_bi = NULL; + argc = 0; + for (arg = skip(&cp); cp; arg = skip(&cp)) + if (argc < MAXARGV) + sep->se_argv[argc++] = newstr(arg); + while (argc <= MAXARGV) + sep->se_argv[argc++] = NULL; + return (sep); +} + +void +freeconfig(cp) + struct servtab *cp; +{ + int i; + + if (cp->se_service) + free(cp->se_service); + if (cp->se_proto) + free(cp->se_proto); + if (cp->se_user) + free(cp->se_user); + if (cp->se_server) + free(cp->se_server); + for (i = 0; i < MAXARGV; i++) + if (cp->se_argv[i]) + free(cp->se_argv[i]); +} + + +/* + * Safe skip - if skip returns null, log a syntax error in the + * configuration file and exit. + */ +char * +sskip(cpp) + char **cpp; +{ + char *cp; + + cp = skip(cpp); + if (cp == NULL) { + syslog(LOG_ERR, "%s: syntax error", CONFIG); + exit(-1); + } + return (cp); +} + +char * +skip(cpp) + char **cpp; +{ + char *cp = *cpp; + char *start; + +again: + while (*cp == ' ' || *cp == '\t') + cp++; + if (*cp == '\0') { + int c; + + c = getc(fconfig); + (void) ungetc(c, fconfig); + if (c == ' ' || c == '\t') + if (cp = nextline(fconfig)) + goto again; + *cpp = (char *)0; + return ((char *)0); + } + start = cp; + while (*cp && *cp != ' ' && *cp != '\t') + cp++; + if (*cp != '\0') + *cp++ = '\0'; + *cpp = cp; + return (start); +} + +char * +nextline(fd) + FILE *fd; +{ + char *cp; + + if (fgets(line, sizeof (line), fd) == NULL) + return ((char *)0); + cp = strchr(line, '\n'); + if (cp) + *cp = '\0'; + return (line); +} + +char * +newstr(cp) + char *cp; +{ + if (cp = strdup(cp ? cp : "")) + return (cp); + syslog(LOG_ERR, "strdup: %m"); + exit(-1); +} + +void +setproctitle(a, s) + char *a; + int s; +{ + int size; + char *cp; + struct sockaddr_in sin; + char buf[80]; + + cp = Argv[0]; + size = sizeof(sin); + if (getpeername(s, (struct sockaddr *)&sin, &size) == 0) + (void) sprintf(buf, "-%s [%s]", a, inet_ntoa(sin.sin_addr)); + else + (void) sprintf(buf, "-%s", a); + strncpy(cp, buf, LastArg - cp); + cp += strlen(cp); + while (cp < LastArg) + *cp++ = ' '; +} + +/* + * Internet services provided internally by inetd: + */ +#define BUFSIZE 8192 + +/* ARGSUSED */ +void +echo_stream(s, sep) /* Echo service -- echo data back */ + int s; + struct servtab *sep; +{ + char buffer[BUFSIZE]; + int i; + + setproctitle(sep->se_service, s); + while ((i = read(s, buffer, sizeof(buffer))) > 0 && + write(s, buffer, i) > 0) + ; + exit(0); +} + +/* ARGSUSED */ +void +echo_dg(s, sep) /* Echo service -- echo data back */ + int s; + struct servtab *sep; +{ + char buffer[BUFSIZE]; + int i, size; + struct sockaddr sa; + + size = sizeof(sa); + if ((i = recvfrom(s, buffer, sizeof(buffer), 0, &sa, &size)) < 0) + return; + (void) sendto(s, buffer, i, 0, &sa, sizeof(sa)); +} + +/* ARGSUSED */ +void +discard_stream(s, sep) /* Discard service -- ignore data */ + int s; + struct servtab *sep; +{ + int ret; + char buffer[BUFSIZE]; + + setproctitle(sep->se_service, s); + while (1) { + while ((ret = read(s, buffer, sizeof(buffer))) > 0) + ; + if (ret == 0 || errno != EINTR) + break; + } + exit(0); +} + +/* ARGSUSED */ +void +discard_dg(s, sep) /* Discard service -- ignore data */ + int s; + struct servtab *sep; +{ + char buffer[BUFSIZE]; + + (void) read(s, buffer, sizeof(buffer)); +} + +#include +#define LINESIZ 72 +char ring[128]; +char *endring; + +void +initring() +{ + int i; + + endring = ring; + + for (i = 0; i <= 128; ++i) + if (isprint(i)) + *endring++ = i; +} + +/* ARGSUSED */ +void +chargen_stream(s, sep) /* Character generator */ + int s; + struct servtab *sep; +{ + int len; + char *rs, text[LINESIZ+2]; + + setproctitle(sep->se_service, s); + + if (!endring) { + initring(); + rs = ring; + } + + text[LINESIZ] = '\r'; + text[LINESIZ + 1] = '\n'; + for (rs = ring;;) { + if ((len = endring - rs) >= LINESIZ) + memmove(text, rs, LINESIZ); + else { + memmove(text, rs, len); + memmove(text + len, ring, LINESIZ - len); + } + if (++rs == endring) + rs = ring; + if (write(s, text, sizeof(text)) != sizeof(text)) + break; + } + exit(0); +} + +/* ARGSUSED */ +void +chargen_dg(s, sep) /* Character generator */ + int s; + struct servtab *sep; +{ + struct sockaddr sa; + static char *rs; + int len, size; + char text[LINESIZ+2]; + + if (endring == 0) { + initring(); + rs = ring; + } + + size = sizeof(sa); + if (recvfrom(s, text, sizeof(text), 0, &sa, &size) < 0) + return; + + if ((len = endring - rs) >= LINESIZ) + memmove(text, rs, LINESIZ); + else { + memmove(text, rs, len); + memmove(text + len, ring, LINESIZ - len); + } + if (++rs == endring) + rs = ring; + text[LINESIZ] = '\r'; + text[LINESIZ + 1] = '\n'; + (void) sendto(s, text, sizeof(text), 0, &sa, sizeof(sa)); +} + +/* + * Return a machine readable date and time, in the form of the + * number of seconds since midnight, Jan 1, 1900. Since gettimeofday + * returns the number of seconds since midnight, Jan 1, 1970, + * we must add 2208988800 seconds to this figure to make up for + * some seventy years Bell Labs was asleep. + */ + +long +machtime() +{ + struct timeval tv; + + if (gettimeofday(&tv, (struct timezone *)0) < 0) { + if (debug) + fprintf(stderr, "Unable to get time of day\n"); + return (0L); + } +#define OFFSET ((u_long)25567 * 24*60*60) + return (htonl((long)(tv.tv_sec + OFFSET))); +#undef OFFSET +} + +/* ARGSUSED */ +void +machtime_stream(s, sep) + int s; + struct servtab *sep; +{ + long result; + + result = machtime(); + (void) write(s, (char *) &result, sizeof(result)); +} + +/* ARGSUSED */ +void +machtime_dg(s, sep) + int s; + struct servtab *sep; +{ + long result; + struct sockaddr sa; + int size; + + size = sizeof(sa); + if (recvfrom(s, (char *)&result, sizeof(result), 0, &sa, &size) < 0) + return; + result = machtime(); + (void) sendto(s, (char *) &result, sizeof(result), 0, &sa, sizeof(sa)); +} + +/* ARGSUSED */ +void +daytime_stream(s, sep) /* Return human-readable time of day */ + int s; + struct servtab *sep; +{ + char buffer[256]; + time_t clock; + + clock = time((time_t *) 0); + + (void) sprintf(buffer, "%.24s\r\n", ctime(&clock)); + (void) write(s, buffer, strlen(buffer)); +} + +/* ARGSUSED */ +void +daytime_dg(s, sep) /* Return human-readable time of day */ + int s; + struct servtab *sep; +{ + char buffer[256]; + time_t clock; + struct sockaddr sa; + int size; + + clock = time((time_t *) 0); + + size = sizeof(sa); + if (recvfrom(s, buffer, sizeof(buffer), 0, &sa, &size) < 0) + return; + (void) sprintf(buffer, "%.24s\r\n", ctime(&clock)); + (void) sendto(s, buffer, strlen(buffer), 0, &sa, sizeof(sa)); +} + +/* + * print_service: + * Dump relevant information to stderr + */ +void +print_service(action, sep) + char *action; + struct servtab *sep; +{ + fprintf(stderr, + "%s: %s proto=%s, wait=%d, user=%s builtin=%x server=%s\n", + action, sep->se_service, sep->se_proto, + sep->se_wait, sep->se_user, (int)sep->se_bi, sep->se_server); +} + +/* + * Based on TCPMUX.C by Mark K. Lottor November 1988 + * sri-nic::ps:tcpmux.c + */ + + +static int /* # of characters upto \r,\n or \0 */ +getline(fd, buf, len) + int fd; + char *buf; + int len; +{ + int count = 0, n; + + do { + n = read(fd, buf, len-count); + if (n == 0) + return (count); + if (n < 0) + return (-1); + while (--n >= 0) { + if (*buf == '\r' || *buf == '\n' || *buf == '\0') + return (count); + count++; + buf++; + } + } while (count < len); + return (count); +} + +#define MAX_SERV_LEN (256+2) /* 2 bytes for \r\n */ + +#define strwrite(fd, buf) (void) write(fd, buf, sizeof(buf)-1) + +struct servtab * +tcpmux(s) + int s; +{ + struct servtab *sep; + char service[MAX_SERV_LEN+1]; + int len; + + /* Get requested service name */ + if ((len = getline(s, service, MAX_SERV_LEN)) < 0) { + strwrite(s, "-Error reading service name\r\n"); + return (NULL); + } + service[len] = '\0'; + + if (debug) + fprintf(stderr, "tcpmux: someone wants %s\n", service); + + /* + * Help is a required command, and lists available services, + * one per line. + */ + if (!strcasecmp(service, "help")) { + for (sep = servtab; sep; sep = sep->se_next) { + if (!ISMUX(sep)) + continue; + (void)write(s,sep->se_service,strlen(sep->se_service)); + strwrite(s, "\r\n"); + } + return (NULL); + } + + /* Try matching a service in inetd.conf with the request */ + for (sep = servtab; sep; sep = sep->se_next) { + if (!ISMUX(sep)) + continue; + if (!strcasecmp(service, sep->se_service)) { + if (ISMUXPLUS(sep)) { + strwrite(s, "+Go\r\n"); + } + return (sep); + } + } + strwrite(s, "-Service not available\r\n"); + return (NULL); +} diff --git a/usr.sbin/inetd/pathnames.h b/usr.sbin/inetd/pathnames.h new file mode 100644 index 0000000..e8ae3cd --- /dev/null +++ b/usr.sbin/inetd/pathnames.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 1989, 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.1 (Berkeley) 6/6/93 + */ + +#include + +#define _PATH_INETDCONF "/etc/inetd.conf" diff --git a/usr.sbin/iostat/Makefile b/usr.sbin/iostat/Makefile new file mode 100644 index 0000000..e9287e3 --- /dev/null +++ b/usr.sbin/iostat/Makefile @@ -0,0 +1,11 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= iostat +CFLAGS+=-I/sys -I${.CURDIR}/../../usr.bin/vmstat +MAN8= iostat.0 +DPADD= ${LIBKVM} +LDADD= -lkvm +BINGRP= kmem +BINMODE=2555 + +.include diff --git a/usr.sbin/iostat/iostat.8 b/usr.sbin/iostat/iostat.8 new file mode 100644 index 0000000..48ef627 --- /dev/null +++ b/usr.sbin/iostat/iostat.8 @@ -0,0 +1,142 @@ +.\" 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. +.\" +.\" @(#)iostat.8 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt IOSTAT 8 +.Os BSD 4 +.Sh NAME +.Nm iostat +.Nd report +.Tn I/O +statistics +.Sh SYNOPSIS +.Nm iostat +.Op Fl c Ar count +.Op Fl M Ar core +.Op Fl N Ar system +.Op Fl w Ar wait +.Op Ar drives +.Sh DESCRIPTION +.Nm Iostat +displays kernel +.Tn I/O +statistics on terminal, disk and cpu +operations. +.Pp +The options are as follows: +.Bl -tag -width flag +.It Fl c +Repeat the display +.Ar count +times. +The first display is for the time since a reboot and each subsequent +report is for the time period since the last display. +If no +.Ar wait +interval is specified, the default is 1 second. +.It Fl M +Extract values associated with the name list from the specified core +instead of the default +.Dq Pa /dev/kmem . +.It Fl N +Extract the name list from the specified system instead of the default +.Dq Pa /vmunix . +.It Fl w +Pause +.Ar wait +seconds between each display. +If no repeat +.Ar count +is specified, the default is infinity. +.El +.Pp +.Nm Iostat +displays its information in the following format: +.Bl -tag -width flag +.It tty +.Bl -tag -width indent -compact +.It tin +characters read from terminals +.It tout +characters written to terminals +.El +.It disks +Disk operations (this field is system dependent). +The header of the field is the disk name and unit number. +If more than four disk drives are configured in the system, +.Nm iostat +displays only the first four drives. +To force +.Nm iostat +to display specific drives, their names may be supplied on the command +line. +.Pp +.Bl -tag -width indent -compact +.It sps +sectors transferred per second +.It tps +transfers per second +.It msps +milliseconds per average seek (including implied +seeks and rotational latency) +.El +.It cpu +.Bl -tag -width indent -compact +.It \&us +% of cpu time in user mode +.It \&ni +% of cpu time in user mode running niced processes +.It \&sy +% of cpu time in system mode +.It \&id +% of cpu time in idle mode +.El +.El +.Sh FILES +.Bl -tag -width /dev/kmem -compact +.It Pa /vmunix +Default kernel namelist. +.It Pa /dev/kmem +Default memory file. +.El +.Sh SEE ALSO +.Xr fstat 1 , +.Xr netstat 1 , +.Xr nfsstat 1 , +.Xr \&ps 1 , +.Xr systat 1 , +.Xr vmstat 1 , +.Xr pstat 8 +.Pp +The sections starting with ``Interpreting system activity'' in +.%T "Installing and Operating 4.3BSD" . diff --git a/usr.sbin/iostat/iostat.c b/usr.sbin/iostat/iostat.c new file mode 100644 index 0000000..a41cac4 --- /dev/null +++ b/usr.sbin/iostat/iostat.c @@ -0,0 +1,391 @@ +/*- + * Copyright (c) 1986, 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1986, 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)iostat.c 8.2 (Berkeley) 1/26/94"; +#endif /* not lint */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct nlist namelist[] = { +#define X_DK_TIME 0 + { "_dk_time" }, +#define X_DK_XFER 1 + { "_dk_xfer" }, +#define X_DK_WDS 2 + { "_dk_wds" }, +#define X_TK_NIN 3 + { "_tk_nin" }, +#define X_TK_NOUT 4 + { "_tk_nout" }, +#define X_DK_SEEK 5 + { "_dk_seek" }, +#define X_CP_TIME 6 + { "_cp_time" }, +#define X_DK_WPMS 7 + { "_dk_wpms" }, +#define X_HZ 8 + { "_hz" }, +#define X_STATHZ 9 + { "_stathz" }, +#define X_DK_NDRIVE 10 + { "_dk_ndrive" }, +#define X_END 10 +#if defined(hp300) || defined(luna68k) +#define X_HPDINIT (X_END+1) + { "_hp_dinit" }, +#endif +#ifdef mips +#define X_SCSI_DINIT (X_END+1) + { "_scsi_dinit" }, +#endif +#ifdef tahoe +#define X_VBDINIT (X_END+1) + { "_vbdinit" }, +#endif +#ifdef vax + { "_mbdinit" }, +#define X_MBDINIT (X_END+1) + { "_ubdinit" }, +#define X_UBDINIT (X_END+2) +#endif + { NULL }, +}; + +struct _disk { + long cp_time[CPUSTATES]; + long *dk_time; + long *dk_wds; + long *dk_seek; + long *dk_xfer; + long tk_nin; + long tk_nout; +} cur, last; + +kvm_t *kd; +double etime; +long *dk_wpms; +int dk_ndrive, *dr_select, hz, kmemfd, ndrives; +char **dr_name; + +#define nlread(x, v) \ + kvm_read(kd, namelist[x].n_value, &(v), sizeof(v)) + +#include "names.c" /* XXX */ + +void cpustats __P((void)); +void dkstats __P((void)); +void phdr __P((int)); +void usage __P((void)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + register int i; + long tmp; + int ch, hdrcnt, reps, interval, stathz, ndrives; + char **cp, *memf, *nlistf, buf[30]; + char errbuf[_POSIX2_LINE_MAX]; + + interval = reps = 0; + nlistf = memf = NULL; + while ((ch = getopt(argc, argv, "c:M:N:w:")) != EOF) + switch(ch) { + case 'c': + if ((reps = atoi(optarg)) <= 0) + errx(1, "repetition count <= 0."); + break; + case 'M': + memf = optarg; + break; + case 'N': + nlistf = optarg; + break; + case 'w': + if ((interval = atoi(optarg)) <= 0) + errx(1, "interval <= 0."); + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + /* + * Discard setgid privileges if not the running kernel so that bad + * guys can't print interesting stuff from kernel memory. + */ + if (nlistf != NULL || memf != NULL) + setgid(getgid()); + + kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); + if (kd == 0) + errx(1, "kvm_openfiles: %s", errbuf); + if (kvm_nlist(kd, namelist) == -1) + errx(1, "kvm_nlist: %s", kvm_geterr(kd)); + if (namelist[X_DK_NDRIVE].n_type == 0) + errx(1, "dk_ndrive not found in namelist"); + (void)nlread(X_DK_NDRIVE, dk_ndrive); + if (dk_ndrive <= 0) + errx(1, "invalid dk_ndrive %d\n", dk_ndrive); + + cur.dk_time = calloc(dk_ndrive, sizeof(long)); + cur.dk_wds = calloc(dk_ndrive, sizeof(long)); + cur.dk_seek = calloc(dk_ndrive, sizeof(long)); + cur.dk_xfer = calloc(dk_ndrive, sizeof(long)); + last.dk_time = calloc(dk_ndrive, sizeof(long)); + last.dk_wds = calloc(dk_ndrive, sizeof(long)); + last.dk_seek = calloc(dk_ndrive, sizeof(long)); + last.dk_xfer = calloc(dk_ndrive, sizeof(long)); + dr_select = calloc(dk_ndrive, sizeof(int)); + dr_name = calloc(dk_ndrive, sizeof(char *)); + dk_wpms = calloc(dk_ndrive, sizeof(long)); + + for (i = 0; i < dk_ndrive; i++) { + (void)sprintf(buf, "dk%d", i); + dr_name[i] = strdup(buf); + } + if (!read_names()) + exit(1); + (void)nlread(X_HZ, hz); + (void)nlread(X_STATHZ, stathz); + if (stathz) + hz = stathz; + (void)kvm_read(kd, namelist[X_DK_WPMS].n_value, dk_wpms, + dk_ndrive * sizeof(dk_wpms)); + + /* + * Choose drives to be displayed. Priority goes to (in order) drives + * supplied as arguments and default drives. If everything isn't + * filled in and there are drives not taken care of, display the first + * few that fit. + * + * The backward compatibility #ifdefs permit the syntax: + * iostat [ drives ] [ interval [ count ] ] + */ +#define BACKWARD_COMPATIBILITY + for (ndrives = 0; *argv; ++argv) { +#ifdef BACKWARD_COMPATIBILITY + if (isdigit(**argv)) + break; +#endif + for (i = 0; i < dk_ndrive; i++) { + if (strcmp(dr_name[i], *argv)) + continue; + dr_select[i] = 1; + ++ndrives; + } + } +#ifdef BACKWARD_COMPATIBILITY + if (*argv) { + interval = atoi(*argv); + if (*++argv) + reps = atoi(*argv); + } +#endif + + if (interval) { + if (!reps) + reps = -1; + } else + if (reps) + interval = 1; + + for (i = 0; i < dk_ndrive && ndrives < 4; i++) { + if (dr_select[i] || dk_wpms[i] == 0) + continue; + for (cp = defdrives; *cp; cp++) + if (strcmp(dr_name[i], *cp) == 0) { + dr_select[i] = 1; + ++ndrives; + break; + } + } + for (i = 0; i < dk_ndrive && ndrives < 4; i++) { + if (dr_select[i]) + continue; + dr_select[i] = 1; + ++ndrives; + } + + (void)signal(SIGCONT, phdr); + + for (hdrcnt = 1;;) { + if (!--hdrcnt) { + phdr(0); + hdrcnt = 20; + } + (void)kvm_read(kd, namelist[X_DK_TIME].n_value, + cur.dk_time, dk_ndrive * sizeof(long)); + (void)kvm_read(kd, namelist[X_DK_XFER].n_value, + cur.dk_xfer, dk_ndrive * sizeof(long)); + (void)kvm_read(kd, namelist[X_DK_WDS].n_value, + cur.dk_wds, dk_ndrive * sizeof(long)); + (void)kvm_read(kd, namelist[X_DK_SEEK].n_value, + cur.dk_seek, dk_ndrive * sizeof(long)); + (void)kvm_read(kd, namelist[X_TK_NIN].n_value, + &cur.tk_nin, sizeof(cur.tk_nin)); + (void)kvm_read(kd, namelist[X_TK_NOUT].n_value, + &cur.tk_nout, sizeof(cur.tk_nout)); + (void)kvm_read(kd, namelist[X_CP_TIME].n_value, + cur.cp_time, sizeof(cur.cp_time)); + for (i = 0; i < dk_ndrive; i++) { + if (!dr_select[i]) + continue; +#define X(fld) tmp = cur.fld[i]; cur.fld[i] -= last.fld[i]; last.fld[i] = tmp + X(dk_xfer); + X(dk_seek); + X(dk_wds); + X(dk_time); + } + tmp = cur.tk_nin; + cur.tk_nin -= last.tk_nin; + last.tk_nin = tmp; + tmp = cur.tk_nout; + cur.tk_nout -= last.tk_nout; + last.tk_nout = tmp; + etime = 0; + for (i = 0; i < CPUSTATES; i++) { + X(cp_time); + etime += cur.cp_time[i]; + } + if (etime == 0.0) + etime = 1.0; + etime /= (float)hz; + (void)printf("%4.0f%5.0f", + cur.tk_nin / etime, cur.tk_nout / etime); + dkstats(); + cpustats(); + (void)printf("\n"); + (void)fflush(stdout); + + if (reps >= 0 && --reps <= 0) + break; + (void)sleep(interval); + } + exit(0); +} + +/* ARGUSED */ +void +phdr(signo) + int signo; +{ + register int i; + + (void)printf(" tty"); + for (i = 0; i < dk_ndrive; i++) + if (dr_select[i]) + (void)printf(" %3.3s ", dr_name[i]); + (void)printf(" cpu\n tin tout"); + for (i = 0; i < dk_ndrive; i++) + if (dr_select[i]) + (void)printf(" sps tps msps "); + (void)printf(" us ni sy id\n"); +} + +void +dkstats() +{ + register int dn; + double atime, itime, msps, words, xtime; + + for (dn = 0; dn < dk_ndrive; ++dn) { + if (!dr_select[dn]) + continue; + words = cur.dk_wds[dn] * 32; /* words xfer'd */ + (void)printf("%4.0f", /* sectors */ + words / (DEV_BSIZE / 2) / etime); + + (void)printf("%4.0f", cur.dk_xfer[dn] / etime); + + if (dk_wpms[dn] && cur.dk_xfer[dn]) { + atime = cur.dk_time[dn]; /* ticks disk busy */ + atime /= (float)hz; /* ticks to seconds */ + xtime = words / dk_wpms[dn]; /* transfer time */ + itime = atime - xtime; /* time not xfer'ing */ + if (itime < 0) + msps = 0; + else + msps = itime * 1000 / cur.dk_xfer[dn]; + } else + msps = 0; + (void)printf("%5.1f ", msps); + } +} + +void +cpustats() +{ + register int state; + double time; + + time = 0; + for (state = 0; state < CPUSTATES; ++state) + time += cur.cp_time[state]; + for (state = 0; state < CPUSTATES; ++state) + (void)printf("%3.0f", + 100. * cur.cp_time[state] / (time ? time : 1)); +} + +void +usage() +{ + (void)fprintf(stderr, +"usage: iostat [-c count] [-M core] [-N system] [-w wait] [drives]\n"); + exit(1); +} diff --git a/usr.sbin/kgmon/Makefile b/usr.sbin/kgmon/Makefile new file mode 100644 index 0000000..e0ef616 --- /dev/null +++ b/usr.sbin/kgmon/Makefile @@ -0,0 +1,14 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= kgmon +MAN8= kgmon.0 +DPADD= ${LIBKVM} +LDADD= -lkvm +# +# This program may safely be run setuid-root to allow non-root +# users to start, stop, and reset profiling buffers. +# +#BINOWN=root +#BINMODE=4555 + +.include diff --git a/usr.sbin/kgmon/kgmon.8 b/usr.sbin/kgmon/kgmon.8 new file mode 100644 index 0000000..060ed2e --- /dev/null +++ b/usr.sbin/kgmon/kgmon.8 @@ -0,0 +1,122 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" @(#)kgmon.8 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt KGMON 8 +.Os BSD 4.2 +.Sh NAME +.Nm kgmon +.Nd generate a dump of the operating system's profile buffers +.Sh SYNOPSIS +.Nm kgmon +.Op Fl bhpr +.Op Fl M core +.Op Fl N system +.Sh DESCRIPTION +.Nm Kgmon +is a tool used when profiling the operating system. +When no arguments are supplied, +.Nm kgmon +indicates the state of operating system profiling as running, +off, or not configured. +(see +.Xr config 8 ) +If the +.Fl p +flag is specified, +.Nm kgmon +extracts profile data from the operating system and produces a +.Pa gmon.out +file suitable for later analysis by +.Xr gprof 1 . +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl b +Resume the collection of profile data. +.It Fl h +Stop the collection of profile data. +.It Fl p +Dump the contents of the profile buffers into a +.Pa gmon.out +file. +.It Fl r +Reset all the profile buffers. +If the +.Fl p +flag is also specified, the +.Pa gmon.out +file is generated before the buffers are reset. +.It Fl M +Extract values associated with the name list from the specified core +instead of the default ``/dev/kmem''. +.It Fl N +Extract the name list from the specified system instead of the +default ``/vmunix''. +.El +.Pp +If neither +.Fl b +nor +.Fl h +is specified, the state of profiling collection remains unchanged. +For example, if the +.Fl p +flag is specified and profile data is being collected, +profiling will be momentarily suspended, +the operating system profile buffers will be dumped, +and profiling will be immediately resumed. +.Sh FILES +.Bl -tag -width /dev/kmemx -compact +.It Pa /vmunix +the default system +.It Pa /dev/kmem +the default memory +.El +.Sh SEE ALSO +.Xr gprof 1 , +.Xr config 8 +.Sh DIAGNOSTICS +Users with only read permission on +.Pa /dev/kmem +cannot change the state +of profiling collection. +They can get a +.Pa gmon.out +file with the warning that the data may be +inconsistent if profiling is in progress. +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.2 . diff --git a/usr.sbin/kgmon/kgmon.c b/usr.sbin/kgmon/kgmon.c new file mode 100644 index 0000000..1265ce2 --- /dev/null +++ b/usr.sbin/kgmon/kgmon.c @@ -0,0 +1,520 @@ +/* + * Copyright (c) 1983, 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 copyright[] = +"@(#) Copyright (c) 1983, 1992, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)kgmon.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct nlist nl[] = { +#define N_GMONPARAM 0 + { "__gmonparam" }, +#define N_PROFHZ 1 + { "_profhz" }, + 0, +}; + +struct kvmvars { + kvm_t *kd; + struct gmonparam gpm; +}; + +int bflag, hflag, kflag, rflag, pflag; +int debug = 0; +void setprof __P((struct kvmvars *kvp, int state)); +void dumpstate __P((struct kvmvars *kvp)); +void reset __P((struct kvmvars *kvp)); + +int +main(int argc, char **argv) +{ + extern char *optarg; + extern int optind; + int ch, mode, disp, accessmode; + struct kvmvars kvmvars; + char *system, *kmemf; + + seteuid(getuid()); + kmemf = NULL; + system = NULL; + while ((ch = getopt(argc, argv, "M:N:bhpr")) != EOF) { + switch((char)ch) { + + case 'M': + kmemf = optarg; + kflag = 1; + break; + + case 'N': + system = optarg; + break; + + case 'b': + bflag = 1; + break; + + case 'h': + hflag = 1; + break; + + case 'p': + pflag = 1; + break; + + case 'r': + rflag = 1; + break; + + default: + (void)fprintf(stderr, + "usage: kgmon [-bhrp] [-M core] [-N system]\n"); + exit(1); + } + } + argc -= optind; + argv += optind; + +#define BACKWARD_COMPATIBILITY +#ifdef BACKWARD_COMPATIBILITY + if (*argv) { + system = *argv; + if (*++argv) { + kmemf = *argv; + ++kflag; + } + } +#endif + if (system == NULL) + system = _PATH_UNIX; + accessmode = openfiles(system, kmemf, &kvmvars); + mode = getprof(&kvmvars); + if (hflag) + disp = GMON_PROF_OFF; + else if (bflag) + disp = GMON_PROF_ON; + else + disp = mode; + if (pflag) + dumpstate(&kvmvars); + if (rflag) + reset(&kvmvars); + if (accessmode == O_RDWR) + setprof(&kvmvars, disp); + (void)fprintf(stdout, "kgmon: kernel profiling is %s.\n", + disp == GMON_PROF_OFF ? "off" : "running"); + return (0); +} + +/* + * Check that profiling is enabled and open any ncessary files. + */ +openfiles(system, kmemf, kvp) + char *system; + char *kmemf; + struct kvmvars *kvp; +{ + int mib[3], state, size, openmode; + char errbuf[_POSIX2_LINE_MAX]; + + if (!kflag) { + mib[0] = CTL_KERN; + mib[1] = KERN_PROF; + mib[2] = GPROF_STATE; + size = sizeof state; + if (sysctl(mib, 3, &state, &size, NULL, 0) < 0) { + (void)fprintf(stderr, + "kgmon: profiling not defined in kernel.\n"); + exit(20); + } + if (!(bflag || hflag || rflag || + (pflag && state == GMON_PROF_ON))) + return (O_RDONLY); + (void)seteuid(0); + if (sysctl(mib, 3, NULL, NULL, &state, size) >= 0) + return (O_RDWR); + (void)seteuid(getuid()); + kern_readonly(state); + return (O_RDONLY); + } + openmode = (bflag || hflag || pflag || rflag) ? O_RDWR : O_RDONLY; + kvp->kd = kvm_openfiles(system, kmemf, NULL, openmode, errbuf); + if (kvp->kd == NULL) { + if (openmode == O_RDWR) { + openmode = O_RDONLY; + kvp->kd = kvm_openfiles(system, kmemf, NULL, O_RDONLY, + errbuf); + } + if (kvp->kd == NULL) { + (void)fprintf(stderr, "kgmon: kvm_openfiles: %s\n", + errbuf); + exit(2); + } + kern_readonly(GMON_PROF_ON); + } + if (kvm_nlist(kvp->kd, nl) < 0) { + (void)fprintf(stderr, "kgmon: %s: no namelist\n", system); + exit(3); + } + if (!nl[N_GMONPARAM].n_value) { + (void)fprintf(stderr, + "kgmon: profiling not defined in kernel.\n"); + exit(20); + } + return (openmode); +} + +/* + * Suppress options that require a writable kernel. + */ +kern_readonly(mode) + int mode; +{ + + (void)fprintf(stderr, "kgmon: kernel read-only: "); + if (pflag && mode == GMON_PROF_ON) + (void)fprintf(stderr, "data may be inconsistent\n"); + if (rflag) + (void)fprintf(stderr, "-r supressed\n"); + if (bflag) + (void)fprintf(stderr, "-b supressed\n"); + if (hflag) + (void)fprintf(stderr, "-h supressed\n"); + rflag = bflag = hflag = 0; +} + +/* + * Get the state of kernel profiling. + */ +getprof(kvp) + struct kvmvars *kvp; +{ + int mib[3], size; + + if (kflag) { + size = kvm_read(kvp->kd, nl[N_GMONPARAM].n_value, &kvp->gpm, + sizeof kvp->gpm); + } else { + mib[0] = CTL_KERN; + mib[1] = KERN_PROF; + mib[2] = GPROF_GMONPARAM; + size = sizeof kvp->gpm; + if (sysctl(mib, 3, &kvp->gpm, &size, NULL, 0) < 0) + size = 0; + } + if (size != sizeof kvp->gpm) { + (void)fprintf(stderr, "kgmon: cannot get gmonparam: %s\n", + kflag ? kvm_geterr(kvp->kd) : strerror(errno)); + exit (4); + } + return (kvp->gpm.state); +} + +/* + * Enable or disable kernel profiling according to the state variable. + */ +void +setprof(kvp, state) + struct kvmvars *kvp; + int state; +{ + struct gmonparam *p = (struct gmonparam *)nl[N_GMONPARAM].n_value; + int mib[3], sz, oldstate; + + sz = sizeof(state); + if (!kflag) { + mib[0] = CTL_KERN; + mib[1] = KERN_PROF; + mib[2] = GPROF_STATE; + if (sysctl(mib, 3, &oldstate, &sz, NULL, 0) < 0) + goto bad; + if (oldstate == state) + return; + (void)seteuid(0); + if (sysctl(mib, 3, NULL, NULL, &state, sz) >= 0) { + (void)seteuid(getuid()); + return; + } + (void)seteuid(getuid()); + } else if (kvm_write(kvp->kd, (u_long)&p->state, (void *)&state, sz) + == sz) + return; +bad: + (void)fprintf(stderr, "kgmon: warning: cannot turn profiling %s\n", + state == GMON_PROF_OFF ? "off" : "on"); +} + +/* + * Build the gmon.out file. + */ +void +dumpstate(kvp) + struct kvmvars *kvp; +{ + register FILE *fp; + struct rawarc rawarc; + struct tostruct *tos; + u_long frompc, addr; + u_short *froms, *tickbuf; + int mib[3], i; + struct gmonhdr h; + int fromindex, endfrom, toindex; + + setprof(kvp, GMON_PROF_OFF); + fp = fopen("gmon.out", "w"); + if (fp == 0) { + perror("gmon.out"); + return; + } + + /* + * Build the gmon header and write it to a file. + */ + bzero(&h, sizeof(h)); + h.lpc = kvp->gpm.lowpc; + h.hpc = kvp->gpm.highpc; + h.ncnt = kvp->gpm.kcountsize + sizeof(h); + h.version = GMONVERSION; + h.profrate = getprofhz(kvp); + fwrite((char *)&h, sizeof(h), 1, fp); + + /* + * Write out the tick buffer. + */ + mib[0] = CTL_KERN; + mib[1] = KERN_PROF; + if ((tickbuf = (u_short *)malloc(kvp->gpm.kcountsize)) == NULL) { + fprintf(stderr, "kgmon: cannot allocate kcount space\n"); + exit (5); + } + if (kflag) { + i = kvm_read(kvp->kd, (u_long)kvp->gpm.kcount, (void *)tickbuf, + kvp->gpm.kcountsize); + } else { + mib[2] = GPROF_COUNT; + i = kvp->gpm.kcountsize; + if (sysctl(mib, 3, tickbuf, &i, NULL, 0) < 0) + i = 0; + } + if (i != kvp->gpm.kcountsize) { + (void)fprintf(stderr, "kgmon: read ticks: read %u, got %d: %s", + kvp->gpm.kcountsize, i, + kflag ? kvm_geterr(kvp->kd) : strerror(errno)); + exit(6); + } + if ((fwrite(tickbuf, kvp->gpm.kcountsize, 1, fp)) != 1) { + perror("kgmon: writing tocks to gmon.out"); + exit(7); + } + free(tickbuf); + + /* + * Write out the arc info. + */ + if ((froms = (u_short *)malloc(kvp->gpm.fromssize)) == NULL) { + fprintf(stderr, "kgmon: cannot allocate froms space\n"); + exit (8); + } + if (kflag) { + i = kvm_read(kvp->kd, (u_long)kvp->gpm.froms, (void *)froms, + kvp->gpm.fromssize); + } else { + mib[2] = GPROF_FROMS; + i = kvp->gpm.fromssize; + if (sysctl(mib, 3, froms, &i, NULL, 0) < 0) + i = 0; + } + if (i != kvp->gpm.fromssize) { + (void)fprintf(stderr, "kgmon: read froms: read %u, got %d: %s", + kvp->gpm.fromssize, i, + kflag ? kvm_geterr(kvp->kd) : strerror(errno)); + exit(9); + } + if ((tos = (struct tostruct *)malloc(kvp->gpm.tossize)) == NULL) { + fprintf(stderr, "kgmon: cannot allocate tos space\n"); + exit(10); + } + if (kflag) { + i = kvm_read(kvp->kd, (u_long)kvp->gpm.tos, (void *)tos, + kvp->gpm.tossize); + } else { + mib[2] = GPROF_TOS; + i = kvp->gpm.tossize; + if (sysctl(mib, 3, tos, &i, NULL, 0) < 0) + i = 0; + } + if (i != kvp->gpm.tossize) { + (void)fprintf(stderr, "kgmon: read tos: read %u, got %d: %s", + kvp->gpm.tossize, i, + kflag ? kvm_geterr(kvp->kd) : strerror(errno)); + exit(11); + } + if (debug) + (void)fprintf(stderr, "kgmon: lowpc 0x%x, textsize 0x%x\n", + kvp->gpm.lowpc, kvp->gpm.textsize); + endfrom = kvp->gpm.fromssize / sizeof(*froms); + for (fromindex = 0; fromindex < endfrom; ++fromindex) { + if (froms[fromindex] == 0) + continue; + frompc = (u_long)kvp->gpm.lowpc + + (fromindex * kvp->gpm.hashfraction * sizeof(*froms)); + for (toindex = froms[fromindex]; toindex != 0; + toindex = tos[toindex].link) { + if (debug) + (void)fprintf(stderr, + "%s: [mcleanup] frompc 0x%x selfpc 0x%x count %d\n", + "kgmon", frompc, tos[toindex].selfpc, + tos[toindex].count); + rawarc.raw_frompc = frompc; + rawarc.raw_selfpc = (u_long)tos[toindex].selfpc; + rawarc.raw_count = tos[toindex].count; + fwrite((char *)&rawarc, sizeof(rawarc), 1, fp); + } + } + fclose(fp); +} + +/* + * Get the profiling rate. + */ +int +getprofhz(kvp) + struct kvmvars *kvp; +{ + int mib[2], size, profrate; + struct clockinfo clockrate; + + if (kflag) { + profrate = 1; + if (kvm_read(kvp->kd, nl[N_PROFHZ].n_value, &profrate, + sizeof profrate) != sizeof profrate) + (void)fprintf(stderr, "kgmon: get clockrate: %s\n", + kvm_geterr(kvp->kd)); + return (profrate); + } + mib[0] = CTL_KERN; + mib[1] = KERN_CLOCKRATE; + clockrate.profhz = 1; + size = sizeof clockrate; + if (sysctl(mib, 2, &clockrate, &size, NULL, 0) < 0) + (void)fprintf(stderr, "kgmon: get clockrate: %s\n", + strerror(errno)); + return (clockrate.profhz); +} + +/* + * Reset the kernel profiling date structures. + */ +void +reset(kvp) + struct kvmvars *kvp; +{ + char *zbuf; + u_long biggest; + int mib[3]; + + setprof(kvp, GMON_PROF_OFF); + + biggest = kvp->gpm.kcountsize; + if (kvp->gpm.fromssize > biggest) + biggest = kvp->gpm.fromssize; + if (kvp->gpm.tossize > biggest) + biggest = kvp->gpm.tossize; + if ((zbuf = (char *)malloc(biggest)) == NULL) { + fprintf(stderr, "kgmon: cannot allocate zbuf space\n"); + exit(12); + } + bzero(zbuf, biggest); + if (kflag) { + if (kvm_write(kvp->kd, (u_long)kvp->gpm.kcount, zbuf, + kvp->gpm.kcountsize) != kvp->gpm.kcountsize) { + (void)fprintf(stderr, "kgmon: tickbuf zero: %s\n", + kvm_geterr(kvp->kd)); + exit(13); + } + if (kvm_write(kvp->kd, (u_long)kvp->gpm.froms, zbuf, + kvp->gpm.fromssize) != kvp->gpm.fromssize) { + (void)fprintf(stderr, "kgmon: froms zero: %s\n", + kvm_geterr(kvp->kd)); + exit(14); + } + if (kvm_write(kvp->kd, (u_long)kvp->gpm.tos, zbuf, + kvp->gpm.tossize) != kvp->gpm.tossize) { + (void)fprintf(stderr, "kgmon: tos zero: %s\n", + kvm_geterr(kvp->kd)); + exit(15); + } + return; + } + (void)seteuid(0); + mib[0] = CTL_KERN; + mib[1] = KERN_PROF; + mib[2] = GPROF_COUNT; + if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.kcountsize) < 0) { + (void)fprintf(stderr, "kgmon: tickbuf zero: %s\n", + strerror(errno)); + exit(13); + } + mib[2] = GPROF_FROMS; + if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.fromssize) < 0) { + (void)fprintf(stderr, "kgmon: froms zero: %s\n", + strerror(errno)); + exit(14); + } + mib[2] = GPROF_TOS; + if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.tossize) < 0) { + (void)fprintf(stderr, "kgmon: tos zero: %s\n", + strerror(errno)); + exit(15); + } + (void)seteuid(getuid()); + free(zbuf); +} diff --git a/usr.sbin/kvm_mkdb/Makefile b/usr.sbin/kvm_mkdb/Makefile new file mode 100644 index 0000000..ea2b883 --- /dev/null +++ b/usr.sbin/kvm_mkdb/Makefile @@ -0,0 +1,7 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= kvm_mkdb +SRCS= kvm_mkdb.c nlist.c testdb.c +MAN8= kvm_mkdb.0 + +.include diff --git a/usr.sbin/kvm_mkdb/extern.h b/usr.sbin/kvm_mkdb/extern.h new file mode 100644 index 0000000..6d72268 --- /dev/null +++ b/usr.sbin/kvm_mkdb/extern.h @@ -0,0 +1,38 @@ +/*- + * 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. + * + * @(#)extern.h 8.1 (Berkeley) 6/6/93 + */ + +void create_knlist __P((char *, DB *)); +void error __P((char *)); +int testdb __P(()); diff --git a/usr.sbin/kvm_mkdb/kvm_mkdb.8 b/usr.sbin/kvm_mkdb/kvm_mkdb.8 new file mode 100644 index 0000000..d9dcbf9 --- /dev/null +++ b/usr.sbin/kvm_mkdb/kvm_mkdb.8 @@ -0,0 +1,69 @@ +.\" Copyright (c) 1989, 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. +.\" +.\" @(#)kvm_mkdb.8 8.1 (Berkeley) 6/9/93 +.\" +.Dd June 9, 1993 +.Dt KVM_MKDB 8 +.Os +.Sh NAME +.Nm kvm_mkdb +.Nd create kernel database +.Sh SYNOPSIS +.Nm kvm_mkdb +.Op file +.Sh DESCRIPTION +.Nm Kvm_mkdb +creates a database in +.Pa /var/db +containing information about the specified file. +If no file is specified, +.Pa /vmunix +is used by default. +The file is named ``kvm_filename.db'', where ``filename'' is the +name of the file read. +Various library routines consult this database. +The only information currently stored is the kernel namelist, which is +used by the +.Xr kvm_nlist 3 +function, however, in the future the database may contain other static +information about the current system. +.Sh FILES +.Bl -tag -width /var/db/kvm_vmunix.db -compact +.It Pa /vmunix +.It Pa /var/db/kvm_vmunix.db +.El +.Sh SEE ALSO +.Xr kvm_nlist 3 +.Sh HISTORY +The +.Nm kvm_mkdb +utility first appeared in 4.4BSD. diff --git a/usr.sbin/kvm_mkdb/kvm_mkdb.c b/usr.sbin/kvm_mkdb/kvm_mkdb.c new file mode 100644 index 0000000..f80b109 --- /dev/null +++ b/usr.sbin/kvm_mkdb/kvm_mkdb.c @@ -0,0 +1,111 @@ +/*- + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1990, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)kvm_mkdb.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "extern.h" + +static void usage __P((void)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + DB *db; + int ch; + char *p, *nlistpath, *nlistname, dbtemp[MAXPATHLEN], dbname[MAXPATHLEN]; + + while ((ch = getopt(argc, argv, "")) != EOF) + switch (ch) { + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc > 1) + usage(); + + /* If the existing db file matches the currently running kernel, exit */ + if (testdb()) + exit(0); + +#define basename(cp) ((p = rindex((cp), '/')) != NULL ? p + 1 : (cp)) + nlistpath = argc > 0 ? argv[0] : _PATH_UNIX; + nlistname = basename(nlistpath); + + (void)snprintf(dbtemp, sizeof(dbtemp), "%skvm_%s.tmp", + _PATH_VARDB, nlistname); + (void)snprintf(dbname, sizeof(dbname), "%skvm_%s.db", + _PATH_VARDB, nlistname); + (void)umask(0); + db = dbopen(dbtemp, O_CREAT | O_EXLOCK | O_TRUNC | O_RDWR, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, DB_HASH, NULL); + if (db == NULL) + err(1, "%s", dbtemp); + create_knlist(nlistpath, db); + if (db->close(db)) + err(1, "%s", dbtemp); + if (rename(dbtemp, dbname)) + err(1, "rename %s to %s", dbtemp, dbname); + exit(0); +} + +void +usage() +{ + (void)fprintf(stderr, "usage: kvm_mkdb [file]\n"); + exit(1); +} diff --git a/usr.sbin/kvm_mkdb/nlist.c b/usr.sbin/kvm_mkdb/nlist.c new file mode 100644 index 0000000..ad31a1a --- /dev/null +++ b/usr.sbin/kvm_mkdb/nlist.c @@ -0,0 +1,186 @@ +/*- + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)nlist.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "extern.h" + +typedef struct nlist NLIST; +#define _strx n_un.n_strx +#define _name n_un.n_name + +#define badfmt(str) errx(1, "%s: %s: %s", kfile, str, strerror(EFTYPE)) + +static void badread __P((int, char *)); + +static char *kfile; + +void +create_knlist(name, db) + char *name; + DB *db; +{ + register int nsyms; + struct exec ebuf; + FILE *fp; + NLIST nbuf; + DBT data, key; + int fd, nr, strsize; + char *strtab, buf[1024]; + + kfile = name; + if ((fd = open(name, O_RDONLY, 0)) < 0) + err(1, "%s", name); + + /* Read in exec structure. */ + nr = read(fd, &ebuf, sizeof(struct exec)); + if (nr != sizeof(struct exec)) + badfmt("no exec header"); + + /* Check magic number and symbol count. */ + if (N_BADMAG(ebuf)) + badfmt("bad magic number"); + if (!ebuf.a_syms) + badfmt("stripped"); + + /* Seek to string table. */ + if (lseek(fd, N_STROFF(ebuf), SEEK_SET) == -1) + badfmt("corrupted string table"); + + /* Read in the size of the symbol table. */ + nr = read(fd, (char *)&strsize, sizeof(strsize)); + if (nr != sizeof(strsize)) + badread(nr, "no symbol table"); + + /* Read in the string table. */ + strsize -= sizeof(strsize); + if (!(strtab = malloc(strsize))) + err(1, NULL); + if ((nr = read(fd, strtab, strsize)) != strsize) + badread(nr, "corrupted symbol table"); + + /* Seek to symbol table. */ + if (!(fp = fdopen(fd, "r"))) + err(1, "%s", name); + if (fseek(fp, N_SYMOFF(ebuf), SEEK_SET) == -1) + err(1, "%s", name); + + data.data = (u_char *)&nbuf; + data.size = sizeof(NLIST); + + /* Read each symbol and enter it into the database. */ + nsyms = ebuf.a_syms / sizeof(struct nlist); + while (nsyms--) { + if (fread((char *)&nbuf, sizeof (NLIST), 1, fp) != 1) { + if (feof(fp)) + badfmt("corrupted symbol table"); + err(1, "%s", name); + } + if (!nbuf._strx || nbuf.n_type&N_STAB) + continue; + + key.data = (u_char *)strtab + nbuf._strx - sizeof(long); + key.size = strlen((char *)key.data); + if (db->put(db, &key, &data, 0)) + err(1, "record enter"); + + if (strcmp((char *)key.data, VRS_SYM) == 0) { + long cur_off, voff; +#ifndef KERNTEXTOFF +#define KERNTEXTOFF KERNBASE +#endif + /* + * Calculate offset relative to a normal (non-kernel) + * a.out. KERNTEXTOFF is where the kernel is really + * loaded; N_TXTADDR is where a normal file is loaded. + * From there, locate file offset in text or data. + */ + voff = nbuf.n_value - KERNTEXTOFF + N_TXTADDR(ebuf); + if ((nbuf.n_type & N_TYPE) == N_TEXT) + voff += N_TXTOFF(ebuf) - N_TXTADDR(ebuf); + else + voff += N_DATOFF(ebuf) - N_DATADDR(ebuf); + cur_off = ftell(fp); + if (fseek(fp, voff, SEEK_SET) == -1) + badfmt("corrupted string table"); + + /* + * Read version string up to, and including newline. + * This code assumes that a newline terminates the + * version line. + */ + if (fgets(buf, sizeof(buf), fp) == NULL) + badfmt("corrupted string table"); + + key.data = (u_char *)VRS_KEY; + key.size = sizeof(VRS_KEY) - 1; + data.data = (u_char *)buf; + data.size = strlen(buf); + if (db->put(db, &key, &data, 0)) + err(1, "record enter"); + + /* Restore to original values. */ + data.data = (u_char *)&nbuf; + data.size = sizeof(NLIST); + if (fseek(fp, cur_off, SEEK_SET) == -1) + badfmt("corrupted string table"); + } + } + (void)fclose(fp); +} + +static void +badread(nr, p) + int nr; + char *p; +{ + if (nr < 0) + err(1, "%s", kfile); + badfmt(p); +} diff --git a/usr.sbin/kvm_mkdb/testdb.c b/usr.sbin/kvm_mkdb/testdb.c new file mode 100644 index 0000000..f4f3bf0 --- /dev/null +++ b/usr.sbin/kvm_mkdb/testdb.c @@ -0,0 +1,113 @@ +/*- + * 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[] = "@(#)testdb.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "extern.h" + +/* Return true if the db file is valid, else false */ +int +testdb() +{ + register DB *db; + register int cc, kd, ret, dbversionlen; + register char *cp, *uf; + DBT rec; + struct nlist nitem; + char dbname[MAXPATHLEN], dbversion[_POSIX2_LINE_MAX]; + char kversion[_POSIX2_LINE_MAX]; + + ret = 0; + db = NULL; + + if ((kd = open(_PATH_KMEM, O_RDONLY, 0)) < 0) + goto close; + + uf = _PATH_UNIX; + if ((cp = rindex(uf, '/')) != 0) + uf = cp + 1; + (void) snprintf(dbname, sizeof(dbname), "%skvm_%s.db", _PATH_VARDB, uf); + if ((db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL)) == NULL) + goto close; + + /* Read the version out of the database */ + rec.data = VRS_KEY; + rec.size = sizeof(VRS_KEY) - 1; + if ((db->get)(db, &rec, &rec, 0)) + goto close; + if (rec.data == 0 || rec.size > sizeof(dbversion)) + goto close; + bcopy(rec.data, dbversion, rec.size); + dbversionlen = rec.size; + + /* Read version string from kernel memory */ + rec.data = VRS_SYM; + rec.size = sizeof(VRS_SYM) - 1; + if ((db->get)(db, &rec, &rec, 0)) + goto close; + if (rec.data == 0 || rec.size != sizeof(struct nlist)) + goto close; + bcopy(rec.data, &nitem, sizeof(nitem)); + /* + * Theoretically possible for lseek to be seeking to -1. Not + * that it's something to lie awake nights about, however. + */ + errno = 0; + if (lseek(kd, (off_t)nitem.n_value, SEEK_SET) == -1 && errno != 0) + goto close; + cc = read(kd, kversion, sizeof(kversion)); + if (cc < 0 || cc != sizeof(kversion)) + goto close; + + /* If they match, we win */ + ret = bcmp(dbversion, kversion, dbversionlen) == 0; + +close: if (kd >= 0) + (void)close(kd); + if (db) + (void)(db->close)(db); + return (ret); +} diff --git a/usr.sbin/lpr/Makefile b/usr.sbin/lpr/Makefile new file mode 100644 index 0000000..9b4d7d2 --- /dev/null +++ b/usr.sbin/lpr/Makefile @@ -0,0 +1,6 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +SUBDIR= lpc lpd lpq lpr lprm lptest pac filters + +.include + diff --git a/usr.sbin/lpr/SMM.doc/0.t b/usr.sbin/lpr/SMM.doc/0.t new file mode 100644 index 0000000..65ecd4e --- /dev/null +++ b/usr.sbin/lpr/SMM.doc/0.t @@ -0,0 +1,68 @@ +.\" 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. +.\" +.\" @(#)0.t 8.1 (Berkeley) 6/8/93 +.\" +.if n .ND +.TL +4.3BSD Line Printer Spooler Manual +.EH 'SMM:7-%''4.3BSD Line Printer Spooler Manual' +.OH '4.3BSD Line Printer Spooler Manual''SMM:7-%' +.AU +Ralph Campbell +.AI +Computer Systems Research Group +Computer Science Division +Department of Electrical Engineering and Computer Science +University of California, Berkeley +Berkeley, CA 94720 +.AB +.FS +* UNIX is a trademark of Bell Laboratories. +.FE +This document describes the structure and installation procedure +for the line printer spooling system +developed for the 4.3BSD version +of the UNIX* operating system. +.de D? +.ie \\n(.$>1 Revised \\$1 \\$2 \\$3 +.el DRAFT of \n(mo/\n(dy/\n(yr +.. +.sp 2 +.LP +.D? June 8, 1993 +.AE +.de IR +\fI\\$1\fP\\$2 +.. +.de DT +.TA 8 16 24 32 40 48 56 64 72 80 +.. diff --git a/usr.sbin/lpr/SMM.doc/1.t b/usr.sbin/lpr/SMM.doc/1.t new file mode 100644 index 0000000..1d34e9e --- /dev/null +++ b/usr.sbin/lpr/SMM.doc/1.t @@ -0,0 +1,77 @@ +.\" 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. +.\" +.\" @(#)1.t 8.1 (Berkeley) 6/8/93 +.\" +.NH 1 +Overview +.PP +The line printer system supports: +.IP \(bu 3 +multiple printers, +.IP \(bu 3 +multiple spooling queues, +.IP \(bu 3 +both local and remote +printers, and +.IP \(bu 3 +printers attached via serial lines that require +line initialization such as the baud rate. +.LP +Raster output devices +such as a Varian or Versatec, and laser printers such as an Imagen, +are also supported by the line printer system. +.PP +The line printer system consists mainly of the +following files and commands: +.DS +.TS +l l. +/etc/printcap printer configuration and capability data base +/usr/lib/lpd line printer daemon, does all the real work +/usr/ucb/lpr program to enter a job in a printer queue +/usr/ucb/lpq spooling queue examination program +/usr/ucb/lprm program to delete jobs from a queue +/etc/lpc program to administer printers and spooling queues +/dev/printer socket on which lpd listens +.TE +.DE +The file /etc/printcap is a master data base describing line +printers directly attached to a machine and, also, printers +accessible across a network. The manual page entry +.IR printcap (5) +provides the authoritative definition of +the format of this data base, as well as +specifying default values for important items +such as the directory in which spooling is performed. +This document introduces some of the +information that may be placed +.IR printcap . diff --git a/usr.sbin/lpr/SMM.doc/2.t b/usr.sbin/lpr/SMM.doc/2.t new file mode 100644 index 0000000..9da2ae2 --- /dev/null +++ b/usr.sbin/lpr/SMM.doc/2.t @@ -0,0 +1,141 @@ +.\" 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. +.\" +.\" @(#)2.t 8.1 (Berkeley) 6/8/93 +.\" +.NH 1 +Commands +.NH 2 +lpd \- line printer daemon +.PP +The program +.IR lpd (8), +usually invoked at boot time from the /etc/rc file, acts as +a master server for coordinating and controlling +the spooling queues configured in the printcap file. +When +.I lpd +is started it makes a single pass through the +.I printcap +database restarting any printers that have jobs. +In normal operation +.I lpd +listens for service requests on multiple sockets, +one in the UNIX domain (named ``/dev/printer'') for +local requests, and one in the Internet domain +(under the ``printer'' service specification) +for requests for printer access from off machine; +see \fIsocket\fP\|(2) and \fIservices\fP\|(5) +for more information on sockets and service +specifications, respectively. +.I Lpd +spawns a copy of itself to process the request; the master daemon +continues to listen for new requests. +.PP +Clients communicate with +.I lpd +using a simple transaction oriented protocol. +Authentication of remote clients is done based +on the ``privilege port'' scheme employed by +\fIrshd\fP\|(8C) and \fIrcmd\fP\|(3X). +The following table shows the requests +understood by +.IR lpd . +In each request the first byte indicates the +``meaning'' of the request, followed by the name +of the printer to which it should be applied. Additional +qualifiers may follow, depending on the request. +.DS +.TS +l l. +Request Interpretation +_ +^Aprinter\en check the queue for jobs and print any found +^Bprinter\en receive and queue a job from another machine +^Cprinter [users ...] [jobs ...]\en return short list of current queue state +^Dprinter [users ...] [jobs ...]\en return long list of current queue state +^Eprinter person [users ...] [jobs ...]\en remove jobs from a queue +.TE +.DE +.PP +The \fIlpr\fP\|(1) command +is used by users to enter a print job in a local queue and to notify +the local +.I lpd +that there are new jobs in the spooling area. +.I Lpd +either schedules the job to be printed locally, or if +printing remotely, attempts to forward +the job to the appropriate machine. +If the printer cannot be opened or the destination +machine is unreachable, the job will remain queued until it is +possible to complete the work. +.NH 2 +lpq \- show line printer queue +.PP +The \fIlpq\fP\|(1) +program works recursively backwards displaying the queue of the machine with +the printer and then the queue(s) of the machine(s) that lead to it. +.I Lpq +has two forms of output: in the default, short, format it +gives a single line of output per queued job; in the long +format it shows the list of files, and their sizes, that +comprise a job. +.NH 2 +lprm \- remove jobs from a queue +.PP +The \fIlprm\fP\|(1) command deletes jobs from a spooling +queue. If necessary, \fIlprm\fP will first kill off a +running daemon that is servicing the queue and restart +it after the required files are removed. When removing +jobs destined for a remote printer, \fIlprm\fP acts +similarly to \fIlpq\fP except it first checks locally +for jobs to remove and then +tries to remove files in queues off-machine. +.NH 2 +lpc \- line printer control program +.PP +The +.IR lpc (8) +program is used by the system administrator to control the +operation of the line printer system. +For each line printer configured in /etc/printcap, +.I lpc +may be used to: +.IP \(bu +disable or enable a printer, +.IP \(bu +disable or enable a printer's spooling queue, +.IP \(bu +rearrange the order of jobs in a spooling queue, +.IP \(bu +find the status of printers, and their associated +spooling queues and printer daemons. diff --git a/usr.sbin/lpr/SMM.doc/3.t b/usr.sbin/lpr/SMM.doc/3.t new file mode 100644 index 0000000..8c950a9 --- /dev/null +++ b/usr.sbin/lpr/SMM.doc/3.t @@ -0,0 +1,73 @@ +.\" 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. +.\" +.\" @(#)3.t 8.1 (Berkeley) 6/8/93 +.\" +.NH 1 +Access control +.PP +The printer system maintains protected spooling areas so that +users cannot circumvent printer accounting or +remove files other than their own. +The strategy used to maintain protected +spooling areas is as follows: +.IP \(bu 3 +The spooling area is writable only by a \fIdaemon\fP user +and \fIdaemon\fP group. +.IP \(bu 3 +The \fIlpr\fP program runs set-user-id to \fIroot\fP and +set-group-id to group \fIdaemon\fP. The \fIroot\fP access permits +reading any file required. Accessibility is verified +with an \fIaccess\fP\|(2) call. The group ID +is used in setting up proper ownership of files +in the spooling area for \fIlprm\fP. +.IP \(bu 3 +Control files in a spooling area are made with \fIdaemon\fP +ownership and group ownership \fIdaemon\fP. Their mode is 0660. +This insures control files are not modified by a user +and that no user can remove files except through \fIlprm\fP. +.IP \(bu 3 +The spooling programs, +\fIlpd\fP, \fIlpq\fP, and \fIlprm\fP run set-user-id to \fIroot\fP +and set-group-id to group \fIdaemon\fP to access spool files and printers. +.IP \(bu 3 +The printer server, \fIlpd\fP, +uses the same verification procedures as \fIrshd\fP\|(8C) +in authenticating remote clients. The host on which a client +resides must be present in the file /etc/hosts.equiv or /etc/hosts.lpd and +the request message must come from a reserved port number. +.PP +In practice, none of \fIlpd\fP, \fIlpq\fP, or +\fIlprm\fP would have to run as user \fIroot\fP if remote +spooling were not supported. In previous incarnations of +the printer system \fIlpd\fP ran set-user-id to \fIdaemon\fP, +set-group-id to group \fIspooling\fP, and \fIlpq\fP and \fIlprm\fP ran +set-group-id to group \fIspooling\fP. diff --git a/usr.sbin/lpr/SMM.doc/4.t b/usr.sbin/lpr/SMM.doc/4.t new file mode 100644 index 0000000..8800bc0 --- /dev/null +++ b/usr.sbin/lpr/SMM.doc/4.t @@ -0,0 +1,206 @@ +.\" 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. +.\" +.\" @(#)4.t 8.1 (Berkeley) 6/8/93 +.\" +.NH 1 +Setting up +.PP +The 4.3BSD release comes with the necessary programs +installed and with the default line printer queue +created. If the system must be modified, the +makefile in the directory /usr/src/usr.lib/lpr +should be used in recompiling and reinstalling +the necessary programs. +.PP +The real work in setting up is to create the +.I printcap +file and any printer filters for printers not supported +in the distribution system. +.NH 2 +Creating a printcap file +.PP +The +.I printcap +database contains one or more entries per printer. +A printer should have a separate spooling directory; +otherwise, jobs will be printed on +different printers depending on which printer daemon starts first. +This section describes how to create entries for printers that do not +conform to the default printer description (an LP-11 style interface to a +standard, band printer). +.NH 3 +Printers on serial lines +.PP +When a printer is connected via a serial communication line +it must have the proper baud rate and terminal modes set. +The following example is for a DecWriter III printer connected +locally via a 1200 baud serial line. +.DS +.DT +lp|LA-180 DecWriter III:\e + :lp=/dev/lp:br#1200:fs#06320:\e + :tr=\ef:of=/usr/lib/lpf:lf=/usr/adm/lpd-errs: +.DE +The +.B lp +entry specifies the file name to open for output. Here it could +be left out since ``/dev/lp'' is the default. +The +.B br +entry sets the baud rate for the tty line and the +.B fs +entry sets CRMOD, no parity, and XTABS (see \fItty\fP\|(4)). +The +.B tr +entry indicates that a form-feed should be printed when the queue +empties so the paper can be torn off without turning the printer off-line and +pressing form feed. +The +.B of +entry specifies the filter program +.I lpf +should be used for printing the files; +more will be said about filters later. +The last entry causes errors +to be written to the file ``/usr/adm/lpd-errs'' +instead of the console. Most errors from \fIlpd\fP are logged using +\fIsyslogd\fP\|(8) and will not be logged in the specified file. The +filters should use \fIsyslogd\fP to report errors; only those that +write to standard error output will end up with errors in the \fBlf\fP file. +(Occasionally errors sent to standard error output have not appeared +in the log file; the use of \fIsyslogd\fP is highly recommended.) +.NH 3 +Remote printers +.PP +Printers that reside on remote hosts should have an empty +.B lp +entry. +For example, the following printcap entry would send output to the printer +named ``lp'' on the machine ``ucbvax''. +.DS +.DT +lp|default line printer:\e + :lp=:rm=ucbvax:rp=lp:sd=/usr/spool/vaxlpd: +.DE +The +.B rm +entry is the name of the remote machine to connect to; this name must +be a known host name for a machine on the network. +The +.B rp +capability indicates +the name of the printer on the remote machine is ``lp''; +here it could be left out since this is the default value. +The +.B sd +entry specifies ``/usr/spool/vaxlpd'' +as the spooling directory instead of the +default value of ``/usr/spool/lpd''. +.NH 2 +Output filters +.PP +Filters are used to handle device dependencies and to +do accounting functions. The output filtering of +.B of +is used when accounting is +not being done or when all text data must be passed through a filter. +It is not intended to do accounting since it is started only once, +all text files are filtered through it, and no provision is made for passing +owners' login name, identifying the beginning and ending of jobs, etc. +The other filters (if specified) are started for each file +printed and do accounting if there is an +.B af +entry. +If entries for both +.B of +and other filters are specified, +the output filter is used only to print the banner page; +it is then stopped to allow other filters access to the printer. +An example of a printer that requires output filters +is the Benson-Varian. +.DS +.DT +va|varian|Benson-Varian:\e + :lp=/dev/va0:sd=/usr/spool/vad:of=/usr/lib/vpf:\e + :tf=/usr/lib/rvcat:mx#2000:pl#58:px=2112:py=1700:tr=\ef: +.DE +The +.B tf +entry specifies ``/usr/lib/rvcat'' as the filter to be +used in printing \fItroff\fP\|(1) output. +This filter is needed to set the device into print mode +for text, and plot mode for printing +.I troff +files and raster images (see \fIva\fP\|(4V)). +Note that the page length is set to 58 lines by the +.B pl +entry for 8.5" by 11" fan-fold paper. +To enable accounting, the varian entry would be +augmented with an +.B af +filter as shown below. +.DS +.DT +va|varian|Benson-Varian:\e + :lp=/dev/va0:sd=/usr/spool/vad:of=/usr/lib/vpf:\e + :if=/usr/lib/vpf:tf=/usr/lib/rvcat:af=/usr/adm/vaacct:\e + :mx#2000:pl#58:px=2112:py=1700:tr=\ef: +.DE +.NH 2 +Access Control +.PP +Local access to printer queues is controlled with the +.B rg +printcap entry. +.DS + :rg=lprgroup: +.DE +Users must be in the group +.I lprgroup +to submit jobs to the specified printer. +The default is to allow all users access. +Note that once the files are in the local queue, they can be printed +locally or forwarded to another host depending on the configuration. +.PP +Remote access is controlled by listing the hosts in either the file +/etc/hosts.equiv or /etc/hosts.lpd, one host per line. Note that +.IR rsh (1) +and +.IR rlogin (1) +use /etc/hosts.equiv to determine which hosts are equivalent for allowing logins +without passwords. The file /etc/hosts.lpd is only used to control +which hosts have line printer access. +Remote access can be further restricted to only allow remote users with accounts +on the local host to print jobs by using the \fBrs\fP printcap entry. +.DS + :rs: +.DE diff --git a/usr.sbin/lpr/SMM.doc/5.t b/usr.sbin/lpr/SMM.doc/5.t new file mode 100644 index 0000000..137a342 --- /dev/null +++ b/usr.sbin/lpr/SMM.doc/5.t @@ -0,0 +1,116 @@ +.\" 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. +.\" +.\" @(#)5.t 8.1 (Berkeley) 6/8/93 +.\" +.NH 1 +Output filter specifications +.PP +The filters supplied with 4.3BSD +handle printing and accounting for most common +line printers, the Benson-Varian, the wide (36") and +narrow (11") Versatec printer/plotters. For other devices or accounting +methods, it may be necessary to create a new filter. +.PP +Filters are spawned by \fIlpd\fP +with their standard input the data to be printed, and standard output +the printer. The standard error is attached to the +.B lf +file for logging errors or \fIsyslogd\fP may be used for logging errors. +A filter must return a 0 exit +code if there were no errors, 1 if the job should be reprinted, +and 2 if the job should be thrown away. +When \fIlprm\fP +sends a kill signal to the \fIlpd\fP process controlling +printing, it sends a SIGINT signal +to all filters and descendents of filters. +This signal can be trapped by filters that need +to do cleanup operations such as +deleting temporary files. +.PP +Arguments passed to a filter depend on its type. +The +.B of +filter is called with the following arguments. +.DS +\fIfilter\fP \fB\-w\fPwidth \fB\-l\fPlength +.DE +The \fIwidth\fP and \fIlength\fP values come from the +.B pw +and +.B pl +entries in the printcap database. +The +.B if +filter is passed the following parameters. +.DS +\fIfilter\fP [\|\fB\-c\fP\|] \fB\-w\fPwidth \fB\-l\fPlength \fB\-i\fPindent \fB\-n\fP login \fB\-h\fP host accounting_file +.DE +The +.B \-c +flag is optional, and only supplied when control characters +are to be passed uninterpreted to the printer (when using the +.B \-l +option of +.I lpr +to print the file). +The +.B \-w +and +.B \-l +parameters are the same as for the +.B of +filter. +The +.B \-n +and +.B \-h +parameters specify the login name and host name of the job owner. +The last argument is the name of the accounting file from +.IR printcap . +.PP +All other filters are called with the following arguments: +.DS +\fIfilter\fP \fB\-x\fPwidth \fB\-y\fPlength \fB\-n\fP login \fB\-h\fP host accounting_file +.DE +The +.B \-x +and +.B \-y +options specify the horizontal and vertical page +size in pixels (from the +.B px +and +.B py +entries in the printcap file). +The rest of the arguments are the same as for the +.B if +filter. diff --git a/usr.sbin/lpr/SMM.doc/6.t b/usr.sbin/lpr/SMM.doc/6.t new file mode 100644 index 0000000..7087790 --- /dev/null +++ b/usr.sbin/lpr/SMM.doc/6.t @@ -0,0 +1,94 @@ +.\" 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. +.\" +.\" @(#)6.t 8.1 (Berkeley) 6/8/93 +.\" +.NH 1 +Line printer Administration +.PP +The +.I lpc +program provides local control over line printer activity. +The major commands and their intended use will be described. +The command format and remaining commands are described in +.IR lpc (8). +.LP +\fBabort\fP and \fBstart\fP +.IP +.I Abort +terminates an active spooling daemon on the local host immediately and +then disables printing (preventing new daemons from being started by +.IR lpr ). +This is normally used to forcibly restart a hung line printer daemon +(i.e., \fIlpq\fP reports that there is a daemon present but nothing is +happening). It does not remove any jobs from the queue +(use the \fIlprm\fP command instead). +.I Start +enables printing and requests \fIlpd\fP to start printing jobs. +.LP +\fBenable\fP and \fBdisable\fP +.IP +\fIEnable\fP and \fIdisable\fP allow spooling in the local queue to be +turned on/off. +This will allow/prevent +.I lpr +from putting new jobs in the spool queue. It is frequently convenient +to turn spooling off while testing new line printer filters since the +.I root +user can still use +.I lpr +to put jobs in the queue but no one else can. +The other main use is to prevent users from putting jobs in the queue +when the printer is expected to be unavailable for a long time. +.LP +\fBrestart\fP +.IP +.I Restart +allows ordinary users to restart printer daemons when +.I lpq +reports that there is no daemon present. +.LP +\fBstop\fP +.IP +.I Stop +halts a spooling daemon after the current job completes; +this also disables printing. This is a clean way to shutdown a +printer to do maintenance, etc. Note that users can still enter jobs in a +spool queue while a printer is +.IR stopped . +.LP +\fBtopq\fP +.IP +.I Topq +places jobs at the top of a printer queue. This can be used +to reorder high priority jobs since +.I lpr +only provides first-come-first-serve ordering of jobs. diff --git a/usr.sbin/lpr/SMM.doc/7.t b/usr.sbin/lpr/SMM.doc/7.t new file mode 100644 index 0000000..a6f6bea --- /dev/null +++ b/usr.sbin/lpr/SMM.doc/7.t @@ -0,0 +1,226 @@ +.\" 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. +.\" +.\" @(#)7.t 8.1 (Berkeley) 6/8/93 +.\" +.NH 1 +Troubleshooting +.PP +There are several messages that may be generated by the +the line printer system. This section +categorizes the most common and explains the cause +for their generation. Where the message implies a failure, +directions are given to remedy the problem. +.PP +In the examples below, the name +.I printer +is the name of the printer from the +.I printcap +database. +.NH 2 +LPR +.SH +lpr: \fIprinter\fP\|: unknown printer +.IP +The +.I printer +was not found in the +.I printcap +database. Usually this is a typing mistake; however, it may indicate +a missing or incorrect entry in the /etc/printcap file. +.SH +lpr: \fIprinter\fP\|: jobs queued, but cannot start daemon. +.IP +The connection to +.I lpd +on the local machine failed. +This usually means the printer server started at +boot time has died or is hung. Check the local socket +/dev/printer to be sure it still exists (if it does not exist, +there is no +.I lpd +process running). +Usually it is enough to get a super-user to type the following to +restart +.IR lpd . +.DS +% /usr/lib/lpd +.DE +You can also check the state of the master printer daemon with the following. +.DS +% ps l`cat /usr/spool/lpd.lock` +.DE +.IP +Another possibility is that the +.I lpr +program is not set-user-id to \fIroot\fP, set-group-id to group \fIdaemon\fP. +This can be checked with +.DS +% ls \-lg /usr/ucb/lpr +.DE +.SH +lpr: \fIprinter\fP\|: printer queue is disabled +.IP +This means the queue was turned off with +.DS +% lpc disable \fIprinter\fP +.DE +to prevent +.I lpr +from putting files in the queue. This is normally +done by the system manager when a printer is +going to be down for a long time. The +printer can be turned back on by a super-user with +.IR lpc . +.NH 2 +LPQ +.SH +waiting for \fIprinter\fP to become ready (offline ?) +.IP +The printer device could not be opened by the daemon. +This can happen for several reasons, +the most common is that the printer is turned off-line. +This message can also be generated if the printer is out +of paper, the paper is jammed, etc. +The actual reason is dependent on the meaning +of error codes returned by system device driver. +Not all printers supply enough information +to distinguish when a printer is off-line or having +trouble (e.g. a printer connected through a serial line). +Another possible cause of this message is +some other process, such as an output filter, +has an exclusive open on the device. Your only recourse +here is to kill off the offending program(s) and +restart the printer with +.IR lpc . +.SH +\fIprinter\fP is ready and printing +.IP +The +.I lpq +program checks to see if a daemon process exists for +.I printer +and prints the file \fIstatus\fP located in the spooling directory. +If the daemon is hung, a super user can use +.I lpc +to abort the current daemon and start a new one. +.SH +waiting for \fIhost\fP to come up +.IP +This implies there is a daemon trying to connect to the remote +machine named +.I host +to send the files in the local queue. +If the remote machine is up, +.I lpd +on the remote machine is probably dead or +hung and should be restarted as mentioned for +.IR lpr . +.SH +sending to \fIhost\fP +.IP +The files should be in the process of being transferred to the remote +.IR host . +If not, the local daemon should be aborted and started with +.IR lpc . +.SH +Warning: \fIprinter\fP is down +.IP +The printer has been marked as being unavailable with +.IR lpc . +.SH +Warning: no daemon present +.IP +The \fIlpd\fP process overseeing +the spooling queue, as specified in the ``lock'' file +in that directory, does not exist. This normally occurs +only when the daemon has unexpectedly died. +The error log file for the printer and the \fIsyslogd\fP logs +should be checked for a +diagnostic from the deceased process. +To restart an \fIlpd\fP, use +.DS +% lpc restart \fIprinter\fP +.DE +.SH +no space on remote; waiting for queue to drain +.IP +This implies that there is insufficient disk space on the remote. +If the file is large enough, there will never be enough space on +the remote (even after the queue on the remote is empty). The solution here +is to move the spooling queue or make more free space on the remote. +.NH 2 +LPRM +.SH +lprm: \fIprinter\fP\|: cannot restart printer daemon +.IP +This case is the same as when +.I lpr +prints that the daemon cannot be started. +.NH 2 +LPD +.PP +The +.I lpd +program can log many different messages using \fIsyslogd\fP\|(8). +Most of these messages are about files that can not +be opened and usually imply that the +.I printcap +file or the protection modes of the files are +incorrect. Files may also be inaccessible if people +manually manipulate the line printer system (i.e. they +bypass the +.I lpr +program). +.PP +In addition to messages generated by +.IR lpd , +any of the filters that +.I lpd +spawns may log messages using \fIsyslogd\fP or to the error log file +(the file specified in the \fBlf\fP entry in \fIprintcap\fP\|). +.NH 2 +LPC +.PP +.SH +couldn't start printer +.IP +This case is the same as when +.I lpr +reports that the daemon cannot be started. +.SH +cannot examine spool directory +.IP +Error messages beginning with ``cannot ...'' are usually because of +incorrect ownership or protection mode of the lock file, spooling +directory or the +.I lpc +program. diff --git a/usr.sbin/lpr/SMM.doc/Makefile b/usr.sbin/lpr/SMM.doc/Makefile new file mode 100644 index 0000000..1701c86 --- /dev/null +++ b/usr.sbin/lpr/SMM.doc/Makefile @@ -0,0 +1,10 @@ +# @(#)Makefile 8.1 (Berkeley) 6/8/93 + +DIR= smm/07.lpd +SRCS= 0.t 1.t 2.t 3.t 4.t 5.t 6.t 7.t +MACROS= -ms + +paper.ps: ${SRCS} + ${TBL} ${SRCS} | ${ROFF} > ${.TARGET} + +.include diff --git a/usr.sbin/lpr/SMM.doc/spell.ok b/usr.sbin/lpr/SMM.doc/spell.ok new file mode 100644 index 0000000..bf31319 --- /dev/null +++ b/usr.sbin/lpr/SMM.doc/spell.ok @@ -0,0 +1,70 @@ +Aprinter +Bprinter +CRMOD +Cprinter +DecWriter +Dprinter +Eprinter +LPC +LPD +Lpd +Manual''SMM:5 +SIGINT +SMM:5 +Topq +XTABS +adm +af +br +daemon +daemons +dev +f:of +fs +hosts.equiv +hosts.lpd +lf +lg +lib +lp:br +lp:sd +lpc +lpd +lpd.lock +lpf +lpf:lf +lprgroup +makefile +mx +offline +pl +printcap +pw +py +rc +rcmd +rg +rlogin +rp +rs +rsh +rshd +rvcat +rvcat:af +rvcat:mx +sd +src +syslogd +tf +topq +ucb +ucbvax +ucbvax:rp +usr.lib +va0:sd +vaacct +vad:of +varian +vaxlpd +vpf +vpf:tf diff --git a/usr.sbin/lpr/common_source/common.c b/usr.sbin/lpr/common_source/common.c new file mode 100644 index 0000000..49f7939 --- /dev/null +++ b/usr.sbin/lpr/common_source/common.c @@ -0,0 +1,352 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * 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[] = "@(#)common.c 8.2 (Berkeley) 1/21/94"; +#endif /* not lint */ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "lp.h" +#include "pathnames.h" + +/* + * Routines and data common to all the line printer functions. + */ + +char *AF; /* accounting file */ +long BR; /* baud rate if lp is a tty */ +char *CF; /* name of cifplot filter (per job) */ +char *DF; /* name of tex filter (per job) */ +long DU; /* daeomon user-id */ +long FC; /* flags to clear if lp is a tty */ +char *FF; /* form feed string */ +long FS; /* flags to set if lp is a tty */ +char *GF; /* name of graph(1G) filter (per job) */ +long HL; /* print header last */ +char *IF; /* name of input filter (created per job) */ +char *LF; /* log file for error messages */ +char *LO; /* lock file name */ +char *LP; /* line printer device name */ +long MC; /* maximum number of copies allowed */ +long MX; /* maximum number of blocks to copy */ +char *NF; /* name of ditroff filter (per job) */ +char *OF; /* name of output filter (created once) */ +char *PF; /* name of vrast filter (per job) */ +long PL; /* page length */ +long PW; /* page width */ +long PX; /* page width in pixels */ +long PY; /* page length in pixels */ +char *RF; /* name of fortran text filter (per job) */ +char *RG; /* resricted group */ +char *RM; /* remote machine name */ +char *RP; /* remote printer name */ +long RS; /* restricted to those with local accounts */ +long RW; /* open LP for reading and writing */ +long SB; /* short banner instead of normal header */ +long SC; /* suppress multiple copies */ +char *SD; /* spool directory */ +long SF; /* suppress FF on each print job */ +long SH; /* suppress header page */ +char *ST; /* status file name */ +char *TF; /* name of troff filter (per job) */ +char *TR; /* trailer string to be output when Q empties */ +char *VF; /* name of vplot filter (per job) */ +long XC; /* flags to clear for local mode */ +long XS; /* flags to set for local mode */ + +char line[BUFSIZ]; +char *bp; /* pointer into printcap buffer. */ +char *name; /* program name */ +char *printer; /* printer name */ + /* host machine name */ +char host[MAXHOSTNAMELEN]; +char *from = host; /* client's machine name */ +int sendtorem; /* are we sending to a remote? */ +char *printcapdb[2] = { _PATH_PRINTCAP, 0 }; + +static int compar __P((const void *, const void *)); + +/* + * Create a connection to the remote printer server. + * Most of this code comes from rcmd.c. + */ +int +getport(rhost) + char *rhost; +{ + struct hostent *hp; + struct servent *sp; + struct sockaddr_in sin; + int s, timo = 1, lport = IPPORT_RESERVED - 1; + int err; + + /* + * Get the host address and port number to connect to. + */ + if (rhost == NULL) + fatal("no remote host to connect to"); + hp = gethostbyname(rhost); + if (hp == NULL) + fatal("unknown host %s", rhost); + sp = getservbyname("printer", "tcp"); + if (sp == NULL) + fatal("printer/tcp: unknown service"); + bzero((char *)&sin, sizeof(sin)); + bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); + sin.sin_family = hp->h_addrtype; + sin.sin_port = sp->s_port; + + /* + * Try connecting to the server. + */ +retry: + s = rresvport(&lport); + if (s < 0) + return(-1); + if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + err = errno; + (void) close(s); + errno = err; + if (errno == EADDRINUSE) { + lport--; + goto retry; + } + if (errno == ECONNREFUSED && timo <= 16) { + sleep(timo); + timo *= 2; + goto retry; + } + return(-1); + } + return(s); +} + +/* + * Getline reads a line from the control file cfp, removes tabs, converts + * new-line to null and leaves it in line. + * Returns 0 at EOF or the number of characters read. + */ +int +getline(cfp) + FILE *cfp; +{ + register int linel = 0; + register char *lp = line; + register c; + + while ((c = getc(cfp)) != '\n') { + if (c == EOF) + return(0); + if (c == '\t') { + do { + *lp++ = ' '; + linel++; + } while ((linel & 07) != 0); + continue; + } + *lp++ = c; + linel++; + } + *lp++ = '\0'; + return(linel); +} + +/* + * Scan the current directory and make a list of daemon files sorted by + * creation time. + * Return the number of entries and a pointer to the list. + */ +int +getq(namelist) + struct queue *(*namelist[]); +{ + register struct dirent *d; + register struct queue *q, **queue; + register int nitems; + struct stat stbuf; + DIR *dirp; + int arraysz; + + if ((dirp = opendir(SD)) == NULL) + return(-1); + if (fstat(dirp->dd_fd, &stbuf) < 0) + goto errdone; + + /* + * Estimate the array size by taking the size of the directory file + * and dividing it by a multiple of the minimum size entry. + */ + arraysz = (stbuf.st_size / 24); + queue = (struct queue **)malloc(arraysz * sizeof(struct queue *)); + if (queue == NULL) + goto errdone; + + nitems = 0; + while ((d = readdir(dirp)) != NULL) { + if (d->d_name[0] != 'c' || d->d_name[1] != 'f') + continue; /* daemon control files only */ + if (stat(d->d_name, &stbuf) < 0) + continue; /* Doesn't exist */ + q = (struct queue *)malloc(sizeof(time_t)+strlen(d->d_name)+1); + if (q == NULL) + goto errdone; + q->q_time = stbuf.st_mtime; + strcpy(q->q_name, d->d_name); + /* + * Check to make sure the array has space left and + * realloc the maximum size. + */ + if (++nitems > arraysz) { + queue = (struct queue **)realloc((char *)queue, + (stbuf.st_size/12) * sizeof(struct queue *)); + if (queue == NULL) + goto errdone; + } + queue[nitems-1] = q; + } + closedir(dirp); + if (nitems) + qsort(queue, nitems, sizeof(struct queue *), compar); + *namelist = queue; + return(nitems); + +errdone: + closedir(dirp); + return(-1); +} + +/* + * Compare modification times. + */ +static int +compar(p1, p2) + const void *p1, *p2; +{ + if ((*(struct queue **)p1)->q_time < (*(struct queue **)p2)->q_time) + return(-1); + if ((*(struct queue **)p1)->q_time > (*(struct queue **)p2)->q_time) + return(1); + return(0); +} + +/* + * Figure out whether the local machine is the same + * as the remote machine (RM) entry (if it exists). + */ +char * +checkremote() +{ + char name[MAXHOSTNAMELEN]; + register struct hostent *hp; + static char errbuf[128]; + + sendtorem = 0; /* assume printer is local */ + if (RM != (char *)NULL) { + /* get the official name of the local host */ + gethostname(name, sizeof(name)); + name[sizeof(name)-1] = '\0'; + hp = gethostbyname(name); + if (hp == (struct hostent *) NULL) { + (void) snprintf(errbuf, sizeof(errbuf), + "unable to get official name for local machine %s", + name); + return errbuf; + } else (void) strcpy(name, hp->h_name); + + /* get the official name of RM */ + hp = gethostbyname(RM); + if (hp == (struct hostent *) NULL) { + (void) snprintf(errbuf, sizeof(errbuf), + "unable to get official name for remote machine %s", + RM); + return errbuf; + } + + /* + * if the two hosts are not the same, + * then the printer must be remote. + */ + if (strcmp(name, hp->h_name) != 0) + sendtorem = 1; + } + return (char *)0; +} + +#if __STDC__ +#include +#else +#include +#endif + +void +#if __STDC__ +fatal(const char *msg, ...) +#else +fatal(msg, va_alist) + char *msg; + va_dcl +#endif +{ + va_list ap; +#if __STDC__ + va_start(ap, msg); +#else + va_start(ap); +#endif + if (from != host) + (void)printf("%s: ", host); + (void)printf("%s: ", name); + if (printer) + (void)printf("%s: ", printer); + (void)vprintf(msg, ap); + va_end(ap); + (void)putchar('\n'); + exit(1); +} diff --git a/usr.sbin/lpr/common_source/displayq.c b/usr.sbin/lpr/common_source/displayq.c new file mode 100644 index 0000000..59d3cc9 --- /dev/null +++ b/usr.sbin/lpr/common_source/displayq.c @@ -0,0 +1,449 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)displayq.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "lp.h" +#include "lp.local.h" +#include "pathnames.h" + +/* + * Routines to display the state of the queue. + */ +#define JOBCOL 40 /* column for job # in -l format */ +#define OWNCOL 7 /* start of Owner column in normal */ +#define SIZCOL 62 /* start of Size column in normal */ + +/* + * Stuff for handling job specifications + */ +extern int requ[]; /* job number of spool entries */ +extern int requests; /* # of spool requests */ +extern char *user[]; /* users to process */ +extern int users; /* # of users in user array */ + +static int col; /* column on screen */ +static char current[40]; /* current file being printed */ +static char file[132]; /* print file name */ +static int first; /* first file in ``files'' column? */ +static int garbage; /* # of garbage cf files */ +static int lflag; /* long output option */ +static int rank; /* order to be printed (-1=none, 0=active) */ +static long totsize; /* total print job size in bytes */ + +static char *head0 = "Rank Owner Job Files"; +static char *head1 = "Total Size\n"; + +/* + * Display the current state of the queue. Format = 1 if long format. + */ +void +displayq(format) + int format; +{ + register struct queue *q; + register int i, nitems, fd; + register char *cp; + struct queue **queue; + struct stat statb; + FILE *fp; + + lflag = format; + totsize = 0; + rank = -1; + if ((i = cgetent(&bp, printcapdb, printer)) == -2) + fatal("can't open printer description file"); + else if (i == -1) + fatal("unknown printer"); + else if (i == -3) + fatal("potential reference loop detected in printcap file"); + if (cgetstr(bp, "lp", &LP) < 0) + LP = _PATH_DEFDEVLP; + if (cgetstr(bp, "rp", &RP) < 0) + RP = DEFLP; + if (cgetstr(bp, "sd", &SD) < 0) + SD = _PATH_DEFSPOOL; + if (cgetstr(bp,"lo", &LO) < 0) + LO = DEFLOCK; + if (cgetstr(bp, "st", &ST) < 0) + ST = DEFSTAT; + cgetstr(bp, "rm", &RM); + if (cp = checkremote()) + printf("Warning: %s\n", cp); + + /* + * Print out local queue + * Find all the control files in the spooling directory + */ + if (chdir(SD) < 0) + fatal("cannot chdir to spooling directory"); + if ((nitems = getq(&queue)) < 0) + fatal("cannot examine spooling area\n"); + if (stat(LO, &statb) >= 0) { + if (statb.st_mode & 0100) { + if (sendtorem) + printf("%s: ", host); + printf("Warning: %s is down: ", printer); + fd = open(ST, O_RDONLY); + if (fd >= 0) { + (void) flock(fd, LOCK_SH); + while ((i = read(fd, line, sizeof(line))) > 0) + (void) fwrite(line, 1, i, stdout); + (void) close(fd); /* unlocks as well */ + } else + putchar('\n'); + } + if (statb.st_mode & 010) { + if (sendtorem) + printf("%s: ", host); + printf("Warning: %s queue is turned off\n", printer); + } + } + + if (nitems) { + fp = fopen(LO, "r"); + if (fp == NULL) + warn(); + else { + /* get daemon pid */ + cp = current; + while ((*cp = getc(fp)) != EOF && *cp != '\n') + cp++; + *cp = '\0'; + i = atoi(current); + if (i <= 0 || kill(i, 0) < 0) + warn(); + else { + /* read current file name */ + cp = current; + while ((*cp = getc(fp)) != EOF && *cp != '\n') + cp++; + *cp = '\0'; + /* + * Print the status file. + */ + if (sendtorem) + printf("%s: ", host); + fd = open(ST, O_RDONLY); + if (fd >= 0) { + (void) flock(fd, LOCK_SH); + while ((i = read(fd, line, sizeof(line))) > 0) + (void) fwrite(line, 1, i, stdout); + (void) close(fd); /* unlocks as well */ + } else + putchar('\n'); + } + (void) fclose(fp); + } + /* + * Now, examine the control files and print out the jobs to + * be done for each user. + */ + if (!lflag) + header(); + for (i = 0; i < nitems; i++) { + q = queue[i]; + inform(q->q_name); + free(q); + } + free(queue); + } + if (!sendtorem) { + if (nitems == 0) + puts("no entries"); + return; + } + + /* + * Print foreign queue + * Note that a file in transit may show up in either queue. + */ + if (nitems) + putchar('\n'); + (void) sprintf(line, "%c%s", format + '\3', RP); + cp = line; + for (i = 0; i < requests; i++) { + cp += strlen(cp); + (void) sprintf(cp, " %d", requ[i]); + } + for (i = 0; i < users; i++) { + cp += strlen(cp); + *cp++ = ' '; + (void) strcpy(cp, user[i]); + } + strcat(line, "\n"); + fd = getport(RM); + if (fd < 0) { + if (from != host) + printf("%s: ", host); + printf("connection to %s is down\n", RM); + } + else { + i = strlen(line); + if (write(fd, line, i) != i) + fatal("Lost connection"); + while ((i = read(fd, line, sizeof(line))) > 0) + (void) fwrite(line, 1, i, stdout); + (void) close(fd); + } +} + +/* + * Print a warning message if there is no daemon present. + */ +void +warn() +{ + if (sendtorem) + printf("\n%s: ", host); + puts("Warning: no daemon present"); + current[0] = '\0'; +} + +/* + * Print the header for the short listing format + */ +void +header() +{ + printf(head0); + col = strlen(head0)+1; + blankfill(SIZCOL); + printf(head1); +} + +void +inform(cf) + char *cf; +{ + register int j; + FILE *cfp; + + /* + * There's a chance the control file has gone away + * in the meantime; if this is the case just keep going + */ + if ((cfp = fopen(cf, "r")) == NULL) + return; + + if (rank < 0) + rank = 0; + if (sendtorem || garbage || strcmp(cf, current)) + rank++; + j = 0; + while (getline(cfp)) { + switch (line[0]) { + case 'P': /* Was this file specified in the user's list? */ + if (!inlist(line+1, cf)) { + fclose(cfp); + return; + } + if (lflag) { + printf("\n%s: ", line+1); + col = strlen(line+1) + 2; + prank(rank); + blankfill(JOBCOL); + printf(" [job %s]\n", cf+3); + } else { + col = 0; + prank(rank); + blankfill(OWNCOL); + printf("%-10s %-3d ", line+1, atoi(cf+3)); + col += 16; + first = 1; + } + continue; + default: /* some format specifer and file name? */ + if (line[0] < 'a' || line[0] > 'z') + continue; + if (j == 0 || strcmp(file, line+1) != 0) + (void) strcpy(file, line+1); + j++; + continue; + case 'N': + show(line+1, file, j); + file[0] = '\0'; + j = 0; + } + } + fclose(cfp); + if (!lflag) { + blankfill(SIZCOL); + printf("%ld bytes\n", totsize); + totsize = 0; + } +} + +int +inlist(name, file) + char *name, *file; +{ + register int *r, n; + register char **u, *cp; + + if (users == 0 && requests == 0) + return(1); + /* + * Check to see if it's in the user list + */ + for (u = user; u < &user[users]; u++) + if (!strcmp(*u, name)) + return(1); + /* + * Check the request list + */ + for (n = 0, cp = file+3; isdigit(*cp); ) + n = n * 10 + (*cp++ - '0'); + for (r = requ; r < &requ[requests]; r++) + if (*r == n && !strcmp(cp, from)) + return(1); + return(0); +} + +void +show(nfile, file, copies) + register char *nfile, *file; + int copies; +{ + if (strcmp(nfile, " ") == 0) + nfile = "(standard input)"; + if (lflag) + ldump(nfile, file, copies); + else + dump(nfile, file, copies); +} + +/* + * Fill the line with blanks to the specified column + */ +void +blankfill(n) + register int n; +{ + while (col++ < n) + putchar(' '); +} + +/* + * Give the abbreviated dump of the file names + */ +void +dump(nfile, file, copies) + char *nfile, *file; + int copies; +{ + register short n, fill; + struct stat lbuf; + + /* + * Print as many files as will fit + * (leaving room for the total size) + */ + fill = first ? 0 : 2; /* fill space for ``, '' */ + if (((n = strlen(nfile)) + col + fill) >= SIZCOL-4) { + if (col < SIZCOL) { + printf(" ..."), col += 4; + blankfill(SIZCOL); + } + } else { + if (first) + first = 0; + else + printf(", "); + printf("%s", nfile); + col += n+fill; + } + if (*file && !stat(file, &lbuf)) + totsize += copies * lbuf.st_size; +} + +/* + * Print the long info about the file + */ +void +ldump(nfile, file, copies) + char *nfile, *file; + int copies; +{ + struct stat lbuf; + + putchar('\t'); + if (copies > 1) + printf("%-2d copies of %-19s", copies, nfile); + else + printf("%-32s", nfile); + if (*file && !stat(file, &lbuf)) + printf(" %qd bytes", lbuf.st_size); + else + printf(" ??? bytes"); + putchar('\n'); +} + +/* + * Print the job's rank in the queue, + * update col for screen management + */ +void +prank(n) + int n; +{ + char rline[100]; + static char *r[] = { + "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" + }; + + if (n == 0) { + printf("active"); + col += 6; + return; + } + if ((n/10)%10 == 1) + (void)snprintf(rline, sizeof(rline), "%dth", n); + else + (void)snprintf(rline, sizeof(rline), "%d%s", n, r[n%10]); + col += strlen(rline); + printf("%s", rline); +} diff --git a/usr.sbin/lpr/common_source/lp.h b/usr.sbin/lpr/common_source/lp.h new file mode 100644 index 0000000..6dd1bf0 --- /dev/null +++ b/usr.sbin/lpr/common_source/lp.h @@ -0,0 +1,126 @@ +/* + * 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. + * + * @(#)lp.h 8.1 (Berkeley) 6/6/93 + */ + + +/* + * Global definitions for the line printer system. + */ + +extern char *AF; /* accounting file */ +extern long BR; /* baud rate if lp is a tty */ +extern char *CF; /* name of cifplot filter (per job) */ +extern char *DF; /* name of tex filter (per job) */ +extern long DU; /* daeomon user-id */ +extern long FC; /* flags to clear if lp is a tty */ +extern char *FF; /* form feed string */ +extern long FS; /* flags to set if lp is a tty */ +extern char *GF; /* name of graph(1G) filter (per job) */ +extern long HL; /* print header last */ +extern char *IF; /* name of input filter (created per job) */ +extern char *LF; /* log file for error messages */ +extern char *LO; /* lock file name */ +extern char *LP; /* line printer device name */ +extern long MC; /* maximum number of copies allowed */ +extern long MX; /* maximum number of blocks to copy */ +extern char *NF; /* name of ditroff(1) filter (per job) */ +extern char *OF; /* name of output filter (created once) */ +extern long PL; /* page length */ +extern long PW; /* page width */ +extern long PX; /* page width in pixels */ +extern long PY; /* page length in pixels */ +extern char *RF; /* name of fortran text filter (per job) */ +extern char *RG; /* restricted group */ +extern char *RM; /* remote machine name */ +extern char *RP; /* remote printer name */ +extern long RS; /* restricted to those with local accounts */ +extern long RW; /* open LP for reading and writing */ +extern long SB; /* short banner instead of normal header */ +extern long SC; /* suppress multiple copies */ +extern char *SD; /* spool directory */ +extern long SF; /* suppress FF on each print job */ +extern long SH; /* suppress header page */ +extern char *ST; /* status file name */ +extern char *TF; /* name of troff(1) filter (per job) */ +extern char *TR; /* trailer string to be output when Q empties */ +extern char *VF; /* name of raster filter (per job) */ +extern long XC; /* flags to clear for local mode */ +extern long XS; /* flags to set for local mode */ + +extern char line[BUFSIZ]; +extern char *bp; /* pointer into printcap buffer */ +extern char *name; /* program name */ +extern char *printer; /* printer name */ + /* host machine name */ +extern char host[MAXHOSTNAMELEN]; +extern char *from; /* client's machine name */ +extern int sendtorem; /* are we sending to a remote? */ +extern char *printcapdb[]; /* printcap database array */ +/* + * Structure used for building a sorted list of control files. + */ +struct queue { + time_t q_time; /* modification time */ + char q_name[MAXNAMLEN+1]; /* control file name */ +}; + +#include + +__BEGIN_DECLS +struct dirent; + +void blankfill __P((int)); +char *checkremote __P((void)); +int chk __P((char *)); +void displayq __P((int)); +void dump __P((char *, char *, int)); +void fatal __P((const char *, ...)); +int getline __P((FILE *)); +int getport __P((char *)); +int getq __P((struct queue *(*[]))); +void header __P((void)); +void inform __P((char *)); +int inlist __P((char *, char *)); +int iscf __P((struct dirent *)); +int isowner __P((char *, char *)); +void ldump __P((char *, char *, int)); +int lockchk __P((char *)); +void prank __P((int)); +void process __P((char *)); +void rmjob __P((void)); +void rmremote __P((void)); +void show __P((char *, char *, int)); +int startdaemon __P((char *)); +void warn __P((void)); +__END_DECLS diff --git a/usr.sbin/lpr/common_source/lp.local.h b/usr.sbin/lpr/common_source/lp.local.h new file mode 100644 index 0000000..837fd2f --- /dev/null +++ b/usr.sbin/lpr/common_source/lp.local.h @@ -0,0 +1,80 @@ +/* + * 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. + * + * @(#)lp.local.h 8.1 (Berkeley) 6/6/93 + */ + +/* + * Possibly, local parameters to the spooling system + */ + +/* + * Defaults for line printer capabilities data base + */ +#define DEFLP "lp" +#define DEFLOCK "lock" +#define DEFSTAT "status" +#define DEFMX 1000 +#define DEFMAXCOPIES 0 +#define DEFFF "\f" +#define DEFWIDTH 132 +#define DEFLENGTH 66 +#define DEFUID 1 + +/* + * When files are created in the spooling area, they are normally + * readable only by their owner and the spooling group. If you + * want otherwise, change this mode. + */ +#define FILMOD 0660 + +/* + * Printer is assumed to support LINELEN (for block chars) + * and background character (blank) is a space + */ +#define LINELEN 132 +#define BACKGND ' ' + +#define HEIGHT 9 /* height of characters */ +#define WIDTH 8 /* width of characters */ +#define DROP 3 /* offset to drop characters with descenders */ + +/* + * Define TERMCAP if the terminal capabilites are to be used for lpq. + */ +#define TERMCAP + +/* + * Maximum number of user and job requests for lpq and lprm. + */ +#define MAXUSERS 50 +#define MAXREQUESTS 50 diff --git a/usr.sbin/lpr/common_source/pathnames.h b/usr.sbin/lpr/common_source/pathnames.h new file mode 100644 index 0000000..5c07cdb --- /dev/null +++ b/usr.sbin/lpr/common_source/pathnames.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 1989, 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.1 (Berkeley) 6/6/93 + */ + +#include + +#define _PATH_DEFDEVLP "/dev/lp" +#define _PATH_DEFSPOOL "/var/spool/output/lpd" +#define _PATH_HOSTSEQUIV "/etc/hosts.equiv" +#define _PATH_HOSTSLPD "/etc/hosts.lpd" +#define _PATH_MASTERLOCK "/var/spool/output/lpd.lock" +#define _PATH_PR "/usr/bin/pr" +#define _PATH_PRINTCAP "/etc/printcap" +#define _PATH_SOCKETNAME "/var/run/printer" +#define _PATH_VFONT "/usr/libdata/vfont/" +#define _PATH_VFONTB "/usr/libdata/vfont/B" +#define _PATH_VFONTI "/usr/libdata/vfont/I" +#define _PATH_VFONTR "/usr/libdata/vfont/R" +#define _PATH_VFONTS "/usr/libdata/vfont/S" diff --git a/usr.sbin/lpr/common_source/printcap.c b/usr.sbin/lpr/common_source/printcap.c new file mode 100644 index 0000000..627d2ce --- /dev/null +++ b/usr.sbin/lpr/common_source/printcap.c @@ -0,0 +1,458 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)printcap.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include + +#include +#include +#include +#include +#include +#include +#include "lp.h" +#include "pathnames.h" + +#ifndef BUFSIZ +#define BUFSIZ 1024 +#endif +#define MAXHOP 32 /* max number of tc= indirections */ + +/* + * termcap - routines for dealing with the terminal capability data base + * + * BUG: Should use a "last" pointer in tbuf, so that searching + * for capabilities alphabetically would not be a n**2/2 + * process when large numbers of capabilities are given. + * Note: If we add a last pointer now we will screw up the + * tc capability. We really should compile termcap. + * + * Essentially all the work here is scanning and decoding escapes + * in string capabilities. We don't use stdio because the editor + * doesn't, and because living w/o it is not hard. + */ + +#define PRINTCAP + +#ifdef PRINTCAP +#define tgetent pgetent +#define tskip pskip +#define tgetstr pgetstr +#define tdecode pdecode +#define tgetnum pgetnum +#define tgetflag pgetflag +#define tdecode pdecode +#define tnchktc pnchktc +#define tnamatch pnamatch +#define V6 +#endif + +static FILE *pfp = NULL; /* printcap data base file pointer */ +static char *tbuf; +static int hopcount; /* detect infinite loops in termcap, init 0 */ + +static char *tskip __P((char *)); +static char *tskip __P((char *bp)); +static char *tdecode __P((char *, char **)); + +/* + * Similar to tgetent except it returns the next enrty instead of + * doing a lookup. + */ +int +getprent(bp) + register char *bp; +{ + register int c, skip = 0; + + if (pfp == NULL && (pfp = fopen(_PATH_PRINTCAP, "r")) == NULL) + return(-1); + tbuf = bp; + for (;;) { + switch (c = getc(pfp)) { + case EOF: + fclose(pfp); + pfp = NULL; + return(0); + case '\n': + if (bp == tbuf) { + skip = 0; + continue; + } + if (bp[-1] == '\\') { + bp--; + continue; + } + *bp = '\0'; + return(1); + case '#': + if (bp == tbuf) + skip++; + default: + if (skip) + continue; + if (bp >= tbuf+BUFSIZ) { + write(2, "Termcap entry too long\n", 23); + *bp = '\0'; + return(1); + } + *bp++ = c; + } + } +} + +void +endprent() +{ + if (pfp != NULL) + fclose(pfp); +} + +/* + * Get an entry for terminal name in buffer bp, + * from the termcap file. Parse is very rudimentary; + * we just notice escaped newlines. + */ +int +tgetent(bp, name) + char *bp, *name; +{ + register char *cp; + register int c; + register int i = 0, cnt = 0; + char ibuf[BUFSIZ]; + int tf; + + tbuf = bp; + tf = 0; +#ifndef V6 + cp = getenv("TERMCAP"); + /* + * TERMCAP can have one of two things in it. It can be the + * name of a file to use instead of /etc/termcap. In this + * case it better start with a "/". Or it can be an entry to + * use so we don't have to read the file. In this case it + * has to already have the newlines crunched out. + */ + if (cp && *cp) { + if (*cp!='/') { + cp2 = getenv("TERM"); + if (cp2==(char *) 0 || strcmp(name,cp2)==0) { + strcpy(bp,cp); + return(tnchktc()); + } else { + tf = open(_PATH_PRINTCAP, 0); + } + } else + tf = open(cp, 0); + } + if (tf==0) + tf = open(_PATH_PRINTCAP, 0); +#else + tf = open(_PATH_PRINTCAP, 0); +#endif + if (tf < 0) + return (-1); + for (;;) { + cp = bp; + for (;;) { + if (i == cnt) { + cnt = read(tf, ibuf, BUFSIZ); + if (cnt <= 0) { + close(tf); + return (0); + } + i = 0; + } + c = ibuf[i++]; + if (c == '\n') { + if (cp > bp && cp[-1] == '\\'){ + cp--; + continue; + } + break; + } + if (cp >= bp+BUFSIZ) { + write(2,"Termcap entry too long\n", 23); + break; + } else + *cp++ = c; + } + *cp = 0; + + /* + * The real work for the match. + */ + if (tnamatch(name)) { + close(tf); + return(tnchktc()); + } + } +} + +/* + * tnchktc: check the last entry, see if it's tc=xxx. If so, + * recursively find xxx and append that entry (minus the names) + * to take the place of the tc=xxx entry. This allows termcap + * entries to say "like an HP2621 but doesn't turn on the labels". + * Note that this works because of the left to right scan. + */ +int +tnchktc() +{ + register char *p, *q; + char tcname[16]; /* name of similar terminal */ + char tcbuf[BUFSIZ]; + char *holdtbuf = tbuf; + int l; + + p = tbuf + strlen(tbuf) - 2; /* before the last colon */ + while (*--p != ':') + if (p MAXHOP) { + write(2, "Infinite tc= loop\n", 18); + return (0); + } + if (tgetent(tcbuf, tcname) != 1) + return(0); + for (q=tcbuf; *q != ':'; q++) + ; + l = p - holdtbuf + strlen(q); + if (l > BUFSIZ) { + write(2, "Termcap entry too long\n", 23); + q[BUFSIZ - (p-tbuf)] = 0; + } + strcpy(p, q+1); + tbuf = holdtbuf; + return(1); +} + +/* + * Tnamatch deals with name matching. The first field of the termcap + * entry is a sequence of names separated by |'s, so we compare + * against each such name. The normal : terminator after the last + * name (before the first field) stops us. + */ +int +tnamatch(np) + char *np; +{ + register char *Np, *Bp; + + Bp = tbuf; + if (*Bp == '#') + return(0); + for (;;) { + for (Np = np; *Np && *Bp == *Np; Bp++, Np++) + continue; + if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0)) + return (1); + while (*Bp && *Bp != ':' && *Bp != '|') + Bp++; + if (*Bp == 0 || *Bp == ':') + return (0); + Bp++; + } +} + +/* + * Skip to the next field. Notice that this is very dumb, not + * knowing about \: escapes or any such. If necessary, :'s can be put + * into the termcap file in octal. + */ +static char * +tskip(bp) + register char *bp; +{ + + while (*bp && *bp != ':') + bp++; + if (*bp == ':') + bp++; + return (bp); +} + +/* + * Return the (numeric) option id. + * Numeric options look like + * li#80 + * i.e. the option string is separated from the numeric value by + * a # character. If the option is not found we return -1. + * Note that we handle octal numbers beginning with 0. + */ +int +tgetnum(id) + char *id; +{ + register int i, base; + register char *bp = tbuf; + + for (;;) { + bp = tskip(bp); + if (*bp == 0) + return (-1); + if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1]) + continue; + if (*bp == '@') + return(-1); + if (*bp != '#') + continue; + bp++; + base = 10; + if (*bp == '0') + base = 8; + i = 0; + while (isdigit(*bp)) + i *= base, i += *bp++ - '0'; + return (i); + } +} + +/* + * Handle a flag option. + * Flag options are given "naked", i.e. followed by a : or the end + * of the buffer. Return 1 if we find the option, or 0 if it is + * not given. + */ +int +tgetflag(id) + char *id; +{ + register char *bp = tbuf; + + for (;;) { + bp = tskip(bp); + if (!*bp) + return (0); + if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) { + if (!*bp || *bp == ':') + return (1); + else if (*bp == '@') + return(0); + } + } +} + +/* + * Get a string valued option. + * These are given as + * cl=^Z + * Much decoding is done on the strings, and the strings are + * placed in area, which is a ref parameter which is updated. + * No checking on area overflow. + */ +char * +tgetstr(id, area) + char *id, **area; +{ + register char *bp = tbuf; + + for (;;) { + bp = tskip(bp); + if (!*bp) + return (0); + if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1]) + continue; + if (*bp == '@') + return(0); + if (*bp != '=') + continue; + bp++; + return (tdecode(bp, area)); + } +} + +/* + * Tdecode does the grung work to decode the + * string capability escapes. + */ +static char * +tdecode(str, area) + register char *str; + char **area; +{ + register char *cp; + register int c; + register char *dp; + int i; + + cp = *area; + while ((c = *str++) && c != ':') { + switch (c) { + + case '^': + c = *str++ & 037; + break; + + case '\\': + dp = "E\033^^\\\\::n\nr\rt\tb\bf\f"; + c = *str++; +nextc: + if (*dp++ == c) { + c = *dp++; + break; + } + dp++; + if (*dp) + goto nextc; + if (isdigit(c)) { + c -= '0', i = 2; + do + c <<= 3, c |= *str++ - '0'; + while (--i && isdigit(*str)); + } + break; + } + *cp++ = c; + } + *cp++ = 0; + str = *area; + *area = cp; + return (str); +} + diff --git a/usr.sbin/lpr/common_source/rmjob.c b/usr.sbin/lpr/common_source/rmjob.c new file mode 100644 index 0000000..74a94d8 --- /dev/null +++ b/usr.sbin/lpr/common_source/rmjob.c @@ -0,0 +1,339 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)rmjob.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "lp.h" +#include "lp.local.h" +#include "pathnames.h" + +/* + * rmjob - remove the specified jobs from the queue. + */ + +/* + * Stuff for handling lprm specifications + */ +extern char *user[]; /* users to process */ +extern int users; /* # of users in user array */ +extern int requ[]; /* job number of spool entries */ +extern int requests; /* # of spool requests */ +extern char *person; /* name of person doing lprm */ + +static char root[] = "root"; +static int all = 0; /* eliminate all files (root only) */ +static int cur_daemon; /* daemon's pid */ +static char current[40]; /* active control file name */ + +void +rmjob() +{ + register int i, nitems; + int assasinated = 0; + struct dirent **files; + char *cp; + + if ((i = cgetent(&bp, printcapdb, printer)) == -2) + fatal("can't open printer description file"); + else if (i == -1) + fatal("unknown printer"); + else if (i == -3) + fatal("potential reference loop detected in printcap file"); + if (cgetstr(bp, "lp", &LP) < 0) + LP = _PATH_DEFDEVLP; + if (cgetstr(bp, "rp", &RP) < 0) + RP = DEFLP; + if (cgetstr(bp, "sd", &SD) < 0) + SD = _PATH_DEFSPOOL; + if (cgetstr(bp,"lo", &LO) < 0) + LO = DEFLOCK; + cgetstr(bp, "rm", &RM); + if (cp = checkremote()) + printf("Warning: %s\n", cp); + + /* + * If the format was `lprm -' and the user isn't the super-user, + * then fake things to look like he said `lprm user'. + */ + if (users < 0) { + if (getuid() == 0) + all = 1; /* all files in local queue */ + else { + user[0] = person; + users = 1; + } + } + if (!strcmp(person, "-all")) { + if (from == host) + fatal("The login name \"-all\" is reserved"); + all = 1; /* all those from 'from' */ + person = root; + } + + if (chdir(SD) < 0) + fatal("cannot chdir to spool directory"); + if ((nitems = scandir(".", &files, iscf, NULL)) < 0) + fatal("cannot access spool directory"); + + if (nitems) { + /* + * Check for an active printer daemon (in which case we + * kill it if it is reading our file) then remove stuff + * (after which we have to restart the daemon). + */ + if (lockchk(LO) && chk(current)) { + assasinated = kill(cur_daemon, SIGINT) == 0; + if (!assasinated) + fatal("cannot kill printer daemon"); + } + /* + * process the files + */ + for (i = 0; i < nitems; i++) + process(files[i]->d_name); + } + rmremote(); + /* + * Restart the printer daemon if it was killed + */ + if (assasinated && !startdaemon(printer)) + fatal("cannot restart printer daemon\n"); + exit(0); +} + +/* + * Process a lock file: collect the pid of the active + * daemon and the file name of the active spool entry. + * Return boolean indicating existence of a lock file. + */ +int +lockchk(s) + char *s; +{ + register FILE *fp; + register int i, n; + + if ((fp = fopen(s, "r")) == NULL) + if (errno == EACCES) + fatal("can't access lock file"); + else + return(0); + if (!getline(fp)) { + (void) fclose(fp); + return(0); /* no daemon present */ + } + cur_daemon = atoi(line); + if (kill(cur_daemon, 0) < 0) { + (void) fclose(fp); + return(0); /* no daemon present */ + } + for (i = 1; (n = fread(current, sizeof(char), sizeof(current), fp)) <= 0; i++) { + if (i > 5) { + n = 1; + break; + } + sleep(i); + } + current[n-1] = '\0'; + (void) fclose(fp); + return(1); +} + +/* + * Process a control file. + */ +void +process(file) + char *file; +{ + FILE *cfp; + + if (!chk(file)) + return; + if ((cfp = fopen(file, "r")) == NULL) + fatal("cannot open %s", file); + while (getline(cfp)) { + switch (line[0]) { + case 'U': /* unlink associated files */ + if (from != host) + printf("%s: ", host); + printf(unlink(line+1) ? "cannot dequeue %s\n" : + "%s dequeued\n", line+1); + } + } + (void) fclose(cfp); + if (from != host) + printf("%s: ", host); + printf(unlink(file) ? "cannot dequeue %s\n" : "%s dequeued\n", file); +} + +/* + * Do the dirty work in checking + */ +int +chk(file) + char *file; +{ + register int *r, n; + register char **u, *cp; + FILE *cfp; + + /* + * Check for valid cf file name (mostly checking current). + */ + if (strlen(file) < 7 || file[0] != 'c' || file[1] != 'f') + return(0); + + if (all && (from == host || !strcmp(from, file+6))) + return(1); + + /* + * get the owner's name from the control file. + */ + if ((cfp = fopen(file, "r")) == NULL) + return(0); + while (getline(cfp)) { + if (line[0] == 'P') + break; + } + (void) fclose(cfp); + if (line[0] != 'P') + return(0); + + if (users == 0 && requests == 0) + return(!strcmp(file, current) && isowner(line+1, file)); + /* + * Check the request list + */ + for (n = 0, cp = file+3; isdigit(*cp); ) + n = n * 10 + (*cp++ - '0'); + for (r = requ; r < &requ[requests]; r++) + if (*r == n && isowner(line+1, file)) + return(1); + /* + * Check to see if it's in the user list + */ + for (u = user; u < &user[users]; u++) + if (!strcmp(*u, line+1) && isowner(line+1, file)) + return(1); + return(0); +} + +/* + * If root is removing a file on the local machine, allow it. + * If root is removing a file from a remote machine, only allow + * files sent from the remote machine to be removed. + * Normal users can only remove the file from where it was sent. + */ +int +isowner(owner, file) + char *owner, *file; +{ + if (!strcmp(person, root) && (from == host || !strcmp(from, file+6))) + return(1); + if (!strcmp(person, owner) && !strcmp(from, file+6)) + return(1); + if (from != host) + printf("%s: ", host); + printf("%s: Permission denied\n", file); + return(0); +} + +/* + * Check to see if we are sending files to a remote machine. If we are, + * then try removing files on the remote machine. + */ +void +rmremote() +{ + register char *cp; + register int i, rem; + char buf[BUFSIZ]; + + if (!sendtorem) + return; /* not sending to a remote machine */ + + /* + * Flush stdout so the user can see what has been deleted + * while we wait (possibly) for the connection. + */ + fflush(stdout); + + (void)snprintf(buf, sizeof(buf), "\5%s %s", RP, all ? "-all" : person); + cp = buf; + for (i = 0; i < users; i++) { + cp += strlen(cp); + *cp++ = ' '; + strcpy(cp, user[i]); + } + for (i = 0; i < requests; i++) { + cp += strlen(cp); + (void) sprintf(cp, " %d", requ[i]); + } + strcat(cp, "\n"); + rem = getport(RM); + if (rem < 0) { + if (from != host) + printf("%s: ", host); + printf("connection to %s is down\n", RM); + } else { + i = strlen(buf); + if (write(rem, buf, i) != i) + fatal("Lost connection"); + while ((i = read(rem, buf, sizeof(buf))) > 0) + (void) fwrite(buf, 1, i, stdout); + (void) close(rem); + } +} + +/* + * Return 1 if the filename begins with 'cf' + */ +int +iscf(d) + struct dirent *d; +{ + return(d->d_name[0] == 'c' && d->d_name[1] == 'f'); +} diff --git a/usr.sbin/lpr/common_source/startdaemon.c b/usr.sbin/lpr/common_source/startdaemon.c new file mode 100644 index 0000000..237769e --- /dev/null +++ b/usr.sbin/lpr/common_source/startdaemon.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 1983, 1993, 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)startdaemon.c 8.2 (Berkeley) 4/17/94"; +#endif /* not lint */ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include "lp.h" +#include "pathnames.h" + +static void perr __P((char *)); + +/* + * Tell the printer daemon that there are new files in the spool directory. + */ + +int +startdaemon(printer) + char *printer; +{ + struct sockaddr_un un; + register int s, n; + char buf[BUFSIZ]; + + s = socket(AF_UNIX, SOCK_STREAM, 0); + if (s < 0) { + perr("socket"); + return(0); + } + memset(&un, 0, sizeof(un)); + un.sun_family = AF_UNIX; + strcpy(un.sun_path, _PATH_SOCKETNAME); +#ifndef SUN_LEN +#define SUN_LEN(unp) (strlen((unp)->sun_path) + 2) +#endif + if (connect(s, (struct sockaddr *)&un, SUN_LEN(&un)) < 0) { + perr("connect"); + (void) close(s); + return(0); + } + (void) sprintf(buf, "\1%s\n", printer); + n = strlen(buf); + if (write(s, buf, n) != n) { + perr("write"); + (void) close(s); + return(0); + } + if (read(s, buf, 1) == 1) { + if (buf[0] == '\0') { /* everything is OK */ + (void) close(s); + return(1); + } + putchar(buf[0]); + } + while ((n = read(s, buf, sizeof(buf))) > 0) + fwrite(buf, 1, n, stdout); + (void) close(s); + return(0); +} + +static void +perr(msg) + char *msg; +{ + extern char *name; + + (void)printf("%s: %s: %s\n", name, msg, strerror(errno)); +} diff --git a/usr.sbin/lpr/filters/Makefile b/usr.sbin/lpr/filters/Makefile new file mode 100644 index 0000000..c9d5c4f --- /dev/null +++ b/usr.sbin/lpr/filters/Makefile @@ -0,0 +1,7 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= lpf +NOMAN= noman +BINDIR= /usr/libexec/lpr + +.include diff --git a/usr.sbin/lpr/filters/lpf.c b/usr.sbin/lpr/filters/lpf.c new file mode 100644 index 0000000..5335f31 --- /dev/null +++ b/usr.sbin/lpr/filters/lpf.c @@ -0,0 +1,217 @@ +/* + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)lpf.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * filter which reads the output of nroff and converts lines + * with ^H's to overwritten lines. Thus this works like 'ul' + * but is much better: it can handle more than 2 overwrites + * and it is written with some style. + * modified by kls to use register references instead of arrays + * to try to gain a little speed. + */ + +#include +#include +#include +#include + +#define MAXWIDTH 132 +#define MAXREP 10 + +char buf[MAXREP][MAXWIDTH]; +int maxcol[MAXREP] = {-1}; +int lineno; +int width = 132; /* default line length */ +int length = 66; /* page length */ +int indent; /* indentation length */ +int npages = 1; +int literal; /* print control characters */ +char *name; /* user's login name */ +char *host; /* user's machine name */ +char *acctfile; /* accounting information file */ + +int +main(argc, argv) + int argc; + char *argv[]; +{ + register FILE *p = stdin, *o = stdout; + register int i, col; + register char *cp; + int done, linedone, maxrep; + char ch, *limit; + + while (--argc) { + if (*(cp = *++argv) == '-') { + switch (cp[1]) { + case 'n': + argc--; + name = *++argv; + break; + + case 'h': + argc--; + host = *++argv; + break; + + case 'w': + if ((i = atoi(&cp[2])) > 0 && i <= MAXWIDTH) + width = i; + break; + + case 'l': + length = atoi(&cp[2]); + break; + + case 'i': + indent = atoi(&cp[2]); + break; + + case 'c': /* Print control chars */ + literal++; + break; + } + } else + acctfile = cp; + } + + for (cp = buf[0], limit = buf[MAXREP]; cp < limit; *cp++ = ' '); + done = 0; + + while (!done) { + col = indent; + maxrep = -1; + linedone = 0; + while (!linedone) { + switch (ch = getc(p)) { + case EOF: + linedone = done = 1; + ch = '\n'; + break; + + case '\f': + lineno = length; + case '\n': + if (maxrep < 0) + maxrep = 0; + linedone = 1; + break; + + case '\b': + if (--col < indent) + col = indent; + break; + + case '\r': + col = indent; + break; + + case '\t': + col = ((col - indent) | 07) + indent + 1; + break; + + case '\031': + /* + * lpd needs to use a different filter to + * print data so stop what we are doing and + * wait for lpd to restart us. + */ + if ((ch = getchar()) == '\1') { + fflush(stdout); + kill(getpid(), SIGSTOP); + break; + } else { + ungetc(ch, stdin); + ch = '\031'; + } + + default: + if (col >= width || !literal && ch < ' ') { + col++; + break; + } + cp = &buf[0][col]; + for (i = 0; i < MAXREP; i++) { + if (i > maxrep) + maxrep = i; + if (*cp == ' ') { + *cp = ch; + if (col > maxcol[i]) + maxcol[i] = col; + break; + } + cp += MAXWIDTH; + } + col++; + break; + } + } + + /* print out lines */ + for (i = 0; i <= maxrep; i++) { + for (cp = buf[i], limit = cp+maxcol[i]; cp <= limit;) { + putc(*cp, o); + *cp++ = ' '; + } + if (i < maxrep) + putc('\r', o); + else + putc(ch, o); + if (++lineno >= length) { + fflush(o); + npages++; + lineno = 0; + } + maxcol[i] = -1; + } + } + if (lineno) { /* be sure to end on a page boundary */ + putchar('\f'); + npages++; + } + if (name && acctfile && access(acctfile, 02) >= 0 && + freopen(acctfile, "a", stdout) != NULL) { + printf("%7.2f\t%s:%s\n", (float)npages, host, name); + } + exit(0); +} diff --git a/usr.sbin/lpr/lpc/Makefile b/usr.sbin/lpr/lpc/Makefile new file mode 100644 index 0000000..10a3d69 --- /dev/null +++ b/usr.sbin/lpr/lpc/Makefile @@ -0,0 +1,12 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= lpc +CFLAGS+=-I${.CURDIR}/../common_source +MAN8= lpc.0 +SRCS= lpc.c cmds.c cmdtab.c startdaemon.c common.c +BINGRP= daemon +BINMODE=2555 +.PATH: ${.CURDIR}/../common_source + +.include "../../Makefile.inc" +.include diff --git a/usr.sbin/lpr/lpc/cmds.c b/usr.sbin/lpr/lpc/cmds.c new file mode 100644 index 0000000..7c2b6fe --- /dev/null +++ b/usr.sbin/lpr/lpc/cmds.c @@ -0,0 +1,1107 @@ +/* + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)cmds.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * lpc -- line printer control program -- commands: + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lp.h" +#include "lp.local.h" +#include "lpc.h" +#include "extern.h" +#include "pathnames.h" + +static void abortpr __P((int)); +static void cleanpr __P((void)); +static void disablepr __P((void)); +static int doarg __P((char *)); +static int doselect __P((struct dirent *)); +static void enablepr __P((void)); +static void prstat __P((void)); +static void putmsg __P((int, char **)); +static int sortq __P((const void *, const void *)); +static void startpr __P((int)); +static void stoppr __P((void)); +static int touch __P((struct queue *)); +static void unlinkf __P((char *)); +static void upstat __P((char *)); + +/* + * kill an existing daemon and disable printing. + */ +void +doabort(argc, argv) + int argc; + char *argv[]; +{ + register int c, status; + register char *cp1, *cp2; + char prbuf[100]; + + if (argc == 1) { + printf("Usage: abort {all | printer ...}\n"); + return; + } + if (argc == 2 && !strcmp(argv[1], "all")) { + printer = prbuf; + while (cgetnext(&bp, printcapdb) > 0) { + cp1 = prbuf; + cp2 = bp; + while ((c = *cp2++) && c != '|' && c != ':') + *cp1++ = c; + *cp1 = '\0'; + abortpr(1); + } + return; + } + while (--argc) { + printer = *++argv; + if ((status = cgetent(&bp, printcapdb, printer)) == -2) { + printf("cannot open printer description file\n"); + continue; + } else if (status == -1) { + printf("unknown printer %s\n", printer); + continue; + } else if (status == -3) + fatal("potential reference loop detected in printcap file"); + abortpr(1); + } +} + +static void +abortpr(dis) + int dis; +{ + register FILE *fp; + struct stat stbuf; + int pid, fd; + + if (cgetstr(bp, "sd", &SD) == -1) + SD = _PATH_DEFSPOOL; + if (cgetstr(bp, "lo", &LO) == -1) + LO = DEFLOCK; + (void) sprintf(line, "%s/%s", SD, LO); + printf("%s:\n", printer); + + /* + * Turn on the owner execute bit of the lock file to disable printing. + */ + if (dis) { + if (stat(line, &stbuf) >= 0) { + if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) + printf("\tcannot disable printing\n"); + else { + upstat("printing disabled\n"); + printf("\tprinting disabled\n"); + } + } else if (errno == ENOENT) { + if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) + printf("\tcannot create lock file\n"); + else { + (void) close(fd); + upstat("printing disabled\n"); + printf("\tprinting disabled\n"); + printf("\tno daemon to abort\n"); + } + return; + } else { + printf("\tcannot stat lock file\n"); + return; + } + } + /* + * Kill the current daemon to stop printing now. + */ + if ((fp = fopen(line, "r")) == NULL) { + printf("\tcannot open lock file\n"); + return; + } + if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { + (void) fclose(fp); /* unlocks as well */ + printf("\tno daemon to abort\n"); + return; + } + (void) fclose(fp); + if (kill(pid = atoi(line), SIGTERM) < 0) + printf("\tWarning: daemon (pid %d) not killed\n", pid); + else + printf("\tdaemon (pid %d) killed\n", pid); +} + +/* + * Write a message into the status file. + */ +static void +upstat(msg) + char *msg; +{ + register int fd; + char statfile[BUFSIZ]; + + if (cgetstr(bp, "st", &ST) == -1) + ST = DEFSTAT; + (void) sprintf(statfile, "%s/%s", SD, ST); + umask(0); + fd = open(statfile, O_WRONLY|O_CREAT, 0664); + if (fd < 0 || flock(fd, LOCK_EX) < 0) { + printf("\tcannot create status file\n"); + return; + } + (void) ftruncate(fd, 0); + if (msg == (char *)NULL) + (void) write(fd, "\n", 1); + else + (void) write(fd, msg, strlen(msg)); + (void) close(fd); +} + +/* + * Remove all spool files and temporaries from the spooling area. + */ +void +clean(argc, argv) + int argc; + char *argv[]; +{ + register int c, status; + register char *cp1, *cp2; + char prbuf[100]; + + if (argc == 1) { + printf("Usage: clean {all | printer ...}\n"); + return; + } + if (argc == 2 && !strcmp(argv[1], "all")) { + printer = prbuf; + while (cgetnext(&bp, printcapdb) > 0) { + cp1 = prbuf; + cp2 = bp; + while ((c = *cp2++) && c != '|' && c != ':') + *cp1++ = c; + *cp1 = '\0'; + cleanpr(); + } + return; + } + while (--argc) { + printer = *++argv; + if ((status = cgetent(&bp, printcapdb, printer)) == -2) { + printf("cannot open printer description file\n"); + continue; + } else if (status == -1) { + printf("unknown printer %s\n", printer); + continue; + } else if (status == -3) + fatal("potential reference loop detected in printcap file"); + + cleanpr(); + } +} + +static int +doselect(d) + struct dirent *d; +{ + int c = d->d_name[0]; + + if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f') + return(1); + return(0); +} + +/* + * Comparison routine for scandir. Sort by job number and machine, then + * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z. + */ +static int +sortq(a, b) + const void *a, *b; +{ + struct dirent **d1, **d2; + int c1, c2; + + d1 = (struct dirent **)a; + d2 = (struct dirent **)b; + if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3)) + return(c1); + c1 = (*d1)->d_name[0]; + c2 = (*d2)->d_name[0]; + if (c1 == c2) + return((*d1)->d_name[2] - (*d2)->d_name[2]); + if (c1 == 'c') + return(-1); + if (c1 == 'd' || c2 == 'c') + return(1); + return(-1); +} + +/* + * Remove incomplete jobs from spooling area. + */ +static void +cleanpr() +{ + register int i, n; + register char *cp, *cp1, *lp; + struct dirent **queue; + int nitems; + + if (cgetstr(bp, "sd", &SD) == -1) + SD = _PATH_DEFSPOOL; + printf("%s:\n", printer); + + for (lp = line, cp = SD; *lp++ = *cp++; ) + ; + lp[-1] = '/'; + + nitems = scandir(SD, &queue, doselect, sortq); + if (nitems < 0) { + printf("\tcannot examine spool directory\n"); + return; + } + if (nitems == 0) + return; + i = 0; + do { + cp = queue[i]->d_name; + if (*cp == 'c') { + n = 0; + while (i + 1 < nitems) { + cp1 = queue[i + 1]->d_name; + if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3)) + break; + i++; + n++; + } + if (n == 0) { + strcpy(lp, cp); + unlinkf(line); + } + } else { + /* + * Must be a df with no cf (otherwise, it would have + * been skipped above) or a tf file (which can always + * be removed). + */ + strcpy(lp, cp); + unlinkf(line); + } + } while (++i < nitems); +} + +static void +unlinkf(name) + char *name; +{ + if (unlink(name) < 0) + printf("\tcannot remove %s\n", name); + else + printf("\tremoved %s\n", name); +} + +/* + * Enable queuing to the printer (allow lpr's). + */ +void +enable(argc, argv) + int argc; + char *argv[]; +{ + register int c, status; + register char *cp1, *cp2; + char prbuf[100]; + + if (argc == 1) { + printf("Usage: enable {all | printer ...}\n"); + return; + } + if (argc == 2 && !strcmp(argv[1], "all")) { + printer = prbuf; + while (cgetnext(&bp, printcapdb) > 0) { + cp1 = prbuf; + cp2 = bp; + while ((c = *cp2++) && c != '|' && c != ':') + *cp1++ = c; + *cp1 = '\0'; + enablepr(); + } + return; + } + while (--argc) { + printer = *++argv; + if ((status = cgetent(&bp, printcapdb, printer)) == -2) { + printf("cannot open printer description file\n"); + continue; + } else if (status == -1) { + printf("unknown printer %s\n", printer); + continue; + } else if (status == -3) + fatal("potential reference loop detected in printcap file"); + + enablepr(); + } +} + +static void +enablepr() +{ + struct stat stbuf; + + if (cgetstr(bp, "sd", &SD) == -1) + SD = _PATH_DEFSPOOL; + if (cgetstr(bp, "lo", &LO) == -1) + LO = DEFLOCK; + (void) sprintf(line, "%s/%s", SD, LO); + printf("%s:\n", printer); + + /* + * Turn off the group execute bit of the lock file to enable queuing. + */ + if (stat(line, &stbuf) >= 0) { + if (chmod(line, stbuf.st_mode & 0767) < 0) + printf("\tcannot enable queuing\n"); + else + printf("\tqueuing enabled\n"); + } +} + +/* + * Disable queuing. + */ +void +disable(argc, argv) + int argc; + char *argv[]; +{ + register int c, status; + register char *cp1, *cp2; + char prbuf[100]; + + if (argc == 1) { + printf("Usage: disable {all | printer ...}\n"); + return; + } + if (argc == 2 && !strcmp(argv[1], "all")) { + printer = prbuf; + while (cgetnext(&bp, printcapdb) > 0) { + cp1 = prbuf; + cp2 = bp; + while ((c = *cp2++) && c != '|' && c != ':') + *cp1++ = c; + *cp1 = '\0'; + disablepr(); + } + return; + } + while (--argc) { + printer = *++argv; + if ((status = cgetent(&bp, printcapdb, printer)) == -2) { + printf("cannot open printer description file\n"); + continue; + } else if (status == -1) { + printf("unknown printer %s\n", printer); + continue; + } else if (status == -3) + fatal("potential reference loop detected in printcap file"); + + disablepr(); + } +} + +static void +disablepr() +{ + register int fd; + struct stat stbuf; + + if (cgetstr(bp, "sd", &SD) == -1) + SD = _PATH_DEFSPOOL; + if (cgetstr(bp, "lo", &LO) == -1) + LO = DEFLOCK; + (void) sprintf(line, "%s/%s", SD, LO); + printf("%s:\n", printer); + /* + * Turn on the group execute bit of the lock file to disable queuing. + */ + if (stat(line, &stbuf) >= 0) { + if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0) + printf("\tcannot disable queuing\n"); + else + printf("\tqueuing disabled\n"); + } else if (errno == ENOENT) { + if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0) + printf("\tcannot create lock file\n"); + else { + (void) close(fd); + printf("\tqueuing disabled\n"); + } + return; + } else + printf("\tcannot stat lock file\n"); +} + +/* + * Disable queuing and printing and put a message into the status file + * (reason for being down). + */ +void +down(argc, argv) + int argc; + char *argv[]; +{ + register int c, status; + register char *cp1, *cp2; + char prbuf[100]; + + if (argc == 1) { + printf("Usage: down {all | printer} [message ...]\n"); + return; + } + if (!strcmp(argv[1], "all")) { + printer = prbuf; + while (cgetnext(&bp, printcapdb) > 0) { + cp1 = prbuf; + cp2 = bp; + while ((c = *cp2++) && c != '|' && c != ':') + *cp1++ = c; + *cp1 = '\0'; + putmsg(argc - 2, argv + 2); + } + return; + } + printer = argv[1]; + if ((status = cgetent(&bp, printcapdb, printer)) == -2) { + printf("cannot open printer description file\n"); + return; + } else if (status == -1) { + printf("unknown printer %s\n", printer); + return; + } else if (status == -3) + fatal("potential reference loop detected in printcap file"); + + putmsg(argc - 2, argv + 2); +} + +static void +putmsg(argc, argv) + int argc; + char **argv; +{ + register int fd; + register char *cp1, *cp2; + char buf[1024]; + struct stat stbuf; + + if (cgetstr(bp, "sd", &SD) == -1) + SD = _PATH_DEFSPOOL; + if (cgetstr(bp, "lo", &LO) == -1) + LO = DEFLOCK; + if (cgetstr(bp, "st", &ST) == -1) + ST = DEFSTAT; + printf("%s:\n", printer); + /* + * Turn on the group execute bit of the lock file to disable queuing and + * turn on the owner execute bit of the lock file to disable printing. + */ + (void) sprintf(line, "%s/%s", SD, LO); + if (stat(line, &stbuf) >= 0) { + if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0) + printf("\tcannot disable queuing\n"); + else + printf("\tprinter and queuing disabled\n"); + } else if (errno == ENOENT) { + if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0) + printf("\tcannot create lock file\n"); + else { + (void) close(fd); + printf("\tprinter and queuing disabled\n"); + } + return; + } else + printf("\tcannot stat lock file\n"); + /* + * Write the message into the status file. + */ + (void) sprintf(line, "%s/%s", SD, ST); + fd = open(line, O_WRONLY|O_CREAT, 0664); + if (fd < 0 || flock(fd, LOCK_EX) < 0) { + printf("\tcannot create status file\n"); + return; + } + (void) ftruncate(fd, 0); + if (argc <= 0) { + (void) write(fd, "\n", 1); + (void) close(fd); + return; + } + cp1 = buf; + while (--argc >= 0) { + cp2 = *argv++; + while (*cp1++ = *cp2++) + ; + cp1[-1] = ' '; + } + cp1[-1] = '\n'; + *cp1 = '\0'; + (void) write(fd, buf, strlen(buf)); + (void) close(fd); +} + +/* + * Exit lpc + */ +void +quit(argc, argv) + int argc; + char *argv[]; +{ + exit(0); +} + +/* + * Kill and restart the daemon. + */ +void +restart(argc, argv) + int argc; + char *argv[]; +{ + register int c, status; + register char *cp1, *cp2; + char prbuf[100]; + + if (argc == 1) { + printf("Usage: restart {all | printer ...}\n"); + return; + } + if (argc == 2 && !strcmp(argv[1], "all")) { + printer = prbuf; + while (cgetnext(&bp, printcapdb) > 0) { + cp1 = prbuf; + cp2 = bp; + while ((c = *cp2++) && c != '|' && c != ':') + *cp1++ = c; + *cp1 = '\0'; + abortpr(0); + startpr(0); + } + return; + } + while (--argc) { + printer = *++argv; + if ((status = cgetent(&bp, printcapdb, printer)) == -2) { + printf("cannot open printer description file\n"); + continue; + } else if (status == -1) { + printf("unknown printer %s\n", printer); + continue; + } else if (status == -3) + fatal("potential reference loop detected in printcap file"); + + abortpr(0); + startpr(0); + } +} + +/* + * Enable printing on the specified printer and startup the daemon. + */ +void +startcmd(argc, argv) + int argc; + char *argv[]; +{ + register int c, status; + register char *cp1, *cp2; + char prbuf[100]; + + if (argc == 1) { + printf("Usage: start {all | printer ...}\n"); + return; + } + if (argc == 2 && !strcmp(argv[1], "all")) { + printer = prbuf; + while (cgetnext(&bp, printcapdb) > 0) { + cp1 = prbuf; + cp2 = bp; + while ((c = *cp2++) && c != '|' && c != ':') + *cp1++ = c; + *cp1 = '\0'; + startpr(1); + } + return; + } + while (--argc) { + printer = *++argv; + if ((status = cgetent(&bp, printcapdb, printer)) == -2) { + printf("cannot open printer description file\n"); + continue; + } else if (status == -1) { + printf("unknown printer %s\n", printer); + continue; + } else if (status == -3) + fatal("potential reference loop detected in printcap file"); + + startpr(1); + } +} + +static void +startpr(enable) + int enable; +{ + struct stat stbuf; + + if (cgetstr(bp, "sd", &SD) == -1) + SD = _PATH_DEFSPOOL; + if (cgetstr(bp, "lo", &LO) == -1) + LO = DEFLOCK; + (void) sprintf(line, "%s/%s", SD, LO); + printf("%s:\n", printer); + + /* + * Turn off the owner execute bit of the lock file to enable printing. + */ + if (enable && stat(line, &stbuf) >= 0) { + if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0) + printf("\tcannot enable printing\n"); + else + printf("\tprinting enabled\n"); + } + if (!startdaemon(printer)) + printf("\tcouldn't start daemon\n"); + else + printf("\tdaemon started\n"); +} + +/* + * Print the status of each queue listed or all the queues. + */ +void +status(argc, argv) + int argc; + char *argv[]; +{ + register int c, status; + register char *cp1, *cp2; + char prbuf[100]; + + if (argc == 1) { + printer = prbuf; + while (cgetnext(&bp, printcapdb) > 0) { + cp1 = prbuf; + cp2 = bp; + while ((c = *cp2++) && c != '|' && c != ':') + *cp1++ = c; + *cp1 = '\0'; + prstat(); + } + return; + } + while (--argc) { + printer = *++argv; + if ((status = cgetent(&bp, printcapdb, printer)) == -2) { + printf("cannot open printer description file\n"); + continue; + } else if (status == -1) { + printf("unknown printer %s\n", printer); + continue; + } else if (status == -3) + fatal("potential reference loop detected in printcap file"); + + prstat(); + } +} + +/* + * Print the status of the printer queue. + */ +static void +prstat() +{ + struct stat stbuf; + register int fd, i; + register struct dirent *dp; + DIR *dirp; + + if (cgetstr(bp, "sd", &SD) == -1) + SD = _PATH_DEFSPOOL; + if (cgetstr(bp, "lo", &LO) == -1) + LO = DEFLOCK; + if (cgetstr(bp, "st", &ST) == -1) + ST = DEFSTAT; + printf("%s:\n", printer); + (void) sprintf(line, "%s/%s", SD, LO); + if (stat(line, &stbuf) >= 0) { + printf("\tqueuing is %s\n", + (stbuf.st_mode & 010) ? "disabled" : "enabled"); + printf("\tprinting is %s\n", + (stbuf.st_mode & 0100) ? "disabled" : "enabled"); + } else { + printf("\tqueuing is enabled\n"); + printf("\tprinting is enabled\n"); + } + if ((dirp = opendir(SD)) == NULL) { + printf("\tcannot examine spool directory\n"); + return; + } + i = 0; + while ((dp = readdir(dirp)) != NULL) { + if (*dp->d_name == 'c' && dp->d_name[1] == 'f') + i++; + } + closedir(dirp); + if (i == 0) + printf("\tno entries\n"); + else if (i == 1) + printf("\t1 entry in spool area\n"); + else + printf("\t%d entries in spool area\n", i); + fd = open(line, O_RDONLY); + if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { + (void) close(fd); /* unlocks as well */ + printf("\tno daemon present\n"); + return; + } + (void) close(fd); + putchar('\t'); + (void) sprintf(line, "%s/%s", SD, ST); + fd = open(line, O_RDONLY); + if (fd >= 0) { + (void) flock(fd, LOCK_SH); + while ((i = read(fd, line, sizeof(line))) > 0) + (void) fwrite(line, 1, i, stdout); + (void) close(fd); /* unlocks as well */ + } +} + +/* + * Stop the specified daemon after completing the current job and disable + * printing. + */ +void +stop(argc, argv) + int argc; + char *argv[]; +{ + register int c, status; + register char *cp1, *cp2; + char prbuf[100]; + + if (argc == 1) { + printf("Usage: stop {all | printer ...}\n"); + return; + } + if (argc == 2 && !strcmp(argv[1], "all")) { + printer = prbuf; + while (cgetnext(&bp, printcapdb) > 0) { + cp1 = prbuf; + cp2 = bp; + while ((c = *cp2++) && c != '|' && c != ':') + *cp1++ = c; + *cp1 = '\0'; + stoppr(); + } + return; + } + while (--argc) { + printer = *++argv; + if ((status = cgetent(&bp, printcapdb, printer)) == -2) { + printf("cannot open printer description file\n"); + continue; + } else if (status == -1) { + printf("unknown printer %s\n", printer); + continue; + } else if (status == -3) + fatal("potential reference loop detected in printcap file"); + + stoppr(); + } +} + +static void +stoppr() +{ + register int fd; + struct stat stbuf; + + if (cgetstr(bp, "sd", &SD) == -1) + SD = _PATH_DEFSPOOL; + if (cgetstr(bp, "lo", &LO) == -1) + LO = DEFLOCK; + (void) sprintf(line, "%s/%s", SD, LO); + printf("%s:\n", printer); + + /* + * Turn on the owner execute bit of the lock file to disable printing. + */ + if (stat(line, &stbuf) >= 0) { + if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) + printf("\tcannot disable printing\n"); + else { + upstat("printing disabled\n"); + printf("\tprinting disabled\n"); + } + } else if (errno == ENOENT) { + if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) + printf("\tcannot create lock file\n"); + else { + (void) close(fd); + upstat("printing disabled\n"); + printf("\tprinting disabled\n"); + } + } else + printf("\tcannot stat lock file\n"); +} + +struct queue **queue; +int nitems; +time_t mtime; + +/* + * Put the specified jobs at the top of printer queue. + */ +void +topq(argc, argv) + int argc; + char *argv[]; +{ + register int i; + struct stat stbuf; + int status, changed; + + if (argc < 3) { + printf("Usage: topq printer [jobnum ...] [user ...]\n"); + return; + } + + --argc; + printer = *++argv; + status = cgetent(&bp, printcapdb, printer); + if (status == -2) { + printf("cannot open printer description file\n"); + return; + } else if (status == -1) { + printf("%s: unknown printer\n", printer); + return; + } else if (status == -3) + fatal("potential reference loop detected in printcap file"); + + if (cgetstr(bp, "sd", &SD) == -1) + SD = _PATH_DEFSPOOL; + if (cgetstr(bp, "lo", &LO) == -1) + LO = DEFLOCK; + printf("%s:\n", printer); + + if (chdir(SD) < 0) { + printf("\tcannot chdir to %s\n", SD); + return; + } + nitems = getq(&queue); + if (nitems == 0) + return; + changed = 0; + mtime = queue[0]->q_time; + for (i = argc; --i; ) { + if (doarg(argv[i]) == 0) { + printf("\tjob %s is not in the queue\n", argv[i]); + continue; + } else + changed++; + } + for (i = 0; i < nitems; i++) + free(queue[i]); + free(queue); + if (!changed) { + printf("\tqueue order unchanged\n"); + return; + } + /* + * Turn on the public execute bit of the lock file to + * get lpd to rebuild the queue after the current job. + */ + if (changed && stat(LO, &stbuf) >= 0) + (void) chmod(LO, (stbuf.st_mode & 0777) | 01); +} + +/* + * Reposition the job by changing the modification time of + * the control file. + */ +static int +touch(q) + struct queue *q; +{ + struct timeval tvp[2]; + + tvp[0].tv_sec = tvp[1].tv_sec = --mtime; + tvp[0].tv_usec = tvp[1].tv_usec = 0; + return(utimes(q->q_name, tvp)); +} + +/* + * Checks if specified job name is in the printer's queue. + * Returns: negative (-1) if argument name is not in the queue. + */ +static int +doarg(job) + char *job; +{ + register struct queue **qq; + register int jobnum, n; + register char *cp, *machine; + int cnt = 0; + FILE *fp; + + /* + * Look for a job item consisting of system name, colon, number + * (example: ucbarpa:114) + */ + if ((cp = index(job, ':')) != NULL) { + machine = job; + *cp++ = '\0'; + job = cp; + } else + machine = NULL; + + /* + * Check for job specified by number (example: 112 or 235ucbarpa). + */ + if (isdigit(*job)) { + jobnum = 0; + do + jobnum = jobnum * 10 + (*job++ - '0'); + while (isdigit(*job)); + for (qq = queue + nitems; --qq >= queue; ) { + n = 0; + for (cp = (*qq)->q_name+3; isdigit(*cp); ) + n = n * 10 + (*cp++ - '0'); + if (jobnum != n) + continue; + if (*job && strcmp(job, cp) != 0) + continue; + if (machine != NULL && strcmp(machine, cp) != 0) + continue; + if (touch(*qq) == 0) { + printf("\tmoved %s\n", (*qq)->q_name); + cnt++; + } + } + return(cnt); + } + /* + * Process item consisting of owner's name (example: henry). + */ + for (qq = queue + nitems; --qq >= queue; ) { + if ((fp = fopen((*qq)->q_name, "r")) == NULL) + continue; + while (getline(fp) > 0) + if (line[0] == 'P') + break; + (void) fclose(fp); + if (line[0] != 'P' || strcmp(job, line+1) != 0) + continue; + if (touch(*qq) == 0) { + printf("\tmoved %s\n", (*qq)->q_name); + cnt++; + } + } + return(cnt); +} + +/* + * Enable everything and start printer (undo `down'). + */ +void +up(argc, argv) + int argc; + char *argv[]; +{ + register int c, status; + register char *cp1, *cp2; + char prbuf[100]; + + if (argc == 1) { + printf("Usage: up {all | printer ...}\n"); + return; + } + if (argc == 2 && !strcmp(argv[1], "all")) { + printer = prbuf; + while (cgetnext(&bp, printcapdb) > 0) { + cp1 = prbuf; + cp2 = bp; + while ((c = *cp2++) && c != '|' && c != ':') + *cp1++ = c; + *cp1 = '\0'; + startpr(2); + } + return; + } + while (--argc) { + printer = *++argv; + if ((status = cgetent(&bp, printcapdb, printer)) == -2) { + printf("cannot open printer description file\n"); + continue; + } else if (status == -1) { + printf("unknown printer %s\n", printer); + continue; + } else if (status == -3) + fatal("potential reference loop detected in printcap file"); + + startpr(2); + } +} diff --git a/usr.sbin/lpr/lpc/cmdtab.c b/usr.sbin/lpr/lpc/cmdtab.c new file mode 100644 index 0000000..7619791 --- /dev/null +++ b/usr.sbin/lpr/lpc/cmdtab.c @@ -0,0 +1,79 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)cmdtab.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include + +#include "lpc.h" +#include "extern.h" + +/* + * lpc -- command tables + */ +char aborthelp[] = "terminate a spooling daemon immediately and disable printing"; +char cleanhelp[] = "remove cruft files from a queue"; +char enablehelp[] = "turn a spooling queue on"; +char disablehelp[] = "turn a spooling queue off"; +char downhelp[] = "do a 'stop' followed by 'disable' and put a message in status"; +char helphelp[] = "get help on commands"; +char quithelp[] = "exit lpc"; +char restarthelp[] = "kill (if possible) and restart a spooling daemon"; +char starthelp[] = "enable printing and start a spooling daemon"; +char statushelp[] = "show status of daemon and queue"; +char stophelp[] = "stop a spooling daemon after current job completes and disable printing"; +char topqhelp[] = "put job at top of printer queue"; +char uphelp[] = "enable everything and restart spooling daemon"; + +struct cmd cmdtab[] = { + { "abort", aborthelp, doabort, 1 }, + { "clean", cleanhelp, clean, 1 }, + { "enable", enablehelp, enable, 1 }, + { "exit", quithelp, quit, 0 }, + { "disable", disablehelp, disable, 1 }, + { "down", downhelp, down, 1 }, + { "help", helphelp, help, 0 }, + { "quit", quithelp, quit, 0 }, + { "restart", restarthelp, restart, 0 }, + { "start", starthelp, startcmd, 1 }, + { "status", statushelp, status, 0 }, + { "stop", stophelp, stop, 1 }, + { "topq", topqhelp, topq, 1 }, + { "up", uphelp, up, 1 }, + { "?", helphelp, help, 0 }, + { 0 }, +}; + +int NCMDS = sizeof (cmdtab) / sizeof (cmdtab[0]); diff --git a/usr.sbin/lpr/lpc/extern.h b/usr.sbin/lpr/lpc/extern.h new file mode 100644 index 0000000..1b807b1 --- /dev/null +++ b/usr.sbin/lpr/lpc/extern.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1989, 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. + * + * @(#)extern.h 8.1 (Berkeley) 6/6/93 + */ + + +#include + + +__BEGIN_DECLS +void clean __P((int, char **)); +void disable __P((int, char **)); +void doabort __P((int, char **)); +void down __P((int, char **)); +void enable __P((int, char **)); +void help __P((int, char **)); +void quit __P((int, char **)); +void restart __P((int, char **)); +void startcmd __P((int, char **)); +void status __P((int, char **)); +void stop __P((int, char **)); +void topq __P((int, char **)); +void up __P((int, char **)); +__END_DECLS + +extern int NCMDS; +extern struct cmd cmdtab[]; diff --git a/usr.sbin/lpr/lpc/lpc.8 b/usr.sbin/lpr/lpc/lpc.8 new file mode 100644 index 0000000..a786adc --- /dev/null +++ b/usr.sbin/lpr/lpc/lpc.8 @@ -0,0 +1,174 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" @(#)lpc.8 8.3 (Berkeley) 4/19/94 +.\" +.Dd April 19, 1994 +.Dt LPC 8 +.Os BSD 4.2 +.Sh NAME +.Nm lpc +.Nd line printer control program +.Sh SYNOPSIS +.Nm lpc +.Oo +.Ar command +.Op Ar argument ... +.Oc +.Sh DESCRIPTION +.Nm Lpc +is used by the system administrator to control the +operation of the line printer system. +For each line printer configured in +.Pa /etc/printcap , +.Nm lpc +may be used to: +.Bl -bullet -offset indent +.It +disable or enable a printer, +.It +disable or enable a printer's spooling queue, +.It +rearrange the order of jobs in a spooling queue, +.It +find the status of printers, and their associated +spooling queues and printer daemons. +.El +.Pp +Without any arguments, +.Nm lpc +will prompt for commands from the standard input. +If arguments are supplied, +.Nm lpc +interprets the first argument as a command and the remaining +arguments as parameters to the command. The standard input +may be redirected causing +.Nm lpc +to read commands from file. +Commands may be abbreviated; +the following is the list of recognized commands. +.Pp +.Bl -tag -width Ds -compact +.It Ic \&? No [ command ... ] +.It Ic help No [ command ... ] +Print a short description of each command specified in the argument list, +or, if no argument is given, a list of the recognized commands. +.Pp +.It Ic abort No {\ all\ |\ printer\ } +Terminate an active spooling daemon on the local host immediately and +then disable printing (preventing new daemons from being started by +.Xr lpr ) +for the specified printers. +.Pp +.It Ic clean No {\ all\ |\ printer\ } +Remove any temporary files, data files, and control files that cannot +be printed (i.e., do not form a complete printer job) +from the specified printer queue(s) on the local machine. +.Pp +.It Ic disable No {\ all\ |\ printer\ } +Turn the specified printer queues off. This prevents new +printer jobs from being entered into the queue by +.Xr lpr . +.Pp +.It Ic down No {\ all\ |\ printer\ } message ... +Turn the specified printer queue off, disable printing and put +.Em message +in the printer status file. The message doesn't need to be quoted, the +remaining arguments are treated like +.Xr echo 1 . +This is normally used to take a printer down and let others know why +.Xr lpq 1 +will indicate the printer is down and print the status message). +.Pp +.It Ic enable No {\ all\ |\ printer\ } +Enable spooling on the local queue for the listed printers. +This will allow +.Xr lpr 1 +to put new jobs in the spool queue. +.Pp +.It Ic exit +.It Ic quit +Exit from lpc. +.Pp +.It Ic restart No {\ all\ |\ printer\ } +Attempt to start a new printer daemon. +This is useful when some abnormal condition causes the daemon to +die unexpectedly, leaving jobs in the queue. +.Xr Lpq +will report that there is no daemon present when this condition occurs. +If the user is the super-user, +try to abort the current daemon first (i.e., kill and restart a stuck daemon). +.Pp +.It Ic start No {\ all\ |\ printer\ } +Enable printing and start a spooling daemon for the listed printers. +.Pp +.It Ic status No {\ all\ |\ printer\ } +Display the status of daemons and queues on the local machine. +.Pp +.It Ic stop No {\ all\ |\ printer\ } +Stop a spooling daemon after the current job completes and disable +printing. +.Pp +.It Ic topq No printer\ [\ jobnum\ ...\ ]\ [\ user\ ...\ ] +Place the jobs in the order listed at the top of the printer queue. +.Pp +.It Ic up No {\ all\ |\ printer\ } +Enable everything and start a new printer daemon. Undoes the effects of +.Ic down . +.Sh FILES +.Bl -tag -width /var/spool/*/lockx -compact +.It Pa /etc/printcap +printer description file +.It Pa /var/spool/* +spool directories +.It Pa /var/spool/*/lock +lock file for queue control +.El +.Sh SEE ALSO +.Xr lpd 8 , +.Xr lpr 1 , +.Xr lpq 1 , +.Xr lprm 1 , +.Xr printcap 5 +.Sh DIAGNOSTICS +.Bl -tag -width Ds +.It Sy "?Ambiguous command" +abbreviation matches more than one command +.It Sy "?Invalid command" +no match was found +.It Sy "?Privileged command" +command can be executed by root only +.El +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.2 . diff --git a/usr.sbin/lpr/lpc/lpc.c b/usr.sbin/lpr/lpc/lpc.c new file mode 100644 index 0000000..01cfc12 --- /dev/null +++ b/usr.sbin/lpr/lpc/lpc.c @@ -0,0 +1,277 @@ +/* + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)lpc.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lp.h" +#include "lpc.h" +#include "extern.h" + +/* + * lpc -- line printer control program + */ + +int fromatty; + +char cmdline[200]; +int margc; +char *margv[20]; +int top; + +jmp_buf toplevel; + +static void cmdscanner __P((int)); +static struct cmd *getcmd __P((char *)); +static void intr __P((int)); +static void makeargv __P((void)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + register struct cmd *c; + + name = argv[0]; + openlog("lpd", 0, LOG_LPR); + + if (--argc > 0) { + c = getcmd(*++argv); + if (c == (struct cmd *)-1) { + printf("?Ambiguous command\n"); + exit(1); + } + if (c == 0) { + printf("?Invalid command\n"); + exit(1); + } + if (c->c_priv && getuid()) { + printf("?Privileged command\n"); + exit(1); + } + (*c->c_handler)(argc, argv); + exit(0); + } + fromatty = isatty(fileno(stdin)); + top = setjmp(toplevel) == 0; + if (top) + signal(SIGINT, intr); + for (;;) { + cmdscanner(top); + top = 1; + } +} + +static void +intr(signo) + int signo; +{ + if (!fromatty) + exit(0); + longjmp(toplevel, 1); +} + +/* + * Command parser. + */ +static void +cmdscanner(top) + int top; +{ + register struct cmd *c; + + if (!top) + putchar('\n'); + for (;;) { + if (fromatty) { + printf("lpc> "); + fflush(stdout); + } + if (fgets(cmdline, sizeof(cmdline), stdin) == 0) + quit(0, NULL); + if (cmdline[0] == 0 || cmdline[0] == '\n') + break; + makeargv(); + c = getcmd(margv[0]); + if (c == (struct cmd *)-1) { + printf("?Ambiguous command\n"); + continue; + } + if (c == 0) { + printf("?Invalid command\n"); + continue; + } + if (c->c_priv && getuid()) { + printf("?Privileged command\n"); + continue; + } + (*c->c_handler)(margc, margv); + } + longjmp(toplevel, 0); +} + +struct cmd * +getcmd(name) + register char *name; +{ + register char *p, *q; + register struct cmd *c, *found; + register int nmatches, longest; + + longest = 0; + nmatches = 0; + found = 0; + for (c = cmdtab; p = c->c_name; c++) { + for (q = name; *q == *p++; q++) + if (*q == 0) /* exact match? */ + return(c); + if (!*q) { /* the name was a prefix */ + if (q - name > longest) { + longest = q - name; + nmatches = 1; + found = c; + } else if (q - name == longest) + nmatches++; + } + } + if (nmatches > 1) + return((struct cmd *)-1); + return(found); +} + +/* + * Slice a string up into argc/argv. + */ +static void +makeargv() +{ + register char *cp; + register char **argp = margv; + + margc = 0; + for (cp = cmdline; *cp;) { + while (isspace(*cp)) + cp++; + if (*cp == '\0') + break; + *argp++ = cp; + margc += 1; + while (*cp != '\0' && !isspace(*cp)) + cp++; + if (*cp == '\0') + break; + *cp++ = '\0'; + } + *argp++ = 0; +} + +#define HELPINDENT (sizeof ("directory")) + +/* + * Help command. + */ +void +help(argc, argv) + int argc; + char *argv[]; +{ + register struct cmd *c; + + if (argc == 1) { + register int i, j, w; + int columns, width = 0, lines; + extern int NCMDS; + + printf("Commands may be abbreviated. Commands are:\n\n"); + for (c = cmdtab; c->c_name; c++) { + int len = strlen(c->c_name); + + if (len > width) + width = len; + } + width = (width + 8) &~ 7; + columns = 80 / width; + if (columns == 0) + columns = 1; + lines = (NCMDS + columns - 1) / columns; + for (i = 0; i < lines; i++) { + for (j = 0; j < columns; j++) { + c = cmdtab + j * lines + i; + if (c->c_name) + printf("%s", c->c_name); + if (c + lines >= &cmdtab[NCMDS]) { + printf("\n"); + break; + } + w = strlen(c->c_name); + while (w < width) { + w = (w + 8) &~ 7; + putchar('\t'); + } + } + } + return; + } + while (--argc > 0) { + register char *arg; + arg = *++argv; + c = getcmd(arg); + if (c == (struct cmd *)-1) + printf("?Ambiguous help command %s\n", arg); + else if (c == (struct cmd *)0) + printf("?Invalid help command %s\n", arg); + else + printf("%-*s\t%s\n", HELPINDENT, + c->c_name, c->c_help); + } +} diff --git a/usr.sbin/lpr/lpc/lpc.h b/usr.sbin/lpr/lpc/lpc.h new file mode 100644 index 0000000..5e71203 --- /dev/null +++ b/usr.sbin/lpr/lpc/lpc.h @@ -0,0 +1,45 @@ +/* + * 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. + * + * @(#)lpc.h 8.1 (Berkeley) 6/6/93 + */ + +/* + * Line printer control program. + */ +struct cmd { + char *c_name; /* command name */ + char *c_help; /* help message */ + /* routine to do the work */ + void (*c_handler) __P((int, char *[])); + int c_priv; /* privileged command */ +}; diff --git a/usr.sbin/lpr/lpd/Makefile b/usr.sbin/lpr/lpd/Makefile new file mode 100644 index 0000000..da95bac --- /dev/null +++ b/usr.sbin/lpr/lpd/Makefile @@ -0,0 +1,11 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= lpd +CFLAGS+=-I${.CURDIR}/../common_source +MAN8= lpd.0 +SRCS= lpd.c printjob.c recvjob.c displayq.c rmjob.c startdaemon.c \ + lpdchar.c common.c +.PATH: ${.CURDIR}/../common_source + +.include "../../Makefile.inc" +.include diff --git a/usr.sbin/lpr/lpd/extern.h b/usr.sbin/lpr/lpd/extern.h new file mode 100644 index 0000000..64dec12 --- /dev/null +++ b/usr.sbin/lpr/lpd/extern.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1989, 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. + * + * @(#)extern.h 8.1 (Berkeley) 6/6/93 + */ + +#include + +void printjob __P((void)); +void recvjob __P((void)); diff --git a/usr.sbin/lpr/lpd/lpd.8 b/usr.sbin/lpr/lpd/lpd.8 new file mode 100644 index 0000000..1e4677f --- /dev/null +++ b/usr.sbin/lpr/lpd/lpd.8 @@ -0,0 +1,249 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" @(#)lpd.8 8.3 (Berkeley) 4/19/94 +.\" +.Dd April 19, 1994 +.Dt LPD 8 +.Os BSD 4.2 +.Sh NAME +.Nm lpd +.Nd line printer spooler daemon +.Sh SYNOPSIS +.Nm lpd +.Op Fl l +.Op Ar port# +.Sh DESCRIPTION +.Nm Lpd +is the line printer daemon (spool area handler) and is normally invoked +at boot time from the +.Xr rc 8 +file. It makes a single pass through the +.Xr printcap 5 +file to find out about the existing printers and +prints any files left after a crash. It then uses the system calls +.Xr listen 2 +and +.Xr accept 2 +to receive requests to print files in the queue, +transfer files to the spooling area, display the queue, +or remove jobs from the queue. In each case, it forks a child to handle +the request so the parent can continue to listen for more requests. +.Pp +Available options: +.Bl -tag -width Ds +.It Fl l +The +.Fl l +flag causes +.Nm lpd +to log valid requests received from the network. This can be useful +for debugging purposes. +.It Ar "port#" +The Internet port number used to rendezvous +with other processes is normally obtained with +.Xr getservbyname 3 +but can be changed with the +.Ar port# +argument. +.El +.Pp +Access control is provided by two means. First, all requests must come from +one of the machines listed in the file +.Pa /etc/hosts.equiv +or +.Pa /etc/hosts.lpd . +Second, if the +.Li rs +capability is specified in the +.Xr printcap +entry for the printer being accessed, +.Em lpr +requests will only be honored for those users with accounts on the +machine with the printer. +.Pp +The file +.Em minfree +in each spool directory contains the number of disk blocks to leave free +so that the line printer queue won't completely fill the disk. +The +.Em minfree +file can be edited with your favorite text editor. +.Pp +The daemon begins processing files +after it has successfully set the lock for exclusive +access (described a bit later), +and scans the spool directory +for files beginning with +.Em cf . +Lines in each +.Em cf +file specify files to be printed or non-printing actions to be +performed. Each such line begins with a key character +to specify what to do with the remainder of the line. +.Bl -tag -width Ds +.It J +Job Name. String to be used for the job name on the burst page. +.It C +Classification. String to be used for the classification line +on the burst page. +.It L +Literal. The line contains identification info from +the password file and causes the banner page to be printed. +.It T +Title. String to be used as the title for +.Xr pr 1 . +.It H +Host Name. Name of the machine where +.Xr lpr +was invoked. +.It P +Person. Login name of the person who invoked +.Xr lpr . +This is used to verify ownership by +.Xr lprm . +.It M +Send mail to the specified user when the current print job completes. +.It f +Formatted File. Name of a file to print which is already formatted. +.It l +Like ``f'' but passes control characters and does not make page breaks. +.It p +Name of a file to print using +.Xr pr 1 +as a filter. +.It t +Troff File. The file contains +.Xr troff 1 +output (cat phototypesetter commands). +.It n +Ditroff File. The file contains device independent troff +output. +.It r +DVI File. The file contains +.Tn Tex l +output +DVI format from Standford. +.It g +Graph File. The file contains data produced by +.Xr plot 3 . +.It c +Cifplot File. The file contains data produced by +.Em cifplot . +.It v +The file contains a raster image. +.It r +The file contains text data with +FORTRAN carriage control characters. +.It \&1 +Troff Font R. Name of the font file to use instead of the default. +.It \&2 +Troff Font I. Name of the font file to use instead of the default. +.It \&3 +Troff Font B. Name of the font file to use instead of the default. +.It \&4 +Troff Font S. Name of the font file to use instead of the default. +.It W +Width. Changes the page width (in characters) used by +.Xr pr 1 +and the text filters. +.It I +Indent. The number of characters to indent the output by (in ascii). +.It U +Unlink. Name of file to remove upon completion of printing. +.It N +File name. The name of the file which is being printed, or a blank +for the standard input (when +.Xr lpr +is invoked in a pipeline). +.El +.Pp +If a file cannot be opened, a message will be logged via +.Xr syslog 3 +using the +.Em LOG_LPR +facility. +.Nm Lpd +will try up to 20 times +to reopen a file it expects to be there, after which it will +skip the file to be printed. +.Pp +.Nm Lpd +uses +.Xr flock 2 +to provide exclusive access to the lock file and to prevent multiple +daemons from becoming active simultaneously. If the daemon should be killed +or die unexpectedly, the lock file need not be removed. +The lock file is kept in a readable +.Tn ASCII +form +and contains two lines. +The first is the process id of the daemon and the second is the control +file name of the current job being printed. The second line is updated to +reflect the current status of +.Nm lpd +for the programs +.Xr lpq 1 +and +.Xr lprm 1 . +.Sh FILES +.Bl -tag -width "/var/spool/*/minfree" -compact +.It Pa /etc/printcap +printer description file +.It Pa /var/spool/* +spool directories +.It Pa /var/spool/*/minfree +minimum free space to leave +.It Pa /dev/lp* +line printer devices +.It Pa /dev/printer +socket for local requests +.It Pa /etc/hosts.equiv +lists machine names allowed printer access +.It Pa /etc/hosts.lpd +lists machine names allowed printer access, +but not under same administrative control. +.El +.Sh SEE ALSO +.Xr lpc 8 , +.Xr pac 1 , +.Xr lpr 1 , +.Xr lpq 1 , +.Xr lprm 1 , +.Xr syslog 3 , +.Xr printcap 5 +.Rs +.%T "4.2 BSD Line Printer Spooler Manual" +.Re +.Sh HISTORY +An +.Nm +daemon appeared in Version 6 AT&T UNIX. diff --git a/usr.sbin/lpr/lpd/lpd.c b/usr.sbin/lpr/lpd/lpd.c new file mode 100644 index 0000000..aaf72b7 --- /dev/null +++ b/usr.sbin/lpr/lpd/lpd.c @@ -0,0 +1,507 @@ +/* + * Copyright (c) 1983, 1993, 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1993, 1994\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)lpd.c 8.4 (Berkeley) 4/17/94"; +#endif /* not lint */ + +/* + * lpd -- line printer daemon. + * + * Listen for a connection and perform the requested operation. + * Operations are: + * \1printer\n + * check the queue for jobs and print any found. + * \2printer\n + * receive a job from another machine and queue it. + * \3printer [users ...] [jobs ...]\n + * return the current state of the queue (short form). + * \4printer [users ...] [jobs ...]\n + * return the current state of the queue (long form). + * \5printer person [users ...] [jobs ...]\n + * remove jobs from the queue. + * + * Strategy to maintain protected spooling area: + * 1. Spooling area is writable only by daemon and spooling group + * 2. lpr runs setuid root and setgrp spooling group; it uses + * root to access any file it wants (verifying things before + * with an access call) and group id to know how it should + * set up ownership of files in the spooling area. + * 3. Files in spooling area are owned by root, group spooling + * group, with mode 660. + * 4. lpd, lpq and lprm run setuid daemon and setgrp spooling group to + * access files and printer. Users can't get to anything + * w/o help of lpq and lprm programs. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lp.h" +#include "lp.local.h" +#include "pathnames.h" +#include "extern.h" + +int lflag; /* log requests flag */ +int from_remote; /* from remote socket */ + +static void reapchild __P((int)); +static void mcleanup __P((int)); +static void doit __P((void)); +static void startup __P((void)); +static void chkhost __P((struct sockaddr_in *)); + +int +main(argc, argv) + int argc; + char **argv; +{ + int f, funix, finet, options, fromlen; + fd_set defreadfds; + struct sockaddr_un un, fromunix; + struct sockaddr_in sin, frominet; + int omask, lfd; + + options = 0; + gethostname(host, sizeof(host)); + name = argv[0]; + + while (--argc > 0) { + argv++; + if (argv[0][0] == '-') + switch (argv[0][1]) { + case 'd': + options |= SO_DEBUG; + break; + case 'l': + lflag++; + break; + } + } + +#ifndef DEBUG + /* + * Set up standard environment by detaching from the parent. + */ + daemon(0, 0); +#endif + + openlog("lpd", LOG_PID, LOG_LPR); + syslog(LOG_INFO, "restarted"); + (void) umask(0); + lfd = open(_PATH_MASTERLOCK, O_WRONLY|O_CREAT, 0644); + if (lfd < 0) { + syslog(LOG_ERR, "%s: %m", _PATH_MASTERLOCK); + exit(1); + } + if (flock(lfd, LOCK_EX|LOCK_NB) < 0) { + if (errno == EWOULDBLOCK) /* active deamon present */ + exit(0); + syslog(LOG_ERR, "%s: %m", _PATH_MASTERLOCK); + exit(1); + } + ftruncate(lfd, 0); + /* + * write process id for others to know + */ + sprintf(line, "%u\n", getpid()); + f = strlen(line); + if (write(lfd, line, f) != f) { + syslog(LOG_ERR, "%s: %m", _PATH_MASTERLOCK); + exit(1); + } + signal(SIGCHLD, reapchild); + /* + * Restart all the printers. + */ + startup(); + (void) unlink(_PATH_SOCKETNAME); + funix = socket(AF_UNIX, SOCK_STREAM, 0); + if (funix < 0) { + syslog(LOG_ERR, "socket: %m"); + exit(1); + } +#define mask(s) (1 << ((s) - 1)) + omask = sigblock(mask(SIGHUP)|mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM)); + signal(SIGHUP, mcleanup); + signal(SIGINT, mcleanup); + signal(SIGQUIT, mcleanup); + signal(SIGTERM, mcleanup); + memset(&un, 0, sizeof(un)); + un.sun_family = AF_UNIX; + strcpy(un.sun_path, _PATH_SOCKETNAME); +#ifndef SUN_LEN +#define SUN_LEN(unp) (strlen((unp)->sun_path) + 2) +#endif + if (bind(funix, (struct sockaddr *)&un, SUN_LEN(&un)) < 0) { + syslog(LOG_ERR, "ubind: %m"); + exit(1); + } + sigsetmask(omask); + FD_ZERO(&defreadfds); + FD_SET(funix, &defreadfds); + listen(funix, 5); + finet = socket(AF_INET, SOCK_STREAM, 0); + if (finet >= 0) { + struct servent *sp; + + if (options & SO_DEBUG) + if (setsockopt(finet, SOL_SOCKET, SO_DEBUG, 0, 0) < 0) { + syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m"); + mcleanup(0); + } + sp = getservbyname("printer", "tcp"); + if (sp == NULL) { + syslog(LOG_ERR, "printer/tcp: unknown service"); + mcleanup(0); + } + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = sp->s_port; + if (bind(finet, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + syslog(LOG_ERR, "bind: %m"); + mcleanup(0); + } + FD_SET(finet, &defreadfds); + listen(finet, 5); + } + /* + * Main loop: accept, do a request, continue. + */ + memset(&frominet, 0, sizeof(frominet)); + memset(&fromunix, 0, sizeof(fromunix)); + for (;;) { + int domain, nfds, s; + fd_set readfds; + + FD_COPY(&defreadfds, &readfds); + nfds = select(20, &readfds, 0, 0, 0); + if (nfds <= 0) { + if (nfds < 0 && errno != EINTR) + syslog(LOG_WARNING, "select: %m"); + continue; + } + if (FD_ISSET(funix, &readfds)) { + domain = AF_UNIX, fromlen = sizeof(fromunix); + s = accept(funix, + (struct sockaddr *)&fromunix, &fromlen); + } else /* if (FD_ISSET(finet, &readfds)) */ { + domain = AF_INET, fromlen = sizeof(frominet); + s = accept(finet, + (struct sockaddr *)&frominet, &fromlen); + } + if (s < 0) { + if (errno != EINTR) + syslog(LOG_WARNING, "accept: %m"); + continue; + } + if (fork() == 0) { + signal(SIGCHLD, SIG_IGN); + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + signal(SIGTERM, SIG_IGN); + (void) close(funix); + (void) close(finet); + dup2(s, 1); + (void) close(s); + if (domain == AF_INET) { + from_remote = 1; + chkhost(&frominet); + } else + from_remote = 0; + doit(); + exit(0); + } + (void) close(s); + } +} + +static void +reapchild(signo) + int signo; +{ + union wait status; + + while (wait3((int *)&status, WNOHANG, 0) > 0) + ; +} + +static void +mcleanup(signo) + int signo; +{ + if (lflag) + syslog(LOG_INFO, "exiting"); + unlink(_PATH_SOCKETNAME); + exit(0); +} + +/* + * Stuff for handling job specifications + */ +char *user[MAXUSERS]; /* users to process */ +int users; /* # of users in user array */ +int requ[MAXREQUESTS]; /* job number of spool entries */ +int requests; /* # of spool requests */ +char *person; /* name of person doing lprm */ + +char fromb[MAXHOSTNAMELEN]; /* buffer for client's machine name */ +char cbuf[BUFSIZ]; /* command line buffer */ +char *cmdnames[] = { + "null", + "printjob", + "recvjob", + "displayq short", + "displayq long", + "rmjob" +}; + +static void +doit() +{ + register char *cp; + register int n; + + for (;;) { + cp = cbuf; + do { + if (cp >= &cbuf[sizeof(cbuf) - 1]) + fatal("Command line too long"); + if ((n = read(1, cp, 1)) != 1) { + if (n < 0) + fatal("Lost connection"); + return; + } + } while (*cp++ != '\n'); + *--cp = '\0'; + cp = cbuf; + if (lflag) { + if (*cp >= '\1' && *cp <= '\5') + syslog(LOG_INFO, "%s requests %s %s", + from, cmdnames[*cp], cp+1); + else + syslog(LOG_INFO, "bad request (%d) from %s", + *cp, from); + } + switch (*cp++) { + case '\1': /* check the queue and print any jobs there */ + printer = cp; + printjob(); + break; + case '\2': /* receive files to be queued */ + if (!from_remote) { + syslog(LOG_INFO, "illegal request (%d)", *cp); + exit(1); + } + printer = cp; + recvjob(); + break; + case '\3': /* display the queue (short form) */ + case '\4': /* display the queue (long form) */ + printer = cp; + while (*cp) { + if (*cp != ' ') { + cp++; + continue; + } + *cp++ = '\0'; + while (isspace(*cp)) + cp++; + if (*cp == '\0') + break; + if (isdigit(*cp)) { + if (requests >= MAXREQUESTS) + fatal("Too many requests"); + requ[requests++] = atoi(cp); + } else { + if (users >= MAXUSERS) + fatal("Too many users"); + user[users++] = cp; + } + } + displayq(cbuf[0] - '\3'); + exit(0); + case '\5': /* remove a job from the queue */ + if (!from_remote) { + syslog(LOG_INFO, "illegal request (%d)", *cp); + exit(1); + } + printer = cp; + while (*cp && *cp != ' ') + cp++; + if (!*cp) + break; + *cp++ = '\0'; + person = cp; + while (*cp) { + if (*cp != ' ') { + cp++; + continue; + } + *cp++ = '\0'; + while (isspace(*cp)) + cp++; + if (*cp == '\0') + break; + if (isdigit(*cp)) { + if (requests >= MAXREQUESTS) + fatal("Too many requests"); + requ[requests++] = atoi(cp); + } else { + if (users >= MAXUSERS) + fatal("Too many users"); + user[users++] = cp; + } + } + rmjob(); + break; + } + fatal("Illegal service request"); + } +} + +/* + * Make a pass through the printcap database and start printing any + * files left from the last time the machine went down. + */ +static void +startup() +{ + char *buf; + register char *cp; + int pid; + + /* + * Restart the daemons. + */ + while (cgetnext(&buf, printcapdb) > 0) { + for (cp = buf; *cp; cp++) + if (*cp == '|' || *cp == ':') { + *cp = '\0'; + break; + } + if ((pid = fork()) < 0) { + syslog(LOG_WARNING, "startup: cannot fork"); + mcleanup(0); + } + if (!pid) { + printer = buf; + cgetclose(); + printjob(); + } + } +} + +#define DUMMY ":nobody::" + +/* + * Check to see if the from host has access to the line printer. + */ +static void +chkhost(f) + struct sockaddr_in *f; +{ + register struct hostent *hp; + register FILE *hostf; + int first = 1; + extern char *inet_ntoa(); + + f->sin_port = ntohs(f->sin_port); + if (f->sin_family != AF_INET || f->sin_port >= IPPORT_RESERVED) + fatal("Malformed from address"); + + /* Need real hostname for temporary filenames */ + hp = gethostbyaddr((char *)&f->sin_addr, + sizeof(struct in_addr), f->sin_family); + if (hp == NULL) + fatal("Host name for your address (%s) unknown", + inet_ntoa(f->sin_addr)); + + (void) strncpy(fromb, hp->h_name, sizeof(fromb)); + from[sizeof(fromb) - 1] = '\0'; + from = fromb; + + hostf = fopen(_PATH_HOSTSEQUIV, "r"); +again: + if (hostf) { + if (__ivaliduser(hostf, f->sin_addr.s_addr, + DUMMY, DUMMY) == 0) { + (void) fclose(hostf); + return; + } + (void) fclose(hostf); + } + if (first == 1) { + first = 0; + hostf = fopen(_PATH_HOSTSLPD, "r"); + goto again; + } + fatal("Your host does not have line printer access"); + /*NOTREACHED*/ +} + + + + + + + + + + + + diff --git a/usr.sbin/lpr/lpd/lpdchar.c b/usr.sbin/lpr/lpd/lpdchar.c new file mode 100644 index 0000000..4a4f5da --- /dev/null +++ b/usr.sbin/lpr/lpd/lpdchar.c @@ -0,0 +1,1066 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)lpdchar.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Character set for line printer daemon + */ +#include "lp.local.h" + +#define c_______ 0 +#define c______1 01 +#define c_____1_ 02 +#define c____1__ 04 +#define c____11_ 06 +#define c___1___ 010 +#define c___1__1 011 +#define c___1_1_ 012 +#define c___11__ 014 +#define c__1____ 020 +#define c__1__1_ 022 +#define c__1_1__ 024 +#define c__11___ 030 +#define c__111__ 034 +#define c__111_1 035 +#define c__1111_ 036 +#define c__11111 037 +#define c_1_____ 040 +#define c_1____1 041 +#define c_1___1_ 042 +#define c_1__1__ 044 +#define c_1_1___ 050 +#define c_1_1__1 051 +#define c_1_1_1_ 052 +#define c_11____ 060 +#define c_11_11_ 066 +#define c_111___ 070 +#define c_111__1 071 +#define c_111_1_ 072 +#define c_1111__ 074 +#define c_1111_1 075 +#define c_11111_ 076 +#define c_111111 077 +#define c1______ 0100 +#define c1_____1 0101 +#define c1____1_ 0102 +#define c1____11 0103 +#define c1___1__ 0104 +#define c1___1_1 0105 +#define c1___11_ 0106 +#define c1__1___ 0110 +#define c1__1__1 0111 +#define c1__11_1 0115 +#define c1__1111 0117 +#define c1_1____ 0120 +#define c1_1___1 0121 +#define c1_1_1_1 0125 +#define c1_1_11_ 0126 +#define c1_111__ 0134 +#define c1_1111_ 0136 +#define c11____1 0141 +#define c11___1_ 0142 +#define c11___11 0143 +#define c11_1___ 0150 +#define c11_1__1 0151 +#define c111_11_ 0166 +#define c1111___ 0170 +#define c11111__ 0174 +#define c111111_ 0176 +#define c1111111 0177 + +char scnkey[][HEIGHT] = /* this is relatively easy to modify */ + /* just look: */ +{ + { c_______, + c_______, + c_______, + c_______, + c_______, + c_______, + c_______, + c_______, + c_______ }, /* */ + + { c__11___, + c__11___, + c__11___, + c__11___, + c__11___, + c_______, + c_______, + c__11___, + c__11___ }, /* ! */ + + { c_1__1__, + c_1__1__, + c_______, + c_______, + c_______, + c_______, + c_______, + c_______, + c_______ }, /* " */ + + { c_______, + c__1_1__, + c__1_1__, + c1111111, + c__1_1__, + c1111111, + c__1_1__, + c__1_1__, + c_______ }, /* # */ + + { c___1___, + c_11111_, + c1__1__1, + c1__1___, + c_11111_, + c___1__1, + c1__1__1, + c_11111_, + c___1___ }, /* $ */ + + { c_1_____, + c1_1___1, + c_1___1_, + c____1__, + c___1___, + c__1____, + c_1___1_, + c1___1_1, + c_____1_ }, /* % */ + + { c_11____, + c1__1___, + c1___1__, + c_1_1___, + c__1____, + c_1_1__1, + c1___11_, + c1___11_, + c_111__1 }, /* & */ + + { c___11__, + c___11__, + c___1___, + c__1____, + c_______, + c_______, + c_______, + c_______, + c_______ }, /* ' */ + + { c____1__, + c___1___, + c__1____, + c__1____, + c__1____, + c__1____, + c__1____, + c___1___, + c____1__ }, /* ( */ + + { c__1____, + c___1___, + c____1__, + c____1__, + c____1__, + c____1__, + c____1__, + c___1___, + c__1____ }, /* ) */ + + { c_______, + c___1___, + c1__1__1, + c_1_1_1_, + c__111__, + c_1_1_1_, + c1__1__1, + c___1___, + c_______ }, /* * */ + + { c_______, + c___1___, + c___1___, + c___1___, + c1111111, + c___1___, + c___1___, + c___1___, + c_______ }, /* + */ + + { c_______, + c_______, + c_______, + c_______, + c__11___, + c__11___, + c__1____, + c_1_____, + c_______ }, /* , */ + + { c_______, + c_______, + c_______, + c_______, + c1111111, + c_______, + c_______, + c_______, + c_______ }, /* - */ + + { c_______, + c_______, + c_______, + c_______, + c_______, + c_______, + c_______, + c__11___, + c__11___ }, /* . */ + + { c_______, + c______1, + c_____1_, + c____1__, + c___1___, + c__1____, + c_1_____, + c1______, + c_______ }, /* / */ + + { c_11111_, + c1_____1, + c1____11, + c1___1_1, + c1__1__1, + c1_1___1, + c11____1, + c1_____1, + c_11111_ }, /* 0 */ + + { c___1___, + c__11___, + c_1_1___, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___, + c_11111_ }, /* 1 */ + + { c_11111_, + c1_____1, + c______1, + c_____1_, + c__111__, + c_1_____, + c1______, + c1______, + c1111111 }, /* 2 */ + + { c_11111_, + c1_____1, + c______1, + c______1, + c__1111_, + c______1, + c______1, + c1_____1, + c_11111_ }, /* 3 */ + + { c_____1_, + c____11_, + c___1_1_, + c__1__1_, + c_1___1_, + c1____1_, + c1111111, + c_____1_, + c_____1_ }, /* 4 */ + + { c1111111, + c1______, + c1______, + c11111__, + c_____1_, + c______1, + c______1, + c1____1_, + c_1111__ }, /* 5 */ + + { c__1111_, + c_1_____, + c1______, + c1______, + c1_1111_, + c11____1, + c1_____1, + c1_____1, + c_11111_ }, /* 6 */ + + { c1111111, + c1_____1, + c_____1_, + c____1__, + c___1___, + c__1____, + c__1____, + c__1____, + c__1____ }, /* 7 */ + + { c_11111_, + c1_____1, + c1_____1, + c1_____1, + c_11111_, + c1_____1, + c1_____1, + c1_____1, + c_11111_ }, /* 8 */ + + { c_11111_, + c1_____1, + c1_____1, + c1_____1, + c_111111, + c______1, + c______1, + c1_____1, + c_1111__ }, /* 9 */ + + { c_______, + c_______, + c_______, + c__11___, + c__11___, + c_______, + c_______, + c__11___, + c__11___ }, /* : */ + + + { c__11___, + c__11___, + c_______, + c_______, + c__11___, + c__11___, + c__1____, + c_1_____, + c_______ }, /* ; */ + + { c____1__, + c___1___, + c__1____, + c_1_____, + c1______, + c_1_____, + c__1____, + c___1___, + c____1__ }, /* < */ + + { c_______, + c_______, + c_______, + c1111111, + c_______, + c1111111, + c_______, + c_______, + c_______ }, /* = */ + + { c__1____, + c___1___, + c____1__, + c_____1_, + c______1, + c_____1_, + c____1__, + c___1___, + c__1____ }, /* > */ + + { c__1111_, + c_1____1, + c_1____1, + c______1, + c____11_, + c___1___, + c___1___, + c_______, + c___1___ }, /* ? */ + + { c__1111_, + c_1____1, + c1__11_1, + c1_1_1_1, + c1_1_1_1, + c1_1111_, + c1______, + c_1____1, + c__1111_ }, /* @ */ + + { c__111__, + c_1___1_, + c1_____1, + c1_____1, + c1111111, + c1_____1, + c1_____1, + c1_____1, + c1_____1 }, /* A */ + + { c111111_, + c_1____1, + c_1____1, + c_1____1, + c_11111_, + c_1____1, + c_1____1, + c_1____1, + c111111_ }, /* B */ + + { c__1111_, + c_1____1, + c1______, + c1______, + c1______, + c1______, + c1______, + c_1____1, + c__1111_ }, /* C */ + + { c11111__, + c_1___1_, + c_1____1, + c_1____1, + c_1____1, + c_1____1, + c_1____1, + c_1___1_, + c11111__ }, /* D */ + + { c1111111, + c1______, + c1______, + c1______, + c111111_, + c1______, + c1______, + c1______, + c1111111 }, /* E */ + + { c1111111, + c1______, + c1______, + c1______, + c111111_, + c1______, + c1______, + c1______, + c1______ }, /* F */ + + { c__1111_, + c_1____1, + c1______, + c1______, + c1______, + c1__1111, + c1_____1, + c_1____1, + c__1111_ }, /* G */ + + { c1_____1, + c1_____1, + c1_____1, + c1_____1, + c1111111, + c1_____1, + c1_____1, + c1_____1, + c1_____1 }, /* H */ + + { c_11111_, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___, + c_11111_ }, /* I */ + + { c__11111, + c____1__, + c____1__, + c____1__, + c____1__, + c____1__, + c____1__, + c1___1__, + c_111___ }, /* J */ + + { c1_____1, + c1____1_, + c1___1__, + c1__1___, + c1_1____, + c11_1___, + c1___1__, + c1____1_, + c1_____1 }, /* K */ + + { c1______, + c1______, + c1______, + c1______, + c1______, + c1______, + c1______, + c1______, + c1111111 }, /* L */ + + { c1_____1, + c11___11, + c1_1_1_1, + c1__1__1, + c1_____1, + c1_____1, + c1_____1, + c1_____1, + c1_____1 }, /* M */ + + { c1_____1, + c11____1, + c1_1___1, + c1__1__1, + c1___1_1, + c1____11, + c1_____1, + c1_____1, + c1_____1 }, /* N */ + + { c__111__, + c_1___1_, + c1_____1, + c1_____1, + c1_____1, + c1_____1, + c1_____1, + c_1___1_, + c__111__ }, /* O */ + + { c111111_, + c1_____1, + c1_____1, + c1_____1, + c111111_, + c1______, + c1______, + c1______, + c1______ }, /* P */ + + { c__111__, + c_1___1_, + c1_____1, + c1_____1, + c1_____1, + c1__1__1, + c1___1_1, + c_1___1_, + c__111_1 }, /* Q */ + + { c111111_, + c1_____1, + c1_____1, + c1_____1, + c111111_, + c1__1___, + c1___1__, + c1____1_, + c1_____1 }, /* R */ + + { c_11111_, + c1_____1, + c1______, + c1______, + c_11111_, + c______1, + c______1, + c1_____1, + c_11111_ }, /* S */ + + { c1111111, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___ }, /* T */ + + { c1_____1, + c1_____1, + c1_____1, + c1_____1, + c1_____1, + c1_____1, + c1_____1, + c1_____1, + c_11111_ }, /* U */ + + { c1_____1, + c1_____1, + c1_____1, + c_1___1_, + c_1___1_, + c__1_1__, + c__1_1__, + c___1___, + c___1___ }, /* V */ + + { c1_____1, + c1_____1, + c1_____1, + c1_____1, + c1__1__1, + c1__1__1, + c1_1_1_1, + c11___11, + c1_____1 }, /* W */ + + { c1_____1, + c1_____1, + c_1___1_, + c__1_1__, + c___1___, + c__1_1__, + c_1___1_, + c1_____1, + c1_____1 }, /* X */ + + { c1_____1, + c1_____1, + c_1___1_, + c__1_1__, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___ }, /* Y */ + + { c1111111, + c______1, + c_____1_, + c____1__, + c___1___, + c__1____, + c_1_____, + c1______, + c1111111 }, /* Z */ + + { c_1111__, + c_1_____, + c_1_____, + c_1_____, + c_1_____, + c_1_____, + c_1_____, + c_1_____, + c_1111__ }, /* [ */ + + { c_______, + c1______, + c_1_____, + c__1____, + c___1___, + c____1__, + c_____1_, + c______1, + c_______ }, /* \ */ + + { c__1111_, + c_____1_, + c_____1_, + c_____1_, + c_____1_, + c_____1_, + c_____1_, + c_____1_, + c__1111_ }, /* ] */ + + { c___1___, + c__1_1__, + c_1___1_, + c1_____1, + c_______, + c_______, + c_______, + c_______ }, /* ^ */ + + { c_______, + c_______, + c_______, + c_______, + c_______, + c_______, + c_______, + c1111111, + c_______ }, /* _ */ + + { c__11___, + c__11___, + c___1___, + c____1__, + c_______, + c_______, + c_______, + c_______, + c_______ }, /* ` */ + + { c_______, + c_______, + c_______, + c_1111__, + c_____1_, + c_11111_, + c1_____1, + c1____11, + c_1111_1 }, /* a */ + + { c1______, + c1______, + c1______, + c1_111__, + c11___1_, + c1_____1, + c1_____1, + c11___1_, + c1_111__ }, /* b */ + + { c_______, + c_______, + c_______, + c_1111__, + c1____1_, + c1______, + c1______, + c1____1_, + c_1111__ }, /* c */ + + { c_____1_, + c_____1_, + c_____1_, + c_111_1_, + c1___11_, + c1____1_, + c1____1_, + c1___11_, + c_111_1_ }, /* d */ + + { c_______, + c_______, + c_______, + c_1111__, + c1____1_, + c111111_, + c1______, + c1____1_, + c_1111__ }, /* e */ + + { c___11__, + c__1__1_, + c__1____, + c__1____, + c11111__, + c__1____, + c__1____, + c__1____, + c__1____ }, /* f */ + + { c_111_1_, + c1___11_, + c1____1_, + c1____1_, + c1___11_, + c_111_1_, + c_____1_, + c1____1_, + c_1111__ }, /* g */ + + { c1______, + c1______, + c1______, + c1_111__, + c11___1_, + c1____1_, + c1____1_, + c1____1_, + c1____1_ }, /* h */ + + { c_______, + c___1___, + c_______, + c__11___, + c___1___, + c___1___, + c___1___, + c___1___, + c__111__ }, /* i */ + + { c____11_, + c_____1_, + c_____1_, + c_____1_, + c_____1_, + c_____1_, + c_____1_, + c_1___1_, + c__111__ }, /* j */ + + { c1______, + c1______, + c1______, + c1___1__, + c1__1___, + c1_1____, + c11_1___, + c1___1__, + c1____1_ }, /* k */ + + { c__11___, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___, + c__111__ }, /* l */ + + { c_______, + c_______, + c_______, + c1_1_11_, + c11_1__1, + c1__1__1, + c1__1__1, + c1__1__1, + c1__1__1 }, /* m */ + + { c_______, + c_______, + c_______, + c1_111__, + c11___1_, + c1____1_, + c1____1_, + c1____1_, + c1____1_ }, /* n */ + + { c_______, + c_______, + c_______, + c_1111__, + c1____1_, + c1____1_, + c1____1_, + c1____1_, + c_1111__ }, /* o */ + + { c1_111__, + c11___1_, + c1____1_, + c1____1_, + c11___1_, + c1_111__, + c1______, + c1______, + c1______ }, /* p */ + + { c_111_1_, + c1___11_, + c1____1_, + c1____1_, + c1___11_, + c_111_1_, + c_____1_, + c_____1_, + c_____1_ }, /* q */ + + { c_______, + c_______, + c_______, + c1_111__, + c11___1_, + c1______, + c1______, + c1______, + c1______ }, /* r */ + + { c_______, + c_______, + c_______, + c_1111__, + c1____1_, + c_11____, + c___11__, + c1____1_, + c_1111__ }, /* s */ + + { c_______, + c__1____, + c__1____, + c11111__, + c__1____, + c__1____, + c__1____, + c__1__1_, + c___11__ }, /* t */ + + { c_______, + c_______, + c_______, + c1____1_, + c1____1_, + c1____1_, + c1____1_, + c1___11_, + c_111_1_ }, /* u */ + + { c_______, + c_______, + c_______, + c1_____1, + c1_____1, + c1_____1, + c_1___1_, + c__1_1__, + c___1___ }, /* v */ + + { c_______, + c_______, + c_______, + c1_____1, + c1__1__1, + c1__1__1, + c1__1__1, + c1__1__1, + c_11_11_ }, /* w */ + + { c_______, + c_______, + c_______, + c1____1_, + c_1__1__, + c__11___, + c__11___, + c_1__1__, + c1____1_ }, /* x */ + + { c1____1_, + c1____1_, + c1____1_, + c1____1_, + c1___11_, + c_111_1_, + c_____1_, + c1____1_, + c_1111__ }, /* y */ + + { c_______, + c_______, + c_______, + c111111_, + c____1__, + c___1___, + c__1____, + c_1_____, + c111111_ }, /* z */ + + { c___11__, + c__1____, + c__1____, + c__1____, + c_1_____, + c__1____, + c__1____, + c__1____, + c___11__ }, /* } */ + + { c___1___, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___, + c___1___ }, /* | */ + + { c__11___, + c____1__, + c____1__, + c____1__, + c_____1_, + c____1__, + c____1__, + c____1__, + c__11___ }, /* } */ + + { c_11____, + c1__1__1, + c____11_, + c_______, + c_______, + c_______, + c_______, + c_______, + c_______ }, /* ~ */ + + { c_1__1__, + c1__1__1, + c__1__1_, + c_1__1__, + c1__1__1, + c__1__1_, + c_1__1__, + c1__1__1, + c__1__1_ } /* rub-out */ +}; diff --git a/usr.sbin/lpr/lpd/printjob.c b/usr.sbin/lpr/lpd/printjob.c new file mode 100644 index 0000000..87c9352 --- /dev/null +++ b/usr.sbin/lpr/lpd/printjob.c @@ -0,0 +1,1377 @@ +/* + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)printjob.c 8.2 (Berkeley) 4/16/94"; +#endif /* not lint */ + + +/* + * printjob -- print jobs in the queue. + * + * NOTE: the lock file is used to pass information to lpq and lprm. + * it does not need to be removed because file locks are dynamic. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lp.h" +#include "lp.local.h" +#include "pathnames.h" +#include "extern.h" + +#define DORETURN 0 /* absorb fork error */ +#define DOABORT 1 /* abort if dofork fails */ + +/* + * Error tokens + */ +#define REPRINT -2 +#define ERROR -1 +#define OK 0 +#define FATALERR 1 +#define NOACCT 2 +#define FILTERERR 3 +#define ACCESS 4 + +static dev_t fdev; /* device of file pointed to by symlink */ +static ino_t fino; /* inode of file pointed to by symlink */ +static FILE *cfp; /* control file */ +static int child; /* id of any filters */ +static int lfd; /* lock file descriptor */ +static int ofd; /* output filter file descriptor */ +static int ofilter; /* id of output filter, if any */ +static int pfd; /* prstatic inter file descriptor */ +static int pid; /* pid of lpd process */ +static int prchild; /* id of pr process */ +static int remote; /* true if sending files to remote */ +static char title[80]; /* ``pr'' title */ +static int tof; /* true if at top of form */ + +static char class[32]; /* classification field */ +static char fromhost[32]; /* user's host machine */ + /* indentation size in static characters */ +static char indent[10] = "-i0"; +static char jobname[100]; /* job or file name */ +static char length[10] = "-l"; /* page length in lines */ +static char logname[32]; /* user's login name */ +static char pxlength[10] = "-y"; /* page length in pixels */ +static char pxwidth[10] = "-x"; /* page width in pixels */ +static char tempfile[] = "errsXXXXXX"; /* file name for filter output */ +static char width[10] = "-w"; /* page width in static characters */ + +static void abortpr __P((int)); +static void banner __P((char *, char *)); +static int dofork __P((int)); +static int dropit __P((int)); +static void init __P((void)); +static void openpr __P((void)); +static int print __P((int, char *)); +static int printit __P((char *)); +static void pstatus __P((const char *, ...)); +static char response __P((void)); +static void scan_out __P((int, char *, int)); +static char *scnline __P((int, char *, int)); +static int sendfile __P((int, char *)); +static int sendit __P((char *)); +static void sendmail __P((char *, int)); +static void setty __P((void)); + +void +printjob() +{ + struct stat stb; + register struct queue *q, **qp; + struct queue **queue; + register int i, nitems; + long pidoff; + int count = 0; + + init(); /* set up capabilities */ + (void) write(1, "", 1); /* ack that daemon is started */ + (void) close(2); /* set up log file */ + if (open(LF, O_WRONLY|O_APPEND, 0664) < 0) { + syslog(LOG_ERR, "%s: %m", LF); + (void) open(_PATH_DEVNULL, O_WRONLY); + } + setgid(getegid()); + pid = getpid(); /* for use with lprm */ + setpgrp(0, pid); + signal(SIGHUP, abortpr); + signal(SIGINT, abortpr); + signal(SIGQUIT, abortpr); + signal(SIGTERM, abortpr); + + (void) mktemp(tempfile); + + /* + * uses short form file names + */ + if (chdir(SD) < 0) { + syslog(LOG_ERR, "%s: %m", SD); + exit(1); + } + if (stat(LO, &stb) == 0 && (stb.st_mode & 0100)) + exit(0); /* printing disabled */ + lfd = open(LO, O_WRONLY|O_CREAT, 0644); + if (lfd < 0) { + syslog(LOG_ERR, "%s: %s: %m", printer, LO); + exit(1); + } + if (flock(lfd, LOCK_EX|LOCK_NB) < 0) { + if (errno == EWOULDBLOCK) /* active deamon present */ + exit(0); + syslog(LOG_ERR, "%s: %s: %m", printer, LO); + exit(1); + } + ftruncate(lfd, 0); + /* + * write process id for others to know + */ + sprintf(line, "%u\n", pid); + pidoff = i = strlen(line); + if (write(lfd, line, i) != i) { + syslog(LOG_ERR, "%s: %s: %m", printer, LO); + exit(1); + } + /* + * search the spool directory for work and sort by queue order. + */ + if ((nitems = getq(&queue)) < 0) { + syslog(LOG_ERR, "%s: can't scan %s", printer, SD); + exit(1); + } + if (nitems == 0) /* no work to do */ + exit(0); + if (stb.st_mode & 01) { /* reset queue flag */ + if (fchmod(lfd, stb.st_mode & 0776) < 0) + syslog(LOG_ERR, "%s: %s: %m", printer, LO); + } + openpr(); /* open printer or remote */ +again: + /* + * we found something to do now do it -- + * write the name of the current control file into the lock file + * so the spool queue program can tell what we're working on + */ + for (qp = queue; nitems--; free((char *) q)) { + q = *qp++; + if (stat(q->q_name, &stb) < 0) + continue; + restart: + (void) lseek(lfd, (off_t)pidoff, 0); + (void) sprintf(line, "%s\n", q->q_name); + i = strlen(line); + if (write(lfd, line, i) != i) + syslog(LOG_ERR, "%s: %s: %m", printer, LO); + if (!remote) + i = printit(q->q_name); + else + i = sendit(q->q_name); + /* + * Check to see if we are supposed to stop printing or + * if we are to rebuild the queue. + */ + if (fstat(lfd, &stb) == 0) { + /* stop printing before starting next job? */ + if (stb.st_mode & 0100) + goto done; + /* rebuild queue (after lpc topq) */ + if (stb.st_mode & 01) { + for (free((char *) q); nitems--; free((char *) q)) + q = *qp++; + if (fchmod(lfd, stb.st_mode & 0776) < 0) + syslog(LOG_WARNING, "%s: %s: %m", + printer, LO); + break; + } + } + if (i == OK) /* file ok and printed */ + count++; + else if (i == REPRINT) { /* try reprinting the job */ + syslog(LOG_INFO, "restarting %s", printer); + if (ofilter > 0) { + kill(ofilter, SIGCONT); /* to be sure */ + (void) close(ofd); + while ((i = wait(0)) > 0 && i != ofilter) + ; + ofilter = 0; + } + (void) close(pfd); /* close printer */ + if (ftruncate(lfd, pidoff) < 0) + syslog(LOG_WARNING, "%s: %s: %m", printer, LO); + openpr(); /* try to reopen printer */ + goto restart; + } + } + free((char *) queue); + /* + * search the spool directory for more work. + */ + if ((nitems = getq(&queue)) < 0) { + syslog(LOG_ERR, "%s: can't scan %s", printer, SD); + exit(1); + } + if (nitems == 0) { /* no more work to do */ + done: + if (count > 0) { /* Files actually printed */ + if (!SF && !tof) + (void) write(ofd, FF, strlen(FF)); + if (TR != NULL) /* output trailer */ + (void) write(ofd, TR, strlen(TR)); + } + (void) unlink(tempfile); + exit(0); + } + goto again; +} + +char fonts[4][50]; /* fonts for troff */ + +char ifonts[4][40] = { + _PATH_VFONTR, + _PATH_VFONTI, + _PATH_VFONTB, + _PATH_VFONTS, +}; + +/* + * The remaining part is the reading of the control file (cf) + * and performing the various actions. + */ +static int +printit(file) + char *file; +{ + register int i; + char *cp; + int bombed = OK; + + /* + * open control file; ignore if no longer there. + */ + if ((cfp = fopen(file, "r")) == NULL) { + syslog(LOG_INFO, "%s: %s: %m", printer, file); + return(OK); + } + /* + * Reset troff fonts. + */ + for (i = 0; i < 4; i++) + strcpy(fonts[i], ifonts[i]); + sprintf(&width[2], "%d", PW); + strcpy(indent+2, "0"); + + /* + * read the control file for work to do + * + * file format -- first character in the line is a command + * rest of the line is the argument. + * valid commands are: + * + * S -- "stat info" for symbolic link protection + * J -- "job name" on banner page + * C -- "class name" on banner page + * L -- "literal" user's name to print on banner + * T -- "title" for pr + * H -- "host name" of machine where lpr was done + * P -- "person" user's login name + * I -- "indent" amount to indent output + * f -- "file name" name of text file to print + * l -- "file name" text file with control chars + * p -- "file name" text file to print with pr(1) + * t -- "file name" troff(1) file to print + * n -- "file name" ditroff(1) file to print + * d -- "file name" dvi file to print + * g -- "file name" plot(1G) file to print + * v -- "file name" plain raster file to print + * c -- "file name" cifplot file to print + * 1 -- "R font file" for troff + * 2 -- "I font file" for troff + * 3 -- "B font file" for troff + * 4 -- "S font file" for troff + * N -- "name" of file (used by lpq) + * U -- "unlink" name of file to remove + * (after we print it. (Pass 2 only)). + * M -- "mail" to user when done printing + * + * getline reads a line and expands tabs to blanks + */ + + /* pass 1 */ + + while (getline(cfp)) + switch (line[0]) { + case 'H': + strcpy(fromhost, line+1); + if (class[0] == '\0') + strncpy(class, line+1, sizeof(class)-1); + continue; + + case 'P': + strncpy(logname, line+1, sizeof(logname)-1); + if (RS) { /* restricted */ + if (getpwnam(logname) == NULL) { + bombed = NOACCT; + sendmail(line+1, bombed); + goto pass2; + } + } + continue; + + case 'S': + cp = line+1; + i = 0; + while (*cp >= '0' && *cp <= '9') + i = i * 10 + (*cp++ - '0'); + fdev = i; + cp++; + i = 0; + while (*cp >= '0' && *cp <= '9') + i = i * 10 + (*cp++ - '0'); + fino = i; + continue; + + case 'J': + if (line[1] != '\0') + strncpy(jobname, line+1, sizeof(jobname)-1); + else + strcpy(jobname, " "); + continue; + + case 'C': + if (line[1] != '\0') + strncpy(class, line+1, sizeof(class)-1); + else if (class[0] == '\0') + gethostname(class, sizeof(class)); + continue; + + case 'T': /* header title for pr */ + strncpy(title, line+1, sizeof(title)-1); + continue; + + case 'L': /* identification line */ + if (!SH && !HL) + banner(line+1, jobname); + continue; + + case '1': /* troff fonts */ + case '2': + case '3': + case '4': + if (line[1] != '\0') + strcpy(fonts[line[0]-'1'], line+1); + continue; + + case 'W': /* page width */ + strncpy(width+2, line+1, sizeof(width)-3); + continue; + + case 'I': /* indent amount */ + strncpy(indent+2, line+1, sizeof(indent)-3); + continue; + + default: /* some file to print */ + switch (i = print(line[0], line+1)) { + case ERROR: + if (bombed == OK) + bombed = FATALERR; + break; + case REPRINT: + (void) fclose(cfp); + return(REPRINT); + case FILTERERR: + case ACCESS: + bombed = i; + sendmail(logname, bombed); + } + title[0] = '\0'; + continue; + + case 'N': + case 'U': + case 'M': + continue; + } + + /* pass 2 */ + +pass2: + fseek(cfp, 0L, 0); + while (getline(cfp)) + switch (line[0]) { + case 'L': /* identification line */ + if (!SH && HL) + banner(line+1, jobname); + continue; + + case 'M': + if (bombed < NOACCT) /* already sent if >= NOACCT */ + sendmail(line+1, bombed); + continue; + + case 'U': + (void) unlink(line+1); + } + /* + * clean-up in case another control file exists + */ + (void) fclose(cfp); + (void) unlink(file); + return(bombed == OK ? OK : ERROR); +} + +/* + * Print a file. + * Set up the chain [ PR [ | {IF, OF} ] ] or {IF, RF, TF, NF, DF, CF, VF}. + * Return -1 if a non-recoverable error occured, + * 2 if the filter detected some errors (but printed the job anyway), + * 1 if we should try to reprint this job and + * 0 if all is well. + * Note: all filters take stdin as the file, stdout as the printer, + * stderr as the log file, and must not ignore SIGINT. + */ +static int +print(format, file) + int format; + char *file; +{ + register int n; + register char *prog; + int fi, fo; + FILE *fp; + char *av[15], buf[BUFSIZ]; + int pid, p[2], stopped = 0; + union wait status; + struct stat stb; + + if (lstat(file, &stb) < 0 || (fi = open(file, O_RDONLY)) < 0) + return(ERROR); + /* + * Check to see if data file is a symbolic link. If so, it should + * still point to the same file or someone is trying to print + * something he shouldn't. + */ + if ((stb.st_mode & S_IFMT) == S_IFLNK && fstat(fi, &stb) == 0 && + (stb.st_dev != fdev || stb.st_ino != fino)) + return(ACCESS); + if (!SF && !tof) { /* start on a fresh page */ + (void) write(ofd, FF, strlen(FF)); + tof = 1; + } + if (IF == NULL && (format == 'f' || format == 'l')) { + tof = 0; + while ((n = read(fi, buf, BUFSIZ)) > 0) + if (write(ofd, buf, n) != n) { + (void) close(fi); + return(REPRINT); + } + (void) close(fi); + return(OK); + } + switch (format) { + case 'p': /* print file using 'pr' */ + if (IF == NULL) { /* use output filter */ + prog = _PATH_PR; + av[0] = "pr"; + av[1] = width; + av[2] = length; + av[3] = "-h"; + av[4] = *title ? title : " "; + av[5] = 0; + fo = ofd; + goto start; + } + pipe(p); + if ((prchild = dofork(DORETURN)) == 0) { /* child */ + dup2(fi, 0); /* file is stdin */ + dup2(p[1], 1); /* pipe is stdout */ + for (n = 3; n < NOFILE; n++) + (void) close(n); + execl(_PATH_PR, "pr", width, length, + "-h", *title ? title : " ", 0); + syslog(LOG_ERR, "cannot execl %s", _PATH_PR); + exit(2); + } + (void) close(p[1]); /* close output side */ + (void) close(fi); + if (prchild < 0) { + prchild = 0; + (void) close(p[0]); + return(ERROR); + } + fi = p[0]; /* use pipe for input */ + case 'f': /* print plain text file */ + prog = IF; + av[1] = width; + av[2] = length; + av[3] = indent; + n = 4; + break; + case 'l': /* like 'f' but pass control characters */ + prog = IF; + av[1] = "-c"; + av[2] = width; + av[3] = length; + av[4] = indent; + n = 5; + break; + case 'r': /* print a fortran text file */ + prog = RF; + av[1] = width; + av[2] = length; + n = 3; + break; + case 't': /* print troff output */ + case 'n': /* print ditroff output */ + case 'd': /* print tex output */ + (void) unlink(".railmag"); + if ((fo = creat(".railmag", FILMOD)) < 0) { + syslog(LOG_ERR, "%s: cannot create .railmag", printer); + (void) unlink(".railmag"); + } else { + for (n = 0; n < 4; n++) { + if (fonts[n][0] != '/') + (void) write(fo, _PATH_VFONT, + sizeof(_PATH_VFONT) - 1); + (void) write(fo, fonts[n], strlen(fonts[n])); + (void) write(fo, "\n", 1); + } + (void) close(fo); + } + prog = (format == 't') ? TF : (format == 'n') ? NF : DF; + av[1] = pxwidth; + av[2] = pxlength; + n = 3; + break; + case 'c': /* print cifplot output */ + prog = CF; + av[1] = pxwidth; + av[2] = pxlength; + n = 3; + break; + case 'g': /* print plot(1G) output */ + prog = GF; + av[1] = pxwidth; + av[2] = pxlength; + n = 3; + break; + case 'v': /* print raster output */ + prog = VF; + av[1] = pxwidth; + av[2] = pxlength; + n = 3; + break; + default: + (void) close(fi); + syslog(LOG_ERR, "%s: illegal format character '%c'", + printer, format); + return(ERROR); + } + if ((av[0] = rindex(prog, '/')) != NULL) + av[0]++; + else + av[0] = prog; + av[n++] = "-n"; + av[n++] = logname; + av[n++] = "-h"; + av[n++] = fromhost; + av[n++] = AF; + av[n] = 0; + fo = pfd; + if (ofilter > 0) { /* stop output filter */ + write(ofd, "\031\1", 2); + while ((pid = + wait3((int *)&status, WUNTRACED, 0)) > 0 && pid != ofilter) + ; + if (status.w_stopval != WSTOPPED) { + (void) close(fi); + syslog(LOG_WARNING, "%s: output filter died (%d)", + printer, status.w_retcode); + return(REPRINT); + } + stopped++; + } +start: + if ((child = dofork(DORETURN)) == 0) { /* child */ + dup2(fi, 0); + dup2(fo, 1); + n = open(tempfile, O_WRONLY|O_CREAT|O_TRUNC, 0664); + if (n >= 0) + dup2(n, 2); + for (n = 3; n < NOFILE; n++) + (void) close(n); + execv(prog, av); + syslog(LOG_ERR, "cannot execv %s", prog); + exit(2); + } + (void) close(fi); + if (child < 0) + status.w_retcode = 100; + else + while ((pid = wait((int *)&status)) > 0 && pid != child) + ; + child = 0; + prchild = 0; + if (stopped) { /* restart output filter */ + if (kill(ofilter, SIGCONT) < 0) { + syslog(LOG_ERR, "cannot restart output filter"); + exit(1); + } + } + tof = 0; + + /* Copy filter output to "lf" logfile */ + if (fp = fopen(tempfile, "r")) { + while (fgets(buf, sizeof(buf), fp)) + fputs(buf, stderr); + fclose(fp); + } + + if (!WIFEXITED(status)) { + syslog(LOG_WARNING, "%s: Daemon filter '%c' terminated (%d)", + printer, format, status.w_termsig); + return(ERROR); + } + switch (status.w_retcode) { + case 0: + tof = 1; + return(OK); + case 1: + return(REPRINT); + default: + syslog(LOG_WARNING, "%s: Daemon filter '%c' exited (%d)", + printer, format, status.w_retcode); + case 2: + return(ERROR); + } +} + +/* + * Send the daemon control file (cf) and any data files. + * Return -1 if a non-recoverable error occured, 1 if a recoverable error and + * 0 if all is well. + */ +static int +sendit(file) + char *file; +{ + register int i, err = OK; + char *cp, last[BUFSIZ]; + + /* + * open control file + */ + if ((cfp = fopen(file, "r")) == NULL) + return(OK); + /* + * read the control file for work to do + * + * file format -- first character in the line is a command + * rest of the line is the argument. + * commands of interest are: + * + * a-z -- "file name" name of file to print + * U -- "unlink" name of file to remove + * (after we print it. (Pass 2 only)). + */ + + /* + * pass 1 + */ + while (getline(cfp)) { + again: + if (line[0] == 'S') { + cp = line+1; + i = 0; + while (*cp >= '0' && *cp <= '9') + i = i * 10 + (*cp++ - '0'); + fdev = i; + cp++; + i = 0; + while (*cp >= '0' && *cp <= '9') + i = i * 10 + (*cp++ - '0'); + fino = i; + continue; + } + if (line[0] >= 'a' && line[0] <= 'z') { + strcpy(last, line); + while (i = getline(cfp)) + if (strcmp(last, line)) + break; + switch (sendfile('\3', last+1)) { + case OK: + if (i) + goto again; + break; + case REPRINT: + (void) fclose(cfp); + return(REPRINT); + case ACCESS: + sendmail(logname, ACCESS); + case ERROR: + err = ERROR; + } + break; + } + } + if (err == OK && sendfile('\2', file) > 0) { + (void) fclose(cfp); + return(REPRINT); + } + /* + * pass 2 + */ + fseek(cfp, 0L, 0); + while (getline(cfp)) + if (line[0] == 'U') + (void) unlink(line+1); + /* + * clean-up in case another control file exists + */ + (void) fclose(cfp); + (void) unlink(file); + return(err); +} + +/* + * Send a data file to the remote machine and spool it. + * Return positive if we should try resending. + */ +static int +sendfile(type, file) + int type; + char *file; +{ + register int f, i, amt; + struct stat stb; + char buf[BUFSIZ]; + int sizerr, resp; + + if (lstat(file, &stb) < 0 || (f = open(file, O_RDONLY)) < 0) + return(ERROR); + /* + * Check to see if data file is a symbolic link. If so, it should + * still point to the same file or someone is trying to print something + * he shouldn't. + */ + if ((stb.st_mode & S_IFMT) == S_IFLNK && fstat(f, &stb) == 0 && + (stb.st_dev != fdev || stb.st_ino != fino)) + return(ACCESS); + (void) sprintf(buf, "%c%qd %s\n", type, stb.st_size, file); + amt = strlen(buf); + for (i = 0; ; i++) { + if (write(pfd, buf, amt) != amt || + (resp = response()) < 0 || resp == '\1') { + (void) close(f); + return(REPRINT); + } else if (resp == '\0') + break; + if (i == 0) + pstatus("no space on remote; waiting for queue to drain"); + if (i == 10) + syslog(LOG_ALERT, "%s: can't send to %s; queue full", + printer, RM); + sleep(5 * 60); + } + if (i) + pstatus("sending to %s", RM); + sizerr = 0; + for (i = 0; i < stb.st_size; i += BUFSIZ) { + amt = BUFSIZ; + if (i + amt > stb.st_size) + amt = stb.st_size - i; + if (sizerr == 0 && read(f, buf, amt) != amt) + sizerr = 1; + if (write(pfd, buf, amt) != amt) { + (void) close(f); + return(REPRINT); + } + } + + + + + (void) close(f); + if (sizerr) { + syslog(LOG_INFO, "%s: %s: changed size", printer, file); + /* tell recvjob to ignore this file */ + (void) write(pfd, "\1", 1); + return(ERROR); + } + if (write(pfd, "", 1) != 1 || response()) + return(REPRINT); + return(OK); +} + +/* + * Check to make sure there have been no errors and that both programs + * are in sync with eachother. + * Return non-zero if the connection was lost. + */ +static char +response() +{ + char resp; + + if (read(pfd, &resp, 1) != 1) { + syslog(LOG_INFO, "%s: lost connection", printer); + return(-1); + } + return(resp); +} + +/* + * Banner printing stuff + */ +static void +banner(name1, name2) + char *name1, *name2; +{ + time_t tvec; + extern char *ctime(); + + time(&tvec); + if (!SF && !tof) + (void) write(ofd, FF, strlen(FF)); + if (SB) { /* short banner only */ + if (class[0]) { + (void) write(ofd, class, strlen(class)); + (void) write(ofd, ":", 1); + } + (void) write(ofd, name1, strlen(name1)); + (void) write(ofd, " Job: ", 7); + (void) write(ofd, name2, strlen(name2)); + (void) write(ofd, " Date: ", 8); + (void) write(ofd, ctime(&tvec), 24); + (void) write(ofd, "\n", 1); + } else { /* normal banner */ + (void) write(ofd, "\n\n\n", 3); + scan_out(ofd, name1, '\0'); + (void) write(ofd, "\n\n", 2); + scan_out(ofd, name2, '\0'); + if (class[0]) { + (void) write(ofd,"\n\n\n",3); + scan_out(ofd, class, '\0'); + } + (void) write(ofd, "\n\n\n\n\t\t\t\t\tJob: ", 15); + (void) write(ofd, name2, strlen(name2)); + (void) write(ofd, "\n\t\t\t\t\tDate: ", 12); + (void) write(ofd, ctime(&tvec), 24); + (void) write(ofd, "\n", 1); + } + if (!SF) + (void) write(ofd, FF, strlen(FF)); + tof = 1; +} + +static char * +scnline(key, p, c) + register int key; + register char *p; + int c; +{ + register scnwidth; + + for (scnwidth = WIDTH; --scnwidth;) { + key <<= 1; + *p++ = key & 0200 ? c : BACKGND; + } + return (p); +} + +#define TRC(q) (((q)-' ')&0177) + +static void +scan_out(scfd, scsp, dlm) + int scfd, dlm; + char *scsp; +{ + register char *strp; + register nchrs, j; + char outbuf[LINELEN+1], *sp, c, cc; + int d, scnhgt; + extern char scnkey[][HEIGHT]; /* in lpdchar.c */ + + for (scnhgt = 0; scnhgt++ < HEIGHT+DROP; ) { + strp = &outbuf[0]; + sp = scsp; + for (nchrs = 0; ; ) { + d = dropit(c = TRC(cc = *sp++)); + if ((!d && scnhgt > HEIGHT) || (scnhgt <= DROP && d)) + for (j = WIDTH; --j;) + *strp++ = BACKGND; + else + strp = scnline(scnkey[c][scnhgt-1-d], strp, cc); + if (*sp == dlm || *sp == '\0' || nchrs++ >= PW/(WIDTH+1)-1) + break; + *strp++ = BACKGND; + *strp++ = BACKGND; + } + while (*--strp == BACKGND && strp >= outbuf) + ; + strp++; + *strp++ = '\n'; + (void) write(scfd, outbuf, strp-outbuf); + } +} + +static int +dropit(c) + int c; +{ + switch(c) { + + case TRC('_'): + case TRC(';'): + case TRC(','): + case TRC('g'): + case TRC('j'): + case TRC('p'): + case TRC('q'): + case TRC('y'): + return (DROP); + + default: + return (0); + } +} + +/* + * sendmail --- + * tell people about job completion + */ +static void +sendmail(user, bombed) + char *user; + int bombed; +{ + register int i; + int p[2], s; + register char *cp; + char buf[100]; + struct stat stb; + FILE *fp; + + pipe(p); + if ((s = dofork(DORETURN)) == 0) { /* child */ + dup2(p[0], 0); + for (i = 3; i < NOFILE; i++) + (void) close(i); + if ((cp = rindex(_PATH_SENDMAIL, '/')) != NULL) + cp++; + else + cp = _PATH_SENDMAIL; + sprintf(buf, "%s@%s", user, fromhost); + execl(_PATH_SENDMAIL, cp, buf, 0); + exit(0); + } else if (s > 0) { /* parent */ + dup2(p[1], 1); + printf("To: %s@%s\n", user, fromhost); + printf("Subject: printer job\n\n"); + printf("Your printer job "); + if (*jobname) + printf("(%s) ", jobname); + switch (bombed) { + case OK: + printf("\ncompleted successfully\n"); + break; + default: + case FATALERR: + printf("\ncould not be printed\n"); + break; + case NOACCT: + printf("\ncould not be printed without an account on %s\n", host); + break; + case FILTERERR: + if (stat(tempfile, &stb) < 0 || stb.st_size == 0 || + (fp = fopen(tempfile, "r")) == NULL) { + printf("\nwas printed but had some errors\n"); + break; + } + printf("\nwas printed but had the following errors:\n"); + while ((i = getc(fp)) != EOF) + putchar(i); + (void) fclose(fp); + break; + case ACCESS: + printf("\nwas not printed because it was not linked to the original file\n"); + } + fflush(stdout); + (void) close(1); + } + (void) close(p[0]); + (void) close(p[1]); + wait(&s); +} + +/* + * dofork - fork with retries on failure + */ +static int +dofork(action) + int action; +{ + register int i, pid; + + for (i = 0; i < 20; i++) { + if ((pid = fork()) < 0) { + sleep((unsigned)(i*i)); + continue; + } + /* + * Child should run as daemon instead of root + */ + if (pid == 0) + setuid(DU); + return(pid); + } + syslog(LOG_ERR, "can't fork"); + + switch (action) { + case DORETURN: + return (-1); + default: + syslog(LOG_ERR, "bad action (%d) to dofork", action); + /*FALL THRU*/ + case DOABORT: + exit(1); + } + /*NOTREACHED*/ +} + +/* + * Kill child processes to abort current job. + */ +static void +abortpr(signo) + int signo; +{ + (void) unlink(tempfile); + kill(0, SIGINT); + if (ofilter > 0) + kill(ofilter, SIGCONT); + while (wait(NULL) > 0) + ; + exit(0); +} + +static void +init() +{ + int status; + char *s; + + if ((status = cgetent(&bp, printcapdb, printer)) == -2) { + syslog(LOG_ERR, "can't open printer description file"); + exit(1); + } else if (status == -1) { + syslog(LOG_ERR, "unknown printer: %s", printer); + exit(1); + } else if (status == -3) + fatal("potential reference loop detected in printcap file"); + + if (cgetstr(bp, "lp", &LP) == -1) + LP = _PATH_DEFDEVLP; + if (cgetstr(bp, "rp", &RP) == -1) + RP = DEFLP; + if (cgetstr(bp, "lo", &LO) == -1) + LO = DEFLOCK; + if (cgetstr(bp, "st", &ST) == -1) + ST = DEFSTAT; + if (cgetstr(bp, "lf", &LF) == -1) + LF = _PATH_CONSOLE; + if (cgetstr(bp, "sd", &SD) == -1) + SD = _PATH_DEFSPOOL; + if (cgetnum(bp, "du", &DU) < 0) + DU = DEFUID; + if (cgetstr(bp,"ff", &FF) == -1) + FF = DEFFF; + if (cgetnum(bp, "pw", &PW) < 0) + PW = DEFWIDTH; + sprintf(&width[2], "%d", PW); + if (cgetnum(bp, "pl", &PL) < 0) + PL = DEFLENGTH; + sprintf(&length[2], "%d", PL); + if (cgetnum(bp,"px", &PX) < 0) + PX = 0; + sprintf(&pxwidth[2], "%d", PX); + if (cgetnum(bp, "py", &PY) < 0) + PY = 0; + sprintf(&pxlength[2], "%d", PY); + cgetstr(bp, "rm", &RM); + if (s = checkremote()) + syslog(LOG_WARNING, s); + + cgetstr(bp, "af", &AF); + cgetstr(bp, "of", &OF); + cgetstr(bp, "if", &IF); + cgetstr(bp, "rf", &RF); + cgetstr(bp, "tf", &TF); + cgetstr(bp, "nf", &NF); + cgetstr(bp, "df", &DF); + cgetstr(bp, "gf", &GF); + cgetstr(bp, "vf", &VF); + cgetstr(bp, "cf", &CF); + cgetstr(bp, "tr", &TR); + + RS = (cgetcap(bp, "rs", ':') != NULL); + SF = (cgetcap(bp, "sf", ':') != NULL); + SH = (cgetcap(bp, "sh", ':') != NULL); + SB = (cgetcap(bp, "sb", ':') != NULL); + HL = (cgetcap(bp, "hl", ':') != NULL); + RW = (cgetcap(bp, "rw", ':') != NULL); + + cgetnum(bp, "br", &BR); + if (cgetnum(bp, "fc", &FC) < 0) + FC = 0; + if (cgetnum(bp, "fs", &FS) < 0) + FS = 0; + if (cgetnum(bp, "xc", &XC) < 0) + XC = 0; + if (cgetnum(bp, "xs", &XS) < 0) + XS = 0; + + tof = (cgetcap(bp, "fo", ':') == NULL); +} + +/* + * Acquire line printer or remote connection. + */ +static void +openpr() +{ + register int i, n; + int resp; + + if (!sendtorem && *LP) { + for (i = 1; ; i = i < 32 ? i << 1 : i) { + pfd = open(LP, RW ? O_RDWR : O_WRONLY); + if (pfd >= 0) + break; + if (errno == ENOENT) { + syslog(LOG_ERR, "%s: %m", LP); + exit(1); + } + if (i == 1) + pstatus("waiting for %s to become ready (offline ?)", printer); + sleep(i); + } + if (isatty(pfd)) + setty(); + pstatus("%s is ready and printing", printer); + } else if (RM != NULL) { + for (i = 1; ; i = i < 256 ? i << 1 : i) { + resp = -1; + pfd = getport(RM); + if (pfd >= 0) { + (void) sprintf(line, "\2%s\n", RP); + n = strlen(line); + if (write(pfd, line, n) == n && + (resp = response()) == '\0') + break; + (void) close(pfd); + } + if (i == 1) { + if (resp < 0) + pstatus("waiting for %s to come up", RM); + else { + pstatus("waiting for queue to be enabled on %s", RM); + i = 256; + } + } + sleep(i); + } + pstatus("sending to %s", RM); + remote = 1; + } else { + syslog(LOG_ERR, "%s: no line printer device or host name", + printer); + exit(1); + } + /* + * Start up an output filter, if needed. + */ + if (!remote && OF) { + int p[2]; + char *cp; + + pipe(p); + if ((ofilter = dofork(DOABORT)) == 0) { /* child */ + dup2(p[0], 0); /* pipe is std in */ + dup2(pfd, 1); /* printer is std out */ + for (i = 3; i < NOFILE; i++) + (void) close(i); + if ((cp = rindex(OF, '/')) == NULL) + cp = OF; + else + cp++; + execl(OF, cp, width, length, 0); + syslog(LOG_ERR, "%s: %s: %m", printer, OF); + exit(1); + } + (void) close(p[0]); /* close input side */ + ofd = p[1]; /* use pipe for output */ + } else { + ofd = pfd; + ofilter = 0; + } +} + +struct bauds { + int baud; + int speed; +} bauds[] = { + 50, B50, + 75, B75, + 110, B110, + 134, B134, + 150, B150, + 200, B200, + 300, B300, + 600, B600, + 1200, B1200, + 1800, B1800, + 2400, B2400, + 4800, B4800, + 9600, B9600, + 19200, EXTA, + 38400, EXTB, + 0, 0 +}; + +/* + * setup tty lines. + */ +static void +setty() +{ + struct sgttyb ttybuf; + register struct bauds *bp; + + if (ioctl(pfd, TIOCEXCL, (char *)0) < 0) { + syslog(LOG_ERR, "%s: ioctl(TIOCEXCL): %m", printer); + exit(1); + } + if (ioctl(pfd, TIOCGETP, (char *)&ttybuf) < 0) { + syslog(LOG_ERR, "%s: ioctl(TIOCGETP): %m", printer); + exit(1); + } + if (BR > 0) { + for (bp = bauds; bp->baud; bp++) + if (BR == bp->baud) + break; + if (!bp->baud) { + syslog(LOG_ERR, "%s: illegal baud rate %d", printer, BR); + exit(1); + } + ttybuf.sg_ispeed = ttybuf.sg_ospeed = bp->speed; + } + ttybuf.sg_flags &= ~FC; + ttybuf.sg_flags |= FS; + if (ioctl(pfd, TIOCSETP, (char *)&ttybuf) < 0) { + syslog(LOG_ERR, "%s: ioctl(TIOCSETP): %m", printer); + exit(1); + } + if (XC) { + if (ioctl(pfd, TIOCLBIC, &XC) < 0) { + syslog(LOG_ERR, "%s: ioctl(TIOCLBIC): %m", printer); + exit(1); + } + } + if (XS) { + if (ioctl(pfd, TIOCLBIS, &XS) < 0) { + syslog(LOG_ERR, "%s: ioctl(TIOCLBIS): %m", printer); + exit(1); + } + } +} + +#if __STDC__ +#include +#else +#include +#endif + +void +#if __STDC__ +pstatus(const char *msg, ...) +#else +pstatus(msg, va_alist) + char *msg; + va_dcl +#endif +{ + register int fd; + char buf[BUFSIZ]; + va_list ap; +#if __STDC__ + va_start(ap, msg); +#else + va_start(ap); +#endif + + umask(0); + fd = open(ST, O_WRONLY|O_CREAT, 0664); + if (fd < 0 || flock(fd, LOCK_EX) < 0) { + syslog(LOG_ERR, "%s: %s: %m", printer, ST); + exit(1); + } + ftruncate(fd, 0); + (void)vsnprintf(buf, sizeof(buf), msg, ap); + va_end(ap); + strcat(buf, "\n"); + (void) write(fd, buf, strlen(buf)); + (void) close(fd); +} diff --git a/usr.sbin/lpr/lpd/recvjob.c b/usr.sbin/lpr/lpd/recvjob.c new file mode 100644 index 0000000..67a6183 --- /dev/null +++ b/usr.sbin/lpr/lpd/recvjob.c @@ -0,0 +1,358 @@ +/* + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)recvjob.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Receive printer jobs from the network, queue them and + * start the printer daemon. + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "lp.h" +#include "lp.local.h" +#include "extern.h" +#include "pathnames.h" + +#define ack() (void) write(1, sp, 1); + +static char dfname[40]; /* data files */ +static int minfree; /* keep at least minfree blocks available */ +static char *sp = ""; +static char tfname[40]; /* tmp copy of cf before linking */ + +static int chksize __P((int)); +static void frecverr __P((const char *, ...)); +static int noresponse __P((void)); +static void rcleanup __P((int)); +static int read_number __P((char *)); +static int readfile __P((char *, int)); +static int readjob __P((void)); + + +void +recvjob() +{ + struct stat stb; + int status; + + /* + * Perform lookup for printer name or abbreviation + */ + if ((status = cgetent(&bp, printcapdb, printer)) == -2) + frecverr("cannot open printer description file"); + else if (status == -1) + frecverr("unknown printer %s", printer); + else if (status == -3) + fatal("potential reference loop detected in printcap file"); + + if (cgetstr(bp, "lf", &LF) == -1) + LF = _PATH_CONSOLE; + if (cgetstr(bp, "sd", &SD) == -1) + SD = _PATH_DEFSPOOL; + if (cgetstr(bp, "lo", &LO) == -1) + LO = DEFLOCK; + + (void) close(2); /* set up log file */ + if (open(LF, O_WRONLY|O_APPEND, 0664) < 0) { + syslog(LOG_ERR, "%s: %m", LF); + (void) open(_PATH_DEVNULL, O_WRONLY); + } + + if (chdir(SD) < 0) + frecverr("%s: %s: %m", printer, SD); + if (stat(LO, &stb) == 0) { + if (stb.st_mode & 010) { + /* queue is disabled */ + putchar('\1'); /* return error code */ + exit(1); + } + } else if (stat(SD, &stb) < 0) + frecverr("%s: %s: %m", printer, SD); + minfree = 2 * read_number("minfree"); /* scale KB to 512 blocks */ + signal(SIGTERM, rcleanup); + signal(SIGPIPE, rcleanup); + + if (readjob()) + printjob(); +} + +/* + * Read printer jobs sent by lpd and copy them to the spooling directory. + * Return the number of jobs successfully transfered. + */ +static int +readjob() +{ + register int size, nfiles; + register char *cp; + + ack(); + nfiles = 0; + for (;;) { + /* + * Read a command to tell us what to do + */ + cp = line; + do { + if ((size = read(1, cp, 1)) != 1) { + if (size < 0) + frecverr("%s: Lost connection",printer); + return(nfiles); + } + } while (*cp++ != '\n'); + *--cp = '\0'; + cp = line; + switch (*cp++) { + case '\1': /* cleanup because data sent was bad */ + rcleanup(0); + continue; + + case '\2': /* read cf file */ + size = 0; + while (*cp >= '0' && *cp <= '9') + size = size * 10 + (*cp++ - '0'); + if (*cp++ != ' ') + break; + /* + * host name has been authenticated, we use our + * view of the host name since we may be passed + * something different than what gethostbyaddr() + * returns + */ + strcpy(cp + 6, from); + strcpy(tfname, cp); + tfname[0] = 't'; + if (!chksize(size)) { + (void) write(1, "\2", 1); + continue; + } + if (!readfile(tfname, size)) { + rcleanup(0); + continue; + } + if (link(tfname, cp) < 0) + frecverr("%s: %m", tfname); + (void) unlink(tfname); + tfname[0] = '\0'; + nfiles++; + continue; + + case '\3': /* read df file */ + size = 0; + while (*cp >= '0' && *cp <= '9') + size = size * 10 + (*cp++ - '0'); + if (*cp++ != ' ') + break; + if (!chksize(size)) { + (void) write(1, "\2", 1); + continue; + } + (void) strcpy(dfname, cp); + if (index(dfname, '/')) + frecverr("readjob: %s: illegal path name", + dfname); + (void) readfile(dfname, size); + continue; + } + frecverr("protocol screwup: %s", line); + } +} + +/* + * Read files send by lpd and copy them to the spooling directory. + */ +static int +readfile(file, size) + char *file; + int size; +{ + register char *cp; + char buf[BUFSIZ]; + register int i, j, amt; + int fd, err; + + fd = open(file, O_CREAT|O_EXCL|O_WRONLY, FILMOD); + if (fd < 0) + frecverr("readfile: %s: illegal path name: %m", file); + ack(); + err = 0; + for (i = 0; i < size; i += BUFSIZ) { + amt = BUFSIZ; + cp = buf; + if (i + amt > size) + amt = size - i; + do { + j = read(1, cp, amt); + if (j <= 0) + frecverr("Lost connection"); + amt -= j; + cp += j; + } while (amt > 0); + amt = BUFSIZ; + if (i + amt > size) + amt = size - i; + if (write(fd, buf, amt) != amt) { + err++; + break; + } + } + (void) close(fd); + if (err) + frecverr("%s: write error", file); + if (noresponse()) { /* file sent had bad data in it */ + (void) unlink(file); + return(0); + } + ack(); + return(1); +} + +static int +noresponse() +{ + char resp; + + if (read(1, &resp, 1) != 1) + frecverr("Lost connection"); + if (resp == '\0') + return(0); + return(1); +} + +/* + * Check to see if there is enough space on the disk for size bytes. + * 1 == OK, 0 == Not OK. + */ +static int +chksize(size) + int size; +{ + int spacefree; + struct statfs sfb; + + if (statfs(".", &sfb) < 0) { + syslog(LOG_ERR, "%s: %m", "statfs(\".\")"); + return (1); + } + spacefree = sfb.f_bavail * (sfb.f_bsize / 512); + size = (size + 511) / 512; + if (minfree + size > spacefree) + return(0); + return(1); +} + +static int +read_number(fn) + char *fn; +{ + char lin[80]; + register FILE *fp; + + if ((fp = fopen(fn, "r")) == NULL) + return (0); + if (fgets(lin, 80, fp) == NULL) { + fclose(fp); + return (0); + } + fclose(fp); + return (atoi(lin)); +} + +/* + * Remove all the files associated with the current job being transfered. + */ +static void +rcleanup(signo) + int signo; +{ + if (tfname[0]) + (void) unlink(tfname); + if (dfname[0]) + do { + do + (void) unlink(dfname); + while (dfname[2]-- != 'A'); + dfname[2] = 'z'; + } while (dfname[0]-- != 'd'); + dfname[0] = '\0'; +} + +#if __STDC__ +#include +#else +#include +#endif + +static void +#if __STDC__ +frecverr(const char *msg, ...) +#else +frecverr(msg, va_alist) + char *msg; + va_dcl +#endif +{ + extern char *fromb; + va_list ap; +#if __STDC__ + va_start(ap, msg); +#else + va_start(ap); +#endif + rcleanup(0); + syslog(LOG_ERR, "%s", fromb); + vsyslog(LOG_ERR, msg, ap); + va_end(ap); + putchar('\1'); /* return error code */ + exit(1); +} diff --git a/usr.sbin/lpr/lpq/Makefile b/usr.sbin/lpr/lpq/Makefile new file mode 100644 index 0000000..1c730c1 --- /dev/null +++ b/usr.sbin/lpr/lpq/Makefile @@ -0,0 +1,12 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= lpq +CFLAGS+=-I${.CURDIR}/../common_source +SRCS= lpq.c displayq.c common.c +BINOWN= root +BINGRP= daemon +BINMODE=6555 +BINDIR= /usr/bin +.PATH: ${.CURDIR}/../common_source + +.include diff --git a/usr.sbin/lpr/lpq/lpq.1 b/usr.sbin/lpr/lpq/lpq.1 new file mode 100644 index 0000000..50e1474 --- /dev/null +++ b/usr.sbin/lpr/lpq/lpq.1 @@ -0,0 +1,134 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" @(#)lpq.1 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt LPQ 1 +.Os BSD 4.2 +.Sh NAME +.Nm lpq +.Nd spool queue examination program +.Sh SYNOPSIS +.Nm lpq +.Op Fl l +.Op Fl P Ns Ar printer +.Op job # ... +.Op user ... +.Sh DESCRIPTION +.Nm Lpq +examines the spooling area used by +.Xr lpd 8 +for printing files on the line printer, and reports the status of the +specified jobs or all jobs associated with a user. +.Nm Lpq +invoked +without any arguments reports on any jobs currently in the queue. +.Pp +Options: +.Pp +.Bl -tag -width indent +.It Fl P +Specify a particular printer, otherwise the default +line printer is used (or the value of the +.Ev PRINTER +variable in the +environment). All other arguments supplied are interpreted as user +names or job numbers to filter out only those jobs of interest. +.It Fl l +Information about each of the files comprising the job entry +is printed. +Normally, only as much information as will fit on one line is displayed. +.El +.Pp +For each job submitted (i.e. invocation of +.Xr lpr 1 ) +.Nm lpq +reports the user's name, current rank in the queue, the +names of files comprising the job, the job identifier (a number which +may be supplied to +.Xr lprm 1 +for removing a specific job), and the total size in bytes. +Job ordering is dependent on +the algorithm used to scan the spooling directory and is supposed +to be +.Tn FIFO +(First in First Out). +File names comprising a job may be unavailable +(when +.Xr lpr 1 +is used as a sink in a pipeline) in which case the file +is indicated as ``(standard input)''. +.Pp +If +.Nm lpq +warns that there is no daemon present (i.e. due to some malfunction), +the +.Xr lpc 8 +command can be used to restart the printer daemon. +.Sh ENVIRONMENT +If the following environment variable exists, it is used by +.Nm lpq : +.Bl -tag -width PRINTER +.It Ev PRINTER +Specifies an alternate default printer. +.El +.Sh FILES +.Bl -tag -width /usr/share/misc/termcap -compact +.It Pa /etc/printcap +To determine printer characteristics. +.It Pa /var/spool/* +The spooling directory, as determined from printcap. +.It Pa /var/spool/*/cf* +Control files specifying jobs. +.It Pa /var/spool/*/lock +The lock file to obtain the currently active job. +.It Pa /usr/share/misc/termcap +For manipulating the screen for repeated display. +.El +.Sh SEE ALSO +.Xr lpr 1 , +.Xr lprm 1 , +.Xr lpc 8 , +.Xr lpd 8 +.Sh HISTORY +.Nm Lpq +appeared in +.Bx 3 . +.Sh BUGS +Due to the dynamic nature of the information in the spooling directory +.Nm lpq +may report unreliably. +Output formatting is sensitive to the line length of the terminal; +this can results in widely spaced columns. +.Sh DIAGNOSTICS +Unable to open various files. The lock file being malformed. Garbage +files when there is no daemon active, but files in the spooling directory. diff --git a/usr.sbin/lpr/lpq/lpq.c b/usr.sbin/lpr/lpq/lpq.c new file mode 100644 index 0000000..b091e8e --- /dev/null +++ b/usr.sbin/lpr/lpq/lpq.c @@ -0,0 +1,126 @@ +/* + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)lpq.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Spool Queue examination program + * + * lpq [-l] [-Pprinter] [user...] [job...] + * + * -l long output + * -P used to identify printer as per lpr/lprm + */ + +#include + +#include +#include +#include +#include +#include +#include +#include "lp.h" +#include "lp.local.h" + +int requ[MAXREQUESTS]; /* job number of spool entries */ +int requests; /* # of spool requests */ +char *user[MAXUSERS]; /* users to process */ +int users; /* # of users in user array */ + +void usage __P((void)); + +int +main(argc, argv) + register int argc; + register char **argv; +{ + extern char *optarg; + extern int optind; + int ch, lflag; /* long output option */ + + name = *argv; + if (gethostname(host, sizeof(host))) { + perror("lpq: gethostname"); + exit(1); + } + openlog("lpd", 0, LOG_LPR); + + lflag = 0; + while ((ch = getopt(argc, argv, "lP:")) != EOF) + switch((char)ch) { + case 'l': /* long output */ + ++lflag; + break; + case 'P': /* printer name */ + printer = optarg; + break; + case '?': + default: + usage(); + } + + if (printer == NULL && (printer = getenv("PRINTER")) == NULL) + printer = DEFLP; + + for (argc -= optind, argv += optind; argc; --argc, ++argv) + if (isdigit(argv[0][0])) { + if (requests >= MAXREQUESTS) + fatal("too many requests"); + requ[requests++] = atoi(*argv); + } + else { + if (users >= MAXUSERS) + fatal("too many users"); + user[users++] = *argv; + } + + displayq(lflag); + exit(0); +} + +void +usage() +{ + puts("usage: lpq [-l] [-Pprinter] [user ...] [job ...]"); + exit(1); +} diff --git a/usr.sbin/lpr/lpr/Makefile b/usr.sbin/lpr/lpr/Makefile new file mode 100644 index 0000000..9a3cbfd --- /dev/null +++ b/usr.sbin/lpr/lpr/Makefile @@ -0,0 +1,12 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= lpr +CFLAGS+=-I${.CURDIR}/../common_source +SRCS= lpr.c startdaemon.c common.c +BINOWN= root +BINGRP= daemon +BINMODE=6555 +BINDIR= /usr/bin +.PATH: ${.CURDIR}/../common_source + +.include diff --git a/usr.sbin/lpr/lpr/lpr.1 b/usr.sbin/lpr/lpr/lpr.1 new file mode 100644 index 0000000..382d508 --- /dev/null +++ b/usr.sbin/lpr/lpr/lpr.1 @@ -0,0 +1,256 @@ +.\" Copyright (c) 1980, 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. +.\" +.\" @(#)lpr.1 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt LPR 1 +.Os BSD 4 +.Sh NAME +.Nm lpr +.Nd off line print +.Sh SYNOPSIS +.Nm lpr +.Op Fl P Ns Ar printer +.Op Fl \&# Ns Ar num +.Op Fl C Ar class +.Op Fl J Ar job +.Op Fl T Ar title +.Op Fl U Ar user +.Op Fl i Op Ar numcols +.Op Fl 1234 Ar font +.Op Fl w Ns Ar num +.Op Fl cdfghlnmprstv +.Op Ar name ... +.Sh DESCRIPTION +.Nm Lpr +uses a spooling daemon to print the named files when facilities +become available. If no names appear, the standard input is assumed. +.Pp +The following single letter options are used to notify the line printer +spooler that the files are not standard text files. The spooling daemon will +use the appropriate filters to print the data accordingly. +.Bl -tag -width indent +.It Fl c +The files are assumed to contain data produced by +.Xr cifplot 1 +.It Fl d +The files are assumed to contain data from +.Em tex +.Pf ( Tn DVI +format from Stanford). +.It Fl f +Use a filter which interprets the first character of each line as a +standard +.Tn FORTRAN +carriage control character. +.It Fl g +The files are assumed to contain standard plot data as produced by the +.Xr plot +routines (see also +.Xr plot +for the filters used by the printer spooler). +.It Fl l +Use a filter which allows control characters to be printed and suppresses +page breaks. +.It Fl n +The files are assumed to contain data from +.Em ditroff +(device independent troff). +.It Fl p +Use +.Xr pr 1 +to format the files (equivalent to +.Xr print ) . +.It Fl t +The files are assumed to contain data from +.Xr troff 1 +(cat phototypesetter commands). +.It Fl v +The files are assumed to contain a raster image for devices like the +Benson Varian. +.El +.Pp +These options apply to the handling of +the print job: +.Bl -tag -width indent +.It Fl P +Force output to a specific printer. Normally, +the default printer is used (site dependent), or the value of the +environment variable +.Ev PRINTER +is used. +.It Fl h +Suppress the printing of the burst page. +.It Fl m +Send mail upon completion. +.It Fl r +Remove the file upon completion of spooling or upon completion of +printing (with the +.Fl s +option). +.It Fl s +Use symbolic links. Usually files are copied to the spool directory. +The +.Fl s +option will use +.Xr symlink 2 +to link data files rather than trying to copy them so large files can be +printed. This means the files should +not be modified or removed until they have been printed. +.El +.Pp +The remaining options apply to copies, the page display, and headers: +.Bl -tag -width indent +.It Fl \&# Ns Ar num +The quantity +.Ar num +is the number of copies desired of each file named. For example, +.Bd -literal -offset indent +lpr \-#3 foo.c bar.c more.c +.Ed +would result in 3 copies of the file foo.c, followed by 3 copies +of the file bar.c, etc. On the other hand, +.Bd -literal -offset indent +cat foo.c bar.c more.c \&| lpr \-#3 +.Ed +.Pp +will give three copies of the concatenation of the files. Often +a site will disable this feature to encourage use of a photocopier +instead. +.It Xo +.Fl Ns Oo Cm 1234 Oc Ar font +.Xc +Specifies a +.Ar font +to be mounted on font position +.Ar i . +The daemon +will construct a +.Li .railmag +file referencing +the font pathname. +.It Fl C Ar class +Job classification +to use on the burst page. For example, +.Bd -literal -offset indent +lpr \-C EECS foo.c +.Ed +.Pp +causes the system name (the name returned by +.Xr hostname 1 ) +to be replaced on the burst page by +.Tn EECS , +and the file foo.c to be printed. +.It Fl J Ar job +Job name to print on the burst page. +Normally, the first file's name is used. +.It Fl T Ar title +Title name for +.Xr pr 1 , +instead of the file name. +.It Fl U Ar user +User name to print on the burst page, +also for accounting purposes. +This option is only honored if the real user-id is daemon +(or that specified in the printcap file instead of daemon), +and is intended for those instances where print filters wish to requeue jobs. +.It Fl i Op numcols +The output is indented. If the next argument +is numeric +.Pq Ar numcols , +it is used as the number of blanks to be printed before each +line; otherwise, 8 characters are printed. +.It Fl w Ns Ar num +Uses +.Ar num +as the page width for +.Xr pr 1 . +.El +.Sh ENVIRONMENT +If the following environment variable exists, it is used by +.Nm lpr : +.Bl -tag -width PRINTER +.It Ev PRINTER +Specifies an alternate default printer. +.El +.Sh FILES +.Bl -tag -width /var/spool/output/*/tf* -compact +.It Pa /etc/passwd +Personal identification. +.It Pa /etc/printcap +Printer capabilities data base. +.It Pa /usr/sbin/lpd* +Line printer daemons. +.It Pa /var/spool/output/* +Directories used for spooling. +.It Pa /var/spool/output/*/cf* +Daemon control files. +.It Pa /var/spool/output/*/df* +Data files specified in "cf" files. +.It Pa /var/spool/output/*/tf* +Temporary copies of "cf" files. +.El +.Sh SEE ALSO +.Xr lpq 1 , +.Xr lprm 1 , +.Xr pr 1 , +.Xr symlink 2 , +.Xr printcap 5 , +.Xr lpc 8 , +.Xr lpd 8 +.Sh HISTORY +The +.Nm lpr +command appeared in +.Bx 3 . +.Sh DIAGNOSTICS +If you try to spool too large a file, it will be truncated. +.Nm Lpr +will object to printing binary files. +If a user other than root prints a file and spooling is disabled, +.Nm lpr +will print a message saying so and will not put jobs in the queue. +If a connection to +.Xr lpd 1 +on the local machine cannot be made, +.Nm lpr +will say that the daemon cannot be started. +Diagnostics may be printed in the daemon's log file +regarding missing spool files by +.Xr lpd 1 . +.Sh BUGS +Fonts for +.Xr troff 1 +and +.Xr tex +reside on the host with the printer. It is currently not possible to +use local font libraries. diff --git a/usr.sbin/lpr/lpr/lpr.c b/usr.sbin/lpr/lpr/lpr.c new file mode 100644 index 0000000..8e9c45f --- /dev/null +++ b/usr.sbin/lpr/lpr/lpr.c @@ -0,0 +1,744 @@ +/* + * Copyright (c) 1983, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * + * 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) 1983, 1989, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)lpr.c 8.3 (Berkeley) 3/30/94"; +#endif /* not lint */ + +/* + * lpr -- off line print + * + * Allows multiple printers and printers on remote machines by + * using information from a printer data base. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lp.h" +#include "lp.local.h" +#include "pathnames.h" + +static char *cfname; /* daemon control files, linked from tf's */ +static char *class = host; /* class title on header page */ +static char *dfname; /* data files */ +static char *fonts[4]; /* troff font names */ +static char format = 'f'; /* format char for printing files */ +static int hdr = 1; /* print header or not (default is yes) */ +static int iflag; /* indentation wanted */ +static int inchar; /* location to increment char in file names */ +static int indent; /* amount to indent */ +static char *jobname; /* job name on header page */ +static int mailflg; /* send mail */ +static int nact; /* number of jobs to act on */ +static int ncopies = 1; /* # of copies to make */ +static char *person; /* user name */ +static int qflag; /* q job, but don't exec daemon */ +static int rflag; /* remove files upon completion */ +static int sflag; /* symbolic link flag */ +static int tfd; /* control file descriptor */ +static char *tfname; /* tmp copy of cf before linking */ +static char *title; /* pr'ing title */ +static int userid; /* user id */ +static char *width; /* width for versatec printing */ + +static struct stat statb; + +static void card __P((int, char *)); +static void chkprinter __P((char *)); +static void cleanup __P((int)); +static void copy __P((int, char [])); +static void fatal2 __P((const char *, ...)); +static char *itoa __P((int)); +static char *linked __P((char *)); +static char *lmktemp __P((char *, int, int)); +static void mktemps __P((void)); +static int nfile __P((char *)); +static int test __P((char *)); + +void +main(argc, argv) + int argc; + char *argv[]; +{ + struct passwd *pw; + struct group *gptr; + extern char *itoa(); + register char *arg, *cp; + char buf[BUFSIZ]; + int i, f; + struct stat stb; + + if (signal(SIGHUP, SIG_IGN) != SIG_IGN) + signal(SIGHUP, cleanup); + if (signal(SIGINT, SIG_IGN) != SIG_IGN) + signal(SIGINT, cleanup); + if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) + signal(SIGQUIT, cleanup); + if (signal(SIGTERM, SIG_IGN) != SIG_IGN) + signal(SIGTERM, cleanup); + + name = argv[0]; + gethostname(host, sizeof (host)); + openlog("lpd", 0, LOG_LPR); + + while (argc > 1 && argv[1][0] == '-') { + argc--; + arg = *++argv; + switch (arg[1]) { + + case 'P': /* specifiy printer name */ + if (arg[2]) + printer = &arg[2]; + else if (argc > 1) { + argc--; + printer = *++argv; + } + break; + + case 'C': /* classification spec */ + hdr++; + if (arg[2]) + class = &arg[2]; + else if (argc > 1) { + argc--; + class = *++argv; + } + break; + + case 'U': /* user name */ + hdr++; + if (arg[2]) + person = &arg[2]; + else if (argc > 1) { + argc--; + person = *++argv; + } + break; + + case 'J': /* job name */ + hdr++; + if (arg[2]) + jobname = &arg[2]; + else if (argc > 1) { + argc--; + jobname = *++argv; + } + break; + + case 'T': /* pr's title line */ + if (arg[2]) + title = &arg[2]; + else if (argc > 1) { + argc--; + title = *++argv; + } + break; + + case 'l': /* literal output */ + case 'p': /* print using ``pr'' */ + case 't': /* print troff output (cat files) */ + case 'n': /* print ditroff output */ + case 'd': /* print tex output (dvi files) */ + case 'g': /* print graph(1G) output */ + case 'c': /* print cifplot output */ + case 'v': /* print vplot output */ + format = arg[1]; + break; + + case 'f': /* print fortran output */ + format = 'r'; + break; + + case '4': /* troff fonts */ + case '3': + case '2': + case '1': + if (argc > 1) { + argc--; + fonts[arg[1] - '1'] = *++argv; + } + break; + + case 'w': /* versatec page width */ + width = arg+2; + break; + + case 'r': /* remove file when done */ + rflag++; + break; + + case 'm': /* send mail when done */ + mailflg++; + break; + + case 'h': /* toggle want of header page */ + hdr = !hdr; + break; + + case 's': /* try to link files */ + sflag++; + break; + + case 'q': /* just q job */ + qflag++; + break; + + case 'i': /* indent output */ + iflag++; + indent = arg[2] ? atoi(&arg[2]) : 8; + break; + + case '#': /* n copies */ + if (isdigit(arg[2])) { + i = atoi(&arg[2]); + if (i > 0) + ncopies = i; + } + } + } + if (printer == NULL && (printer = getenv("PRINTER")) == NULL) + printer = DEFLP; + chkprinter(printer); + if (SC && ncopies > 1) + fatal2("multiple copies are not allowed"); + if (MC > 0 && ncopies > MC) + fatal2("only %d copies are allowed", MC); + /* + * Get the identity of the person doing the lpr using the same + * algorithm as lprm. + */ + userid = getuid(); + if (userid != DU || person == 0) { + if ((pw = getpwuid(userid)) == NULL) + fatal2("Who are you?"); + person = pw->pw_name; + } + /* + * Check for restricted group access. + */ + if (RG != NULL && userid != DU) { + if ((gptr = getgrnam(RG)) == NULL) + fatal2("Restricted group specified incorrectly"); + if (gptr->gr_gid != getgid()) { + while (*gptr->gr_mem != NULL) { + if ((strcmp(person, *gptr->gr_mem)) == 0) + break; + gptr->gr_mem++; + } + if (*gptr->gr_mem == NULL) + fatal2("Not a member of the restricted group"); + } + } + /* + * Check to make sure queuing is enabled if userid is not root. + */ + (void) sprintf(buf, "%s/%s", SD, LO); + if (userid && stat(buf, &stb) == 0 && (stb.st_mode & 010)) + fatal2("Printer queue is disabled"); + /* + * Initialize the control file. + */ + mktemps(); + tfd = nfile(tfname); + (void) fchown(tfd, DU, -1); /* owned by daemon for protection */ + card('H', host); + card('P', person); + if (hdr) { + if (jobname == NULL) { + if (argc == 1) + jobname = "stdin"; + else + jobname = (arg = rindex(argv[1], '/')) ? arg+1 : argv[1]; + } + card('J', jobname); + card('C', class); + card('L', person); + } + if (iflag) + card('I', itoa(indent)); + if (mailflg) + card('M', person); + if (format == 't' || format == 'n' || format == 'd') + for (i = 0; i < 4; i++) + if (fonts[i] != NULL) + card('1'+i, fonts[i]); + if (width != NULL) + card('W', width); + + /* + * Read the files and spool them. + */ + if (argc == 1) + copy(0, " "); + else while (--argc) { + if ((f = test(arg = *++argv)) < 0) + continue; /* file unreasonable */ + + if (sflag && (cp = linked(arg)) != NULL) { + (void) sprintf(buf, "%d %d", statb.st_dev, statb.st_ino); + card('S', buf); + if (format == 'p') + card('T', title ? title : arg); + for (i = 0; i < ncopies; i++) + card(format, &dfname[inchar-2]); + card('U', &dfname[inchar-2]); + if (f) + card('U', cp); + card('N', arg); + dfname[inchar]++; + nact++; + continue; + } + if (sflag) + printf("%s: %s: not linked, copying instead\n", name, arg); + if ((i = open(arg, O_RDONLY)) < 0) { + printf("%s: cannot open %s\n", name, arg); + continue; + } + copy(i, arg); + (void) close(i); + if (f && unlink(arg) < 0) + printf("%s: %s: not removed\n", name, arg); + } + + if (nact) { + (void) close(tfd); + tfname[inchar]--; + /* + * Touch the control file to fix position in the queue. + */ + if ((tfd = open(tfname, O_RDWR)) >= 0) { + char c; + + if (read(tfd, &c, 1) == 1 && + lseek(tfd, (off_t)0, 0) == 0 && + write(tfd, &c, 1) != 1) { + printf("%s: cannot touch %s\n", name, tfname); + tfname[inchar]++; + cleanup(0); + } + (void) close(tfd); + } + if (link(tfname, cfname) < 0) { + printf("%s: cannot rename %s\n", name, cfname); + tfname[inchar]++; + cleanup(0); + } + unlink(tfname); + if (qflag) /* just q things up */ + exit(0); + if (!startdaemon(printer)) + printf("jobs queued, but cannot start daemon.\n"); + exit(0); + } + cleanup(0); + /* NOTREACHED */ +} + +/* + * Create the file n and copy from file descriptor f. + */ +static void +copy(f, n) + int f; + char n[]; +{ + register int fd, i, nr, nc; + char buf[BUFSIZ]; + + if (format == 'p') + card('T', title ? title : n); + for (i = 0; i < ncopies; i++) + card(format, &dfname[inchar-2]); + card('U', &dfname[inchar-2]); + card('N', n); + fd = nfile(dfname); + nr = nc = 0; + while ((i = read(f, buf, BUFSIZ)) > 0) { + if (write(fd, buf, i) != i) { + printf("%s: %s: temp file write error\n", name, n); + break; + } + nc += i; + if (nc >= BUFSIZ) { + nc -= BUFSIZ; + nr++; + if (MX > 0 && nr > MX) { + printf("%s: %s: copy file is too large\n", name, n); + break; + } + } + } + (void) close(fd); + if (nc==0 && nr==0) + printf("%s: %s: empty input file\n", name, f ? n : "stdin"); + else + nact++; +} + +/* + * Try and link the file to dfname. Return a pointer to the full + * path name if successful. + */ +static char * +linked(file) + register char *file; +{ + register char *cp; + static char buf[BUFSIZ]; + + if (*file != '/') { + if (getwd(buf) == NULL) + return(NULL); + while (file[0] == '.') { + switch (file[1]) { + case '/': + file += 2; + continue; + case '.': + if (file[2] == '/') { + if ((cp = rindex(buf, '/')) != NULL) + *cp = '\0'; + file += 3; + continue; + } + } + break; + } + strcat(buf, "/"); + strcat(buf, file); + file = buf; + } + return(symlink(file, dfname) ? NULL : file); +} + +/* + * Put a line into the control file. + */ +static void +card(c, p2) + register int c; + register char *p2; +{ + char buf[BUFSIZ]; + register char *p1 = buf; + register int len = 2; + + *p1++ = c; + while ((c = *p2++) != '\0') { + *p1++ = (c == '\n') ? ' ' : c; + len++; + } + *p1++ = '\n'; + write(tfd, buf, len); +} + +/* + * Create a new file in the spool directory. + */ +static int +nfile(n) + char *n; +{ + register int f; + int oldumask = umask(0); /* should block signals */ + + f = open(n, O_WRONLY | O_EXCL | O_CREAT, FILMOD); + (void) umask(oldumask); + if (f < 0) { + printf("%s: cannot create %s\n", name, n); + cleanup(0); + } + if (fchown(f, userid, -1) < 0) { + printf("%s: cannot chown %s\n", name, n); + cleanup(0); + } + if (++n[inchar] > 'z') { + if (++n[inchar-2] == 't') { + printf("too many files - break up the job\n"); + cleanup(0); + } + n[inchar] = 'A'; + } else if (n[inchar] == '[') + n[inchar] = 'a'; + return(f); +} + +/* + * Cleanup after interrupts and errors. + */ +static void +cleanup(signo) + int signo; +{ + register i; + + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + signal(SIGTERM, SIG_IGN); + i = inchar; + if (tfname) + do + unlink(tfname); + while (tfname[i]-- != 'A'); + if (cfname) + do + unlink(cfname); + while (cfname[i]-- != 'A'); + if (dfname) + do { + do + unlink(dfname); + while (dfname[i]-- != 'A'); + dfname[i] = 'z'; + } while (dfname[i-2]-- != 'd'); + exit(1); +} + +/* + * Test to see if this is a printable file. + * Return -1 if it is not, 0 if its printable, and 1 if + * we should remove it after printing. + */ +static int +test(file) + char *file; +{ + struct exec execb; + register int fd; + register char *cp; + + if (access(file, 4) < 0) { + printf("%s: cannot access %s\n", name, file); + return(-1); + } + if (stat(file, &statb) < 0) { + printf("%s: cannot stat %s\n", name, file); + return(-1); + } + if ((statb.st_mode & S_IFMT) == S_IFDIR) { + printf("%s: %s is a directory\n", name, file); + return(-1); + } + if (statb.st_size == 0) { + printf("%s: %s is an empty file\n", name, file); + return(-1); + } + if ((fd = open(file, O_RDONLY)) < 0) { + printf("%s: cannot open %s\n", name, file); + return(-1); + } + if (read(fd, &execb, sizeof(execb)) == sizeof(execb) && + !N_BADMAG(execb)) { + printf("%s: %s is an executable program", name, file); + goto error1; + } + (void) close(fd); + if (rflag) { + if ((cp = rindex(file, '/')) == NULL) { + if (access(".", 2) == 0) + return(1); + } else { + if (cp == file) { + fd = access("/", 2); + } else { + *cp = '\0'; + fd = access(file, 2); + *cp = '/'; + } + if (fd == 0) + return(1); + } + printf("%s: %s: is not removable by you\n", name, file); + } + return(0); + +error1: + printf(" and is unprintable\n"); + (void) close(fd); + return(-1); +} + +/* + * itoa - integer to string conversion + */ +static char * +itoa(i) + register int i; +{ + static char b[10] = "########"; + register char *p; + + p = &b[8]; + do + *p-- = i%10 + '0'; + while (i /= 10); + return(++p); +} + +/* + * Perform lookup for printer name or abbreviation -- + */ +static void +chkprinter(s) + char *s; +{ + int status; + + if ((status = cgetent(&bp, printcapdb, s)) == -2) + fatal2("cannot open printer description file"); + else if (status == -1) + fatal2("%s: unknown printer", s); + if (cgetstr(bp, "sd", &SD) == -1) + SD = _PATH_DEFSPOOL; + if (cgetstr(bp, "lo", &LO) == -1) + LO = DEFLOCK; + cgetstr(bp, "rg", &RG); + if (cgetnum(bp, "mx", &MX) < 0) + MX = DEFMX; + if (cgetnum(bp,"mc", &MC) < 0) + MC = DEFMAXCOPIES; + if (cgetnum(bp, "du", &DU) < 0) + DU = DEFUID; + SC = (cgetcap(bp, "sc", ':') != NULL); +} + +/* + * Make the temp files. + */ +static void +mktemps() +{ + register int len, fd, n; + register char *cp; + char buf[BUFSIZ]; + char *lmktemp(); + + (void) sprintf(buf, "%s/.seq", SD); + if ((fd = open(buf, O_RDWR|O_CREAT, 0661)) < 0) { + printf("%s: cannot create %s\n", name, buf); + exit(1); + } + if (flock(fd, LOCK_EX)) { + printf("%s: cannot lock %s\n", name, buf); + exit(1); + } + n = 0; + if ((len = read(fd, buf, sizeof(buf))) > 0) { + for (cp = buf; len--; ) { + if (*cp < '0' || *cp > '9') + break; + n = n * 10 + (*cp++ - '0'); + } + } + len = strlen(SD) + strlen(host) + 8; + tfname = lmktemp("tf", n, len); + cfname = lmktemp("cf", n, len); + dfname = lmktemp("df", n, len); + inchar = strlen(SD) + 3; + n = (n + 1) % 1000; + (void) lseek(fd, (off_t)0, 0); + sprintf(buf, "%03d\n", n); + (void) write(fd, buf, strlen(buf)); + (void) close(fd); /* unlocks as well */ +} + +/* + * Make a temp file name. + */ +static char * +lmktemp(id, num, len) + char *id; + int num, len; +{ + register char *s; + + if ((s = malloc(len)) == NULL) + fatal2("out of memory"); + (void) sprintf(s, "%s/%sA%03d%s", SD, id, num, host); + return(s); +} + +#if __STDC__ +#include +#else +#include +#endif + +static void +#if __STDC__ +fatal2(const char *msg, ...) +#else +fatal2(msg, va_alist) + char *msg; + va_dcl +#endif +{ + va_list ap; +#if __STDC__ + va_start(ap, msg); +#else + va_start(ap); +#endif + printf("%s: ", name); + vprintf(msg, ap); + putchar('\n'); + va_end(ap); + exit(1); +} diff --git a/usr.sbin/lpr/lprm/Makefile b/usr.sbin/lpr/lprm/Makefile new file mode 100644 index 0000000..d1362f5 --- /dev/null +++ b/usr.sbin/lpr/lprm/Makefile @@ -0,0 +1,12 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= lprm +CFLAGS+=-I${.CURDIR}/../common_source +SRCS= lprm.c rmjob.c startdaemon.c common.c +BINOWN= root +BINGRP= daemon +BINMODE=6555 +BINDIR= /usr/bin +.PATH: ${.CURDIR}/../common_source + +.include diff --git a/usr.sbin/lpr/lprm/lprm.1 b/usr.sbin/lpr/lprm/lprm.1 new file mode 100644 index 0000000..22309d1 --- /dev/null +++ b/usr.sbin/lpr/lprm/lprm.1 @@ -0,0 +1,145 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" @(#)lprm.1 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt LPRM 1 +.Os BSD 4.2 +.Sh NAME +.Nm lprm +.Nd remove jobs from the line printer spooling queue +.Sh SYNOPSIS +.Nm lprm +.Op Fl P Ns Ar printer +.Op Fl +.Op job # ... +.Op Ar user ... +.Sh DESCRIPTION +.Nm Lprm +will remove a job, or jobs, from a printer's spool queue. +Since the spooling directory is protected from users, using +.Nm lprm +is normally the only method by which a user may remove a job. +The owner of a job is determined by the user's login name +and host name on the machine where the +.Xr lpr 1 +command was invoked. +.Pp +Options and arguments: +.Bl -tag -width indent +.It Fl P Ns Ar printer +Specify the queue associated with a specific +.Ar printer +(otherwise the default printer is used). +.It Fl +If a single +.Sq Fl +is given, +.Nm lprm +will remove all jobs which a user +owns. If the super-user employs this flag, the spool queue will +be emptied entirely. +.It Ar user +Causes +.Nm lprm +to attempt to remove any jobs queued belonging to that user +(or users). This form of invoking +.Nm lprm +is useful only to the super-user. +.It Ar job\ \&# +A user may dequeue an individual job by specifying its job number. +This number may be obtained from the +.Xr lpq 1 +program, e.g. +.Pp +.Bd -literal -offset indent +\&% lpq \-l + +1st:ken [job #013ucbarpa] + (standard input) 100 bytes +% lprm 13 +.Ed +.El +.Pp +If neither arguments or options are given, +.Nm Lprm +will delete the currently active job if it is +owned by the user who invoked +.Nm lprm . +.Pp +.Nm Lprm +announces the names of any files it removes and is silent if +there are no jobs in the queue which match the request list. +.Pp +.Nm Lprm +will kill off an active daemon, if necessary, before removing +any spooling files. If a daemon is killed, a new one is +automatically restarted upon completion of file removals. +.Sh ENVIRONMENT +If the following environment variable exists, it is utilized by +.Nm lprm . +.Bl -tag -width PRINTER +.It Ev PRINTER +If the environment variable +.Ev PRINTER +exists, +and a printer has not been specified with the +.Fl P +option, +the default printer is assumed from +.Ev PRINTER . +.El +.Sh FILES +.Bl -tag -width /var/spool/*/lock/ -compact +.It Pa /etc/printcap +Printer characteristics file. +.It Pa /var/spool/* +Spooling directories. +.It Pa /var/spool/*/lock +Lock file used to obtain the pid of the current +daemon and the job number of the currently active job. +.El +.Sh SEE ALSO +.Xr lpr 1 , +.Xr lpq 1 , +.Xr lpd 8 +.Sh DIAGNOSTICS +``Permission denied" if the user tries to remove files other than his +own. +.Sh BUGS +Since there are race conditions possible in the update of the lock file, +the currently active job may be incorrectly identified. +.Sh HISTORY +The +.Nm lprm +command appeared in +.Bx 3.0 . diff --git a/usr.sbin/lpr/lprm/lprm.c b/usr.sbin/lpr/lprm/lprm.c new file mode 100644 index 0000000..20c4ee7 --- /dev/null +++ b/usr.sbin/lpr/lprm/lprm.c @@ -0,0 +1,144 @@ +/* + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)lprm.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * lprm - remove the current user's spool entry + * + * lprm [-] [[job #] [user] ...] + * + * Using information in the lock file, lprm will kill the + * currently active daemon (if necessary), remove the associated files, + * and startup a new daemon. Priviledged users may remove anyone's spool + * entries, otherwise one can only remove their own. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "lp.h" +#include "lp.local.h" + +/* + * Stuff for handling job specifications + */ +char *person; /* name of person doing lprm */ +int requ[MAXREQUESTS]; /* job number of spool entries */ +int requests; /* # of spool requests */ +char *user[MAXUSERS]; /* users to process */ +int users; /* # of users in user array */ + +static char luser[16]; /* buffer for person */ + +void usage __P((void)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + register char *arg; + struct passwd *p; + + name = argv[0]; + gethostname(host, sizeof(host)); + openlog("lpd", 0, LOG_LPR); + if ((p = getpwuid(getuid())) == NULL) + fatal("Who are you?"); + if (strlen(p->pw_name) >= sizeof(luser)) + fatal("Your name is too long"); + strcpy(luser, p->pw_name); + person = luser; + while (--argc) { + if ((arg = *++argv)[0] == '-') + switch (arg[1]) { + case 'P': + if (arg[2]) + printer = &arg[2]; + else if (argc > 1) { + argc--; + printer = *++argv; + } + break; + case '\0': + if (!users) { + users = -1; + break; + } + default: + usage(); + } + else { + if (users < 0) + usage(); + if (isdigit(arg[0])) { + if (requests >= MAXREQUESTS) + fatal("Too many requests"); + requ[requests++] = atoi(arg); + } else { + if (users >= MAXUSERS) + fatal("Too many users"); + user[users++] = arg; + } + } + } + if (printer == NULL && (printer = getenv("PRINTER")) == NULL) + printer = DEFLP; + + rmjob(); + exit(0); +} + +void +usage() +{ + fprintf(stderr, "usage: lprm [-] [-Pprinter] [[job #] [user] ...]\n"); + exit(2); +} diff --git a/usr.sbin/lpr/lptest/Makefile b/usr.sbin/lpr/lptest/Makefile new file mode 100644 index 0000000..6ff8e7f --- /dev/null +++ b/usr.sbin/lpr/lptest/Makefile @@ -0,0 +1,6 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= lptest + +.include "../../Makefile.inc" +.include diff --git a/usr.sbin/lpr/lptest/lptest.1 b/usr.sbin/lpr/lptest/lptest.1 new file mode 100644 index 0000000..95b28f3 --- /dev/null +++ b/usr.sbin/lpr/lptest/lptest.1 @@ -0,0 +1,74 @@ +.\" 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. +.\" +.\" @(#)lptest.1 8.2 (Berkeley) 12/30/93 +.\" +.Dd December 30, 1993 +.Dt LPTEST 1 +.Os BSD 4.3 +.Sh NAME +.Nm lptest +.Nd generate lineprinter ripple pattern +.Sh SYNOPSIS +.Nm lptest +.Op Ar length +.Op Ar count +.Sh DESCRIPTION +.Nm Lptest +writes the traditional "ripple test" pattern on standard output. +In 96 lines, +this pattern will print all 96 printable +.Tn ASCII +characters +in each position. +While originally created to test printers, it is quite +useful for testing terminals, +driving terminal ports for debugging purposes, +or any other task where a quick supply of random data is needed. +.Pp +The +.Ar length +argument specifies the output line length if the default +length of 79 is inappropriate. +.Pp +The +.Ar count +argument specifies the number of output lines to be generated if +the default count of 200 is inappropriate. +Note that if +.Ar count +is to be specified, +.Ar length +must be also be specified. +.Sh HISTORY +.Nm Lptest +appeared in +.Bx 4.3 . diff --git a/usr.sbin/lpr/lptest/lptest.c b/usr.sbin/lpr/lptest/lptest.c new file mode 100644 index 0000000..5ce80b5 --- /dev/null +++ b/usr.sbin/lpr/lptest/lptest.c @@ -0,0 +1,83 @@ +/* + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)lptest.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include + +/* + * lptest -- line printer test program (and other devices). + */ +void +main(argc, argv) + int argc; + char **argv; +{ + int len, count; + register i, j, fc, nc; + char outbuf[BUFSIZ]; + + setbuf(stdout, outbuf); + if (argc >= 2) + len = atoi(argv[1]); + else + len = 79; + if (argc >= 3) + count = atoi(argv[2]); + else + count = 200; + fc = ' '; + for (i = 0; i < count; i++) { + if (++fc == 0177) + fc = ' '; + nc = fc; + for (j = 0; j < len; j++) { + putchar(nc); + if (++nc == 0177) + nc = ' '; + } + putchar('\n'); + } + (void) fflush(stdout); + exit(0); +} diff --git a/usr.sbin/lpr/pac/Makefile b/usr.sbin/lpr/pac/Makefile new file mode 100644 index 0000000..70cea89 --- /dev/null +++ b/usr.sbin/lpr/pac/Makefile @@ -0,0 +1,10 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= pac +CFLAGS+=-I${.CURDIR}/../common_source +MAN8= pac.0 +SRCS= pac.c common.c +.PATH: ${.CURDIR}/../common_source + +.include "../../Makefile.inc" +.include diff --git a/usr.sbin/lpr/pac/pac.8 b/usr.sbin/lpr/pac/pac.8 new file mode 100644 index 0000000..6e7ffc0 --- /dev/null +++ b/usr.sbin/lpr/pac/pac.8 @@ -0,0 +1,106 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" @(#)pac.8 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt PAC 8 +.Os BSD 4.2 +.Sh NAME +.Nm pac +.Nd printer/plotter accounting information +.Sh SYNOPSIS +.Nm pac +.Op Fl P Ns Ar printer +.Op Fl c +.Op Fl m +.Op Fl p Ns Ar price +.Op Fl s +.Op Fl r +.Op Ar name ... +.Sh DESCRIPTION +.Nm Pac +reads the printer/plotter accounting files, accumulating the number +of pages (the usual case) or feet (for raster devices) +of paper consumed by each user, and printing out +how much each user consumed in pages or feet and dollars. +.Pp +Options and operands available: +.Bl -tag -width PPprinter +.It Fl P Ns Ar printer +Accounting is done for the named printer. +Normally, accounting is done for the default printer (site dependent) or +the value of the environment variable +.Ev PRINTER +is used. +.It Fl c +flag causes the output to be sorted by cost; usually the +output is sorted alphabetically by name. +.It Fl m +flag causes the host name to be ignored in the accounting file. This +allows for a user on multiple machines to have all of his printing +charges grouped together. +.It Fl p Ns Ar price +The value +.Ar price +is used for the cost in dollars instead of the default value of 0.02 +or the price specified in +.Pa /etc/printcap . +.It Fl r +Reverse the sorting order. +.It Fl s +Accounting information is summarized on the +summary accounting file; this summarization is necessary since on a +busy system, the accounting file can grow by several lines per day. +.It Ar names +Statistics are only printed for user(s) +.Ar name ; +usually, statistics are printed for every user who has used any paper. +.El +.Sh FILES +.Bl -tag -width /var/account/?_sum -compact +.It Pa /var/account/?acct +raw accounting files +.It Pa /var/account/?_sum +summary accounting files +.It Pa /etc/printcap +printer capability data base +.El +.Sh SEE ALSO +.Xr printcap 5 +.Sh BUGS +The relationship between the computed price and reality is +as yet unknown. +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.0 . diff --git a/usr.sbin/lpr/pac/pac.c b/usr.sbin/lpr/pac/pac.c new file mode 100644 index 0000000..af0c8cc --- /dev/null +++ b/usr.sbin/lpr/pac/pac.c @@ -0,0 +1,444 @@ +/* + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)pac.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Do Printer accounting summary. + * Currently, usage is + * pac [-Pprinter] [-pprice] [-s] [-r] [-c] [-m] [user ...] + * to print the usage information for the named people. + */ + +#include + +#include +#include +#include +#include +#include "lp.h" +#include "lp.local.h" + +static char *acctfile; /* accounting file (input data) */ +static int allflag = 1; /* Get stats on everybody */ +static int errs; +static int hcount; /* Count of hash entries */ +static int mflag = 0; /* disregard machine names */ +static int pflag = 0; /* 1 if -p on cmd line */ +static float price = 0.02; /* cost per page (or what ever) */ +static long price100; /* per-page cost in 100th of a cent */ +static int reverse; /* Reverse sort order */ +static int sort; /* Sort by cost */ +static char *sumfile; /* summary file */ +static int summarize; /* Compress accounting file */ + +/* + * Grossness follows: + * Names to be accumulated are hashed into the following + * table. + */ + +#define HSHSIZE 97 /* Number of hash buckets */ + +struct hent { + struct hent *h_link; /* Forward hash link */ + char *h_name; /* Name of this user */ + float h_feetpages; /* Feet or pages of paper */ + int h_count; /* Number of runs */ +}; + +static struct hent *hashtab[HSHSIZE]; /* Hash table proper */ + +static void account __P((FILE *)); +static int any __P((int, char [])); +static int chkprinter __P((char *)); +static void dumpit __P((void)); +static int hash __P((char [])); +static struct hent *enter __P((char [])); +static struct hent *lookup __P((char [])); +static int qucmp __P((const void *, const void *)); +static void rewrite __P((void)); + +void +main(argc, argv) + int argc; + char **argv; +{ + register FILE *acct; + register char *cp; + + while (--argc) { + cp = *++argv; + if (*cp++ == '-') { + switch(*cp++) { + case 'P': + /* + * Printer name. + */ + printer = cp; + continue; + + case 'p': + /* + * get the price. + */ + price = atof(cp); + pflag = 1; + continue; + + case 's': + /* + * Summarize and compress accounting file. + */ + summarize++; + continue; + + case 'c': + /* + * Sort by cost. + */ + sort++; + continue; + + case 'm': + /* + * disregard machine names for each user + */ + mflag = 1; + continue; + + case 'r': + /* + * Reverse sorting order. + */ + reverse++; + continue; + + default: +fprintf(stderr, + "usage: pac [-Pprinter] [-pprice] [-s] [-c] [-r] [-m] [user ...]\n"); + exit(1); + } + } + (void) enter(--cp); + allflag = 0; + } + if (printer == NULL && (printer = getenv("PRINTER")) == NULL) + printer = DEFLP; + if (!chkprinter(printer)) { + printf("pac: unknown printer %s\n", printer); + exit(2); + } + + if ((acct = fopen(acctfile, "r")) == NULL) { + perror(acctfile); + exit(1); + } + account(acct); + fclose(acct); + if ((acct = fopen(sumfile, "r")) != NULL) { + account(acct); + fclose(acct); + } + if (summarize) + rewrite(); + else + dumpit(); + exit(errs); +} + +/* + * Read the entire accounting file, accumulating statistics + * for the users that we have in the hash table. If allflag + * is set, then just gather the facts on everyone. + * Note that we must accomodate both the active and summary file + * formats here. + * Host names are ignored if the -m flag is present. + */ +static void +account(acct) + register FILE *acct; +{ + char linebuf[BUFSIZ]; + double t; + register char *cp, *cp2; + register struct hent *hp; + register int ic; + + while (fgets(linebuf, BUFSIZ, acct) != NULL) { + cp = linebuf; + while (any(*cp, " t\t")) + cp++; + t = atof(cp); + while (any(*cp, ".0123456789")) + cp++; + while (any(*cp, " \t")) + cp++; + for (cp2 = cp; !any(*cp2, " \t\n"); cp2++) + ; + ic = atoi(cp2); + *cp2 = '\0'; + if (mflag && index(cp, ':')) + cp = index(cp, ':') + 1; + hp = lookup(cp); + if (hp == NULL) { + if (!allflag) + continue; + hp = enter(cp); + } + hp->h_feetpages += t; + if (ic) + hp->h_count += ic; + else + hp->h_count++; + } +} + +/* + * Sort the hashed entries by name or footage + * and print it all out. + */ +static void +dumpit() +{ + struct hent **base; + register struct hent *hp, **ap; + register int hno, c, runs; + float feet; + + hp = hashtab[0]; + hno = 1; + base = (struct hent **) calloc(sizeof hp, hcount); + for (ap = base, c = hcount; c--; ap++) { + while (hp == NULL) + hp = hashtab[hno++]; + *ap = hp; + hp = hp->h_link; + } + qsort(base, hcount, sizeof hp, qucmp); + printf(" Login pages/feet runs price\n"); + feet = 0.0; + runs = 0; + for (ap = base, c = hcount; c--; ap++) { + hp = *ap; + runs += hp->h_count; + feet += hp->h_feetpages; + printf("%-24s %7.2f %4d $%6.2f\n", hp->h_name, + hp->h_feetpages, hp->h_count, hp->h_feetpages * price); + } + if (allflag) { + printf("\n"); + printf("%-24s %7.2f %4d $%6.2f\n", "total", feet, + runs, feet * price); + } +} + +/* + * Rewrite the summary file with the summary information we have accumulated. + */ +static void +rewrite() +{ + register struct hent *hp; + register int i; + register FILE *acctf; + + if ((acctf = fopen(sumfile, "w")) == NULL) { + perror(sumfile); + errs++; + return; + } + for (i = 0; i < HSHSIZE; i++) { + hp = hashtab[i]; + while (hp != NULL) { + fprintf(acctf, "%7.2f\t%s\t%d\n", hp->h_feetpages, + hp->h_name, hp->h_count); + hp = hp->h_link; + } + } + fflush(acctf); + if (ferror(acctf)) { + perror(sumfile); + errs++; + } + fclose(acctf); + if ((acctf = fopen(acctfile, "w")) == NULL) + perror(acctfile); + else + fclose(acctf); +} + +/* + * Hashing routines. + */ + +/* + * Enter the name into the hash table and return the pointer allocated. + */ + +static struct hent * +enter(name) + char name[]; +{ + register struct hent *hp; + register int h; + + if ((hp = lookup(name)) != NULL) + return(hp); + h = hash(name); + hcount++; + hp = (struct hent *) calloc(sizeof *hp, 1); + hp->h_name = (char *) calloc(sizeof(char), strlen(name)+1); + strcpy(hp->h_name, name); + hp->h_feetpages = 0.0; + hp->h_count = 0; + hp->h_link = hashtab[h]; + hashtab[h] = hp; + return(hp); +} + +/* + * Lookup a name in the hash table and return a pointer + * to it. + */ + +static struct hent * +lookup(name) + char name[]; +{ + register int h; + register struct hent *hp; + + h = hash(name); + for (hp = hashtab[h]; hp != NULL; hp = hp->h_link) + if (strcmp(hp->h_name, name) == 0) + return(hp); + return(NULL); +} + +/* + * Hash the passed name and return the index in + * the hash table to begin the search. + */ +static int +hash(name) + char name[]; +{ + register int h; + register char *cp; + + for (cp = name, h = 0; *cp; h = (h << 2) + *cp++) + ; + return((h & 0x7fffffff) % HSHSIZE); +} + +/* + * Other stuff + */ +static int +any(ch, str) + int ch; + char str[]; +{ + register int c = ch; + register char *cp = str; + + while (*cp) + if (*cp++ == c) + return(1); + return(0); +} + +/* + * The qsort comparison routine. + * The comparison is ascii collating order + * or by feet of typesetter film, according to sort. + */ +static int +qucmp(a, b) + const void *a, *b; +{ + register struct hent *h1, *h2; + register int r; + + h1 = *(struct hent **)a; + h2 = *(struct hent **)b; + if (sort) + r = h1->h_feetpages < h2->h_feetpages ? + -1 : h1->h_feetpages > h2->h_feetpages; + else + r = strcmp(h1->h_name, h2->h_name); + return(reverse ? -r : r); +} + +/* + * Perform lookup for printer name or abbreviation -- + */ +static int +chkprinter(s) + register char *s; +{ + int stat; + + if ((stat = cgetent(&bp, printcapdb, s)) == -2) { + printf("pac: can't open printer description file\n"); + exit(3); + } else if (stat == -1) + return(0); + else if (stat == -3) + fatal("potential reference loop detected in printcap file"); + + if (cgetstr(bp, "af", &acctfile) == -1) { + printf("accounting not enabled for printer %s\n", printer); + exit(2); + } + if (!pflag && (cgetnum(bp, "pc", &price100) == 0)) + price = price100/10000.0; + sumfile = (char *) calloc(sizeof(char), strlen(acctfile)+5); + if (sumfile == NULL) { + perror("pac"); + exit(1); + } + strcpy(sumfile, acctfile); + strcat(sumfile, "_sum"); + return(1); +} diff --git a/usr.sbin/mtree/Makefile b/usr.sbin/mtree/Makefile new file mode 100644 index 0000000..fb8b424 --- /dev/null +++ b/usr.sbin/mtree/Makefile @@ -0,0 +1,8 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= mtree +#CFLAGS+=-DDEBUG +SRCS= compare.c crc.c create.c misc.c mtree.c spec.c verify.c +.PATH: ${.CURDIR}/../../usr.bin/cksum + +.include diff --git a/usr.sbin/mtree/compare.c b/usr.sbin/mtree/compare.c new file mode 100644 index 0000000..b258572 --- /dev/null +++ b/usr.sbin/mtree/compare.c @@ -0,0 +1,271 @@ +/*- + * Copyright (c) 1989, 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[] = "@(#)compare.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mtree.h" +#include "extern.h" + +extern int uflag; + +static char *ftype __P((u_int)); + +#define INDENTNAMELEN 8 +#define LABEL \ + if (!label++) { \ + len = printf("%s: ", RP(p)); \ + if (len > INDENTNAMELEN) { \ + tab = "\t"; \ + (void)printf("\n"); \ + } else { \ + tab = ""; \ + (void)printf("%*s", INDENTNAMELEN - len, ""); \ + } \ + } + +int +compare(name, s, p) + char *name; + register NODE *s; + register FTSENT *p; +{ + extern int uflag; + u_long len, val; + int fd, label; + char *cp, *tab; + + label = 0; + switch(s->type) { + case F_BLOCK: + if (!S_ISBLK(p->fts_statp->st_mode)) + goto typeerr; + break; + case F_CHAR: + if (!S_ISCHR(p->fts_statp->st_mode)) + goto typeerr; + break; + case F_DIR: + if (!S_ISDIR(p->fts_statp->st_mode)) + goto typeerr; + break; + case F_FIFO: + if (!S_ISFIFO(p->fts_statp->st_mode)) + goto typeerr; + break; + case F_FILE: + if (!S_ISREG(p->fts_statp->st_mode)) + goto typeerr; + break; + case F_LINK: + if (!S_ISLNK(p->fts_statp->st_mode)) + goto typeerr; + break; + case F_SOCK: + if (!S_ISSOCK(p->fts_statp->st_mode)) { +typeerr: LABEL; + (void)printf("\ttype (%s, %s)\n", + ftype(s->type), inotype(p->fts_statp->st_mode)); + } + break; + } + /* Set the uid/gid first, then set the mode. */ + if (s->flags & (F_UID | F_UNAME) && s->st_uid != p->fts_statp->st_uid) { + LABEL; + (void)printf("%suser (%u, %u", + tab, s->st_uid, p->fts_statp->st_uid); + if (uflag) + if (chown(p->fts_accpath, s->st_uid, -1)) + (void)printf(", not modified: %s)\n", + strerror(errno)); + else + (void)printf(", modified)\n"); + else + (void)printf(")\n"); + tab = "\t"; + } + if (s->flags & (F_GID | F_GNAME) && s->st_gid != p->fts_statp->st_gid) { + LABEL; + (void)printf("%sgid (%u, %u", + tab, s->st_gid, p->fts_statp->st_gid); + if (uflag) + if (chown(p->fts_accpath, -1, s->st_gid)) + (void)printf(", not modified: %s)\n", + strerror(errno)); + else + (void)printf(", modified)\n"); + else + (void)printf(")\n"); + tab = "\t"; + } + if (s->flags & F_MODE && + s->st_mode != (p->fts_statp->st_mode & MBITS)) { + LABEL; + (void)printf("%spermissions (%#o, %#o", + tab, s->st_mode, p->fts_statp->st_mode & MBITS); + if (uflag) + if (chmod(p->fts_accpath, s->st_mode)) + (void)printf(", not modified: %s)\n", + strerror(errno)); + else + (void)printf(", modified)\n"); + else + (void)printf(")\n"); + tab = "\t"; + } + if (s->flags & F_NLINK && s->type != F_DIR && + s->st_nlink != p->fts_statp->st_nlink) { + LABEL; + (void)printf("%slink count (%u, %u)\n", + tab, s->st_nlink, p->fts_statp->st_nlink); + tab = "\t"; + } + if (s->flags & F_SIZE && s->st_size != p->fts_statp->st_size) { + LABEL; + (void)printf("%ssize (%qd, %qd)\n", + tab, s->st_size, p->fts_statp->st_size); + tab = "\t"; + } + /* + * XXX + * Catches nano-second differences, but doesn't display them. + */ + if (s->flags & F_TIME && + s->st_mtimespec.ts_sec != p->fts_statp->st_mtimespec.ts_sec || + s->st_mtimespec.ts_nsec != p->fts_statp->st_mtimespec.ts_nsec) { + LABEL; + (void)printf("%smodification time (%.24s, ", + tab, ctime(&s->st_mtimespec.ts_sec)); + (void)printf("%.24s)\n", + ctime(&p->fts_statp->st_mtimespec.ts_sec)); + tab = "\t"; + } + if (s->flags & F_CKSUM) + if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0) { + LABEL; + (void)printf("%scksum: %s: %s\n", + tab, p->fts_accpath, strerror(errno)); + tab = "\t"; + } else if (crc(fd, &val, &len)) { + (void)close(fd); + LABEL; + (void)printf("%scksum: %s: %s\n", + tab, p->fts_accpath, strerror(errno)); + tab = "\t"; + } else { + (void)close(fd); + if (s->cksum != val) { + LABEL; + (void)printf("%scksum (%lu, %lu)\n", + tab, s->cksum, val); + } + tab = "\t"; + } + if (s->flags & F_SLINK && strcmp(cp = rlink(name), s->slink)) { + LABEL; + (void)printf("%slink ref (%s, %s)\n", tab, cp, s->slink); + } + return (label); +} + +char * +inotype(type) + u_int type; +{ + switch(type & S_IFMT) { + case S_IFBLK: + return ("block"); + case S_IFCHR: + return ("char"); + case S_IFDIR: + return ("dir"); + case S_IFIFO: + return ("fifo"); + case S_IFREG: + return ("file"); + case S_IFLNK: + return ("link"); + case S_IFSOCK: + return ("socket"); + default: + return ("unknown"); + } + /* NOTREACHED */ +} + +static char * +ftype(type) + u_int type; +{ + switch(type) { + case F_BLOCK: + return ("block"); + case F_CHAR: + return ("char"); + case F_DIR: + return ("dir"); + case F_FIFO: + return ("fifo"); + case F_FILE: + return ("file"); + case F_LINK: + return ("link"); + case F_SOCK: + return ("socket"); + default: + return ("unknown"); + } + /* NOTREACHED */ +} + +char * +rlink(name) + char *name; +{ + static char lbuf[MAXPATHLEN]; + register int len; + + if ((len = readlink(name, lbuf, sizeof(lbuf))) == -1) + err("%s: %s", name, strerror(errno)); + lbuf[len] = '\0'; + return (lbuf); +} diff --git a/usr.sbin/mtree/create.c b/usr.sbin/mtree/create.c new file mode 100644 index 0000000..9ce603e --- /dev/null +++ b/usr.sbin/mtree/create.c @@ -0,0 +1,290 @@ +/*- + * Copyright (c) 1989, 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[] = "@(#)create.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mtree.h" +#include "extern.h" + +#define INDENTNAMELEN 15 +#define MAXLINELEN 80 + +extern int crc_total, ftsoptions; +extern int dflag, sflag; +extern u_short keys; +extern char fullpath[MAXPATHLEN]; + +static gid_t gid; +static uid_t uid; +static mode_t mode; + +static int dsort __P((const FTSENT **, const FTSENT **)); +static void output __P((int *, const char *, ...)); +static int statd __P((FTS *, FTSENT *, uid_t *, gid_t *, mode_t *)); +static void statf __P((FTSENT *)); + +void +cwalk() +{ + register FTS *t; + register FTSENT *p; + time_t clock; + char *argv[2], host[MAXHOSTNAMELEN]; + + (void)time(&clock); + (void)gethostname(host, sizeof(host)); + (void)printf( + "#\t user: %s\n#\tmachine: %s\n#\t tree: %s\n#\t date: %s", + getlogin(), host, fullpath, ctime(&clock)); + + argv[0] = "."; + argv[1] = NULL; + if ((t = fts_open(argv, ftsoptions, dsort)) == NULL) + err("fts_open: %s", strerror(errno)); + while (p = fts_read(t)) + switch(p->fts_info) { + case FTS_D: + (void)printf("\n# %s\n", p->fts_path); + statd(t, p, &uid, &gid, &mode); + statf(p); + break; + case FTS_DP: + if (p->fts_level > 0) + (void)printf("# %s\n..\n\n", p->fts_path); + break; + case FTS_DNR: + case FTS_ERR: + case FTS_NS: + (void)fprintf(stderr, + "mtree: %s: %s\n", p->fts_path, strerror(errno)); + break; + default: + if (!dflag) + statf(p); + break; + + } + (void)fts_close(t); + if (sflag && keys & F_CKSUM) + (void)fprintf(stderr, + "mtree: %s checksum: %lu\n", fullpath, crc_total); +} + +static void +statf(p) + FTSENT *p; +{ + struct group *gr; + struct passwd *pw; + u_long len, val; + int fd, indent; + + if (S_ISDIR(p->fts_statp->st_mode)) + indent = printf("%s", p->fts_name); + else + indent = printf(" %s", p->fts_name); + + if (indent > INDENTNAMELEN) + indent = MAXLINELEN; + else + indent += printf("%*s", INDENTNAMELEN - indent, ""); + + if (!S_ISREG(p->fts_statp->st_mode)) + output(&indent, "type=%s", inotype(p->fts_statp->st_mode)); + if (keys & (F_UID | F_UNAME) && p->fts_statp->st_uid != uid) + if (keys & F_UNAME && (pw = getpwuid(p->fts_statp->st_uid))) + output(&indent, "uname=%s", pw->pw_name); + else /* if (keys & F_UID) */ + output(&indent, "uid=%u", p->fts_statp->st_uid); + if (keys & (F_GID | F_GNAME) && p->fts_statp->st_gid != gid) + if (keys & F_GNAME && (gr = getgrgid(p->fts_statp->st_gid))) + output(&indent, "gname=%s", gr->gr_name); + else /* if (keys & F_GID) */ + output(&indent, "gid=%u", p->fts_statp->st_gid); + if (keys & F_MODE && (p->fts_statp->st_mode & MBITS) != mode) + output(&indent, "mode=%#o", p->fts_statp->st_mode & MBITS); + if (keys & F_NLINK && p->fts_statp->st_nlink != 1) + output(&indent, "nlink=%u", p->fts_statp->st_nlink); + if (keys & F_SIZE) + output(&indent, "size=%qd", p->fts_statp->st_size); + if (keys & F_TIME) + output(&indent, "time=%ld.%ld", + p->fts_statp->st_mtimespec.ts_sec, + p->fts_statp->st_mtimespec.ts_nsec); + if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) { + if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0 || + crc(fd, &val, &len)) + err("%s: %s", p->fts_accpath, strerror(errno)); + (void)close(fd); + output(&indent, "cksum=%lu", val); + } + if (keys & F_SLINK && + (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) + output(&indent, "link=%s", rlink(p->fts_accpath)); + (void)putchar('\n'); +} + +#define MAXGID 5000 +#define MAXUID 5000 +#define MAXMODE MBITS + 1 + +static int +statd(t, parent, puid, pgid, pmode) + FTS *t; + FTSENT *parent; + uid_t *puid; + gid_t *pgid; + mode_t *pmode; +{ + register FTSENT *p; + register gid_t sgid; + register uid_t suid; + register mode_t smode; + struct group *gr; + struct passwd *pw; + gid_t savegid; + uid_t saveuid; + mode_t savemode; + u_short maxgid, maxuid, maxmode, g[MAXGID], u[MAXUID], m[MAXMODE]; + + if ((p = fts_children(t, 0)) == NULL) { + if (errno) + err("%s: %s", RP(parent), strerror(errno)); + return (1); + } + + bzero(g, sizeof(g)); + bzero(u, sizeof(u)); + bzero(m, sizeof(m)); + + maxuid = maxgid = maxmode = 0; + for (; p; p = p->fts_link) { + smode = p->fts_statp->st_mode & MBITS; + if (smode < MAXMODE && ++m[smode] > maxmode) { + savemode = smode; + maxmode = m[smode]; + } + sgid = p->fts_statp->st_gid; + if (sgid < MAXGID && ++g[sgid] > maxgid) { + savegid = sgid; + maxgid = g[sgid]; + } + suid = p->fts_statp->st_uid; + if (suid < MAXUID && ++u[suid] > maxuid) { + saveuid = suid; + maxuid = u[suid]; + } + } + (void)printf("/set type=file"); + if (keys & F_GID) + (void)printf(" gid=%u", savegid); + if (keys & F_GNAME) + if ((gr = getgrgid(savegid)) != NULL) + (void)printf(" gname=%s", gr->gr_name); + else + (void)printf(" gid=%u", savegid); + if (keys & F_UNAME) + if ((pw = getpwuid(saveuid)) != NULL) + (void)printf(" uname=%s", pw->pw_name); + else + (void)printf(" uid=%u", saveuid); + if (keys & F_UID) + (void)printf(" uid=%u", saveuid); + if (keys & F_MODE) + (void)printf(" mode=%#o", savemode); + if (keys & F_NLINK) + (void)printf(" nlink=1"); + (void)printf("\n"); + *puid = saveuid; + *pgid = savegid; + *pmode = savemode; + return (0); +} + +static int +dsort(a, b) + const FTSENT **a, **b; +{ + if (S_ISDIR((*a)->fts_statp->st_mode)) { + if (!S_ISDIR((*b)->fts_statp->st_mode)) + return (1); + } else if (S_ISDIR((*b)->fts_statp->st_mode)) + return (-1); + return (strcmp((*a)->fts_name, (*b)->fts_name)); +} + +#if __STDC__ +#include +#else +#include +#endif + +void +#if __STDC__ +output(int *offset, const char *fmt, ...) +#else +output(offset, fmt, va_alist) + int *offset; + char *fmt; + va_dcl +#endif +{ + va_list ap; + char buf[1024]; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + if (*offset + strlen(buf) > MAXLINELEN - 3) { + (void)printf(" \\\n%*s", INDENTNAMELEN, ""); + *offset = INDENTNAMELEN; + } + *offset += printf(" %s", buf) + 1; +} diff --git a/usr.sbin/mtree/extern.h b/usr.sbin/mtree/extern.h new file mode 100644 index 0000000..72c5dbc --- /dev/null +++ b/usr.sbin/mtree/extern.h @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 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. + * + * @(#)extern.h 8.1 (Berkeley) 6/6/93 + */ + +int compare __P((char *, NODE *, FTSENT *)); +int crc __P((int, u_long *, u_long *)); +void cwalk __P((void)); +void err __P((const char *, ...)); +char *inotype __P((u_int)); +u_int parsekey __P((char *, int *)); +char *rlink __P((char *)); +NODE *spec __P((void)); +int verify __P((void)); diff --git a/usr.sbin/mtree/misc.c b/usr.sbin/mtree/misc.c new file mode 100644 index 0000000..3169136 --- /dev/null +++ b/usr.sbin/mtree/misc.c @@ -0,0 +1,125 @@ +/*- + * Copyright (c) 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. + * + * @(#)misc.c 8.1 (Berkeley) 6/6/93 + */ + +#include +#include +#include +#include +#include "mtree.h" +#include "extern.h" + +extern int lineno; + +typedef struct _key { + char *name; /* key name */ + u_int val; /* value */ + +#define NEEDVALUE 0x01 + u_int flags; +} KEY; + +/* NB: the following table must be sorted lexically. */ +static KEY keylist[] = { + "cksum", F_CKSUM, NEEDVALUE, + "gid", F_GID, NEEDVALUE, + "gname", F_GNAME, NEEDVALUE, + "ignore", F_IGN, 0, + "link", F_SLINK, NEEDVALUE, + "mode", F_MODE, NEEDVALUE, + "nlink", F_NLINK, NEEDVALUE, + "size", F_SIZE, NEEDVALUE, + "time", F_TIME, NEEDVALUE, + "type", F_TYPE, NEEDVALUE, + "uid", F_UID, NEEDVALUE, + "uname", F_UNAME, NEEDVALUE, +}; + +u_int +parsekey(name, needvaluep) + char *name; + int *needvaluep; +{ + KEY *k, tmp; + int keycompare __P((const void *, const void *)); + + tmp.name = name; + k = (KEY *)bsearch(&tmp, keylist, sizeof(keylist) / sizeof(KEY), + sizeof(KEY), keycompare); + if (k == NULL) + err("unknown keyword %s", name); + + if (needvaluep) + *needvaluep = k->flags & NEEDVALUE ? 1 : 0; + return (k->val); +} + +int +keycompare(a, b) + const void *a, *b; +{ + return (strcmp(((KEY *)a)->name, ((KEY *)b)->name)); +} + +#if __STDC__ +#include +#else +#include +#endif + +void +#if __STDC__ +err(const char *fmt, ...) +#else +err(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)fprintf(stderr, "mtree: "); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + (void)fprintf(stderr, "\n"); + if (lineno) + (void)fprintf(stderr, + "mtree: failed at line %d of the specification\n", lineno); + exit(1); + /* NOTREACHED */ +} diff --git a/usr.sbin/mtree/mtree.8 b/usr.sbin/mtree/mtree.8 new file mode 100644 index 0000000..3c50f71 --- /dev/null +++ b/usr.sbin/mtree/mtree.8 @@ -0,0 +1,249 @@ +.\" Copyright (c) 1989, 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. +.\" +.\" @(#)mtree.8 8.2 (Berkeley) 12/11/93 +.\" +.Dd December 11, 1993 +.Dt MTREE 8 +.Os +.Sh NAME +.Nm mtree +.Nd map a directory hierarchy +.Sh SYNOPSIS +.Nm mtree +.Op Fl cderux +.Op Fl f Ar spec +.Op Fl K Ar keywords +.Op Fl k Ar keywords +.Op Fl p Ar path +.Op Fl s Ar seed +.Sh DESCRIPTION +The utility +.Nm mtree +compares the file hierarchy rooted in the current directory against a +specification read from the standard input. +Messages are written to the standard output for any files whose +characteristics do not match the specifications, or which are +missing from either the file hierarchy or the specification. +.Pp +The options are as follows: +.Bl -tag -width flag +.It Fl c +Print a specification for the file hierarchy to the standard output. +.It Fl d +Ignore everything except directory type files. +.It Fl e +Don't complain about files that are in the file hierarchy, but not in the +specification. +.It Fl f +Read the specification from +.Ar file , +instead of from the standard input. +.It Fl K +Add the specified (whitespace or comma separated) keywords to the current +set of keywords. +.It Fl k +Use the ``type'' keyword plus the specified (whitespace or comma separated) +keywords instead of the current set of keywords. +.It Fl p +Use the file hierarchy rooted in +.Ar path , +instead of the current directory. +.It Fl r +Remove any files in the file hierarchy that are not described in the +specification. +.It Fl s +Display a single checksum to the standard error output that represents all +of the files for which the keyword +.Cm cksum +was specified. +The checksum is seeded with the specified value. +.It Fl u +Modify the owner, group, and permissions of existing files to match +the specification and create any missing directories. +User, group, and permissions must all be specified for missing directories +to be created. +.It Fl x +Don't descend below mount points in the file hierarchy. +.El +.Pp +Specifications are mostly composed of ``keywords'', i.e. strings that +that specify values relating to files. +No keywords have default values, and if a keyword has no value set, no +checks based on it are performed. +.Pp +Currently supported keywords are as follows: +.Bl -tag -width Cm +.It Cm cksum +The checksum of the file using the default algorithm specified by +the +.Xr cksum 1 +utility. +.It Cm ignore +Ignore any file hierarchy below this file. +.It Cm gid +The file group as a numeric value. +.It Cm gname +The file group as a symbolic name. +.It Cm mode +The current file's permissions as a numeric (octal) or symbolic +value. +.It Cm nlink +The number of hard links the file is expected to have. +.It Cm uid +The file owner as a numeric value. +.It Cm uname +The file group as a symbolic name. +.It Cm size +The size, in bytes, of the file. +.It Cm link +The file the symbolic link is expected to reference. +.It Cm time +The last modification time of the file. +.It Cm type +The type of the file; may be set to any one of the following: +.sp +.Bl -tag -width Cm -compact +.It Cm block +block special device +.It Cm char +character special device +.It Cm dir +directory +.It Cm fifo +fifo +.It Cm file +regular file +.It Cm link +symbolic link +.It Cm socket +socket +.El +.El +.Pp +The default set of keywords are +.Cm gid , +.Cm mode , +.Cm nlink , +.Cm size , +.Cm slink , +.Cm time , +and +.Cm uid . +.Pp +There are four types of lines in a specification. +.Pp +The first type of line sets a global value for a keyword, and consists of +the string ``/set'' followed by whitespace, followed by sets of keyword/value +pairs, separated by whitespace. +Keyword/value pairs consist of a keyword, followed by an equals sign +(``=''), followed by a value, without whitespace characters. +Once a keyword has been set, its value remains unchanged until either +reset or unset. +.Pp +The second type of line unsets keywords and consists of the string +``/unset'', followed by whitespace, followed by one or more keywords, +separated by whitespace. +.Pp +The third type of line is a file specification and consists of a file +name, followed by whitespace, followed by zero or more whitespace +separated keyword/value pairs. +The file name may be preceded by whitespace characters. +The file name may contain any of the standard file name matching +characters (``['', ``]'', ``?'' or ``*''), in which case files +in the hierarchy will be associated with the first pattern that +they match. +.Pp +Each of the keyword/value pairs consist of a keyword, followed by an +equals sign (``=''), followed by the keyword's value, without +whitespace characters. +These values override, without changing, the global value of the +corresponding keyword. +.Pp +All paths are relative. +Specifying a directory will cause subsequent files to be searched +for in that directory hierarchy. +Which brings us to the last type of line in a specification: a line +containing only the string +.Dq Nm \&.. +causes the current directory +path to ascend one level. +.Pp +Empty lines and lines whose first non-whitespace character is a hash +mark (``#'') are ignored. +.Pp +The +.Nm mtree +utility exits with a status of 0 on success, 1 if any error occurred, +and 2 if the file hierarchy did not match the specification. +.Sh EXAMPLES +To detect system binaries that have been ``trojan horsed'', it is recommended +that +.Nm mtree +be run on the file systems, and a copy of the results stored on a different +machine, or, at least, in encrypted form. +The seed for the +.Fl s +option should not be an obvious value and the final checksum should not be +stored on-line under any circumstances! +Then, periodically, +.Nm mtree +should be run against the on-line specifications and the final checksum +compared with the previous value. +While it is possible for the bad guys to change the on-line specifications +to conform to their modified binaries, it shouldn't be possible for them +to make it produce the same final checksum value. +If the final checksum value changes, the off-line copies of the specification +can be used to detect which of the binaries have actually been modified. +.Pp +The +.Fl d +and +.Fl u +options can be used in combination to create directory hierarchies +for distributions and other such things. +.Sh FILES +.Bl -tag -width /etc/mtree -compact +.It Pa /etc/mtree +system specification directory +.El +.Sh SEE ALSO +.Xr chmod 1 , +.Xr chown 1 , +.Xr chgrp 1 , +.Xr cksum 1 , +.Xr stat 2 , +.Xr fts 3 , +.Sh HISTORY +The +.Nm mtree +utility appeared in +.Bx 4.3 Reno . diff --git a/usr.sbin/mtree/mtree.c b/usr.sbin/mtree/mtree.c new file mode 100644 index 0000000..17857c5 --- /dev/null +++ b/usr.sbin/mtree/mtree.c @@ -0,0 +1,146 @@ +/*- + * Copyright (c) 1989, 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1989, 1990, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)mtree.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include "mtree.h" +#include "extern.h" + +extern int crc_total; + +int ftsoptions = FTS_PHYSICAL; +int cflag, dflag, eflag, rflag, sflag, uflag; +u_short keys; +char fullpath[MAXPATHLEN]; + +static void usage __P((void)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern int optind; + extern char *optarg; + int ch; + char *dir, *p; + + dir = NULL; + keys = KEYDEFAULT; + while ((ch = getopt(argc, argv, "cdef:K:k:p:rs:ux")) != EOF) + switch((char)ch) { + case 'c': + cflag = 1; + break; + case 'd': + dflag = 1; + break; + case 'e': + eflag = 1; + break; + case 'f': + if (!(freopen(optarg, "r", stdin))) + err("%s: %s", optarg, strerror(errno)); + break; + case 'K': + while ((p = strsep(&optarg, " \t,")) != NULL) + if (*p != '\0') + keys |= parsekey(p, NULL); + break; + case 'k': + keys = F_TYPE; + while ((p = strsep(&optarg, " \t,")) != NULL) + if (*p != '\0') + keys |= parsekey(p, NULL); + break; + case 'p': + dir = optarg; + break; + case 'r': + rflag = 1; + break; + case 's': + sflag = 1; + crc_total = ~strtol(optarg, &p, 0); + if (*p) + err("illegal seed value -- %s", optarg); + case 'u': + uflag = 1; + break; + case 'x': + ftsoptions |= FTS_XDEV; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc) + usage(); + + if (dir && chdir(dir)) + err("%s: %s", dir, strerror(errno)); + + if ((cflag || sflag) && !getwd(fullpath)) + err("%s", fullpath); + + if (cflag) { + cwalk(); + exit(0); + } + exit(verify()); +} + +static void +usage() +{ + (void)fprintf(stderr, +"usage: mtree [-cderux] [-f spec] [-K key] [-k key] [-p path] [-s seed]\n"); + exit(1); +} diff --git a/usr.sbin/mtree/mtree.h b/usr.sbin/mtree/mtree.h new file mode 100644 index 0000000..5583127 --- /dev/null +++ b/usr.sbin/mtree/mtree.h @@ -0,0 +1,88 @@ +/*- + * 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. + * + * @(#)mtree.h 8.1 (Berkeley) 6/6/93 + */ + +#include +#include + +#define KEYDEFAULT \ + (F_GID | F_MODE | F_NLINK | F_SIZE | F_SLINK | F_TIME | F_UID) + +#define MISMATCHEXIT 2 + +typedef struct _node { + struct _node *parent, *child; /* up, down */ + struct _node *prev, *next; /* left, right */ + off_t st_size; /* size */ + struct timespec st_mtimespec; /* last modification time */ + u_long cksum; /* check sum */ + char *slink; /* symbolic link reference */ + uid_t st_uid; /* uid */ + gid_t st_gid; /* gid */ +#define MBITS (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO) + mode_t st_mode; /* mode */ + nlink_t st_nlink; /* link count */ + +#define F_CKSUM 0x0001 /* check sum */ +#define F_DONE 0x0002 /* directory done */ +#define F_GID 0x0004 /* gid */ +#define F_GNAME 0x0008 /* group name */ +#define F_IGN 0x0010 /* ignore */ +#define F_MAGIC 0x0020 /* name has magic chars */ +#define F_MODE 0x0040 /* mode */ +#define F_NLINK 0x0080 /* number of links */ +#define F_SIZE 0x0100 /* size */ +#define F_SLINK 0x0200 /* link count */ +#define F_TIME 0x0400 /* modification time */ +#define F_TYPE 0x0800 /* file type */ +#define F_UID 0x1000 /* uid */ +#define F_UNAME 0x2000 /* user name */ +#define F_VISIT 0x4000 /* file visited */ + u_short flags; /* items set */ + +#define F_BLOCK 0x001 /* block special */ +#define F_CHAR 0x002 /* char special */ +#define F_DIR 0x004 /* directory */ +#define F_FIFO 0x008 /* fifo */ +#define F_FILE 0x010 /* regular file */ +#define F_LINK 0x020 /* symbolic link */ +#define F_SOCK 0x040 /* socket */ + u_char type; /* file type */ + + char name[1]; /* file name (must be last) */ +} NODE; + +#define RP(p) \ + ((p)->fts_path[0] == '.' && (p)->fts_path[1] == '/' ? \ + (p)->fts_path + 2 : (p)->fts_path) diff --git a/usr.sbin/mtree/spec.c b/usr.sbin/mtree/spec.c new file mode 100644 index 0000000..a50574f --- /dev/null +++ b/usr.sbin/mtree/spec.c @@ -0,0 +1,280 @@ +/*- + * Copyright (c) 1989, 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[] = "@(#)spec.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mtree.h" +#include "extern.h" + +int lineno; /* Current spec line number. */ + +static void set __P((char *, NODE *)); +static void unset __P((char *, NODE *)); + +NODE * +spec() +{ + register NODE *centry, *last; + register char *p; + NODE ginfo, *root; + int c_cur, c_next; + char buf[2048]; + + root = NULL; + bzero(&ginfo, sizeof(ginfo)); + c_cur = c_next = 0; + for (lineno = 1; fgets(buf, sizeof(buf), stdin); + ++lineno, c_cur = c_next, c_next = 0) { + /* Skip empty lines. */ + if (buf[0] == '\n') + continue; + + /* Find end of line. */ + if ((p = index(buf, '\n')) == NULL) + err("line %d too long", lineno); + + /* See if next line is continuation line. */ + if (p[-1] == '\\') { + --p; + c_next = 1; + } + + /* Null-terminate the line. */ + *p = '\0'; + + /* Skip leading whitespace. */ + for (p = buf; *p && isspace(*p); ++p); + + /* If nothing but whitespace or comment char, continue. */ + if (!*p || *p == '#') + continue; + +#ifdef DEBUG + (void)fprintf(stderr, "line %d: {%s}\n", lineno, p); +#endif + if (c_cur) { + set(p, centry); + continue; + } + + /* Grab file name, "$", "set", or "unset". */ + if ((p = strtok(p, "\n\t ")) == NULL) + err("missing field"); + + if (p[0] == '/') + switch(p[1]) { + case 's': + if (strcmp(p + 1, "set")) + break; + set(NULL, &ginfo); + continue; + case 'u': + if (strcmp(p + 1, "unset")) + break; + unset(NULL, &ginfo); + continue; + } + + if (index(p, '/')) + err("slash character in file name"); + + if (!strcmp(p, "..")) { + /* Don't go up, if haven't gone down. */ + if (!root) + goto noparent; + if (last->type != F_DIR || last->flags & F_DONE) { + if (last == root) + goto noparent; + last = last->parent; + } + last->flags |= F_DONE; + continue; + +noparent: err("no parent node"); + } + + if ((centry = calloc(1, sizeof(NODE) + strlen(p))) == NULL) + err("%s", strerror(errno)); + *centry = ginfo; + (void)strcpy(centry->name, p); +#define MAGIC "?*[" + if (strpbrk(p, MAGIC)) + centry->flags |= F_MAGIC; + set(NULL, centry); + + if (!root) { + last = root = centry; + root->parent = root; + } else if (last->type == F_DIR && !(last->flags & F_DONE)) { + centry->parent = last; + last = last->child = centry; + } else { + centry->parent = last->parent; + centry->prev = last; + last = last->next = centry; + } + } + return (root); +} + +static void +set(t, ip) + char *t; + register NODE *ip; +{ + register int type; + register char *kw, *val; + struct group *gr; + struct passwd *pw; + mode_t *m; + int value; + char *ep; + + for (; kw = strtok(t, "= \t\n"); t = NULL) { + ip->flags |= type = parsekey(kw, &value); + if (value && (val = strtok(NULL, " \t\n")) == NULL) + err("missing value"); + switch(type) { + case F_CKSUM: + ip->cksum = strtoul(val, &ep, 10); + if (*ep) + err("invalid checksum %s", val); + break; + case F_GID: + ip->st_gid = strtoul(val, &ep, 10); + if (*ep) + err("invalid gid %s", val); + break; + case F_GNAME: + if ((gr = getgrnam(val)) == NULL) + err("unknown group %s", val); + ip->st_gid = gr->gr_gid; + break; + case F_IGN: + /* just set flag bit */ + break; + case F_MODE: + if ((m = setmode(val)) == NULL) + err("invalid file mode %s", val); + ip->st_mode = getmode(m, 0); + break; + case F_NLINK: + ip->st_nlink = strtoul(val, &ep, 10); + if (*ep) + err("invalid link count %s", val); + break; + case F_SIZE: + ip->st_size = strtoul(val, &ep, 10); + if (*ep) + err("invalid size %s", val); + break; + case F_SLINK: + if ((ip->slink = strdup(val)) == NULL) + err("%s", strerror(errno)); + break; + case F_TIME: + ip->st_mtimespec.ts_sec = strtoul(val, &ep, 10); + if (*ep != '.') + err("invalid time %s", val); + val = ep + 1; + ip->st_mtimespec.ts_nsec = strtoul(val, &ep, 10); + if (*ep) + err("invalid time %s", val); + break; + case F_TYPE: + switch(*val) { + case 'b': + if (!strcmp(val, "block")) + ip->type = F_BLOCK; + break; + case 'c': + if (!strcmp(val, "char")) + ip->type = F_CHAR; + break; + case 'd': + if (!strcmp(val, "dir")) + ip->type = F_DIR; + break; + case 'f': + if (!strcmp(val, "file")) + ip->type = F_FILE; + if (!strcmp(val, "fifo")) + ip->type = F_FIFO; + break; + case 'l': + if (!strcmp(val, "link")) + ip->type = F_LINK; + break; + case 's': + if (!strcmp(val, "socket")) + ip->type = F_SOCK; + break; + default: + err("unknown file type %s", val); + } + break; + case F_UID: + ip->st_uid = strtoul(val, &ep, 10); + if (*ep) + err("invalid uid %s", val); + break; + case F_UNAME: + if ((pw = getpwnam(val)) == NULL) + err("unknown user %s", val); + ip->st_uid = pw->pw_uid; + break; + } + } +} + +static void +unset(t, ip) + char *t; + register NODE *ip; +{ + register char *p; + + while (p = strtok(t, "\n\t ")) + ip->flags &= ~parsekey(p, NULL); +} diff --git a/usr.sbin/mtree/verify.c b/usr.sbin/mtree/verify.c new file mode 100644 index 0000000..27d9b90 --- /dev/null +++ b/usr.sbin/mtree/verify.c @@ -0,0 +1,202 @@ +/*- + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)verify.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mtree.h" +#include "extern.h" + +extern int crc_total, ftsoptions; +extern int dflag, eflag, rflag, sflag, uflag; +extern char fullpath[MAXPATHLEN]; + +static NODE *root; +static char path[MAXPATHLEN]; + +static void miss __P((NODE *, char *)); +static int vwalk __P((void)); + +int +verify() +{ + int rval; + + root = spec(); + rval = vwalk(); + miss(root, path); + return (rval); +} + +static int +vwalk() +{ + register FTS *t; + register FTSENT *p; + register NODE *ep, *level; + int ftsdepth, specdepth, rval; + char *argv[2]; + + argv[0] = "."; + argv[1] = NULL; + if ((t = fts_open(argv, ftsoptions, NULL)) == NULL) + err("fts_open: %s", strerror(errno)); + level = root; + ftsdepth = specdepth = rval = 0; + while (p = fts_read(t)) { + switch(p->fts_info) { + case FTS_D: + ++ftsdepth; + break; + case FTS_DP: + --ftsdepth; + if (specdepth > ftsdepth) { + for (level = level->parent; level->prev; + level = level->prev); + --specdepth; + } + continue; + case FTS_DNR: + case FTS_ERR: + case FTS_NS: + (void)fprintf(stderr, "mtree: %s: %s\n", + RP(p), strerror(errno)); + continue; + default: + if (dflag) + continue; + } + + for (ep = level; ep; ep = ep->next) + if (ep->flags & F_MAGIC && + !fnmatch(ep->name, p->fts_name, FNM_PATHNAME) || + !strcmp(ep->name, p->fts_name)) { + ep->flags |= F_VISIT; + if (compare(ep->name, ep, p)) + rval = MISMATCHEXIT; + if (ep->flags & F_IGN) + (void)fts_set(t, p, FTS_SKIP); + else if (ep->child && ep->type == F_DIR && + p->fts_info == FTS_D) { + level = ep->child; + ++specdepth; + } + break; + } + + if (ep) + continue; + if (!eflag) { + (void)printf("extra: %s", RP(p)); + if (rflag) { + if (unlink(p->fts_accpath)) { + (void)printf(", not removed: %s", + strerror(errno)); + } else + (void)printf(", removed"); + } + (void)putchar('\n'); + } + (void)fts_set(t, p, FTS_SKIP); + } + (void)fts_close(t); + if (sflag) + (void)fprintf(stderr, + "mtree: %s checksum: %lu\n", fullpath, crc_total); + return (rval); +} + +static void +miss(p, tail) + register NODE *p; + register char *tail; +{ + register int create; + register char *tp; + + for (; p; p = p->next) { + if (p->type != F_DIR && (dflag || p->flags & F_VISIT)) + continue; + (void)strcpy(tail, p->name); + if (!(p->flags & F_VISIT)) + (void)printf("missing: %s", path); + if (p->type != F_DIR) { + putchar('\n'); + continue; + } + + create = 0; + if (!(p->flags & F_VISIT) && uflag) + if (!(p->flags & (F_UID | F_UNAME))) + (void)printf(" (not created: user not specified)"); + else if (!(p->flags & (F_GID | F_GNAME))) + (void)printf(" (not created: group not specified)"); + else if (!(p->flags & F_MODE)) + (void)printf(" (not created: mode not specified)"); + else if (mkdir(path, S_IRWXU)) + (void)printf(" (not created: %s)", + strerror(errno)); + else { + create = 1; + (void)printf(" (created)"); + } + + if (!(p->flags & F_VISIT)) + (void)putchar('\n'); + + for (tp = tail; *tp; ++tp); + *tp = '/'; + miss(p->child, tp + 1); + *tp = '\0'; + + if (!create) + continue; + if (chown(path, p->st_uid, p->st_gid)) { + (void)printf("%s: user/group/mode not modified: %s\n", + path, strerror(errno)); + continue; + } + if (chmod(path, p->st_mode)) + (void)printf("%s: permissions not set: %s\n", + path, strerror(errno)); + } +} diff --git a/usr.sbin/pstat/Makefile b/usr.sbin/pstat/Makefile new file mode 100644 index 0000000..9969a64 --- /dev/null +++ b/usr.sbin/pstat/Makefile @@ -0,0 +1,10 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= pstat +CFLAGS+=-I/sys +BINGRP= kmem +BINMODE=2555 +DPADD= ${LIBKVM} +LDADD= -lkvm + +.include diff --git a/usr.sbin/pstat/pstat.8 b/usr.sbin/pstat/pstat.8 new file mode 100644 index 0000000..95f3d86 --- /dev/null +++ b/usr.sbin/pstat/pstat.8 @@ -0,0 +1,321 @@ +.\" Copyright (c) 1980, 1991, 1993, 1994 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" @(#)pstat.8 8.4 (Berkeley) 4/19/94 +.\" 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. +.\" +.\" @(#)pstat.8 8.4 (Berkeley) 4/19/94 +.\" +.Dd April 19, 1994 +.Dt PSTAT 8 +.Os BSD 4 +.Sh NAME +.Nm pstat +.Nd display system data structures +.Sh SYNOPSIS +.Nm pstat +.Op Fl Tfnstv +.Op Fl M Ar core +.Op Fl N Ar system +.Sh DESCRIPTION +.Nm Pstat +displays open file entry, swap space utilization, +terminal state, and vnode data structures. +If +.Ar corefile +is given, the information is sought there, otherwise +in +.Pa /dev/kmem . +The required namelist is taken from +.Pa /vmunix +unless +.Ar system +is specified. +The +.Fl n +option specifies that devices should be printed out by major/minor +number rather than by name. +.Pp +Options are +.Bl -tag -width indent +.It Fl T +Prints the number of used and free slots in the several system tables +and is useful for checking to see how large system tables have become +if the system is under heavy load. +.It Fl f +Print the open file table with these headings: +.Bl -tag -width indent +.It LOC +The core location of this table entry. +.It TYPE +The type of object the file table entry points to. +.It FLG +Miscellaneous state variables encoded thus: +.Bl -tag -width indent +.It R +open for reading +.It W +open for writing +.It A +open for appending +.It S +shared lock present +.It X +exclusive lock present +.It I +signal pgrp when data ready +.El +.It CNT +Number of processes that know this open file. +.It MSG +Number of messages outstanding for this file. +.It DATA +The location of the vnode table entry or socket structure for this file. +.It OFFSET +The file offset (see +.Xr lseek 2 ) . +.El +.It Fl s +Print information about swap space usage on all the +swap areas compiled into the kernel. +The first column is the device name of the partition. The next column is +the total space available in the partition. The +.Ar Used +column indicates the total blocks used so far; the +.Ar Available +column indicates how much space is remaining on each partition. +The +.Ar Capacity +reports the percentage of space used. +.Pp +If more than one partition is configured into the system, totals for all +of the statistics will be reported in the final line of the report. +.It Fl t +Print table for terminals +with these headings: +.Bl -tag -width indent +.It RAW +Number of characters in raw input queue. +.It CAN +Number of characters in canonicalized input queue. +.It OUT +Number of characters in putput queue. +.It MODE +See +.Xr tty 4 . +.It ADDR +Physical device address. +.It DEL +Number of delimiters (newlines) in canonicalized input queue. +.It COL +Calculated column position of terminal. +.It STATE +Miscellaneous state variables encoded thus: +.Bl -tag -width indent +.It T +delay timeout in progress +.It W +waiting for open to complete +.It O +open +.It F +outq has been flushed during DMA +.It C +carrier is on +.It B +busy doing output +.It A +process is awaiting output +.It X +open for exclusive use +.It S +output stopped +.It H +hangup on close +.El +.It PGRP +Process group for which this is controlling terminal. +.It DISC +Line discipline; blank is old tty +OTTYDISC +or +.Ql new tty +for +NTTYDISC +or +.Ql net +for +NETLDISC +(see +.Xr bk 4 ) . +.El +.It Fl v +Print the active vnodes. Each group of vnodes corresponding +to a particular filesystem is preceded by a two line header. The +first line consists of the following: +.Pp +.Df I +.No *** MOUNT Em fstype from +on +.Em on fsflags +.De +.Pp +where +.Em fstype +is one of +.Em ufs , nfs , mfs , or pc ; +.Em from +is the filesystem is mounted from; +.Em on +is the directory +the filesystem is mounted on; and +.Em fsflags +is a list +of optional flags applied to the mount (see +.Xr mount 8 ) . +.The second line is a header for the individual fields , +the first part of which are fixed, and the second part are filesystem +type specific. The headers common to all vnodes are: +.Bl -tag -width indent +.It ADDR +Location of this vnode. +.It TYP +File type. +.It VFLAG +.Pp +A list of letters representing vnode flags: +.Bl -tag -width indent +.It R +\- VROOT +.It T +\- VTEXT +.It L +\- VXLOCK +.It W +\- VXWANT +.It E +\- VEXLOCK +.It S +\- VSHLOCK +.It T +\- VLWAIT +.It A +\- VALIASED +.It B +\- VBWAIT +.El +.Pp +.It USE +The number of references to this vnode. +.It HOLD +The number of I/O buffers held by this vnode. +.It FILEID +The vnode fileid. +In the case of +.Em ufs +this is the inode number. +.It IFLAG +Miscellaneous filesystem specific state variables encoded thus: +.Bl -tag -width indent +.It "For ufs:" +.Pp +.Bl -tag -width indent +.It L +locked +.It U +update time +.Pq Xr fs 5 +must be corrected +.It A +access time must be corrected +.It W +wanted by another process (L flag is on) +.It C +changed time must be corrected +.It S +shared lock applied +.It E +exclusive lock applied +.It Z +someone waiting for a lock +.It M +contains modifications +.It R +has a rename in progress +.El +.It "For nfs:" +.Bl -tag -width indent +.It W +waiting for I/O buffer flush to complete +.It P +I/O buffers being flushed +.It M +locally modified data exists +.It E +an earlier write failed +.It X +non-cacheable lease (nqnfs) +.It O +write lease (nqnfs) +.It G +lease was evicted (nqnfs) +.El +.El +.It SIZ/RDEV +Number of bytes in an ordinary file, or +major and minor device of special file. +.El +.El +.Sh FILES +.Bl -tag -width /dev/kmemxxx -compact +.It Pa /vmunix +namelist +.It Pa /dev/kmem +default source of tables +.El +.Sh SEE ALSO +.Xr iostat 1 , +.Xr ps 1 , +.Xr systat 1 , +.Xr vmstat 1 , +.Xr stat 2 , +.Xr fs 5 , +.Rs +.Rt Tn UNIX Rt Implementation , +.Ra K. Thompson +.Re +.Sh BUGS +Swap statistics are reported for all swap partitions compiled into the kernel, +regardless of whether those partitions are being used. +.Pp +Does not understand NFS swap servers. +.Sh HISTORY +The +.Nm pstat +command appeared in 4.0BSD. diff --git a/usr.sbin/pstat/pstat.c b/usr.sbin/pstat/pstat.c new file mode 100644 index 0000000..0a3cdea --- /dev/null +++ b/usr.sbin/pstat/pstat.c @@ -0,0 +1,1110 @@ +/*- + * Copyright (c) 1980, 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1980, 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)pstat.c 8.9 (Berkeley) 2/16/94"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#define KERNEL +#include +#include +#include +#define NFS +#include +#undef NFS +#undef KERNEL +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +struct nlist nl[] = { +#define VM_SWAPMAP 0 + { "_swapmap" }, /* list of free swap areas */ +#define VM_NSWAPMAP 1 + { "_nswapmap" },/* size of the swap map */ +#define VM_SWDEVT 2 + { "_swdevt" }, /* list of swap devices and sizes */ +#define VM_NSWAP 3 + { "_nswap" }, /* size of largest swap device */ +#define VM_NSWDEV 4 + { "_nswdev" }, /* number of swap devices */ +#define VM_DMMAX 5 + { "_dmmax" }, /* maximum size of a swap block */ +#define V_MOUNTLIST 6 + { "_mountlist" }, /* address of head of mount list. */ +#define V_NUMV 7 + { "_numvnodes" }, +#define FNL_NFILE 8 + {"_nfiles"}, +#define FNL_MAXFILE 9 + {"_maxfiles"}, +#define NLMANDATORY FNL_MAXFILE /* names up to here are mandatory */ +#define VM_NISWAP NLMANDATORY + 1 + { "_niswap" }, +#define VM_NISWDEV NLMANDATORY + 2 + { "_niswdev" }, +#define SCONS NLMANDATORY + 3 + { "_cons" }, +#define SPTY NLMANDATORY + 4 + { "_pt_tty" }, +#define SNPTY NLMANDATORY + 5 + { "_npty" }, + +#ifdef hp300 +#define SDCA (SNPTY+1) + { "_dca_tty" }, +#define SNDCA (SNPTY+2) + { "_ndca" }, +#define SDCM (SNPTY+3) + { "_dcm_tty" }, +#define SNDCM (SNPTY+4) + { "_ndcm" }, +#define SDCL (SNPTY+5) + { "_dcl_tty" }, +#define SNDCL (SNPTY+6) + { "_ndcl" }, +#define SITE (SNPTY+7) + { "_ite_tty" }, +#define SNITE (SNPTY+8) + { "_nite" }, +#endif + +#ifdef mips +#define SDC (SNPTY+1) + { "_dc_tty" }, +#define SNDC (SNPTY+2) + { "_dc_cnt" }, +#endif + + { "" } +}; + +int usenumflag; +int totalflag; +char *nlistf = NULL; +char *memf = NULL; +kvm_t *kd; + +#define SVAR(var) __STRING(var) /* to force expansion */ +#define KGET(idx, var) \ + KGET1(idx, &var, sizeof(var), SVAR(var)) +#define KGET1(idx, p, s, msg) \ + KGET2(nl[idx].n_value, p, s, msg) +#define KGET2(addr, p, s, msg) \ + if (kvm_read(kd, (u_long)(addr), p, s) != s) \ + warnx("cannot read %s: %s", msg, kvm_geterr(kd)) +#define KGETRET(addr, p, s, msg) \ + if (kvm_read(kd, (u_long)(addr), p, s) != s) { \ + warnx("cannot read %s: %s", msg, kvm_geterr(kd)); \ + return (0); \ + } + +void filemode __P((void)); +int getfiles __P((char **, int *)); +struct mount * + getmnt __P((struct mount *)); +struct e_vnode * + kinfo_vnodes __P((int *)); +struct e_vnode * + loadvnodes __P((int *)); +void mount_print __P((struct mount *)); +void nfs_header __P((void)); +int nfs_print __P((struct vnode *)); +void swapmode __P((void)); +void ttymode __P((void)); +void ttyprt __P((struct tty *, int)); +void ttytype __P((struct tty *, char *, int, int)); +void ufs_header __P((void)); +int ufs_print __P((struct vnode *)); +void usage __P((void)); +void vnode_header __P((void)); +void vnode_print __P((struct vnode *, struct vnode *)); +void vnodemode __P((void)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int optind; + int ch, i, quit, ret; + int fileflag, swapflag, ttyflag, vnodeflag; + char buf[_POSIX2_LINE_MAX]; + + fileflag = swapflag = ttyflag = vnodeflag = 0; + while ((ch = getopt(argc, argv, "TM:N:finstv")) != EOF) + switch (ch) { + case 'f': + fileflag = 1; + break; + case 'M': + memf = optarg; + break; + case 'N': + nlistf = optarg; + break; + case 'n': + usenumflag = 1; + break; + case 's': + swapflag = 1; + break; + case 'T': + totalflag = 1; + break; + case 't': + ttyflag = 1; + break; + case 'v': + case 'i': /* Backward compatibility. */ + vnodeflag = 1; + break; + default: + usage(); + } + argc -= optind; + argv += optind; + + /* + * Discard setgid privileges if not the running kernel so that bad + * guys can't print interesting stuff from kernel memory. + */ + if (nlistf != NULL || memf != NULL) + (void)setgid(getgid()); + + if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf)) == 0) + errx(1, "kvm_openfiles: %s", buf); + if ((ret = kvm_nlist(kd, nl)) != 0) { + if (ret == -1) + errx(1, "kvm_nlist: %s", kvm_geterr(kd)); + for (i = quit = 0; i <= NLMANDATORY; i++) + if (!nl[i].n_value) { + quit = 1; + warnx("undefined symbol: %s\n", nl[i].n_name); + } + if (quit) + exit(1); + } + if (!(fileflag | vnodeflag | ttyflag | swapflag | totalflag)) + usage(); + if (fileflag || totalflag) + filemode(); + if (vnodeflag || totalflag) + vnodemode(); + if (ttyflag) + ttymode(); + if (swapflag || totalflag) + swapmode(); + exit (0); +} + +struct e_vnode { + struct vnode *avnode; + struct vnode vnode; +}; + +void +vnodemode() +{ + register struct e_vnode *e_vnodebase, *endvnode, *evp; + register struct vnode *vp; + register struct mount *maddr, *mp; + int numvnodes; + + e_vnodebase = loadvnodes(&numvnodes); + if (totalflag) { + (void)printf("%7d vnodes\n", numvnodes); + return; + } + endvnode = e_vnodebase + numvnodes; + (void)printf("%d active vnodes\n", numvnodes); + + +#define ST mp->mnt_stat + maddr = NULL; + for (evp = e_vnodebase; evp < endvnode; evp++) { + vp = &evp->vnode; + if (vp->v_mount != maddr) { + /* + * New filesystem + */ + if ((mp = getmnt(vp->v_mount)) == NULL) + continue; + maddr = vp->v_mount; + mount_print(mp); + vnode_header(); + switch(ST.f_type) { + case MOUNT_UFS: + case MOUNT_MFS: + ufs_header(); + break; + case MOUNT_NFS: + nfs_header(); + break; + case MOUNT_NONE: + case MOUNT_MSDOS: + default: + break; + } + (void)printf("\n"); + } + vnode_print(evp->avnode, vp); + switch(ST.f_type) { + case MOUNT_UFS: + case MOUNT_MFS: + ufs_print(vp); + break; + case MOUNT_NFS: + nfs_print(vp); + break; + case MOUNT_NONE: + case MOUNT_MSDOS: + default: + break; + } + (void)printf("\n"); + } + free(e_vnodebase); +} + +void +vnode_header() +{ + (void)printf("ADDR TYP VFLAG USE HOLD"); +} + +void +vnode_print(avnode, vp) + struct vnode *avnode; + struct vnode *vp; +{ + char *type, flags[16]; + char *fp = flags; + register int flag; + + /* + * set type + */ + switch(vp->v_type) { + case VNON: + type = "non"; break; + case VREG: + type = "reg"; break; + case VDIR: + type = "dir"; break; + case VBLK: + type = "blk"; break; + case VCHR: + type = "chr"; break; + case VLNK: + type = "lnk"; break; + case VSOCK: + type = "soc"; break; + case VFIFO: + type = "fif"; break; + case VBAD: + type = "bad"; break; + default: + type = "unk"; break; + } + /* + * gather flags + */ + flag = vp->v_flag; + if (flag & VROOT) + *fp++ = 'R'; + if (flag & VTEXT) + *fp++ = 'T'; + if (flag & VSYSTEM) + *fp++ = 'S'; + if (flag & VXLOCK) + *fp++ = 'L'; + if (flag & VXWANT) + *fp++ = 'W'; + if (flag & VBWAIT) + *fp++ = 'B'; + if (flag & VALIASED) + *fp++ = 'A'; + if (flag == 0) + *fp++ = '-'; + *fp = '\0'; + (void)printf("%8x %s %5s %4d %4d", + avnode, type, flags, vp->v_usecount, vp->v_holdcnt); +} + +void +ufs_header() +{ + (void)printf(" FILEID IFLAG RDEV|SZ"); +} + +int +ufs_print(vp) + struct vnode *vp; +{ + register int flag; + struct inode inode, *ip = &inode; + char flagbuf[16], *flags = flagbuf; + char *name; + mode_t type; + + KGETRET(VTOI(vp), &inode, sizeof(struct inode), "vnode's inode"); + flag = ip->i_flag; + if (flag & IN_LOCKED) + *flags++ = 'L'; + if (flag & IN_WANTED) + *flags++ = 'W'; + if (flag & IN_RENAME) + *flags++ = 'R'; + if (flag & IN_UPDATE) + *flags++ = 'U'; + if (flag & IN_ACCESS) + *flags++ = 'A'; + if (flag & IN_CHANGE) + *flags++ = 'C'; + if (flag & IN_MODIFIED) + *flags++ = 'M'; + if (flag & IN_SHLOCK) + *flags++ = 'S'; + if (flag & IN_EXLOCK) + *flags++ = 'E'; + if (flag & IN_LWAIT) + *flags++ = 'Z'; + if (flag == 0) + *flags++ = '-'; + *flags = '\0'; + + (void)printf(" %6d %5s", ip->i_number, flagbuf); + type = ip->i_mode & S_IFMT; + if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode)) + if (usenumflag || ((name = devname(ip->i_rdev, type)) == NULL)) + (void)printf(" %2d,%-2d", + major(ip->i_rdev), minor(ip->i_rdev)); + else + (void)printf(" %7s", name); + else + (void)printf(" %7qd", ip->i_size); + return (0); +} + +void +nfs_header() +{ + (void)printf(" FILEID NFLAG RDEV|SZ"); +} + +int +nfs_print(vp) + struct vnode *vp; +{ + struct nfsnode nfsnode, *np = &nfsnode; + char flagbuf[16], *flags = flagbuf; + register int flag; + char *name; + mode_t type; + + KGETRET(VTONFS(vp), &nfsnode, sizeof(nfsnode), "vnode's nfsnode"); + flag = np->n_flag; + if (flag & NFLUSHWANT) + *flags++ = 'W'; + if (flag & NFLUSHINPROG) + *flags++ = 'P'; + if (flag & NMODIFIED) + *flags++ = 'M'; + if (flag & NWRITEERR) + *flags++ = 'E'; + if (flag & NQNFSNONCACHE) + *flags++ = 'X'; + if (flag & NQNFSWRITE) + *flags++ = 'O'; + if (flag & NQNFSEVICTED) + *flags++ = 'G'; + if (flag == 0) + *flags++ = '-'; + *flags = '\0'; + +#define VT np->n_vattr + (void)printf(" %6d %5s", VT.va_fileid, flagbuf); + type = VT.va_mode & S_IFMT; + if (S_ISCHR(VT.va_mode) || S_ISBLK(VT.va_mode)) + if (usenumflag || ((name = devname(VT.va_rdev, type)) == NULL)) + (void)printf(" %2d,%-2d", + major(VT.va_rdev), minor(VT.va_rdev)); + else + (void)printf(" %7s", name); + else + (void)printf(" %7qd", np->n_size); + return (0); +} + +/* + * Given a pointer to a mount structure in kernel space, + * read it in and return a usable pointer to it. + */ +struct mount * +getmnt(maddr) + struct mount *maddr; +{ + static struct mtab { + struct mtab *next; + struct mount *maddr; + struct mount mount; + } *mhead = NULL; + register struct mtab *mt; + + for (mt = mhead; mt != NULL; mt = mt->next) + if (maddr == mt->maddr) + return (&mt->mount); + if ((mt = malloc(sizeof(struct mtab))) == NULL) + err(1, NULL); + KGETRET(maddr, &mt->mount, sizeof(struct mount), "mount table"); + mt->maddr = maddr; + mt->next = mhead; + mhead = mt; + return (&mt->mount); +} + +void +mount_print(mp) + struct mount *mp; +{ + register int flags; + char *type; + +#define ST mp->mnt_stat + (void)printf("*** MOUNT "); + switch (ST.f_type) { + case MOUNT_NONE: + type = "none"; + break; + case MOUNT_UFS: + type = "ufs"; + break; + case MOUNT_NFS: + type = "nfs"; + break; + case MOUNT_MFS: + type = "mfs"; + break; + case MOUNT_MSDOS: + type = "pc"; + break; + default: + type = "unknown"; + break; + } + (void)printf("%s %s on %s", type, ST.f_mntfromname, ST.f_mntonname); + if (flags = mp->mnt_flag) { + char *comma = "("; + + putchar(' '); + /* user visable flags */ + if (flags & MNT_RDONLY) { + (void)printf("%srdonly", comma); + flags &= ~MNT_RDONLY; + comma = ","; + } + if (flags & MNT_SYNCHRONOUS) { + (void)printf("%ssynchronous", comma); + flags &= ~MNT_SYNCHRONOUS; + comma = ","; + } + if (flags & MNT_NOEXEC) { + (void)printf("%snoexec", comma); + flags &= ~MNT_NOEXEC; + comma = ","; + } + if (flags & MNT_NOSUID) { + (void)printf("%snosuid", comma); + flags &= ~MNT_NOSUID; + comma = ","; + } + if (flags & MNT_NODEV) { + (void)printf("%snodev", comma); + flags &= ~MNT_NODEV; + comma = ","; + } + if (flags & MNT_EXPORTED) { + (void)printf("%sexport", comma); + flags &= ~MNT_EXPORTED; + comma = ","; + } + if (flags & MNT_EXRDONLY) { + (void)printf("%sexrdonly", comma); + flags &= ~MNT_EXRDONLY; + comma = ","; + } + if (flags & MNT_LOCAL) { + (void)printf("%slocal", comma); + flags &= ~MNT_LOCAL; + comma = ","; + } + if (flags & MNT_QUOTA) { + (void)printf("%squota", comma); + flags &= ~MNT_QUOTA; + comma = ","; + } + /* filesystem control flags */ + if (flags & MNT_UPDATE) { + (void)printf("%supdate", comma); + flags &= ~MNT_UPDATE; + comma = ","; + } + if (flags & MNT_MLOCK) { + (void)printf("%slock", comma); + flags &= ~MNT_MLOCK; + comma = ","; + } + if (flags & MNT_MWAIT) { + (void)printf("%swait", comma); + flags &= ~MNT_MWAIT; + comma = ","; + } + if (flags & MNT_MPBUSY) { + (void)printf("%sbusy", comma); + flags &= ~MNT_MPBUSY; + comma = ","; + } + if (flags & MNT_MPWANT) { + (void)printf("%swant", comma); + flags &= ~MNT_MPWANT; + comma = ","; + } + if (flags & MNT_UNMOUNT) { + (void)printf("%sunmount", comma); + flags &= ~MNT_UNMOUNT; + comma = ","; + } + if (flags) + (void)printf("%sunknown_flags:%x", comma, flags); + (void)printf(")"); + } + (void)printf("\n"); +#undef ST +} + +struct e_vnode * +loadvnodes(avnodes) + int *avnodes; +{ + int mib[2]; + size_t copysize; + struct e_vnode *vnodebase; + + if (memf != NULL) { + /* + * do it by hand + */ + return (kinfo_vnodes(avnodes)); + } + mib[0] = CTL_KERN; + mib[1] = KERN_VNODE; + if (sysctl(mib, 2, NULL, ©size, NULL, 0) == -1) + err(1, "sysctl: KERN_VNODE"); + if ((vnodebase = malloc(copysize)) == NULL) + err(1, NULL); + if (sysctl(mib, 2, vnodebase, ©size, NULL, 0) == -1) + err(1, "sysctl: KERN_VNODE"); + if (copysize % sizeof(struct e_vnode)) + errx(1, "vnode size mismatch"); + *avnodes = copysize / sizeof(struct e_vnode); + + return (vnodebase); +} + +/* + * simulate what a running kernel does in in kinfo_vnode + */ +struct e_vnode * +kinfo_vnodes(avnodes) + int *avnodes; +{ + struct mntlist mountlist; + struct mount *mp, mount; + struct vnode *vp, vnode; + char *vbuf, *evbuf, *bp; + int num, numvnodes; + +#define VPTRSZ sizeof(struct vnode *) +#define VNODESZ sizeof(struct vnode) + + KGET(V_NUMV, numvnodes); + if ((vbuf = malloc((numvnodes + 20) * (VPTRSZ + VNODESZ))) == NULL) + err(1, NULL); + bp = vbuf; + evbuf = vbuf + (numvnodes + 20) * (VPTRSZ + VNODESZ); + KGET(V_MOUNTLIST, mountlist); + for (num = 0, mp = mountlist.tqh_first; + mp != NULL; mp = mp->mnt_list.tqe_next) { + KGET2(mp, &mount, sizeof(mount), "mount entry"); + for (vp = mount.mnt_vnodelist.lh_first; + vp != NULL; vp = vp->v_mntvnodes.le_next) { + KGET2(vp, &vnode, sizeof(vnode), "vnode"); + if ((bp + VPTRSZ + VNODESZ) > evbuf) + /* XXX - should realloc */ + errx(1, "no more room for vnodes"); + memmove(bp, &vp, VPTRSZ); + bp += VPTRSZ; + memmove(bp, &vnode, VNODESZ); + bp += VNODESZ; + num++; + } + } + *avnodes = num; + return ((struct e_vnode *)vbuf); +} + +char hdr[]=" LINE RAW CAN OUT HWT LWT COL STATE SESS PGID DISC\n"; +int ttyspace = 128; + +void +ttymode() +{ + struct tty *tty; + + if ((tty = malloc(ttyspace * sizeof(*tty))) == NULL) + err(1, NULL); +#ifndef hp300 + (void)printf("1 console\n"); + KGET(SCONS, *tty); + (void)printf(hdr); + ttyprt(&tty[0], 0); +#endif +#ifdef vax + if (nl[SNQD].n_type != 0) + qdss(); + if (nl[SNDZ].n_type != 0) + ttytype(tty, "dz", SDZ, SNDZ); + if (nl[SNDH].n_type != 0) + ttytype(tty, "dh", SDH, SNDH); + if (nl[SNDMF].n_type != 0) + ttytype(tty, "dmf", SDMF, SNDMF); + if (nl[SNDHU].n_type != 0) + ttytype(tty, "dhu", SDHU, SNDHU); + if (nl[SNDMZ].n_type != 0) + ttytype(tty, "dmz", SDMZ, SNDMZ); +#endif +#ifdef tahoe + if (nl[SNVX].n_type != 0) + ttytype(tty, "vx", SVX, SNVX); + if (nl[SNMP].n_type != 0) + ttytype(tty, "mp", SMP, SNMP); +#endif +#ifdef hp300 + if (nl[SNITE].n_type != 0) + ttytype(tty, "ite", SITE, SNITE); + if (nl[SNDCA].n_type != 0) + ttytype(tty, "dca", SDCA, SNDCA); + if (nl[SNDCM].n_type != 0) + ttytype(tty, "dcm", SDCM, SNDCM); + if (nl[SNDCL].n_type != 0) + ttytype(tty, "dcl", SDCL, SNDCL); +#endif +#ifdef mips + if (nl[SNDC].n_type != 0) + ttytype(tty, "dc", SDC, SNDC); +#endif + if (nl[SNPTY].n_type != 0) + ttytype(tty, "pty", SPTY, SNPTY); +} + +void +ttytype(tty, name, type, number) + register struct tty *tty; + char *name; + int type, number; +{ + register struct tty *tp; + int ntty; + + if (tty == NULL) + return; + KGET(number, ntty); + (void)printf("%d %s %s\n", ntty, name, (ntty == 1) ? "line" : "lines"); + if (ntty > ttyspace) { + ttyspace = ntty; + if ((tty = realloc(tty, ttyspace * sizeof(*tty))) == 0) + err(1, NULL); + } + KGET1(type, tty, ntty * sizeof(struct tty), "tty structs"); + (void)printf(hdr); + for (tp = tty; tp < &tty[ntty]; tp++) + ttyprt(tp, tp - tty); +} + +struct { + int flag; + char val; +} ttystates[] = { + { TS_WOPEN, 'W'}, + { TS_ISOPEN, 'O'}, + { TS_CARR_ON, 'C'}, + { TS_TIMEOUT, 'T'}, + { TS_FLUSH, 'F'}, + { TS_BUSY, 'B'}, + { TS_ASLEEP, 'A'}, + { TS_XCLUDE, 'X'}, + { TS_TTSTOP, 'S'}, + { TS_TBLOCK, 'K'}, + { TS_ASYNC, 'Y'}, + { TS_BKSL, 'D'}, + { TS_ERASE, 'E'}, + { TS_LNCH, 'L'}, + { TS_TYPEN, 'P'}, + { TS_CNTTB, 'N'}, + { 0, '\0'}, +}; + +void +ttyprt(tp, line) + register struct tty *tp; + int line; +{ + register int i, j; + pid_t pgid; + char *name, state[20]; + + if (usenumflag || tp->t_dev == 0 || + (name = devname(tp->t_dev, S_IFCHR)) == NULL) + (void)printf("%7d ", line); + else + (void)printf("%7s ", name); + (void)printf("%2d %3d ", tp->t_rawq.c_cc, tp->t_canq.c_cc); + (void)printf("%3d %4d %3d %3d ", tp->t_outq.c_cc, + tp->t_hiwat, tp->t_lowat, tp->t_column); + for (i = j = 0; ttystates[i].flag; i++) + if (tp->t_state&ttystates[i].flag) + state[j++] = ttystates[i].val; + if (j == 0) + state[j++] = '-'; + state[j] = '\0'; + (void)printf("%-4s %6x", state, (u_long)tp->t_session & ~KERNBASE); + pgid = 0; + if (tp->t_pgrp != NULL) + KGET2(&tp->t_pgrp->pg_id, &pgid, sizeof(pid_t), "pgid"); + (void)printf("%6d ", pgid); + switch (tp->t_line) { + case TTYDISC: + (void)printf("term\n"); + break; + case TABLDISC: + (void)printf("tab\n"); + break; + case SLIPDISC: + (void)printf("slip\n"); + break; + default: + (void)printf("%d\n", tp->t_line); + break; + } +} + +void +filemode() +{ + register struct file *fp; + struct file *addr; + char *buf, flagbuf[16], *fbp; + int len, maxfile, nfile; + static char *dtypes[] = { "???", "inode", "socket" }; + + KGET(FNL_MAXFILE, maxfile); + if (totalflag) { + KGET(FNL_NFILE, nfile); + (void)printf("%3d/%3d files\n", nfile, maxfile); + return; + } + if (getfiles(&buf, &len) == -1) + return; + /* + * Getfiles returns in malloc'd memory a pointer to the first file + * structure, and then an array of file structs (whose addresses are + * derivable from the previous entry). + */ + addr = *((struct file **)buf); + fp = (struct file *)(buf + sizeof(struct file *)); + nfile = (len - sizeof(struct file *)) / sizeof(struct file); + + (void)printf("%d/%d open files\n", nfile, maxfile); + (void)printf(" LOC TYPE FLG CNT MSG DATA OFFSET\n"); + for (; (char *)fp < buf + len; addr = fp->f_filef, fp++) { + if ((unsigned)fp->f_type > DTYPE_SOCKET) + continue; + (void)printf("%x ", addr); + (void)printf("%-8.8s", dtypes[fp->f_type]); + fbp = flagbuf; + if (fp->f_flag & FREAD) + *fbp++ = 'R'; + if (fp->f_flag & FWRITE) + *fbp++ = 'W'; + if (fp->f_flag & FAPPEND) + *fbp++ = 'A'; +#ifdef FSHLOCK /* currently gone */ + if (fp->f_flag & FSHLOCK) + *fbp++ = 'S'; + if (fp->f_flag & FEXLOCK) + *fbp++ = 'X'; +#endif + if (fp->f_flag & FASYNC) + *fbp++ = 'I'; + *fbp = '\0'; + (void)printf("%6s %3d", flagbuf, fp->f_count); + (void)printf(" %3d", fp->f_msgcount); + (void)printf(" %8.1x", fp->f_data); + if (fp->f_offset < 0) + (void)printf(" %qx\n", fp->f_offset); + else + (void)printf(" %qd\n", fp->f_offset); + } + free(buf); +} + +int +getfiles(abuf, alen) + char **abuf; + int *alen; +{ + size_t len; + int mib[2]; + char *buf; + + /* + * XXX + * Add emulation of KINFO_FILE here. + */ + if (memf != NULL) + errx(1, "files on dead kernel, not implemented\n"); + + mib[0] = CTL_KERN; + mib[1] = KERN_FILE; + if (sysctl(mib, 2, NULL, &len, NULL, 0) == -1) { + warn("sysctl: KERN_FILE"); + return (-1); + } + if ((buf = malloc(len)) == NULL) + err(1, NULL); + if (sysctl(mib, 2, buf, &len, NULL, 0) == -1) { + warn("sysctl: KERN_FILE"); + return (-1); + } + *abuf = buf; + *alen = len; + return (0); +} + +/* + * swapmode is based on a program called swapinfo written + * by Kevin Lahey . + */ +void +swapmode() +{ + char *header; + int hlen, nswap, nswdev, dmmax, nswapmap, niswap, niswdev; + int s, e, div, i, l, avail, nfree, npfree, used; + struct swdevt *sw; + long blocksize, *perdev; + struct map *swapmap, *kswapmap; + struct mapent *mp; + + KGET(VM_NSWAP, nswap); + KGET(VM_NSWDEV, nswdev); + KGET(VM_DMMAX, dmmax); + KGET(VM_NSWAPMAP, nswapmap); + KGET(VM_SWAPMAP, kswapmap); /* kernel `swapmap' is a pointer */ + if ((sw = malloc(nswdev * sizeof(*sw))) == NULL || + (perdev = malloc(nswdev * sizeof(*perdev))) == NULL || + (mp = malloc(nswapmap * sizeof(*mp))) == NULL) + err(1, "malloc"); + KGET1(VM_SWDEVT, sw, nswdev * sizeof(*sw), "swdevt"); + KGET2((long)kswapmap, mp, nswapmap * sizeof(*mp), "swapmap"); + + /* Supports sequential swap */ + if (nl[VM_NISWAP].n_value != 0) { + KGET(VM_NISWAP, niswap); + KGET(VM_NISWDEV, niswdev); + } else { + niswap = nswap; + niswdev = nswdev; + } + + /* First entry in map is `struct map'; rest are mapent's. */ + swapmap = (struct map *)mp; + if (nswapmap != swapmap->m_limit - (struct mapent *)kswapmap) + errx(1, "panic: nswapmap goof"); + + /* Count up swap space. */ + nfree = 0; + memset(perdev, 0, nswdev * sizeof(*perdev)); + for (mp++; mp->m_addr != 0; mp++) { + s = mp->m_addr; /* start of swap region */ + e = mp->m_addr + mp->m_size; /* end of region */ + nfree += mp->m_size; + + /* + * Swap space is split up among the configured disks. + * + * For interleaved swap devices, the first dmmax blocks + * of swap space some from the first disk, the next dmmax + * blocks from the next, and so on up to niswap blocks. + * + * Sequential swap devices follow the interleaved devices + * (i.e. blocks starting at niswap) in the order in which + * they appear in the swdev table. The size of each device + * will be a multiple of dmmax. + * + * The list of free space joins adjacent free blocks, + * ignoring device boundries. If we want to keep track + * of this information per device, we'll just have to + * extract it ourselves. We know that dmmax-sized chunks + * cannot span device boundaries (interleaved or sequential) + * so we loop over such chunks assigning them to devices. + */ + i = -1; + while (s < e) { /* XXX this is inefficient */ + int bound = roundup(s+1, dmmax); + + if (bound > e) + bound = e; + if (bound <= niswap) { + /* Interleaved swap chunk. */ + if (i == -1) + i = (s / dmmax) % niswdev; + perdev[i] += bound - s; + if (++i >= niswdev) + i = 0; + } else { + /* Sequential swap chunk. */ + if (i < niswdev) { + i = niswdev; + l = niswap + sw[i].sw_nblks; + } + while (s >= l) { + /* XXX don't die on bogus blocks */ + if (i == nswdev-1) + break; + l += sw[++i].sw_nblks; + } + perdev[i] += bound - s; + } + s = bound; + } + } + + header = getbsize(&hlen, &blocksize); + if (!totalflag) + (void)printf("%-11s %*s %8s %8s %8s %s\n", + "Device", hlen, header, + "Used", "Avail", "Capacity", "Type"); + div = blocksize / 512; + avail = npfree = 0; + for (i = 0; i < nswdev; i++) { + int xsize, xfree; + + if (!totalflag) + (void)printf("/dev/%-6s %*d ", + devname(sw[i].sw_dev, S_IFBLK), + hlen, sw[i].sw_nblks / div); + + /* + * Don't report statistics for partitions which have not + * yet been activated via swapon(8). + */ + if (!(sw[i].sw_flags & SW_FREED)) { + if (totalflag) + continue; + (void)printf(" *** not available for swapping ***\n"); + continue; + } + xsize = sw[i].sw_nblks; + xfree = perdev[i]; + used = xsize - xfree; + npfree++; + avail += xsize; + if (totalflag) + continue; + (void)printf("%8d %8d %5.0f%% %s\n", + used / div, xfree / div, + (double)used / (double)xsize * 100.0, + (sw[i].sw_flags & SW_SEQUENTIAL) ? + "Sequential" : "Interleaved"); + } + + /* + * If only one partition has been set up via swapon(8), we don't + * need to bother with totals. + */ + used = avail - nfree; + if (totalflag) { + (void)printf("%dM/%dM swap space\n", used / 2048, avail / 2048); + return; + } + if (npfree > 1) { + (void)printf("%-11s %*d %8d %8d %5.0f%%\n", + "Total", hlen, avail / div, used / div, nfree / div, + (double)used / (double)avail * 100.0); + } +} + +void +usage() +{ + (void)fprintf(stderr, + "usage: pstat -Tfnstv [system] [-M core] [-N system]\n"); + exit(1); +} diff --git a/usr.sbin/pwd_mkdb/Makefile b/usr.sbin/pwd_mkdb/Makefile new file mode 100644 index 0000000..f1e9020 --- /dev/null +++ b/usr.sbin/pwd_mkdb/Makefile @@ -0,0 +1,7 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= pwd_mkdb +SRCS= pw_scan.c pwd_mkdb.c +MAN8= pwd_mkdb.0 + +.include diff --git a/usr.sbin/pwd_mkdb/pw_scan.c b/usr.sbin/pwd_mkdb/pw_scan.c new file mode 100644 index 0000000..3093ac2 --- /dev/null +++ b/usr.sbin/pwd_mkdb/pw_scan.c @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 1990, 1993, 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)pw_scan.c 8.3 (Berkeley) 4/2/94"; +#endif /* not lint */ + +/* + * This module is used to "verify" password entries by chpass(1) and + * pwd_mkdb(8). + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pw_scan.h" + +int +pw_scan(bp, pw) + char *bp; + struct passwd *pw; +{ + long id; + int root; + char *p, *sh; + + if (!(pw->pw_name = strsep(&bp, ":"))) /* login */ + goto fmt; + root = !strcmp(pw->pw_name, "root"); + + if (!(pw->pw_passwd = strsep(&bp, ":"))) /* passwd */ + goto fmt; + + if (!(p = strsep(&bp, ":"))) /* uid */ + goto fmt; + id = atol(p); + if (root && id) { + warnx("root uid should be 0"); + return (0); + } + if (id > USHRT_MAX) { + warnx("%s > max uid value (%d)", p, USHRT_MAX); + return (0); + } + pw->pw_uid = id; + + if (!(p = strsep(&bp, ":"))) /* gid */ + goto fmt; + id = atol(p); + if (id > USHRT_MAX) { + warnx("%s > max gid value (%d)", p, USHRT_MAX); + return (0); + } + pw->pw_gid = id; + + pw->pw_class = strsep(&bp, ":"); /* class */ + if (!(p = strsep(&bp, ":"))) /* change */ + goto fmt; + pw->pw_change = atol(p); + if (!(p = strsep(&bp, ":"))) /* expire */ + goto fmt; + pw->pw_expire = atol(p); + pw->pw_gecos = strsep(&bp, ":"); /* gecos */ + pw->pw_dir = strsep(&bp, ":"); /* directory */ + if (!(pw->pw_shell = strsep(&bp, ":"))) /* shell */ + goto fmt; + + p = pw->pw_shell; + if (root && *p) /* empty == /bin/sh */ + for (setusershell();;) { + if (!(sh = getusershell())) { + warnx("warning, unknown root shell"); + break; + } + if (!strcmp(p, sh)) + break; + } + + if (p = strsep(&bp, ":")) { /* too many */ +fmt: warnx("corrupted entry"); + return (0); + } + return (1); +} diff --git a/usr.sbin/pwd_mkdb/pw_scan.h b/usr.sbin/pwd_mkdb/pw_scan.h new file mode 100644 index 0000000..d1d4bc1 --- /dev/null +++ b/usr.sbin/pwd_mkdb/pw_scan.h @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 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. + * + * @(#)pw_scan.h 8.1 (Berkeley) 4/1/94 + */ + +extern int pw_scan __P((char *, struct passwd *)); diff --git a/usr.sbin/pwd_mkdb/pwd_mkdb.8 b/usr.sbin/pwd_mkdb/pwd_mkdb.8 new file mode 100644 index 0000000..01bc1c2 --- /dev/null +++ b/usr.sbin/pwd_mkdb/pwd_mkdb.8 @@ -0,0 +1,128 @@ +.\" Copyright (c) 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. +.\" +.\" @(#)pwd_mkdb.8 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt PWD_MKDB 8 +.Os +.Sh NAME +.Nm pwd_mkdb +.Nd "generate the password databases" +.Sh SYNOPSIS +.Nm pwd_mkdb +.Op Fl p +.Ar file +.Sh DESCRIPTION +.Nm Pwd_mkdb +creates +.Xr db 3 +style secure and insecure databases for the specified file. +These databases are then installed into +.Dq Pa /etc/spwd.db +and +.Dq Pa /etc/pwd.db +respectively. +The file is installed into +.Dq Pa /etc/master.passwd . +The file must be in the correct format (see +.Xr passwd 5 ) . +It is important to note that the format used in this system is +different from the historic Version 7 style format. +.Pp +The options are as follows: +.Bl -tag -width flag +.It Fl p +Create a Version 7 style password file and install it into +.Dq Pa /etc/passwd . +.El +.Pp +The two databases differ in that the secure version contains the user's +encrypted password and the insecure version has an asterisk (``*'') +.Pp +The databases are used by the C library password routines (see +.Xr getpwent 3 ) . +.Pp +.Nm Pwd_mkdb +exits zero on success, non-zero on failure. +.Sh FILES +.Bl -tag -width Pa -compact +.It Pa /var/db/pwd.db +The insecure password database file. +.It Pa /var/db/pwd.db.tmp +A temporary file. +.It Pa /var/db/spwd.db +The secure password database file. +.It Pa /var/db/spwd.db.tmp +A temporary file. +.It Pa /etc/master.passwd +The current password file. +.It Pa /etc/passwd +A Version 7 format password file. +.El +.Sh BUGS +Because of the necessity for atomic update of the password files, +.Nm pwd_mkdb +uses +.Xr rename 2 +to install them. +This, however, requires that the file specified on the command line live +on the same file system as the +.Dq Pa /etc +directory. +.Pp +There are the obvious races with multiple people running +.Nm pwd_mkdb +on different password files at the same time. +The front-ends to +.Nm pwd_mkdb , +.Xr chpass 1 , +.Xr passwd 1 +and +.Xr vipw 8 , +handle the locking necessary to avoid this problem. +.Sh COMPATIBILITY +Previous versions of the system had a program similar to +.Nm pwd_mkdb , +.Xr mkpasswd 8 , +which built +.Xr dbm 3 +style databases for the password file but depended on the calling programs +to install them. +The program was renamed in order that previous users of the program +not be surprised by the changes in functionality. +.Sh SEE ALSO +.Xr chpass 1 , +.Xr passwd 1 , +.Xr db 3 , +.Xr getpwent 3 , +.Xr passwd 5 , +.Xr vipw 8 diff --git a/usr.sbin/pwd_mkdb/pwd_mkdb.c b/usr.sbin/pwd_mkdb/pwd_mkdb.c new file mode 100644 index 0000000..7ccc91f --- /dev/null +++ b/usr.sbin/pwd_mkdb/pwd_mkdb.c @@ -0,0 +1,387 @@ +/*- + * Copyright (c) 1991, 1993, 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993, 1994\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)pwd_mkdb.c 8.5 (Berkeley) 4/20/94"; +#endif /* not lint */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pw_scan.h" + +#define INSECURE 1 +#define SECURE 2 +#define PERM_INSECURE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) +#define PERM_SECURE (S_IRUSR|S_IWUSR) + +HASHINFO openinfo = { + 4096, /* bsize */ + 32, /* ffactor */ + 256, /* nelem */ + 2048 * 1024, /* cachesize */ + NULL, /* hash() */ + 0 /* lorder */ +}; + +static enum state { FILE_INSECURE, FILE_SECURE, FILE_ORIG } clean; +static struct passwd pwd; /* password structure */ +static char *pname; /* password file name */ + +void cleanup __P((void)); +void error __P((char *)); +void mv __P((char *, char *)); +int scan __P((FILE *, struct passwd *)); +void usage __P((void)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + DB *dp, *edp; + DBT data, key; + FILE *fp, *oldfp; + sigset_t set; + int ch, cnt, len, makeold, tfd; + char *p, *t; + char buf[MAX(MAXPATHLEN, LINE_MAX * 2)], tbuf[1024]; + + makeold = 0; + while ((ch = getopt(argc, argv, "pv")) != EOF) + switch(ch) { + case 'p': /* create V7 "file.orig" */ + makeold = 1; + break; + case 'v': /* backward compatible */ + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + /* + * This could be changed to allow the user to interrupt. + * Probably not worth the effort. + */ + sigemptyset(&set); + sigaddset(&set, SIGTSTP); + sigaddset(&set, SIGHUP); + sigaddset(&set, SIGINT); + sigaddset(&set, SIGQUIT); + sigaddset(&set, SIGTERM); + (void)sigprocmask(SIG_BLOCK, &set, (sigset_t *)NULL); + + /* We don't care what the user wants. */ + (void)umask(0); + + pname = *argv; + /* Open the original password file */ + if (!(fp = fopen(pname, "r"))) + error(pname); + + /* Open the temporary insecure password database. */ + (void)snprintf(buf, sizeof(buf), "%s.tmp", _PATH_MP_DB); + dp = dbopen(buf, + O_RDWR|O_CREAT|O_EXCL, PERM_INSECURE, DB_HASH, &openinfo); + if (dp == NULL) + error(buf); + clean = FILE_INSECURE; + + /* + * Open file for old password file. Minor trickiness -- don't want to + * chance the file already existing, since someone (stupidly) might + * still be using this for permission checking. So, open it first and + * fdopen the resulting fd. The resulting file should be readable by + * everyone. + */ + if (makeold) { + (void)snprintf(buf, sizeof(buf), "%s.orig", pname); + if ((tfd = open(buf, + O_WRONLY|O_CREAT|O_EXCL, PERM_INSECURE)) < 0) + error(buf); + if ((oldfp = fdopen(tfd, "w")) == NULL) + error(buf); + clean = FILE_ORIG; + } + + /* + * The databases actually contain three copies of the original data. + * Each password file entry is converted into a rough approximation + * of a ``struct passwd'', with the strings placed inline. This + * object is then stored as the data for three separate keys. The + * first key * is the pw_name field prepended by the _PW_KEYBYNAME + * character. The second key is the pw_uid field prepended by the + * _PW_KEYBYUID character. The third key is the line number in the + * original file prepended by the _PW_KEYBYNUM character. (The special + * characters are prepended to ensure that the keys do not collide.) + */ + data.data = (u_char *)buf; + key.data = (u_char *)tbuf; + for (cnt = 1; scan(fp, &pwd); ++cnt) { +#define COMPACT(e) t = e; while (*p++ = *t++); + /* Create insecure data. */ + p = buf; + COMPACT(pwd.pw_name); + COMPACT("*"); + memmove(p, &pwd.pw_uid, sizeof(int)); + p += sizeof(int); + memmove(p, &pwd.pw_gid, sizeof(int)); + p += sizeof(int); + memmove(p, &pwd.pw_change, sizeof(time_t)); + p += sizeof(time_t); + COMPACT(pwd.pw_class); + COMPACT(pwd.pw_gecos); + COMPACT(pwd.pw_dir); + COMPACT(pwd.pw_shell); + memmove(p, &pwd.pw_expire, sizeof(time_t)); + p += sizeof(time_t); + data.size = p - buf; + + /* Store insecure by name. */ + tbuf[0] = _PW_KEYBYNAME; + len = strlen(pwd.pw_name); + memmove(tbuf + 1, pwd.pw_name, len); + key.size = len + 1; + if ((dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1) + error("put"); + + /* Store insecure by number. */ + tbuf[0] = _PW_KEYBYNUM; + memmove(tbuf + 1, &cnt, sizeof(cnt)); + key.size = sizeof(cnt) + 1; + if ((dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1) + error("put"); + + /* Store insecure by uid. */ + tbuf[0] = _PW_KEYBYUID; + memmove(tbuf + 1, &pwd.pw_uid, sizeof(pwd.pw_uid)); + key.size = sizeof(pwd.pw_uid) + 1; + if ((dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1) + error("put"); + + /* Create original format password file entry */ + if (makeold) + (void)fprintf(oldfp, "%s:*:%d:%d:%s:%s:%s\n", + pwd.pw_name, pwd.pw_uid, pwd.pw_gid, pwd.pw_gecos, + pwd.pw_dir, pwd.pw_shell); + } + (void)(dp->close)(dp); + if (makeold) { + (void)fflush(oldfp); + (void)fclose(oldfp); + } + + /* Open the temporary encrypted password database. */ + (void)snprintf(buf, sizeof(buf), "%s.tmp", _PATH_SMP_DB); + edp = dbopen(buf, + O_RDWR|O_CREAT|O_EXCL, PERM_SECURE, DB_HASH, &openinfo); + if (!edp) + error(buf); + clean = FILE_SECURE; + + rewind(fp); + for (cnt = 1; scan(fp, &pwd); ++cnt) { + + /* Create secure data. */ + p = buf; + COMPACT(pwd.pw_name); + COMPACT(pwd.pw_passwd); + memmove(p, &pwd.pw_uid, sizeof(int)); + p += sizeof(int); + memmove(p, &pwd.pw_gid, sizeof(int)); + p += sizeof(int); + memmove(p, &pwd.pw_change, sizeof(time_t)); + p += sizeof(time_t); + COMPACT(pwd.pw_class); + COMPACT(pwd.pw_gecos); + COMPACT(pwd.pw_dir); + COMPACT(pwd.pw_shell); + memmove(p, &pwd.pw_expire, sizeof(time_t)); + p += sizeof(time_t); + data.size = p - buf; + + /* Store secure by name. */ + tbuf[0] = _PW_KEYBYNAME; + len = strlen(pwd.pw_name); + memmove(tbuf + 1, pwd.pw_name, len); + key.size = len + 1; + if ((dp->put)(edp, &key, &data, R_NOOVERWRITE) == -1) + error("put"); + + /* Store secure by number. */ + tbuf[0] = _PW_KEYBYNUM; + memmove(tbuf + 1, &cnt, sizeof(cnt)); + key.size = sizeof(cnt) + 1; + if ((dp->put)(edp, &key, &data, R_NOOVERWRITE) == -1) + error("put"); + + /* Store secure by uid. */ + tbuf[0] = _PW_KEYBYUID; + memmove(tbuf + 1, &pwd.pw_uid, sizeof(pwd.pw_uid)); + key.size = sizeof(pwd.pw_uid) + 1; + if ((dp->put)(edp, &key, &data, R_NOOVERWRITE) == -1) + error("put"); + } + + (void)(edp->close)(edp); + + /* Set master.passwd permissions, in case caller forgot. */ + (void)fchmod(fileno(fp), S_IRUSR|S_IWUSR); + (void)fclose(fp); + + /* Install as the real password files. */ + (void)snprintf(buf, sizeof(buf), "%s.tmp", _PATH_MP_DB); + mv(buf, _PATH_MP_DB); + (void)snprintf(buf, sizeof(buf), "%s.tmp", _PATH_SMP_DB); + mv(buf, _PATH_SMP_DB); + if (makeold) { + (void)snprintf(buf, sizeof(buf), "%s.orig", pname); + mv(buf, _PATH_PASSWD); + } + /* + * Move the master password LAST -- chpass(1), passwd(1) and vipw(8) + * all use flock(2) on it to block other incarnations of themselves. + * The rename means that everything is unlocked, as the original file + * can no longer be accessed. + */ + mv(pname, _PATH_MASTERPASSWD); + exit(0); +} + +int +scan(fp, pw) + FILE *fp; + struct passwd *pw; +{ + static int lcnt; + static char line[LINE_MAX]; + char *p; + + if (!fgets(line, sizeof(line), fp)) + return (0); + ++lcnt; + /* + * ``... if I swallow anything evil, put your fingers down my + * throat...'' + * -- The Who + */ + if (!(p = strchr(line, '\n'))) { + warnx("line too long"); + goto fmt; + + } + *p = '\0'; + if (!pw_scan(line, pw)) { + warnx("at line #%d", lcnt); +fmt: errno = EFTYPE; /* XXX */ + error(pname); + } + + return (1); +} + +void +mv(from, to) + char *from, *to; +{ + char buf[MAXPATHLEN]; + + if (rename(from, to)) { + int sverrno = errno; + (void)snprintf(buf, sizeof(buf), "%s to %s", from, to); + errno = sverrno; + error(buf); + } +} + +void +error(name) + char *name; +{ + + warn(name); + cleanup(); + exit(1); +} + +void +cleanup() +{ + char buf[MAXPATHLEN]; + + switch(clean) { + case FILE_ORIG: + (void)snprintf(buf, sizeof(buf), "%s.orig", pname); + (void)unlink(buf); + /* FALLTHROUGH */ + case FILE_SECURE: + (void)snprintf(buf, sizeof(buf), "%s.tmp", _PATH_SMP_DB); + (void)unlink(buf); + /* FALLTHROUGH */ + case FILE_INSECURE: + (void)snprintf(buf, sizeof(buf), "%s.tmp", _PATH_MP_DB); + (void)unlink(buf); + } +} + +void +usage() +{ + + (void)fprintf(stderr, "usage: pwd_mkdb [-p] file\n"); + exit(1); +} diff --git a/usr.sbin/quotaon/Makefile b/usr.sbin/quotaon/Makefile new file mode 100644 index 0000000..b2f571b --- /dev/null +++ b/usr.sbin/quotaon/Makefile @@ -0,0 +1,8 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= quotaon +MAN8= quotaon.0 +MLINKS= quotaon.8 quotaoff.8 +LINKS= ${BINDIR}/quotaon ${BINDIR}/quotaoff + +.include diff --git a/usr.sbin/quotaon/quotaon.8 b/usr.sbin/quotaon/quotaon.8 new file mode 100644 index 0000000..8c68d76 --- /dev/null +++ b/usr.sbin/quotaon/quotaon.8 @@ -0,0 +1,139 @@ +.\" Copyright (c) 1983, 1990, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Robert Elz at The University of Melbourne. +.\" 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. +.\" +.\" @(#)quotaon.8 8.2 (Berkeley) 12/11/93 +.\" +.Dd December 11, 1993 +.Dt QUOTAON 8 +.Os BSD 4.2 +.Sh NAME +.Nm quotaon , +.Nm quotaoff +.Nd turn filesystem quotas on and off +.Sh SYNOPSIS +.Nm quotaon +.Op Fl g +.Op Fl u +.Op Fl v +.Ar filesystem Ar ... +.Nm quotaon +.Op Fl g +.Op Fl u +.Op Fl v +.Fl a +.Nm quotaoff +.Op Fl g +.Op Fl u +.Op Fl v +.Ar filesystem Ar ... +.Nm quotaoff +.Op Fl g +.Op Fl u +.Op Fl v +.Fl a +.Sh DESCRIPTION +.Nm Quotaon +announces to the system that disk quotas should be enabled on one or more +filesystems. +.Nm Quotaoff +announces to the system that the specified +filesystems should have any disk quotas +diskquotas turned off. +The filesystems specified must have entries in +.Pa /etc/fstab +and be mounted. +.Nm Quotaon +expects each filesystem to have quota files named +.Pa quota.user +and +.Pa quota.group +which are located at the root of the associated file system. +These defaults may be overridden in +.Pa /etc/fstab . +By default both user and group quotas are enabled. +.Pp +Available options: +.Bl -tag -width Ds +.It Fl a +If the +.Fl a +flag is supplied in place of any filesystem names, +.Nm quotaon Ns / Ns Nm quotaoff +will enable/disable all the filesystems indicated in +.Pa /etc/fstab +to be read-write with disk quotas. +By default only the types of quotas listed in +.Pa /etc/fstab +are enabled. +.It Fl g +Only group quotas listed in +.Pa /etc/fstab +should be enabled/disabled. +.It Fl u +Only user quotas listed in +.Pa /etc/fstab +should be enabled/disabled. +.It Fl v +Causes +.Nm quotaon +and +.Nm quotaoff +to print a message for each filesystem where quotas are turned on or off. +.El +.Pp +Specifying both +.Fl g +and +.Fl u +is equivalent to the default. +.Sh FILES +.Bl -tag -width quota.group -compact +.It Pa quota.user +at the filesystem root with user quotas +.It Pa quota.group +at the filesystem root with group quotas +.It Pa /etc/fstab +filesystem table +.El +.Sh SEE ALSO +.Xr quota 1 , +.Xr quotactl 2 , +.Xr fstab 5 , +.Xr edquota 8 , +.Xr quotacheck 8 , +.Xr repquota 8 +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.2 . diff --git a/usr.sbin/quotaon/quotaon.c b/usr.sbin/quotaon/quotaon.c new file mode 100644 index 0000000..8eabd27 --- /dev/null +++ b/usr.sbin/quotaon/quotaon.c @@ -0,0 +1,251 @@ +/* + * Copyright (c) 1980, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Robert Elz at The University of Melbourne. + * + * 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) 1980, 1990, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)quotaon.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Turn quota on/off for a filesystem. + */ +#include +#include +#include +#include +#include +#include + +char *qfname = QUOTAFILENAME; +char *qfextension[] = INITQFNAMES; + +int aflag; /* all file systems */ +int gflag; /* operate on group quotas */ +int uflag; /* operate on user quotas */ +int vflag; /* verbose */ + +main(argc, argv) + int argc; + char **argv; +{ + register struct fstab *fs; + char ch, *qfnp, *whoami, *rindex(); + long argnum, done = 0; + int i, offmode = 0, errs = 0; + extern char *optarg; + extern int optind; + + whoami = rindex(*argv, '/') + 1; + if (whoami == (char *)1) + whoami = *argv; + if (strcmp(whoami, "quotaoff") == 0) + offmode++; + else if (strcmp(whoami, "quotaon") != 0) { + fprintf(stderr, "Name must be quotaon or quotaoff not %s\n", + whoami); + exit(1); + } + while ((ch = getopt(argc, argv, "avug")) != EOF) { + switch(ch) { + case 'a': + aflag++; + break; + case 'g': + gflag++; + break; + case 'u': + uflag++; + break; + case 'v': + vflag++; + break; + default: + usage(whoami); + } + } + argc -= optind; + argv += optind; + if (argc <= 0 && !aflag) + usage(whoami); + if (!gflag && !uflag) { + gflag++; + uflag++; + } + setfsent(); + while ((fs = getfsent()) != NULL) { + if (strcmp(fs->fs_vfstype, "ufs") || + strcmp(fs->fs_type, FSTAB_RW)) + continue; + if (aflag) { + if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) + errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp); + if (uflag && hasquota(fs, USRQUOTA, &qfnp)) + errs += quotaonoff(fs, offmode, USRQUOTA, qfnp); + continue; + } + if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || + (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { + done |= 1 << argnum; + if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) + errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp); + if (uflag && hasquota(fs, USRQUOTA, &qfnp)) + errs += quotaonoff(fs, offmode, USRQUOTA, qfnp); + } + } + endfsent(); + for (i = 0; i < argc; i++) + if ((done & (1 << i)) == 0) + fprintf(stderr, "%s not found in fstab\n", + argv[i]); + exit(errs); +} + +usage(whoami) + char *whoami; +{ + + fprintf(stderr, "Usage:\n\t%s [-g] [-u] [-v] -a\n", whoami); + fprintf(stderr, "\t%s [-g] [-u] [-v] filesys ...\n", whoami); + exit(1); +} + +quotaonoff(fs, offmode, type, qfpathname) + register struct fstab *fs; + int offmode, type; + char *qfpathname; +{ + + if (strcmp(fs->fs_file, "/") && readonly(fs)) + return (1); + if (offmode) { + if (quotactl(fs->fs_file, QCMD(Q_QUOTAOFF, type), 0, 0) < 0) { + fprintf(stderr, "quotaoff: "); + perror(fs->fs_file); + return (1); + } + if (vflag) + printf("%s: quotas turned off\n", fs->fs_file); + return (0); + } + if (quotactl(fs->fs_file, QCMD(Q_QUOTAON, type), 0, qfpathname) < 0) { + fprintf(stderr, "quotaon: using %s on", qfpathname); + perror(fs->fs_file); + return (1); + } + if (vflag) + printf("%s: %s quotas turned on\n", fs->fs_file, + qfextension[type]); + return (0); +} + +/* + * Check to see if target appears in list of size cnt. + */ +oneof(target, list, cnt) + register char *target, *list[]; + int cnt; +{ + register int i; + + for (i = 0; i < cnt; i++) + if (strcmp(target, list[i]) == 0) + return (i); + return (-1); +} + +/* + * Check to see if a particular quota is to be enabled. + */ +hasquota(fs, type, qfnamep) + register struct fstab *fs; + int type; + char **qfnamep; +{ + register char *opt; + char *cp, *index(), *strtok(); + static char initname, usrname[100], grpname[100]; + static char buf[BUFSIZ]; + + if (!initname) { + sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname); + sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname); + initname = 1; + } + strcpy(buf, fs->fs_mntops); + for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { + if (cp = index(opt, '=')) + *cp++ = '\0'; + if (type == USRQUOTA && strcmp(opt, usrname) == 0) + break; + if (type == GRPQUOTA && strcmp(opt, grpname) == 0) + break; + } + if (!opt) + return (0); + if (cp) { + *qfnamep = cp; + return (1); + } + (void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]); + *qfnamep = buf; + return (1); +} + +/* + * Verify file system is mounted and not readonly. + */ +readonly(fs) + register struct fstab *fs; +{ + struct statfs fsbuf; + + if (statfs(fs->fs_file, &fsbuf) < 0 || + strcmp(fsbuf.f_mntonname, fs->fs_file) || + strcmp(fsbuf.f_mntfromname, fs->fs_spec)) { + printf("%s: not mounted\n", fs->fs_file); + return (1); + } + if (fsbuf.f_flags & MNT_RDONLY) { + printf("%s: mounted read-only\n", fs->fs_file); + return (1); + } + return (0); +} diff --git a/usr.sbin/repquota/Makefile b/usr.sbin/repquota/Makefile new file mode 100644 index 0000000..9330509 --- /dev/null +++ b/usr.sbin/repquota/Makefile @@ -0,0 +1,6 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= repquota +MAN8= repquota.0 + +.include diff --git a/usr.sbin/repquota/repquota.8 b/usr.sbin/repquota/repquota.8 new file mode 100644 index 0000000..6fba8e1 --- /dev/null +++ b/usr.sbin/repquota/repquota.8 @@ -0,0 +1,103 @@ +.\" Copyright (c) 1983, 1990, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Robert Elz at The University of Melbourne. +.\" +.\" 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. +.\" +.\" @(#)repquota.8 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt REPQUOTA 8 +.Os BSD 4.2 +.Sh NAME +.Nm repquota +.Nd summarize quotas for a file system +.Sh SYNOPSIS +.Nm repquota +.Op Fl g +.Op Fl u +.Op Fl v +.Ar filesystem Ar ... +.Nm repquota +.Op Fl g +.Op Fl u +.Op Fl v +.Fl a +.Sh DESCRIPTION +.Nm Repquota +prints a summary of the disk usage and quotas for the +specified file systems. +.Pp +Available options: +.Bl -tag -width Ds +.It Fl a +Print the quotas of all the filesystems listed in +.Pa /etc/fstab . +.It Fl g +Print only group quotas (the default is to print both +group and user quotas if they exist). +.It Fl u +Print only user quotas (the default is to print both +group and user quotas if they exist). +.It Fl v +Print a header line before printing each filesystem quotas. +.El +.Pp +For each user or group, the current +number files and amount of space (in kilobytes) is +printed, along with any quotas created with +.Xr edquota 8 . +.Pp +Only members of the operator group or the super-user may +use this command. +.Sh FILES +.Bl -tag -width quota.group -compact +.It Pa quota.user +at the filesystem root with user quotas +.It Pa quota.group +at the filesystem root with group quotas +.It Pa /etc/fstab +for file system names and locations +.El +.Sh SEE ALSO +.Xr quota 1 , +.Xr quotactl 2 , +.Xr fstab 5 , +.Xr edquota 8 , +.Xr quotacheck 8 , +.Xr quotaon 8 +.Sh DIAGNOSTICS +Various messages about inaccessible files; self-explanatory. +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.2 . diff --git a/usr.sbin/repquota/repquota.c b/usr.sbin/repquota/repquota.c new file mode 100644 index 0000000..29989eb --- /dev/null +++ b/usr.sbin/repquota/repquota.c @@ -0,0 +1,379 @@ +/* + * Copyright (c) 1980, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Robert Elz at The University of Melbourne. + * + * 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) 1980, 1990, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)repquota.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Quota report + */ +#include +#include +#include +#include +#include +#include +#include +#include + +char *qfname = QUOTAFILENAME; +char *qfextension[] = INITQFNAMES; + +struct fileusage { + struct fileusage *fu_next; + struct dqblk fu_dqblk; + u_long fu_id; + char fu_name[1]; + /* actually bigger */ +}; +#define FUHASH 1024 /* must be power of two */ +struct fileusage *fuhead[MAXQUOTAS][FUHASH]; +struct fileusage *lookup(); +struct fileusage *addid(); +u_long highid[MAXQUOTAS]; /* highest addid()'ed identifier per type */ + +int vflag; /* verbose */ +int aflag; /* all file systems */ + +main(argc, argv) + int argc; + char **argv; +{ + register struct fstab *fs; + register struct passwd *pw; + register struct group *gr; + int gflag = 0, uflag = 0, errs = 0; + long i, argnum, done = 0; + extern char *optarg; + extern int optind; + char ch, *qfnp; + + while ((ch = getopt(argc, argv, "aguv")) != EOF) { + switch(ch) { + case 'a': + aflag++; + break; + case 'g': + gflag++; + break; + case 'u': + uflag++; + break; + case 'v': + vflag++; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + if (argc == 0 && !aflag) + usage(); + if (!gflag && !uflag) { + if (aflag) + gflag++; + uflag++; + } + if (gflag) { + setgrent(); + while ((gr = getgrent()) != 0) + (void) addid((u_long)gr->gr_gid, GRPQUOTA, gr->gr_name); + endgrent(); + } + if (uflag) { + setpwent(); + while ((pw = getpwent()) != 0) + (void) addid((u_long)pw->pw_uid, USRQUOTA, pw->pw_name); + endpwent(); + } + setfsent(); + while ((fs = getfsent()) != NULL) { + if (strcmp(fs->fs_vfstype, "ufs")) + continue; + if (aflag) { + if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) + errs += repquota(fs, GRPQUOTA, qfnp); + if (uflag && hasquota(fs, USRQUOTA, &qfnp)) + errs += repquota(fs, USRQUOTA, qfnp); + continue; + } + if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || + (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { + done |= 1 << argnum; + if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) + errs += repquota(fs, GRPQUOTA, qfnp); + if (uflag && hasquota(fs, USRQUOTA, &qfnp)) + errs += repquota(fs, USRQUOTA, qfnp); + } + } + endfsent(); + for (i = 0; i < argc; i++) + if ((done & (1 << i)) == 0) + fprintf(stderr, "%s not found in fstab\n", argv[i]); + exit(errs); +} + +usage() +{ + fprintf(stderr, "Usage:\n\t%s\n\t%s\n", + "repquota [-v] [-g] [-u] -a", + "repquota [-v] [-g] [-u] filesys ..."); + exit(1); +} + +repquota(fs, type, qfpathname) + register struct fstab *fs; + int type; + char *qfpathname; +{ + register struct fileusage *fup; + FILE *qf; + u_long id; + struct dqblk dqbuf; + char *timeprt(); + static struct dqblk zerodqblk; + static int warned = 0; + static int multiple = 0; + extern int errno; + + if (quotactl(fs->fs_file, QCMD(Q_SYNC, type), 0, 0) < 0 && + errno == EOPNOTSUPP && !warned && vflag) { + warned++; + fprintf(stdout, + "*** Warning: Quotas are not compiled into this kernel\n"); + } + if (multiple++) + printf("\n"); + if (vflag) + fprintf(stdout, "*** Report for %s quotas on %s (%s)\n", + qfextension[type], fs->fs_file, fs->fs_spec); + if ((qf = fopen(qfpathname, "r")) == NULL) { + perror(qfpathname); + return (1); + } + for (id = 0; ; id++) { + fread(&dqbuf, sizeof(struct dqblk), 1, qf); + if (feof(qf)) + break; + if (dqbuf.dqb_curinodes == 0 && dqbuf.dqb_curblocks == 0) + continue; + if ((fup = lookup(id, type)) == 0) + fup = addid(id, type, (char *)0); + fup->fu_dqblk = dqbuf; + } + fclose(qf); + printf(" Block limits File limits\n"); + printf("User used soft hard grace used soft hard grace\n"); + for (id = 0; id <= highid[type]; id++) { + fup = lookup(id, type); + if (fup == 0) + continue; + if (fup->fu_dqblk.dqb_curinodes == 0 && + fup->fu_dqblk.dqb_curblocks == 0) + continue; + printf("%-10s", fup->fu_name); + printf("%c%c%8d%8d%8d%7s", + fup->fu_dqblk.dqb_bsoftlimit && + fup->fu_dqblk.dqb_curblocks >= + fup->fu_dqblk.dqb_bsoftlimit ? '+' : '-', + fup->fu_dqblk.dqb_isoftlimit && + fup->fu_dqblk.dqb_curinodes >= + fup->fu_dqblk.dqb_isoftlimit ? '+' : '-', + dbtob(fup->fu_dqblk.dqb_curblocks) / 1024, + dbtob(fup->fu_dqblk.dqb_bsoftlimit) / 1024, + dbtob(fup->fu_dqblk.dqb_bhardlimit) / 1024, + fup->fu_dqblk.dqb_bsoftlimit && + fup->fu_dqblk.dqb_curblocks >= + fup->fu_dqblk.dqb_bsoftlimit ? + timeprt(fup->fu_dqblk.dqb_btime) : ""); + printf(" %6d%6d%6d%7s\n", + fup->fu_dqblk.dqb_curinodes, + fup->fu_dqblk.dqb_isoftlimit, + fup->fu_dqblk.dqb_ihardlimit, + fup->fu_dqblk.dqb_isoftlimit && + fup->fu_dqblk.dqb_curinodes >= + fup->fu_dqblk.dqb_isoftlimit ? + timeprt(fup->fu_dqblk.dqb_itime) : ""); + fup->fu_dqblk = zerodqblk; + } + return (0); +} + +/* + * Check to see if target appears in list of size cnt. + */ +oneof(target, list, cnt) + register char *target, *list[]; + int cnt; +{ + register int i; + + for (i = 0; i < cnt; i++) + if (strcmp(target, list[i]) == 0) + return (i); + return (-1); +} + +/* + * Check to see if a particular quota is to be enabled. + */ +hasquota(fs, type, qfnamep) + register struct fstab *fs; + int type; + char **qfnamep; +{ + register char *opt; + char *cp, *index(), *strtok(); + static char initname, usrname[100], grpname[100]; + static char buf[BUFSIZ]; + + if (!initname) { + sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname); + sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname); + initname = 1; + } + strcpy(buf, fs->fs_mntops); + for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { + if (cp = index(opt, '=')) + *cp++ = '\0'; + if (type == USRQUOTA && strcmp(opt, usrname) == 0) + break; + if (type == GRPQUOTA && strcmp(opt, grpname) == 0) + break; + } + if (!opt) + return (0); + if (cp) { + *qfnamep = cp; + return (1); + } + (void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]); + *qfnamep = buf; + return (1); +} + +/* + * Routines to manage the file usage table. + * + * Lookup an id of a specific type. + */ +struct fileusage * +lookup(id, type) + u_long id; + int type; +{ + register struct fileusage *fup; + + for (fup = fuhead[type][id & (FUHASH-1)]; fup != 0; fup = fup->fu_next) + if (fup->fu_id == id) + return (fup); + return ((struct fileusage *)0); +} + +/* + * Add a new file usage id if it does not already exist. + */ +struct fileusage * +addid(id, type, name) + u_long id; + int type; + char *name; +{ + struct fileusage *fup, **fhp; + int len; + extern char *calloc(); + + if (fup = lookup(id, type)) + return (fup); + if (name) + len = strlen(name); + else + len = 10; + if ((fup = (struct fileusage *)calloc(1, sizeof(*fup) + len)) == NULL) { + fprintf(stderr, "out of memory for fileusage structures\n"); + exit(1); + } + fhp = &fuhead[type][id & (FUHASH - 1)]; + fup->fu_next = *fhp; + *fhp = fup; + fup->fu_id = id; + if (id > highid[type]) + highid[type] = id; + if (name) { + bcopy(name, fup->fu_name, len + 1); + } else { + sprintf(fup->fu_name, "%u", id); + } + return (fup); +} + +/* + * Calculate the grace period and return a printable string for it. + */ +char * +timeprt(seconds) + time_t seconds; +{ + time_t hours, minutes; + static char buf[20]; + static time_t now; + + if (now == 0) + time(&now); + if (now > seconds) + return ("none"); + seconds -= now; + minutes = (seconds + 30) / 60; + hours = (minutes + 30) / 60; + if (hours >= 36) { + sprintf(buf, "%ddays", (hours + 12) / 24); + return (buf); + } + if (minutes >= 60) { + sprintf(buf, "%2d:%d", minutes / 60, minutes % 60); + return (buf); + } + sprintf(buf, "%2d", minutes); + return (buf); +} diff --git a/usr.sbin/rmt/Makefile b/usr.sbin/rmt/Makefile new file mode 100644 index 0000000..c55ae71 --- /dev/null +++ b/usr.sbin/rmt/Makefile @@ -0,0 +1,6 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= rmt +MAN8= rmt.0 + +.include diff --git a/usr.sbin/rmt/rmt.8 b/usr.sbin/rmt/rmt.8 new file mode 100644 index 0000000..fae5628 --- /dev/null +++ b/usr.sbin/rmt/rmt.8 @@ -0,0 +1,217 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" @(#)rmt.8 8.2 (Berkeley) 12/11/93 +.\" +.Dd December 11, 1993 +.Dt RMT 8 +.Os BSD 4.2 +.Sh NAME +.Nm rmt +.Nd remote magtape protocol module +.Sh SYNOPSIS +.Nm rmt +.Sh DESCRIPTION +.Nm Rmt +is a program used by the remote dump and restore programs +in manipulating a magnetic tape drive through an interprocess +communication connection. +.Nm Rmt +is normally started up with an +.Xr rexec 3 +or +.Xr rcmd 3 +call. +.Pp +The +.Nm rmt +program accepts requests specific to the manipulation of +magnetic tapes, performs the commands, then responds with +a status indication. All responses are in +.Tn ASCII +and in +one of two forms. +Successful commands have responses of: +.Bd -filled -offset indent +.Sm off +.Sy A Ar number No \en +.Sm on +.Ed +.Pp +.Ar Number +is an +.Tn ASCII +representation of a decimal number. +Unsuccessful commands are responded to with: +.Bd -filled -offset indent +.Sm off +.Xo Sy E Ar error-number +.No \en Ar error-message +.No \en +.Xc +.Sm on +.Ed +.Pp +.Ar Error-number +is one of the possible error +numbers described in +.Xr intro 2 +and +.Ar error-message +is the corresponding error string as printed +from a call to +.Xr perror 3 . +The protocol is comprised of the +following commands, which are sent as indicated - no spaces are supplied +between the command and its arguments, or between its arguments, and +.Ql \en +indicates that a newline should be supplied: +.Bl -tag -width Ds +.Sm off +.It Xo Sy \&O Ar device +.No \en Ar mode No \en +.Xc +Open the specified +.Ar device +using the indicated +.Ar mode . +.Ar Device +is a full pathname and +.Ar mode +is an +.Tn ASCII +representation of a decimal +number suitable for passing to +.Xr open 2 . +If a device had already been opened, it is +closed before a new open is performed. +.It Xo Sy C Ar device No \en +.Xc +Close the currently open device. The +.Ar device +specified is ignored. +.It Xo Sy L +.Ar whence No \en +.Ar offset No \en +.Xc +.Sm on +Perform an +.Xr lseek 2 +operation using the specified parameters. +The response value is that returned from the +.Xr lseek +call. +.Sm off +.It Sy W Ar count No \en +.Sm on +Write data onto the open device. +.Nm Rmt +reads +.Ar count +bytes from the connection, aborting if +a premature end-of-file is encountered. +The response value is that returned from +the +.Xr write 2 +call. +.Sm off +.It Sy R Ar count No \en +.Sm on +Read +.Ar count +bytes of data from the open device. +If +.Ar count +exceeds the size of the data buffer (10 kilobytes), it is +truncated to the data buffer size. +.Nm rmt +then performs the requested +.Xr read 2 +and responds with +.Sm off +.Sy A Ar count-read No \en +.Sm on +if the read was +successful; otherwise an error in the +standard format is returned. If the read +was successful, the data read is then sent. +.Sm off +.It Xo Sy I Ar operation +.No \en Ar count No \en +.Xc +.Sm on +Perform a +.Dv MTIOCOP +.Xr ioctl 2 +command using the specified parameters. +The parameters are interpreted as the +.Tn ASCII +representations of the decimal values +to place in the +.Ar mt_op +and +.Ar mt_count +fields of the structure used in the +.Xr ioctl +call. The return value is the +.Ar count +parameter when the operation is successful. +.It Sy S +Return the status of the open device, as +obtained with a +.Dv MTIOCGET +.Xr ioctl +call. If the operation was successful, +an ``ack'' is sent with the size of the +status buffer, then the status buffer is +sent (in binary). +.El +.Sm on +.Pp +Any other command causes +.Nm rmt +to exit. +.Sh DIAGNOSTICS +All responses are of the form described above. +.Sh SEE ALSO +.Xr rcmd 3 , +.Xr rexec 3 , +.Xr mtio 4 , +.Xr rdump 8 , +.Xr rrestore 8 +.Sh BUGS +People should be discouraged from using this for a remote +file access protocol. +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.2 . diff --git a/usr.sbin/rmt/rmt.c b/usr.sbin/rmt/rmt.c new file mode 100644 index 0000000..098e502 --- /dev/null +++ b/usr.sbin/rmt/rmt.c @@ -0,0 +1,244 @@ +/* + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)rmt.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * rmt + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int tape = -1; + +char *record; +int maxrecsize = -1; + +#define SSIZE 64 +char device[SSIZE]; +char count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE]; + +char resp[BUFSIZ]; + +FILE *debug; +#define DEBUG(f) if (debug) fprintf(debug, f) +#define DEBUG1(f,a) if (debug) fprintf(debug, f, a) +#define DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2) + +char *checkbuf __P((char *, int)); +void error __P((int)); +void getstring __P((char *)); + +int +main(argc, argv) + int argc; + char **argv; +{ + int rval; + char c; + int n, i, cc; + + argc--, argv++; + if (argc > 0) { + debug = fopen(*argv, "w"); + if (debug == 0) + exit(1); + (void)setbuf(debug, (char *)0); + } +top: + errno = 0; + rval = 0; + if (read(0, &c, 1) != 1) + exit(0); + switch (c) { + + case 'O': + if (tape >= 0) + (void) close(tape); + getstring(device); + getstring(mode); + DEBUG2("rmtd: O %s %s\n", device, mode); + tape = open(device, atoi(mode)); + if (tape < 0) + goto ioerror; + goto respond; + + case 'C': + DEBUG("rmtd: C\n"); + getstring(device); /* discard */ + if (close(tape) < 0) + goto ioerror; + tape = -1; + goto respond; + + case 'L': + getstring(count); + getstring(pos); + DEBUG2("rmtd: L %s %s\n", count, pos); + rval = lseek(tape, (off_t)atol(count), atoi(pos)); + if (rval < 0) + goto ioerror; + goto respond; + + case 'W': + getstring(count); + n = atoi(count); + DEBUG1("rmtd: W %s\n", count); + record = checkbuf(record, n); + for (i = 0; i < n; i += cc) { + cc = read(0, &record[i], n - i); + if (cc <= 0) { + DEBUG("rmtd: premature eof\n"); + exit(2); + } + } + rval = write(tape, record, n); + if (rval < 0) + goto ioerror; + goto respond; + + case 'R': + getstring(count); + DEBUG1("rmtd: R %s\n", count); + n = atoi(count); + record = checkbuf(record, n); + rval = read(tape, record, n); + if (rval < 0) + goto ioerror; + (void)sprintf(resp, "A%d\n", rval); + (void)write(1, resp, strlen(resp)); + (void)write(1, record, rval); + goto top; + + case 'I': + getstring(op); + getstring(count); + DEBUG2("rmtd: I %s %s\n", op, count); + { struct mtop mtop; + mtop.mt_op = atoi(op); + mtop.mt_count = atoi(count); + if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0) + goto ioerror; + rval = mtop.mt_count; + } + goto respond; + + case 'S': /* status */ + DEBUG("rmtd: S\n"); + { struct mtget mtget; + if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0) + goto ioerror; + rval = sizeof (mtget); + (void)sprintf(resp, "A%d\n", rval); + (void)write(1, resp, strlen(resp)); + (void)write(1, (char *)&mtget, sizeof (mtget)); + goto top; + } + + default: + DEBUG1("rmtd: garbage command %c\n", c); + exit(3); + } +respond: + DEBUG1("rmtd: A %d\n", rval); + (void)sprintf(resp, "A%d\n", rval); + (void)write(1, resp, strlen(resp)); + goto top; +ioerror: + error(errno); + goto top; +} + +void +getstring(bp) + char *bp; +{ + int i; + char *cp = bp; + + for (i = 0; i < SSIZE; i++) { + if (read(0, cp+i, 1) != 1) + exit(0); + if (cp[i] == '\n') + break; + } + cp[i] = '\0'; +} + +char * +checkbuf(record, size) + char *record; + int size; +{ + + if (size <= maxrecsize) + return (record); + if (record != 0) + free(record); + record = malloc(size); + if (record == 0) { + DEBUG("rmtd: cannot allocate buffer space\n"); + exit(4); + } + maxrecsize = size; + while (size > 1024 && + setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0) + size -= 1024; + return (record); +} + +void +error(num) + int num; +{ + + DEBUG2("rmtd: E %d (%s)\n", num, strerror(num)); + (void)sprintf(resp, "E%d\n%s\n", num, strerror(num)); + (void)write(1, resp, strlen(resp)); +} diff --git a/usr.sbin/rwhod/Makefile b/usr.sbin/rwhod/Makefile new file mode 100644 index 0000000..5846743 --- /dev/null +++ b/usr.sbin/rwhod/Makefile @@ -0,0 +1,6 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= rwhod +MAN8= rwhod.0 + +.include diff --git a/usr.sbin/rwhod/rwhod.8 b/usr.sbin/rwhod/rwhod.8 new file mode 100644 index 0000000..4b8492e --- /dev/null +++ b/usr.sbin/rwhod/rwhod.8 @@ -0,0 +1,146 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" @(#)rwhod.8 8.2 (Berkeley) 12/11/93 +.\" +.Dd December 11, 1993 +.Dt RWHOD 8 +.Os BSD 4.2 +.Sh NAME +.Nm rwhod +.Nd system status server +.Sh SYNOPSIS +.Nm rwhod +.Sh DESCRIPTION +.Nm Rwhod +is the server which maintains the database used by the +.Xr rwho 1 +and +.Xr ruptime 1 +programs. Its operation is predicated on the ability to +.Em broadcast +messages on a network. +.Pp +.Nm Rwhod +operates as both a producer and consumer of status information. +As a producer of information it periodically +queries the state of the system and constructs +status messages which are broadcast on a network. +As a consumer of information, it listens for other +.Nm rwhod +servers' status messages, validating them, then recording +them in a collection of files located in the directory +.Pa /var/rwho . +.Pp +The server transmits and receives messages at the port indicated +in the ``rwho'' service specification; see +.Xr services 5 . +The messages sent and received, are of the form: +.Bd -literal -offset indent +struct outmp { + char out_line[8]; /* tty name */ + char out_name[8]; /* user id */ + long out_time; /* time on */ +}; + +struct whod { + char wd_vers; + char wd_type; + char wd_fill[2]; + int wd_sendtime; + int wd_recvtime; + char wd_hostname[32]; + int wd_loadav[3]; + int wd_boottime; + struct whoent { + struct outmp we_utmp; + int we_idle; + } wd_we[1024 / sizeof (struct whoent)]; +}; +.Ed +.Pp +All fields are converted to network byte order prior to +transmission. The load averages are as calculated by the +.Xr w 1 +program, and represent load averages over the 5, 10, and 15 minute +intervals prior to a server's transmission; they are multiplied by 100 +for representation in an integer. The host name +included is that returned by the +.Xr gethostname 2 +system call, with any trailing domain name omitted. +The array at the end of the message contains information about +the users logged in to the sending machine. This information +includes the contents of the +.Xr utmp 5 +entry for each non-idle terminal line and a value indicating the +time in seconds since a character was last received on the terminal line. +.Pp +Messages received by the +.Xr rwho +server are discarded unless they originated at an +.Xr rwho +server's port. In addition, if the host's name, as specified +in the message, contains any unprintable +.Tn ASCII +characters, the +message is discarded. Valid messages received by +.Nm rwhod +are placed in files named +.Pa whod.hostname +in the directory +.Pa /var/rwho . +These files contain only the most recent message, in the +format described above. +.Pp +Status messages are generated approximately once every +3 minutes. +.Nm Rwhod +performs an +.Xr nlist 3 +on +.Pa /vmunix +every 30 minutes to guard against +the possibility that this file is not the system +image currently operating. +.Sh SEE ALSO +.Xr rwho 1 , +.Xr ruptime 1 +.Sh BUGS +There should be a way to relay status information between networks. +Status information should be sent only upon request rather than continuously. +People often interpret the server dying +or network communication failures +as a machine going down. +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.2 . diff --git a/usr.sbin/rwhod/rwhod.c b/usr.sbin/rwhod/rwhod.c new file mode 100644 index 0000000..75c02ff --- /dev/null +++ b/usr.sbin/rwhod/rwhod.c @@ -0,0 +1,539 @@ +/* + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)rwhod.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Alarm interval. Don't forget to change the down time check in ruptime + * if this is changed. + */ +#define AL_INTERVAL (3 * 60) + +char myname[MAXHOSTNAMELEN]; + +/* + * We communicate with each neighbor in a list constructed at the time we're + * started up. Neighbors are currently directly connected via a hardware + * interface. + */ +struct neighbor { + struct neighbor *n_next; + char *n_name; /* interface name */ + struct sockaddr *n_addr; /* who to send to */ + int n_addrlen; /* size of address */ + int n_flags; /* should forward?, interface flags */ +}; + +struct neighbor *neighbors; +struct whod mywd; +struct servent *sp; +int s, utmpf; + +#define WHDRSIZE (sizeof(mywd) - sizeof(mywd.wd_we)) + +int configure __P((int)); +void getboottime __P((int)); +void onalrm __P((int)); +void quit __P((char *)); +void rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *)); +int verify __P((char *)); +#ifdef DEBUG +char *interval __P((int, char *)); +void Sendto __P((int, char *, int, int, char *, int)); +#define sendto Sendto +#endif + +int +main(argc, argv) + int argc; + char argv[]; +{ + struct sockaddr_in from; + struct stat st; + char path[64]; + int on = 1; + char *cp; + struct sockaddr_in sin; + + if (getuid()) { + fprintf(stderr, "rwhod: not super user\n"); + exit(1); + } + sp = getservbyname("who", "udp"); + if (sp == NULL) { + fprintf(stderr, "rwhod: udp/who: unknown service\n"); + exit(1); + } +#ifndef DEBUG + daemon(1, 0); +#endif + if (chdir(_PATH_RWHODIR) < 0) { + (void)fprintf(stderr, "rwhod: %s: %s\n", + _PATH_RWHODIR, strerror(errno)); + exit(1); + } + (void) signal(SIGHUP, getboottime); + openlog("rwhod", LOG_PID, LOG_DAEMON); + /* + * Establish host name as returned by system. + */ + if (gethostname(myname, sizeof(myname) - 1) < 0) { + syslog(LOG_ERR, "gethostname: %m"); + exit(1); + } + if ((cp = index(myname, '.')) != NULL) + *cp = '\0'; + strncpy(mywd.wd_hostname, myname, sizeof(myname) - 1); + utmpf = open(_PATH_UTMP, O_RDONLY|O_CREAT, 0644); + if (utmpf < 0) { + syslog(LOG_ERR, "%s: %m", _PATH_UTMP); + exit(1); + } + getboottime(0); + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + syslog(LOG_ERR, "socket: %m"); + exit(1); + } + if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) { + syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m"); + exit(1); + } + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = sp->s_port; + if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + syslog(LOG_ERR, "bind: %m"); + exit(1); + } + if (!configure(s)) + exit(1); + signal(SIGALRM, onalrm); + onalrm(0); + for (;;) { + struct whod wd; + int cc, whod, len = sizeof(from); + + cc = recvfrom(s, (char *)&wd, sizeof(struct whod), 0, + (struct sockaddr *)&from, &len); + if (cc <= 0) { + if (cc < 0 && errno != EINTR) + syslog(LOG_WARNING, "recv: %m"); + continue; + } + if (from.sin_port != sp->s_port) { + syslog(LOG_WARNING, "%d: bad from port", + ntohs(from.sin_port)); + continue; + } + if (wd.wd_vers != WHODVERSION) + continue; + if (wd.wd_type != WHODTYPE_STATUS) + continue; + if (!verify(wd.wd_hostname)) { + syslog(LOG_WARNING, "malformed host name from %x", + from.sin_addr); + continue; + } + (void) sprintf(path, "whod.%s", wd.wd_hostname); + /* + * Rather than truncating and growing the file each time, + * use ftruncate if size is less than previous size. + */ + whod = open(path, O_WRONLY | O_CREAT, 0644); + if (whod < 0) { + syslog(LOG_WARNING, "%s: %m", path); + continue; + } +#if ENDIAN != BIG_ENDIAN + { + int i, n = (cc - WHDRSIZE)/sizeof(struct whoent); + struct whoent *we; + + /* undo header byte swapping before writing to file */ + wd.wd_sendtime = ntohl(wd.wd_sendtime); + for (i = 0; i < 3; i++) + wd.wd_loadav[i] = ntohl(wd.wd_loadav[i]); + wd.wd_boottime = ntohl(wd.wd_boottime); + we = wd.wd_we; + for (i = 0; i < n; i++) { + we->we_idle = ntohl(we->we_idle); + we->we_utmp.out_time = + ntohl(we->we_utmp.out_time); + we++; + } + } +#endif + (void) time((time_t *)&wd.wd_recvtime); + (void) write(whod, (char *)&wd, cc); + if (fstat(whod, &st) < 0 || st.st_size > cc) + ftruncate(whod, cc); + (void) close(whod); + } +} + +/* + * Check out host name for unprintables + * and other funnies before allowing a file + * to be created. Sorry, but blanks aren't allowed. + */ +int +verify(name) + register char *name; +{ + register int size = 0; + + while (*name) { + if (!isascii(*name) || !(isalnum(*name) || ispunct(*name))) + return (0); + name++, size++; + } + return (size > 0); +} + +int utmptime; +int utmpent; +int utmpsize = 0; +struct utmp *utmp; +int alarmcount; + +void +onalrm(signo) + int signo; +{ + register struct neighbor *np; + register struct whoent *we = mywd.wd_we, *wlast; + register int i; + struct stat stb; + double avenrun[3]; + time_t now; + int cc; + + now = time(NULL); + if (alarmcount % 10 == 0) + getboottime(0); + alarmcount++; + (void) fstat(utmpf, &stb); + if ((stb.st_mtime != utmptime) || (stb.st_size > utmpsize)) { + utmptime = stb.st_mtime; + if (stb.st_size > utmpsize) { + utmpsize = stb.st_size + 10 * sizeof(struct utmp); + if (utmp) + utmp = (struct utmp *)realloc(utmp, utmpsize); + else + utmp = (struct utmp *)malloc(utmpsize); + if (! utmp) { + fprintf(stderr, "rwhod: malloc failed\n"); + utmpsize = 0; + goto done; + } + } + (void) lseek(utmpf, (off_t)0, L_SET); + cc = read(utmpf, (char *)utmp, stb.st_size); + if (cc < 0) { + fprintf(stderr, "rwhod: %s: %s\n", + _PATH_UTMP, strerror(errno)); + goto done; + } + wlast = &mywd.wd_we[1024 / sizeof(struct whoent) - 1]; + utmpent = cc / sizeof(struct utmp); + for (i = 0; i < utmpent; i++) + if (utmp[i].ut_name[0]) { + memcpy(we->we_utmp.out_line, utmp[i].ut_line, + sizeof(utmp[i].ut_line)); + memcpy(we->we_utmp.out_name, utmp[i].ut_name, + sizeof(utmp[i].ut_name)); + we->we_utmp.out_time = htonl(utmp[i].ut_time); + if (we >= wlast) + break; + we++; + } + utmpent = we - mywd.wd_we; + } + + /* + * The test on utmpent looks silly---after all, if no one is + * logged on, why worry about efficiency?---but is useful on + * (e.g.) compute servers. + */ + if (utmpent && chdir(_PATH_DEV)) { + syslog(LOG_ERR, "chdir(%s): %m", _PATH_DEV); + exit(1); + } + we = mywd.wd_we; + for (i = 0; i < utmpent; i++) { + if (stat(we->we_utmp.out_line, &stb) >= 0) + we->we_idle = htonl(now - stb.st_atime); + we++; + } + (void)getloadavg(avenrun, sizeof(avenrun)/sizeof(avenrun[0])); + for (i = 0; i < 3; i++) + mywd.wd_loadav[i] = htonl((u_long)(avenrun[i] * 100)); + cc = (char *)we - (char *)&mywd; + mywd.wd_sendtime = htonl(time(0)); + mywd.wd_vers = WHODVERSION; + mywd.wd_type = WHODTYPE_STATUS; + for (np = neighbors; np != NULL; np = np->n_next) + (void)sendto(s, (char *)&mywd, cc, 0, + np->n_addr, np->n_addrlen); + if (utmpent && chdir(_PATH_RWHODIR)) { + syslog(LOG_ERR, "chdir(%s): %m", _PATH_RWHODIR); + exit(1); + } +done: + (void) alarm(AL_INTERVAL); +} + +void +getboottime(signo) + int signo; +{ + int mib[2]; + size_t size; + struct timeval tm; + + mib[0] = CTL_KERN; + mib[1] = KERN_BOOTTIME; + size = sizeof(tm); + if (sysctl(mib, 2, &tm, &size, NULL, 0) == -1) { + syslog(LOG_ERR, "cannot get boottime: %m"); + exit(1); + } + mywd.wd_boottime = htonl(tm.tv_sec); +} + +void +quit(msg) + char *msg; +{ + syslog(LOG_ERR, msg); + exit(1); +} + +#define ROUNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) +#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) + +void +rt_xaddrs(cp, cplim, rtinfo) + register caddr_t cp, cplim; + register struct rt_addrinfo *rtinfo; +{ + register struct sockaddr *sa; + register int i; + + memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info)); + for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { + if ((rtinfo->rti_addrs & (1 << i)) == 0) + continue; + rtinfo->rti_info[i] = sa = (struct sockaddr *)cp; + ADVANCE(cp, sa); + } +} + +/* + * Figure out device configuration and select + * networks which deserve status information. + */ +int +configure(s) + int s; +{ + register struct neighbor *np; + register struct if_msghdr *ifm; + register struct ifa_msghdr *ifam; + struct sockaddr_dl *sdl; + size_t needed; + int mib[6], flags = 0, len; + char *buf, *lim, *next; + struct rt_addrinfo info; + + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = AF_INET; + mib[4] = NET_RT_IFLIST; + mib[5] = 0; + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + quit("route-sysctl-estimate"); + if ((buf = malloc(needed)) == NULL) + quit("malloc"); + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) + quit("actual retrieval of interface table"); + lim = buf + needed; + + sdl = NULL; /* XXX just to keep gcc -Wall happy */ + for (next = buf; next < lim; next += ifm->ifm_msglen) { + ifm = (struct if_msghdr *)next; + if (ifm->ifm_type == RTM_IFINFO) { + sdl = (struct sockaddr_dl *)(ifm + 1); + flags = ifm->ifm_flags; + continue; + } + if ((flags & IFF_UP) == 0 || + (flags & (IFF_BROADCAST|IFF_POINTOPOINT)) == 0) + continue; + if (ifm->ifm_type != RTM_NEWADDR) + quit("out of sync parsing NET_RT_IFLIST"); + ifam = (struct ifa_msghdr *)ifm; + info.rti_addrs = ifam->ifam_addrs; + rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam, + &info); + /* gag, wish we could get rid of Internet dependencies */ +#define dstaddr info.rti_info[RTAX_BRD] +#define IPADDR_SA(x) ((struct sockaddr_in *)(x))->sin_addr.s_addr +#define PORT_SA(x) ((struct sockaddr_in *)(x))->sin_port + if (dstaddr == 0 || dstaddr->sa_family != AF_INET) + continue; + PORT_SA(dstaddr) = sp->s_port; + for (np = neighbors; np != NULL; np = np->n_next) + if (memcmp(sdl->sdl_data, np->n_name, + sdl->sdl_nlen) == 0 && + IPADDR_SA(np->n_addr) == IPADDR_SA(dstaddr)) + break; + if (np != NULL) + continue; + len = sizeof(*np) + dstaddr->sa_len + sdl->sdl_nlen + 1; + np = (struct neighbor *)malloc(len); + if (np == NULL) + quit("malloc of neighbor structure"); + memset(np, 0, len); + np->n_flags = flags; + np->n_addr = (struct sockaddr *)(np + 1); + np->n_addrlen = dstaddr->sa_len; + np->n_name = np->n_addrlen + (char *)np->n_addr; + np->n_next = neighbors; + neighbors = np; + memcpy((char *)np->n_addr, (char *)dstaddr, np->n_addrlen); + memcpy(np->n_name, sdl->sdl_data, sdl->sdl_nlen); + } + free(buf); + return (1); +} + +#ifdef DEBUG +void +Sendto(s, buf, cc, flags, to, tolen) + int s; + char *buf; + int cc, flags; + char *to; + int tolen; +{ + register struct whod *w = (struct whod *)buf; + register struct whoent *we; + struct sockaddr_in *sin = (struct sockaddr_in *)to; + + printf("sendto %x.%d\n", ntohl(sin->sin_addr), ntohs(sin->sin_port)); + printf("hostname %s %s\n", w->wd_hostname, + interval(ntohl(w->wd_sendtime) - ntohl(w->wd_boottime), " up")); + printf("load %4.2f, %4.2f, %4.2f\n", + ntohl(w->wd_loadav[0]) / 100.0, ntohl(w->wd_loadav[1]) / 100.0, + ntohl(w->wd_loadav[2]) / 100.0); + cc -= WHDRSIZE; + for (we = w->wd_we, cc /= sizeof(struct whoent); cc > 0; cc--, we++) { + time_t t = ntohl(we->we_utmp.out_time); + printf("%-8.8s %s:%s %.12s", + we->we_utmp.out_name, + w->wd_hostname, we->we_utmp.out_line, + ctime(&t)+4); + we->we_idle = ntohl(we->we_idle) / 60; + if (we->we_idle) { + if (we->we_idle >= 100*60) + we->we_idle = 100*60 - 1; + if (we->we_idle >= 60) + printf(" %2d", we->we_idle / 60); + else + printf(" "); + printf(":%02d", we->we_idle % 60); + } + printf("\n"); + } +} + +char * +interval(time, updown) + int time; + char *updown; +{ + static char resbuf[32]; + int days, hours, minutes; + + if (time < 0 || time > 3*30*24*60*60) { + (void) sprintf(resbuf, " %s ??:??", updown); + return (resbuf); + } + minutes = (time + 59) / 60; /* round to minutes */ + hours = minutes / 60; minutes %= 60; + days = hours / 24; hours %= 24; + if (days) + (void) sprintf(resbuf, "%s %2d+%02d:%02d", + updown, days, hours, minutes); + else + (void) sprintf(resbuf, "%s %2d:%02d", + updown, hours, minutes); + return (resbuf); +} +#endif diff --git a/usr.sbin/sendmail/cf/cf/alpha.mc b/usr.sbin/sendmail/cf/cf/alpha.mc new file mode 100644 index 0000000..026fed1 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/alpha.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)alpha.mc 8.1 (Berkeley) 6/7/93') +OSTYPE(osf1)dnl +DOMAIN(s2k)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/auspex.mc b/usr.sbin/sendmail/cf/cf/auspex.mc new file mode 100644 index 0000000..961c139 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/auspex.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)auspex.mc 8.1 (Berkeley) 6/7/93') +OSTYPE(sunos4.1)dnl +DOMAIN(cs.hidden)dnl +FEATURE(use_cw_file)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/chez.mc b/usr.sbin/sendmail/cf/cf/chez.mc new file mode 100644 index 0000000..13f9519 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/chez.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(`@(#)chez.mc 8.1 (Berkeley) 6/7/93') +OSTYPE(bsd4.4)dnl +DOMAIN(cs.exposed)dnl +define(`LOCAL_RELAY', vangogh.CS.Berkeley.EDU)dnl +define(`MASQUERADE_NAME', vangogh.CS.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl +Fw/etc/sendmail.cw diff --git a/usr.sbin/sendmail/cf/cf/cogsci.mc b/usr.sbin/sendmail/cf/cf/cogsci.mc new file mode 100644 index 0000000..4faa46d --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/cogsci.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)cogsci.mc 8.1 (Berkeley) 6/7/93') +DOMAIN(cs.exposed)dnl +MAILER(smtp)dnl +MAILER(uucp)dnl +SITECONFIG(uucp.cogsci, Ucogsci, U) diff --git a/usr.sbin/sendmail/cf/cf/cs-exposed.mc b/usr.sbin/sendmail/cf/cf/cs-exposed.mc new file mode 100644 index 0000000..62072b7 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/cs-exposed.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)cs-exposed.mc 8.1 (Berkeley) 6/7/93') +DOMAIN(cs.exposed)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/cs-hidden.mc b/usr.sbin/sendmail/cf/cf/cs-hidden.mc new file mode 100644 index 0000000..216062c --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/cs-hidden.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)cs-hidden.mc 8.1 (Berkeley) 6/7/93') +DOMAIN(cs.hidden)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/hpux-cs-exposed.mc b/usr.sbin/sendmail/cf/cf/hpux-cs-exposed.mc new file mode 100644 index 0000000..4f61ffd --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/hpux-cs-exposed.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)hpux-cs-exposed.mc 8.1 (Berkeley) 6/7/93') +OSTYPE(hpux)dnl +DOMAIN(cs.exposed)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/hpux-cs-hidden.mc b/usr.sbin/sendmail/cf/cf/hpux-cs-hidden.mc new file mode 100644 index 0000000..33cf580 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/hpux-cs-hidden.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)hpux-cs-hidden.mc 8.1 (Berkeley) 6/7/93') +OSTYPE(hpux)dnl +DOMAIN(cs.hidden)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/osf1-cs-exposed.mc b/usr.sbin/sendmail/cf/cf/osf1-cs-exposed.mc new file mode 100644 index 0000000..eaed6cc --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/osf1-cs-exposed.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)osf1-cs-exposed.mc 8.1 (Berkeley) 10/15/93') +OSTYPE(osf1)dnl +DOMAIN(cs.exposed)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/osf1-cs-hidden.mc b/usr.sbin/sendmail/cf/cf/osf1-cs-hidden.mc new file mode 100644 index 0000000..2b85ba4 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/osf1-cs-hidden.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)osf1-cs-hidden.mc 8.1 (Berkeley) 10/15/93') +OSTYPE(osf1)dnl +DOMAIN(cs.hidden)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/python.mc b/usr.sbin/sendmail/cf/cf/python.mc new file mode 100644 index 0000000..ac23e61 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/python.mc @@ -0,0 +1,52 @@ +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(`@(#)python.mc 8.1 (Berkeley) 6/7/93') +OSTYPE(bsd4.4)dnl +DOMAIN(cs.exposed)dnl +define(`LOCAL_RELAY', vangogh.CS.Berkeley.EDU)dnl +define(`MASQUERADE_NAME', vangogh.CS.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl + +# accept mail sent to the domain head +DDBostic.COM + +LOCAL_RULE_0 +# accept mail sent to the domain head +R< @ $D . > : $* $@ $>7 $1 @here:... -> ... +R$* $=O $* < @ $D . > $@ $>7 $1 $2 $3 ...@here -> ... +R$* < @ $D . > $#local $: $1 user@here -> user diff --git a/usr.sbin/sendmail/cf/cf/riscos-cs-exposed.mc b/usr.sbin/sendmail/cf/cf/riscos-cs-exposed.mc new file mode 100644 index 0000000..a92b770 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/riscos-cs-exposed.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)riscos-cs-exposed.mc 8.1 (Berkeley) 12/1/93') +OSTYPE(riscos4.5)dnl +DOMAIN(cs.exposed)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/s2k.mc b/usr.sbin/sendmail/cf/cf/s2k.mc new file mode 100644 index 0000000..e65fc9f --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/s2k.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)s2k.mc 8.1 (Berkeley) 6/7/93') +OLDSENDMAIL +OSTYPE(ultrix4.1)dnl +DOMAIN(s2k)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/sample.mc b/usr.sbin/sendmail/cf/cf/sample.mc new file mode 100644 index 0000000..760409d --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/sample.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)sample.mc 8.1 (Berkeley) 6/7/93') +OSTYPE(bsd4.4) +DOMAIN(cs.hidden) +MAILER(smtp) diff --git a/usr.sbin/sendmail/cf/cf/sleepy.mc b/usr.sbin/sendmail/cf/cf/sleepy.mc new file mode 100644 index 0000000..ff6a7cd --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/sleepy.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(@(#)sleepy.mc 8.1 (Berkeley) 6/7/93) +OSTYPE(hpux)dnl +DOMAIN(cs.exposed)dnl +define(`LOCAL_RELAY', diva.Berkeley.EDU)dnl +define(`MASQUERADE_NAME', diva.Berkeley.EDU)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/sunos3.5-cs-exposed.mc b/usr.sbin/sendmail/cf/cf/sunos3.5-cs-exposed.mc new file mode 100644 index 0000000..46d04d9 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/sunos3.5-cs-exposed.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)sunos3.5-cs-exposed.mc 8.1 (Berkeley) 6/7/93') +OSTYPE(sunos3.5)dnl +DOMAIN(cs.exposed)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/sunos3.5-cs-hidden.mc b/usr.sbin/sendmail/cf/cf/sunos3.5-cs-hidden.mc new file mode 100644 index 0000000..a3d6f20 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/sunos3.5-cs-hidden.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)sunos3.5-cs-hidden.mc 8.1 (Berkeley) 6/7/93') +OSTYPE(sunos3.5)dnl +DOMAIN(cs.hidden)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/sunos4.1-cs-exposed.mc b/usr.sbin/sendmail/cf/cf/sunos4.1-cs-exposed.mc new file mode 100644 index 0000000..7c94ba5 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/sunos4.1-cs-exposed.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)sunos4.1-cs-exposed.mc 8.1 (Berkeley) 6/7/93') +OSTYPE(sunos4.1)dnl +DOMAIN(cs.exposed)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/sunos4.1-cs-hidden.mc b/usr.sbin/sendmail/cf/cf/sunos4.1-cs-hidden.mc new file mode 100644 index 0000000..8e1dbb9 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/sunos4.1-cs-hidden.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)sunos4.1-cs-hidden.mc 8.1 (Berkeley) 6/7/93') +OSTYPE(sunos4.1)dnl +DOMAIN(cs.hidden)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/udb.mc b/usr.sbin/sendmail/cf/cf/udb.mc new file mode 100644 index 0000000..624d2d4 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/udb.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)udb.mc 8.1 (Berkeley) 6/7/93') +OSTYPE(sunos4.1)dnl +DOMAIN(cs.hidden)dnl +MAILER(smtp)dnl +define(`USERDB_FILE', `/home/auspex/a/staff/gnn/UDB/UI')dnl diff --git a/usr.sbin/sendmail/cf/cf/ultrix4.1-cs-exposed.mc b/usr.sbin/sendmail/cf/cf/ultrix4.1-cs-exposed.mc new file mode 100644 index 0000000..093590f --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/ultrix4.1-cs-exposed.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)ultrix4.1-cs-exposed.mc 8.1 (Berkeley) 6/7/93') +OSTYPE(ultrix4.1)dnl +DOMAIN(cs.exposed)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/ultrix4.1-cs-hidden.mc b/usr.sbin/sendmail/cf/cf/ultrix4.1-cs-hidden.mc new file mode 100644 index 0000000..ea25375 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/ultrix4.1-cs-hidden.mc @@ -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. +# + +include(`../m4/cf.m4') +VERSIONID(`@(#)ultrix4.1-cs-hidden.mc 8.1 (Berkeley) 6/7/93') +OSTYPE(ultrix4.1)dnl +DOMAIN(cs.hidden)dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/usr.sbin/sendmail/cf/cf/vangogh.mc b/usr.sbin/sendmail/cf/cf/vangogh.mc new file mode 100644 index 0000000..2406364 --- /dev/null +++ b/usr.sbin/sendmail/cf/cf/vangogh.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(`@(#)vangogh.mc 8.2 (Berkeley) 1/26/94') +DOMAIN(cs.exposed)dnl +OSTYPE(bsd4.4)dnl +MAILER(local)dnl +MAILER(smtp)dnl +define(`MCI_CACHE_SIZE', 5) +Cw okeeffe.CS.Berkeley.EDU +Cw python.CS.Berkeley.EDU diff --git a/usr.sbin/sendmail/cf/domain/Berkeley.m4 b/usr.sbin/sendmail/cf/domain/Berkeley.m4 new file mode 100644 index 0000000..4f572d6 --- /dev/null +++ b/usr.sbin/sendmail/cf/domain/Berkeley.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(`@(#)Berkeley.m4 8.5 (Berkeley) 2/18/94') +define(`UUCP_RELAY', `ucbvax.Berkeley.EDU')dnl +define(`BITNET_RELAY', `CMSA.Berkeley.EDU')dnl +define(`confFORWARD_PATH', `$z/.forward.$w:$z/.forward')dnl +define(`confCW_FILE', `-o /etc/sendmail.cw')dnl +FEATURE(redirect)dnl +FEATURE(use_cw_file)dnl diff --git a/usr.sbin/sendmail/cf/domain/cs.exposed.m4 b/usr.sbin/sendmail/cf/domain/cs.exposed.m4 new file mode 100644 index 0000000..43c07be --- /dev/null +++ b/usr.sbin/sendmail/cf/domain/cs.exposed.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(`@(#)cs.exposed.m4 8.1 (Berkeley) 6/7/93') +DOMAIN(Berkeley)dnl +HACK(cssubdomain)dnl +define(`confUSERDB_SPEC', + `/usr/sww/share/lib/users.cs.db,/usr/sww/share/lib/users.eecs.db')dnl diff --git a/usr.sbin/sendmail/cf/domain/cs.hidden.m4 b/usr.sbin/sendmail/cf/domain/cs.hidden.m4 new file mode 100644 index 0000000..3d9721a --- /dev/null +++ b/usr.sbin/sendmail/cf/domain/cs.hidden.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(`@(#)cs.hidden.m4 8.1 (Berkeley) 6/7/93') +DOMAIN(cs.exposed)dnl +MASQUERADE_AS(CS.Berkeley.EDU)dnl diff --git a/usr.sbin/sendmail/cf/domain/eecs.hidden.m4 b/usr.sbin/sendmail/cf/domain/eecs.hidden.m4 new file mode 100644 index 0000000..bbdc01a --- /dev/null +++ b/usr.sbin/sendmail/cf/domain/eecs.hidden.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(`@(#)eecs.hidden.m4 8.1 (Berkeley) 6/7/93') +DOMAIN(Berkeley)dnl +MASQUERADE_AS(EECS.Berkeley.EDU)dnl diff --git a/usr.sbin/sendmail/cf/domain/s2k.m4 b/usr.sbin/sendmail/cf/domain/s2k.m4 new file mode 100644 index 0000000..25b931f --- /dev/null +++ b/usr.sbin/sendmail/cf/domain/s2k.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(`@(#)s2k.m4 8.1 (Berkeley) 6/7/93') +DOMAIN(cs.exposed)dnl +MASQUERADE_AS(postgres.Berkeley.EDU)dnl diff --git a/usr.sbin/sendmail/cf/ostype/hpux.m4 b/usr.sbin/sendmail/cf/ostype/hpux.m4 new file mode 100644 index 0000000..1be21f3 --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/hpux.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(`@(#)hpux.m4 8.5 (Berkeley) 1/9/94') + +define(`QUEUE_DIR', /usr/spool/mqueue)dnl +define(`ALIAS_FILE', /usr/lib/aliases)dnl +define(`STATUS_FILE', /usr/lib/sendmail.st)dnl +define(`LOCAL_MAILER_FLAGS', `m')dnl +define(`UUCP_MAILER_ARGS', `uux - -r -a$f -gC $h!rmail ($u)')dnl +define(`confTIME_ZONE', `USE_TZ')dnl diff --git a/usr.sbin/sendmail/cf/ostype/irix.m4 b/usr.sbin/sendmail/cf/ostype/irix.m4 new file mode 100644 index 0000000..6cd7fc9 --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/irix.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(`@(#)irix.m4 8.4 (Berkeley) 2/1/94') +define(`LOCAL_MAILER_FLAGS', Ehm)dnl +define(`QUEUE_DIR', /usr/spool/mqueue)dnl +define(`ALIAS_FILE', /usr/lib/aliases)dnl +define(`STATUS_FILE', /usr/lib/sendmail.st)dnl diff --git a/usr.sbin/sendmail/cf/ostype/ultrix4.1.m4 b/usr.sbin/sendmail/cf/ostype/ultrix4.1.m4 new file mode 100644 index 0000000..87c4425 --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/ultrix4.1.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(`@(#)ultrix4.1.m4 8.1 (Berkeley) 6/7/93') +ifdef(`_OLD_SENDMAIL_', `define(`NEED_DOMAIN', `')')dnl diff --git a/usr.sbin/sendmail/contrib/rcpt-streaming b/usr.sbin/sendmail/contrib/rcpt-streaming new file mode 100644 index 0000000..a43af6d --- /dev/null +++ b/usr.sbin/sendmail/contrib/rcpt-streaming @@ -0,0 +1,305 @@ +Message-ID: +Date: Sun, 1 Aug 1993 00:02:57 -0400 (EDT) +From: John Gardiner Myers +To: sendmail@cs.berkeley.edu +Subject: contrib/rcpt-streaming +Beak: Is + +This patch implements "RCPT streaming" in sendmail version 8. This +patch is not an official part of sendmail. Please report all problems +with this patch to jgm+@cmu.edu. + +RCPT streming avoids network round trips by sending all RCPT commands +for a single SMTP transaction together. Sendmail then waits for all +the replies, matching them up with the apropriate addresses. + +Apply to the sendmail src directory (your line numbers may vary) and +compile with -DRCPTSTREAM + +diff -cr ./src/deliver.c /afs/andrew.cmu.edu/system/src/local/../host/oldsmail/016/src/deliver.c +*** ./src/deliver.c Thu Jul 22 14:28:19 1993 +--- /afs/andrew.cmu.edu/system/src/local/../host/oldsmail/016/src/deliver.c Fri Jul 30 21:11:16 1993 +*************** +*** 1334,1339 **** +--- 1334,1354 ---- + register int i; + + /* send the recipient list */ ++ #ifdef RCPTSTREAM ++ /*********************************************************************** ++ * ++ * RCPT streaming code by John G Myers, jgm+@cmu.edu ++ * This is not supported by the maintainer of sendmail. ++ * Report all bugs concerning RCPT streaming to jgm+@cmu.edu ++ * ++ *********************************************************************** ++ */ ++ for (to = tochain; to != NULL; to = to->q_tchain) ++ { ++ smtpstreammessage("RCPT To:<%s>", m, mci, ++ to->q_user); ++ } ++ #endif + tobuf[0] = '\0'; + for (to = tochain; to != NULL; to = to->q_tchain) + { +diff -cr ./src/usersmtp.c /afs/andrew.cmu.edu/system/src/local/../host/oldsmail/016/src/usersmtp.c +*** ./src/usersmtp.c Mon Jul 19 23:50:43 1993 +--- /afs/andrew.cmu.edu/system/src/local/../host/oldsmail/016/src/usersmtp.c Fri Jul 30 21:12:00 1993 +*************** +*** 44,49 **** +--- 44,61 ---- + + # include + # include ++ #ifdef RCPTSTREAM ++ /*********************************************************************** ++ * ++ * RCPT streaming code by John G Myers, jgm+@cmu.edu ++ * This is not supported by the maintainer of sendmail. ++ * Report all bugs concerning RCPT streaming to jgm+@cmu.edu ++ * ++ *********************************************************************** ++ */ ++ # include ++ # include ++ #endif + + # ifdef SMTP + +*************** +*** 62,67 **** +--- 74,87 ---- + char SmtpError[MAXLINE] = ""; /* save failure error messages */ + int SmtpPid; /* pid of mailer */ + ++ #ifdef RCPTSTREAM ++ char *SmtpStreamBuf; /* buffer for streaming output */ ++ int SmtpStreamBufSize = 0; /* allocated size of buffer */ ++ char *SmtpStreamStart; /* pointer to text not yet written */ ++ int SmtpStreamLen = 0; /* # chars not yet written */ ++ #endif ++ ++ + #ifdef __STDC__ + extern smtpmessage(char *f, MAILER *m, MCI *mci, ...); + #endif +*************** +*** 404,410 **** +--- 424,434 ---- + { + register int r; + ++ #ifdef RCPTSTREAM ++ sprintf(SmtpMsgBuffer, "RCPT To:<%s>", to->q_user); ++ #else + smtpmessage("RCPT To:<%s>", m, mci, to->q_user); ++ #endif + + SmtpPhase = mci->mci_phase = "client RCPT"; + setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); +*************** +*** 667,672 **** +--- 694,703 ---- + bool firstline = TRUE; + char junkbuf[MAXLINE]; + ++ #ifdef RCPTSTREAM ++ extern char MsgBuf[]; /* err.c */ ++ #endif ++ + if (mci->mci_out != NULL) + (void) fflush(mci->mci_out); + +*************** +*** 682,687 **** +--- 713,755 ---- + register char *p; + extern time_t curtime(); + ++ #ifdef RCPTSTREAM ++ if (SmtpStreamLen > 0) { ++ int outfd; ++ ++ outfd = fileno(mci->mci_out); ++ ++ nonblock(outfd, TRUE); ++ r = write(outfd, SmtpStreamStart, SmtpStreamLen); ++ nonblock(outfd, FALSE); ++ if (r == -1 && errno != EAGAIN ++ #ifdef EWOULDBLOCK ++ && errno != EWOULDBLOCK ++ #endif ++ ) { ++ ++ mci->mci_errno = errno; ++ message("451 streamreply: write error to %s", ++ mci->mci_host); ++ ++ /* if debugging, pause so we can see state */ ++ if (tTd(18, 100)) ++ pause(); ++ # ifdef LOG ++ if (LogLevel > 0) ++ syslog(LOG_INFO, "%s", &MsgBuf[4]); ++ # endif /* LOG */ ++ /* stop trying to write output */ ++ SmtpStreamLen = 0; ++ continue; ++ } ++ if (r > 0) { ++ SmtpStreamStart += r; ++ SmtpStreamLen -= r; ++ } ++ } ++ #endif /* RCPTSTREAM */ ++ + /* actually do the read */ + if (e->e_xfp != NULL) + (void) fflush(e->e_xfp); /* for debugging */ +*************** +*** 792,797 **** +--- 860,937 ---- + + return (r); + } ++ ++ #ifdef RCPTSTREAM ++ /* ++ ** SMTPSTREAMMESSAGE -- buffer message to be streamed to server ++ ** ++ ** Parameters: ++ ** f -- format ++ ** m -- the mailer to control formatting. ++ ** a, b, c -- parameters ++ ** ++ ** Returns: ++ ** none. ++ ** ++ ** Side Effects: ++ ** stores message in SmtpStreamBuf ++ */ ++ ++ /*VARARGS1*/ ++ #ifdef __STDC__ ++ smtpstreammessage(char *f, MAILER *m, MCI *mci, ...) ++ #else ++ smtpstreammessage(f, m, mci, va_alist) ++ char *f; ++ MAILER *m; ++ MCI *mci; ++ va_dcl ++ #endif ++ { ++ VA_LOCAL_DECL ++ int len; ++ ++ 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) { ++ if (tTd(18, 1)) printf("smtpstreammessage: NULL mci_out\n"); ++ return; ++ } ++ ++ strcat(SmtpMsgBuffer, m == NULL ? "\r\n" : m->m_eol); ++ len = strlen(SmtpMsgBuffer); ++ ++ if (SmtpStreamLen == 0) { ++ if (SmtpStreamBufSize == 0) { ++ SmtpStreamBufSize = MAXLINE; ++ SmtpStreamBuf = xalloc(SmtpStreamBufSize); ++ } ++ SmtpStreamStart = SmtpStreamBuf; ++ } ++ ++ if (SmtpStreamBufSize - SmtpStreamLen < len + 1) { ++ int start = SmtpStreamStart - SmtpStreamBuf; ++ SmtpStreamBufSize += MAXLINE; ++ SmtpStreamBuf = realloc(SmtpStreamBuf, SmtpStreamBufSize); ++ if (!SmtpStreamBuf) { ++ syserr("Out of memory!!"); ++ abort(); ++ /* exit(EX_UNAVAILABLE); */ ++ } ++ SmtpStreamStart = SmtpStreamBuf + start; ++ } ++ ++ strcpy(SmtpStreamBuf + SmtpStreamLen, SmtpMsgBuffer); ++ SmtpStreamLen += len; ++ } ++ #endif /* RCPTSTREAM */ + /* + ** SMTPMESSAGE -- send message to server + ** +Only in /afs/andrew.cmu.edu/system/src/local/../host/oldsmail/016/src: usersmtp.c~ +diff -cr ./src/util.c /afs/andrew.cmu.edu/system/src/local/../host/oldsmail/016/src/util.c +*** ./src/util.c Mon Jul 19 23:50:45 1993 +--- /afs/andrew.cmu.edu/system/src/local/../host/oldsmail/016/src/util.c Mon Jul 26 17:17:10 1993 +*************** +*** 1034,1039 **** +--- 1034,1091 ---- + return (FALSE); + return (TRUE); + } ++ ++ #ifdef RCPTSTREAM ++ /*********************************************************************** ++ * ++ * RCPT streaming code by John G Myers, jgm+@cmu.edu ++ * This is not supported by the maintainer of sendmail. ++ * Report all bugs concerning RCPT streaming to jgm+@cmu.edu ++ * ++ *********************************************************************** ++ */ ++ ++ #include ++ ++ /* ++ ** NONBLOCK -- set or clear non-blocking mode on file descriptor ++ ** ++ ** Parameters: ++ ** fd -- the file descriptor ++ ** mode -- TRUE to set non-blocking mode ++ ** FALSE to clear non-blocking mode ++ ** ++ ** Returns: ++ ** none ++ ** ++ ** Side Effects: ++ ** modifies nonblocking status of fd ++ */ ++ ++ nonblock(fd, mode) ++ int fd; ++ bool mode; ++ { ++ int flags; ++ ++ flags = fcntl(fd, F_GETFL, 0); ++ if (mode) { ++ #ifdef FNONBIO ++ flags |= FNONBIO; ++ #else ++ flags |= O_NDELAY; ++ #endif ++ } ++ else { ++ #ifdef FNONBIO ++ flags &= ~FNONBIO; ++ #else ++ flags &= ~O_NDELAY; ++ #endif ++ } ++ fcntl(fd, F_SETFL, flags); ++ } ++ #endif + /* + ** STRCONTAINEDIN -- tell if one string is contained in another + ** diff --git a/usr.sbin/sendmail/doc/Makefile b/usr.sbin/sendmail/doc/Makefile new file mode 100644 index 0000000..fc9dc19 --- /dev/null +++ b/usr.sbin/sendmail/doc/Makefile @@ -0,0 +1,5 @@ +# @(#)Makefile 8.1 (Berkeley) 6/7/93 + +SUBDIR= op intro usenix + +.include diff --git a/usr.sbin/sendmail/doc/op/spell.ok b/usr.sbin/sendmail/doc/op/spell.ok new file mode 100644 index 0000000..d1cb19e --- /dev/null +++ b/usr.sbin/sendmail/doc/op/spell.ok @@ -0,0 +1,324 @@ +AA06698 +AA06703 +AA22757 +AA22777 +AA99999 +ACHECK +ARPANET +AVENRUN +Allman +Arpa +Arpanet +BSD +BSD4.4 +BTree +Bcc +BitNET +CHmonet +CHucbmonet +CNAME +CS.Berkeley.EDU +Cdaemon +Ceric +Cnt +Ctest.cf +DB +DLA +DdfAA13557 +Dj +DlFrom +DnMAILER +Dq +EDU +EOH +EXPN +Eol +Eowner +Eric.Allman +FAX +FSCALE +Fri +GECOS +Guide''SMM:07 +H?F?from +H?P?return +H?x?full +HELO +HTo +HdrInfo +HiTech.COM +Hmessage +Hreceived +Hsubject +INT +IP +IPC +Jul +Kmapname +LAN +LHS +LOCKF +Linelimit +LocalMailer +MATCHGECOS +MAXATOM +MAXHOP +MAXLINE +MAXMAILERS +MAXMXHOSTS +MAXNAME +MAXPRIORITIES +MAXPV +MAXRWSETS +MAXTRUST +MAXUSERENVIRON +MX +Makefile +Makefile.dist +Maxsize +Meta +Mether +Mlocal +MsgSize +NEWDB +NIS +NOOP +NOTUNIX +NoReturn +OJ +OSTYPE +OT3d +PSyserr +Pfirst +Pjunk +Pspecial +QUEUESIZE +RCPT +README +RFC +RFC's +RFC1123 +RFC819 +RFC821 +RFC822 +RHS +Rbostic +Reric +Ruleset +Rulesets +S,D +SETPROCTITLE +SITECONFIG +SMM:07 +SMTP +SUBR +SYS5TZ +SYSTEM5 +Seric +TCP +TSyserr +UCBARPA +UCBARPA:eric +UGLYUUCP +USERDB +Ucbvax +Ultrix3.0 +Usrerr +VRFY +Wildcard +YP +a.CC.Berkeley.EDU +aliases.db +aliases.dir +aliases.pag +args +automounter +av +avenrun +bd +behaviour +bi +bollard +bool +bostic +bp +bt +btree +buf +bufsize +bz +c70:user +calder +canonification +checkcompat +cnt +conf.c +conf.h +contessa +cs +cs.exposed.m4 +cs.hidden.m4 +csam +csam.arpa +cw +daemon.c +db +decvax +default:mailname +delivermail +dev +dir +doc +ef +email +eric +eric:mailname +ernie +errno +fallback +fax +fi +filename +filenames +fo +foo.bar.baz.de +fullname +gateway.HiTech.COM +getla +getloadavg +groupid +hdrinfo +hname +hoptoad +host.domain +hosta +hostb +htemplate +ie +iff +int +ip +lbl +lf +lhs +lib +lnx +localhost +lockf +lp +mail.CS.Berkeley.EDU +mail.cf +maildrop +mailname +mailq +mailstats +mailstats.c +makemap +mammoth.Berkeley.EDU +mammoth.Berkeley.EDU.HiTech.COM +mapclass +maphostname +mapname +matisse +mc +mckusick +meC +mflags +monet +monet:bollard +mqueue +msg +name1 +name2 +nameserver +newalias +nkainc +nosuchuser +num +oM +oQ +oT1d +oT2m +okeeffe.CS.Berkeley.EDU +omqueue +ostype +pUUCP:uunet +pag +pag,dir +pathname +pathnames +pathnames.h +pid +pp +prep.ai.MIT.EDU +prog +q30m +qf +querytype +queueups +rc.local +resolv.conf +rfc819.lpr +rfc822.lpr +rhs +rlsm +ruleset +rulesets +rwset +rwsets +sam +sbin +sendmail.cf +sendmail.cw +sendmail.fc +sendmail.hf +sendmail.st +setupmaps +si +site.config.file +siteconfig +smtp +sp +src +suid +syserr +sysname +tcpproto.mc +test.cf +text1 +text2 +tf +timestamp +timestamps +ucb +ucbarpa +ucblib +ucbmonet +ucbvax +ucbvax.mc +udbspec +user1 +user2 +usera +userb +userc +userid +username +usrerr +uucpproto.mc +uunet +val +vangogh.CS.Berkeley.EDU +vangogh.berkeley.edu +var +vikki +voyeurism +wildcard +wildcards +wnj +word1 +word2 +xf +xxx +xyzvax +yp diff --git a/usr.sbin/sendmail/doc/rfc/rfc819.txt b/usr.sbin/sendmail/doc/rfc/rfc819.txt new file mode 100644 index 0000000..d66f8d9 --- /dev/null +++ b/usr.sbin/sendmail/doc/rfc/rfc819.txt @@ -0,0 +1,1044 @@ + + +Network Working Group Zaw-Sing Su (SRI) +Request for Comments: 819 Jon Postel (ISI) + August 1982 + + + + The Domain Naming Convention for Internet User Applications + + + + +1. Introduction + + For many years, the naming convention "@" has served the + ARPANET user community for its mail system, and the substring + "" has been used for other applications such as file transfer + (FTP) and terminal access (Telnet). With the advent of network + interconnection, this naming convention needs to be generalized to + accommodate internetworking. A decision has recently been reached to + replace the simple name field, "", by a composite name field, + "" [2]. This note is an attempt to clarify this generalized + naming convention, the Internet Naming Convention, and to explore the + implications of its adoption for Internet name service and user + applications. + + The following example illustrates the changes in naming convention: + + ARPANET Convention: Fred@ISIF + Internet Convention: Fred@F.ISI.ARPA + + The intent is that the Internet names be used to form a + tree-structured administrative dependent, rather than a strictly + topology dependent, hierarchy. The left-to-right string of name + components proceeds from the most specific to the most general, that + is, the root of the tree, the administrative universe, is on the + right. + + The name service for realizing the Internet naming convention is + assumed to be application independent. It is not a part of any + particular application, but rather an independent name service serves + different user applications. + +2. The Structural Model + + The Internet naming convention is based on the domain concept. The + name of a domain consists of a concatenation of one or more . A domain can be considered as a region of jurisdiction for + name assignment and of responsibility for name-to-address + translation. The set of domains forms a hierarchy. + + Using a graph theory representation, this hierarchy may be modeled as + a directed graph. A directed graph consists of a set of nodes and a + + +Su & Postel [Page 1] + + + +RFC 819 August 1982; + + + collection of arcs, where arcs are identified by ordered pairs of + distinct nodes [1]. Each node of the graph represents a domain. An + ordered pair (B, A), an arc from B to A, indicates that B is a + subdomain of domain A, and B is a simple name unique within A. We + will refer to B as a child of A, and A a parent of B. The directed + graph that best describes the naming hierarchy is called an + "in-tree", which is a rooted tree with all arcs directed towards the + root (Figure 1). The root of the tree represents the naming universe, + ancestor of all domains. Endpoints (or leaves) of the tree are the + lowest-level domains. + + U + / | \ + / | \ U -- Naming Universe + ^ ^ ^ I -- Intermediate Domain + | | | E -- Endpoint Domain + I E I + / \ | + ^ ^ ^ + | | | + E E I + / | \ + ^ ^ ^ + | | | + E E E + + Figure 1 + The In-Tree Model for Domain Hierarchy + + The simple name of a child in this model is necessarily unique within + its parent domain. Since the simple name of the child's parent is + unique within the child's grandparent domain, the child can be + uniquely named in its grandparent domain by the concatenation of its + simple name followed by its parent's simple name. + + For example, if the simple name of a child is "C1" then no other + child of the same parent may be named "C1". Further, if the + parent of this child is named "P1", then "P1" is a unique simple + name in the child's grandparent domain. Thus, the concatenation + C1.P1 is unique in C1's grandparent domain. + + Similarly, each element of the hierarchy is uniquely named in the + universe by its complete name, the concatenation of its simple name + and those for the domains along the trail leading to the naming + universe. + + The hierarchical structure of the Internet naming convention supports + decentralization of naming authority and distribution of name service + capability. We assume a naming authority and a name server + + +Su & Postel [Page 2] + + + +RFC 819 August 1982; + + + associated with each domain. In Sections 5 and 6 respectively the + name service and the naming authority are discussed. + + Within an endpoint domain, unique names are assigned to + representing user mailboxes. User mailboxes may be viewed as + children of their respective domains. + + In reality, anomalies may exist violating the in-tree model of naming + hierarchy. Overlapping domains imply multiple parentage, i.e., an + entity of the naming hierarchy being a child of more than one domain. + It is conceivable that ISI can be a member of the ARPA domain as well + as a member of the USC domain (Figure 2). Such a relation + constitutes an anomaly to the rule of one-connectivity between any + two points of a tree. The common child and the sub-tree below it + become descendants of both parent domains. + + U + / | \ + / . \ + . . ARPA + . . | \ + USC | \ + \ | . + \ | . + ISI + + Figure 2 + Anomaly in the In-Tree Model + + Some issues resulting from multiple parentage are addressed in + Appendix B. The general implications of multiple parentage are a + subject for further investigation. + +3. Advantage of Absolute Naming + + Absolute naming implies that the (complete) names are assigned with + respect to a universal reference point. The advantage of absolute + naming is that a name thus assigned can be universally interpreted + with respect to the universal reference point. The Internet naming + convention provides absolute naming with the naming universe as its + universal reference point. + + For relative naming, an entity is named depending upon the position + of the naming entity relative to that of the named entity. A set of + hosts running the "unix" operating system exchange mail using a + method called "uucp". The naming convention employed by uucp is an + example of relative naming. The mail recipient is typically named by + a source route identifying a chain of locally known hosts linking the + + + +Su & Postel [Page 3] + + + +RFC 819 August 1982; + + + sender's host to the recipient's. A destination name can be, for + example, + + "alpha!beta!gamma!john", + + where "alpha" is presumably known to the originating host, "beta" is + known to "alpha", and so on. + + The uucp mail system has demonstrated many of the problems inherent + to relative naming. When the host names are only locally + interpretable, routing optimization becomes impossible. A reply + message may have to traverse the reverse route to the original sender + in order to be forwarded to other parties. + + Furthermore, if a message is forwarded by one of the original + recipients or passed on as the text of another message, the frame of + reference of the relative source route can be completely lost. Such + relative naming schemes have severe problems for many of the uses + that we depend upon in the ARPA Internet community. + +4. Interoperability + + To allow interoperation with a different naming convention, the names + assigned by a foreign naming convention need to be accommodated. + Given the autonomous nature of domains, a foreign naming environment + may be incorporated as a domain anywhere in the hierarchy. Within + the naming universe, the name service for a domain is provided within + that domain. Thus, a foreign naming convention can be independent of + the Internet naming convention. What is implied here is that no + standard convention for naming needs to be imposed to allow + interoperations among heterogeneous naming environments. + + For example: + + There might be a naming convention, say, in the FOO world, + something like "%%". Communications with an + entity in that environment can be achieved from the Internet + community by simply appending ".FOO" on the end of the name in + that foreign convention. + + John%ISI-Tops20-7%California.FOO + + Another example: + + One way of accommodating the "uucp world" described in the last + section is to declare it as a foreign system. Thus, a uucp + name + + "alpha!beta!gamma!john" + + +Su & Postel [Page 4] + + + +RFC 819 August 1982; + + + might be known in the Internet community as + + "alpha!beta!gamma!john.UUCP". + + Communicating with a complex subdomain is another case which can + be treated as interoperation. A complex subdomain is a domain + with complex internal naming structure presumably unknown to the + outside world (or the outside world does not care to be concerned + with its complexity). + + For the mail system application, the names embedded in the message + text are often used by the destination for such purpose as to reply + to the original message. Thus, the embedded names may need to be + converted for the benefit of the name server in the destination + environment. + + Conversion of names on the boundary between heterogeneous naming + environments is a complex subject. The following example illustrates + some of the involved issues. + + For example: + + A message is sent from the Internet community to the FOO + environment. It may bear the "From" and "To" fields as: + + From: Fred@F.ISI.ARPA + To: John%ISI-Tops20-7%California.FOO + + where "FOO" is a domain independent of the Internet naming + environment. The interface on the boundary of the two + environments may be represented by a software module. We may + assume this interface to be an entity of the Internet community + as well as an entity of the FOO community. For the benefit of + the FOO environment, the "From" and "To" fields need to be + modified upon the message's arrival at the boundary. One may + view naming as a separate layer of protocol, and treat + conversion as a protocol translation. The matter is + complicated when the message is sent to more than one + destination within different naming environments; or the + message is destined within an environment not sharing boundary + with the originating naming environment. + + While the general subject concerning conversion is beyond the scope + of this note, a few questions are raised in Appendix D. + + + + + + + +Su & Postel [Page 5] + + + +RFC 819 August 1982; + + +5. Name Service + + Name service is a network service providing name-to-address + translation. Such service may be achieved in a number of ways. For + a simple networking environment, it can be accomplished with a single + central database containing name-to-address correspondence for all + the pertinent network entities, such as hosts. + + In the case of the old ARPANET host names, a central database is + duplicated in each individual host. The originating module of an + application process would query the local name service (e.g., make a + system call) to obtain network address for the destination host. With + the proliferation of networks and an accelerating increase in the + number of hosts participating in networking, the ever growing size, + update frequency, and the dissemination of the central database makes + this approach unmanageable. + + The hierarchical structure of the Internet naming convention supports + decentralization of naming authority and distribution of name service + capability. It readily accommodates growth of the naming universe. + It allows an arbitrary number of hierarchical layers. The addition + of a new domain adds little complexity to an existing Internet + system. + + The name service at each domain is assumed to be provided by one or + more name servers. There are two models for how a name server + completes its work, these might be called "iterative" and + "recursive". + + For an iterative name server there may be two kinds of responses. + The first kind of response is a destination address. The second + kind of response is the address of another name server. If the + response is a destination address, then the query is satisfied. If + the response is the address of another name server, then the query + must be repeated using that name server, and so on until a + destination address is obtained. + + For a recursive name server there is only one kind of response -- + a destination address. This puts an obligation on the name server + to actually make the call on another name server if it can't + answer the query itself. + + It is noted that looping can be avoided since the names presented for + translation can only be of finite concatenation. However, care + should be taken in employing mechanisms such as a pointer to the next + simple name for resolution. + + We believe that some name servers will be recursive, but we don't + believe that all will be. This means that the caller must be + + +Su & Postel [Page 6] + + + +RFC 819 August 1982; + + + prepared for either type of server. Further discussion and examples + of name service is given in Appendix C. + + The basic name service at each domain is the translation of simple + names to addresses for all of its children. However, if only this + basic name service is provided, the use of complete (or fully + qualified) names would be required. Such requirement can be + unreasonable in practice. Thus, we propose the use of partial names + in the context in which their uniqueness is preserved. By + construction, naming uniqueness is preserved within the domain of a + common ancestry. Thus, a partially qualified name is constructed by + omitting from the complete name ancestors common to the communicating + parties. When a partially qualified name leaves its context of + uniqueness it must be additionally qualified. + + The use of partially qualified names places a requirement on the + Internet name service. To satisfy this requirement, the name service + at each domain must be capable of, in addition to the basic service, + resolving simple names for all of its ancestors (including itself) + and their children. In Appendix B, the required distinction among + simple names for such resolution is addressed. + +6. Naming Authority + + Associated with each domain there must be a naming authority to + assign simple names and ensure proper distinction among simple names. + + Note that if the use of partially qualified names is allowed in a + sub-domain, the uniqueness of simple names inside that sub-domain is + insufficient to avoid ambiguity with names outside the subdomain. + Appendix B discusses simple name assignment in a sub-domain that + would allow the use of partially qualified names without ambiguity. + + Administratively, associated with each domain there is a single + person (or office) called the registrar. The registrar of the naming + universe specifies the top-level set of domains and designates a + registrar for each of these domains. The registrar for any given + domain maintains the naming authority for that domain. + +7. Network-Oriented Applications + + For user applications such as file transfer and terminal access, the + remote host needs to be named. To be compatible with ARPANET naming + convention, a host can be treated as an endpoint domain. + + Many operating systems or programming language run-time environments + provide functions or calls (JSYSs, SVCs, UUOs, SYSs, etc.) for + standard services (e.g., time-of-day, account-of-logged-in-user, + convert-number-to-string). It is likely to be very helpful if such a + + +Su & Postel [Page 7] + + + +RFC 819 August 1982; + + + function or call is developed for translating a host name to an + address. Indeed, several systems on the ARPANET already have such + facilities for translating an ARPANET host name into an ARPANET + address based on internal tables. + + We recommend that this provision of a standard function or call for + translating names to addresses be extended to accept names of + Internet convention. This will promote a consistent interface to the + users of programs involving internetwork activities. The standard + facility for translating Internet names to Internet addresses should + include all the mechanisms available on the host, such as checking a + local table or cache of recently checked names, or consulting a name + server via the Internet. + +8. Mail Relaying + + Relaying is a feature adopted by more and more mail systems. + Relaying facilitates, among other things, interoperations between + heterogeneous mail systems. The term "relay" is used to describe the + situation where a message is routed via one or more intermediate + points between the sender and the recipient. The mail relays are + normally specified explicitly as relay points in the instructions for + message delivery. Usually, each of the intermediate relays assume + responsibility for the relayed message [3]. + + A point should be made on the basic difference between mail + relaying and the uucp naming system. The difference is that + although mail relaying with absolute naming can also be considered + as a form of source routing, the names of each intermediate points + and that of the destination are universally interpretable, while + the host names along a source route of the uucp convention is + relative and thus only locally interpretable. + + The Internet naming convention explicitly allows interoperations + among heterogeneous systems. This implies that the originator of a + communication may name a destination which resides in a foreign + system. The probability is that the destination network address may + not be comprehensible to the transport system of the originator. + Thus, an implicit relaying mechanism is called for at the boundary + between the domains. The function of this implicit relay is the same + as the explicit relay. + + + + + + + + + + +Su & Postel [Page 8] + + + +RFC 819 August 1982; + + +9. Implementation + + The Actual Domains + + The initial set of top-level names include: + + ARPA + + This represents the set of organizations involved in the + Internet system through the authority of the U.S. Defense + Advanced Research Projects Agency. This includes all the + research and development hosts on the ARPANET and hosts on + many other nets as well. But note very carefully that the + top-level domain "ARPA" does not map one-to-one with the + ARPANET -- domains are administrative, not topological. + + Transition + + In the transition from the ARPANET naming convention to the + Internet naming convention, a host name may be used as a simple + name for an endpoint domain. Thus, if "USC-ISIF" is an ARPANET + host name, then "USC-ISIF.ARPA" is the name of an Internet domain. + +10. Summary + + A hierarchical naming convention based on the domain concept has been + adopted by the Internet community. It is an absolute naming + convention defined along administrative rather than topological + boundaries. This naming convention is adaptive for interoperations + with other naming conventions. Thus, no standard convention needs to + be imposed for interoperations among heterogeneous naming + environments. + + This Internet naming convention allows distributed name service and + naming authority functions at each domain. We have specified these + functions required at each domain. Also discussed are implications + on network-oriented applications, mail systems, and administrative + aspects of this convention. + + + + + + + + + + + + + +Su & Postel [Page 9] + + + +RFC 819 August 1982; + + +APPENDIX A + + The BNF Specification + + We present here a rather detailed "BNF" definition of the allowed + form for a computer mail "mailbox" composed of a "local-part" and a + "domain" (separated by an at sign). Clearly, the domain can be used + separately in other network-oriented applications. + + ::= "@" + + ::= | + + ::= | + + ::= """ """ + + ::= "\" | "\" | | + + ::= | "\" + + ::= | "." + + ::= |
+ + ::= + + ::= | + + ::= | + + ::= | | "-" + +
:: = "#" | "[" "]" + + ::= | + + ::= "." "." "." + + ::= one, two, or three digits representing a decimal integer + value in the range 0 through 255 + + ::= any one of the 52 alphabetic characters A through Z in upper + case and a through z in lower case + + ::= any one of the 128 ASCII characters except or + + ::= any one of the ten digits 0 through 9 + + + +Su & Postel [Page 10] + + + +RFC 819 August 1982; + + + ::= any one of the 128 ASCII characters except CR, LF, quote ("), + or backslash (\) + + ::= any one of the 128 ASCII characters (no exceptions) + + ::= "<", ">", "(", ")", "[", "]", "\", ".", ",", ";", ":", "@", + """, and the control characters (ASCII codes 0 through 31 inclusive + and 127) + + Note that the backslash, "\", is a quote character, which is used to + indicate that the next character is to be used literally (instead of + its normal interpretation). For example, "Joe\,Smith" could be used + to indicate a single nine character user field with comma being the + fourth character of the field. + + The simple names that make up a domain may contain both upper and + lower case letters (as well as digits and hyphen), but these names + are not case sensitive. + + Hosts are generally known by names. Sometimes a host is not known to + the translation function and communication is blocked. To bypass + this barrier two forms of addresses are also allowed for host + "names". One form is a decimal integer prefixed by a pound sign, "#". + Another form, called "dotted decimal", is four small decimal integers + separated by dots and enclosed by brackets, e.g., "[123.255.37.2]", + which indicates a 32-bit ARPA Internet Address in four 8-bit fields. + (Of course, these numeric address forms are specific to the Internet, + other forms may have to be provided if this problem arises in other + transport systems.) + + + + + + + + + + + + + + + + + + + + + + +Su & Postel [Page 11] + + + +RFC 819 August 1982; + + +APPENDIX B + + An Aside on the Assignment of Simple Names + + In the following example, there are two naming hierarchies joining at + the naming universe 'U'. One consists of domains (S, R, N, J, P, Q, + B, A); and the other (L, E, F, G, H, D, C, K, B, A). Domain B is + assumed to have multiple parentage as shown. + + U + / \ + / \ + J L + / \ + N E + / \ / \ + R P D F + / \ | \ \ + S Q C (X) G + \ / \ \ + B K H + / + A + + Figure 3 + Illustration of Requirements for the Distinction of Simple Names + + Suppose someone at A tries to initiate communication with destination + H. The fully qualified destination name would be + + H.G.F.E.L.U + + Omitting common ancestors, the partially qualified name for the + destination would be + + H.G.F + + To permit the case of partially qualified names, name server at A + needs to resolve the simple name F, i.e., F needs to be distinct from + all the other simple names in its database. + + To enable the name server of a domain to resolve simple names, a + simple name for a child needs to be assigned distinct from those of + all of its ancestors and their immediate children. However, such + distinction would not be sufficient to allow simple name resolution + at lower-level domains because lower-level domains could have + multiple parentage below the level of this domain. + + In the example above, let us assume that a name is to be assigned + + +Su & Postel [Page 12] + + + +RFC 819 August 1982; + + + to a new domain X by D. To allow name server at D to resolve + simple names, the name for X must be distinct from L, E, D, C, F, + and J. However, allowing A to resolve simple names, X needs to be + also distinct from A, B, K, as well as from Q, P, N, and R. + + The following observations can be made. + + Simple names along parallel trails (distinct trails leading from + one domain to the naming universe) must be distinct, e.g., N must + be distinct from E for B or A to properly resolve simple names. + + No universal uniqueness of simple names is called for, e.g., the + simple name S does not have to be distinct from that of E, F, G, + H, D, C, K, Q, B, or A. + + The lower the level at which a domain occurs, the more immune it + is to the requirement of naming uniqueness. + + To satisfy the required distinction of simple names for proper + resolution at all levels, a naming authority needs to ensure the + simple name to be assigned distinct from those in the name server + databases at the endpoint naming domains within its domain. As an + example, for D to assign a simple name for X, it would need to + consult databases at A and K. It is, however, acceptable to have + simple names under domain A identical with those under K. Failure of + such distinct assignment of simple names by naming authority of one + domain would jeopardize the capability of simple name resolution for + entities within the subtree under that domain. + + + + + + + + + + + + + + + + + + + + + + + +Su & Postel [Page 13] + + + +RFC 819 August 1982; + + +APPENDIX C + + Further Discussion of Name Service and Name Servers + + The name service on a system should appear to the programmer of an + application program simply as a system call or library subroutine. + Within that call or subroutine there may be several types of methods + for resolving the name string into an address. + + First, a local table may be consulted. This table may be a + complete table and may be updated frequently, or it may simply be + a cache of the few latest name to address mappings recently + determined. + + Second, a call may be made to a name server to resolve the string + into a destination address. + + Third, a call may be made to a name server to resolve the string + into a relay address. + + Whenever a name server is called it may be a recursive server or an + interactive server. + + If the server is recursive, the caller won't be able to tell if + the server itself had the information to resolve the query or + called another server recursively (except perhaps for the time it + takes). + + If the server is iterative, the caller must be prepared for either + the answer to its query, or a response indicating that it should + call on a different server. + + It should be noted that the main name service discussed in this memo + is simply a name string to address service. For some applications + there may be other services needed. + + For example, even within the Internet there are several procedures + or protocols for actually transferring mail. One need is to + determine which mail procedures a destination host can use. + Another need is to determine the name of a relay host if the + source and destination hosts do not have a common mail procedure. + These more specialized services must be specific to each + application since the answers may be application dependent, but + the basic name to address translation is application independent. + + + + + + + +Su & Postel [Page 14] + + + +RFC 819 August 1982; + + +APPENDIX D + + Further Discussion of Interoperability and Protocol Translations + + The translation of protocols from one system to another is often + quite difficult. Following are some questions that stem from + considering the translations of addresses between mail systems: + + What is the impact of different addressing environments (i.e., + environments of different address formats)? + + It is noted that the boundary of naming environment may or may not + coincide with the boundary of different mail systems. Should the + conversion of naming be independent of the application system? + + The boundary between different addressing environments may or may + not coincide with that of different naming environments or + application systems. Some generic approach appears to be + necessary. + + If the conversion of naming is to be independent of the + application system, some form of interaction appears necessary + between the interface module of naming conversion with some + application level functions, such as the parsing and modification + of message text. + + To accommodate encryption, conversion may not be desirable at all. + What then can be an alternative to conversion? + + + + + + + + + + + + + + + + + + + + + + + +Su & Postel [Page 15] + + + +RFC 819 August 1982; + + +GLOSSARY + + address + + An address is a numerical identifier for the topological location + of the named entity. + + name + + A name is an alphanumeric identifier associated with the named + entity. For unique identification, a name needs to be unique in + the context in which the name is used. A name can be mapped to an + address. + + complete (fully qualified) name + + A complete name is a concatenation of simple names representing + the hierarchical relation of the named with respect to the naming + universe, that is it is the concatenation of the simple names of + the domain structure tree nodes starting with its own name and + ending with the top level node name. It is a unique name in the + naming universe. + + partially qualified name + + A partially qualified name is an abbreviation of the complete name + omitting simple names of the common ancestors of the communicating + parties. + + simple name + + A simple name is an alphanumeric identifier unique only within its + parent domain. + + domain + + A domain defines a region of jurisdiction for name assignment and + of responsibility for name-to-address translation. + + naming universe + + Naming universe is the ancestor of all network entities. + + naming environment + + A networking environment employing a specific naming convention. + + + + + +Su & Postel [Page 16] + + + +RFC 819 August 1982; + + + name service + + Name service is a network service for name-to-address mapping. + + name server + + A name server is a network mechanism (e.g., a process) realizing + the function of name service. + + naming authority + + Naming authority is an administrative entity having the authority + for assigning simple names and responsibility for resolving naming + conflict. + + parallel relations + + A network entity may have one or more hierarchical relations with + respect to the naming universe. Such multiple relations are + parallel relations to each other. + + multiple parentage + + A network entity has multiple parentage when it is assigned a + simple name by more than one naming domain. + + + + + + + + + + + + + + + + + + + + + + + + + + +Su & Postel [Page 17] + + + +RFC 819 August 1982; + + +REFERENCES + + [1] F. Harary, "Graph Theory", Addison-Wesley, Reading, + Massachusetts, 1969. + + [2] J. Postel, "Computer Mail Meeting Notes", RFC-805, + USC/Information Sciences Institute, 8 February 1982. + + [3] J. Postel, "Simple Mail Transfer Protocol", RFC-821, + USC/Information Sciences Institute, August 1982. + + [4] D. Crocker, "Standard for the Format of ARPA Internet Text + Messages", RFC-822, Department of Electrical Engineering, University + of Delaware, August 1982. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Su & Postel [Page 18] + diff --git a/usr.sbin/sendmail/doc/rfc/rfc821.txt b/usr.sbin/sendmail/doc/rfc/rfc821.txt new file mode 100644 index 0000000..d877b72 --- /dev/null +++ b/usr.sbin/sendmail/doc/rfc/rfc821.txt @@ -0,0 +1,4050 @@ + + + + RFC 821 + + + + + + SIMPLE MAIL TRANSFER PROTOCOL + + + + Jonathan B. Postel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + August 1982 + + + + Information Sciences Institute + University of Southern California + 4676 Admiralty Way + Marina del Rey, California 90291 + + (213) 822-1511 + + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + TABLE OF CONTENTS + + 1. INTRODUCTION .................................................. 1 + + 2. THE SMTP MODEL ................................................ 2 + + 3. THE SMTP PROCEDURE ............................................ 4 + + 3.1. Mail ..................................................... 4 + 3.2. Forwarding ............................................... 7 + 3.3. Verifying and Expanding .................................. 8 + 3.4. Sending and Mailing ..................................... 11 + 3.5. Opening and Closing ..................................... 13 + 3.6. Relaying ................................................ 14 + 3.7. Domains ................................................. 17 + 3.8. Changing Roles .......................................... 18 + + 4. THE SMTP SPECIFICATIONS ...................................... 19 + + 4.1. SMTP Commands ........................................... 19 + 4.1.1. Command Semantics ..................................... 19 + 4.1.2. Command Syntax ........................................ 27 + 4.2. SMTP Replies ............................................ 34 + 4.2.1. Reply Codes by Function Group ......................... 35 + 4.2.2. Reply Codes in Numeric Order .......................... 36 + 4.3. Sequencing of Commands and Replies ...................... 37 + 4.4. State Diagrams .......................................... 39 + 4.5. Details ................................................. 41 + 4.5.1. Minimum Implementation ................................ 41 + 4.5.2. Transparency .......................................... 41 + 4.5.3. Sizes ................................................. 42 + + APPENDIX A: TCP ................................................. 44 + APPENDIX B: NCP ................................................. 45 + APPENDIX C: NITS ................................................ 46 + APPENDIX D: X.25 ................................................ 47 + APPENDIX E: Theory of Reply Codes ............................... 48 + APPENDIX F: Scenarios ........................................... 51 + + GLOSSARY ......................................................... 64 + + REFERENCES ....................................................... 67 + + + + +Network Working Group J. Postel +Request for Comments: DRAFT ISI +Replaces: RFC 788, 780, 772 August 1982 + + SIMPLE MAIL TRANSFER PROTOCOL + + +1. INTRODUCTION + + The objective of Simple Mail Transfer Protocol (SMTP) is to transfer + mail reliably and efficiently. + + SMTP is independent of the particular transmission subsystem and + requires only a reliable ordered data stream channel. Appendices A, + B, C, and D describe the use of SMTP with various transport services. + A Glossary provides the definitions of terms as used in this + document. + + An important feature of SMTP is its capability to relay mail across + transport service environments. A transport service provides an + interprocess communication environment (IPCE). An IPCE may cover one + network, several networks, or a subset of a network. It is important + to realize that transport systems (or IPCEs) are not one-to-one with + networks. A process can communicate directly with another process + through any mutually known IPCE. Mail is an application or use of + interprocess communication. Mail can be communicated between + processes in different IPCEs by relaying through a process connected + to two (or more) IPCEs. More specifically, mail can be relayed + between hosts on different transport systems by a host on both + transport systems. + + + + + + + + + + + + + + + + + + + + + + + + +Postel [Page 1] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + +2. THE SMTP MODEL + + The SMTP design is based on the following model of communication: as + the result of a user mail request, the sender-SMTP establishes a + two-way transmission channel to a receiver-SMTP. The receiver-SMTP + may be either the ultimate destination or an intermediate. SMTP + commands are generated by the sender-SMTP and sent to the + receiver-SMTP. SMTP replies are sent from the receiver-SMTP to the + sender-SMTP in response to the commands. + + Once the transmission channel is established, the SMTP-sender sends a + MAIL command indicating the sender of the mail. If the SMTP-receiver + can accept mail it responds with an OK reply. The SMTP-sender then + sends a RCPT command identifying a recipient of the mail. If the + SMTP-receiver can accept mail for that recipient it responds with an + OK reply; if not, it responds with a reply rejecting that recipient + (but not the whole mail transaction). The SMTP-sender and + SMTP-receiver may negotiate several recipients. When the recipients + have been negotiated the SMTP-sender sends the mail data, terminating + with a special sequence. If the SMTP-receiver successfully processes + the mail data it responds with an OK reply. The dialog is purposely + lock-step, one-at-a-time. + + ------------------------------------------------------------- + + + +----------+ +----------+ + +------+ | | | | + | User |<-->| | SMTP | | + +------+ | Sender- |Commands/Replies| Receiver-| + +------+ | SMTP |<-------------->| SMTP | +------+ + | File |<-->| | and Mail | |<-->| File | + |System| | | | | |System| + +------+ +----------+ +----------+ +------+ + + + Sender-SMTP Receiver-SMTP + + Model for SMTP Use + + Figure 1 + + ------------------------------------------------------------- + + The SMTP provides mechanisms for the transmission of mail; directly + from the sending user's host to the receiving user's host when the + + + +[Page 2] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + two host are connected to the same transport service, or via one or + more relay SMTP-servers when the source and destination hosts are not + connected to the same transport service. + + To be able to provide the relay capability the SMTP-server must be + supplied with the name of the ultimate destination host as well as + the destination mailbox name. + + The argument to the MAIL command is a reverse-path, which specifies + who the mail is from. The argument to the RCPT command is a + forward-path, which specifies who the mail is to. The forward-path + is a source route, while the reverse-path is a return route (which + may be used to return a message to the sender when an error occurs + with a relayed message). + + When the same message is sent to multiple recipients the SMTP + encourages the transmission of only one copy of the data for all the + recipients at the same destination host. + + The mail commands and replies have a rigid syntax. Replies also have + a numeric code. In the following, examples appear which use actual + commands and replies. The complete lists of commands and replies + appears in Section 4 on specifications. + + Commands and replies are not case sensitive. That is, a command or + reply word may be upper case, lower case, or any mixture of upper and + lower case. Note that this is not true of mailbox user names. For + some hosts the user name is case sensitive, and SMTP implementations + must take case to preserve the case of user names as they appear in + mailbox arguments. Host names are not case sensitive. + + Commands and replies are composed of characters from the ASCII + character set [1]. When the transport service provides an 8-bit byte + (octet) transmission channel, each 7-bit character is transmitted + right justified in an octet with the high order bit cleared to zero. + + When specifying the general form of a command or reply, an argument + (or special symbol) will be denoted by a meta-linguistic variable (or + constant), for example, "" or "". Here the + angle brackets indicate these are meta-linguistic variables. + However, some arguments use the angle brackets literally. For + example, an actual reverse-path is enclosed in angle brackets, i.e., + "" is an instance of (the + angle brackets are actually transmitted in the command or reply). + + + + + +Postel [Page 3] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + +3. THE SMTP PROCEDURES + + This section presents the procedures used in SMTP in several parts. + First comes the basic mail procedure defined as a mail transaction. + Following this are descriptions of forwarding mail, verifying mailbox + names and expanding mailing lists, sending to terminals instead of or + in combination with mailboxes, and the opening and closing exchanges. + At the end of this section are comments on relaying, a note on mail + domains, and a discussion of changing roles. Throughout this section + are examples of partial command and reply sequences, several complete + scenarios are presented in Appendix F. + + 3.1. MAIL + + There are three steps to SMTP mail transactions. The transaction + is started with a MAIL command which gives the sender + identification. A series of one or more RCPT commands follows + giving the receiver information. Then a DATA command gives the + mail data. And finally, the end of mail data indicator confirms + the transaction. + + The first step in the procedure is the MAIL command. The + contains the source mailbox. + + MAIL FROM: + + This command tells the SMTP-receiver that a new mail + transaction is starting and to reset all its state tables and + buffers, including any recipients or mail data. It gives the + reverse-path which can be used to report errors. If accepted, + the receiver-SMTP returns a 250 OK reply. + + The can contain more than just a mailbox. The + is a reverse source routing list of hosts and + source mailbox. The first host in the should be + the host sending this command. + + The second step in the procedure is the RCPT command. + + RCPT TO: + + This command gives a forward-path identifying one recipient. + If accepted, the receiver-SMTP returns a 250 OK reply, and + stores the forward-path. If the recipient is unknown the + receiver-SMTP returns a 550 Failure reply. This second step of + the procedure can be repeated any number of times. + + + +[Page 4] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + The can contain more than just a mailbox. The + is a source routing list of hosts and the + destination mailbox. The first host in the + should be the host receiving this command. + + The third step in the procedure is the DATA command. + + DATA + + If accepted, the receiver-SMTP returns a 354 Intermediate reply + and considers all succeeding lines to be the message text. + When the end of text is received and stored the SMTP-receiver + sends a 250 OK reply. + + Since the mail data is sent on the transmission channel the end + of the mail data must be indicated so that the command and + reply dialog can be resumed. SMTP indicates the end of the + mail data by sending a line containing only a period. A + transparency procedure is used to prevent this from interfering + with the user's text (see Section 4.5.2). + + Please note that the mail data includes the memo header + items such as Date, Subject, To, Cc, From [2]. + + The end of mail data indicator also confirms the mail + transaction and tells the receiver-SMTP to now process the + stored recipients and mail data. If accepted, the + receiver-SMTP returns a 250 OK reply. The DATA command should + fail only if the mail transaction was incomplete (for example, + no recipients), or if resources are not available. + + The above procedure is an example of a mail transaction. These + commands must be used only in the order discussed above. + Example 1 (below) illustrates the use of these commands in a mail + transaction. + + + + + + + + + + + + + + +Postel [Page 5] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + + ------------------------------------------------------------- + + Example of the SMTP Procedure + + This SMTP example shows mail sent by Smith at host Alpha.ARPA, + to Jones, Green, and Brown at host Beta.ARPA. Here we assume + that host Alpha contacts host Beta directly. + + S: MAIL FROM: + R: 250 OK + + S: RCPT TO: + R: 250 OK + + S: RCPT TO: + R: 550 No such user here + + S: RCPT TO: + R: 250 OK + + S: DATA + R: 354 Start mail input; end with . + S: Blah blah blah... + S: ...etc. etc. etc. + S: . + R: 250 OK + + The mail has now been accepted for Jones and Brown. Green did + not have a mailbox at host Beta. + + Example 1 + + ------------------------------------------------------------- + + + + + + + + + + + + + + + + +[Page 6] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + 3.2. FORWARDING + + There are some cases where the destination information in the + is incorrect, but the receiver-SMTP knows the + correct destination. In such cases, one of the following replies + should be used to allow the sender to contact the correct + destination. + + 251 User not local; will forward to + + This reply indicates that the receiver-SMTP knows the user's + mailbox is on another host and indicates the correct + forward-path to use in the future. Note that either the + host or user or both may be different. The receiver takes + responsibility for delivering the message. + + 551 User not local; please try + + This reply indicates that the receiver-SMTP knows the user's + mailbox is on another host and indicates the correct + forward-path to use. Note that either the host or user or + both may be different. The receiver refuses to accept mail + for this user, and the sender must either redirect the mail + according to the information provided or return an error + response to the originating user. + + Example 2 illustrates the use of these responses. + + ------------------------------------------------------------- + + Example of Forwarding + + Either + + S: RCPT TO: + R: 251 User not local; will forward to + + Or + + S: RCPT TO: + R: 551 User not local; please try + + Example 2 + + ------------------------------------------------------------- + + + + +Postel [Page 7] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + + 3.3. VERIFYING AND EXPANDING + + SMTP provides as additional features, commands to verify a user + name or expand a mailing list. This is done with the VRFY and + EXPN commands, which have character string arguments. For the + VRFY command, the string is a user name, and the response may + include the full name of the user and must include the mailbox of + the user. For the EXPN command, the string identifies a mailing + list, and the multiline response may include the full name of the + users and must give the mailboxes on the mailing list. + + "User name" is a fuzzy term and used purposely. If a host + implements the VRFY or EXPN commands then at least local mailboxes + must be recognized as "user names". If a host chooses to + recognize other strings as "user names" that is allowed. + + In some hosts the distinction between a mailing list and an alias + for a single mailbox is a bit fuzzy, since a common data structure + may hold both types of entries, and it is possible to have mailing + lists of one mailbox. If a request is made to verify a mailing + list a positive response can be given if on receipt of a message + so addressed it will be delivered to everyone on the list, + otherwise an error should be reported (e.g., "550 That is a + mailing list, not a user"). If a request is made to expand a user + name a positive response can be formed by returning a list + containing one name, or an error can be reported (e.g., "550 That + is a user name, not a mailing list"). + + In the case of a multiline reply (normal for EXPN) exactly one + mailbox is to be specified on each line of the reply. In the case + of an ambiguous request, for example, "VRFY Smith", where there + are two Smith's the response must be "553 User ambiguous". + + The case of verifying a user name is straightforward as shown in + example 3. + + + + + + + + + + + + + + +[Page 8] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + ------------------------------------------------------------- + + Example of Verifying a User Name + + Either + + S: VRFY Smith + R: 250 Fred Smith + + Or + + S: VRFY Smith + R: 251 User not local; will forward to + + Or + + S: VRFY Jones + R: 550 String does not match anything. + + Or + + S: VRFY Jones + R: 551 User not local; please try + + Or + + S: VRFY Gourzenkyinplatz + R: 553 User ambiguous. + + Example 3 + + ------------------------------------------------------------- + + + + + + + + + + + + + + + + + +Postel [Page 9] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + + The case of expanding a mailbox list requires a multiline reply as + shown in example 4. + + ------------------------------------------------------------- + + Example of Expanding a Mailing List + + Either + + S: EXPN Example-People + R: 250-Jon Postel + R: 250-Fred Fonebone + R: 250-Sam Q. Smith + R: 250-Quincy Smith <@USC-ISIF.ARPA:Q-Smith@ISI-VAXA.ARPA> + R: 250- + R: 250 + + Or + + S: EXPN Executive-Washroom-List + R: 550 Access Denied to You. + + Example 4 + + ------------------------------------------------------------- + + The character string arguments of the VRFY and EXPN commands + cannot be further restricted due to the variety of implementations + of the user name and mailbox list concepts. On some systems it + may be appropriate for the argument of the EXPN command to be a + file name for a file containing a mailing list, but again there is + a variety of file naming conventions in the Internet. + + The VRFY and EXPN commands are not included in the minimum + implementation (Section 4.5.1), and are not required to work + across relays when they are implemented. + + + + + + + + + + + + + +[Page 10] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + 3.4. SENDING AND MAILING + + The main purpose of SMTP is to deliver messages to user's + mailboxes. A very similar service provided by some hosts is to + deliver messages to user's terminals (provided the user is active + on the host). The delivery to the user's mailbox is called + "mailing", the delivery to the user's terminal is called + "sending". Because in many hosts the implementation of sending is + nearly identical to the implementation of mailing these two + functions are combined in SMTP. However the sending commands are + not included in the required minimum implementation + (Section 4.5.1). Users should have the ability to control the + writing of messages on their terminals. Most hosts permit the + users to accept or refuse such messages. + + The following three command are defined to support the sending + options. These are used in the mail transaction instead of the + MAIL command and inform the receiver-SMTP of the special semantics + of this transaction: + + SEND FROM: + + The SEND command requires that the mail data be delivered to + the user's terminal. If the user is not active (or not + accepting terminal messages) on the host a 450 reply may + returned to a RCPT command. The mail transaction is + successful if the message is delivered the terminal. + + SOML FROM: + + The Send Or MaiL command requires that the mail data be + delivered to the user's terminal if the user is active (and + accepting terminal messages) on the host. If the user is + not active (or not accepting terminal messages) then the + mail data is entered into the user's mailbox. The mail + transaction is successful if the message is delivered either + to the terminal or the mailbox. + + SAML FROM: + + The Send And MaiL command requires that the mail data be + delivered to the user's terminal if the user is active (and + accepting terminal messages) on the host. In any case the + mail data is entered into the user's mailbox. The mail + transaction is successful if the message is delivered the + mailbox. + + + +Postel [Page 11] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + + The same reply codes that are used for the MAIL commands are used + for these commands. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 12] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + 3.5. OPENING AND CLOSING + + At the time the transmission channel is opened there is an + exchange to ensure that the hosts are communicating with the hosts + they think they are. + + The following two commands are used in transmission channel + opening and closing: + + HELO + + QUIT + + In the HELO command the host sending the command identifies + itself; the command may be interpreted as saying "Hello, I am + ". + + ------------------------------------------------------------- + + Example of Connection Opening + + R: 220 BBN-UNIX.ARPA Simple Mail Transfer Service Ready + S: HELO USC-ISIF.ARPA + R: 250 BBN-UNIX.ARPA + + Example 5 + + ------------------------------------------------------------- + + ------------------------------------------------------------- + + Example of Connection Closing + + S: QUIT + R: 221 BBN-UNIX.ARPA Service closing transmission channel + + Example 6 + + ------------------------------------------------------------- + + + + + + + + + + +Postel [Page 13] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + + 3.6. RELAYING + + The forward-path may be a source route of the form + "@ONE,@TWO:JOE@THREE", where ONE, TWO, and THREE are hosts. This + form is used to emphasize the distinction between an address and a + route. The mailbox is an absolute address, and the route is + information about how to get there. The two concepts should not + be confused. + + Conceptually the elements of the forward-path are moved to the + reverse-path as the message is relayed from one server-SMTP to + another. The reverse-path is a reverse source route, (i.e., a + source route from the current location of the message to the + originator of the message). When a server-SMTP deletes its + identifier from the forward-path and inserts it into the + reverse-path, it must use the name it is known by in the + environment it is sending into, not the environment the mail came + from, in case the server-SMTP is known by different names in + different environments. + + If when the message arrives at an SMTP the first element of the + forward-path is not the identifier of that SMTP the element is not + deleted from the forward-path and is used to determine the next + SMTP to send the message to. In any case, the SMTP adds its own + identifier to the reverse-path. + + Using source routing the receiver-SMTP receives mail to be relayed + to another server-SMTP The receiver-SMTP may accept or reject the + task of relaying the mail in the same way it accepts or rejects + mail for a local user. The receiver-SMTP transforms the command + arguments by moving its own identifier from the forward-path to + the beginning of the reverse-path. The receiver-SMTP then becomes + a sender-SMTP, establishes a transmission channel to the next SMTP + in the forward-path, and sends it the mail. + + The first host in the reverse-path should be the host sending the + SMTP commands, and the first host in the forward-path should be + the host receiving the SMTP commands. + + Notice that the forward-path and reverse-path appear in the SMTP + commands and replies, but not necessarily in the message. That + is, there is no need for these paths and especially this syntax to + appear in the "To:" , "From:", "CC:", etc. fields of the message + header. + + If a server-SMTP has accepted the task of relaying the mail and + + + +[Page 14] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + later finds that the forward-path is incorrect or that the mail + cannot be delivered for whatever reason, then it must construct an + "undeliverable mail" notification message and send it to the + originator of the undeliverable mail (as indicated by the + reverse-path). + + This notification message must be from the server-SMTP at this + host. Of course, server-SMTPs should not send notification + messages about problems with notification messages. One way to + prevent loops in error reporting is to specify a null reverse-path + in the MAIL command of a notification message. When such a + message is relayed it is permissible to leave the reverse-path + null. A MAIL command with a null reverse-path appears as follows: + + MAIL FROM:<> + + An undeliverable mail notification message is shown in example 7. + This notification is in response to a message originated by JOE at + HOSTW and sent via HOSTX to HOSTY with instructions to relay it on + to HOSTZ. What we see in the example is the transaction between + HOSTY and HOSTX, which is the first step in the return of the + notification message. + + + + + + + + + + + + + + + + + + + + + + + + + + + +Postel [Page 15] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + + ------------------------------------------------------------- + + Example Undeliverable Mail Notification Message + + S: MAIL FROM:<> + R: 250 ok + S: RCPT TO:<@HOSTX.ARPA:JOE@HOSTW.ARPA> + R: 250 ok + S: DATA + R: 354 send the mail data, end with . + S: Date: 23 Oct 81 11:22:33 + S: From: SMTP@HOSTY.ARPA + S: To: JOE@HOSTW.ARPA + S: Subject: Mail System Problem + S: + S: Sorry JOE, your message to SAM@HOSTZ.ARPA lost. + S: HOSTZ.ARPA said this: + S: "550 No Such User" + S: . + R: 250 ok + + Example 7 + + ------------------------------------------------------------- + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 16] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + 3.7. DOMAINS + + Domains are a recently introduced concept in the ARPA Internet + mail system. The use of domains changes the address space from a + flat global space of simple character string host names to a + hierarchically structured rooted tree of global addresses. The + host name is replaced by a domain and host designator which is a + sequence of domain element strings separated by periods with the + understanding that the domain elements are ordered from the most + specific to the most general. + + For example, "USC-ISIF.ARPA", "Fred.Cambridge.UK", and + "PC7.LCS.MIT.ARPA" might be host-and-domain identifiers. + + Whenever domain names are used in SMTP only the official names are + used, the use of nicknames or aliases is not allowed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Postel [Page 17] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + + 3.8. CHANGING ROLES + + The TURN command may be used to reverse the roles of the two + programs communicating over the transmission channel. + + If program-A is currently the sender-SMTP and it sends the TURN + command and receives an ok reply (250) then program-A becomes the + receiver-SMTP. + + If program-B is currently the receiver-SMTP and it receives the + TURN command and sends an ok reply (250) then program-B becomes + the sender-SMTP. + + To refuse to change roles the receiver sends the 502 reply. + + Please note that this command is optional. It would not normally + be used in situations where the transmission channel is TCP. + However, when the cost of establishing the transmission channel is + high, this command may be quite useful. For example, this command + may be useful in supporting be mail exchange using the public + switched telephone system as a transmission channel, especially if + some hosts poll other hosts for mail exchanges. + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 18] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + +4. THE SMTP SPECIFICATIONS + + 4.1. SMTP COMMANDS + + 4.1.1. COMMAND SEMANTICS + + The SMTP commands define the mail transfer or the mail system + function requested by the user. SMTP commands are character + strings terminated by . The command codes themselves are + alphabetic characters terminated by if parameters follow + and otherwise. The syntax of mailboxes must conform to + receiver site conventions. The SMTP commands are discussed + below. The SMTP replies are discussed in the Section 4.2. + + A mail transaction involves several data objects which are + communicated as arguments to different commands. The + reverse-path is the argument of the MAIL command, the + forward-path is the argument of the RCPT command, and the mail + data is the argument of the DATA command. These arguments or + data objects must be transmitted and held pending the + confirmation communicated by the end of mail data indication + which finalizes the transaction. The model for this is that + distinct buffers are provided to hold the types of data + objects, that is, there is a reverse-path buffer, a + forward-path buffer, and a mail data buffer. Specific commands + cause information to be appended to a specific buffer, or cause + one or more buffers to be cleared. + + HELLO (HELO) + + This command is used to identify the sender-SMTP to the + receiver-SMTP. The argument field contains the host name of + the sender-SMTP. + + The receiver-SMTP identifies itself to the sender-SMTP in + the connection greeting reply, and in the response to this + command. + + This command and an OK reply to it confirm that both the + sender-SMTP and the receiver-SMTP are in the initial state, + that is, there is no transaction in progress and all state + tables and buffers are cleared. + + + + + + + +Postel [Page 19] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + + MAIL (MAIL) + + This command is used to initiate a mail transaction in which + the mail data is delivered to one or more mailboxes. The + argument field contains a reverse-path. + + The reverse-path consists of an optional list of hosts and + the sender mailbox. When the list of hosts is present, it + is a "reverse" source route and indicates that the mail was + relayed through each host on the list (the first host in the + list was the most recent relay). This list is used as a + source route to return non-delivery notices to the sender. + As each relay host adds itself to the beginning of the list, + it must use its name as known in the IPCE to which it is + relaying the mail rather than the IPCE from which the mail + came (if they are different). In some types of error + reporting messages (for example, undeliverable mail + notifications) the reverse-path may be null (see Example 7). + + This command clears the reverse-path buffer, the + forward-path buffer, and the mail data buffer; and inserts + the reverse-path information from this command into the + reverse-path buffer. + + RECIPIENT (RCPT) + + This command is used to identify an individual recipient of + the mail data; multiple recipients are specified by multiple + use of this command. + + The forward-path consists of an optional list of hosts and a + required destination mailbox. When the list of hosts is + present, it is a source route and indicates that the mail + must be relayed to the next host on the list. If the + receiver-SMTP does not implement the relay function it may + user the same reply it would for an unknown local user + (550). + + When mail is relayed, the relay host must remove itself from + the beginning forward-path and put itself at the beginning + of the reverse-path. When mail reaches its ultimate + destination (the forward-path contains only a destination + mailbox), the receiver-SMTP inserts it into the destination + mailbox in accordance with its host mail conventions. + + + + + +[Page 20] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + For example, mail received at relay host A with arguments + + FROM: + TO:<@HOSTA.ARPA,@HOSTB.ARPA:USERC@HOSTD.ARPA> + + will be relayed on to host B with arguments + + FROM:<@HOSTA.ARPA:USERX@HOSTY.ARPA> + TO:<@HOSTB.ARPA:USERC@HOSTD.ARPA>. + + This command causes its forward-path argument to be appended + to the forward-path buffer. + + DATA (DATA) + + The receiver treats the lines following the command as mail + data from the sender. This command causes the mail data + from this command to be appended to the mail data buffer. + The mail data may contain any of the 128 ASCII character + codes. + + The mail data is terminated by a line containing only a + period, that is the character sequence "." (see + Section 4.5.2 on Transparency). This is the end of mail + data indication. + + The end of mail data indication requires that the receiver + must now process the stored mail transaction information. + This processing consumes the information in the reverse-path + buffer, the forward-path buffer, and the mail data buffer, + and on the completion of this command these buffers are + cleared. If the processing is successful the receiver must + send an OK reply. If the processing fails completely the + receiver must send a failure reply. + + When the receiver-SMTP accepts a message either for relaying + or for final delivery it inserts at the beginning of the + mail data a time stamp line. The time stamp line indicates + the identity of the host that sent the message, and the + identity of the host that received the message (and is + inserting this time stamp), and the date and time the + message was received. Relayed messages will have multiple + time stamp lines. + + When the receiver-SMTP makes the "final delivery" of a + message it inserts at the beginning of the mail data a + + + +Postel [Page 21] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + + return path line. The return path line preserves the + information in the from the MAIL command. + Here, final delivery means the message leaves the SMTP + world. Normally, this would mean it has been delivered to + the destination user, but in some cases it may be further + processed and transmitted by another mail system. + + It is possible for the mailbox in the return path be + different from the actual sender's mailbox, for example, + if error responses are to be delivered a special error + handling mailbox rather than the message senders. + + The preceding two paragraphs imply that the final mail data + will begin with a return path line, followed by one or more + time stamp lines. These lines will be followed by the mail + data header and body [2]. See Example 8. + + Special mention is needed of the response and further action + required when the processing following the end of mail data + indication is partially successful. This could arise if + after accepting several recipients and the mail data, the + receiver-SMTP finds that the mail data can be successfully + delivered to some of the recipients, but it cannot be to + others (for example, due to mailbox space allocation + problems). In such a situation, the response to the DATA + command must be an OK reply. But, the receiver-SMTP must + compose and send an "undeliverable mail" notification + message to the originator of the message. Either a single + notification which lists all of the recipients that failed + to get the message, or separate notification messages must + be sent for each failed recipient (see Example 7). All + undeliverable mail notification messages are sent using the + MAIL command (even if they result from processing a SEND, + SOML, or SAML command). + + + + + + + + + + + + + + + +[Page 22] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + ------------------------------------------------------------- + + Example of Return Path and Received Time Stamps + + Return-Path: <@GHI.ARPA,@DEF.ARPA,@ABC.ARPA:JOE@ABC.ARPA> + Received: from GHI.ARPA by JKL.ARPA ; 27 Oct 81 15:27:39 PST + Received: from DEF.ARPA by GHI.ARPA ; 27 Oct 81 15:15:13 PST + Received: from ABC.ARPA by DEF.ARPA ; 27 Oct 81 15:01:59 PST + Date: 27 Oct 81 15:01:01 PST + From: JOE@ABC.ARPA + Subject: Improved Mailing System Installed + To: SAM@JKL.ARPA + + This is to inform you that ... + + Example 8 + + ------------------------------------------------------------- + + SEND (SEND) + + This command is used to initiate a mail transaction in which + the mail data is delivered to one or more terminals. The + argument field contains a reverse-path. This command is + successful if the message is delivered to a terminal. + + The reverse-path consists of an optional list of hosts and + the sender mailbox. When the list of hosts is present, it + is a "reverse" source route and indicates that the mail was + relayed through each host on the list (the first host in the + list was the most recent relay). This list is used as a + source route to return non-delivery notices to the sender. + As each relay host adds itself to the beginning of the list, + it must use its name as known in the IPCE to which it is + relaying the mail rather than the IPCE from which the mail + came (if they are different). + + This command clears the reverse-path buffer, the + forward-path buffer, and the mail data buffer; and inserts + the reverse-path information from this command into the + reverse-path buffer. + + SEND OR MAIL (SOML) + + This command is used to initiate a mail transaction in which + the mail data is delivered to one or more terminals or + + + +Postel [Page 23] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + + mailboxes. For each recipient the mail data is delivered to + the recipient's terminal if the recipient is active on the + host (and accepting terminal messages), otherwise to the + recipient's mailbox. The argument field contains a + reverse-path. This command is successful if the message is + delivered to a terminal or the mailbox. + + The reverse-path consists of an optional list of hosts and + the sender mailbox. When the list of hosts is present, it + is a "reverse" source route and indicates that the mail was + relayed through each host on the list (the first host in the + list was the most recent relay). This list is used as a + source route to return non-delivery notices to the sender. + As each relay host adds itself to the beginning of the list, + it must use its name as known in the IPCE to which it is + relaying the mail rather than the IPCE from which the mail + came (if they are different). + + This command clears the reverse-path buffer, the + forward-path buffer, and the mail data buffer; and inserts + the reverse-path information from this command into the + reverse-path buffer. + + SEND AND MAIL (SAML) + + This command is used to initiate a mail transaction in which + the mail data is delivered to one or more terminals and + mailboxes. For each recipient the mail data is delivered to + the recipient's terminal if the recipient is active on the + host (and accepting terminal messages), and for all + recipients to the recipient's mailbox. The argument field + contains a reverse-path. This command is successful if the + message is delivered to the mailbox. + + The reverse-path consists of an optional list of hosts and + the sender mailbox. When the list of hosts is present, it + is a "reverse" source route and indicates that the mail was + relayed through each host on the list (the first host in the + list was the most recent relay). This list is used as a + source route to return non-delivery notices to the sender. + As each relay host adds itself to the beginning of the list, + it must use its name as known in the IPCE to which it is + relaying the mail rather than the IPCE from which the mail + came (if they are different). + + This command clears the reverse-path buffer, the + + + +[Page 24] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + forward-path buffer, and the mail data buffer; and inserts + the reverse-path information from this command into the + reverse-path buffer. + + RESET (RSET) + + This command specifies that the current mail transaction is + to be aborted. Any stored sender, recipients, and mail data + must be discarded, and all buffers and state tables cleared. + The receiver must send an OK reply. + + VERIFY (VRFY) + + This command asks the receiver to confirm that the argument + identifies a user. If it is a user name, the full name of + the user (if known) and the fully specified mailbox are + returned. + + This command has no effect on any of the reverse-path + buffer, the forward-path buffer, or the mail data buffer. + + EXPAND (EXPN) + + This command asks the receiver to confirm that the argument + identifies a mailing list, and if so, to return the + membership of that list. The full name of the users (if + known) and the fully specified mailboxes are returned in a + multiline reply. + + This command has no effect on any of the reverse-path + buffer, the forward-path buffer, or the mail data buffer. + + HELP (HELP) + + This command causes the receiver to send helpful information + to the sender of the HELP command. The command may take an + argument (e.g., any command name) and return more specific + information as a response. + + This command has no effect on any of the reverse-path + buffer, the forward-path buffer, or the mail data buffer. + + + + + + + + +Postel [Page 25] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + + NOOP (NOOP) + + This command does not affect any parameters or previously + entered commands. It specifies no action other than that + the receiver send an OK reply. + + This command has no effect on any of the reverse-path + buffer, the forward-path buffer, or the mail data buffer. + + QUIT (QUIT) + + This command specifies that the receiver must send an OK + reply, and then close the transmission channel. + + The receiver should not close the transmission channel until + it receives and replies to a QUIT command (even if there was + an error). The sender should not close the transmission + channel until it send a QUIT command and receives the reply + (even if there was an error response to a previous command). + If the connection is closed prematurely the receiver should + act as if a RSET command had been received (canceling any + pending transaction, but not undoing any previously + completed transaction), the sender should act as if the + command or transaction in progress had received a temporary + error (4xx). + + TURN (TURN) + + This command specifies that the receiver must either (1) + send an OK reply and then take on the role of the + sender-SMTP, or (2) send a refusal reply and retain the role + of the receiver-SMTP. + + If program-A is currently the sender-SMTP and it sends the + TURN command and receives an OK reply (250) then program-A + becomes the receiver-SMTP. Program-A is then in the initial + state as if the transmission channel just opened, and it + then sends the 220 service ready greeting. + + If program-B is currently the receiver-SMTP and it receives + the TURN command and sends an OK reply (250) then program-B + becomes the sender-SMTP. Program-B is then in the initial + state as if the transmission channel just opened, and it + then expects to receive the 220 service ready greeting. + + To refuse to change roles the receiver sends the 502 reply. + + + +[Page 26] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + There are restrictions on the order in which these command may + be used. + + The first command in a session must be the HELO command. + The HELO command may be used later in a session as well. If + the HELO command argument is not acceptable a 501 failure + reply must be returned and the receiver-SMTP must stay in + the same state. + + The NOOP, HELP, EXPN, and VRFY commands can be used at any + time during a session. + + The MAIL, SEND, SOML, or SAML commands begin a mail + transaction. Once started a mail transaction consists of + one of the transaction beginning commands, one or more RCPT + commands, and a DATA command, in that order. A mail + transaction may be aborted by the RSET command. There may + be zero or more transactions in a session. + + If the transaction beginning command argument is not + acceptable a 501 failure reply must be returned and the + receiver-SMTP must stay in the same state. If the commands + in a transaction are out of order a 503 failure reply must + be returned and the receiver-SMTP must stay in the same + state. + + The last command in a session must be the QUIT command. The + QUIT command can not be used at any other time in a session. + + 4.1.2. COMMAND SYNTAX + + The commands consist of a command code followed by an argument + field. Command codes are four alphabetic characters. Upper + and lower case alphabetic characters are to be treated + identically. Thus, any of the following may represent the mail + command: + + MAIL Mail mail MaIl mAIl + + This also applies to any symbols representing parameter values, + such as "TO" or "to" for the forward-path. Command codes and + the argument fields are separated by one or more spaces. + However, within the reverse-path and forward-path arguments + case is important. In particular, in some hosts the user + "smith" is different from the user "Smith". + + + + +Postel [Page 27] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + + The argument field consists of a variable length character + string ending with the character sequence . The receiver + is to take no action until this sequence is received. + + Square brackets denote an optional argument field. If the + option is not taken, the appropriate default is implied. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Page 28] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + The following are the SMTP commands: + + HELO + + MAIL FROM: + + RCPT TO: + + DATA + + RSET + + SEND FROM: + + SOML FROM: + + SAML FROM: + + VRFY + + EXPN + + HELP [ ] + + NOOP + + QUIT + + TURN + + + + + + + + + + + + + + + + + + + + +Postel [Page 29] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + + The syntax of the above argument fields (using BNF notation + where applicable) is given below. The "..." notation indicates + that a field may be repeated one or more times. + + ::= + + ::= + + ::= "<" [ ":" ] ">" + + ::= | "," + + ::= "@" + + ::= | "." + + ::= | "#" | "[" "]" + + ::= "@" + + ::= | + + ::= + + ::= | + + ::= | + + ::= | | "-" + + ::= | "." + + ::= | + + ::= """ """ + + ::= "\" | "\" | | + + ::= | "\" + + ::= "." "." "." + + ::= | + + ::= + + + + +[Page 30] Postel + + + +RFC 821 August 1982 + Simple Mail Transfer Protocol + + + + ::= the carriage return character (ASCII code 13) + + ::= the line feed character (ASCII code 10) + + ::= the space character (ASCII code 32) + + ::= one, two, or three digits representing a decimal + integer value in the range 0 through 255 + + ::= any one of the 52 alphabetic characters A through Z + in upper case and a through z in lower case + + ::= any one of the 128 ASCII characters, but not any + or + + ::= any one of the ten digits 0 through 9 + + ::= any one of the 128 ASCII characters except , + , quote ("), or backslash (\) + + ::= any one of the 128 ASCII characters (no exceptions) + + ::= "<" | ">" | "(" | ")" | "[" | "]" | "\" | "." + | "," | ";" | ":" | "@" """ | the control + characters (ASCII codes 0 through 31 inclusive and + 127) + + Note that the backslash, "\", is a quote character, which is + used to indicate that the next character is to be used + literally (instead of its normal interpretation). For example, + "Joe\,Smith" could be used to indicate a single nine character + user field with comma being the fourth character of the field. + + Hosts are generally known by names which are translated to + addresses in each host. Note that the name elements of domains + are the official names -- no use of nicknames or aliases is + allowed. + + Sometimes a host is not known to the translation function and + communication is blocked. To bypass this barrier two numeric + forms are also allowed for host "names". One form is a decimal + integer prefixed by a pound sign, "#", which indicates the + number is the address of the host. Another form is four small + decimal integers separated by dots and enclosed by brackets, + e.g., "[123.255.37.2]", which indicates a 32-bit ARPA Internet + Address in four 8-bit fields. + + + +Postel [Page 31] + + + +August 1982 RFC 821 +Simple Mail Transfer Protocol + + + + The time stamp line and the return path line are formally + defined as follows: + + ::= "Return-Path:" + + ::= "Received:" + + ::= ";" + + + ::= "FROM" + + ::= "BY" + + ::= [] [] [] [] + + ::= "VIA" + + ::= "WITH" + + ::= "ID" + + ::= "FOR" + + ::= The standard names for links are registered with + the Network Information Center. + + ::= The standard names for protocols are + registered with the Network Information Center. + + ::=