Apply by doing:
	cd /usr/src
	patch -p0 < 001_sendmail.patch

And then rebuild, install and restart sendmail:
	cd gnu/usr.sbin/sendmail
	make obj
	make depend
	make
	make install
	kill -HUP `sed 1q /var/run/sendmail.pid`

Index: gnu/usr.sbin/sendmail/RELEASE_NOTES
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/RELEASE_NOTES,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/RELEASE_NOTES	2001/02/28 02:43:48	1.4
+++ gnu/usr.sbin/sendmail/RELEASE_NOTES	2001/05/29 01:31:10	1.5
@@ -1,11 +1,75 @@
 			SENDMAIL RELEASE NOTES
-      $Sendmail: RELEASE_NOTES,v 8.561.2.5.2.208 2001/02/26 21:24:54 gshapiro Exp $
+      $Sendmail: RELEASE_NOTES,v 8.561.2.5.2.235 2001/05/27 21:39:16 gshapiro Exp $
 
 
 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.11.4/8.11.4	2001/05/28
+	Clean up signal handling routines to reduce the chances of heap
+		corruption and other potential race conditions.
+		Terminating and restarting the daemon may not be
+		instantaneous due to this change.  Also, non-root users can
+		no longer send out-of-band signals.  Problem reported by
+		Michal Zalewski of BindView.
+	If LogLevel is greater than 9 and SASL fails to negotiate an
+		encryption layer, avoid core dump logging the encryption
+		strength.  Problem noted by Miroslav Zubcic of Crol.
+	If a server offers "AUTH=" and "AUTH " and the list of mechanisms is
+		different in those two lines, sendmail might not have
+		recognized (and used) all of the offered mechanisms.
+	Fix an IP address lookup problem on Solaris 2.0 - 2.3.  Patch
+		from Kenji Miyake.
+	This time, really don't use the .. directory when expanding
+		QueueDirectory wildcards.
+	If a process is interrupted while closing a map, don't try to close
+		the same map again while exiting.
+	Allow local mailers (F=l) to contact remote hosts (e.g., via
+		LMTP).  Problem noted by Norbert Klasen of the University
+		of Tuebingen.
+	If Timeout.QueueReturn was set to a value less the time it took
+		to write a new queue file (e.g., 0 seconds), the bounce
+		message would be lost.  Problem noted by Lorraine L Goff of
+		Oklahoma State University.
+	Pass map argument vector into map rewriting engine for the regex
+		and prog map types.  Problem noted by Stephen Gildea of
+		InTouch Systems, Inc.
+	When closing an LDAP map due to a temporary error, close all of the
+		other LDAP maps which share the original map's connection
+		to the LDAP server.  Patch from Victor Duchovni of
+		Morgan Stanley.
+	To detect changes of NDBM aliases files check the timestamp of the
+		.pag file instead of the .dir file.  Problem noted by Neil
+		Rickert of Northern Illinois University.
+	Don't treat temporary hesiod lookup failures as permanent.  Patch
+		from Werner Wiethege.
+	If ClientPortOptions is set, make sure to create the outgoing socket
+		with the family set in that option.  Patch from Sean Farley.
+	Avoid a segmentation fault trying to dereference a NULL pointer
+		when logging a MaxHopCount exceeded error with an empty
+		recipient list.  Problem noted by Chris Adams of HiWAAY
+		Internet Services.
+	Fix DSN for "Too many hops" bounces.  Problem noticed by Ulrich
+		Windl of the Universitaet Regensburg.
+	Fix DSN for "mail loops back to me" bounces.  Problem noticed by
+		Kari Hurtta of the Finnish Meteorological Institute.
+	Portability:
+		OpenBSD has a broken setreuid() implementation.
+	CONFIG: Undo change from 8.11.1: change 501 SMTP reply code back
+		to 553 since it is allowed by DRUMS.
+	CONFIG: Add OSTYPE(freebsd4) for FreeBSD 4.X.
+	DEVTOOLS: install.sh did not properly handle paths in the source
+		file name argument.  Noted by Kari Hurtta of the Finnish
+		Meteorological Institute.
+	DEVTOOLS: Add FAST_PID_RECYCLE to compile time options for OpenBSD
+		since it generates random process ids.
+	PRALIASES: Add back adaptive algorithm to deal with different endings
+		of entries in the database (with/without trailing '\0').
+		Patch from John Beck of Sun Microsystems.
+	New Files:
+		cf/ostype/freebsd4.m4
+
 8.11.3/8.11.3	2001/02/27
 	Prevent a segmentation fault when a bogus value was used in the
 		LDAPDefaultSpec option's -r, -s, or -M flags and if a bogus
@@ -2651,7 +2715,7 @@
 	CONFIG: new FEATURE(relay_based_on_MX) to allow relaying based on
 		the MX records of the host portion of an incoming recipient.
 	CONFIG: new FEATURE(access_db) which turns on the access database
-		feature.  This database give you the ability to allow
+		feature.  This database gives you the ability to allow
 		or refuse to accept mail from specified domains for
 		administrative reasons.  By default, names that are listed
 		as "OK" in the access db are domain names, not host names.
Index: gnu/usr.sbin/sendmail/cf/README
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/cf/README,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- gnu/usr.sbin/sendmail/cf/README	2001/02/28 02:43:49	1.5
+++ gnu/usr.sbin/sendmail/cf/README	2001/05/29 01:31:10	1.6
@@ -3113,6 +3113,7 @@
 relayed to another MTA.  It will also enforce the normal address syntax
 rules and log error messages.  Additionally, by using the M=a modifier
 you can require authentication before messages are accepted by the MSA.
+Notice: Do NOT use the 'a' modifier on a public accessible MTA!
 Finally, the M=E modifier shown above disables ETRN as required by RFC
 2476.
 
@@ -3277,4 +3278,4 @@
    8	DNS based blacklists
    9	special local rulesets (1 and 2)
 
-$Revision: 1.5 $, Last updated $Date: 2001/02/28 02:43:49 $
+$Revision: 1.6 $, Last updated $Date: 2001/05/29 01:31:10 $
Index: gnu/usr.sbin/sendmail/cf/cf/Makefile
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/cf/cf/Makefile,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- gnu/usr.sbin/sendmail/cf/cf/Makefile	2001/02/02 06:41:18	1.9
+++ gnu/usr.sbin/sendmail/cf/cf/Makefile	2001/05/29 01:31:11	1.10
@@ -1,8 +1,8 @@
-#	$OpenBSD: Makefile,v 1.9 2001/02/02 06:41:18 tholo Exp $
+#	$OpenBSD: Makefile,v 1.10 2001/05/29 01:31:11 millert Exp $
 #
 #  Makefile for configuration files.
 #
-#	$Sendmail: Makefile,v 8.40.8.4 2000/10/26 18:27:44 gshapiro Exp $
+#	$Sendmail: Makefile,v 8.40.8.5 2001/04/12 22:39:52 gshapiro Exp $
 #
 
 #
@@ -110,7 +110,6 @@
 	${CFDIR}/ostype/aix4.m4 \
 	${CFDIR}/ostype/altos.m4 \
 	${CFDIR}/ostype/amdahl-uts.m4 \
-	${CFDIR}/ostype/aux.m4 \
 	${CFDIR}/ostype/bsd4.3.m4 \
 	${CFDIR}/ostype/bsd4.4.m4 \
 	${CFDIR}/ostype/bsdi.m4 \
Index: gnu/usr.sbin/sendmail/cf/m4/cfhead.m4
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/cf/m4/cfhead.m4,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/cf/m4/cfhead.m4	2001/02/28 02:43:50	1.4
+++ gnu/usr.sbin/sendmail/cf/m4/cfhead.m4	2001/05/29 01:31:11	1.5
@@ -223,7 +223,6 @@
 	_REC_TLS_
 	_REC_END_')
 define(`confSEVEN_BIT_INPUT', `False')
-define(`confEIGHT_BIT_HANDLING', `pass8')
 define(`confALIAS_WAIT', `10')
 define(`confMIN_FREE_BLOCKS', `100')
 define(`confBLANK_SUB', `.')
@@ -252,4 +251,4 @@
 
 
 divert(0)dnl
-VERSIONID(`$Sendmail: cfhead.m4,v 8.76.4.15 2001/02/14 04:07:20 gshapiro Exp $')
+VERSIONID(`$Sendmail: cfhead.m4,v 8.76.4.16 2001/03/06 22:56:36 ca Exp $')
Index: gnu/usr.sbin/sendmail/cf/m4/proto.m4
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/cf/m4/proto.m4,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- gnu/usr.sbin/sendmail/cf/m4/proto.m4	2001/01/15 21:08:57	1.3
+++ gnu/usr.sbin/sendmail/cf/m4/proto.m4	2001/05/29 01:31:11	1.4
@@ -13,7 +13,7 @@
 #
 divert(0)
 
-VERSIONID(`$Sendmail: proto.m4,v 8.446.2.5.2.38 2000/12/28 03:37:28 ca Exp $')
+VERSIONID(`$Sendmail: proto.m4,v 8.446.2.5.2.41 2001/05/23 21:32:16 ca Exp $')
 
 MAILER(local)dnl
 
@@ -77,6 +77,7 @@
 define(`_U_',ifdef(`_DELAY_CHECKS_',`',`_'))
 dnl default relaying denied message
 ifdef(`confRELAY_MSG', `', `define(`confRELAY_MSG', `"550 Relaying denied"')')
+define(`CODE553', `553')
 divert(0)dnl
 
 # override file safeties - setting this option compromises system security,
@@ -221,7 +222,7 @@
 _OPTION(SevenBitInput, `confSEVEN_BIT_INPUT', `False')
 
 # 8-bit data handling
-_OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `adaptive')
+_OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `pass8')
 
 # wait for alias file rebuild (default units: minutes)
 _OPTION(AliasWait, `confALIAS_WAIT', `5m')
@@ -867,26 +868,26 @@
 
 SParse0
 R<@>			$@ <@>			special case error msgs
-R$* : $* ; <@>		$#error $@ 5.1.3 $: "501 List:; syntax illegal for recipient addresses"
+R$* : $* ; <@>		$#error $@ 5.1.3 $: "CODE553 List:; syntax illegal for recipient addresses"
 R@ <@ $* >		< @ $1 >		catch "@@host" bogosity
-R<@ $+>			$#error $@ 5.1.3 $: "501 User address required"
+R<@ $+>			$#error $@ 5.1.3 $: "CODE553 User address required"
 R$*			$: <> $1
 R<> $* < @ [ $+ ] > $*	$1 < @ [ $2 ] > $3
-R<> $* <$* : $* > $*	$#error $@ 5.1.3 $: "501 Colon illegal in host name part"
+R<> $* <$* : $* > $*	$#error $@ 5.1.3 $: "CODE553 Colon illegal in host name part"
 R<> $*			$1
-R$* < @ . $* > $*	$#error $@ 5.1.2 $: "501 Invalid host name"
-R$* < @ $* .. $* > $*	$#error $@ 5.1.2 $: "501 Invalid host name"
+R$* < @ . $* > $*	$#error $@ 5.1.2 $: "CODE553 Invalid host name"
+R$* < @ $* .. $* > $*	$#error $@ 5.1.2 $: "CODE553 Invalid host name"
 dnl comma only allowed before @; this check is not complete
-R$* , $~O $*		$#error $@ 5.1.2 $: "501 Invalid route address"
+R$* , $~O $*		$#error $@ 5.1.2 $: "CODE553 Invalid route address"
 
 # now delete the local info -- note $=O to find characters that cause forwarding
 R$* < @ > $*		$@ $>Parse0 $>canonify $1	user@ => user
 R< @ $=w . > : $*	$@ $>Parse0 $>canonify $2	@here:... -> ...
 R$- < @ $=w . >		$: $(dequote $1 $) < @ $2 . >	dequote "foo"@here
-R< @ $+ >		$#error $@ 5.1.3 $: "501 User address required"
+R< @ $+ >		$#error $@ 5.1.3 $: "CODE553 User address required"
 R$* $=O $* < @ $=w . >	$@ $>Parse0 $>canonify $1 $2 $3	...@here -> ...
 R$- 			$: $(dequote $1 $) < @ *LOCAL* >	dequote "foo"
-R< @ *LOCAL* >		$#error $@ 5.1.3 $: "501 User address required"
+R< @ *LOCAL* >		$#error $@ 5.1.3 $: "CODE553 User address required"
 R$* $=O $* < @ *LOCAL* >
 			$@ $>Parse0 $>canonify $1 $2 $3	...@*LOCAL* -> ...
 R$* < @ *LOCAL* >	$: $1
@@ -935,8 +936,10 @@
 R<!> $+			$: $1
 R< error : $-.$-.$- : $+ > $* 	$#error $@ $1.$2.$3 $: $4
 R< error : $- $+ > $* 	$#error $@ $(dequote $1 $) $: $2
-R< $+ > $+ < @ $+ >	$: $>Recurse $1',
-`dnl')
+ifdef(`_NO_VIRTUSER_RECURSION_',
+`R< $+ > $+ < @ $+ >	$: $>ParseLocal $>Parse0 $>canonify $1',
+`R< $+ > $+ < @ $+ >	$: $>Recurse $1')
+dnl', `dnl')
 
 # short circuit local delivery so forwarded email works
 ifdef(`_MAILER_usenet_', `dnl
@@ -1013,7 +1016,7 @@
 # deal with other remote names
 ifdef(`_MAILER_smtp_',
 `R$* < @$* > $*		$#_SMTP_ $@ $2 $: $1 < @ $2 > $3	user@host.domain',
-`R$* < @$* > $*		$#error $@ 5.1.2 $: "501 Unrecognized host name " $2')
+`R$* < @$* > $*		$#error $@ 5.1.2 $: "CODE553 Unrecognized host name " $2')
 
 # handle locally delivered names
 R$=L			$#_LOCAL_ $: @ $1		special local names
@@ -1522,7 +1525,7 @@
 dnl	or:    <address>
 dnl	or:    <?> <address>	(thanks to u in ${daemon_flags})
 R<? $=w> $*		$: $2			local client: ok
-R<? $+> <$+>		$#error $@ 5.5.4 $: "501 Real domain name required for sender address"
+R<? $+> <$+>		$#error $@ 5.5.4 $: "CODE553 Real domain name required for sender address"
 dnl remove <?> (happens only if ${client_name} == "" or u in ${daemon_flags})
 R<?> $*			$: $1')
 dnl workspace: address (or <address>)
@@ -1572,13 +1575,13 @@
 R$* $| $*		$: $2
 R<?> $*			$: < ? $&{client_name} > $1
 R<?> $*			$@ <OK>				...local unqualed ok
-R<? $+> $*		$#error $@ 5.5.4 $: "501 Domain name required for sender address " $&f
+R<? $+> $*		$#error $@ 5.5.4 $: "CODE553 Domain name required for sender address " $&f
 							...remote is not')
 # check results
 R<?> $*			$: @ $1		mark address: nothing known about it
 R<OK> $*		$@ <OK>
 R<TEMP> $*		$#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve"
-R<PERM> $*		$#error $@ 5.1.8 $: "501 Domain of sender address " $&f " does not exist"
+R<PERM> $*		$#error $@ 5.1.8 $: "CODE553 Domain of sender address " $&f " does not exist"
 ifdef(`_ACCESS_TABLE_', `dnl
 R<$={Accept}> $*	$# $1
 R<DISCARD> $*		$#discard $: discard
Index: gnu/usr.sbin/sendmail/cf/m4/version.m4
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/cf/m4/version.m4,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/cf/m4/version.m4	2001/02/28 02:43:50	1.4
+++ gnu/usr.sbin/sendmail/cf/m4/version.m4	2001/05/29 01:31:11	1.5
@@ -11,8 +11,8 @@
 # the sendmail distribution.
 #
 #
-VERSIONID(`$Sendmail: version.m4,v 8.39.4.26 2001/02/27 19:22:29 gshapiro Exp $')
+VERSIONID(`$Sendmail: version.m4,v 8.39.4.29 2001/05/27 21:39:20 gshapiro Exp $')
 #
 divert(0)
 # Configuration version number
-DZ8.11.3`'ifdef(`confCF_VERSION', `/confCF_VERSION')
+DZ8.11.4`'ifdef(`confCF_VERSION', `/confCF_VERSION')
Index: gnu/usr.sbin/sendmail/cf/ostype/aux.m4
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/cf/ostype/aux.m4,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- gnu/usr.sbin/sendmail/cf/ostype/aux.m4	2001/01/15 21:08:58	1.2
+++ gnu/usr.sbin/sendmail/cf/ostype/aux.m4	2001/05/29 01:31:11	1.3
@@ -13,7 +13,7 @@
 #
 
 divert(0)
-VERSIONID(`$Sendmail: aux.m4,v 8.16 1999/04/24 05:37:40 gshapiro Exp $')
+VERSIONID(`$Sendmail: a-ux.m4,v 8.1 2001/04/12 22:29:58 gshapiro Exp $')
 ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /usr/spool/mqueue)')dnl
 ifdef(`UUCP_MAILER_PATH',, `define(`UUCP_MAILER_PATH', /usr/bin/uux)')dnl
 _DEFIFNOT(`LOCAL_MAILER_FLAGS', `mn9')dnl
Index: gnu/usr.sbin/sendmail/doc/op/op.me
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/doc/op/op.me,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- gnu/usr.sbin/sendmail/doc/op/op.me	2001/02/28 02:43:50	1.5
+++ gnu/usr.sbin/sendmail/doc/op/op.me	2001/05/29 01:31:11	1.6
@@ -9,7 +9,7 @@
 .\" the sendmail distribution.
 .\"
 .\"
-.\"	$Sendmail: op.me,v 8.317.4.56 2001/02/15 23:38:16 ca Exp $
+.\"	$Sendmail: op.me,v 8.317.4.64 2001/05/24 16:45:49 ca Exp $
 .\"
 .\" eqn op.me | pic | troff -me
 .eh 'SMM:08-%''Sendmail Installation and Operation Guide'
@@ -53,7 +53,7 @@
 .de Ve
 Version \\$2
 ..
-.Ve $Revision: 1.5 $
+.Ve $Revision: 1.6 $
 .rm Ve
 .sp
 For Sendmail Version 8.11
@@ -2413,7 +2413,7 @@
 .b QueueLA
 option
 plus one
-exceeds the priority of the message \(em
+is less than the priority of the message \(em
 that is, the message is queued iff:
 .EQ
 pri > { bold QueueFactor } over { LA - { bold QueueLA } + 1 }
@@ -2455,7 +2455,7 @@
 i	deliver interactively (synchronously)
 b	deliver in background (asynchronously)
 q	queue only (don't deliver)
-d	defer delvery attempts (don't deliver)
+d	defer delivery attempts (don't deliver)
 .)b
 There are tradeoffs.
 Mode
@@ -3357,13 +3357,14 @@
 .b $#
 syntax should
 .i only
-be used in ruleset zero
-or a subroutine of ruleset zero.
+be used in ruleset zero,
+a subroutine of ruleset zero,
+or rulesets that return decisions (e.g., check_rcpt).
 It causes evaluation of the ruleset to terminate immediately,
 and signals to
 .i sendmail
 that the address has completely resolved.
-The complete syntax is:
+The complete syntax for ruleset 0 is:
 .(b
 \fB$#\fP\fImailer\fP \fB$@\fP\fIhost\fP \fB$:\fP\fIuser\fP
 .)b
@@ -5299,7 +5300,7 @@
 ${hdr_name} and ${currHeader}.
 The header is treated as a structured field,
 that is,
-comments (in parentheses) are deleted before processing,
+text in parentheses is deleted before processing,
 unless the second form
 .b $>+
 is used.
@@ -5498,6 +5499,8 @@
 .ip CACERTPath
 [no short name]
 Path to directory with certificates of CAs.
+This directory directory must contain the hashes of each CA certificate
+as filenames (or as links to them).
 .ip CACERTFile
 [no short name]
 File containing one CA certificate.
@@ -5700,6 +5703,12 @@
 effect in the standard configuration file, in which
 they are available via
 .b ${daemon_flags} .
+Notice: Do
+.b not
+use the ``a'' modifier on a public accessible MTA!
+It should only be used for a MSA that is accessed by authorized
+users for initial mail submission.
+Users must authenticate to use a MSA which has this option turned on.
 The flags ``c'' and ``C'' can change the default for
 hostname canonification in the
 .i sendmail.cf
@@ -6825,13 +6834,13 @@
 (very unlikely).
 .ip UnsafeGroupWrites
 [no short name]
-If set,
+If set (default),
 :include: and .forward files that are group writable are considered
 .q unsafe ,
 that is,
 they cannot reference programs or write directly to files.
 World writable :include: and .forward files
-are always unsafe..
+are always unsafe.
 .ip UseErrorsTo
 [l]
 If there is an
@@ -8705,6 +8714,14 @@
 The DNs of these certificates are sent
 to the client during the TLS handshake (as part of the
 CertificateRequest) as the list of acceptable CAs.
+The CACERTPath directory must contain the hashes of each CA certificate
+as filenames (or as links to them).
+Symbolic links can be generated with the following
+two (Bourne) shell commands:
+.(b
+C=FileName_of_CA_Certificate
+ln -s $C `openssl x509 -noout -hash < $C`.0
+.)b
 An X.509 certificate is also required for authentication in client mode
 (ClientCertFile), however,
 .i sendmail
@@ -9259,10 +9276,6 @@
 .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.
@@ -9412,7 +9425,7 @@
 .\".sz 10
 .\"Eric Allman
 .\".sp
-.\"Version $Revision: 1.5 $
+.\"Version $Revision: 1.6 $
 .\".ce 0
 .bp 3
 .ce
Index: gnu/usr.sbin/sendmail/include/libmilter/milter.h
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/include/libmilter/milter.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- gnu/usr.sbin/sendmail/include/libmilter/milter.h	2001/01/15 21:09:01	1.2
+++ gnu/usr.sbin/sendmail/include/libmilter/milter.h	2001/05/29 01:31:12	1.3
@@ -7,7 +7,7 @@
  * the sendmail distribution.
  *
  *
- *	$Sendmail: milter.h,v 8.24.16.8 2000/09/17 17:04:24 gshapiro Exp $
+ *	$Sendmail: milter.h,v 8.24.16.9 2001/03/02 21:22:48 geir Exp $
  */
 
 /*
Index: gnu/usr.sbin/sendmail/libmilter/README
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/libmilter/README,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- gnu/usr.sbin/sendmail/libmilter/README	2001/02/28 02:43:51	1.5
+++ gnu/usr.sbin/sendmail/libmilter/README	2001/05/29 01:31:12	1.6
@@ -10,7 +10,7 @@
 issuing the './Build' command in SRCDIR/libmilter .
 
 NOTE: Both libmilter and the callouts in sendmail are marked as an FFR (For
-Future Release).  If you intend to use them in 8.10.X, you must compiled
+Future Release).  If you intend to use them in 8.11.X, you must compiled
 both libmilter and sendmail with -D_FFR_MILTER defined.  You can do this by
 adding the following to your devtools/Site/site.config.m4 file:
 
@@ -97,7 +97,8 @@
 where 's' is seconds and 'm' is minutes.
 
 Which filters are invoked and their sequencing is handled by the 
-InputMailFilters option.
+InputMailFilters option. Note: if InputMailFilters is not defined no filters
+will be used.
 
 	O InputMailFilters=filter1, filter2, filter3
 
@@ -223,7 +224,7 @@
 	char **envfrom;
 {
 	struct mlfiPriv *priv;
-	int fd;
+	int fd = -1;
 
 	/* allocate some private memory */
 	priv = malloc(sizeof *priv);
@@ -244,6 +245,8 @@
 	if ((fd = mkstemp(priv->mlfi_fname)) < 0 ||
 	    (priv->mlfi_fp = fdopen(fd, "w+")) == NULL)
 	{
+		if (fd >= 0)
+			(void) close(fd);
 		free(priv->mlfi_fname);
 		free(priv);
 		return SMFIS_TEMPFAIL;
@@ -421,4 +424,4 @@
 
 /* eof */
 
-$Revision: 1.5 $, Last updated $Date: 2001/02/28 02:43:51 $
+$Revision: 1.6 $, Last updated $Date: 2001/05/29 01:31:12 $
Index: gnu/usr.sbin/sendmail/libmilter/libmilter.h
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/libmilter/libmilter.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- gnu/usr.sbin/sendmail/libmilter/libmilter.h	2001/01/15 21:09:02	1.2
+++ gnu/usr.sbin/sendmail/libmilter/libmilter.h	2001/05/29 01:31:12	1.3
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  *
  * By using this file, you agree to the terms and conditions set
@@ -17,7 +17,7 @@
 # define EXTERN
 # define INIT(x)	= x
 # ifndef lint
-static char MilterlId[] = "@(#)$Sendmail: libmilter.h,v 8.3.6.10 2000/11/20 21:15:36 ca Exp $";
+static char MilterlId[] = "@(#)$Sendmail: libmilter.h,v 8.3.6.14 2001/05/27 14:31:12 ca Exp $";
 # endif /* ! lint */
 #else /* _DEFINE */
 # define EXTERN extern
@@ -58,7 +58,7 @@
 #define MILTER_VERSION		100
 
 /* some defaults */
-#define MI_TIMEOUT	1800		/* default timeout for read/write */
+#define MI_TIMEOUT	7210		/* default timeout for read/write */
 #define MI_CHK_TIME	5		/* checking whether to terminate */
 
 #if SOMAXCONN > 20
@@ -70,6 +70,7 @@
 /* maximum number of repeated failures in mi_listener() */
 #define MAX_FAILS_M	16	/* malloc() */
 #define MAX_FAILS_T	16	/* thread creation */
+#define MAX_FAILS_A	16	/* accept() */
 
 /* internal "commands", i.e., error codes */
 #define SMFIC_TIMEOUT	((char) 1)	/* timeout */
Index: gnu/usr.sbin/sendmail/libmilter/listener.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/libmilter/listener.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- gnu/usr.sbin/sendmail/libmilter/listener.c	2001/02/28 02:43:51	1.3
+++ gnu/usr.sbin/sendmail/libmilter/listener.c	2001/05/29 01:31:12	1.4
@@ -9,7 +9,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: listener.c,v 8.38.2.1.2.21 2001/02/14 02:20:40 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: listener.c,v 8.38.2.1.2.22 2001/05/16 17:15:58 ca Exp $";
 #endif /* ! lint */
 
 #if _FFR_MILTER
@@ -515,6 +515,8 @@
 	int ret = MI_SUCCESS;
 	int mcnt = 0;
 	int tcnt = 0;
+	int acnt = 0;
+	int save_errno = 0;
 	sthread_t thread_id;
 	_SOCK_ADDR cliaddr;
 	SOCKADDR_LEN_T socksize;
@@ -574,10 +576,9 @@
 		}
 		if (r < 0)
 		{
-			int err = errno;
-
+			save_errno = errno;
 			(void) smutex_unlock(&L_Mutex);
-			if (err == EINTR)
+			if (save_errno == EINTR)
 				continue;
 			ret = MI_FAILURE;
 			break;
@@ -593,6 +594,7 @@
 		memset(&cliaddr, '\0', sizeof cliaddr);
 		connfd = accept(listenfd, (struct sockaddr *) &cliaddr,
 				&clilen);
+		save_errno = errno;
 		(void) smutex_unlock(&L_Mutex);
 
 		/*
@@ -610,14 +612,23 @@
 		{
 			(void) close(connfd);
 			connfd = INVALID_SOCKET;
-			errno = EINVAL;
+			save_errno = EINVAL;
 		}
 
 		if (!ValidSocket(connfd))
 		{
 			smi_log(SMI_LOG_ERR,
-				"%s: accept() returned invalid socket",
-				smfi->xxfi_name);
+				"%s: accept() returned invalid socket (%s)",
+				smfi->xxfi_name, strerror(save_errno));
+			if (save_errno == EINTR)
+				continue;
+			acnt++;
+			MI_SLEEP(acnt);
+			if (acnt >= MAX_FAILS_A)
+			{
+				ret = MI_FAILURE;
+				break;
+			}
 			continue;
 		}
 
@@ -643,6 +654,7 @@
 			continue;
 		}
 		mcnt = 0;
+		acnt = 0;
 		memset(ctx, '\0', sizeof *ctx);
 		ctx->ctx_sd = connfd;
 		ctx->ctx_dbg = dbg;
Index: gnu/usr.sbin/sendmail/libmilter/main.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/libmilter/main.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- gnu/usr.sbin/sendmail/libmilter/main.c	2001/01/15 21:09:02	1.2
+++ gnu/usr.sbin/sendmail/libmilter/main.c	2001/05/29 01:31:12	1.3
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers.
+ *  Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  *
  * By using this file, you agree to the terms and conditions set
@@ -9,7 +9,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: main.c,v 8.34.4.9 2000/09/09 02:23:03 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: main.c,v 8.34.4.11 2001/05/07 22:06:37 gshapiro Exp $";
 #endif /* ! lint */
 
 #if _FFR_MILTER
@@ -131,9 +131,11 @@
 	return MI_SUCCESS;
 }
 
+
 int
 smfi_main()
 {
+
 	signal(SIGPIPE, SIG_IGN);
 	if (conn == NULL)
 	{
@@ -150,6 +152,7 @@
 			smfi->xxfi_name);
 		return MI_FAILURE;
 	}
+
 
 	/* Startup the listener */
 	if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS)
Index: gnu/usr.sbin/sendmail/libmilter/sm_gethost.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/libmilter/sm_gethost.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- gnu/usr.sbin/sendmail/libmilter/sm_gethost.c	2001/02/28 02:43:51	1.3
+++ gnu/usr.sbin/sendmail/libmilter/sm_gethost.c	2001/05/29 01:31:13	1.4
@@ -9,7 +9,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: sm_gethost.c,v 8.7.8.6 2001/02/14 04:07:23 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: sm_gethost.c,v 8.7.8.10 2001/05/09 20:57:12 gshapiro Exp $";
 #endif /* ! lint */
 
 #if _FFR_MILTER
@@ -29,7 +29,7 @@
 **	Support IPv6 as well as IPv4.
 */
 
-#if NETINET6 && NEEDSGETIPNODE && __RES < 19990909
+#if NETINET6 && NEEDSGETIPNODE
 
 # ifndef AI_V4MAPPED
 #  define AI_V4MAPPED	0	/* dummy */
@@ -75,7 +75,7 @@
 	return;
 }
 # endif /* _FFR_FREEHOSTENT */
-#endif /* NEEDSGETIPNODE && NETINET6 && __RES < 19990909 */
+#endif /* NEEDSGETIPNODE && NETINET6 */
 
 struct hostent *
 mi_gethostbyname(name, family)
Index: gnu/usr.sbin/sendmail/mailstats/mailstats.8
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/mailstats/mailstats.8,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- gnu/usr.sbin/sendmail/mailstats/mailstats.8	2001/03/01 20:20:39	1.6
+++ gnu/usr.sbin/sendmail/mailstats/mailstats.8	2001/05/29 01:31:13	1.7
@@ -1,4 +1,4 @@
-.\" Copyright (c) 1998 Sendmail, Inc. and its suppliers.
+.\" Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
 .\"	All rights reserved.
 .\"
 .\" By using this file, you agree to the terms and conditions set
@@ -6,9 +6,9 @@
 .\" the sendmail distribution.
 .\"
 .\"
-.\"	$Sendmail: mailstats.8,v 8.17.4.3 2000/12/29 18:12:20 gshapiro Exp $
+.\"	$Sendmail: mailstats.8,v 8.17.4.6 2001/05/07 22:06:38 gshapiro Exp $
 .\"
-.Dd December 29, 2000
+.Dd May 7, 2001
 .Dt MAILSTATS 1
 .Os
 .Sh NAME
Index: gnu/usr.sbin/sendmail/mailstats/mailstats.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/mailstats/mailstats.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- gnu/usr.sbin/sendmail/mailstats/mailstats.c	2001/02/28 02:43:52	1.3
+++ gnu/usr.sbin/sendmail/mailstats/mailstats.c	2001/05/29 01:31:13	1.4
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  * Copyright (c) 1983 Eric P. Allman.  All rights reserved.
  * Copyright (c) 1988, 1993
@@ -14,14 +14,14 @@
 
 #ifndef lint
 static char copyright[] =
-"@(#) Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.\n\
+"@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\
 	All rights reserved.\n\
      Copyright (c) 1988, 1993\n\
 	The Regents of the University of California.  All rights reserved.\n";
 #endif /* ! lint */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: mailstats.c,v 8.53.16.12 2001/02/15 20:52:36 geir Exp $";
+static char id[] = "@(#)$Sendmail: mailstats.c,v 8.53.16.13 2001/05/07 22:06:38 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <unistd.h>
Index: gnu/usr.sbin/sendmail/praliases/praliases.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/praliases/praliases.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/praliases/praliases.c	2001/02/28 02:43:52	1.4
+++ gnu/usr.sbin/sendmail/praliases/praliases.c	2001/05/29 01:31:13	1.5
@@ -21,7 +21,7 @@
 #endif /* ! lint */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: praliases.c,v 8.59.4.18 2001/01/22 19:00:18 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: praliases.c,v 8.59.4.19 2001/02/28 02:37:57 ca Exp $";
 #endif /* ! lint */
 
 #include <sys/types.h>
@@ -357,12 +357,20 @@
 	}
 	else for (; *argv != NULL; ++argv)
 	{
+		int get_res;
+
 		memset(&db_key, '\0', sizeof db_key);
 		memset(&db_value, '\0', sizeof db_value);
 		db_key.data = *argv;
-		db_key.size = strlen(*argv) + 1;
-		if (database->smdb_get(database, &db_key,
-				       &db_value, 0) == SMDBE_OK)
+		db_key.size = strlen(*argv);
+		get_res = database->smdb_get(database, &db_key, &db_value, 0);
+		if (get_res == SMDBE_NOT_FOUND)
+		{
+			db_key.size++;
+			get_res = database->smdb_get(database, &db_key,
+						     &db_value, 0);
+		}
+		if (get_res == SMDBE_OK)
 		{
 			printf("%.*s:%.*s\n",
 			       (int) db_key.size,
Index: gnu/usr.sbin/sendmail/rmail/rmail.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/rmail/rmail.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/rmail/rmail.c	2001/02/28 02:43:52	1.4
+++ gnu/usr.sbin/sendmail/rmail/rmail.c	2001/05/29 01:31:13	1.5
@@ -12,14 +12,14 @@
 
 #ifndef lint
 static char copyright[] =
-"@(#) Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.\n\
+"@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\
 	All rights reserved.\n\
      Copyright (c) 1988, 1993\n\
 	The Regents of the University of California.  All rights reserved.\n";
 #endif /* ! lint */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: rmail.c,v 8.39.4.11 2001/02/14 04:07:25 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: rmail.c,v 8.39.4.12 2001/05/07 22:06:39 gshapiro Exp $";
 #endif /* ! lint */
 
 /*
Index: gnu/usr.sbin/sendmail/sendmail/Makefile
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/Makefile,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- gnu/usr.sbin/sendmail/sendmail/Makefile	2001/02/11 22:35:18	1.11
+++ gnu/usr.sbin/sendmail/sendmail/Makefile	2001/05/05 22:00:17	1.12
@@ -1,4 +1,4 @@
-#	$OpenBSD: Makefile,v 1.11 2001/02/11 22:35:18 millert Exp $
+#	$OpenBSD: Makefile,v 1.12 2001/05/05 22:00:17 millert Exp $
 
 PROG=	sendmail
 
@@ -12,6 +12,9 @@
 
 # Work around broken name servers that return SERV_FAIL for AAAA records
 ENVDEF+= -D_FFR_WORKAROUND_BROKEN_NAMESERVERS
+
+# Since we have random PIDs we need to be careful to avoid filename collisions
+ENVDEF+= -DFAST_PID_RECYCLE
 
 # To cause sendmail to drop privs in test mode (-bt) uncomment the following
 #ENVDEF+= -D_FFR_TESTMODE_DROP_PRIVS
Index: gnu/usr.sbin/sendmail/sendmail/README
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/README,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- gnu/usr.sbin/sendmail/sendmail/README	2001/02/28 02:43:53	1.5
+++ gnu/usr.sbin/sendmail/sendmail/README	2001/05/29 01:31:13	1.6
@@ -9,7 +9,7 @@
 # the sendmail distribution.
 #
 #
-#	$Sendmail: README,v 8.263.2.1.2.32 2001/01/29 23:45:22 gshapiro Exp $
+#	$Sendmail: README,v 8.263.2.1.2.35 2001/05/09 20:58:32 gshapiro Exp $
 #
 
 This directory contains the source files for sendmail(TM).
@@ -459,6 +459,9 @@
 		Set this if your system has an snprintf() implementation
 		which does not NUL terminate the string being filled in.
 		Use test/t_snprintf.c to test your system.
+NEEDSGETIPNODE	Set this if your system supports IPv6 but doesn't include
+		the getipnodeby{name,addr}() functions.  Set automatically
+		for Linux's glibc.
 
 +-----------------------+
 | COMPILE-TIME FEATURES |
@@ -1448,6 +1451,21 @@
 	problems.  You may want to turn this off if you have problems
 	running sendmail.  Reported by Jerry G. DeLapp <jgd@acl.lanl.gov>.
 
+Mac OS X (10.0.X)
+	From: Mike Zimmerman <zimmy@torrentnet.com>
+	From scratch here is what Darwin users need to do to the standard
+	10.0.0, 10.0.1 install to get sendmail working.
+	From http://www.macosx.com/forums/showthread.php?s=6dac0e9e1f3fd118a4870a8a9b559491&threadid=2242:
+	1. chmod g-w / /private /private/etc
+	2. Properly set HOSTNAME in /etc/hostconfig to your FQDN:
+	   HOSTNAME=-my.domain.com-
+	3. Edit /etc/rc.boot:
+	   hostname my.domain.com
+	   domainname domain.com
+	4. Edit /System/Library/StartupItems/Sendmail/Sendmail:
+	   Remove the "&" after the sendmail command:
+	   /usr/sbin/sendmail -bd -q1h
+
 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.
@@ -1688,4 +1706,4 @@
 version.c	The version number and information about this
 		version of sendmail.
 
-(Version $Revision: 1.5 $, last update $Date: 2001/02/28 02:43:53 $ )
+(Version $Revision: 1.6 $, last update $Date: 2001/05/29 01:31:13 $ )
Index: gnu/usr.sbin/sendmail/sendmail/TRACEFLAGS
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/TRACEFLAGS,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- gnu/usr.sbin/sendmail/sendmail/TRACEFLAGS	2001/01/15 21:09:06	1.2
+++ gnu/usr.sbin/sendmail/sendmail/TRACEFLAGS	2001/05/29 01:31:14	1.3
@@ -1,4 +1,4 @@
-#	$Sendmail: TRACEFLAGS,v 8.29 1999/11/04 23:31:02 gshapiro Exp $
+#	$Sendmail: TRACEFLAGS,v 8.29.16.1 2001/05/03 17:24:00 gshapiro Exp $
 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
@@ -75,6 +75,7 @@
 62	multiple	file descriptor checking
 63	queue.c		runqueue process watching
 64	multiple	Milter
+67	conf.c		signals
 80			content length
 81			sun remote mode
 91	mci.c		syslogging of MCI cache information
Index: gnu/usr.sbin/sendmail/sendmail/alias.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/alias.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- gnu/usr.sbin/sendmail/sendmail/alias.c	2001/01/15 21:09:06	1.3
+++ gnu/usr.sbin/sendmail/sendmail/alias.c	2001/05/29 01:31:14	1.4
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
  * Copyright (c) 1988, 1993
@@ -13,7 +13,7 @@
 #include <sendmail.h>
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: alias.c,v 8.142.4.9 2000/11/08 20:58:42 geir Exp $";
+static char id[] = "@(#)$Sendmail: alias.c,v 8.142.4.11 2001/05/03 17:24:01 gshapiro Exp $";
 #endif /* ! lint */
 
 # define SEPARATOR ':'
@@ -405,8 +405,9 @@
 				dprintf("aliaswait: sleeping for %u seconds\n",
 					sleeptime);
 
+			map->map_mflags |= MF_CLOSING;
 			map->map_class->map_close(map);
-			map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+			map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
 			(void) sleep(sleeptime);
 			sleeptime *= 2;
 			if (sleeptime > 60)
@@ -449,8 +450,9 @@
 			SuprErrs = TRUE;
 			if (isopen)
 			{
+				map->map_mflags |= MF_CLOSING;
 				map->map_class->map_close(map);
-				map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+				map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
 			}
 			(void) rebuildaliases(map, TRUE);
 			isopen = map->map_class->map_open(map, O_RDONLY);
@@ -595,8 +597,9 @@
 	/* add distinguished entries and close the database */
 	if (bitset(MF_OPEN, map->map_mflags))
 	{
+		map->map_mflags |= MF_CLOSING;
 		map->map_class->map_close(map);
-		map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+		map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
 	}
 
 	/* restore the old signals */
@@ -827,11 +830,11 @@
 		}
 
 		if (al.q_paddr != NULL)
-			free(al.q_paddr);
+			sm_free(al.q_paddr);
 		if (al.q_host != NULL)
-			free(al.q_host);
+			sm_free(al.q_host);
 		if (al.q_user != NULL)
-			free(al.q_user);
+			sm_free(al.q_user);
 	}
 
 	CurEnv->e_to = NULL;
Index: gnu/usr.sbin/sendmail/sendmail/arpadate.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/arpadate.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- gnu/usr.sbin/sendmail/sendmail/arpadate.c	2001/01/15 21:09:07	1.2
+++ gnu/usr.sbin/sendmail/sendmail/arpadate.c	2001/05/29 01:31:14	1.3
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998, 1999, 2001 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
  * Copyright (c) 1988, 1993
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: arpadate.c,v 8.23 1999/09/23 19:59:18 ca Exp $";
+static char id[] = "@(#)$Sendmail: arpadate.c,v 8.23.20.2 2001/05/07 22:07:26 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -117,11 +117,12 @@
 		*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).
-	 */
+	**  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);
 
Index: gnu/usr.sbin/sendmail/sendmail/bf_portable.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/bf_portable.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- gnu/usr.sbin/sendmail/sendmail/bf_portable.c	2001/02/28 02:43:53	1.3
+++ gnu/usr.sbin/sendmail/sendmail/bf_portable.c	2001/05/29 01:31:14	1.4
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: bf_portable.c,v 8.25.4.5 2001/02/14 04:07:27 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: bf_portable.c,v 8.25.4.6 2001/05/03 17:24:01 gshapiro Exp $";
 #endif /* ! lint */
 
 #if SFIO
@@ -28,9 +28,12 @@
 #if !SFIO
 # include <stdio.h>
 #endif /* !SFIO */
-#ifndef BF_STANDALONE
+#ifdef BF_STANDALONE
+# define sm_free free
+# define xalloc malloc
+#else /* BF_STANDALONE */
 # include "sendmail.h"
-#endif /* ! BF_STANDALONE */
+#endif /* BF_STANDALONE */
 #include "bf_portable.h"
 #include "bf.h"
 
@@ -95,7 +98,7 @@
 	}
 
 	/* Allocate memory */
-	bfp = (struct bf *)malloc(sizeof(struct bf));
+	bfp = (struct bf *)xalloc(sizeof(struct bf));
 	if (bfp == NULL)
 	{
 		(void) fclose(retval);
@@ -110,10 +113,10 @@
 			filename, (long) sizeof(struct bf));
 
 	l = strlen(filename) + 1;
-	bfp->bf_filename = (char *)malloc(l);
+	bfp->bf_filename = (char *)xalloc(l);
 	if (bfp->bf_filename == NULL)
 	{
-		free(bfp);
+		sm_free(bfp);
 		(void) fclose(retval);
 
 		/* don't care about errors */
@@ -224,7 +227,6 @@
 
 	/* check to see if there is an error on the stream */
 	err = ferror(fp);
-
 	(void) fflush(fp);
 
 	/*
@@ -379,8 +381,8 @@
 		if (!bfp->bf_committed)
 			retval = unlink(bfp->bf_filename);
 
-		free(bfp->bf_filename);
-		free(bfp);
+		sm_free(bfp->bf_filename);
+		sm_free(bfp);
 		if (tTd(58, 8))
 			dprintf("bfclose: freed %ld\n",
 				(long) sizeof(struct bf));
Index: gnu/usr.sbin/sendmail/sendmail/bf_torek.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/bf_torek.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- gnu/usr.sbin/sendmail/sendmail/bf_torek.c	2001/02/28 02:43:53	1.3
+++ gnu/usr.sbin/sendmail/sendmail/bf_torek.c	2001/05/29 01:31:14	1.4
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: bf_torek.c,v 8.19.18.4 2001/02/14 04:07:27 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: bf_torek.c,v 8.19.18.6 2001/05/08 06:52:19 gshapiro Exp $";
 #endif /* ! lint */
 
 #if SFIO
@@ -26,9 +26,12 @@
 #include <string.h>
 #include <errno.h>
 #include <stdio.h>
-#ifndef BF_STANDALONE
+#ifdef BF_STANDALONE
+# define sm_free free
+# define xalloc malloc
+#else /* BF_STANDALONE */
 # include "sendmail.h"
-#endif /* ! BF_STANDALONE */
+#endif /* BF_STANDALONE */
 #include "bf_torek.h"
 #include "bf.h"
 
@@ -90,7 +93,7 @@
 	}
 
 	/* Allocate memory */
-	bfp = (struct bf *)malloc(sizeof(struct bf));
+	bfp = (struct bf *)xalloc(sizeof(struct bf));
 	if (bfp == NULL)
 	{
 		errno = ENOMEM;
@@ -100,10 +103,10 @@
 	/* A zero bsize is valid, just don't allocate memory */
 	if (bsize > 0)
 	{
-		bfp->bf_buf = (char *)malloc(bsize);
+		bfp->bf_buf = (char *)xalloc(bsize);
 		if (bfp->bf_buf == NULL)
 		{
-			free(bfp);
+			sm_free(bfp);
 			errno = ENOMEM;
 			return NULL;
 		}
@@ -119,12 +122,12 @@
 	bfp->bf_bufsize = bsize;
 	bfp->bf_buffilled = 0;
 	l = strlen(filename) + 1;
-	bfp->bf_filename = (char *)malloc(l);
+	bfp->bf_filename = (char *)xalloc(l);
 	if (bfp->bf_filename == NULL)
 	{
-		free(bfp);
 		if (bfp->bf_buf != NULL)
-			free(bfp->bf_buf);
+			sm_free(bfp->bf_buf);
+		sm_free(bfp);
 		errno = ENOMEM;
 		return NULL;
 	}
@@ -142,10 +145,10 @@
 	{
 		/* Just in case free() sets errno */
 		save_errno = errno;
-		free(bfp);
-		free(bfp->bf_filename);
+		sm_free(bfp->bf_filename);
 		if (bfp->bf_buf != NULL)
-			free(bfp->bf_buf);
+			sm_free(bfp->bf_buf);
+		sm_free(bfp);
 		errno = save_errno;
 		return NULL;
 	}
@@ -285,7 +288,7 @@
 	{
 		/* Don't need buffer anymore; free it */
 		bfp->bf_bufsize = 0;
-		free(bfp->bf_buf);
+		sm_free(bfp->bf_buf);
 	}
 	return 0;
 }
@@ -317,7 +320,6 @@
 
 	/* check to see if there is an error on the stream */
 	err = ferror(fp);
-
 	(void) fflush(fp);
 
 	/*
@@ -530,10 +532,10 @@
 
 	/* Need to free the buffer */
 	if (bfp->bf_bufsize > 0)
-		free(bfp->bf_buf);
+		sm_free(bfp->bf_buf);
 
 	/* Finally, free the structure */
-	free(bfp);
+	sm_free(bfp);
 
 	return 0;
 }
Index: gnu/usr.sbin/sendmail/sendmail/clock.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/clock.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- gnu/usr.sbin/sendmail/sendmail/clock.c	2001/01/15 21:09:07	1.2
+++ gnu/usr.sbin/sendmail/sendmail/clock.c	2001/05/29 01:31:14	1.3
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
  * Copyright (c) 1988, 1993
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: clock.c,v 8.52.18.3 2000/09/17 17:04:26 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: clock.c,v 8.52.18.14 2001/05/17 18:12:28 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -21,6 +21,7 @@
 # define sigmask(s)	(1 << ((s) - 1))
 #endif /* ! sigmask */
 
+static SIGFUNC_DECL	tick __P((int));
 static void	endsleep __P((void));
 
 
@@ -42,7 +43,8 @@
 **		none.
 */
 
-EVENT	*FreeEventList;		/* list of free events */
+static EVENT	*volatile EventQueue;		/* head of event queue */
+static EVENT	*volatile FreeEventList;	/* list of free events */
 
 EVENT *
 setevent(intvl, func, arg)
@@ -50,10 +52,7 @@
 	void (*func)();
 	int arg;
 {
-	register EVENT **evp;
 	register EVENT *ev;
-	auto time_t now;
-	int wasblocked;
 
 	if (intvl <= 0)
 	{
@@ -61,34 +60,89 @@
 		return NULL;
 	}
 
+	ENTER_CRITICAL();
+	if (FreeEventList == NULL)
+	{
+		FreeEventList = (EVENT *) xalloc(sizeof *FreeEventList);
+		FreeEventList->ev_link = NULL;
+	}
+	LEAVE_CRITICAL();
+
+	ev = sigsafe_setevent(intvl, func, arg);
+
+	if (tTd(5, 5))
+		dprintf("setevent: intvl=%ld, for=%ld, func=%lx, arg=%d, ev=%lx\n",
+			(long) intvl, (long) (curtime() + intvl),
+			(u_long) func, arg,
+			ev == NULL ? 0 : (u_long) ev);
+
+	return ev;
+}
+
+/*
+**
+**	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+**		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+**		DOING.
+*/
+
+EVENT *
+sigsafe_setevent(intvl, func, arg)
+	time_t intvl;
+	void (*func)();
+	int arg;
+{
+	register EVENT **evp;
+	register EVENT *ev;
+	auto time_t now;
+	int wasblocked;
+
+	if (intvl <= 0)
+		return NULL;
+
 	wasblocked = blocksignal(SIGALRM);
 	now = curtime();
 
 	/* search event queue for correct position */
-	for (evp = &EventQueue; (ev = *evp) != NULL; evp = &ev->ev_link)
+	for (evp = (EVENT **) (&EventQueue);
+	     (ev = *evp) != NULL;
+	     evp = &ev->ev_link)
 	{
 		if (ev->ev_time >= now + intvl)
 			break;
 	}
 
-	/* insert new event */
-	ev = FreeEventList;
-	if (ev == NULL)
-		ev = (EVENT *) xalloc(sizeof *ev);
+	ENTER_CRITICAL();
+	if (FreeEventList == NULL)
+	{
+		/*
+		**  This shouldn't happen.  If called from setevent(),
+		**  we have just malloced a FreeEventList entry.  If
+		**  called from a signal handler, it should have been
+		**  from an existing event which tick() just added to the
+		**  FreeEventList.
+		*/
+
+		LEAVE_CRITICAL();
+		return NULL;
+	}
 	else
+	{
+		ev = FreeEventList;
 		FreeEventList = ev->ev_link;
+	}
+	LEAVE_CRITICAL();
+
+	/* insert new event */
 	ev->ev_time = now + intvl;
 	ev->ev_func = func;
 	ev->ev_arg = arg;
 	ev->ev_pid = getpid();
+	ENTER_CRITICAL();
 	ev->ev_link = *evp;
 	*evp = ev;
+	LEAVE_CRITICAL();
 
-	if (tTd(5, 5))
-		dprintf("setevent: intvl=%ld, for=%ld, func=%lx, arg=%d, ev=%lx\n",
-			(long) intvl, (long)(now + intvl), (u_long) func,
-			arg, (u_long) ev);
-
 	(void) setsignal(SIGALRM, tick);
 	intvl = EventQueue->ev_time - now;
 	(void) alarm((unsigned) intvl < 1 ? 1 : intvl);
@@ -123,7 +177,9 @@
 
 	/* find the parent event */
 	wasblocked = blocksignal(SIGALRM);
-	for (evp = &EventQueue; *evp != NULL; evp = &(*evp)->ev_link)
+	for (evp = (EVENT **) (&EventQueue);
+	     *evp != NULL;
+	     evp = &(*evp)->ev_link)
 	{
 		if (*evp == ev)
 			break;
@@ -132,9 +188,11 @@
 	/* now remove it */
 	if (*evp != NULL)
 	{
+		ENTER_CRITICAL();
 		*evp = ev->ev_link;
 		ev->ev_link = FreeEventList;
 		FreeEventList = ev;
+		LEAVE_CRITICAL();
 	}
 
 	/* restore clocks and pick up anything spare */
@@ -178,9 +236,11 @@
 	for (ev = EventQueue; ev->ev_link != NULL; ev = ev->ev_link)
 		continue;
 
+	ENTER_CRITICAL();
 	ev->ev_link = FreeEventList;
 	FreeEventList = EventQueue;
 	EventQueue = NULL;
+	LEAVE_CRITICAL();
 
 	/* restore clocks and pick up anything spare */
 	if (wasblocked == 0)
@@ -201,6 +261,10 @@
 **
 **	Side Effects:
 **		calls the next function in EventQueue.
+**
+**	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+**		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+**		DOING.
 */
 
 /* ARGSUSED */
@@ -210,27 +274,67 @@
 {
 	register time_t now;
 	register EVENT *ev;
-	int mypid = getpid();
+	pid_t mypid;
 	int save_errno = errno;
 
 	(void) alarm(0);
-	now = curtime();
 
+	FIX_SYSV_SIGNAL(sig, tick);
+
+	errno = save_errno;
+	CHECK_CRITICAL(sig);
+
+	mypid = getpid();
+	while (PendingSignal != 0)
+	{
+		int sigbit;
+		int sig;
+
+		if (bitset(PEND_SIGHUP, PendingSignal))
+		{
+			sigbit = PEND_SIGHUP;
+			sig = SIGHUP;
+		}
+		else if (bitset(PEND_SIGINT, PendingSignal))
+		{
+			sigbit = PEND_SIGINT;
+			sig = SIGINT;
+		}
+		else if (bitset(PEND_SIGTERM, PendingSignal))
+		{
+			sigbit = PEND_SIGTERM;
+			sig = SIGTERM;
+		}
+		else if (bitset(PEND_SIGUSR1, PendingSignal))
+		{
+			sigbit = PEND_SIGUSR1;
+			sig = SIGUSR1;
+		}
+		else
+		{
+			/* If we get here, we are in trouble */
+			abort();
+		}
+		PendingSignal &= ~sigbit;
+		kill(mypid, sig);
+	}
+
+	now = curtime();
 	if (tTd(5, 4))
 		dprintf("tick: now=%ld\n", (long) now);
 
-	/* reset signal in case System V semantics */
-	(void) setsignal(SIGALRM, tick);
 	while ((ev = EventQueue) != NULL &&
 	       (ev->ev_time <= now || ev->ev_pid != mypid))
 	{
 		void (*f)();
 		int arg;
-		int pid;
+		pid_t pid;
 
 		/* process the event on the top of the queue */
+		ENTER_CRITICAL();
 		ev = EventQueue;
 		EventQueue = EventQueue->ev_link;
+		LEAVE_CRITICAL();
 		if (tTd(5, 6))
 			dprintf("tick: ev=%lx, func=%lx, arg=%d, pid=%d\n",
 				(u_long) ev, (u_long) ev->ev_func,
@@ -240,9 +344,11 @@
 		f = ev->ev_func;
 		arg = ev->ev_arg;
 		pid = ev->ev_pid;
+		ENTER_CRITICAL();
 		ev->ev_link = FreeEventList;
 		FreeEventList = ev;
-		if (pid != getpid())
+		LEAVE_CRITICAL();
+		if (pid != mypid)
 			continue;
 		if (EventQueue != NULL)
 		{
@@ -264,6 +370,72 @@
 	return SIGFUNC_RETURN;
 }
 /*
+**  PEND_SIGNAL -- Add a signal to the pending signal list
+**
+**	Parameters:
+**		sig -- signal to add
+**
+**	Returns:
+**		none.
+**
+**	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+**		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+**		DOING.
+*/
+
+void
+pend_signal(sig)
+	int sig;
+{
+	int sigbit;
+	int save_errno = errno;
+
+	/*
+	**  Don't want to interrupt something critical, hence delay
+	**  the alarm for one second.  Hopefully, by then we
+	**  will be out of the critical section.  If not, then
+	**  we will just delay again.  The events to be run will
+	**  still all be run, maybe just a little bit late.
+	*/
+
+	switch (sig)
+	{
+	  case SIGHUP:
+		sigbit = PEND_SIGHUP;
+		break;
+
+	  case SIGINT:
+		sigbit = PEND_SIGINT;
+		break;
+
+	  case SIGTERM:
+		sigbit = PEND_SIGTERM;
+		break;
+
+	  case SIGUSR1:
+		sigbit = PEND_SIGUSR1;
+		break;
+
+	  case SIGALRM:
+		/* don't have to pend these */
+		sigbit = 0;
+		break;
+
+	  default:
+		/* If we get here, we are in trouble */
+		abort();
+
+		/* NOTREACHED */
+		break;
+	}
+
+	if (sigbit != 0)
+		PendingSignal |= sigbit;
+	(void) setsignal(SIGALRM, tick);
+	(void) alarm(1);
+	errno = save_errno;
+}
+/*
 **  SLEEP -- a version of sleep that works with this stuff
 **
 **	Because sleep uses the alarm facility, I must reimplement
@@ -281,7 +453,7 @@
 */
 
 
-static bool	SleepDone;
+static bool	volatile SleepDone;
 
 #ifndef SLEEP_T
 # define SLEEP_T	unsigned int
@@ -308,5 +480,11 @@
 static void
 endsleep()
 {
+	/*
+	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+	**	DOING.
+	*/
+
 	SleepDone = TRUE;
 }
Index: gnu/usr.sbin/sendmail/sendmail/collect.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/collect.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/sendmail/collect.c	2001/02/28 02:43:53	1.4
+++ gnu/usr.sbin/sendmail/sendmail/collect.c	2001/05/29 01:31:14	1.5
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: collect.c,v 8.136.4.15 2001/02/21 01:05:59 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: collect.c,v 8.136.4.21 2001/05/17 18:10:14 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -47,8 +47,8 @@
 */
 
 static jmp_buf	CtxCollectTimeout;
-static bool	CollectProgress;
-static EVENT	*CollectTimeout;
+static bool	volatile CollectProgress;
+static EVENT	*volatile CollectTimeout = NULL;
 
 /* values for input state machine */
 #define IS_NORM		0	/* middle of line */
@@ -212,10 +212,12 @@
 				if (TrafficLogFile != NULL && !headeronly)
 				{
 					if (istate == IS_BOL)
-						(void) fprintf(TrafficLogFile, "%05d <<< ",
-							(int) getpid());
+						(void) fprintf(TrafficLogFile,
+							       "%05d <<< ",
+							       (int) getpid());
 					if (c == EOF)
-						(void) fprintf(TrafficLogFile, "[EOF]\n");
+						(void) fprintf(TrafficLogFile,
+							       "[EOF]\n");
 					else
 						(void) putc(c, TrafficLogFile);
 				}
@@ -312,7 +314,6 @@
 				/* just put the character out */
 				if (!bitset(EF_TOOBIG, e->e_flags))
 					(void) putc(c, df);
-
 				/* FALLTHROUGH */
 
 			  case MS_DISCARD:
@@ -337,7 +338,7 @@
 				memmove(buf, obuf, bp - obuf);
 				bp = &buf[bp - obuf];
 				if (obuf != bufbuf)
-					free(obuf);
+					sm_free(obuf);
 			}
 			if (c >= 0200 && c <= 0237)
 			{
@@ -479,7 +480,8 @@
 	}
 
 	/* reset global timer */
-	clrevent(CollectTimeout);
+	if (CollectTimeout != NULL)
+		clrevent(CollectTimeout);
 
 	if (headeronly)
 		return;
@@ -721,15 +723,37 @@
 collecttimeout(timeout)
 	time_t timeout;
 {
-	/* if no progress was made, die now */
-	if (!CollectProgress)
+	int save_errno = errno;
+
+	/*
+	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+	**	DOING.
+	*/
+
+	if (CollectProgress)
+	{
+		/* reset the timeout */
+		CollectTimeout = sigsafe_setevent(timeout, collecttimeout,
+						  timeout);
+		CollectProgress = FALSE;
+	}
+	else
+	{
+		/* event is done */
+		CollectTimeout = NULL;
+	}
+
+	/* if no progress was made or problem resetting event, die now */
+	if (CollectTimeout == NULL)
+	{
+		errno = ETIMEDOUT;
 		longjmp(CtxCollectTimeout, 1);
+	}
 
-	/* otherwise reset the timeout */
-	CollectTimeout = setevent(timeout, collecttimeout, timeout);
-	CollectProgress = FALSE;
+	errno = save_errno;
 }
-/*
+/*
 **  DFERROR -- signal error on writing the data file.
 **
 **	Parameters:
Index: gnu/usr.sbin/sendmail/sendmail/conf.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/conf.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- gnu/usr.sbin/sendmail/sendmail/conf.c	2001/02/28 02:43:53	1.6
+++ gnu/usr.sbin/sendmail/sendmail/conf.c	2001/05/29 01:31:14	1.7
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: conf.c,v 8.646.2.2.2.69 2001/02/27 19:50:11 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: conf.c,v 8.646.2.2.2.86 2001/05/17 18:18:40 ca Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -976,7 +976,7 @@
 
 				st = stab(buf, ST_SERVICE, ST_ENTER);
 				if (st->s_service[0] != NULL)
-					free((void *) st->s_service[0]);
+					sm_free((void *) st->s_service[0]);
 				p = newstr(p);
 				for (svcno = 0; svcno < MAXMAPSTACK; )
 				{
@@ -1226,6 +1226,10 @@
 **  SETSIGNAL -- set a signal handler
 **
 **	This is essentially old BSD "signal(3)".
+**
+**	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+**		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+**		DOING.
 */
 
 sigfunc_t
@@ -1233,14 +1237,16 @@
 	int sig;
 	sigfunc_t handler;
 {
+# if defined(SA_RESTART) || (!defined(SYS5SIGNALS) && !defined(BSD4_3))
+	struct sigaction n, o;
+# endif /* defined(SA_RESTART) || (!defined(SYS5SIGNALS) && !defined(BSD4_3)) */
+
 	/*
 	**  First, try for modern signal calls
 	**  and restartable syscalls
 	*/
 
 # ifdef SA_RESTART
-	struct sigaction n, o;
-
 	memset(&n, '\0', sizeof n);
 #  if USE_SA_SIGACTION
 	n.sa_sigaction = (void(*)(int, siginfo_t *, void *)) handler;
@@ -1272,8 +1278,6 @@
 	**  go for a default
 	*/
 
-	struct sigaction n, o;
-
 	memset(&n, '\0', sizeof n);
 	n.sa_handler = handler;
 	if (sigaction(sig, &n, &o) < 0)
@@ -1283,6 +1287,73 @@
 # endif /* SA_RESTART */
 }
 /*
+**  ALLSIGNALS -- act on all signals
+**
+**	Parameters:
+**		block -- whether to block or release all signals.
+**
+**	Returns:
+**		none.
+*/
+
+void
+allsignals(block)
+	bool block;
+{
+# ifdef BSD4_3
+#  ifndef sigmask
+#   define sigmask(s)	(1 << ((s) - 1))
+#  endif /* ! sigmask */
+	if (block)
+	{
+		int mask = 0;
+
+		mask |= sigmask(SIGALRM);
+		mask |= sigmask(SIGCHLD);
+		mask |= sigmask(SIGHUP);
+		mask |= sigmask(SIGINT);
+		mask |= sigmask(SIGTERM);
+		mask |= sigmask(SIGUSR1);
+
+		(void) sigblock(mask);
+	}
+	else
+		sigsetmask(0);
+# else /* BSD4_3 */
+#  ifdef ALTOS_SYSTEM_V
+	if (block)
+	{
+		(void) sigset(SIGALRM, SIG_HOLD);
+		(void) sigset(SIGCHLD, SIG_HOLD);
+		(void) sigset(SIGHUP, SIG_HOLD);
+		(void) sigset(SIGINT, SIG_HOLD);
+		(void) sigset(SIGTERM, SIG_HOLD);
+		(void) sigset(SIGUSR1, SIG_HOLD);
+	}
+	else
+	{
+		(void) sigset(SIGALRM, SIG_DFL);
+		(void) sigset(SIGCHLD, SIG_DFL);
+		(void) sigset(SIGHUP, SIG_DFL);
+		(void) sigset(SIGINT, SIG_DFL);
+		(void) sigset(SIGTERM, SIG_DFL);
+		(void) sigset(SIGUSR1, SIG_DFL);
+	}
+#  else /* ALTOS_SYSTEM_V */
+	sigset_t sset;
+
+	(void) sigemptyset(&sset);
+	(void) sigaddset(&sset, SIGALRM);
+	(void) sigaddset(&sset, SIGCHLD);
+	(void) sigaddset(&sset, SIGHUP);
+	(void) sigaddset(&sset, SIGINT);
+	(void) sigaddset(&sset, SIGTERM);
+	(void) sigaddset(&sset, SIGUSR1);
+	(void) sigprocmask(block ? SIG_BLOCK : SIG_UNBLOCK, &sset, NULL);
+#  endif /* ALTOS_SYSTEM_V */
+# endif /* BSD4_3 */
+}
+/*
 **  BLOCKSIGNAL -- hold a signal to prevent delivery
 **
 **	Parameters:
@@ -2441,7 +2512,7 @@
 #  if SPT_TYPE == SPT_SCO
 	off_t seek_off;
 	static int kmem = -1;
-	static int kmempid = -1;
+	static pid_t kmempid = -1;
 	struct user u;
 #  endif /* SPT_TYPE == SPT_SCO */
 
@@ -2619,6 +2690,10 @@
 **	Side Effects:
 **		Picks up extant zombies.
 **		Control socket exits may restart/shutdown daemon.
+**
+**	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+**		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+**		DOING.
 */
 
 /* ARGSUSED0 */
@@ -2629,32 +2704,30 @@
 	int save_errno = errno;
 	int st;
 	pid_t pid;
-#if HASWAITPID
+# if HASWAITPID
 	auto int status;
 	int count;
+# else /* HASWAITPID */
+#  ifdef WNOHANG
+	union wait status;
+#  else /* WNOHANG */
+	auto int status;
+#  endif /* WNOHANG */
+# endif /* HASWAITPID */
 
+# if HASWAITPID
 	count = 0;
 	while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
 	{
 		st = status;
 		if (count++ > 1000)
-		{
-			if (LogLevel > 0)
-				sm_syslog(LOG_ALERT, NOQID,
-					"reapchild: waitpid loop: pid=%d, status=%x",
-					pid, status);
 			break;
-		}
-#else /* HASWAITPID */
-# ifdef WNOHANG
-	union wait status;
-
+# else /* HASWAITPID */
+#  ifdef WNOHANG
 	while ((pid = wait3(&status, WNOHANG, (struct rusage *) NULL)) > 0)
 	{
 		st = status.w_status;
-# else /* WNOHANG */
-	auto int status;
-
+#  else /* WNOHANG */
 	/*
 	**  Catch one zombie -- we will be re-invoked (we hope) if there
 	**  are more.  Unreliable signals probably break this, but this
@@ -2665,8 +2738,8 @@
 	if ((pid = wait(&status)) > 0)
 	{
 		st = status;
-# endif /* WNOHANG */
-#endif /* HASWAITPID */
+#  endif /* WNOHANG */
+# endif /* HASWAITPID */
 		/* Drop PID and check if it was a control socket child */
 		if (proc_list_drop(pid) == PROC_CONTROL &&
 		    WIFEXITED(st))
@@ -2674,21 +2747,17 @@
 			/* if so, see if we need to restart or shutdown */
 			if (WEXITSTATUS(st) == EX_RESTART)
 			{
-				/* emulate a SIGHUP restart */
-				sighup(0);
-				/* NOTREACHED */
+				RestartRequest = "control socket";
 			}
 			else if (WEXITSTATUS(st) == EX_SHUTDOWN)
 			{
 				/* emulate a SIGTERM shutdown */
-				intsig(0);
+				ShutdownRequest = "control socket";
 				/* NOTREACHED */
 			}
 		}
 	}
-#ifdef SYS5SIGNALS
-	(void) setsignal(SIGCHLD, reapchild);
-#endif /* SYS5SIGNALS */
+	FIX_SYSV_SIGNAL(sig, reapchild);
 	errno = save_errno;
 	return SIGFUNC_RETURN;
 }
@@ -2753,18 +2822,14 @@
 	 */
 	if (first)
 	{
-		newenv = (char **) malloc(sizeof(char *) * (envlen + 2));
-		if (newenv == NULL)
-			return -1;
-
+		newenv = (char **) xalloc(sizeof(char *) * (envlen + 2));
 		first = FALSE;
 		(void) memcpy(newenv, environ, sizeof(char *) * envlen);
 	}
 	else
 	{
-		newenv = (char **) realloc((char *)environ, sizeof(char *) * (envlen + 2));
-		if (newenv == NULL)
-			return -1;
+		newenv = (char **) xrealloc((char *)environ,
+					    sizeof(char *) * (envlen + 2));
 	}
 
 	/* actually add in the new entry */
@@ -4327,7 +4392,7 @@
 **	Support IPv6 as well as IPv4.
 */
 
-#if NETINET6 && NEEDSGETIPNODE && __RES < 19990909
+#if NETINET6 && NEEDSGETIPNODE
 
 # ifndef AI_DEFAULT
 #  define AI_DEFAULT	0	/* dummy */
@@ -4394,7 +4459,7 @@
 	return;
 }
 # endif /* _FFR_FREEHOSTENT */
-#endif /* NEEDSGETIPNODE && NETINET6 && __RES < 19990909 */
+#endif /* NEEDSGETIPNODE && NETINET6 */
 
 struct hostent *
 sm_gethostbyname(name, family)
@@ -4582,8 +4647,8 @@
 # else /* NETINET6 */
 	hp = gethostbyaddr(addr, len, type);
 # endif /* NETINET6 */
-	return hp;
 #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */
+	return hp;
 }
 /*
 **  SM_GETPW{NAM,UID} -- wrapper for getpwnam and getpwuid
@@ -4869,7 +4934,7 @@
 		if (tTd(0, 4))
 			dprintf("SIOCGLIFCONF failed: %s\n", errstring(errno));
 		(void) close(s);
-		free(lifc.lifc_buf);
+		sm_free(lifc.lifc_buf);
 		return;
 	}
 
@@ -4903,7 +4968,7 @@
 		s = socket(af, SOCK_DGRAM, 0);
 		if (s == -1)
 		{
-			free(lifc.lifc_buf);
+			sm_free(lifc.lifc_buf);
 			return;
 		}
 
@@ -5018,7 +5083,7 @@
 #   endif /* SIOCGLIFFLAGS */
 		(void) add_hostnames(sa);
 	}
-	free(lifc.lifc_buf);
+	sm_free(lifc.lifc_buf);
 	(void) close(s);
 #else /* NETINET6 && defined(SIOCGLIFCONF) */
 # if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN
@@ -5058,7 +5123,7 @@
 		if (tTd(0, 4))
 			dprintf("SIOCGIFCONF failed: %s\n", errstring(errno));
 		(void) close(s);
-		free(ifc.ifc_buf);
+		sm_free(ifc.ifc_buf);
 		return;
 	}
 
@@ -5201,7 +5266,7 @@
 
 		(void) add_hostnames(sa);
 	}
-	free(ifc.ifc_buf);
+	sm_free(ifc.ifc_buf);
 	(void) close(s);
 #  undef IFRFREF
 # endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */
@@ -5375,7 +5440,7 @@
 		/* String too small, redo with correct size */
 		bufsize += SnprfOverflow + 1;
 		if (buf != buf0)
-			free(buf);
+			sm_free(buf);
 		buf = xalloc(bufsize * sizeof (char));
 	}
 	if ((strlen(buf) + idlen + 1) < SYSLOG_BUFSIZE)
@@ -5532,6 +5597,9 @@
 
 char	*CompileOptions[] =
 {
+#if EGD
+	"EGD",
+#endif /* EGD */
 #ifdef HESIOD
 	"HESIOD",
 #endif /* HESIOD */
Index: gnu/usr.sbin/sendmail/sendmail/conf.h
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/conf.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- gnu/usr.sbin/sendmail/sendmail/conf.h	2001/02/28 02:43:53	1.8
+++ gnu/usr.sbin/sendmail/sendmail/conf.h	2001/05/29 01:31:14	1.9
@@ -10,7 +10,7 @@
  * the sendmail distribution.
  *
  *
- *	$Sendmail: conf.h,v 8.496.4.37 2001/02/12 21:40:16 gshapiro Exp $
+ *	$Sendmail: conf.h,v 8.496.4.43 2001/05/20 22:29:59 gshapiro Exp $
  */
 
 /*
@@ -84,7 +84,7 @@
 #define MAXMIMEARGS	20		/* max args in Content-Type: */
 #define MAXMIMENESTING	20		/* max MIME multipart nesting */
 #define QUEUESEGSIZE	1000		/* increment for queue size */
-#define MAXQFNAME	20		/* max qf file name length */
+#define MAXQFNAME	21		/* max qf file name length */
 #define MACBUFSIZE	4096		/* max expanded macro buffer size */
 #define TOBUFSIZE	SM_ARG_MAX	/* max buffer to hold address list */
 #define MAXSHORTSTR	203		/* max short string length */
@@ -551,6 +551,9 @@
 #   undef _PATH_SENDMAILPID	/* tmpfs /var/run added in 2.8 */
 #   define _PATH_SENDMAILPID	"/var/run/sendmail.pid"
 #  endif /* SOLARIS >= 20800 || (SOLARIS < 10000 && SOLARIS >= 208) */
+#  if SOLARIS >= 20900 || (SOLARIS < 10000 && SOLARIS >= 209)
+#   define HASURANDOMDEV	1	/* /dev/[u]random added in S9 */
+#  endif /* SOLARIS >= 20900 || (SOLARIS < 10000 && SOLARIS >= 209) */
 #  ifndef HASGETUSERSHELL
 #   define HASGETUSERSHELL 0	/* getusershell(3) causes core dumps pre-2.7 */
 #  endif /* ! HASGETUSERSHELL */
@@ -1002,6 +1005,7 @@
 #  undef SPT_TYPE
 #  define SPT_TYPE	SPT_BUILTIN	/* setproctitle is in libc */
 #  define HASSETLOGIN	1	/* has setlogin(2) */
+#  define HASSETREUID	0	/* OpenBSD has broken setreuid(2) emulation */
 #  define HASURANDOMDEV	1	/* has /dev/urandom(4) */
 #  if OpenBSD < 199912
 #   define HASSTRL	0	/* strlcat(3) is broken in 2.5 and earlier */
@@ -1468,10 +1472,10 @@
 #   else /* (GLIBC_VERSION >= 0x201) */
 #    include <linux/in6.h>	/* IPv6 support */
 #   endif /* (GLIBC_VERSION >= 0x201) */
-#   if (GLIBC_VERSION == 0x201 && !defined(NEEDSGETIPNODE))
+#   if (GLIBC_VERSION >= 0x201 && !defined(NEEDSGETIPNODE))
      /* Have APIs in <netdb.h>, but no support in glibc */
 #    define NEEDSGETIPNODE	1
-#   endif /* (GLIBC_VERSION == 0x201 && ! NEEDSGETIPNODE) */
+#   endif /* (GLIBC_VERSION >= 0x201 && !defined(NEEDSGETIPNODE)) */
 #   undef GLIBC_VERSION
 #  endif /* defined(__GLIBC__) && defined(__GLIBC_MINOR__) */
 # endif /* NETINET6 */
@@ -2243,7 +2247,9 @@
 /* general BSD defines */
 #ifdef BSD
 # define HASGETDTABLESIZE 1	/* has getdtablesize(2) call */
-# define HASSETREUID	1	/* has setreuid(2) call */
+# ifndef HASSETREUID
+#  define HASSETREUID	1	/* has setreuid(2) call */
+# endif /* ! HASSETREUID */
 # define HASINITGROUPS	1	/* has initgroups(3) call */
 # ifndef IP_SRCROUTE
 #  define IP_SRCROUTE	1	/* can check IP source routing */
Index: gnu/usr.sbin/sendmail/sendmail/control.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/control.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- gnu/usr.sbin/sendmail/sendmail/control.c	2001/02/28 02:43:53	1.3
+++ gnu/usr.sbin/sendmail/sendmail/control.c	2001/05/29 01:31:14	1.4
@@ -9,12 +9,34 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: control.c,v 8.44.14.15 2001/01/22 19:00:22 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: control.c,v 8.44.14.20 2001/05/03 17:24:03 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
 
+/* values for cmd_code */
+# define CMDERROR	0	/* bad command */
+# define CMDRESTART	1	/* restart daemon */
+# define CMDSHUTDOWN	2	/* end daemon */
+# define CMDHELP	3	/* help */
+# define CMDSTATUS	4	/* daemon status */
+
+struct cmd
+{
+	char	*cmd_name;	/* command name */
+	int	cmd_code;	/* internal code, see below */
+};
 
+static struct cmd	CmdTab[] =
+{
+	{ "help",	CMDHELP		},
+	{ "restart",	CMDRESTART	},
+	{ "shutdown",	CMDSHUTDOWN	},
+	{ "status",	CMDSTATUS	},
+	{ NULL,		CMDERROR	}
+};
+
+
 int ControlSocket = -1;
 
 /*
@@ -208,34 +230,19 @@
 **		none.
 */
 
-struct cmd
-{
-	char	*cmd_name;	/* command name */
-	int	cmd_code;	/* internal code, see below */
-};
-
-/* values for cmd_code */
-# define CMDERROR	0	/* bad command */
-# define CMDRESTART	1	/* restart daemon */
-# define CMDSHUTDOWN	2	/* end daemon */
-# define CMDHELP	3	/* help */
-# define CMDSTATUS	4	/* daemon status */
-
-static struct cmd	CmdTab[] =
-{
-	{ "help",	CMDHELP		},
-	{ "restart",	CMDRESTART	},
-	{ "shutdown",	CMDSHUTDOWN	},
-	{ "status",	CMDSTATUS	},
-	{ NULL,		CMDERROR	}
-};
-
 static jmp_buf	CtxControlTimeout;
 
 static void
 controltimeout(timeout)
 	time_t timeout;
 {
+	/*
+	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+	**	DOING.
+	*/
+
+	errno = ETIMEDOUT;
 	longjmp(CtxControlTimeout, 1);
 }
 
Index: gnu/usr.sbin/sendmail/sendmail/daemon.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/daemon.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- gnu/usr.sbin/sendmail/sendmail/daemon.c	2001/02/28 02:43:53	1.6
+++ gnu/usr.sbin/sendmail/sendmail/daemon.c	2001/05/29 01:31:14	1.7
@@ -16,9 +16,9 @@
 
 #ifndef lint
 # ifdef DAEMON
-static char id[] = "@(#)$Sendmail: daemon.c,v 8.401.4.51 2001/02/23 18:57:27 geir Exp $ (with daemon mode)";
+static char id[] = "@(#)$Sendmail: daemon.c,v 8.401.4.61 2001/05/27 22:14:40 gshapiro Exp $ (with daemon mode)";
 # else /* DAEMON */
-static char id[] = "@(#)$Sendmail: daemon.c,v 8.401.4.51 2001/02/23 18:57:27 geir Exp $ (without daemon mode)";
+static char id[] = "@(#)$Sendmail: daemon.c,v 8.401.4.61 2001/05/27 22:14:40 gshapiro Exp $ (without daemon mode)";
 # endif /* DAEMON */
 #endif /* ! lint */
 
@@ -87,6 +87,8 @@
 static void	connecttimeout __P((void));
 static int	opendaemonsocket __P((struct daemon *, bool));
 static u_short	setupdaemon __P((SOCKADDR *));
+static SIGFUNC_DECL	sighup __P((int));
+static void	restart_daemon __P((void));
 
 /*
 **  DAEMON.C -- routines to use when running as a daemon.
@@ -194,7 +196,11 @@
 			  ControlSocketName, errstring(errno));
 
 	(void) setsignal(SIGCHLD, reapchild);
+	(void) setsignal(SIGHUP, sighup);
 
+	/* workaround: can't seem to release the signal in the parent */
+	(void) releasesignal(SIGHUP);
+
 	/* write the pid to file */
 	log_sendmail_pid(e);
 
@@ -235,6 +241,11 @@
 		/* see if we are rejecting connections */
 		(void) blocksignal(SIGALRM);
 
+		if (ShutdownRequest != NULL)
+			shutdown_daemon();
+		else if (RestartRequest != NULL)
+			restart_daemon();
+
 		timenow = curtime();
 
 		/*
@@ -298,6 +309,12 @@
 			}
 		}
 
+		/* May have been sleeping above, check again */
+		if (ShutdownRequest != NULL)
+			shutdown_daemon();
+		else if (RestartRequest != NULL)
+			restart_daemon();
+
 		if (timenow >= last_disk_space_check)
 		{
 			bool logged = FALSE;
@@ -391,6 +408,11 @@
 			fd_set readfds;
 			struct timeval timeout;
 
+			if (ShutdownRequest != NULL)
+				shutdown_daemon();
+			else if (RestartRequest != NULL)
+				restart_daemon();
+
 			FD_ZERO(&readfds);
 
 			for (idx = 0; idx < ndaemons; idx++)
@@ -421,26 +443,20 @@
 			}
 # endif /* NETUNIX */
 
-			/*
-			**  if one socket is closed, set the timeout
-			**  to 5 seconds (so it might get reopened soon),
-			**  otherwise (all sockets open) 60.
-			*/
-
-			idx = 0;
-			while (idx < ndaemons && Daemons[idx].d_socket >= 0)
-				idx++;
-			if (idx < ndaemons)
-				timeout.tv_sec = 5;
-			else
-				timeout.tv_sec = 60;
+			timeout.tv_sec = 5;
 			timeout.tv_usec = 0;
 
 			t = select(highest + 1, FDSET_CAST &readfds,
 				   NULL, NULL, &timeout);
 
+			/* Did someone signal while waiting? */
+			if (ShutdownRequest != NULL)
+				shutdown_daemon();
+			else if (RestartRequest != NULL)
+				restart_daemon();
 
 
+
 			if (DoQueueRun)
 				(void) runqueue(TRUE, FALSE);
 
@@ -677,6 +693,18 @@
 			**	Verify calling user id if possible here.
 			*/
 
+			/* Reset global flags */
+			RestartRequest = NULL;
+			ShutdownRequest = NULL;
+			PendingSignal = 0;
+
+			(void) releasesignal(SIGALRM);
+			(void) releasesignal(SIGCHLD);
+			(void) setsignal(SIGCHLD, SIG_DFL);
+			(void) setsignal(SIGHUP, SIG_DFL);
+			(void) setsignal(SIGTERM, intsig);
+
+
 			if (!control)
 			{
 				define(macid("{daemon_addr}", NULL),
@@ -688,10 +716,6 @@
 				       newstr(status), &BlankEnvelope);
 			}
 
-			(void) releasesignal(SIGALRM);
-			(void) releasesignal(SIGCHLD);
-			(void) setsignal(SIGCHLD, SIG_DFL);
-			(void) setsignal(SIGHUP, intsig);
 			for (idx = 0; idx < ndaemons; idx++)
 			{
 				if (Daemons[idx].d_socket >= 0)
@@ -1719,7 +1743,7 @@
 	{
 		STRUCTCOPY(ClientAddr, clt_addr);
 		if (clt_addr.sa.sa_family == AF_UNSPEC)
-			clt_addr.sa.sa_family = InetMode;
+			clt_addr.sa.sa_family = family;
 		switch (clt_addr.sa.sa_family)
 		{
 # if NETINET
@@ -2008,8 +2032,9 @@
 	for (;;)
 	{
 		if (tTd(16, 1))
-			dprintf("makeconnection (%s [%s])\n",
-				host, anynet_ntoa(&addr));
+			dprintf("makeconnection (%s [%s].%d (%d))\n",
+				host, anynet_ntoa(&addr), ntohs(port),
+				addr.sa.sa_family);
 
 		/* save for logging */
 		CurHostAddr = addr;
@@ -2022,7 +2047,7 @@
 		}
 		else
 		{
-			s = socket(addr.sa.sa_family, SOCK_STREAM, 0);
+			s = socket(clt_addr.sa.sa_family, SOCK_STREAM, 0);
 		}
 		if (s < 0)
 		{
@@ -2128,9 +2153,11 @@
 			int i;
 
 			if (e->e_ntries <= 0 && TimeOuts.to_iconnect != 0)
-				ev = setevent(TimeOuts.to_iconnect, connecttimeout, 0);
+				ev = setevent(TimeOuts.to_iconnect,
+					      connecttimeout, 0);
 			else if (TimeOuts.to_connect != 0)
-				ev = setevent(TimeOuts.to_connect, connecttimeout, 0);
+				ev = setevent(TimeOuts.to_connect,
+					      connecttimeout, 0);
 			else
 				ev = NULL;
 
@@ -2316,6 +2343,12 @@
 static void
 connecttimeout()
 {
+	/*
+	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+	**	DOING.
+	*/
+
 	errno = ETIMEDOUT;
 	longjmp(CtxConnectTimeout, 1);
 }
@@ -2416,6 +2449,124 @@
 }
 # endif /* NETUNIX */
 /*
+**  SIGHUP -- handle a SIGHUP signal
+**
+**	Parameters:
+**		sig -- incoming signal.
+**
+**	Returns:
+**		none.
+**
+**	Side Effects:
+**		Sets RestartRequest which should cause the daemon
+**		to restart.
+**
+**	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+**		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+**		DOING.
+*/
+
+/* ARGSUSED */
+static SIGFUNC_DECL
+sighup(sig)
+	int sig;
+{
+	int save_errno = errno;
+
+	FIX_SYSV_SIGNAL(sig, sighup);
+	RestartRequest = "signal";
+	errno = save_errno;
+	return SIGFUNC_RETURN;
+}
+/*
+**  RESTART_DAEMON -- Performs a clean restart of the daemon
+**
+**	Parameters:
+**		none.
+**
+**	Returns:
+**		none.
+**
+**	Side Effects:
+**		restarts the daemon or exits if restart fails.
+*/
+
+static void
+restart_daemon()
+{
+	int i;
+	int save_errno;
+	char *reason;
+	sigfunc_t oalrm, ochld, ohup, oint, opipe, oterm, ousr1;
+	extern int DtableSize;
+
+	allsignals(TRUE);
+
+	reason = RestartRequest;
+	RestartRequest = NULL;
+	PendingSignal = 0;
+
+	if (SaveArgv[0][0] != '/')
+	{
+		if (LogLevel > 3)
+			sm_syslog(LOG_INFO, NOQID,
+				  "could not restart: need full path");
+		finis(FALSE, EX_OSFILE);
+	}
+	if (LogLevel > 3)
+		sm_syslog(LOG_INFO, NOQID, "restarting %s due to %s",
+			  SaveArgv[0],
+			  reason == NULL ? "implicit call" : reason);
+
+	closecontrolsocket(TRUE);
+	if (drop_privileges(TRUE) != EX_OK)
+	{
+		if (LogLevel > 0)
+			sm_syslog(LOG_ALERT, NOQID,
+				  "could not set[ug]id(%d, %d): %m",
+				  RunAsUid, RunAsGid);
+		finis(FALSE, EX_OSERR);
+	}
+
+	/* 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 | FD_CLOEXEC);
+	}
+
+	/* need to allow signals before execve() so make them harmless */
+	oalrm = setsignal(SIGALRM, SIG_DFL);
+	ochld = setsignal(SIGCHLD, SIG_DFL);
+	ohup = setsignal(SIGHUP, SIG_DFL);
+	oint = setsignal(SIGINT, SIG_DFL);
+	opipe = setsignal(SIGPIPE, SIG_DFL);
+	oterm = setsignal(SIGTERM, SIG_DFL);
+	ousr1 = setsignal(SIGUSR1, SIG_DFL);
+	allsignals(FALSE);
+
+	(void) execve(SaveArgv[0], (ARGV_T) SaveArgv, (ARGV_T) ExternalEnviron);
+	save_errno = errno;
+
+	/* restore signals */
+	allsignals(TRUE);
+	(void) setsignal(SIGALRM, oalrm);
+	(void) setsignal(SIGCHLD, ochld);
+	(void) setsignal(SIGHUP, ohup);
+	(void) setsignal(SIGINT, oint);
+	(void) setsignal(SIGPIPE, opipe);
+	(void) setsignal(SIGTERM, oterm);
+	(void) setsignal(SIGUSR1, ousr1);
+
+	errno = save_errno;
+	if (LogLevel > 0)
+		sm_syslog(LOG_ALERT, NOQID, "could not exec %s: %m",
+			  SaveArgv[0]);
+	finis(FALSE, EX_OSFILE);
+}
+/*
 **  MYHOSTNAME -- return the name of this host.
 **
 **	Parameters:
@@ -2578,6 +2729,13 @@
 static void
 authtimeout()
 {
+	/*
+	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+	**	DOING.
+	*/
+
+	errno = ETIMEDOUT;
 	longjmp(CtxAuthTimeout, 1);
 }
 
Index: gnu/usr.sbin/sendmail/sendmail/deliver.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/deliver.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/sendmail/deliver.c	2001/02/28 02:43:54	1.4
+++ gnu/usr.sbin/sendmail/sendmail/deliver.c	2001/05/29 01:31:14	1.5
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: deliver.c,v 8.600.2.1.2.66 2001/02/25 23:30:35 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: deliver.c,v 8.600.2.1.2.81 2001/05/23 02:15:42 ca Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -135,22 +135,31 @@
 
 	if (e->e_hopcount > MaxHopCount)
 	{
+		char *recip;
+
+		if (e->e_sendqueue != NULL &&
+		    e->e_sendqueue->q_paddr != NULL)
+			recip = e->e_sendqueue->q_paddr;
+		else
+			recip = "(nobody)";
+
 		errno = 0;
 #if QUEUE
 		queueup(e, mode == SM_QUEUE || mode == SM_DEFER);
 #endif /* QUEUE */
 		e->e_flags |= EF_FATALERRS|EF_PM_NOTIFY|EF_CLRQUEUE;
 		ExitStat = EX_UNAVAILABLE;
-		syserr("554 5.0.0 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);
+		syserr("554 5.4.6 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,
+		       recip);
 		for (q = e->e_sendqueue; q != NULL; q = q->q_next)
 		{
 			if (QS_IS_DEAD(q->q_state))
 				continue;
 			q->q_state = QS_BADADDR;
 			q->q_status = "5.4.6";
+			q->q_rstatus = "554 5.4.6 Too many hops";
 		}
 		return;
 	}
@@ -635,6 +644,11 @@
 			return;
 		}
 
+		/* Reset global flags */
+		RestartRequest = NULL;
+		ShutdownRequest = NULL;
+		PendingSignal = 0;
+
 		/*
 		**  Since we have accepted responsbility for the message,
 		**  change the SIGTERM handler.  intsig() (the old handler)
@@ -931,7 +945,7 @@
 **		returns twice, once in parent and once in child.
 */
 
-int
+pid_t
 dofork()
 {
 	register pid_t pid = -1;
@@ -1451,7 +1465,7 @@
 		if (l > tobufsize)
 		{
 			if (tobuf != NULL)
-				free(tobuf);
+				sm_free(tobuf);
 			tobufsize = l;
 			tobuf = xalloc(tobufsize);
 		}
@@ -1719,10 +1733,10 @@
 						m->m_name);
 				i = makeconnection(hostbuf, port, mci, e);
 			}
+			mci->mci_errno = errno;
 			mci->mci_lastuse = curtime();
 			mci->mci_deliveries = 0;
 			mci->mci_exitstat = i;
-			mci->mci_errno = errno;
 # if NAMED_BIND
 			mci->mci_herrno = h_errno;
 # endif /* NAMED_BIND */
@@ -1913,6 +1927,11 @@
 			struct stat stb;
 			extern int DtableSize;
 
+			/* Reset global flags */
+			RestartRequest = NULL;
+			ShutdownRequest = NULL;
+			PendingSignal = 0;
+
 			if (e->e_lockfp != NULL)
 				(void) close(fileno(e->e_lockfp));
 
@@ -2511,7 +2530,9 @@
 						  mci->mci_host,
 						  macvalue(macid("{auth_type}",
 								 NULL), e),
-						  *ssf);
+						  result == SASL_OK ? *ssf
+						  		    : 0);
+
 				/*
 				**  only switch to encrypted connection
 				**  if a security layer has been negotiated
@@ -3041,6 +3062,12 @@
 static void
 endwaittimeout()
 {
+	/*
+	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+	**	DOING.
+	*/
+
 	errno = ETIMEDOUT;
 	longjmp(EndWaitTimeout, 1);
 }
@@ -3059,6 +3086,19 @@
 
 	mci_unlock_host(mci);
 
+	/* close output to mailer */
+	if (mci->mci_out != NULL)
+		(void) fclose(mci->mci_out);
+
+	/* copy any remaining input to transcript */
+	if (mci->mci_in != NULL && mci->mci_state != MCIS_ERROR &&
+	    e->e_xfp != NULL)
+	{
+		while (sfgets(buf, sizeof buf, mci->mci_in,
+		       TimeOuts.to_quit, "Draining Input") != NULL)
+			(void) fputs(buf, e->e_xfp);
+	}
+
 #if SASL
 	/* shutdown SASL */
 	if (bitset(MCIF_AUTHACT, mci->mci_flags))
@@ -3073,19 +3113,6 @@
 	(void) endtlsclt(mci);
 #endif /* STARTTLS */
 
-	/* close output to mailer */
-	if (mci->mci_out != NULL)
-		(void) fclose(mci->mci_out);
-
-	/* copy any remaining input to transcript */
-	if (mci->mci_in != NULL && mci->mci_state != MCIS_ERROR &&
-	    e->e_xfp != NULL)
-	{
-		while (sfgets(buf, sizeof buf, mci->mci_in,
-		       TimeOuts.to_quit, "Draining Input") != NULL)
-			(void) fputs(buf, e->e_xfp);
-	}
-
 	/* now close the input */
 	if (mci->mci_in != NULL)
 		(void) fclose(mci->mci_in);
@@ -3375,7 +3402,7 @@
 	if (status != EX_OK && (status != EX_TEMPFAIL || e->e_message == NULL))
 	{
 		if (e->e_message != NULL)
-			free(e->e_message);
+			sm_free(e->e_message);
 		e->e_message = newstr(statmsg + off);
 	}
 	errno = 0;
@@ -3947,7 +3974,7 @@
 							    TrafficLogFile);
 					if (c == '\n')
 						(void) fputs(mci->mci_mailer->m_eol,
-						      TrafficLogFile);
+							     TrafficLogFile);
 				}
 				if (padc != EOF)
 				{
@@ -4375,6 +4402,11 @@
 		int err;
 		volatile int oflags = O_WRONLY|O_APPEND;
 
+		/* Reset global flags */
+		RestartRequest = NULL;
+		ShutdownRequest = NULL;
+		PendingSignal = 0;
+
 		if (e->e_lockfp != NULL)
 			(void) close(fileno(e->e_lockfp));
 
@@ -4391,7 +4423,8 @@
 		}
 
 		if (TimeOuts.to_fileopen > 0)
-			ev = setevent(TimeOuts.to_fileopen, mailfiletimeout, 0);
+			ev = setevent(TimeOuts.to_fileopen,
+				      mailfiletimeout, 0);
 		else
 			ev = NULL;
 
@@ -4705,7 +4738,7 @@
 		(*e->e_puthdr)(&mcibuf, e->e_header, e, M87F_OUTER);
 		(*e->e_putbody)(&mcibuf, e, NULL);
 		putline("\n", &mcibuf);
-		if (fflush(f) < 0 ||
+		if (fflush(f) != 0 ||
 		    (SuperSafe && fsync(fileno(f)) < 0) ||
 		    ferror(f))
 		{
@@ -4755,6 +4788,13 @@
 static void
 mailfiletimeout()
 {
+	/*
+	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+	**	DOING.
+	*/
+
+	errno = ETIMEDOUT;
 	longjmp(CtxMailfileTimeout, 1);
 }
 /*
@@ -4802,17 +4842,19 @@
 		dprintf("hostsignature(%s)\n", host);
 
 	/*
-	**  If local delivery, just return a constant.
+	**  If local delivery (and not remote), just return a constant.
 	*/
 
-	if (bitnset(M_LOCALMAILER, m->m_flags))
+	p = m->m_mailer;
+	if (bitnset(M_LOCALMAILER, m->m_flags) &&
+	    strcmp(p, "[IPC]") != 0 &&
+	    strcmp(p, "[TCP]") != 0)
 		return "localhost";
 
 	/*
 	**  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)
 	{
@@ -4920,7 +4962,7 @@
 		if (s->s_hostsig != NULL)
 		{
 			(void) strlcpy(p, s->s_hostsig, len);
-			free(s->s_hostsig);
+			sm_free(s->s_hostsig);
 			s->s_hostsig = p;
 			hl = strlen(p);
 			p += hl;
Index: gnu/usr.sbin/sendmail/sendmail/envelope.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/envelope.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- gnu/usr.sbin/sendmail/sendmail/envelope.c	2001/01/15 21:09:08	1.3
+++ gnu/usr.sbin/sendmail/sendmail/envelope.c	2001/05/29 01:31:15	1.4
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
  * Copyright (c) 1988, 1993
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: envelope.c,v 8.180.14.6 2000/11/30 00:39:46 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: envelope.c,v 8.180.14.10 2001/05/03 17:24:06 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -132,7 +132,7 @@
 	*/
 
 	now = curtime();
-	if (now > e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass])
+	if (now >= e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass])
 		message_timeout = TRUE;
 
 	if (TimeOuts.to_q_return[e->e_timeoutclass] == NOW &&
@@ -150,7 +150,7 @@
 
 		/* see if a notification is needed */
 		if (bitset(QPINGONFAILURE, q->q_flags) &&
-		    ((message_timeout && QS_IS_QUEUEUP(q->q_state)) ||
+		    ((message_timeout && QS_IS_UNDELIVERED(q->q_state)) ||
 		     QS_IS_BADADDR(q->q_state) ||
 		     (TimeOuts.to_q_return[e->e_timeoutclass] == NOW &&
 		      !bitset(EF_RESPONSE, e->e_flags))))
@@ -192,7 +192,7 @@
 					"Cannot send message for %s",
 					pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
 			if (e->e_message != NULL)
-				free(e->e_message);
+				sm_free(e->e_message);
 			e->e_message = newstr(buf);
 			message(buf);
 			e->e_flags |= EF_CLRQUEUE;
@@ -210,7 +210,7 @@
 		}
 	}
 	else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 &&
-		 now > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass])
+		 now >= e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass])
 	{
 		if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) &&
 		    e->e_class >= 0 &&
@@ -222,7 +222,7 @@
 		{
 			for (q = e->e_sendqueue; q != NULL; q = q->q_next)
 			{
-				if (QS_IS_QUEUEUP(q->q_state) &&
+				if (QS_IS_UNDELIVERED(q->q_state) &&
 #if _FFR_NODELAYDSN_ON_HOLD
 				    !bitnset(M_HOLD, q->q_mailer->m_flags) &&
 #endif /* _FFR_NODELAYDSN_ON_HOLD */
@@ -239,7 +239,7 @@
 				"Warning: could not send message for past %s",
 				pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE));
 			if (e->e_message != NULL)
-				free(e->e_message);
+				sm_free(e->e_message);
 			e->e_message = newstr(buf);
 			message(buf);
 			e->e_flags |= EF_WARNING;
Index: gnu/usr.sbin/sendmail/sendmail/err.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/err.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- gnu/usr.sbin/sendmail/sendmail/err.c	2001/01/15 21:09:08	1.2
+++ gnu/usr.sbin/sendmail/sendmail/err.c	2001/05/29 01:31:15	1.3
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
  * Copyright (c) 1988, 1993
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: err.c,v 8.120.4.1 2000/05/25 18:56:15 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: err.c,v 8.120.4.2 2001/05/03 17:24:06 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -107,7 +107,7 @@
 	if (!panic && CurEnv != NULL)
 	{
 		if (CurEnv->e_message != NULL)
-			free(CurEnv->e_message);
+			sm_free(CurEnv->e_message);
 		CurEnv->e_message = newstr(errtxt);
 	}
 
@@ -122,13 +122,13 @@
 			dprintf("syserr: ExitStat = %d\n", ExitStat);
 	}
 
-	pw = sm_getpwuid(getuid());
+	pw = sm_getpwuid(RealUid);
 	if (pw != NULL)
 		user = pw->pw_name;
 	else
 	{
 		user = ubuf;
-		snprintf(ubuf, sizeof ubuf, "UID%d", (int) getuid());
+		snprintf(ubuf, sizeof ubuf, "UID%d", (int) RealUid);
 	}
 
 	if (LogLevel > 0)
@@ -237,7 +237,7 @@
 	  case '5':
 	  case '6':
 		if (CurEnv->e_message != NULL)
-			free(CurEnv->e_message);
+			sm_free(CurEnv->e_message);
 		if (MsgBuf[0] == '6')
 		{
 			char buf[MAXLINE];
@@ -323,7 +323,7 @@
 	  case '5':
 	  case '6':
 		if (CurEnv->e_message != NULL)
-			free(CurEnv->e_message);
+			sm_free(CurEnv->e_message);
 		if (MsgBuf[0] == '6')
 		{
 			char buf[MAXLINE];
@@ -392,7 +392,7 @@
 
 	  case '5':
 		if (CurEnv->e_message != NULL)
-			free(CurEnv->e_message);
+			sm_free(CurEnv->e_message);
 		CurEnv->e_message = newstr(errtxt);
 		break;
 	}
@@ -446,7 +446,7 @@
 
 	  case '5':
 		if (CurEnv->e_message != NULL)
-			free(CurEnv->e_message);
+			sm_free(CurEnv->e_message);
 		CurEnv->e_message = newstr(errtxt);
 		break;
 	}
Index: gnu/usr.sbin/sendmail/sendmail/headers.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/headers.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/sendmail/headers.c	2001/02/28 02:43:54	1.4
+++ gnu/usr.sbin/sendmail/sendmail/headers.c	2001/05/29 01:31:15	1.5
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: headers.c,v 8.203.4.12 2001/01/22 19:00:22 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: headers.c,v 8.203.4.13 2001/05/03 17:24:06 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -341,7 +341,7 @@
 			}
 			if ((sp = macvalue(macid("{currHeader}", NULL), e)) !=
 			    NULL)
-				free(sp);
+				sm_free(sp);
 			define(macid("{currHeader}", NULL), newstr(qval), e);
 			define(macid("{hdr_name}", NULL), newstr(fname), e);
 			(void) rscheck(rs, fvalue, NULL, e, stripcom, TRUE, 4,
Index: gnu/usr.sbin/sendmail/sendmail/main.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/main.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- gnu/usr.sbin/sendmail/sendmail/main.c	2001/02/28 02:43:54	1.5
+++ gnu/usr.sbin/sendmail/sendmail/main.c	2001/05/29 01:31:15	1.6
@@ -21,7 +21,7 @@
 #endif /* ! lint */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: main.c,v 8.485.4.44 2001/02/08 14:06:55 ca Exp $";
+static char id[] = "@(#)$Sendmail: main.c,v 8.485.4.60 2001/05/27 22:00:26 gshapiro Exp $";
 #endif /* ! lint */
 
 #define	_DEFINE
@@ -33,6 +33,10 @@
 # include <arpa/inet.h>
 #endif /* NETINET || NETINET6 */
 
+static SIGFUNC_DECL	intindebug __P((int));
+static SIGFUNC_DECL	quiesce __P((int));
+static SIGFUNC_DECL	sigusr1 __P((int));
+static SIGFUNC_DECL	term_daemon __P((int));
 static void	dump_class __P((STAB *, int));
 static void	obsolete __P((char **));
 static void	testmodeline __P((char *, ENVELOPE *));
@@ -76,7 +80,6 @@
 		{ "", "", NULL, "" };
 char		*CommandLineArgs;	/* command line args for pid file */
 bool		Warn_Q_option = FALSE;	/* warn about Q option use */
-char		**SaveArgv;	/* argument vector for re-execing */
 static int	MissingFds = 0;	/* bit map of fds missing on startup */
 
 #ifdef NGROUPS_MAX
@@ -161,6 +164,14 @@
 	/* avoid null pointer dereferences */
 	TermEscape.te_rv_on = TermEscape.te_rv_off = "";
 
+	/*
+	**  Seed the random number generator.
+	**  Used for queue file names, picking a queue directory, and
+	**  MX randomization.
+	*/
+
+	seed_random();
+
 	/* do machine-dependent initializations */
 	init_md(argc, argv);
 
@@ -218,14 +229,6 @@
 	checkfd012("after openlog");
 #endif /* XDEBUG */
 
-	/*
-	**  Seed the random number generator.
-	**  Used for queue file names, picking a queue directory, and
-	**  MX randomization.
-	*/
-
-	seed_random();
-
 	tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
 
 #ifdef NGROUPS_MAX
@@ -242,8 +245,13 @@
 	setstat(dp);
 
 # ifdef SIGUSR1
-	/* arrange to dump state on user-1 signal */
-	(void) setsignal(SIGUSR1, sigusr1);
+	/* Only allow root (or non-set-*-ID binaries) to use SIGUSR1 */
+	if (getuid() == 0 ||
+	    (getuid() == geteuid() && getgid() == getegid()))
+	{
+		/* arrange to dump state on user-1 signal */
+		(void) setsignal(SIGUSR1, sigusr1);
+	}
 # endif /* SIGUSR1 */
 
 	/* initialize for setproctitle */
@@ -300,17 +308,23 @@
 	}
 	opterr = 1;
 
+#if LOG
 	if (sysloglabel != NULL)
 	{
-#if LOG
+		/* Sanitize the string */
+		for (p = sysloglabel; *p != '\0'; p++)
+		{
+			if (!isascii(*p) || !isprint(*p) || *p == '%')
+				*p = '*';
+		}
 		closelog();
 #  ifdef LOG_MAIL
 		openlog(sysloglabel, LOG_PID, LOG_MAIL);
 #  else /* LOG_MAIL */
 		openlog(sysloglabel, LOG_PID);
 #  endif /* LOG_MAIL */
-#endif /* LOG */
 	}
+#endif /* LOG */
 
 	/* set up the blank envelope */
 	BlankEnvelope.e_puthdr = putheader;
@@ -349,6 +363,7 @@
 	**  if running non-setuid binary as non-root, pretend
 	**  we are the RunAsUid
 	*/
+
 	if (RealUid != 0 && geteuid() == RealUid)
 	{
 		if (tTd(47, 1))
@@ -471,11 +486,8 @@
 
 	/* prime the child environment */
 	setuserenv("AGENT", "sendmail");
-
-	if (setsignal(SIGINT, SIG_IGN) != SIG_IGN)
-		(void) setsignal(SIGINT, intsig);
-	(void) setsignal(SIGTERM, intsig);
 	(void) setsignal(SIGPIPE, SIG_IGN);
+
 	OldUmask = umask(022);
 	OpMode = MD_DELIVER;
 	FullName = getextenv("NAME");
@@ -1025,6 +1037,59 @@
 	ConfigFileRead = TRUE;
 	vendor_post_defaults(CurEnv);
 
+	/* Remove the ability for a normal user to send signals */
+	if (RealUid != 0 &&
+	    RealUid != geteuid())
+	{
+		uid_t new_uid = geteuid();
+
+#if HASSETREUID
+		/*
+		**  Since we can differentiate between uid and euid,
+		**  make the uid a different user so the real user
+		**  can't send signals.  However, it doesn't need to be
+		**  root (euid has root).
+		*/
+
+		if (new_uid == 0)
+			new_uid = DefUid;
+		if (tTd(47, 5))
+			dprintf("Changing real uid to %d\n", (int) new_uid);
+		if (setreuid(new_uid, geteuid()) < 0)
+		{
+			syserr("main: setreuid(%d, %d) failed",
+			       (int) new_uid, (int) geteuid());
+			finis(FALSE, EX_OSERR);
+			/* NOTREACHED */
+		}
+		if (tTd(47, 10))
+			dprintf("Now running as e/ruid %d:%d\n",
+				(int) geteuid(), (int) getuid());
+#else /* HASSETREUID */
+		/*
+		**  Have to change both effective and real so need to
+		**  change them both to effective to keep privs.
+		*/
+
+		if (tTd(47, 5))
+			dprintf("Changing uid to %d\n", (int) new_uid);
+		if (setuid(new_uid) < 0)
+		{
+			syserr("main: setuid(%d) failed", (int) new_uid);
+			finis(FALSE, EX_OSERR);
+			/* NOTREACHED */
+		}
+		if (tTd(47, 10))
+			dprintf("Now running as e/ruid %d:%d\n",
+				(int) geteuid(), (int) getuid());
+#endif /* HASSETREUID */
+	}
+
+	/* set up the basic signal handlers */
+	if (setsignal(SIGINT, SIG_IGN) != SIG_IGN)
+		(void) setsignal(SIGINT, intsig);
+	(void) setsignal(SIGTERM, intsig);
+
 	/* Enforce use of local time (null string overrides this) */
 	if (TimeZoneSpec == NULL)
 		unsetenv("TZ");
@@ -1184,6 +1249,7 @@
 	  case MD_VERIFY:
 		CurEnv->e_errormode = EM_PRINT;
 		HoldErrs = FALSE;
+
 		/* arrange to exit cleanly on hangup signal */
 		if (setsignal(SIGHUP, SIG_IGN) == (sigfunc_t) SIG_DFL)
 			(void) setsignal(SIGHUP, intsig);
@@ -1205,10 +1271,7 @@
 		if (SaveArgv[0] == NULL || SaveArgv[0][0] != '/')
 			sm_syslog(LOG_WARNING, NOQID,
 				  "daemon invoked without full pathname; kill -1 won't work");
-		(void) setsignal(SIGHUP, sighup);
-
-		/* workaround: can't seem to release the signal in the parent */
-		(void) releasesignal(SIGHUP);
+		(void) setsignal(SIGTERM, term_daemon);
 		break;
 
 	  case MD_INITALIAS:
@@ -1247,7 +1310,7 @@
 
 			FullName = addquotes(FullName);
 			if (full != NULL)
-				free(full);
+				sm_free(full);
 		}
 	}
 
@@ -1589,20 +1652,7 @@
 
 #if SMTP
 # if STARTTLS
-	/*
-	**  basic TLS initialization
-	**  ignore result for now
-	*/
-	SSL_library_init();
-	SSL_load_error_strings();
-#  if 0
-	/* this is currently a macro for SSL_library_init */
-	SSLeay_add_ssl_algorithms();
-#  endif /* 0 */
-
-	/* initialize PRNG */
-	tls_ok = tls_rand_init(RandFile, 7);
-
+	tls_ok = init_tls_library();
 # endif /* STARTTLS */
 #endif /* SMTP */
 
@@ -1698,10 +1748,13 @@
 			{
 				/* write the pid to file */
 				log_sendmail_pid(CurEnv);
+				(void) setsignal(SIGTERM, term_daemon);
 				for (;;)
 				{
 					(void) pause();
-					if (DoQueueRun)
+					if (ShutdownRequest != NULL)
+						shutdown_daemon();
+					else if (DoQueueRun)
 						(void) runqueue(TRUE, FALSE);
 				}
 			}
@@ -1996,21 +2049,89 @@
 	/* NOTREACHED */
 	return ExitStat;
 }
+/*
+**  QUIESCE -- signal handler for SIGPIPE
+**
+**	Parameters:
+**		sig -- incoming signal.
+**
+**	Returns:
+**		none.
+**
+**	Side Effects:
+**		Sets StopRequest which should cause the mailq/hoststatus
+**		display to stop.
+**
+**	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+**		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+**		DOING.
+*/
 
 /* ARGSUSED */
-SIGFUNC_DECL
+static SIGFUNC_DECL
 quiesce(sig)
 	int sig;
 {
-	clear_events();
-	finis(FALSE, EX_OK);
+	int save_errno = errno;
+
+	FIX_SYSV_SIGNAL(sig, quiesce);
+	StopRequest = TRUE;
+	errno = save_errno;
+	return SIGFUNC_RETURN;
 }
+/*
+**  STOP_SENDMAIL -- Stop the running program
+**
+**	Parameters:
+**		none.
+**
+**	Returns:
+**		none.
+**
+**	Side Effects:
+**		exits.
+*/
 
+void
+stop_sendmail()
+{
+	/* reset uid for process accounting */
+	endpwent();
+	(void) setuid(RealUid);
+	exit(EX_OK);
+}
+
+/*
+**  INTINDEBUG -- signal handler for SIGINT in -bt mode
+**
+**	Parameters:
+**		sig -- incoming signal.
+**
+**	Returns:
+**		none.
+**
+**	Side Effects:
+**		longjmps back to test mode loop.
+**
+**	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+**		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+**		DOING.
+**
+**	XXX: More work is needed for this signal handler.
+*/
+
 /* ARGSUSED */
-SIGFUNC_DECL
+static SIGFUNC_DECL
 intindebug(sig)
 	int sig;
 {
+	int save_errno = errno;
+
+	FIX_SYSV_SIGNAL(sig, intindebug);
+	errno = save_errno;
+	CHECK_CRITICAL(sig);
+
+	errno = save_errno;
 	longjmp(TopFrame, 1);
 	return SIGFUNC_RETURN;
 }
@@ -2033,6 +2154,9 @@
 	bool drop;
 	volatile int exitstat;
 {
+	/* Still want to process new timeouts added below */
+	clear_events();
+	releasesignal(SIGALRM);
 
 	if (tTd(2, 1))
 	{
@@ -2082,7 +2206,7 @@
 	if (LogLevel > 78)
 		sm_syslog(LOG_DEBUG, CurEnv->e_id,
 			  "finis, pid=%d",
-			  getpid());
+			  (int) getpid());
 	if (exitstat == EX_TEMPFAIL || CurEnv->e_errormode == EM_BERKNET)
 		exitstat = EX_OK;
 
@@ -2094,6 +2218,71 @@
 	exit(exitstat);
 }
 /*
+**  TERM_DEAMON -- SIGTERM handler for the daemon
+**
+**	Parameters:
+**		sig -- signal number.
+**
+**	Returns:
+**		none.
+**
+**	Side Effects:
+**		Sets ShutdownRequest which will hopefully trigger
+**		the daemon to exit.
+**
+**	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+**		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+**		DOING.
+*/
+
+/* ARGSUSED */
+static SIGFUNC_DECL
+term_daemon(sig)
+	int sig;
+{
+	int save_errno = errno;
+
+	FIX_SYSV_SIGNAL(sig, term_daemon);
+	ShutdownRequest = "signal";
+	errno = save_errno;
+	return SIGFUNC_RETURN;
+}
+/*
+**  SHUTDOWN_DAEMON -- Performs a clean shutdown of the daemon
+**
+**	Parameters:
+**		none.
+**
+**	Returns:
+**		none.
+**
+**	Side Effects:
+**		closes control socket, exits.
+*/
+
+void
+shutdown_daemon()
+{
+	char *reason;
+
+	allsignals(TRUE);
+
+	reason = ShutdownRequest;
+	ShutdownRequest = NULL;
+	PendingSignal = 0;
+
+	if (LogLevel > 79)
+		sm_syslog(LOG_DEBUG, CurEnv->e_id, "interrupt");
+
+	FileName = NULL;
+	closecontrolsocket(TRUE);
+#ifdef XLA
+	xla_all_end();
+#endif /* XLA */
+
+	finis(FALSE, EX_OK);
+}
+/*
 **  INTSIG -- clean up on interrupt
 **
 **	This just arranges to exit.  It pessimizes in that it
@@ -2107,6 +2296,12 @@
 **
 **	Side Effects:
 **		Unlocks the current job.
+**
+**	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+**		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+**		DOING.
+**
+**		XXX: More work is needed for this signal handler.
 */
 
 /* ARGSUSED */
@@ -2115,15 +2310,15 @@
 	int sig;
 {
 	bool drop = FALSE;
+	int save_errno = errno;
 
-	clear_events();
+	FIX_SYSV_SIGNAL(sig, intsig);
+	errno = save_errno;
+	CHECK_CRITICAL(sig);
+	allsignals(TRUE);
 	if (sig != 0 && LogLevel > 79)
 		sm_syslog(LOG_DEBUG, CurEnv->e_id, "interrupt");
 	FileName = NULL;
-	closecontrolsocket(TRUE);
-#ifdef XLA
-	xla_all_end();
-#endif /* XLA */
 
 	/* Clean-up on aborted stdin message submission */
 	if (CurEnv->e_id != NULL &&
@@ -2324,7 +2519,7 @@
 	if (LogLevel > 71)
 		sm_syslog(LOG_DEBUG, e->e_id,
 			  "in background, pid=%d",
-			  getpid());
+			  (int) getpid());
 
 	errno = 0;
 }
@@ -2563,68 +2758,35 @@
 	}
 	sm_syslog(LOG_DEBUG, CurEnv->e_id, "--- end of state dump ---");
 }
-
+/*
+**  SIGUSR1 -- Signal a request to dump state.
+**
+**	Parameters:
+**		sig -- calling signal.
+**
+**	Returns:
+**		none.
+**
+**	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+**		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+**		DOING.
+**
+**		XXX: More work is needed for this signal handler.
+*/
 
 /* ARGSUSED */
-SIGFUNC_DECL
+static SIGFUNC_DECL
 sigusr1(sig)
 	int sig;
 {
+	int save_errno = errno;
+
+	FIX_SYSV_SIGNAL(sig, sigusr1);
+	errno = save_errno;
+	CHECK_CRITICAL(sig);
 	dumpstate("user signal");
+	errno = save_errno;
 	return SIGFUNC_RETURN;
-}
-
-
-/* ARGSUSED */
-SIGFUNC_DECL
-sighup(sig)
-	int sig;
-{
-	int i;
-	extern int DtableSize;
-
-	clear_events();
-	(void) alarm(0);
-	if (SaveArgv[0][0] != '/')
-	{
-		if (LogLevel > 3)
-			sm_syslog(LOG_INFO, NOQID,
-				  "could not restart: need full path");
-		finis(FALSE, EX_OSFILE);
-	}
-	if (LogLevel > 3)
-		sm_syslog(LOG_INFO, NOQID, "restarting %s %s",
-			  sig == 0 ? "due to control command" : "on signal",
-			  SaveArgv[0]);
-
-	/* Control socket restart? */
-	if (sig != 0)
-		(void) releasesignal(SIGHUP);
-
-	closecontrolsocket(TRUE);
-	if (drop_privileges(TRUE) != EX_OK)
-	{
-		if (LogLevel > 0)
-			sm_syslog(LOG_ALERT, NOQID,
-				  "could not set[ug]id(%d, %d): %m",
-				  RunAsUid, RunAsGid);
-		finis(FALSE, EX_OSERR);
-	}
-
-	/* 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 | FD_CLOEXEC);
-	}
-
-	(void) execve(SaveArgv[0], (ARGV_T) SaveArgv, (ARGV_T) ExternalEnviron);
-	if (LogLevel > 0)
-		sm_syslog(LOG_ALERT, NOQID, "could not exec %s: %m",
-			  SaveArgv[0]);
-	finis(FALSE, EX_OSFILE);
 }
 /*
 **  DROP_PRIVILEGES -- reduce privileges to those of the RunAsUser option
Index: gnu/usr.sbin/sendmail/sendmail/map.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/map.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/sendmail/map.c	2001/02/28 02:43:54	1.4
+++ gnu/usr.sbin/sendmail/sendmail/map.c	2001/05/29 01:31:15	1.5
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: map.c,v 8.414.4.39 2001/02/22 18:56:22 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: map.c,v 8.414.4.53 2001/05/04 01:29:00 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -370,7 +370,7 @@
 		/* need to malloc additional space */
 		buflen = len;
 		if (buf != NULL)
-			free(buf);
+			sm_free(buf);
 		buf = xalloc(buflen);
 	}
 
@@ -492,8 +492,9 @@
 	/* if already open, close it (for nested open) */
 	if (bitset(MF_OPEN, map->map_mflags))
 	{
+		map->map_mflags |= MF_CLOSING;
 		map->map_class->map_close(map);
-		map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+		map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
 	}
 
 	(void) rebuildaliases(map, FALSE);
@@ -627,6 +628,7 @@
 
 	if (!bitset(MF_VALID, map->map_mflags) ||
 	    !bitset(MF_OPEN, map->map_mflags) ||
+	    bitset(MF_CLOSING, map->map_mflags) ||
 	    map->map_pid != getpid())
 		return;
 
@@ -635,8 +637,9 @@
 			map->map_mname == NULL ? "NULL" : map->map_mname,
 			map->map_file == NULL ? "NULL" : map->map_file);
 
+	map->map_mflags |= MF_CLOSING;
 	map->map_class->map_close(map);
-	map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+	map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
 }
 /*
 **  GETCANONNAME -- look up name using service switch
@@ -1079,7 +1082,7 @@
 	**  map_mtime to be set
 	*/
 
-	if (fstat(dfd, &st) >= 0)
+	if (fstat(pfd, &st) >= 0)
 		map->map_mtime = st.st_mtime;
 
 	if (mode == O_RDONLY)
@@ -1130,7 +1133,7 @@
 	int *statp;
 {
 	datum key, val;
-	int fd;
+	int dfd, pfd;
 	char keybuf[MAXNAME + 1];
 	struct stat stbuf;
 
@@ -1150,19 +1153,22 @@
 		key.dptr = keybuf;
 	}
 lockdbm:
-	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);
-	if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
+	dfd = dbm_dirfno((DBM *) map->map_db1);
+	if (dfd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
+		(void) lockfile(dfd, map->map_file, ".dir", LOCK_SH);
+	pfd = dbm_pagfno((DBM *) map->map_db1);
+	if (pfd < 0 || fstat(pfd, &stbuf) < 0 ||
+	    stbuf.st_mtime > map->map_mtime)
 	{
 		/* Reopen the database to sync the cache */
 		int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
 								 : O_RDONLY;
 
-		if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
-			(void) lockfile(fd, map->map_file, ".dir", LOCK_UN);
+		if (dfd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
+			(void) lockfile(dfd, map->map_file, ".dir", LOCK_UN);
+		map->map_mflags |= MF_CLOSING;
 		map->map_class->map_close(map);
-		map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+		map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
 		if (map->map_class->map_open(map, omode))
 		{
 			map->map_mflags |= MF_OPEN;
@@ -1201,8 +1207,8 @@
 		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 (dfd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
+		(void) lockfile(dfd, map->map_file, ".dir", LOCK_UN);
 	if (val.dptr == NULL)
 		return NULL;
 	if (bitset(MF_MATCHONLY, map->map_mflags))
@@ -1272,7 +1278,7 @@
 				if (data.dsize + old.dsize + 2 > bufsiz)
 				{
 					if (buf != NULL)
-						(void) free(buf);
+						sm_free(buf);
 					bufsiz = data.dsize + old.dsize + 2;
 					buf = xalloc(bufsiz);
 				}
@@ -1803,8 +1809,9 @@
 
 		if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
 			(void) lockfile(fd, buf, ".db", LOCK_UN);
+		map->map_mflags |= MF_CLOSING;
 		map->map_class->map_close(map);
-		map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+		map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
 		if (map->map_class->map_open(map, omode))
 		{
 			map->map_mflags |= MF_OPEN;
@@ -1983,7 +1990,7 @@
 				if (data.size + old.size + 2 > (size_t)bufsiz)
 				{
 					if (buf != NULL)
-						(void) free(buf);
+						sm_free(buf);
 					bufsiz = data.size + old.size + 2;
 					buf = xalloc(bufsiz);
 				}
@@ -2141,7 +2148,7 @@
 		dprintf("nis_map_open: yp_match(@, %s, %s) => %s\n",
 			map->map_domain, map->map_file, yperr_string(yperr));
 	if (vp != NULL)
-		free(vp);
+		sm_free(vp);
 
 	if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY)
 	{
@@ -2211,7 +2218,7 @@
 	{
 		if (vp != NULL)
 		{
-			free(vp);
+			sm_free(vp);
 			vp = NULL;
 		}
 		buflen++;
@@ -2225,7 +2232,7 @@
 		if (yperr != YPERR_KEY && yperr != YPERR_BUSY)
 			map->map_mflags &= ~(MF_VALID|MF_OPEN);
 		if (vp != NULL)
-			free(vp);
+			sm_free(vp);
 		return NULL;
 	}
 	if (bitset(MF_MATCHONLY, map->map_mflags))
@@ -2236,7 +2243,7 @@
 
 		ret = map_rewrite(map, vp, vsize, av);
 		if (vp != NULL)
-			free(vp);
+			sm_free(vp);
 		return ret;
 	}
 }
@@ -2290,7 +2297,7 @@
 	{
 		if (vp != NULL)
 		{
-			free(vp);
+			sm_free(vp);
 			vp = NULL;
 		}
 		keylen++;
@@ -2308,11 +2315,11 @@
 		else
 			*statp = EX_UNAVAILABLE;
 		if (vp != NULL)
-			free(vp);
+			sm_free(vp);
 		return FALSE;
 	}
 	(void) strlcpy(host_record, vp, sizeof host_record);
-	free(vp);
+	sm_free(vp);
 	if (tTd(38, 44))
 		dprintf("got record `%s'\n", host_record);
 	if (!extract_canonname(nbuf, NULL, host_record, cbuf, sizeof cbuf))
@@ -2850,10 +2857,15 @@
 	lmap = (LDAPMAP_STRUCT *) map->map_db1;
 
 	s = ldapmap_findconn(lmap);
-	if (s->s_ldap != NULL)
+	if (s->s_lmap != NULL)
 	{
 		/* Already have a connection open to this LDAP server */
-		lmap->ldap_ld = s->s_ldap;
+		lmap->ldap_ld = ((LDAPMAP_STRUCT *)s->s_lmap->map_db1)->ldap_ld;
+
+		/* Add this map as head of linked list */
+		lmap->ldap_next = s->s_lmap;
+		s->s_lmap = map;
+
 		if (tTd(38, 2))
 			dprintf("using cached connection\n");
 		return TRUE;
@@ -2867,7 +2879,7 @@
 		return FALSE;
 
 	/* Save connection for reuse */
-	s->s_ldap = lmap->ldap_ld;
+	s->s_lmap = map;
 	return TRUE;
 }
 
@@ -3036,6 +3048,13 @@
 ldaptimeout(sig_no)
 	int sig_no;
 {
+	/*
+	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+	**	DOING.
+	*/
+
+	errno = ETIMEDOUT;
 	longjmp(LDAPTimeout, 1);
 }
 
@@ -3059,20 +3078,25 @@
 	if (lmap->ldap_ld == NULL)
 		return;
 
+	/* Close the LDAP connection */
+	ldap_unbind(lmap->ldap_ld);
+
+	/* Mark all the maps that share the connection as closed */
 	s = ldapmap_findconn(lmap);
 
-	/* Check if already closed */
-	if (s->s_ldap == NULL)
-		return;
+	while (s->s_lmap != NULL)
+	{
+		MAP *smap = s->s_lmap;
 
-	/* If same as saved connection, stored connection is going away */
-	if (s->s_ldap == lmap->ldap_ld)
-		s->s_ldap = NULL;
+		if (tTd(38, 2) && smap != map)
+			dprintf("ldapmap_close(%s): closed %s (shared LDAP connection)\n",
+				map->map_mname, smap->map_mname);
 
-	if (lmap->ldap_ld != NULL)
-	{
-		ldap_unbind(lmap->ldap_ld);
+		smap->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+		lmap = (LDAPMAP_STRUCT *) smap->map_db1;
 		lmap->ldap_ld = NULL;
+		s->s_lmap = lmap->ldap_next;
+		lmap->ldap_next = NULL;
 	}
 }
 
@@ -3214,7 +3238,10 @@
 			    lmap->ldap_attrsonly);
 	if (msgid == -1)
 	{
+		int save_errno;
+
 		errno = ldapmap_geterrno(lmap->ldap_ld) + E_LDAPBASE;
+		save_errno = errno;
 		if (!bitset(MF_OPTIONAL, map->map_mflags))
 		{
 			if (bitset(MF_NODEFER, map->map_mflags))
@@ -3226,16 +3253,14 @@
 		}
 		*statp = EX_TEMPFAIL;
 #ifdef LDAP_SERVER_DOWN
-		if (errno == LDAP_SERVER_DOWN)
+		errno = save_errno;
+		if (errno == LDAP_SERVER_DOWN + E_LDAPBASE)
 		{
-			int save_errno = errno;
-
 			/* server disappeared, try reopen on next search */
-			map->map_class->map_close(map);
-			map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
-			errno = save_errno;
+			ldapmap_close(map);
 		}
 #endif /* LDAP_SERVER_DOWN */
+		errno = save_errno;
 		return NULL;
 	}
 
@@ -3265,7 +3290,7 @@
 				}
 				(void) ldap_abandon(lmap->ldap_ld, msgid);
 				if (vp != NULL)
-					free(vp);
+					sm_free(vp);
 				if (tTd(38, 25))
 					dprintf("ldap search found multiple on a single match query\n");
 				return NULL;
@@ -3348,7 +3373,7 @@
 						(void) ldap_abandon(lmap->ldap_ld,
 								    msgid);
 						if (vp != NULL)
-							free(vp);
+							sm_free(vp);
 						return NULL;
 					}
 				}
@@ -3419,7 +3444,7 @@
 						snprintf(tmp, vsize, "%s%c%s",
 							 vp, map->map_coldelim,
 							 attr);
-						free(vp);
+						sm_free(vp);
 						vp = tmp;
 					}
 # if USING_NETSCAPE_LDAP
@@ -3465,8 +3490,8 @@
 				snprintf(tmp, vsize, "%s%c%s",
 					 vp, map->map_coldelim, vp_tmp);
 
-				free(vp);
-				free(vp_tmp);
+				sm_free(vp);
+				sm_free(vp_tmp);
 				vp = tmp;
 			}
 			errno = ldapmap_geterrno(lmap->ldap_ld);
@@ -3502,7 +3527,7 @@
 				}
 				(void) ldap_abandon(lmap->ldap_ld, msgid);
 				if (vp != NULL)
-					free(vp);
+					sm_free(vp);
 				return NULL;
 			}
 
@@ -3532,7 +3557,7 @@
 			}
 			(void) ldap_abandon(lmap->ldap_ld, msgid);
 			if (vp != NULL)
-				free(vp);
+				sm_free(vp);
 			return NULL;
 		}
 		ldap_msgfree(lmap->ldap_res);
@@ -3557,7 +3582,7 @@
 				lmap->ldap_res = NULL;
 			}
 			if (vp != NULL)
-				free(vp);
+				sm_free(vp);
 			return NULL;
 		}
 		*statp = EX_OK;
@@ -3569,9 +3594,13 @@
 		errno = ldapmap_geterrno(lmap->ldap_ld);
 	if (errno != LDAP_SUCCESS)
 	{
+		int save_errno;
+
 		/* Must be an error */
 		if (ret != 0)
 			errno += E_LDAPBASE;
+		save_errno = errno;
+
 		if (!bitset(MF_OPTIONAL, map->map_mflags))
 		{
 			if (bitset(MF_NODEFER, map->map_mflags))
@@ -3583,7 +3612,16 @@
 		}
 		*statp = EX_TEMPFAIL;
 		if (vp != NULL)
-			free(vp);
+			sm_free(vp);
+#ifdef LDAP_SERVER_DOWN
+		errno = save_errno;
+		if (errno == LDAP_SERVER_DOWN + E_LDAPBASE)
+		{
+			/* server disappeared, try reopen on next search */
+			ldapmap_close(map);
+		}
+#endif /* LDAP_SERVER_DOWN */
+		errno = save_errno;
 		return NULL;
 	}
 
@@ -3601,7 +3639,7 @@
 	if (bitset(MF_NOREWRITE, map->map_mflags))
 	{
 		if (vp != NULL)
-			free(vp);
+			sm_free(vp);
 		return "";
 	}
 
@@ -3619,7 +3657,7 @@
 			result = map_rewrite(map, vp, strlen(vp), av);
 		}
 		if (vp != NULL)
-			free(vp);
+			sm_free(vp);
 	}
 	return result;
 }
@@ -3664,9 +3702,9 @@
 		 (lmap->ldap_binddn == NULL ? "" : lmap->ldap_binddn),
 		 CONDELSE,
 		 (lmap->ldap_secret == NULL ? "" : lmap->ldap_secret),
-		 getpid());
-	s = stab(nbuf, ST_LDAP, ST_ENTER);
-	free(nbuf);
+		 (int) getpid());
+	s = stab(nbuf, ST_LMAP, ST_ENTER);
+	sm_free(nbuf);
 	return s;
 }
 /*
@@ -4309,6 +4347,7 @@
 	lmap->ldap_filter = NULL;
 	lmap->ldap_attr[0] = NULL;
 	lmap->ldap_res = NULL;
+	lmap->ldap_next = NULL;
 }
 /*
 **  LDAPMAP_SET_DEFAULTS -- Read default map spec from LDAPDefaults in .cf
@@ -4357,12 +4396,12 @@
 		syserr("readcf: option LDAPDefaultSpec: Do not set non-LDAP specific flags");
 		if (map.map_app != NULL)
 		{
-			free(map.map_app);
+			sm_free(map.map_app);
 			map.map_app = NULL;
 		}
 		if (map.map_tapp != NULL)
 		{
-			free(map.map_tapp);
+			sm_free(map.map_tapp);
 			map.map_tapp = NULL;
 		}
 	}
@@ -4594,9 +4633,16 @@
 
 /* ARGSUSED */
 static void
-ph_timeout_func(sig_no)
-	int sig_no;
+ph_timeout(sig)
+	int sig;
 {
+	/*
+	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+	**	DOING.
+	*/
+
+	errno = ETIMEDOUT;
 	longjmp(PHTimeout, 1);
 }
 #else /* _FFR_PHMAP_TIMEOUT */
@@ -4695,7 +4741,7 @@
 # endif /* ETIMEDOUT */
 				goto ph_map_open_abort;
 			}
-			ev = setevent(pmap->ph_timeout, ph_timeout_func, 0);
+			ev = setevent(pmap->ph_timeout, ph_timeout, 0);
 		}
 		if (!OpenQiSock(tmp, &(pmap->ph_sockfd)) &&
 		    !Sock2FILEs(pmap->ph_sockfd, &(pmap->ph_to_server),
@@ -4714,7 +4760,7 @@
 		{
 			if (fprintf(pmap->ph_to_server,
 				    "id sendmail+phmap\n") < 0 ||
-			    fflush(pmap->ph_to_server) < 0 ||
+			    fflush(pmap->ph_to_server) != 0 ||
 			    (server_data = ReadQi(pmap->ph_from_server,
 						  &j)) == NULL ||
 			    server_data->code != 200)
@@ -4727,7 +4773,7 @@
 			if (server_data != NULL)
 				FreeQIR(server_data);
 #endif /* _FFR_PHMAP_TIMEOUT */
-			free(hostlist);
+			sm_free(hostlist);
 			return TRUE;
 		}
 #if _FFR_PHMAP_TIMEOUT
@@ -4759,7 +4805,7 @@
 		sm_syslog(LOG_NOTICE, CurEnv->e_id,
 			  "ph_map_open: %s: cannot connect to PH server",
 			  map->map_mname);
-	free(hostlist);
+	sm_free(hostlist);
 	return FALSE;
 }
 
@@ -4814,7 +4860,7 @@
 			*pstat = EX_TEMPFAIL;
 			goto ph_map_lookup_abort;
 		}
-		ev = setevent(pmap->ph_timeout, ph_timeout_func, 0);
+		ev = setevent(pmap->ph_timeout, ph_timeout, 0);
 	}
 
 #endif /* _FFR_PHMAP_TIMEOUT */
@@ -4883,7 +4929,7 @@
 		if (fprintf(pmap->ph_to_server, "query %s=%s return email\n",
 			    tmp2, fmtkey) < 0)
 			message = "qi query command failed";
-		else if (fflush(pmap->ph_to_server) < 0)
+		else if (fflush(pmap->ph_to_server) != 0)
 			message = "qi fflush failed";
 		else if ((server_data = ReadQi(pmap->ph_from_server,
 					       &j)) == NULL)
@@ -5271,6 +5317,7 @@
 	{
 		char *np;
 		int nl;
+		int save_errno;
 		char nbuf[MAXNAME];
 
 		nl = strlen(name);
@@ -5285,8 +5332,10 @@
 # else /* HESIOD_INIT */
 		hp = hes_resolve(np, map->map_file);
 # endif /* HESIOD_INIT */
+		save_errno = errno;
 		if (np != nbuf)
-			free(np);
+			sm_free(np);
+		errno = save_errno;
 	}
 	else
 	{
@@ -5297,11 +5346,8 @@
 # endif /* HESIOD_INIT */
 	}
 # ifdef HESIOD_INIT
-	if (hp == NULL)
-		return NULL;
-	if (*hp == NULL)
+	if (hp == NULL || *hp == NULL)
 	{
-		hesiod_free_list(HesiodContext, hp);
 		switch (errno)
 		{
 		  case ENOENT:
@@ -5316,6 +5362,7 @@
 			  *statp = EX_UNAVAILABLE;
 			  break;
 		}
+		hesiod_free_list(HesiodContext, hp);
 		return NULL;
 	}
 # else /* HESIOD_INIT */
@@ -5413,7 +5460,7 @@
 		res = map_rewrite(map, name, strlen(name), NULL);
 	else
 		res = map_rewrite(map, propval, strlen(propval), av);
-	free(propval);
+	sm_free(propval);
 	return res;
 }
 
@@ -5461,12 +5508,12 @@
 	if (hbsize >= strlen(vptr))
 	{
 		(void) strlcpy(name, vptr, hbsize);
-		free(vptr);
+		sm_free(vptr);
 		*statp = EX_OK;
 		return TRUE;
 	}
 	*statp = EX_UNAVAILABLE;
-	free(vptr);
+	sm_free(vptr);
 	return FALSE;
 }
 
@@ -6352,7 +6399,7 @@
 		if (bitset(MF_MATCHONLY, map->map_mflags))
 			rval = map_rewrite(map, name, strlen(name), NULL);
 		else
-			rval = map_rewrite(map, buf, strlen(buf), NULL);
+			rval = map_rewrite(map, buf, strlen(buf), av);
 
 		/* now flush any additional output */
 		while ((i = read(fd, buf, sizeof buf)) > 0)
@@ -6543,8 +6590,9 @@
 
 		if (mm == NULL || !bitset(MF_OPEN, mm->map_mflags))
 			continue;
+		mm->map_mflags |= MF_CLOSING;
 		mm->map_class->map_close(mm);
-		mm->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+		mm->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
 	}
 }
 
@@ -6892,8 +6940,8 @@
 		(void) regerror(regerr, map_p->regex_pattern_buf,
 			 errbuf, ERRBUF_SIZE);
 		syserr("pattern-compile-error: %s\n", errbuf);
-		free(map_p->regex_pattern_buf);
-		free(map_p);
+		sm_free(map_p->regex_pattern_buf);
+		sm_free(map_p);
 		return FALSE;
 	}
 
@@ -6919,8 +6967,8 @@
 		if (substrings >= MAX_MATCH)
 		{
 			syserr("too many substrings, %d max\n", MAX_MATCH);
-			free(map_p->regex_pattern_buf);
-			free(map_p);
+			sm_free(map_p->regex_pattern_buf);
+			sm_free(map_p);
 			return FALSE;
 		}
 		if (sub_param != NULL && sub_param[0] != '\0')
@@ -6965,7 +7013,7 @@
 	if (bitset(MF_MATCHONLY, map->map_mflags))
 		return map_rewrite(map, av[0], strlen(av[0]), NULL);
 	else
-		return map_rewrite(map, s, slen, NULL);
+		return map_rewrite(map, s, slen, av);
 }
 
 char *
@@ -7194,7 +7242,11 @@
 		*statp = EX_TEMPFAIL;
 		return NULL;
 	}
-	if (r == NS_BADREQ || r == NS_NOPERM)
+	if (r == NS_BADREQ
+# ifdef NS_NOPERM
+	    || r == NS_NOPERM
+# endif /* NS_NOPERM */
+	    )
 	{
 		*statp = EX_CONFIG;
 		return NULL;
Index: gnu/usr.sbin/sendmail/sendmail/mci.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/mci.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- gnu/usr.sbin/sendmail/sendmail/mci.c	2001/01/15 21:09:09	1.2
+++ gnu/usr.sbin/sendmail/sendmail/mci.c	2001/05/29 01:31:15	1.3
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  * Copyright (c) 1995-1997 Eric P. Allman.  All rights reserved.
  * Copyright (c) 1988, 1993
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: mci.c,v 8.133.10.7 2000/12/12 00:39:34 ca Exp $";
+static char id[] = "@(#)$Sendmail: mci.c,v 8.133.10.8 2001/05/03 17:24:10 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -422,7 +422,7 @@
 
 	mci->mci_status = dstat;
 	if (mci->mci_rstatus != NULL)
-		free(mci->mci_rstatus);
+		sm_free(mci->mci_rstatus);
 	if (rstat != NULL)
 		rstat = newstr(rstat);
 	mci->mci_rstatus = rstat;
@@ -807,7 +807,7 @@
 
 	mci->mci_status = NULL;
 	if (mci->mci_rstatus != NULL)
-		free(mci->mci_rstatus);
+		sm_free(mci->mci_rstatus);
 	mci->mci_rstatus = NULL;
 
 	rewind(fp);
@@ -1026,6 +1026,8 @@
 					       sizeof newpath -
 					       (newptr - newpath));
 
+				if (StopRequest)
+					stop_sendmail();
 				ret = mci_traverse_persistent(action, newpath);
 				if (ret < 0)
 					break;
@@ -1125,6 +1127,9 @@
 	/* skip directories */
 	if (hostname == NULL)
 		return 0;
+
+	if (StopRequest)
+		stop_sendmail();
 
 	if (!initflag)
 	{
Index: gnu/usr.sbin/sendmail/sendmail/milter.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/milter.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/sendmail/milter.c	2001/02/28 02:43:54	1.4
+++ gnu/usr.sbin/sendmail/sendmail/milter.c	2001/05/29 01:31:15	1.5
@@ -9,7 +9,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: milter.c,v 8.50.4.44 2001/01/23 19:43:57 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: milter.c,v 8.50.4.46 2001/05/11 18:11:36 gshapiro Exp $";
 #endif /* ! lint */
 
 #if _FFR_MILTER
@@ -62,7 +62,7 @@
 	    !isascii(response[2]) || !isdigit(response[2])) \
 	{ \
 		if (response != NULL) \
-			free(response); \
+			sm_free(response); \
 		response = newstr(default); \
 	} \
 	else \
@@ -74,7 +74,7 @@
 		{ \
 			if (*ptr == '%' && *++ptr != '%') \
 			{ \
-				free(response); \
+				sm_free(response); \
 				response = newstr(default); \
 				break; \
 			} \
@@ -354,7 +354,7 @@
 
 	if (milter_sysread(m, buf, expl, to, e) == NULL)
 	{
-		free(buf);
+		sm_free(buf);
 		return NULL;
 	}
 
@@ -1007,12 +1007,12 @@
 			continue;
 		}
 		if (tTd(64, 5))
-			dprintf("X%s: error connecting to filter\n",
-				m->mf_name);
+			dprintf("X%s: error connecting to filter: %s\n",
+				m->mf_name, errstring(save_errno));
 		if (LogLevel > 0)
 			sm_syslog(LOG_ERR, e->e_id,
-				  "X%s: error connecting to filter",
-				  m->mf_name);
+				  "X%s: error connecting to filter: %s",
+				  m->mf_name, errstring(save_errno));
 		milter_error(m);
 # if _FFR_FREEHOSTENT && NETINET6
 		if (hp != NULL)
@@ -1681,7 +1681,7 @@
 	}
 	(void) milter_write(m, SMFIC_MACRO, buf, s,
 			    m->mf_timeout[SMFTO_WRITE], e);
-	free(buf);
+	sm_free(buf);
 }
 
 /*
@@ -1836,7 +1836,7 @@
 	if (*state != SMFIR_REPLYCODE &&
 	    response != NULL)
 	{
-		free(response);
+		sm_free(response);
 		response = NULL;
 	}
 	return response;
@@ -1970,7 +1970,7 @@
 				  "milter_negotiate(%s): returned %c instead of %c",
 				  m->mf_name, rcmd, SMFIC_OPTNEG);
 		if (response != NULL)
-			free(response);
+			sm_free(response);
 		milter_error(m);
 		return -1;
 	}
@@ -1986,7 +1986,7 @@
 				  "milter_negotiate(%s): did not return valid info",
 				  m->mf_name);
 		if (response != NULL)
-			free(response);
+			sm_free(response);
 		milter_error(m);
 		return -1;
 	}
@@ -2005,7 +2005,7 @@
 				  "milter_negotiate(%s): did not return enough info",
 				  m->mf_name);
 		if (response != NULL)
-			free(response);
+			sm_free(response);
 		milter_error(m);
 		return -1;
 	}
@@ -2014,7 +2014,7 @@
 		      MILTER_LEN_BYTES);
 	(void) memcpy((char *) &pflags, response + (MILTER_LEN_BYTES * 2),
 		      MILTER_LEN_BYTES);
-	free(response);
+	sm_free(response);
 	response = NULL;
 
 	m->mf_fvers = ntohl(fvers);
@@ -2178,7 +2178,7 @@
 		/* send it over */
 		response = milter_send_command(m, SMFIC_HEADER, buf,
 					       s, e, state);
-		free(buf);
+		sm_free(buf);
 		if (m->mf_state == SMFS_ERROR ||
 		    m->mf_state == SMFS_DONE ||
 		    *state != SMFIR_CONTINUE)
@@ -2280,7 +2280,7 @@
 			*state = SMFIR_TEMPFAIL;
 			if (response != NULL)
 			{
-				free(response);
+				sm_free(response);
 				response = NULL;
 			}
 		}
@@ -2522,7 +2522,7 @@
 	if (h != sysheader && h->h_value != NULL)
 	{
 		e->e_msgsize -= strlen(h->h_value);
-		free(h->h_value);
+		sm_free(h->h_value);
 	}
 
 	if (*val == '\0')
@@ -2889,7 +2889,7 @@
 
 	response = milter_command(SMFIC_CONNECT, buf, s,
 				  MilterConnectMacros, e, state);
-	free(buf);
+	sm_free(buf);
 
 	/*
 	**  If this message connection is done for,
@@ -2916,7 +2916,7 @@
 			*state = SMFIR_REJECT;
 		if (response != NULL)
 		{
-			free(response);
+			sm_free(response);
 			response = NULL;
 		}
 	}
@@ -3042,7 +3042,7 @@
 	/* send it over */
 	response = milter_command(SMFIC_MAIL, buf, s,
 				  MilterEnvFromMacros, e, state);
-	free(buf);
+	sm_free(buf);
 
 	/*
 	**  If filter rejects/discards a per message command,
@@ -3106,7 +3106,7 @@
 	/* send it over */
 	response = milter_command(SMFIC_RCPT, buf, s,
 				  MilterEnvRcptMacros, e, state);
-	free(buf);
+	sm_free(buf);
 	return response;
 }
 /*
@@ -3382,7 +3382,7 @@
 			if (rcmd != SMFIR_REPLYCODE &&
 			    response != NULL)
 			{
-				free(response);
+				sm_free(response);
 				response = NULL;
 			}
 
@@ -3414,7 +3414,7 @@
 			*state = SMFIR_TEMPFAIL;
 			if (response != NULL)
 			{
-				free(response);
+				sm_free(response);
 				response = NULL;
 			}
 		}
@@ -3446,7 +3446,7 @@
 			*state = SMFIR_TEMPFAIL;
 			if (response != NULL)
 			{
-				free(response);
+				sm_free(response);
 				response = NULL;
 			}
 		}
Index: gnu/usr.sbin/sendmail/sendmail/parseaddr.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/parseaddr.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/sendmail/parseaddr.c	2001/02/28 02:43:54	1.4
+++ gnu/usr.sbin/sendmail/sendmail/parseaddr.c	2001/05/29 01:31:15	1.5
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: parseaddr.c,v 8.234.4.11 2001/02/14 04:07:27 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: parseaddr.c,v 8.234.4.12 2001/05/03 17:24:11 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -1157,7 +1157,7 @@
 					if ((size_t) trsize > pvpb1_size)
 					{
 						if (pvpb1 != NULL)
-							free(pvpb1);
+							sm_free(pvpb1);
 						pvpb1 = (char **)xalloc(trsize);
 						pvpb1_size = trsize;
 					}
@@ -1583,7 +1583,7 @@
 		if (i > rwbuflen)
 		{
 			if (rwbuf != NULL)
-				free(rwbuf);
+				sm_free(rwbuf);
 			rwbuflen = i;
 			rwbuf = (char *) xalloc(rwbuflen);
 		}
@@ -2461,7 +2461,7 @@
 		if (tTd(29, 9))
 			dprintf("maplocaluser: address unchanged\n");
 		if (a1 != NULL)
-			free(a1);
+			sm_free(a1);
 		return;
 	}
 
@@ -2808,7 +2808,7 @@
 	QuickAbort = saveQuickAbort;
 	setstat(rstat);
 	if (buf != buf0)
-		free(buf);
+		sm_free(buf);
 
 	if (rstat != EX_OK && QuickAbort)
 		longjmp(TopFrame, 2);
Index: gnu/usr.sbin/sendmail/sendmail/queue.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/queue.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/sendmail/queue.c	2001/02/28 02:43:54	1.4
+++ gnu/usr.sbin/sendmail/sendmail/queue.c	2001/05/29 01:31:15	1.5
@@ -16,9 +16,9 @@
 
 #ifndef lint
 # if QUEUE
-static char id[] = "@(#)$Sendmail: queue.c,v 8.343.4.44 2001/02/22 00:55:35 ca Exp $ (with queueing)";
+static char id[] = "@(#)$Sendmail: queue.c,v 8.343.4.55 2001/05/03 23:37:11 gshapiro Exp $ (with queueing)";
 # else /* QUEUE */
-static char id[] = "@(#)$Sendmail: queue.c,v 8.343.4.44 2001/02/22 00:55:35 ca Exp $ (without queueing)";
+static char id[] = "@(#)$Sendmail: queue.c,v 8.343.4.55 2001/05/03 23:37:11 gshapiro Exp $ (without queueing)";
 # endif /* QUEUE */
 #endif /* ! lint */
 
@@ -507,7 +507,7 @@
 
 	fprintf(tfp, ".\n");
 
-	if (fflush(tfp) < 0 ||
+	if (fflush(tfp) != 0 ||
 	    (SuperSafe && fsync(fileno(tfp)) < 0) ||
 	    ferror(tfp))
 	{
@@ -793,6 +793,12 @@
 			return TRUE;
 		}
 		/* child -- clean up signals */
+
+		/* Reset global flags */
+		RestartRequest = NULL;
+		ShutdownRequest = NULL;
+		PendingSignal = 0;
+
 		clrcontrol();
 		proc_list_clear();
 
@@ -801,8 +807,8 @@
 			      PROC_QUEUE_CHILD);
 		(void) releasesignal(SIGCHLD);
 		(void) setsignal(SIGCHLD, SIG_DFL);
-		(void) setsignal(SIGHUP, intsig);
-
+		(void) setsignal(SIGHUP, SIG_DFL);
+		(void) setsignal(SIGTERM, intsig);
 	}
 
 	sm_setproctitle(TRUE, CurEnv, "running queue: %s",
@@ -811,7 +817,7 @@
 	if (LogLevel > 69 || tTd(63, 99))
 		sm_syslog(LOG_DEBUG, NOQID,
 			  "runqueue %s, pid=%d, forkflag=%d",
-			  qid_printqueue(queuedir), getpid(), forkflag);
+			  qid_printqueue(queuedir), (int) getpid(), forkflag);
 
 	/*
 	**  Release any resources used by the daemon code.
@@ -953,10 +959,10 @@
 			if (pid != 0)
 				(void) waitfor(pid);
 		}
-		free(w->w_name);
+		sm_free(w->w_name);
 		if (w->w_host)
-			free(w->w_host);
-		free((char *) w);
+			sm_free(w->w_host);
+		sm_free((char *) w);
 	}
 
 	/* exit without the usual cleanup */
@@ -969,6 +975,16 @@
 
 /*
 **  RUNQUEUEEVENT -- stub for use in setevent
+**
+**	Parameters:
+**		none.
+**
+**	Returns:
+**		none.
+**
+**	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+**		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+**		DOING.
 */
 
 static void
@@ -1061,10 +1077,10 @@
 		register WORK *nw = w->w_next;
 
 		WorkQ = nw;
-		free(w->w_name);
+		sm_free(w->w_name);
 		if (w->w_host != NULL)
-			free(w->w_host);
-		free((char *) w);
+			sm_free(w->w_host);
+		sm_free((char *) w);
 		w = nw;
 	}
 
@@ -1312,9 +1328,9 @@
 			/* don't even bother sorting this job in */
 			if (tTd(41, 49))
 				dprintf("skipping %s (%x)\n", w->w_name, i);
-			free(w->w_name);
+			sm_free(w->w_name);
 			if (w->w_host)
-				free(w->w_host);
+				sm_free(w->w_host);
 			wn--;
 		}
 	}
@@ -1415,7 +1431,7 @@
 		WorkQ = w;
 	}
 	if (WorkList != NULL)
-		free(WorkList);
+		sm_free(WorkList);
 	WorkList = NULL;
 	WorkListSize = 0;
 
@@ -1464,8 +1480,8 @@
 	else
 	{
 		int newsize = WorkListSize + QUEUESEGSIZE;
-		WORK *newlist = (WORK *) realloc((char *)WorkList,
-					  (unsigned)sizeof(WORK) * (newsize + 1));
+		WORK *newlist = (WORK *) xrealloc((char *)WorkList,
+						  (unsigned)sizeof(WORK) * (newsize + 1));
 
 		if (newlist != NULL)
 		{
@@ -1762,6 +1778,11 @@
 		**		can recover on interrupt.
 		*/
 
+		/* Reset global flags */
+		RestartRequest = NULL;
+		ShutdownRequest = NULL;
+		PendingSignal = 0;
+
 		/* set basic modes, etc. */
 		(void) alarm(0);
 		clearstats();
@@ -1782,7 +1803,7 @@
 		if (LogLevel > 76)
 			sm_syslog(LOG_DEBUG, e->e_id,
 				  "dowork, pid=%d",
-				  getpid());
+				  (int) getpid());
 
 		/* don't use the headers from sendmail.cf... */
 		e->e_header = NULL;
@@ -1838,7 +1859,7 @@
 {
 	register FILE *qfp;
 	ADDRESS *ctladdr;
-	struct stat st;
+	struct stat st, stf;
 	char *bp;
 	int qfver = 0;
 	long hdrsize = 0;
@@ -1883,19 +1904,59 @@
 	}
 
 	/*
-	**  Check the queue file for plausibility to avoid attacks.
+	**  Prevent locking race condition.
+	**
+	**  Process A: readqf(): qfp = fopen(qffile)
+	**  Process B: queueup(): rename(tf, qf)
+	**  Process B: unlocks(tf)
+	**  Process A: lockfile(qf);
+	**
+	**  Process A (us) has the old qf file (before the rename deleted
+	**  the directory entry) and will be delivering based on old data.
+	**  This can lead to multiple deliveries of the same recipients.
+	**
+	**  Catch this by checking if the underlying qf file has changed
+	**  *after* acquiring our lock and if so, act as though the file
+	**  was still locked (i.e., just return like the lockfile() case
+	**  above.
 	*/
 
-	if (fstat(fileno(qfp), &st) < 0)
+	if (stat(qf, &stf) < 0 ||
+	    fstat(fileno(qfp), &st) < 0)
 	{
 		/* must have been being processed by someone else */
 		if (tTd(40, 8))
-			dprintf("readqf(%s): fstat failure (%s)\n",
+			dprintf("readqf(%s): [f]stat failure (%s)\n",
 				qf, errstring(errno));
 		(void) fclose(qfp);
 		return FALSE;
 	}
 
+	if (st.st_nlink != stf.st_nlink ||
+	    st.st_dev != stf.st_dev ||
+	    st.st_ino != stf.st_ino ||
+# if HAS_ST_GEN && 0		/* AFS returns garbage in st_gen */
+	    st.st_gen != stf.st_gen ||
+# endif /* HAS_ST_GEN && 0 */
+	    st.st_uid != stf.st_uid ||
+	    st.st_gid != stf.st_gid ||
+	    st.st_size != stf.st_size)
+	{
+		/* changed after opened */
+		if (Verbose)
+			printf("%s: changed\n", e->e_id);
+		if (tTd(40, 8))
+			dprintf("%s: changed\n", e->e_id);
+		if (LogLevel > 19)
+			sm_syslog(LOG_DEBUG, e->e_id, "changed");
+		(void) fclose(qfp);
+		return FALSE;
+	}
+
+	/*
+	**  Check the queue file for plausibility to avoid attacks.
+	*/
+
 	qsafe = S_IWOTH|S_IWGRP;
 #if _FFR_QUEUE_FILE_MODE
 	if (bitset(S_IWGRP, QueueFileMode))
@@ -2243,7 +2304,7 @@
 		}
 
 		if (bp != buf)
-			free(bp);
+			sm_free(bp);
 	}
 
 	/*
@@ -2351,7 +2412,11 @@
 	int i, nrequests = 0;
 
 	for (i = 0; i < NumQueues; i++)
+	{
+		if (StopRequest)
+			stop_sendmail();
 		nrequests += print_single_queue(i);
+	}
 	if (NumQueues > 1)
 		printf("\t\tTotal Requests: %d\n", nrequests);
 }
@@ -2467,6 +2532,9 @@
 		char bodytype[MAXNAME + 1];
 		char qf[MAXPATHLEN];
 
+		if (StopRequest)
+			stop_sendmail();
+
 		printf("%12s", w->w_name + 2);
 		(void) snprintf(qf, sizeof qf, "%s/%s", qd, w->w_name);
 		f = fopen(qf, "r");
@@ -2499,6 +2567,9 @@
 			register int i;
 			register char *p;
 
+			if (StopRequest)
+				stop_sendmail();
+
 			fixcrlf(buf, TRUE);
 			switch (buf[0])
 			{
@@ -2680,7 +2751,8 @@
 **		none.
 */
 
-static char	Base60Code[] =	"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx";
+static const char QueueIdChars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx";
+# define QIC_LEN	60
 
 void
 assign_queueid(e)
@@ -2696,7 +2768,7 @@
 		return;
 
 	/* see if we need to get a new base time/pid */
-	if (cX >= 60 || LastQueueTime == 0 || LastQueuePid != pid)
+	if (cX >= QIC_LEN || LastQueueTime == 0 || LastQueuePid != pid)
 	{
 		time_t then = LastQueueTime;
 
@@ -2714,16 +2786,16 @@
 	}
 	if (tTd(7, 50))
 		dprintf("assign_queueid: random_offset = %ld (%d)\n",
-			random_offset, (int)(cX + random_offset) % 60);
+			random_offset, (int)(cX + random_offset) % QIC_LEN);
 
 	tm = gmtime(&LastQueueTime);
-	idbuf[0] = Base60Code[tm->tm_year % 60];
-	idbuf[1] = Base60Code[tm->tm_mon];
-	idbuf[2] = Base60Code[tm->tm_mday];
-	idbuf[3] = Base60Code[tm->tm_hour];
-	idbuf[4] = Base60Code[tm->tm_min];
-	idbuf[5] = Base60Code[tm->tm_sec];
-	idbuf[6] = Base60Code[((int)cX++ + random_offset) % 60];
+	idbuf[0] = QueueIdChars[tm->tm_year % QIC_LEN];
+	idbuf[1] = QueueIdChars[tm->tm_mon];
+	idbuf[2] = QueueIdChars[tm->tm_mday];
+	idbuf[3] = QueueIdChars[tm->tm_hour];
+	idbuf[4] = QueueIdChars[tm->tm_min];
+	idbuf[5] = QueueIdChars[tm->tm_sec];
+	idbuf[6] = QueueIdChars[((int)cX++ + random_offset) % QIC_LEN];
 	(void) snprintf(&idbuf[7], sizeof idbuf - 7, "%05d",
 			(int) LastQueuePid);
 	e->e_id = newstr(idbuf);
@@ -3056,7 +3128,7 @@
 
 	/* skip over . and .. directories */
 	if (name[0] == '.' &&
-	    (name[1] == '\0' || (name[2] == '.' && name[3] == '\0')))
+	    (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
 		return FALSE;
 # if HASLSTAT
 	if (lstat(name, &statb) < 0)
@@ -3137,9 +3209,9 @@
 		for (i = 0; i < NumQueues; i++)
 		{
 			if (QPaths[i].qp_name != NULL)
-				(void) free(QPaths[i].qp_name);
+				sm_free(QPaths[i].qp_name);
 		}
-		(void) free((char *)QPaths);
+		sm_free((char *)QPaths);
 		QPaths = NULL;
 		NumQueues = 0;
 	}
@@ -3232,9 +3304,9 @@
 			}
 			else if (slotsleft < 1)
 			{
-				QPaths = (QPATHS *)realloc((char *)QPaths,
-							  (sizeof *QPaths) *
-							  (NumQueues + 10));
+				QPaths = (QPATHS *)xrealloc((char *)QPaths,
+							    (sizeof *QPaths) *
+							    (NumQueues + 10));
 				if (QPaths == NULL)
 				{
 					(void) closedir(dp);
Index: gnu/usr.sbin/sendmail/sendmail/readcf.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/readcf.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- gnu/usr.sbin/sendmail/sendmail/readcf.c	2001/02/28 02:43:55	1.5
+++ gnu/usr.sbin/sendmail/sendmail/readcf.c	2001/05/29 01:31:16	1.6
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: readcf.c,v 8.382.4.38 2001/02/17 00:05:12 geir Exp $";
+static char id[] = "@(#)$Sendmail: readcf.c,v 8.382.4.40 2001/05/03 17:24:13 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -148,7 +148,7 @@
 		if (bp[0] == '#')
 		{
 			if (bp != buf)
-				free(bp);
+				sm_free(bp);
 			continue;
 		}
 
@@ -545,7 +545,7 @@
 			syserr("unknown configuration line \"%s\"", bp);
 		}
 		if (bp != buf)
-			free(bp);
+			sm_free(bp);
 	}
 	if (ferror(cf))
 	{
@@ -1269,7 +1269,7 @@
 	if (s->s_mailer != NULL)
 	{
 		i = s->s_mailer->m_mno;
-		free(s->s_mailer);
+		sm_free(s->s_mailer);
 	}
 	else
 	{
@@ -1548,9 +1548,7 @@
 	{ "RemoteMode",			'>',		OI_NONE	},
 #endif /* defined(SUN_EXTENSIONS) && defined(REMOTE_MODE) */
 	{ "SevenBitInput",		'7',		OI_SAFE	},
-#if MIME8TO7
 	{ "EightBitMode",		'8',		OI_SAFE	},
-#endif /* MIME8TO7 */
 	{ "AliasFile",			'A',		OI_NONE	},
 	{ "AliasWait",			'a',		OI_NONE	},
 	{ "BlankSub",			'B',		OI_NONE	},
@@ -1898,8 +1896,8 @@
 		SevenBitInput = atobool(val);
 		break;
 
-#if MIME8TO7
 	  case '8':		/* handling of 8-bit input */
+#if MIME8TO7
 		switch (*val)
 		{
 		  case 'm':		/* convert 8-bit, convert MIME */
@@ -1936,8 +1934,10 @@
 			syserr("Unknown 8-bit mode %c", *val);
 			finis(FALSE, EX_USAGE);
 		}
-		break;
+#else /* MIME8TO7 */
+		printf("Warning: Option EightBitMode requires MIME8TO7 support\n");
 #endif /* MIME8TO7 */
+		break;
 
 	  case 'A':		/* set default alias file */
 		if (val[0] == '\0')
@@ -2641,7 +2641,7 @@
 
 	  case O_PIDFILE:
 		if (PidFile != NULL)
-			free(PidFile);
+			sm_free(PidFile);
 		PidFile = newstr(val);
 		break;
 
@@ -2688,7 +2688,7 @@
 
 	  case O_DEADLETTER:
 		if (DeadLetterDrop != NULL)
-			free(DeadLetterDrop);
+			sm_free(DeadLetterDrop);
 		DeadLetterDrop = newstr(val);
 		break;
 
@@ -2778,7 +2778,7 @@
 
 	  case O_CONTROLSOCKET:
 		if (ControlSocketName != NULL)
-			free(ControlSocketName);
+			sm_free(ControlSocketName);
 		ControlSocketName = newstr(val);
 		break;
 
@@ -2792,7 +2792,7 @@
 
 	  case O_PROCTITLEPREFIX:
 		if (ProcTitlePrefix != NULL)
-			free(ProcTitlePrefix);
+			sm_free(ProcTitlePrefix);
 		ProcTitlePrefix = newstr(val);
 		break;
 
@@ -2818,13 +2818,13 @@
 		}
 #endif /* _FFR_ALLOW_SASLINFO */
 		if (SASLInfo != NULL)
-			free(SASLInfo);
+			sm_free(SASLInfo);
 		SASLInfo = newstr(val);
 		break;
 
 	  case O_SASLMECH:
 		if (AuthMechanisms != NULL)
-			free(AuthMechanisms);
+			sm_free(AuthMechanisms);
 		if (*val != '\0')
 			AuthMechanisms = newstr(val);
 		else
@@ -2886,63 +2886,63 @@
 #if STARTTLS
 	  case O_SRVCERTFILE:
 		if (SrvCERTfile != NULL)
-			free(SrvCERTfile);
+			sm_free(SrvCERTfile);
 		SrvCERTfile = newstr(val);
 		break;
 
 	  case O_SRVKEYFILE:
 		if (Srvkeyfile != NULL)
-			free(Srvkeyfile);
+			sm_free(Srvkeyfile);
 		Srvkeyfile = newstr(val);
 		break;
 
 	  case O_CLTCERTFILE:
 		if (CltCERTfile != NULL)
-			free(CltCERTfile);
+			sm_free(CltCERTfile);
 		CltCERTfile = newstr(val);
 		break;
 
 	  case O_CLTKEYFILE:
 		if (Cltkeyfile != NULL)
-			free(Cltkeyfile);
+			sm_free(Cltkeyfile);
 		Cltkeyfile = newstr(val);
 		break;
 
 	  case O_CACERTFILE:
 		if (CACERTfile != NULL)
-			free(CACERTfile);
+			sm_free(CACERTfile);
 		CACERTfile = newstr(val);
 		break;
 
 	  case O_CACERTPATH:
 		if (CACERTpath != NULL)
-			free(CACERTpath);
+			sm_free(CACERTpath);
 		CACERTpath = newstr(val);
 		break;
 
 	  case O_DHPARAMS:
 		if (DHParams != NULL)
-			free(DHParams);
+			sm_free(DHParams);
 		DHParams = newstr(val);
 		break;
 
 #  if _FFR_TLS_1
 	  case O_DHPARAMS5:
 		if (DHParams5 != NULL)
-			free(DHParams5);
+			sm_free(DHParams5);
 		DHParams5 = newstr(val);
 		break;
 
 	  case O_CIPHERLIST:
 		if (CipherList != NULL)
-			free(CipherList);
+			sm_free(CipherList);
 		CipherList = newstr(val);
 		break;
 #  endif /* _FFR_TLS_1 */
 
 	  case O_RANDFILE:
 		if (RandFile != NULL)
-			free(RandFile);
+			sm_free(RandFile);
 		RandFile= newstr(val);
 		break;
 
@@ -3272,7 +3272,7 @@
 			char *h = NULL;
 
 			if (RuleSetNames[ruleset] != NULL)
-				free(RuleSetNames[ruleset]);
+				sm_free(RuleSetNames[ruleset]);
 			if (delim != '\0' && (h = strchr(q, delim)) != NULL)
 				*h = '\0';
 			RuleSetNames[ruleset] = newstr(q);
Index: gnu/usr.sbin/sendmail/sendmail/recipient.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/recipient.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- gnu/usr.sbin/sendmail/sendmail/recipient.c	2001/02/28 02:43:55	1.3
+++ gnu/usr.sbin/sendmail/sendmail/recipient.c	2001/05/29 01:31:16	1.4
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: recipient.c,v 8.231.14.10 2001/02/14 04:07:30 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: recipient.c,v 8.231.14.11 2001/05/03 17:24:14 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -185,7 +185,7 @@
 
 	e->e_to = oldto;
 	if (bufp != buf)
-		free(bufp);
+		sm_free(bufp);
 #if _FFR_ADDR_TYPE
 	define(macid("{addr_type}", NULL), NULL, e);
 #endif /* _FFR_ADDR_TYPE */
@@ -293,7 +293,7 @@
 
 	e->e_to = oldto;
 	if (bufp != buf)
-		free(bufp);
+		sm_free(bufp);
 #if _FFR_ADDR_TYPE
 	define(macid("{addr_type}", NULL), NULL, e);
 #endif /* _FFR_ADDR_TYPE */
@@ -780,7 +780,7 @@
   done:
 	a->q_flags |= QTHISPASS;
 	if (buf != buf0)
-		free(buf);
+		sm_free(buf);
 
 	/*
 	**  If we are at the top level, check to see if this has
@@ -1573,6 +1573,13 @@
 static void
 includetimeout()
 {
+	/*
+	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+	**	DOING.
+	*/
+
+	errno = ETIMEDOUT;
 	longjmp(CtxIncludeTimeout, 1);
 }
 /*
Index: gnu/usr.sbin/sendmail/sendmail/savemail.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/savemail.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/sendmail/savemail.c	2001/02/28 02:43:55	1.4
+++ gnu/usr.sbin/sendmail/sendmail/savemail.c	2001/05/29 01:31:16	1.5
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: savemail.c,v 8.212.4.12 2001/01/07 19:31:05 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: savemail.c,v 8.212.4.13 2001/05/03 17:24:15 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -1413,7 +1413,7 @@
 	if (l > bplen)
 	{
 		if (bp != NULL)
-			free(bp);
+			sm_free(bp);
 		bp = xalloc(l);
 		bplen = l;
 	}
@@ -1466,7 +1466,7 @@
 	if (l > bplen)
 	{
 		if (bp != NULL)
-			free(bp);
+			sm_free(bp);
 		bp = xalloc(l);
 		bplen = l;
 	}
Index: gnu/usr.sbin/sendmail/sendmail/sendmail.h
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/sendmail.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- gnu/usr.sbin/sendmail/sendmail/sendmail.h	2001/02/28 02:43:55	1.5
+++ gnu/usr.sbin/sendmail/sendmail/sendmail.h	2001/05/29 01:31:16	1.6
@@ -20,7 +20,7 @@
 #ifdef _DEFINE
 # define EXTERN
 # ifndef lint
-static char SmailId[] =	"@(#)$Sendmail: sendmail.h,v 8.517.4.50 2001/02/22 18:56:24 gshapiro Exp $";
+static char SmailId[] =	"@(#)$Sendmail: sendmail.h,v 8.517.4.64 2001/05/23 17:49:13 ca Exp $";
 # endif /* ! lint */
 #else /* _DEFINE */
 # define EXTERN extern
@@ -881,6 +881,7 @@
 #define MF_DEFER	0x00080000	/* don't lookup map in defer mode */
 #define MF_SINGLEMATCH	0x00100000	/* successful only if match one key */
 #define MF_NOREWRITE	0x00200000	/* don't rewrite result, return as-is */
+#define MF_CLOSING	0x00400000	/* map is being closed */
 
 #define DYNOPENMAP(map) if (!bitset(MF_OPEN, (map)->map_mflags)) \
 	{	\
@@ -969,6 +970,9 @@
 	/* args for ldap_result */
 	struct timeval	ldap_timeout;
 	LDAPMessage	*ldap_res;
+
+	/* Linked list of maps sharing the same LDAP binding */
+	MAP		*ldap_next;
 };
 
 typedef struct ldapmap_struct	LDAPMAP_STRUCT;
@@ -1076,7 +1080,7 @@
 		struct hdrinfo	sv_header;	/* header metainfo */
 		char		*sv_service[MAXMAPSTACK]; /* service switch */
 #ifdef LDAPMAP
-		LDAP		*sv_ldap;	/* LDAP connection */
+		MAP		*sv_lmap;	/* Maps for LDAP connection */
 #endif /* LDAPMAP */
 #if _FFR_MILTER
 		struct milter	*sv_milter;	/* milter filter name */
@@ -1101,7 +1105,7 @@
 #define ST_SERVICE	11	/* service switch entry */
 #define ST_HEADER	12	/* special header flags */
 #ifdef LDAPMAP
-# define ST_LDAP	13	/* LDAP connection */
+# define ST_LMAP	13	/* List head of maps for LDAP connection */
 #endif /* LDAPMAP */
 #if _FFR_MILTER
 # define ST_MILTER	14	/* milter filter */
@@ -1122,7 +1126,7 @@
 #define s_service	s_value.sv_service
 #define s_header	s_value.sv_header
 #ifdef LDAPMAP
-# define s_ldap		s_value.sv_ldap
+# define s_lmap		s_value.sv_lmap
 #endif /* LDAPMAP */
 #if _FFR_MILTER
 # define s_milter	s_value.sv_milter
@@ -1151,7 +1155,7 @@
 	void		(*ev_func)__P((int));
 					/* function to call */
 	int		ev_arg;		/* argument to ev_func */
-	int		ev_pid;		/* pid that set this event */
+	pid_t		ev_pid;		/* pid that set this event */
 	struct event	*ev_link;	/* link to next item */
 };
 
@@ -1161,6 +1165,7 @@
 extern void	clrevent __P((EVENT *));
 extern void	clear_events __P((void));
 extern EVENT	*setevent __P((time_t, void(*)(), int));
+extern EVENT	*sigsafe_setevent __P((time_t, void(*)(), int));
 
 /*
 **  Operation, send, error, and MIME modes
@@ -1628,6 +1633,51 @@
 /* variables */
 extern u_char	tTdvect[100];	/* trace vector */
 /*
+**  Critical signal sections
+*/
+
+#define PEND_SIGHUP	0x0001
+#define PEND_SIGINT	0x0002
+#define PEND_SIGTERM	0x0004
+#define PEND_SIGUSR1	0x0008
+
+#define ENTER_CRITICAL()	InCriticalSection++
+
+#define LEAVE_CRITICAL()						\
+do									\
+{									\
+	if (InCriticalSection > 0)					\
+		InCriticalSection--;					\
+} while (0)
+
+#define CHECK_CRITICAL(sig)						\
+{									\
+	if (InCriticalSection > 0 && (sig) != 0)			\
+	{								\
+		pend_signal((sig));					\
+		return SIGFUNC_RETURN;					\
+	}								\
+}
+
+/* reset signal in case System V semantics */
+#ifdef SYS5SIGNALS
+# define FIX_SYSV_SIGNAL(sig, handler)					\
+{									\
+	if ((sig) != 0)							\
+		(void) setsignal((sig), (handler));			\
+}
+#else /* SYS5SIGNALS */
+# define FIX_SYSV_SIGNAL(sig, handler)	{ /* EMPTY */ }
+#endif /* SYS5SIGNALS */
+
+/* variables */
+EXTERN u_int	volatile InCriticalSection;	/* >0 if in a critical section */
+EXTERN int	volatile PendingSignal;	/* pending signal to resend */
+
+/* functions */
+extern void	pend_signal __P((int));
+
+/*
 **  Miscellaneous information.
 */
 
@@ -1664,9 +1714,9 @@
 EXTERN bool	ChownAlwaysSafe;	/* treat chown(2) as safe */
 EXTERN bool	ColonOkInAddr;	/* single colon legal in address */
 EXTERN bool	ConfigFileRead;	/* configuration file has been read */
-EXTERN bool	DataProgress;	/* have we sent anything since last check */
+EXTERN bool	volatile DataProgress;	/* have we sent anything since last check */
 EXTERN bool	DisConnected;	/* running with OutChannel redirected to xf */
-EXTERN bool	DoQueueRun;	/* non-interrupt time queue run needed */
+EXTERN bool	volatile DoQueueRun;	/* non-interrupt time queue run needed */
 EXTERN bool	DontExpandCnames;	/* do not $[...$] expand CNAMEs */
 EXTERN bool	DontInitGroups;	/* avoid initgroups() because of NIS cost */
 EXTERN bool	DontLockReadFiles;	/* don't read lock support files */
@@ -1695,6 +1745,7 @@
 EXTERN bool	SevenBitInput;	/* force 7-bit data on input */
 EXTERN bool	SingleLineFromHeader;	/* force From: header to be one line */
 EXTERN bool	SingleThreadDelivery;	/* single thread hosts on delivery */
+EXTERN bool	volatile StopRequest;	/* stop sending output */
 EXTERN bool	SuperSafe;	/* be extra careful, even if expensive */
 EXTERN bool	SuprErrs;	/* set if we are suppressing errors */
 EXTERN bool	TryNullMXList;	/* if we are the best MX, try host directly */
@@ -1710,7 +1761,7 @@
 EXTERN int	CheckpointInterval;	/* queue file checkpoint interval */
 EXTERN int	ConfigLevel;	/* config file level */
 EXTERN int	ConnRateThrottle;	/* throttle for SMTP connection rate */
-EXTERN int	CurChildren;	/* current number of daemonic children */
+EXTERN int	volatile CurChildren;	/* current number of daemonic children */
 EXTERN int	CurrentLA;	/* current load average */
 EXTERN int	DefaultNotify;	/* default DSN notification flags */
 EXTERN int	Errors;		/* set if errors (local to single pass) */
@@ -1815,9 +1866,11 @@
 #endif /* _FFR_QUEUEDELAY */
 EXTERN char	*RealHostName;	/* name of host we are talking to */
 EXTERN char	*RealUserName;	/* real user name of caller */
+EXTERN char	*volatile RestartRequest;/* a sendmail restart has been requested */
 EXTERN char	*RunAsUserName;	/* user to become for bulk of run */
 EXTERN char	*SafeFileEnv;	/* chroot location for file delivery */
 EXTERN char	*ServiceSwitchFile;	/* backup service switch */
+EXTERN char	*volatile ShutdownRequest;/* a sendmail shutdown has been requested */
 EXTERN char	*SmtpGreeting;	/* SMTP greeting message (old $e macro) */
 EXTERN char	*SmtpPhase;	/* current phase in SMTP processing */
 EXTERN char	SmtpError[MAXLINE];	/* save failure error messages */
@@ -1827,6 +1880,7 @@
 EXTERN char	*UnixFromLine;	/* UNIX From_ line (old $l macro) */
 EXTERN char	**ExternalEnviron;	/* input environment */
 					/* saved user environment */
+EXTERN char	**SaveArgv;	/* argument vector for re-execing */
 EXTERN BITMAP256	DontBlameSendmail;	/* DontBlameSendmail bits */
 #if SFIO
 EXTERN Sfio_t	*InChannel;	/* input connection */
@@ -1840,7 +1894,6 @@
 EXTERN void	*HesiodContext;
 #endif /* HESIOD */
 EXTERN ENVELOPE	*CurEnv;	/* envelope currently being processed */
-EXTERN EVENT	*EventQueue;	/* head of event queue */
 EXTERN MAILER	*LocalMailer;	/* ptr to local mailer */
 EXTERN MAILER	*ProgMailer;	/* ptr to program mailer */
 EXTERN MAILER	*FileMailer;	/* ptr to *file* mailer */
@@ -1878,6 +1931,7 @@
 
 #if STARTTLS
 extern void	apps_ssl_info_cb __P((SSL *, int , int));
+extern bool	init_tls_library __P((void));
 extern bool	inittls __P((SSL_CTX **, u_long, bool, char *, char *, char *, char *, char *));
 extern bool	initclttls __P((void));
 extern bool	initsrvtls __P((void));
@@ -1974,6 +2028,7 @@
 #endif /* _FFR_MILTER */
 
 extern char	*addquotes __P((char *));
+extern void	allsignals __P((bool));
 extern char	*arpadate __P((char *));
 extern bool	atobool __P((char *));
 extern int	atooct __P((char *));
@@ -2000,7 +2055,7 @@
 extern char	*denlstring __P((char *, bool, bool));
 extern void	disconnect __P((int, ENVELOPE *));
 extern bool	dns_getcanonname __P((char *, int, bool, int *));
-extern int	dofork __P((void));
+extern pid_t	dofork __P((void));
 extern int	drop_privileges __P((bool));
 extern int	dsntoexitstat __P((char *));
 extern void	dumpfd __P((int, bool, bool));
@@ -2014,6 +2069,11 @@
 extern void	finis __P((bool, volatile int));
 extern void	fixcrlf __P((char *, bool));
 extern long	freediskspace __P((char *, long *));
+#if NETINET6 && NEEDSGETIPNODE
+# if _FFR_FREEHOSTENT
+extern void	freehostent __P((struct hostent *));
+# endif /* _FFR_FREEHOSTENT */
+#endif /* NEEDSGETIPNODE && NETINET6 */
 extern char	*get_column __P((char *, int, int, char *, int));
 extern char	*getauthinfo __P((int, bool *));
 extern char	*getcfname __P((void));
@@ -2028,7 +2088,6 @@
 extern void	initmacros __P((ENVELOPE *));
 extern void	initsetproctitle __P((int, char **, char **));
 extern void	init_vendor_macros __P((ENVELOPE *));
-extern SIGFUNC_DECL	intindebug __P((int));
 extern SIGFUNC_DECL	intsig __P((int));
 extern bool	isloopback __P((SOCKADDR sa));
 extern void	load_if_names __P((void));
@@ -2048,11 +2107,10 @@
 extern void	printopenfds __P((bool));
 extern void	printqueue __P((void));
 extern void	printrules __P((void));
-extern int	prog_open __P((char **, int *, ENVELOPE *));
+extern pid_t	prog_open __P((char **, int *, ENVELOPE *));
 extern void	putline __P((char *, MCI *));
 extern void	putxline __P((char *, size_t, MCI *, int));
 extern void	queueup_macros __P((int, FILE *, ENVELOPE *));
-extern SIGFUNC_DECL	quiesce __P((int));
 extern void	readcf __P((char *, bool, ENVELOPE *));
 extern SIGFUNC_DECL	reapchild __P((int));
 extern int	releasesignal __P((int));
@@ -2074,9 +2132,9 @@
 extern char	*shortenstring __P((const char *, int));
 extern char	*shorten_hostname __P((char []));
 extern bool	shorten_rfc822_string __P((char *, size_t));
-extern SIGFUNC_DECL	sigusr1 __P((int));
-extern SIGFUNC_DECL	sighup __P((int));
+extern void	shutdown_daemon __P((void));
 extern void	sm_dopr __P((char *, const char *, va_list));
+extern void	sm_free __P((void *));
 extern struct hostent	*sm_gethostbyname __P((char *, int));
 extern struct hostent	*sm_gethostbyaddr __P((char *, int, int));
 extern int	sm_getla __P((ENVELOPE *));
@@ -2084,13 +2142,13 @@
 extern struct passwd	*sm_getpwuid __P((UID_T));
 extern void	sm_setproctitle __P((bool, ENVELOPE *, const char *, ...));
 extern int	sm_strcasecmp __P((const char *, const char *));
+extern void	stop_sendmail __P((void));
 extern bool	strcontainedin __P((char *, char *));
 extern void	stripquotes __P((char *));
 extern int	switch_map_find __P((char *, char *[], short []));
 extern bool	transienterror __P((int));
 extern void	tTflag __P((char *));
 extern void	tTsetup __P((u_char *, int, char *));
-extern SIGFUNC_DECL	tick __P((int));
 extern char	*ttypath __P((void));
 extern void	unlockqueue __P((ENVELOPE *));
 #if !HASUNSETENV
@@ -2103,6 +2161,8 @@
 extern int	waitfor __P((pid_t));
 extern bool	writable __P((char *, ADDRESS *, long));
 extern char	*xalloc __P((int));
+extern char	*xcalloc __P((size_t, size_t));
+extern char	*xrealloc __P((void *, size_t));
 extern void	xputs __P((const char *));
 extern char	*xtextify __P((char *, char *));
 extern bool	xtextok __P((char *));
Index: gnu/usr.sbin/sendmail/sendmail/sfsasl.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/sfsasl.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- gnu/usr.sbin/sendmail/sendmail/sfsasl.c	2001/01/15 21:09:10	1.3
+++ gnu/usr.sbin/sendmail/sendmail/sfsasl.c	2001/05/29 01:31:16	1.4
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  *
  * By using this file, you agree to the terms and conditions set
@@ -9,7 +9,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: sfsasl.c,v 8.17.4.13 2000/11/03 00:24:49 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: sfsasl.c,v 8.17.4.14 2001/05/03 17:24:16 gshapiro Exp $";
 #endif /* ! lint */
 
 #if SFIO
@@ -28,7 +28,7 @@
 # include "sfsasl.h"
 
 /* how to deallocate a buffer allocated by SASL */
-#  define SASL_DEALLOC(b)	free(b)
+#  define SASL_DEALLOC(b)	sm_free(b)
 
 static ssize_t
 sasl_read(f, buf, size, disc)
@@ -134,14 +134,8 @@
 		return 0;
 	}
 
-	if ((saslin = (Sasldisc_t *) malloc(sizeof(Sasldisc_t))) == NULL)
-		return -1;
-	if ((saslout = (Sasldisc_t *) malloc(sizeof(Sasldisc_t))) == NULL)
-	{
-		free(saslin);
-		return -1;
-	}
-
+	saslin = (Sasldisc_t *) xalloc(sizeof(Sasldisc_t));
+	saslout = (Sasldisc_t *) xalloc(sizeof(Sasldisc_t));
 	saslin->disc.readf = sasl_read;
 	saslin->disc.writef = sasl_write;
 	saslin->disc.seekf = NULL;
@@ -158,8 +152,8 @@
 	if (sfdisc(fin, (Sfdisc_t *) saslin) != (Sfdisc_t *) saslin ||
 	    sfdisc(fout, (Sfdisc_t *) saslout) != (Sfdisc_t *) saslout)
 	{
-		free(saslin);
-		free(saslout);
+		sm_free(saslin);
+		sm_free(saslout);
 		return -1;
 	}
 	return 0;
@@ -310,7 +304,7 @@
 		tc->fp = NULL;
 	}
 
-	free(tc);
+	sm_free(tc);
 	return retval;
 }
 # endif /* !SFIO */
@@ -335,15 +329,9 @@
 
 	if (con == NULL)
 		return 0;
-
-	if ((tlsin = (Tlsdisc_t *) malloc(sizeof(Tlsdisc_t))) == NULL)
-		return -1;
-	if ((tlsout = (Tlsdisc_t *) malloc(sizeof(Tlsdisc_t))) == NULL)
-	{
-		free(tlsin);
-		return -1;
-	}
 
+	tlsin = (Tlsdisc_t *) xalloc(sizeof(Tlsdisc_t));
+	tlsout = (Tlsdisc_t *) xalloc(sizeof(Tlsdisc_t));
 # if SFIO
 	tlsin->disc.readf = tls_read;
 	tlsin->disc.writef = tls_write;
@@ -362,15 +350,15 @@
 	if (rfd < 0 || wfd < 0 ||
 	    SSL_set_rfd(con, rfd) <= 0 || SSL_set_wfd(con, wfd) <= 0)
 	{
-		free(tlsin);
-		free(tlsout);
+		sm_free(tlsin);
+		sm_free(tlsout);
 		return -1;
 	}
 	if (sfdisc(fin, (Sfdisc_t *) tlsin) != (Sfdisc_t *) tlsin ||
 	    sfdisc(fout, (Sfdisc_t *) tlsout) != (Sfdisc_t *) tlsout)
 	{
-		free(tlsin);
-		free(tlsout);
+		sm_free(tlsin);
+		sm_free(tlsout);
 		return -1;
 	}
 # else /* SFIO */
@@ -379,7 +367,7 @@
 	fp = funopen(tlsin, tls_read, tls_write, NULL, tls_close);
 	if (fp == NULL)
 	{
-		free(tlsin);
+		sm_free(tlsin);
 		return -1;
 	}
 	*fin = fp;
@@ -396,7 +384,7 @@
 		tlsin->fp = NULL;
 		fclose(*fin);
 		*fin = save;
-		free(tlsout);
+		sm_free(tlsout);
 		return -1;
 	}
 	*fout = fp;
Index: gnu/usr.sbin/sendmail/sendmail/srvrsmtp.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/srvrsmtp.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/sendmail/srvrsmtp.c	2001/02/28 02:43:55	1.4
+++ gnu/usr.sbin/sendmail/sendmail/srvrsmtp.c	2001/05/29 01:31:16	1.5
@@ -16,9 +16,9 @@
 
 #ifndef lint
 # if SMTP
-static char id[] = "@(#)$Sendmail: srvrsmtp.c,v 8.471.2.2.2.67 2001/01/07 19:31:05 gshapiro Exp $ (with SMTP)";
+static char id[] = "@(#)$Sendmail: srvrsmtp.c,v 8.471.2.2.2.77 2001/05/27 22:20:30 gshapiro Exp $ (with SMTP)";
 # else /* SMTP */
-static char id[] = "@(#)$Sendmail: srvrsmtp.c,v 8.471.2.2.2.67 2001/01/07 19:31:05 gshapiro Exp $ (without SMTP)";
+static char id[] = "@(#)$Sendmail: srvrsmtp.c,v 8.471.2.2.2.77 2001/05/27 22:20:30 gshapiro Exp $ (without SMTP)";
 # endif /* SMTP */
 #endif /* ! lint */
 
@@ -44,7 +44,7 @@
 #  if !TLS_NO_RSA
 static RSA	*rsa = NULL;
 #  endif /* !TLS_NO_RSA */
-static bool	tls_ok = FALSE;
+static bool	tls_ok_srv = FALSE;
 static int	tls_verify_cb __P((X509_STORE_CTX *));
 #  if !TLS_NO_RSA
 #   define RSA_KEYLENGTH	512
@@ -966,7 +966,7 @@
 				message("503 5.5.0 TLS not available");
 				break;
 			}
-			if (!tls_ok)
+			if (!tls_ok_srv)
 			{
 				message("454 4.3.3 TLS not available after start");
 				break;
@@ -1038,7 +1038,7 @@
 					if (LogLevel > 9)
 						tlslogerr();
 				}
-				tls_ok = FALSE;
+				tls_ok_srv = FALSE;
 				SSL_free(srv_ssl);
 				srv_ssl = NULL;
 
@@ -1080,7 +1080,7 @@
 			QuickAbort = saveQuickAbort;
 			SuprErrs = saveSuprErrs;
 
-			tls_ok = FALSE;	/* don't offer STARTTLS again */
+			tls_ok_srv = FALSE;	/* don't offer STARTTLS again */
 			gothello = FALSE;	/* discard info */
 			n_helo = 0;
 			OneXact = TRUE;	/* only one xaction this run */
@@ -1100,7 +1100,7 @@
 					sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL,
 							       &ext_ssf) == SASL_OK;
 					if (mechlist != NULL)
-						free(mechlist);
+						sm_free(mechlist);
 					mechlist = NULL;
 					if (sasl_ok)
 					{
@@ -1301,7 +1301,7 @@
 				message("250-AUTH %s", mechlist);
 # endif /* SASL */
 # if STARTTLS
-			if (tls_ok && usetls)
+			if (tls_ok_srv && usetls)
 				message("250-STARTTLS");
 # endif /* STARTTLS */
 			message("250 HELP");
@@ -1525,7 +1525,8 @@
 				goto undo_subproc_no_pm;
 
 			if (MaxMessageSize > 0 &&
-			   (e->e_msgsize > MaxMessageSize || e->e_msgsize < 0))
+			    (e->e_msgsize > MaxMessageSize ||
+			     e->e_msgsize < 0))
 			{
 				usrerr("552 5.2.3 Message size exceeds fixed maximum message size (%ld)",
 					MaxMessageSize);
@@ -1567,7 +1568,7 @@
 					break;
 				}
 				if (response != NULL)
-					free(response);
+					sm_free(response);
 			}
 # endif /* _FFR_MILTER */
 			if (Errors > 0)
@@ -1745,7 +1746,7 @@
 					break;
 				}
 				if (response != NULL)
-					free(response);
+					sm_free(response);
 			}
 # endif /* _FFR_MILTER */
 
@@ -1847,7 +1848,7 @@
 					break;
 				}
 				if (response != NULL)
-					free(response);
+					sm_free(response);
 			}
 
 			/* abort message filters that didn't get the body */
@@ -1858,7 +1859,7 @@
 			/* redefine message size */
 			if ((q = macvalue(macid("{msg_size}", NULL), e))
 			    != NULL)
-				free(q);
+				sm_free(q);
 			snprintf(inp, sizeof inp, "%ld", e->e_msgsize);
 			define(macid("{msg_size}", NULL), newstr(inp), e);
 			if (Errors > 0)
@@ -2163,16 +2164,12 @@
 			else
 				*--id = '@';
 
-			if ((new = (QUEUE_CHAR *)malloc(sizeof(QUEUE_CHAR))) == NULL)
-			{
-				syserr("500 5.5.0 ETRN out of memory");
-				break;
-			}
+			new = (QUEUE_CHAR *)xalloc(sizeof(QUEUE_CHAR));
 			new->queue_match = id;
 			new->queue_next = NULL;
 			QueueLimitRecipient = new;
 			ok = runqueue(TRUE, FALSE);
-			free(QueueLimitRecipient);
+			sm_free(QueueLimitRecipient);
 			QueueLimitRecipient = NULL;
 			if (ok && Errors == 0)
 				message("250 2.0.0 Queuing for node %s started", p);
@@ -2357,8 +2354,8 @@
 		if (*pcounter == maxcount && LogLevel > 5)
 		{
 			sm_syslog(LOG_INFO, e->e_id,
-				  "%.100s: %.40s attack?",
-				  CurSmtpClient, cname);
+				  "%.100s: possible SMTP attack: command=%.40s, count=%d",
+				  CurSmtpClient, cname, *pcounter);
 		}
 		s = 1 << (*pcounter - maxcount);
 		if (s >= MAXTIMEOUT)
@@ -2604,7 +2601,8 @@
 				dprintf("auth=\"%.100s\" trusted\n", pbuf);
 			e->e_auth_param = newstr(auth_param);
 		}
-		free(auth_param);
+		sm_free(auth_param);
+
 		/* reset values */
 		Errors = 0;
 		QuickAbort = saveQuickAbort;
@@ -2848,6 +2846,12 @@
 			/* child */
 			InChild = TRUE;
 			QuickAbort = FALSE;
+
+			/* Reset global flags */
+			RestartRequest = NULL;
+			ShutdownRequest = NULL;
+			PendingSignal = 0;
+
 			clearstats();
 			clearenvelope(e, FALSE);
 			assign_queueid(e);
@@ -2992,7 +2996,6 @@
 {
 # ifndef HASURANDOMDEV
 	/* not required if /dev/urandom exists, OpenSSL does it internally */
-
 #define RF_OK		0	/* randfile OK */
 #define RF_MISS		1	/* randfile == NULL || *randfile == '\0' */
 #define RF_UNKNOWN	2	/* unknown prefix for randfile */
@@ -3017,7 +3020,7 @@
 	ok = FALSE;
 	done = RI_FAIL;
 	randdef = (randfile == NULL || *randfile == '\0') ? RF_MISS : RF_OK;
-#   if EGD
+#    if EGD
 	if (randdef == RF_OK && strncasecmp(randfile, "egd:", 4) == 0)
 	{
 		randfile += 4;
@@ -3031,7 +3034,7 @@
 			ok = TRUE;
 	}
 	else
-#   endif /* EGD */
+#    endif /* EGD */
 	if (randdef == RF_OK && strncasecmp(randfile, "file:", 5) == 0)
 	{
 		int fd;
@@ -3288,7 +3291,39 @@
 		else if (req) \
 			ok = FALSE;	\
 	}
+/*
+**  INIT_TLS_LIBRARY -- calls functions which setup TLS library for global use
+**
+**	Parameters:
+**		none.
+**
+**	Returns:
+**		succeeded?
+**
+**	Side Effects:
+**		Sets tls_ok_srv static, even when called from main()
+*/
+
+bool
+init_tls_library()
+{
+	/*
+	**  basic TLS initialization
+	**  ignore result for now
+	*/
+
+	SSL_library_init();
+	SSL_load_error_strings();
+# if 0
+	/* this is currently a macro for SSL_library_init */
+	SSLeay_add_ssl_algorithms();
+# endif /* 0 */
+
+	/* initialize PRNG */
+	tls_ok_srv = tls_rand_init(RandFile, 7);
 
+	return tls_ok_srv;
+}
 /*
 **  INITTLS -- initialize TLS
 **
@@ -3471,6 +3506,8 @@
 			if (LogLevel > 7)
 				sm_syslog(LOG_WARNING, NOQID,
 					  "TLS: error: SSL_CTX_new(SSLv23_server_method()) failed");
+			if (LogLevel > 9)
+				tlslogerr();
 			return FALSE;
 		}
 	}
@@ -3481,6 +3518,8 @@
 			if (LogLevel > 7)
 				sm_syslog(LOG_WARNING, NOQID,
 					  "TLS: error: SSL_CTX_new(SSLv23_client_method()) failed");
+			if (LogLevel > 9)
+				tlslogerr();
 			return FALSE;
 		}
 	}
@@ -3802,15 +3841,18 @@
 **
 **	Returns:
 **		succeeded?
+**
+**	Side Effects:
+**		sets tls_ok_srv static, even when called from main()
 */
 
 bool
 initsrvtls()
 {
 
-	tls_ok = inittls(&srv_ctx, TLS_I_SRV, TRUE, SrvCERTfile, Srvkeyfile,
-			 CACERTpath, CACERTfile, DHParams);
-	return tls_ok;
+	tls_ok_srv = inittls(&srv_ctx, TLS_I_SRV, TRUE, SrvCERTfile,
+			     Srvkeyfile, CACERTpath, CACERTfile, DHParams);
+	return tls_ok_srv;
 }
 /*
 **  TLS_GET_INFO -- get information about TLS connection
Index: gnu/usr.sbin/sendmail/sendmail/stab.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/stab.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- gnu/usr.sbin/sendmail/sendmail/stab.c	2001/01/15 21:09:10	1.3
+++ gnu/usr.sbin/sendmail/sendmail/stab.c	2001/05/29 01:31:16	1.4
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
  * Copyright (c) 1988, 1993
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: stab.c,v 8.40.16.3 2000/10/09 02:46:12 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: stab.c,v 8.40.16.7 2001/05/07 22:06:41 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -160,8 +160,8 @@
 		break;
 
 #ifdef LDAPMAP
-	  case ST_LDAP:
-		len = sizeof s->s_ldap;
+	  case ST_LMAP:
+		len = sizeof s->s_lmap;
 		break;
 #endif /* LDAPMAP */
 
Index: gnu/usr.sbin/sendmail/sendmail/udb.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/udb.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- gnu/usr.sbin/sendmail/sendmail/udb.c	2001/02/28 02:43:55	1.3
+++ gnu/usr.sbin/sendmail/sendmail/udb.c	2001/05/29 01:31:16	1.4
@@ -15,9 +15,9 @@
 
 #ifndef lint
 # if USERDB
-static char id[] = "@(#)$Sendmail: udb.c,v 8.111.16.1 2001/01/04 18:18:37 gshapiro Exp $ (with USERDB)";
+static char id[] = "@(#)$Sendmail: udb.c,v 8.111.16.2 2001/05/03 17:24:17 gshapiro Exp $ (with USERDB)";
 # else /* USERDB */
-static char id[] = "@(#)$Sendmail: udb.c,v 8.111.16.1 2001/01/04 18:18:37 gshapiro Exp $ (without USERDB)";
+static char id[] = "@(#)$Sendmail: udb.c,v 8.111.16.2 2001/05/03 17:24:17 gshapiro Exp $ (without USERDB)";
 # endif /* USERDB */
 #endif /* ! lint */
 
@@ -290,7 +290,7 @@
 
 					memmove(nuser, user, usersize);
 					if (user != userbuf)
-						free(user);
+						sm_free(user);
 					user = nuser;
 					usersize += size;
 					userleft += size;
@@ -545,7 +545,7 @@
 			break;
 		}
 		if (user != userbuf)
-			free(user);
+			sm_free(user);
 	}
 	return EX_OK;
 }
@@ -1055,11 +1055,11 @@
 							  errstring(errno));
 					up->udb_type = UDB_EOLIST;
 					if (up->udb_dbname != spec)
-						free(up->udb_dbname);
+						sm_free(up->udb_dbname);
 					goto tempfail;
 				}
 				if (up->udb_dbname != spec)
-					free(up->udb_dbname);
+					sm_free(up->udb_dbname);
 				break;
 			}
 			if (tTd(28, 1))
Index: gnu/usr.sbin/sendmail/sendmail/usersmtp.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/usersmtp.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/sendmail/usersmtp.c	2001/02/28 02:43:55	1.4
+++ gnu/usr.sbin/sendmail/sendmail/usersmtp.c	2001/05/29 01:31:16	1.5
@@ -15,9 +15,9 @@
 
 #ifndef lint
 # if SMTP
-static char id[] = "@(#)$Sendmail: usersmtp.c,v 8.245.4.24 2001/02/21 00:59:09 gshapiro Exp $ (with SMTP)";
+static char id[] = "@(#)$Sendmail: usersmtp.c,v 8.245.4.33 2001/05/23 18:53:09 ca Exp $ (with SMTP)";
 # else /* SMTP */
-static char id[] = "@(#)$Sendmail: usersmtp.c,v 8.245.4.24 2001/02/21 00:59:09 gshapiro Exp $ (without SMTP)";
+static char id[] = "@(#)$Sendmail: usersmtp.c,v 8.245.4.33 2001/05/23 18:53:09 ca Exp $ (without SMTP)";
 # endif /* SMTP */
 #endif /* ! lint */
 
@@ -199,7 +199,8 @@
 	{
 		syserr("553 5.3.5 %s config error: mail loops back to me (MX problem?)",
 			CurHostName);
-		mci_setstat(mci, EX_CONFIG, "5.3.5", "system config error");
+		mci_setstat(mci, EX_CONFIG, "5.3.5",
+			    "553 5.3.5 system config error");
 		mci->mci_errno = 0;
 		smtpquit(m, mci, e);
 		return;
@@ -303,15 +304,9 @@
 	l1 = strlen(s1);
 	l2 = strlen(s2);
 	rl = l1 + l2;
-	res = (char *)malloc(rl + 2);
-	if (res == NULL)
-	{
-		if (l1 > l2)
-			return s1;
-		return s2;
-	}
+	res = (char *)xalloc(rl + 2);
 	(void) strlcpy(res, s1, rl);
-	hr = res;
+	hr = res + l1;
 	h1 = s2;
 	h = s2;
 
@@ -374,7 +369,7 @@
 	{
 # if SASL
 		if (mci->mci_saslcap != NULL)
-			free(mci->mci_saslcap);
+			sm_free(mci->mci_saslcap);
 		mci->mci_saslcap = NULL;
 # endif /* SASL */
 		return;
@@ -424,7 +419,7 @@
 				h = mci->mci_saslcap;
 				mci->mci_saslcap = str_union(h, p);
 				if (h != mci->mci_saslcap)
-					free(h);
+					sm_free(h);
 				mci->mci_flags |= MCIF_AUTH;
 			}
 			else
@@ -432,14 +427,9 @@
 				int l;
 
 				l = strlen(p) + 1;
-				mci->mci_saslcap = (char *)malloc(l);
-
-				/* XXX this may be leaked */
-				if (mci->mci_saslcap != NULL)
-				{
-					(void) strlcpy(mci->mci_saslcap, p, l);
-					mci->mci_flags |= MCIF_AUTH;
-				}
+				mci->mci_saslcap = (char *)xalloc(l);
+				(void) strlcpy(mci->mci_saslcap, p, l);
+				mci->mci_flags |= MCIF_AUTH;
 			}
 		}
 	}
@@ -501,7 +491,7 @@
 	{
 		if (mci->mci_sasl_string_len <= len)
 		{
-			free(mci->mci_sasl_string);
+			sm_free(mci->mci_sasl_string);
 			mci->mci_sasl_string = xalloc(len + 1);
 		}
 	}
@@ -511,7 +501,7 @@
 	memcpy(mci->mci_sasl_string, out, len);
 	mci->mci_sasl_string[len] = '\0';
 	mci->mci_sasl_string_len = len;
-	free(out);
+	sm_free(out);
 	return;
 }
 
@@ -728,7 +718,8 @@
 			**  workaround: don't free() it here
 			**  this can cause a memory leak!
 			*/
-			free(authid);
+
+			sm_free(authid);
 #  endif /* SASL > 10522 */
 			authid = NULL;
 			addedrealm = addrealm;
@@ -804,9 +795,7 @@
 		authpass = newstr(h);
 	}
 	len = strlen(authpass);
-	*psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len + 1);
-	if (*psecret == NULL)
-		return SASL_FAIL;
+	*psecret = (sasl_secret_t *) xalloc(sizeof(sasl_secret_t) + len + 1);
 	(void) strlcpy((*psecret)->data, authpass, len + 1);
 	(*psecret)->len = len;
 	return SASL_OK;
@@ -1057,9 +1046,7 @@
 	l1 = strlen(s1);
 	l2 = strlen(s2);
 	rl = min(l1, l2);
-	res = (char *)malloc(rl + 1);
-	if (res == NULL)
-		return NULL;
+	res = (char *)xalloc(rl + 1);
 	*res = '\0';
 	if (rl == 0)	/* at least one string empty? */
 		return res;
@@ -1751,6 +1738,7 @@
 */
 
 static jmp_buf	CtxDataTimeout;
+static EVENT	*volatile DataTimeout = NULL;
 
 int
 smtpdata(m, mci, e)
@@ -1759,13 +1747,13 @@
 	register ENVELOPE *e;
 {
 	register int r;
-	register EVENT *ev;
 	int rstat;
 	int xstat;
 	time_t timeout;
 	char *enhsc;
 
 	enhsc = NULL;
+
 	/*
 	**  Send the data.
 	**	First send the command and check that it is ok.
@@ -1840,27 +1828,29 @@
 	else
 		timeout = DATA_PROGRESS_TIMEOUT;
 
-	ev = setevent(timeout, datatimeout, 0);
+	DataTimeout = setevent(timeout, datatimeout, 0);
 
 
-	if (tTd(18, 101))
-	{
-		/* simulate a DATA timeout */
-		(void) sleep(1);
-	}
-
 	/*
 	**  Output the actual message.
 	*/
 
 	(*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER);
+
+	if (tTd(18, 101))
+	{
+		/* simulate a DATA timeout */
+		(void) sleep(2);
+	}
+
 	(*e->e_putbody)(mci, e, NULL);
 
 	/*
 	**  Cleanup after sending message.
 	*/
 
-	clrevent(ev);
+	if (DataTimeout != NULL)
+		clrevent(DataTimeout);
 
 # if _FFR_CATCH_BROKEN_MTAS
 	{
@@ -1938,7 +1928,7 @@
 	mci_setstat(mci, xstat, ENHSCN(enhsc, smtptodsn(r)),
 		    SmtpReplyBuffer);
 	if (e->e_statmsg != NULL)
-		free(e->e_statmsg);
+		sm_free(e->e_statmsg);
 	if (bitset(MCIF_ENHSTAT, mci->mci_flags) &&
 	    (r = isenhsc(SmtpReplyBuffer + 4, ' ')) > 0)
 		r += 5;
@@ -1963,10 +1953,17 @@
 static void
 datatimeout()
 {
+	int save_errno = errno;
+
+	/*
+	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+	**	DOING.
+	*/
+
 	if (DataProgress)
 	{
 		time_t timeout;
-		register EVENT *ev;
 
 		/* check back again later */
 		if (tTd(18, 101))
@@ -1977,14 +1974,24 @@
 		else
 			timeout = DATA_PROGRESS_TIMEOUT;
 
+		/* reset the timeout */
+		DataTimeout = sigsafe_setevent(timeout, datatimeout, 0);
 		DataProgress = FALSE;
-		ev = setevent(timeout, datatimeout, 0);
 	}
 	else
 	{
-		/* no progress, give up */
+		/* event is done */
+		DataTimeout = NULL;
+	}
+
+	/* if no progress was made or problem resetting event, die now */
+	if (DataTimeout == NULL)
+	{
+		errno = ETIMEDOUT;
 		longjmp(CtxDataTimeout, 1);
 	}
+
+	errno = save_errno;
 }
 /*
 **  SMTPGETSTAT -- get status code from DATA in LMTP
@@ -2027,7 +2034,7 @@
 	else
 		status = EX_PROTOCOL;
 	if (e->e_statmsg != NULL)
-		free(e->e_statmsg);
+		sm_free(e->e_statmsg);
 	if (bitset(MCIF_ENHSTAT, mci->mci_flags) &&
 	    (r = isenhsc(SmtpReplyBuffer + 4, ' ')) > 0)
 		r += 5;
Index: gnu/usr.sbin/sendmail/sendmail/util.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/util.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/sendmail/util.c	2001/02/28 02:43:55	1.4
+++ gnu/usr.sbin/sendmail/sendmail/util.c	2001/05/29 01:31:16	1.5
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: util.c,v 8.225.2.1.2.19 2001/02/22 18:56:24 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: util.c,v 8.225.2.1.2.23 2001/05/17 18:10:18 gshapiro Exp $";
 #endif /* ! lint */
 
 #include <sendmail.h>
@@ -378,15 +378,122 @@
 	if (sz <= 0)
 		sz = 1;
 
+	ENTER_CRITICAL();
 	p = malloc((unsigned) sz);
+	LEAVE_CRITICAL();
 	if (p == NULL)
 	{
 		syserr("!Out of memory!!");
-		/* exit(EX_UNAVAILABLE); */
+
+		/* NOTREACHED */
+		exit(EX_UNAVAILABLE);
+	}
+	return p;
+}
+/*
+**  XREALLOC -- Reallocate 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:
+**		ptr -- original area.
+**		sz -- size of new area to allocate.
+**
+**	Returns:
+**		pointer to data region.
+**
+**	Side Effects:
+**		Memory is allocated.
+*/
+
+char *
+xrealloc(ptr, sz)
+	void *ptr;
+	size_t sz;
+{
+	register char *p;
+
+	/* some systems can't handle size zero mallocs */
+	if (sz <= 0)
+		sz = 1;
+
+	ENTER_CRITICAL();
+	p = realloc(ptr, (unsigned) sz);
+	LEAVE_CRITICAL();
+	if (p == NULL)
+	{
+		syserr("!Out of memory!!");
+
+		/* NOTREACHED */
+		exit(EX_UNAVAILABLE);
 	}
 	return p;
 }
 /*
+**  XCALLOC -- 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:
+**		num -- number of items to allocate
+**		sz -- size of new area to allocate.
+**
+**	Returns:
+**		pointer to data region.
+**
+**	Side Effects:
+**		Memory is allocated.
+*/
+
+char *
+xcalloc(num, sz)
+	size_t num;
+	size_t sz;
+{
+	register char *p;
+
+	/* some systems can't handle size zero mallocs */
+	if (num <= 0)
+		num = 1;
+	if (sz <= 0)
+		sz = 1;
+
+	ENTER_CRITICAL();
+	p = calloc((unsigned) num, (unsigned) sz);
+	LEAVE_CRITICAL();
+	if (p == NULL)
+	{
+		syserr("!Out of memory!!");
+
+		/* NOTREACHED */
+		exit(EX_UNAVAILABLE);
+	}
+	return p;
+}
+/*
+**  SM_FREE -- Free memory safely.
+**
+**	Parameters:
+**		ptr -- area to free
+**
+**	Returns:
+**		none.
+**
+**	Side Effects:
+**		Memory is freed.
+*/
+
+void
+sm_free(ptr)
+	void *ptr;
+{
+	ENTER_CRITICAL();
+	free(ptr);
+	LEAVE_CRITICAL();
+}
+/*
 **  COPYPLIST -- copy list of pointers.
 **
 **	This routine is the equivalent of newstr for lists of
@@ -502,13 +609,13 @@
 	}
 	else
 	{
-		long pid;
+		pid_t pid;
 		extern char *CommandLineArgs;
 
-		pid = (long) getpid();
+		pid = getpid();
 
 		/* write the process id on line 1 */
-		fprintf(pidf, "%ld\n", pid);
+		fprintf(pidf, "%ld\n", (long) pid);
 
 		/* line 2 contains all command line flags */
 		fprintf(pidf, "%s\n", CommandLineArgs);
@@ -1212,6 +1319,13 @@
 readtimeout(timeout)
 	time_t timeout;
 {
+	/*
+	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+	**	DOING.
+	*/
+
+	errno = ETIMEDOUT;
 	longjmp(CtxReadTimeout, 1);
 }
 /*
@@ -1271,7 +1385,7 @@
 			memmove(nbp, bp, p - bp);
 			p = &nbp[p - bp];
 			if (bp != buf)
-				free(bp);
+				sm_free(bp);
 			bp = nbp;
 			n = nn - (p - bp);
 		}
@@ -1836,13 +1950,13 @@
 **		pid of the process -- -1 if it failed.
 */
 
-int
+pid_t
 prog_open(argv, pfd, e)
 	char **argv;
 	int *pfd;
 	ENVELOPE *e;
 {
-	int pid;
+	pid_t pid;
 	int i;
 	int save_errno;
 	int fdv[2];
@@ -1874,6 +1988,11 @@
 	/* child -- close stdin */
 	(void) close(0);
 
+	/* Reset global flags */
+	RestartRequest = NULL;
+	ShutdownRequest = NULL;
+	PendingSignal = 0;
+
 	/* stdout goes back to parent */
 	(void) close(fdv[0]);
 	if (dup2(fdv[1], 1) < 0)
@@ -2119,7 +2238,7 @@
 	{
 		/* allocate more space */
 		if (bp != NULL)
-			free(bp);
+			sm_free(bp);
 		bp = xalloc(l);
 		bl = l;
 	}
@@ -2199,7 +2318,7 @@
 **		none
 */
 
-static struct procs	*ProcListVec = NULL;
+static struct procs	*volatile ProcListVec = NULL;
 static int		ProcListSize = 0;
 
 void
@@ -2238,7 +2357,7 @@
 		{
 			memmove(npv, ProcListVec,
 				ProcListSize * sizeof (struct procs));
-			free(ProcListVec);
+			sm_free(ProcListVec);
 		}
 		for (i = ProcListSize; i < ProcListSize + PROC_LIST_SEG; i++)
 		{
@@ -2252,7 +2371,7 @@
 	}
 	ProcListVec[i].proc_pid = pid;
 	if (ProcListVec[i].proc_task != NULL)
-		free(ProcListVec[i].proc_task);
+		sm_free(ProcListVec[i].proc_task);
 	ProcListVec[i].proc_task = newstr(task);
 	ProcListVec[i].proc_type = type;
 
@@ -2283,7 +2402,7 @@
 		if (ProcListVec[i].proc_pid == pid)
 		{
 			if (ProcListVec[i].proc_task != NULL)
-				free(ProcListVec[i].proc_task);
+				sm_free(ProcListVec[i].proc_task);
 			ProcListVec[i].proc_task = newstr(task);
 			break;
 		}
@@ -2297,6 +2416,10 @@
 **
 **	Returns:
 **		type of process
+**
+**	NOTE:	THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
+**		ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+**		DOING.
 */
 
 int
Index: gnu/usr.sbin/sendmail/sendmail/version.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/sendmail/version.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/sendmail/version.c	2001/02/28 02:43:55	1.4
+++ gnu/usr.sbin/sendmail/sendmail/version.c	2001/05/29 01:31:16	1.5
@@ -12,7 +12,7 @@
  */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: version.c,v 8.43.4.30 2001/02/27 19:22:31 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: version.c,v 8.43.4.33 2001/05/27 21:39:21 gshapiro Exp $";
 #endif /* ! lint */
 
-char	Version[] = "8.11.3";
+char	Version[] = "8.11.4";
Index: gnu/usr.sbin/sendmail/smrsh/smrsh.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/smrsh/smrsh.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/smrsh/smrsh.c	2001/02/28 02:43:56	1.4
+++ gnu/usr.sbin/sendmail/smrsh/smrsh.c	2001/05/29 01:31:17	1.5
@@ -21,7 +21,7 @@
 #endif /* ! lint */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: smrsh.c,v 8.31.4.8 2001/01/22 19:00:26 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: smrsh.c,v 8.31.4.9 2001/04/24 04:11:51 ca Exp $";
 #endif /* ! lint */
 
 /*
@@ -173,7 +173,6 @@
 	*/
 
 	prg = argv[0];
-	par = argv[2];
 
 	if (argc != 3 || strcmp(argv[1], "-c") != 0)
 	{
@@ -183,6 +182,8 @@
 #endif /* ! DEBUG */
 		exit(EX_USAGE);
 	}
+
+	par = argv[2];
 
 	/*
 	**  Disallow special shell syntax.  This is overly restrictive,
Index: gnu/usr.sbin/sendmail/vacation/vacation.c
===================================================================
RCS file: /cvs/src/gnu/usr.sbin/sendmail/vacation/vacation.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- gnu/usr.sbin/sendmail/vacation/vacation.c	2001/02/28 02:43:56	1.4
+++ gnu/usr.sbin/sendmail/vacation/vacation.c	2001/05/29 01:31:17	1.5
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  * Copyright (c) 1983, 1987, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -13,7 +13,7 @@
 
 #ifndef lint
 static char copyright[] =
-"@(#) Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers.\n\
+"@(#) Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.\n\
 	All rights reserved.\n\
      Copyright (c) 1983, 1987, 1993\n\
 	The Regents of the University of California.  All rights reserved.\n\
@@ -21,9 +21,10 @@
 #endif /* ! lint */
 
 #ifndef lint
-static char id[] = "@(#)$Sendmail: vacation.c,v 8.68.4.16 2001/02/14 05:02:21 gshapiro Exp $";
+static char id[] = "@(#)$Sendmail: vacation.c,v 8.68.4.21 2001/05/07 22:06:41 gshapiro Exp $";
 #endif /* ! lint */
 
+
 #include <ctype.h>
 #include <stdlib.h>
 #include <syslog.h>
@@ -113,12 +114,16 @@
 				eatmsg(); \
 				return excode; \
 			}
+
 int
 main(argc, argv)
 	int argc;
 	char **argv;
 {
 	bool iflag, emptysender, exclude;
+#if _FFR_BLACKBOX
+	bool runasuser = FALSE;
+#endif /* _FFR_BLACKBOX */
 #if _FFR_LISTDB
 	bool lflag = FALSE;
 #endif /* _FFR_LISTDB */
@@ -129,8 +134,8 @@
 	time_t interval;
 	struct passwd *pw;
 	ALIAS *cur;
-	char *dbfilename = VDB;
-	char *msgfilename = VMSG;
+	char *dbfilename = NULL;
+	char *msgfilename = NULL;
 	char *name;
 	SMDB_USER_INFO user_info;
 	static char rnamebuf[MAXNAME];
@@ -173,11 +178,11 @@
 			 "Unknown UID %d", (int) RealUid);
 	RunAsUserName = RealUserName = rnamebuf;
 
-#ifdef LOG_MAIL
+# ifdef LOG_MAIL
 	openlog("vacation", LOG_PID, LOG_MAIL);
-#else /* LOG_MAIL */
+# else /* LOG_MAIL */
 	openlog("vacation", LOG_PID);
-#endif /* LOG_MAIL */
+# endif /* LOG_MAIL */
 
 	opterr = 0;
 	iflag = FALSE;
@@ -186,19 +191,7 @@
 	interval = INTERVAL_UNDEF;
 	*From = '\0';
 
-#if _FFR_DEBUG && _FFR_LISTDB
-# define OPTIONS		"a:df:Iilm:r:s:t:xz"
-#else /* _FFR_DEBUG && _FFR_LISTDB */
-# if _FFR_DEBUG
-#  define OPTIONS		"a:df:Iim:r:s:t:xz"
-# else /* _FFR_DEBUG */
-#  if _FFR_LISTDB
-#   define OPTIONS		"a:f:Iilm:r:s:t:xz"
-#  else /* _FFR_LISTDB */
-#   define OPTIONS		"a:f:Iim:r:s:t:xz"
-#  endif /* _FFR_LISTDB */
-# endif /* _FFR_DEBUG */
-#endif /* _FFR_DEBUG && _FFR_LISTDB */
+#define OPTIONS		"a:df:Iilm:r:s:t:Uxz"
 
 	while (mfail == 0 && ufail == 0 &&
 	       (ch = getopt(argc, argv, OPTIONS)) != -1)
@@ -218,12 +211,11 @@
 			break;
 
 #if _FFR_DEBUG
-		case 'd':			/* debug mode */
+		  case 'd':			/* debug mode */
 			msglog = &debuglog;
 			break;
 #endif /* _FFR_DEBUG */
 
-
 		  case 'f':		/* alternate database */
 			dbfilename = optarg;
 			break;
@@ -261,6 +253,12 @@
 		  case 't':		/* SunOS: -t1d (default expire) */
 			break;
 
+#if _FFR_BLACKBOX
+		  case 'U':		/* run as single user mode */
+			runasuser = TRUE;
+			break;
+#endif /* _FFR_BLACKBOX */
+
 		  case 'x':
 			exclude = TRUE;
 			break;
@@ -301,34 +299,67 @@
 			       "vacation: no such user uid %u.\n", getuid());
 			EXITM(EX_NOUSER);
 		}
+		name = pw->pw_name;
+		user_info.smdbu_id = pw->pw_uid;
+		user_info.smdbu_group_id = pw->pw_gid;
+		(void) strlcpy(user_info.smdbu_name, pw->pw_name,
+			       SMDB_MAX_USER_NAME_LEN);
+		if (chdir(pw->pw_dir) != 0)
+		{
+			msglog(LOG_NOTICE, "vacation: no such directory %s.\n",
+			       pw->pw_dir);
+			EXITM(EX_NOINPUT);
+		}
 	}
 #if _FFR_BLACKBOX
-	name = *argv;
-#else /* _FFR_BLACKBOX */
+	else if (runasuser)
+	{
+		name = *argv;
+		if (dbfilename == NULL || msgfilename == NULL)
+		{
+			msglog(LOG_NOTICE,
+			       "vacation: -U requires setting both -f and -m\n");
+			EXITM(EX_NOINPUT);
+		}
+		user_info.smdbu_id = pw->pw_uid;
+		user_info.smdbu_group_id = pw->pw_gid;
+		(void) strlcpy(user_info.smdbu_name, pw->pw_name,
+			       SMDB_MAX_USER_NAME_LEN);
+	}
+#endif /* _FFR_BLACKBOX */
 	else if ((pw = getpwnam(*argv)) == NULL)
 	{
 		msglog(LOG_ERR, "vacation: no such user %s.\n", *argv);
 		EXITM(EX_NOUSER);
 	}
-	name = pw->pw_name;
-	if (chdir(pw->pw_dir) != 0)
+	else
 	{
-		msglog(LOG_NOTICE,
-		       "vacation: no such directory %s.\n", pw->pw_dir);
-		EXITM(EX_NOINPUT);
+		name = pw->pw_name;
+		if (chdir(pw->pw_dir) != 0)
+		{
+			msglog(LOG_NOTICE, "vacation: no such directory %s.\n",
+			       pw->pw_dir);
+			EXITM(EX_NOINPUT);
+		}
+		user_info.smdbu_id = pw->pw_uid;
+		user_info.smdbu_group_id = pw->pw_gid;
+		(void) strlcpy(user_info.smdbu_name, pw->pw_name,
+			       SMDB_MAX_USER_NAME_LEN);
 	}
-#endif /* _FFR_BLACKBOX */
-	user_info.smdbu_id = pw->pw_uid;
-	user_info.smdbu_group_id = pw->pw_gid;
-	(void) strlcpy(user_info.smdbu_name, pw->pw_name,
-		       SMDB_MAX_USER_NAME_LEN);
+
+	if (dbfilename == NULL)
+		dbfilename = VDB;
+	if (msgfilename == NULL)
+		msgfilename = VMSG;
 
 	sff = SFF_CREAT;
 #if _FFR_BLACKBOX
 	if (getegid() != getgid())
+	{
+		/* Allow a set-group-id vacation binary */
 		RunAsGid = user_info.smdbu_group_id = getegid();
-
-	sff |= SFF_NOPATHCHECK|SFF_OPENASROOT;
+		sff |= SFF_NOPATHCHECK|SFF_OPENASROOT;
+	}
 #endif /* _FFR_BLACKBOX */
 
 	result = smdb_open_database(&Db, dbfilename,
@@ -407,6 +438,7 @@
 **		nothing.
 **
 */
+
 static void
 eatmsg()
 {
@@ -562,6 +594,7 @@
 **		is name a substring of str?
 **
 */
+
 bool
 nsearch(name, str)
 	register char *name, *str;
@@ -737,7 +770,6 @@
 				cur->len) == 0)
 			return TRUE;
 	}
-
 	return FALSE;
 }
 
@@ -754,6 +786,7 @@
 **		TRUE iff user has gotten a vacation message recently.
 **
 */
+
 bool
 recent()
 {
@@ -815,6 +848,7 @@
 **	Side Effects:
 **		stores the reply interval in database.
 */
+
 void
 setinterval(interval)
 	time_t interval;
@@ -845,6 +879,7 @@
 **	Side Effects:
 **		stores user/time in database.
 */
+
 void
 setreply(from, when)
 	char *from;
@@ -875,6 +910,7 @@
 **	Side Effects:
 **		stores users in database.
 */
+
 void
 xclude(f)
 	FILE *f;
@@ -906,6 +942,7 @@
 **	Side Effects:
 **		sends vacation reply.
 */
+
 void
 sendmessage(myname, msgfn, emptysender)
 	char *myname;
@@ -915,6 +952,7 @@
 	FILE *mfp, *sfp;
 	int i;
 	int pvect[2];
+	char *pv[8];
 	char buf[MAXLINE];
 
 	mfp = fopen(msgfn, "r");
@@ -932,6 +970,16 @@
 		msglog(LOG_ERR, "vacation: pipe: %s", errstring(errno));
 		exit(EX_OSERR);
 	}
+	pv[0] = "sendmail";
+	pv[1] = "-oi";
+	pv[2] = "-f";
+	if (emptysender)
+		pv[3] = "<>";
+	else
+		pv[3] = myname;
+	pv[4] = "--";
+	pv[5] = From;
+	pv[6] = NULL;
 	i = fork();
 	if (i < 0)
 	{
@@ -944,10 +992,7 @@
 		(void) close(pvect[0]);
 		(void) close(pvect[1]);
 		(void) fclose(mfp);
-		if (emptysender)
-			myname = "<>";
-		(void) execl(_PATH_SENDMAIL, "sendmail", "-oi",
-			     "-f", myname, "--", From, NULL);
+		(void) execv(_PATH_SENDMAIL, pv);
 		msglog(LOG_ERR, "vacation: can't exec %s: %s",
 			_PATH_SENDMAIL, errstring(errno));
 		exit(EX_UNAVAILABLE);
@@ -974,7 +1019,8 @@
 void
 usage()
 {
-	msglog(LOG_NOTICE, "uid %u: usage: vacation [-i] [-a alias]%s [-f db]%s [-m msg] [-r interval] [-s sender] [-t time] [-x] [-z] login\n",
+	msglog(LOG_NOTICE,
+	       "uid %u: usage: vacation [-a alias]%s [-f db] [-i]%s [-m msg] [-r interval] [-s sender] [-t time]%s [-x] [-z] login\n",
 	       getuid(),
 #if _FFR_DEBUG
 	       " [-d]",
@@ -982,10 +1028,15 @@
 	       "",
 #endif /* _FFR_DEBUG */
 #if _FFR_LISTDB
-	       " [-l]"
+	       " [-l]",
 #else /* _FFR_LISTDB */
-	       ""
+	       "",
 #endif /* _FFR_LISTDB */
+#if _FFR_BLACKBOX
+	       " [-U]"
+#else /* _FFR_BLACKBOX */
+	       ""
+#endif /* _FFR_BLACKBOX */
 	       );
 	exit(EX_USAGE);
 }
