Apply this patch to update an 8.6.2 sendmail to 8.6.3.

THIS IS A CRITICAL PATCH!  There were at least two bugs in 8.6.2 that
caused problems on some jobs; these certainly included core dumps and
duplicated mail delivery, and possibly lost mail.

*** RELEASE_NOTES.OLD	Sun Oct 17 12:01:28 1993
--- RELEASE_NOTES	Sun Oct 24 11:18:10 1993
***************
*** 1,3 ****
--- 1,79 ----
+ 8.6.3/8.6.3	93/10/24
+ 	IMPORTANT FIX: Fix several problems that caused open files to
+ 		be "lost" during queue runs; this overflowed the open
+ 		file table on large runs.  An assumption that fdopen
+ 		always succeeds sometimes resulted in core dumps when
+ 		this happens; sometimes the message is delivered twice,
+ 		sometimes (probably) infinite times.  This problem in
+ 		various form was reported by P{r (Pell) Emanuelsson and
+ 		Robert Campbell of U.C. Berkeley.
+ 	Special diagnosis of EMFILE error conditions -- it now prints
+ 		the known open file descriptors so you can figure out
+ 		what is consuming so much resources.
+ 	Fix a couple of problems caused by early address parsing
+ 		errors -- one caused it to return a "this is only a
+ 		warning" when it really wasn't, and the other started
+ 		parsing through a random pointer.  The first was
+ 		noted by Eric Wassenaar.
+ 	Fix an infinite loop problem caused by null components in the
+ 		host signature.  Problem noted by Jan Sorensen.
+ 	Be sure to reset the "current date" when sending an error
+ 		message -- PostMasterCopy messages were being sent
+ 		with an old Date: header.
+ 	Fix a problem that caused duplicated mail when sendmail was
+ 		(1) compiled without HASFLOCK, (2) you are sending to
+ 		an alias that has an owner-* alias, (3) you execute
+ 		sendmail with -t flag, (4) you run in -odb mode, and
+ 		(5) the sender specifies both the alias name and
+ 		another alias [i.e., the envelope is split], then
+ 		duplicate messages are sent.  The problem description
+ 		and one-line fix are from Motonori Nakamura of Kyoto
+ 		University.
+ 	Avoid a problem that causes error messages to be discarded
+ 		in some cases -- this was the result of a "fix" to
+ 		avoid duplicate error messages, but two are better
+ 		than zero.  Reported by Tim Rylance.
+ 	Fix a minor botch in checkfd012() -- fix from Dave Hill of
+ 		Computervision R&D Ltd.
+ 	Remove "X-Authentication-Warning: <user> set sender to <address>
+ 		using -f" entirely -- it is far too eager to include
+ 		this, and it is confusing folks.  I'll try to make it
+ 		work "right" in 8.7.  Problem noted by Yoshitaka
+ 		Tokugawa of dit Co., Ltd.
+ 	Fix a race condition with the errno value in tick() and
+ 		reapchild() -- this caused occasional misdiagnosis
+ 		of problems.  Kyle Jones of UUNET helped this along.
+ 	Repair rule loop-detection code.  From Michael Corrigan of
+ 		U.C. San Diego.
+ 	Fix a problem that caused sender domain addition (C mailer
+ 		flag to be ignored if you use -odq or use -odb with
+ 		a high load average.  Problem reported by Jim Murray
+ 		of Stratus.
+ 	Fix ident protocol on multi-homed machines.  It was not
+ 		always using the correct interface.  Fix from J.R.
+ 		Oldroyd of Opal.
+ 	Previously, sendmail assumed that any SMTP greeting message
+ 		that wasn't 2xx was a temporary failure -- it should
+ 		only take 4xx as a temporary failure, and return a
+ 		solid error message on anything else -- for example,
+ 		to allow you to reject connections on a workstation
+ 		that is MXed to a mail server.
+ 	Portability enhancements for 386BSD/FreeBSD/NetBSD from
+ 		Ollivier Robert.
+ 	CONFIG: FEATURE(always_add_domain) didn't always add the domain;
+ 		in particular, on local mail it modified the header sender
+ 		but not the header recipient address(es).  Reported by
+ 		Jeffrey Honig of Cornell University.  Also, strip
+ 		any host from envelope recipient address(es), since
+ 		local mailers don't understand host names -- this is
+ 		to help mailertable entries.  From Christopher Davis.
+ 	CONFIG: masquerading didn't apply to addresses that already
+ 		had a domain.  This change replaces a local hostname
+ 		by the masquerade name in the SMTP mailer (previously
+ 		it only added the masquerade name if it didn't already
+ 		have a domain name).  Several people complained about
+ 		this.
+ 
  8.6.2/8.6.2	93/10/15
  	Put a "successful delivery" message in the transcript for
  		addresses that get return-receipts.
*** KNOWNBUGS.OLD	Sat Oct 23 16:43:19 1993
--- KNOWNBUGS	Sun Oct 24 10:39:02 1993
***************
*** 1,7 ****
  
  
  	     K N O W N   B U G S   I N   S E N D M A I L
! 			     (for 8.6)
  
  
  The following are bugs or deficiencies in sendmail that I am aware of
--- 1,7 ----
  
  
  	     K N O W N   B U G S   I N   S E N D M A I L
! 			     (for 8.6.3)
  
  
  The following are bugs or deficiencies in sendmail that I am aware of
***************
*** 37,53 ****
    Sometimes identical, duplicate error messages can be generated.  As
    near as I can tell, this is rare and relatively innocuous.
  
  * If you EXPN a list or user that has a program mailer, the output of
    EXPN will include ``@local.host.name''.  You can't actually mail to
    this address.  It's not clear what the right behaviour is in this
    circumstance.
  
! * You can't use a ``mailer:relay.host'' for UUCP_RELAY or the relay
!   host in the SITECONFIG macro (the second argument) in the
!   configurations.  If the goal is to use ESMTP instead of SMTP,
!   define `confRELAY_MAILER' to `esmtp' and use no mailer name.  Note
!   that the default mailer used for relays (`relay') does use ESMTP
!   by default (it didn't in prior releases).  This problem does not
!   occur for other relays (BITNET or CSNET) or mailertable entries.
! 
! (Version 8.7, last updated 10/8/93)
--- 37,51 ----
    Sometimes identical, duplicate error messages can be generated.  As
    near as I can tell, this is rare and relatively innocuous.
  
+ * No "exposed users" in "nullrelay" configuration.
+ 
+   The "nullrelay" configuration hides all addresses behind the mail
+   hub name.  Some sites might prefer to expose some names such as
+   root.  This information is always available in Received: lines.
+ 
  * If you EXPN a list or user that has a program mailer, the output of
    EXPN will include ``@local.host.name''.  You can't actually mail to
    this address.  It's not clear what the right behaviour is in this
    circumstance.
  
! (Version 8.8, last updated 10/24/93)
*** src/Makefile.OSF1.OLD	Wed Oct 20 08:14:13 1993
--- src/Makefile.OSF1	Wed Oct 20 08:16:23 1993
***************
*** 47,53 ****
  OBJADD=
  
  # additional link flags
! LDADD=
  
  ###################  end of user configuration flags  ######################
  
--- 47,53 ----
  OBJADD=
  
  # additional link flags
! LDADD=	-non_shared
  
  ###################  end of user configuration flags  ######################
  
***************
*** 85,93 ****
  install-sendmail: sendmail
  	install -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} sendmail ${BINDIR}
  	for i in ${LINKS}; do rm -f $$i; ln -s ${BINDIR}/sendmail $$i; done
! 	install -c -o ${BINOWN} -g ${BINGRP} -m 666 /dev/null \
! 	    ${STDIR}/sendmail.st
! 	install -c -o ${BINOWN} -g ${BINGRP} -m 444 sendmail.hf ${HFDIR}
  
  # doesn't actually install them -- you may want to install pre-nroff versions
  install-docs: aliases.0 newaliases.0 sendmail.0
--- 85,94 ----
  install-sendmail: sendmail
  	install -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} sendmail ${BINDIR}
  	for i in ${LINKS}; do rm -f $$i; ln -s ${BINDIR}/sendmail $$i; done
! 	cp /dev/null ${STDIR}/sendmail.st
! 	chmod ${BINMOD}.${BINGRP} ${STDIR}/sendmail.st
! 	installbsd -c -o ${BINOWN} -g ${BINGRP} -m 444 sendmail.hf ${HFDIR}
! 	rm -f /usr/sbin/smtpd
  
  # doesn't actually install them -- you may want to install pre-nroff versions
  install-docs: aliases.0 newaliases.0 sendmail.0
*** src/READ_ME.OLD	Wed Oct 20 08:26:46 1993
--- src/READ_ME	Sun Oct 24 10:39:25 1993
***************
*** 30,36 ****
  # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  # SUCH DAMAGE.
  #
! #	@(#)READ_ME	8.29 (Berkeley) 10/15/93
  #
  
  This directory contains the source files for sendmail.
--- 30,36 ----
  # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  # SUCH DAMAGE.
  #
! #	@(#)READ_ME	8.30 (Berkeley) 10/24/93
  #
  
  This directory contains the source files for sendmail.
***************
*** 298,304 ****
  	patch.
  
  OSF/1
! 	If you are compiling on OSF/1 (DEC Alpha), you must use -lmld.
  
  NeXT
  	If you are compiling on NeXT, you will have to create an empty
--- 298,307 ----
  	patch.
  
  OSF/1
! 	If you are compiling on OSF/1 (DEC Alpha), you must use -lmld
! 	and -non_shared (otherwise it core dumps on startup).  Also,
! 	the enclosed makefile removed /usr/sbin/smtpd; if you need it,
! 	just create the link to the sendmail binary.
  
  NeXT
  	If you are compiling on NeXT, you will have to create an empty
***************
*** 480,483 ****
  
  Eric Allman
  
! (Version 8.29, last update 10/15/93 08:34:06)
--- 483,486 ----
  
  Eric Allman
  
! (Version 8.30, last update 10/24/93 10:39:02)
*** src/clock.c.OLD	Thu Oct 21 07:46:17 1993
--- src/clock.c	Thu Oct 21 12:28:19 1993
***************
*** 33,39 ****
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)clock.c	8.6 (Berkeley) 9/29/93";
  #endif /* not lint */
  
  # include "sendmail.h"
--- 33,39 ----
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)clock.c	8.7 (Berkeley) 10/21/93";
  #endif /* not lint */
  
  # include "sendmail.h"
***************
*** 166,171 ****
--- 166,172 ----
  	register time_t now;
  	register EVENT *ev;
  	int mypid = getpid();
+ 	int olderrno = errno;
  #ifdef SIG_UNBLOCK
  	sigset_t ss;
  #endif
***************
*** 221,226 ****
--- 222,228 ----
  #endif /* SIG_UNBLOCK */
  
  		/* call ev_func */
+ 		errno = olderrno;
  		(*f)(arg);
  		(void) alarm(0);
  		now = curtime();
***************
*** 228,233 ****
--- 230,236 ----
  	(void) setsignal(SIGALRM, tick);
  	if (EventQueue != NULL)
  		(void) alarm((unsigned) (EventQueue->ev_time - now));
+ 	errno = olderrno;
  }
  /*
  **  SLEEP -- a version of sleep that works with this stuff
*** src/conf.c.OLD	Thu Oct 21 07:50:21 1993
--- src/conf.c	Thu Oct 21 12:28:19 1993
***************
*** 33,39 ****
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)conf.c	8.41 (Berkeley) 10/15/93";
  #endif /* not lint */
  
  # include "sendmail.h"
--- 33,39 ----
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)conf.c	8.42 (Berkeley) 10/21/93";
  #endif /* not lint */
  
  # include "sendmail.h"
***************
*** 990,995 ****
--- 990,996 ----
  void
  reapchild()
  {
+ 	int olderrno = errno;
  # ifdef HASWAITPID
  	auto int status;
  	int count;
***************
*** 1021,1026 ****
--- 1022,1028 ----
  # ifdef SYS5SIGNALS
  	(void) setsignal(SIGCHLD, reapchild);
  # endif
+ 	errno = olderrno;
  }
  /*
  **  UNSETENV -- remove a variable from the environment
*** src/conf.h.OLD	Sun Oct 17 18:23:09 1993
--- src/conf.h	Thu Oct 21 07:19:39 1993
***************
*** 31,37 ****
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *	@(#)conf.h	8.38 (Berkeley) 10/15/93
   */
  
  /*
--- 31,37 ----
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *	@(#)conf.h	8.42 (Berkeley) 10/21/93
   */
  
  /*
***************
*** 118,123 ****
--- 118,125 ----
  */
  
  # ifdef __hpux
+ /* avoid m_flags conflict between db.h & sys/sysmacros.h on HP 300 */
+ # undef m_flags
  # define SYSTEM5	1	/* include all the System V defines */
  # define HASINITGROUPS	1	/* has initgroups(3) call */
  # define HASSTATFS	1	/* has the statfs(2) syscall */
***************
*** 147,152 ****
--- 149,155 ----
  */
  
  # ifdef IRIX
+ # include <sys/sysmacros.h>
  # define HASSETREUID	1	/* has setreuid(2) call */
  # define HASINITGROUPS	1	/* has initgroups(3) call */
  # define HASSTATFS	1	/* has the statfs(2) syscall */
***************
*** 171,176 ****
--- 174,180 ----
  			/* Solaris 2.x (a.k.a. SunOS 5.x) */
  #  define SYSTEM5	1	/* use System V definitions */
  #  define setreuid(r, e)	seteuid(e)
+ #  include <sys/sysmacros.h>
  #  include <sys/time.h>
  #  define gethostbyname	__switch_gethostbyname	/* get working version */
  #  define gethostbyaddr	__switch_gethostbyaddr	/* get working version */
***************
*** 290,295 ****
--- 294,317 ----
  
  
  /*
+ **  386BSD / FreeBSD 1.0E (works) / NetBSD (not tested)
+ **
+ **  4.3BSD clone, closer to 4.4BSD
+ */
+ 
+ #ifdef __386BSD__
+ # define HASUNSETENV	1	/* has unsetenv(3) call */
+ # define HASSETSID	1	/* has the setsid(2) POSIX syscall */
+ # define HASSTATFS	1	/* has the statfs(2) syscall */
+ # include <sys/cdefs.h>
+ # define ERRLIST_PREDEFINED	/* don't declare sys_errlist */
+ # ifndef LA_TYPE
+ #  define LA_TYPE	LA_SUBR
+ # endif
+ #endif
+ 
+ 
+ /*
  **  4.3 BSD -- this is for very old systems
  **
  **	You'll also have to install a new resolver library.
***************
*** 398,403 ****
--- 420,426 ----
  */
  
  #ifdef _AUX_SOURCE
+ # include <sys/sysmacros.h>
  # define BSD			/* has BSD routines */
  # define HASSTATFS	1	/* has the statfs(2) syscall */
  # define HASUNAME	1	/* use System V uname(2) system call */
*** src/daemon.c.OLD	Sat Oct 16 08:25:43 1993
--- src/daemon.c	Sat Oct 23 17:19:05 1993
***************
*** 37,45 ****
  
  #ifndef lint
  #ifdef DAEMON
! static char sccsid[] = "@(#)daemon.c	8.15 (Berkeley) 9/22/93 (with daemon mode)";
  #else
! static char sccsid[] = "@(#)daemon.c	8.15 (Berkeley) 9/22/93 (without daemon mode)";
  #endif
  #endif /* not lint */
  
--- 37,45 ----
  
  #ifndef lint
  #ifdef DAEMON
! static char sccsid[] = "@(#)daemon.c	8.19 (Berkeley) 10/23/93 (with daemon mode)";
  #else
! static char sccsid[] = "@(#)daemon.c	8.19 (Berkeley) 10/23/93 (without daemon mode)";
  #endif
  #endif /* not lint */
  
***************
*** 315,322 ****
  #endif
  
  			(void) close(DaemonSocket);
! 			InChannel = fdopen(t, "r");
! 			OutChannel = fdopen(dup(t), "w");
  
  			/* should we check for illegal connection here? XXX */
  #ifdef XLA
--- 315,327 ----
  #endif
  
  			(void) close(DaemonSocket);
! 			if ((InChannel = fdopen(t, "r")) == NULL ||
! 			    (t = dup(t)) < 0 ||
! 			    (OutChannel = fdopen(t, "w")) == NULL)
! 			{
! 				syserr("cannot open SMTP server channel, fd=%d", t);
! 				exit(0);
! 			}
  
  			/* should we check for illegal connection here? XXX */
  #ifdef XLA
***************
*** 765,772 ****
  	}
  
  	/* connection ok, put it into canonical form */
! 	mci->mci_out = fdopen(s, "w");
! 	mci->mci_in = fdopen(dup(s), "r");
  
  	return (EX_OK);
  }
--- 770,782 ----
  	}
  
  	/* connection ok, put it into canonical form */
! 	if ((mci->mci_out = fdopen(s, "w")) == NULL ||
! 	    (s = dup(s)) < 0 ||
! 	    (mci->mci_in = fdopen(s, "r")) == NULL)
! 	{
! 		syserr("cannot open SMTP client channel, fd=%d", s);
! 		return EX_TEMPFAIL;
! 	}
  
  	return (EX_OK);
  }
***************
*** 896,902 ****
  		ntohs(fa.sin.sin_port), ntohs(la.sin.sin_port));
  
  	/* create local address */
! 	bzero(&la, sizeof la);
  
  	/* create foreign address */
  	sp = getservbyname("auth", "tcp");
--- 906,912 ----
  		ntohs(fa.sin.sin_port), ntohs(la.sin.sin_port));
  
  	/* create local address */
! 	la.sin.sin_port = 0;
  
  	/* create foreign address */
  	sp = getservbyname("auth", "tcp");
***************
*** 916,922 ****
  	/* put a timeout around the whole thing */
  	ev = setevent(TimeOuts.to_ident, authtimeout, 0);
  
! 	/* connect to foreign IDENT server */
  	s = socket(AF_INET, SOCK_STREAM, 0);
  	if (s < 0)
  	{
--- 926,932 ----
  	/* put a timeout around the whole thing */
  	ev = setevent(TimeOuts.to_ident, authtimeout, 0);
  
! 	/* connect to foreign IDENT server using same address as SMTP socket */
  	s = socket(AF_INET, SOCK_STREAM, 0);
  	if (s < 0)
  	{
***************
*** 923,929 ****
  		clrevent(ev);
  		goto noident;
  	}
! 	if (connect(s, &fa.sa, sizeof fa.sin) < 0)
  	{
  closeident:
  		(void) close(s);
--- 933,940 ----
  		clrevent(ev);
  		goto noident;
  	}
! 	if (bind(s, &la.sa, sizeof la.sin) < 0 ||
! 	    connect(s, &fa.sa, sizeof fa.sin) < 0)
  	{
  closeident:
  		(void) close(s);
***************
*** 1177,1183 ****
  	register char *bp;
  	register char *ap;
  	int l;
! 	static char buf[80];
  
  	/* check for null/zero family */
  	if (sap == NULL)
--- 1188,1194 ----
  	register char *bp;
  	register char *ap;
  	int l;
! 	static char buf[100];
  
  	/* check for null/zero family */
  	if (sap == NULL)
***************
*** 1185,1195 ****
  	if (sap->sa.sa_family == 0)
  		return "0";
  
  #ifdef NETINET
! 	if (sap->sa.sa_family == AF_INET)
  		return inet_ntoa(((struct sockaddr_in *) sap)->sin_addr);
  #endif
  
  	/* unknown family -- just dump bytes */
  	(void) sprintf(buf, "Family %d: ", sap->sa.sa_family);
  	bp = &buf[strlen(buf)];
--- 1196,1222 ----
  	if (sap->sa.sa_family == 0)
  		return "0";
  
+ 	switch (sap->sa.sa_family)
+ 	{
+ #ifdef MAYBENEXTRELEASE		/*** UNTESTED *** UNTESTED *** UNTESTED ***/
+ 	  case AF_UNIX:
+ 	  	if (sap->sun.sun_path[0] != '\0')
+ 	  		sprintf(buf, "[UNIX: %.64s]", sap->sun.sun_path);
+ 	  	else
+ 	  		sprintf(buf, "[UNIX: localhost]");
+ 		return buf;
+ #endif
+ 
  #ifdef NETINET
! 	  case AF_INET:
  		return inet_ntoa(((struct sockaddr_in *) sap)->sin_addr);
  #endif
  
+ 	  default:
+ 	  	/* this case is only to ensure syntactic correctness */
+ 	  	break;
+ 	}
+ 
  	/* unknown family -- just dump bytes */
  	(void) sprintf(buf, "Family %d: ", sap->sa.sa_family);
  	bp = &buf[strlen(buf)];
***************
*** 1220,1229 ****
  	register SOCKADDR *sap;
  {
  	register struct hostent *hp;
- 
- #ifdef NAMED_BIND
  	int saveretry;
  
  	/* shorten name server timeout to avoid higher level timeouts */
  	saveretry = _res.retry;
  	_res.retry = 3;
--- 1247,1255 ----
  	register SOCKADDR *sap;
  {
  	register struct hostent *hp;
  	int saveretry;
  
+ #ifdef NAMED_BIND
  	/* shorten name server timeout to avoid higher level timeouts */
  	saveretry = _res.retry;
  	_res.retry = 3;
***************
*** 1244,1249 ****
--- 1270,1281 ----
  		hp = gethostbyaddr((char *) &sap->siso.siso_addr,
  			sizeof sap->siso.siso_addr,
  			AF_ISO);
+ 		break;
+ #endif
+ 
+ #ifdef MAYBENEXTRELEASE		/*** UNTESTED *** UNTESTED *** UNTESTED ***/
+ 	  case AF_UNIX:
+ 		hp = NULL;
  		break;
  #endif
  
*** src/deliver.c.OLD	Sat Oct 16 08:25:43 1993
--- src/deliver.c	Sat Oct 23 12:46:37 1993
***************
*** 33,39 ****
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)deliver.c	8.31 (Berkeley) 10/15/93";
  #endif /* not lint */
  
  #include "sendmail.h"
--- 33,39 ----
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)deliver.c	8.36 (Berkeley) 10/23/93";
  #endif /* not lint */
  
  #include "sendmail.h"
***************
*** 236,242 ****
  			ee->e_from.q_flags |= QDONTSEND;
  			ee->e_dfp = NULL;
  			ee->e_xfp = NULL;
- 			ee->e_lockfp = NULL;
  			ee->e_df = NULL;
  			ee->e_errormode = EM_MAIL;
  			ee->e_sibling = splitenv;
--- 236,241 ----
***************
*** 369,375 ****
  
  		/* now drop the envelope in the parent */
  		e->e_flags |= EF_INQUEUE|EF_KEEPQUEUE;
- 		e->e_flags &= ~EF_FATALERRS;
  		dropenvelope(e);
  
  		/* and reacquire in the child */
--- 368,373 ----
***************
*** 591,597 ****
  	char buf[MAXNAME];
  	char rpathbuf[MAXNAME];		/* translated return path */
  	extern int checkcompat();
- 	extern FILE *fdopen();
  	extern char SmtpError[];
  
  	errno = 0;
--- 589,594 ----
***************
*** 615,620 ****
--- 612,619 ----
  	if (tTd(10, 1))
  		printf("\n--deliver, mailer=%d, host=`%s', first user=`%s'\n",
  			m->m_mno, host, to->q_user);
+ 	if (tTd(10, 100))
+ 		printopenfds(FALSE);
  
  	/*
  	**  If this mailer is expensive, and if we don't want to make
***************
*** 993,998 ****
--- 992,998 ----
  			if (p == curhost)
  			{
  				syserr("deliver: null host name in signature");
+ 				curhost++;
  				continue;
  			}
  			strncpy(hostbuf, curhost, p - curhost);
***************
*** 1009,1015 ****
  				if (tTd(11, 1))
  				{
  					printf("openmailer: ");
! 					mci_dump(mci);
  				}
  				CurHostName = mci->mci_host;
  				break;
--- 1009,1015 ----
  				if (tTd(11, 1))
  				{
  					printf("openmailer: ");
! 					mci_dump(mci, FALSE);
  				}
  				CurHostName = mci->mci_host;
  				break;
***************
*** 1145,1153 ****
  			(void) setsignal(SIGHUP, SIG_IGN);
  			(void) setsignal(SIGTERM, SIG_DFL);
  
- 			/* close any other cached connections */
- 			mci_flush(FALSE, mci);
- 
  			/* reset user and group */
  			if (!bitnset(M_RESTR, m->m_flags))
  			{
--- 1145,1150 ----
***************
*** 1270,1279 ****
--- 1267,1299 ----
  		mci->mci_pid = pid;
  		(void) close(mpvect[0]);
  		mci->mci_out = fdopen(mpvect[1], "w");
+ 		if (mci->mci_out == NULL)
+ 		{
+ 			syserr("deliver: cannot create mailer output channel, fd=%d",
+ 				mpvect[1]);
+ 			(void) close(mpvect[1]);
+ 			if (clever)
+ 			{
+ 				(void) close(rpvect[0]);
+ 				(void) close(rpvect[1]);
+ 			}
+ 			rcode = EX_OSERR;
+ 			goto give_up;
+ 		}
  		if (clever)
  		{
  			(void) close(rpvect[1]);
  			mci->mci_in = fdopen(rpvect[0], "r");
+ 			if (mci->mci_in == NULL)
+ 			{
+ 				syserr("deliver: cannot create mailer input channel, fd=%d",
+ 					mpvect[1]);
+ 				(void) close(rpvect[0]);
+ 				fclose(mci->mci_out);
+ 				mci->mci_out = NULL;
+ 				rcode = EX_OSERR;
+ 				goto give_up;
+ 			}
  		}
  		else
  		{
***************
*** 1293,1299 ****
  	if (tTd(11, 1))
  	{
  		printf("openmailer: ");
! 		mci_dump(mci);
  	}
  
  	if (mci->mci_state != MCIS_OPEN)
--- 1313,1319 ----
  	if (tTd(11, 1))
  	{
  		printf("openmailer: ");
! 		mci_dump(mci, FALSE);
  	}
  
  	if (mci->mci_state != MCIS_OPEN)
*** src/envelope.c.OLD	Sat Oct 16 08:25:43 1993
--- src/envelope.c	Sat Oct 23 12:45:36 1993
***************
*** 33,39 ****
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)envelope.c	8.11 (Berkeley) 9/4/93";
  #endif /* not lint */
  
  #include "sendmail.h"
--- 33,39 ----
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)envelope.c	8.13 (Berkeley) 10/23/93";
  #endif /* not lint */
  
  #include "sendmail.h"
***************
*** 135,140 ****
--- 135,141 ----
  	**  Extract state information from dregs of send list.
  	*/
  
+ 	e->e_flags &= ~EF_QUEUERUN;
  	for (q = e->e_sendqueue; q != NULL; q = q->q_next)
  	{
  		if (bitset(QQUEUEUP, q->q_flags))
***************
*** 488,493 ****
--- 489,503 ----
  			syserr("!Can't open /dev/null");
  	}
  	e->e_xfp = fdopen(fd, "w");
+ 	if (e->e_xfp == NULL)
+ 	{
+ 		syserr("!Can't create transcript stream %s", p);
+ 	}
+ 	if (tTd(46, 9))
+ 	{
+ 		printf("openxscript(%s):\n  ", p);
+ 		dumpfd(fileno(e->e_xfp), TRUE, FALSE);
+ 	}
  }
  /*
  **  CLOSEXSCRIPT -- close the transcript file.
*** src/err.c.OLD	Sun Oct 17 09:53:40 1993
--- src/err.c	Thu Oct 21 07:18:59 1993
***************
*** 33,39 ****
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)err.c	8.10 (Berkeley) 10/3/93";
  #endif /* not lint */
  
  # include "sendmail.h"
--- 33,39 ----
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)err.c	8.12 (Berkeley) 10/21/93";
  #endif /* not lint */
  
  # include "sendmail.h"
***************
*** 116,121 ****
--- 116,126 ----
  			CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
  			&MsgBuf[4]);
  # endif /* LOG */
+ 	if (olderrno == EMFILE)
+ 	{
+ 		printopenfds(TRUE);
+ 		mci_dump_all(TRUE);
+ 	}
  	if (panic)
  	{
  #ifdef XLA
*** src/headers.c.OLD	Sun Oct 24 08:11:14 1993
--- src/headers.c	Sun Oct 24 10:34:35 1993
***************
*** 33,39 ****
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)headers.c	8.12 (Berkeley) 9/26/93";
  #endif /* not lint */
  
  # include <errno.h>
--- 33,39 ----
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)headers.c	8.13 (Berkeley) 10/24/93";
  #endif /* not lint */
  
  # include <errno.h>
***************
*** 713,721 ****
  			gotangle = TRUE;
  
  			/* oops -- have to change our mind */
! 			anglelev++;
  			if (!skipping)
! 				realanglelev++;
  
  			bp = buf;
  			if (quoteit)
--- 713,721 ----
  			gotangle = TRUE;
  
  			/* oops -- have to change our mind */
! 			anglelev = 1;
  			if (!skipping)
! 				realanglelev = 1;
  
  			bp = buf;
  			if (quoteit)
***************
*** 772,777 ****
--- 772,778 ----
  				/* syntax error: unmatched > */
  				if (copylev > 0)
  					bp--;
+ 				quoteit = TRUE;
  				continue;
  			}
  			if (copylev++ <= 0)
*** src/main.c.OLD	Thu Oct 21 06:39:27 1993
--- src/main.c	Sun Oct 24 10:34:05 1993
***************
*** 39,45 ****
  #endif /* not lint */
  
  #ifndef lint
! static char sccsid[] = "@(#)main.c	8.30 (Berkeley) 10/15/93";
  #endif /* not lint */
  
  #define	_DEFINE
--- 39,45 ----
  #endif /* not lint */
  
  #ifndef lint
! static char sccsid[] = "@(#)main.c	8.33 (Berkeley) 10/24/93";
  #endif /* not lint */
  
  #define	_DEFINE
***************
*** 624,632 ****
--- 624,634 ----
  	if (warn_C_flag)
  		auth_warning(CurEnv, "Processed by %s with -C %s",
  			RealUserName, ConfFile);
+ /*
  	if (warn_f_flag != '\0')
  		auth_warning(CurEnv, "%s set sender to %s using -%c",
  			RealUserName, from, warn_f_flag);
+ */
  	if (Warn_Q_option)
  		auth_warning(CurEnv, "Processed from queue %s", QueueDir);
  
***************
*** 857,862 ****
--- 859,865 ----
  			char *q;
  			auto char *delimptr;
  			extern bool invalidaddr();
+ 			extern char *crackaddr();
  
  			if (Verbose)
  				printf("> ");
***************
*** 865,872 ****
  				finis();
  			if (!Verbose)
  				printf("> %s", buf);
! 			if (buf[0] == '#')
  				continue;
  			for (p = buf; isascii(*p) && isspace(*p); p++)
  				continue;
  			q = p;
--- 868,887 ----
  				finis();
  			if (!Verbose)
  				printf("> %s", buf);
! 			switch (buf[0])
! 			{
! 			  case '#':
  				continue;
+ 
+ #ifdef MAYBENEXTRELEASE
+ 			  case 'C':		/* try crackaddr */
+ 			  	q = crackaddr(&buf[1]);
+ 			  	xputs(q);
+ 			  	printf("\n");
+ 			  	continue;
+ #endif
+ 			}
+ 
  			for (p = buf; isascii(*p) && isspace(*p); p++)
  				continue;
  			q = p;
***************
*** 878,884 ****
  				continue;
  			}
  			*p = '\0';
! 			if (invalidaddr(p + 1))
  				continue;
  			do
  			{
--- 893,899 ----
  				continue;
  			}
  			*p = '\0';
! 			if (invalidaddr(p + 1, NULL))
  				continue;
  			do
  			{
***************
*** 1090,1095 ****
--- 1105,1112 ----
  		printf("\n====finis: stat %d e_flags %o, e_id=%s\n",
  			ExitStat, CurEnv->e_flags,
  			CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id);
+ 	if (tTd(2, 9))
+ 		printopenfds(FALSE);
  
  	/* clean up temp files */
  	CurEnv->e_to = NULL;
*** src/mci.c.OLD	Wed Oct 20 09:43:01 1993
--- src/mci.c	Sat Oct 23 11:56:32 1993
***************
*** 33,39 ****
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)mci.c	8.3 (Berkeley) 7/19/93";
  #endif /* not lint */
  
  #include "sendmail.h"
--- 33,39 ----
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)mci.c	8.6 (Berkeley) 10/23/93";
  #endif /* not lint */
  
  #include "sendmail.h"
***************
*** 104,109 ****
--- 104,119 ----
  	if (*mcislot != NULL)
  		mci_uncache(mcislot, TRUE);
  
+ 	if (tTd(42, 5))
+ 		printf("mci_cache: caching %x (%s) in slot %d\n",
+ 			mci, mci->mci_host, mcislot - MciCache);
+ #ifdef LOG
+ 	if (tTd(91, 100))
+ 		syslog(LOG_DEBUG, "%s: mci_cache: caching %x (%s) in slot %d",
+ 			CurEnv->e_id ? CurEnv->e_id : "NOQUEUE",
+ 			mci, mci->mci_host, mcislot - MciCache);
+ #endif
+ 
  	*mcislot = mci;
  	mci->mci_flags |= MCIF_CACHED;
  }
***************
*** 185,190 ****
--- 195,210 ----
  		return;
  	*mcislot = NULL;
  
+ 	if (tTd(42, 5))
+ 		printf("mci_uncache: uncaching %x (%s) from slot %d (%d)\n",
+ 			mci, mci->mci_host, mcislot - MciCache, doquit);
+ #ifdef LOG
+ 	if (tTd(91, 100))
+ 		syslog(LOG_DEBUG, "%s: mci_uncache: uncaching %x (%s) from slot %d (%d)",
+ 			CurEnv->e_id ? CurEnv->e_id : "NOQUEUE",
+ 			mci, mci->mci_host, mcislot - MciCache, doquit);
+ #endif
+ 
  	if (doquit)
  	{
  		message("Closing connection to %s", mci->mci_host);
***************
*** 295,319 ****
  **		none.
  */
  
! mci_dump(mci)
  	register MCI *mci;
  {
  	extern char *ctime();
  
! 	printf("MCI@%x: ", mci);
  	if (mci == NULL)
  	{
! 		printf("NULL\n");
! 		return;
  	}
! 	printf("flags=%o, errno=%d, herrno=%d, exitstat=%d, state=%d, pid=%d,\n",
  		mci->mci_flags, mci->mci_errno, mci->mci_herrno,
! 		mci->mci_exitstat, mci->mci_state, mci->mci_pid);
! 	printf("\tmaxsize=%ld, phase=%s, mailer=%s,\n",
  		mci->mci_maxsize,
  		mci->mci_phase == NULL ? "NULL" : mci->mci_phase,
! 		mci->mci_mailer == NULL ? "NULL" : mci->mci_mailer->m_name);
! 	printf("\thost=%s, lastuse=%s\n",
  		mci->mci_host == NULL ? "NULL" : mci->mci_host,
  		ctime(&mci->mci_lastuse));
  }
--- 315,373 ----
  **		none.
  */
  
! mci_dump(mci, logit)
  	register MCI *mci;
+ 	bool logit;
  {
+ 	register char *p;
+ 	char *sep;
+ 	char buf[1000];
  	extern char *ctime();
  
! 	sep = logit ? " " : "\n\t";
! 	p = buf;
! 	sprintf(p, "MCI@%x: ", mci);
! 	p += strlen(p);
  	if (mci == NULL)
  	{
! 		sprintf(p, "NULL");
! 		goto printit;
  	}
! 	sprintf(p, "flags=%o, errno=%d, herrno=%d, exitstat=%d, state=%d, pid=%d,%s",
  		mci->mci_flags, mci->mci_errno, mci->mci_herrno,
! 		mci->mci_exitstat, mci->mci_state, mci->mci_pid, sep);
! 	p += strlen(p);
! 	sprintf(p, "maxsize=%ld, phase=%s, mailer=%s,%s",
  		mci->mci_maxsize,
  		mci->mci_phase == NULL ? "NULL" : mci->mci_phase,
! 		mci->mci_mailer == NULL ? "NULL" : mci->mci_mailer->m_name,
! 		sep);
! 	p += strlen(p);
! 	sprintf(p, "host=%s, lastuse=%s",
  		mci->mci_host == NULL ? "NULL" : mci->mci_host,
  		ctime(&mci->mci_lastuse));
+ printit:
+ 	if (logit)
+ 		syslog(LOG_INFO, "%s", buf);
+ 	else
+ 		printf("%s\n", buf);
+ }
+ /*
+ **  MCI_DUMP_ALL -- print the entire MCI cache
+ **
+ **	Parameters:
+ **		logit -- if set, log the result instead of printing
+ **			to stdout.
+ **
+ **	Returns:
+ **		none.
+ */
+ 
+ mci_dump_all(logit)
+ 	bool logit;
+ {
+ 	register int i;
+ 
+ 	for (i = 0; i < MaxMciCache; i++)
+ 		mci_dump(MciCache[i], logit);
  }
*** src/parseaddr.c.OLD	Sun Oct 17 11:59:06 1993
--- src/parseaddr.c	Fri Oct 22 09:21:59 1993
***************
*** 33,39 ****
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)parseaddr.c	8.12 (Berkeley) 9/27/93";
  #endif /* not lint */
  
  # include "sendmail.h"
--- 33,39 ----
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)parseaddr.c	8.14 (Berkeley) 10/22/93";
  #endif /* not lint */
  
  # include "sendmail.h"
***************
*** 100,112 ****
  	if (tTd(20, 1))
  		printf("\n--parseaddr(%s)\n", addr);
  
- 	if (invalidaddr(addr))
- 	{
- 		if (tTd(20, 1))
- 			printf("parseaddr-->bad address\n");
- 		return NULL;
- 	}
- 
  	if (delimptr == NULL)
  		delimptr = &delimptrbuf;
  
--- 100,105 ----
***************
*** 118,123 ****
--- 111,123 ----
  		return (NULL);
  	}
  
+ 	if (invalidaddr(addr, delim == '\0' ? NULL : *delimptr))
+ 	{
+ 		if (tTd(20, 1))
+ 			printf("parseaddr-->bad address\n");
+ 		return NULL;
+ 	}
+ 
  	/*
  	**  Save addr if we are going to have to.
  	**
***************
*** 204,221 ****
  */
  
  bool
! invalidaddr(addr)
  	register char *addr;
  {
! 	for (; *addr != '\0'; addr++)
  	{
! 		if ((*addr & 0340) != 0200)
! 			continue;
! 		setstat(EX_USAGE);
! 		usrerr("553 Address contained invalid control characters");
  		return TRUE;
  	}
! 	return FALSE;
  }
  /*
  **  ALLOCADDR -- do local allocations of address on demand.
--- 204,239 ----
  */
  
  bool
! invalidaddr(addr, delimptr)
  	register char *addr;
+ 	char *delimptr;
  {
! 	char savedelim;
! 
! 	if (delimptr != NULL)
! 		savedelim = *delimptr;
! #if 0
! 	/* for testing.... */
! 	if (strcmp(addr, "INvalidADDR") == 0)
  	{
! 		usrerr("553 INvalid ADDRess");
! 		if (delimptr != NULL)
! 			*delimptr = savedelim;
  		return TRUE;
  	}
! #endif
! 	for (; *addr != '\0'; addr++)
! 	{
! 		if ((*addr & 0340) == 0200)
! 			break;
! 	}
! 	if (delimptr != NULL)
! 		*delimptr = savedelim;
! 	if (*addr == '\0')
! 		return FALSE;
! 	setstat(EX_USAGE);
! 	usrerr("553 Address contained invalid control characters");
! 	return TRUE;
  }
  /*
  **  ALLOCADDR -- do local allocations of address on demand.
***************
*** 625,630 ****
--- 643,649 ----
  	register struct rewrite *rwr;	/* pointer to current rewrite rule */
  	int ruleno;			/* current rule number */
  	int rstat = EX_OK;		/* return status */
+ 	int loopcount;
  	struct match mlist[MAXMATCH];	/* stores match on LHS */
  	char *npvp[MAXATOM+1];		/* temporary space for rebuild */
  
***************
*** 647,656 ****
  	*/
  
  	ruleno = 1;
  	for (rwr = RewriteRules[ruleset]; rwr != NULL; )
  	{
- 		int loopcount = 0;
- 
  		if (tTd(21, 12))
  		{
  			printf("-----trying rule:");
--- 666,674 ----
  	*/
  
  	ruleno = 1;
+ 	loopcount = 0;
  	for (rwr = RewriteRules[ruleset]; rwr != NULL; )
  	{
  		if (tTd(21, 12))
  		{
  			printf("-----trying rule:");
***************
*** 860,865 ****
--- 878,884 ----
  				printf("----- rule fails\n");
  			rwr = rwr->r_next;
  			ruleno++;
+ 			loopcount = 0;
  			continue;
  		}
  
***************
*** 876,881 ****
--- 895,901 ----
  			rvp++;
  			rwr = rwr->r_next;
  			ruleno++;
+ 			loopcount = 0;
  		}
  		else if ((*rp & 0377) == CANONHOST)
  		{
*** src/queue.c.OLD	Sat Oct 16 08:25:43 1993
--- src/queue.c	Sat Oct 23 16:45:38 1993
***************
*** 36,44 ****
  
  #ifndef lint
  #ifdef QUEUE
! static char sccsid[] = "@(#)queue.c	8.20 (Berkeley) 10/8/93 (with queueing)";
  #else
! static char sccsid[] = "@(#)queue.c	8.20 (Berkeley) 10/8/93 (without queueing)";
  #endif
  #endif /* not lint */
  
--- 36,44 ----
  
  #ifndef lint
  #ifdef QUEUE
! static char sccsid[] = "@(#)queue.c	8.24 (Berkeley) 10/23/93 (with queueing)";
  #else
! static char sccsid[] = "@(#)queue.c	8.24 (Berkeley) 10/23/93 (without queueing)";
  #endif
  #endif /* not lint */
  
***************
*** 100,106 ****
  	**  Create control file.
  	*/
  
! 	newid = (e->e_id == NULL);
  
  	/* if newid, queuename will create a locked qf file in e->lockfp */
  	strcpy(tf, queuename(e, 't'));
--- 100,106 ----
  	**  Create control file.
  	*/
  
! 	newid = (e->e_id == NULL) || !bitset(EF_INQUEUE, e->e_flags);
  
  	/* if newid, queuename will create a locked qf file in e->lockfp */
  	strcpy(tf, queuename(e, 't'));
***************
*** 109,120 ****
  		newid = FALSE;
  
  	/* if newid, just write the qf file directly (instead of tf file) */
! 	if (newid)
  	{
- 		tfp = e->e_lockfp;
- 	}
- 	else
- 	{
  		/* get a locked tf file */
  		for (i = 0; i < 128; i++)
  		{
--- 109,116 ----
  		newid = FALSE;
  
  	/* if newid, just write the qf file directly (instead of tf file) */
! 	if (!newid)
  	{
  		/* get a locked tf file */
  		for (i = 0; i < 128; i++)
  		{
***************
*** 149,162 ****
  			else
  				sleep(i % 32);
  		}
! 		if (fd < 0)
! 			syserr("!queueup: cannot create temp file %s", tf);
! 
! 		tfp = fdopen(fd, "w");
  	}
  
  	if (tTd(40, 1))
! 		printf("\n>>>>> queueing %s >>>>>\n", e->e_id);
  
  	/*
  	**  If there is no data file yet, create one.
--- 145,167 ----
  			else
  				sleep(i % 32);
  		}
! 		if (fd < 0 || (tfp = fdopen(fd, "w")) == NULL)
! 			syserr("!queueup: cannot create queue temp file %s", tf);
  	}
  
  	if (tTd(40, 1))
! 		printf("\n>>>>> queueing %s%s >>>>>\n", e->e_id,
! 			newid ? " (new id)" : "");
! 	if (tTd(40, 9))
! 	{
! 		printf("  tfp=");
! 		dumpfd(fileno(tfp), TRUE, FALSE);
! 		printf("  lockfp=");
! 		if (e->e_lockfp == NULL)
! 			printf("NULL\n");
! 		else
! 			dumpfd(fileno(e->e_lockfp), TRUE, FALSE);
! 	}
  
  	/*
  	**  If there is no data file yet, create one.
***************
*** 170,178 ****
  		e->e_df = queuename(e, 'd');
  		e->e_df = newstr(e->e_df);
  		fd = open(e->e_df, O_WRONLY|O_CREAT, FileMode);
! 		if (fd < 0)
! 			syserr("!queueup: cannot create %s", e->e_df);
! 		dfp = fdopen(fd, "w");
  		(*e->e_putbody)(dfp, FileMailer, e, NULL);
  		(void) xfclose(dfp, "queueup dfp", e->e_id);
  		e->e_putbody = putbody;
--- 175,183 ----
  		e->e_df = queuename(e, 'd');
  		e->e_df = newstr(e->e_df);
  		fd = open(e->e_df, O_WRONLY|O_CREAT, FileMode);
! 		if (fd < 0 || (dfp = fdopen(fd, "w")) == NULL)
! 			syserr("!queueup: cannot create data temp file %s",
! 				e->e_df);
  		(*e->e_putbody)(dfp, FileMailer, e, NULL);
  		(void) xfclose(dfp, "queueup dfp", e->e_id);
  		e->e_putbody = putbody;
***************
*** 267,273 ****
  
  	bzero((char *) &nullmailer, sizeof nullmailer);
  	nullmailer.m_re_rwset = nullmailer.m_rh_rwset =
! 			nullmailer.m_se_rwset = nullmailer.m_sh_rwset = -1;
  	nullmailer.m_eol = "\n";
  
  	define('g', "\201f", e);
--- 272,278 ----
  
  	bzero((char *) &nullmailer, sizeof nullmailer);
  	nullmailer.m_re_rwset = nullmailer.m_rh_rwset =
! 			nullmailer.m_se_rwset = nullmailer.m_sh_rwset = 0;
  	nullmailer.m_eol = "\n";
  
  	define('g', "\201f", e);
***************
*** 352,357 ****
--- 357,363 ----
  	else
  		qf = tf;
  	errno = 0;
+ 	e->e_flags |= EF_INQUEUE;
  
  # ifdef LOG
  	/* save log info */
***************
*** 868,873 ****
--- 874,880 ----
  		e->e_flags |= EF_QUEUERUN|EF_GLOBALERRS;
  		e->e_errormode = EM_MAIL;
  		e->e_id = id;
+ 		GrabTo = FALSE;
  		if (forkflag)
  		{
  			disconnect(1, e);
***************
*** 1424,1429 ****
--- 1431,1441 ----
  		define('i', e->e_id, e);
  		if (tTd(7, 1))
  			printf("queuename: assigned id %s, env=%x\n", e->e_id, e);
+ 		if (tTd(7, 9))
+ 		{
+ 			printf("  lockfd=");
+ 			dumpfd(fileno(e->e_lockfp), TRUE, FALSE);
+ 		}
  # ifdef LOG
  		if (LogLevel > 93)
  			syslog(LOG_DEBUG, "%s: assigned id", e->e_id);
*** src/savemail.c.OLD	Sun Oct 17 11:18:51 1993
--- src/savemail.c	Thu Oct 21 12:24:51 1993
***************
*** 33,39 ****
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)savemail.c	8.14 (Berkeley) 10/15/93";
  #endif /* not lint */
  
  # include "sendmail.h"
--- 33,39 ----
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)savemail.c	8.16 (Berkeley) 10/21/93";
  #endif /* not lint */
  
  # include "sendmail.h"
***************
*** 96,103 ****
  		return;
  	}
  
- 	e->e_flags &= ~EF_FATALERRS;
- 
  	/*
  	**  In the unhappy event we don't know who to return the mail
  	**  to, make someone up.
--- 96,101 ----
***************
*** 479,485 ****
  	ee->e_msgsize = ERRORFUDGE;
  	if (!NoReturn)
  		ee->e_msgsize += e->e_msgsize;
! 	openxscript(ee);
  	for (q = returnq; q != NULL; q = q->q_next)
  	{
  		if (bitset(QBADADDR, q->q_flags))
--- 477,483 ----
  	ee->e_msgsize = ERRORFUDGE;
  	if (!NoReturn)
  		ee->e_msgsize += e->e_msgsize;
! 	initsys(ee);
  	for (q = returnq; q != NULL; q = q->q_next)
  	{
  		if (bitset(QBADADDR, q->q_flags))
***************
*** 601,607 ****
  	for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
  		if (bitset(QBADADDR, q->q_flags))
  			break;
! 	if (q == NULL)
  	{
  		putline("    **********************************************",
  			fp, m);
--- 599,605 ----
  	for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
  		if (bitset(QBADADDR, q->q_flags))
  			break;
! 	if (q == NULL && !bitset(EF_FATALERRS, e->e_parent->e_flags))
  	{
  		putline("    **********************************************",
  			fp, m);
No differences encountered
*** src/usersmtp.c.OLD	Wed Oct 20 09:55:57 1993
--- src/usersmtp.c	Sun Oct 24 07:44:14 1993
***************
*** 36,44 ****
  
  #ifndef lint
  #ifdef SMTP
! static char sccsid[] = "@(#)usersmtp.c	8.11 (Berkeley) 10/15/93 (with SMTP)";
  #else
! static char sccsid[] = "@(#)usersmtp.c	8.11 (Berkeley) 10/15/93 (without SMTP)";
  #endif
  #endif /* not lint */
  
--- 36,44 ----
  
  #ifndef lint
  #ifdef SMTP
! static char sccsid[] = "@(#)usersmtp.c	8.13 (Berkeley) 10/24/93 (with SMTP)";
  #else
! static char sccsid[] = "@(#)usersmtp.c	8.13 (Berkeley) 10/24/93 (without SMTP)";
  #endif
  #endif /* not lint */
  
***************
*** 96,102 ****
  	if (tTd(18, 1))
  	{
  		printf("smtpinit ");
! 		mci_dump(mci);
  	}
  
  	/*
--- 96,102 ----
  	if (tTd(18, 1))
  	{
  		printf("smtpinit ");
! 		mci_dump(mci, FALSE);
  	}
  
  	/*
***************
*** 141,148 ****
  	SmtpPhase = mci->mci_phase = "client greeting";
  	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
  	r = reply(m, mci, e, TimeOuts.to_initial, esmtp_check);
! 	if (r < 0 || REPLYTYPE(r) != 2)
  		goto tempfail1;
  
  	/*
  	**  Send the HELO command.
--- 141,150 ----
  	SmtpPhase = mci->mci_phase = "client greeting";
  	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
  	r = reply(m, mci, e, TimeOuts.to_initial, esmtp_check);
! 	if (r < 0 || REPLYTYPE(r) == 4)
  		goto tempfail1;
+ 	if (REPLYTYPE(r) != 2)
+ 		goto unavailable;
  
  	/*
  	**  Send the HELO command.
*** src/util.c.OLD	Sun Oct 17 07:12:08 1993
--- src/util.c	Sat Oct 23 12:45:37 1993
***************
*** 33,39 ****
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)util.c	8.11 (Berkeley) 9/22/93";
  #endif /* not lint */
  
  # include "sendmail.h"
--- 33,39 ----
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)util.c	8.14 (Berkeley) 10/23/93";
  #endif /* not lint */
  
  # include "sendmail.h"
***************
*** 1155,1161 ****
  
  	for (i = 0; i < 3; i++)
  	{
! 		if (fstat(i, &stbuf) < 0)
  		{
  			/* oops.... */
  			int fd;
--- 1155,1161 ----
  
  	for (i = 0; i < 3; i++)
  	{
! 		if (fstat(i, &stbuf) < 0 && errno != EOPNOTSUPP)
  		{
  			/* oops.... */
  			int fd;
***************
*** 1170,1173 ****
--- 1170,1293 ----
  		}
  	}
  #endif /* XDEBUG */
+ }
+ /*
+ **  PRINTOPENFDS -- print the open file descriptors (for debugging)
+ **
+ **	Parameters:
+ **		logit -- if set, send output to syslog; otherwise
+ **			print for debugging.
+ **
+ **	Returns:
+ **		none.
+ */
+ 
+ #include <netdb.h>
+ #include <arpa/inet.h>
+ 
+ printopenfds(logit)
+ 	bool logit;
+ {
+ 	register int fd;
+ 	extern int DtableSize;
+ 
+ 	for (fd = 0; fd < DtableSize; fd++)
+ 		dumpfd(fd, FALSE, logit);
+ }
+ /*
+ **  DUMPFD -- dump a file descriptor
+ **
+ **	Parameters:
+ **		fd -- the file descriptor to dump.
+ **		printclosed -- if set, print a notification even if
+ **			it is closed; otherwise print nothing.
+ **		logit -- if set, send output to syslog instead of stdout.
+ */
+ 
+ dumpfd(fd, printclosed, logit)
+ 	int fd;
+ 	bool printclosed;
+ 	bool logit;
+ {
+ 	register struct hostent *hp;
+ 	register char *p;
+ 	struct sockaddr_in sin;
+ 	auto int slen;
+ 	struct stat st;
+ 	char buf[200];
+ 
+ 	p = buf;
+ 	sprintf(p, "%3d: ", fd);
+ 	p += strlen(p);
+ 
+ 	if (fstat(fd, &st) < 0)
+ 	{
+ 		if (printclosed || errno != EBADF)
+ 		{
+ 			sprintf(p, "CANNOT STAT (%s)", errstring(errno));
+ 			goto printit;
+ 		}
+ 		return;
+ 	}
+ 
+ 	slen = fcntl(fd, F_GETFL, NULL);
+ 	if (slen != -1)
+ 	{
+ 		sprintf(p, "fl=0x%x, ", slen);
+ 		p += strlen(p);
+ 	}
+ 
+ 	sprintf(p, "mode=%o: ", st.st_mode);
+ 	p += strlen(p);
+ 	switch (st.st_mode & S_IFMT)
+ 	{
+ 	  case S_IFSOCK:
+ 		sprintf(p, "SOCK ");
+ 		p += strlen(p);
+ 		slen = sizeof sin;
+ 		if (getsockname(fd, (struct sockaddr *) &sin, &slen) < 0)
+ 			sprintf(p, "(badsock)");
+ 		else
+ 		{
+ 			hp = gethostbyaddr((char *) &sin.sin_addr, slen, AF_INET);
+ 			sprintf(p, "%s/%d", hp == NULL ? inet_ntoa(sin.sin_addr)
+ 						   : hp->h_name, ntohs(sin.sin_port));
+ 		}
+ 		p += strlen(p);
+ 		sprintf(p, "->");
+ 		p += strlen(p);
+ 		slen = sizeof sin;
+ 		if (getpeername(fd, (struct sockaddr *) &sin, &slen) < 0)
+ 			sprintf(p, "(badsock)");
+ 		else
+ 		{
+ 			hp = gethostbyaddr((char *) &sin.sin_addr, slen, AF_INET);
+ 			sprintf(p, "%s/%d", hp == NULL ? inet_ntoa(sin.sin_addr)
+ 						   : hp->h_name, ntohs(sin.sin_port));
+ 		}
+ 		break;
+ 
+ 	  case S_IFCHR:
+ 		sprintf(p, "CHR: ");
+ 		p += strlen(p);
+ 		goto defprint;
+ 
+ 	  case S_IFBLK:
+ 		sprintf(p, "BLK: ");
+ 		p += strlen(p);
+ 		goto defprint;
+ 
+ 	  default:
+ defprint:
+ 		sprintf(p, "dev=%d/%d, ino=%d, nlink=%d, u/gid=%d/%d, size=%ld",
+ 			major(st.st_dev), minor(st.st_dev), st.st_ino,
+ 			st.st_nlink, st.st_uid, st.st_gid, st.st_size);
+ 		break;
+ 	}
+ 
+ printit:
+ 	if (logit)
+ 		syslog(LOG_INFO, "%s", buf);
+ 	else
+ 		printf("%s\n", buf);
  }
*** src/version.c.OLD	Sat Oct 23 12:50:19 1993
--- src/version.c	Sun Oct 24 10:39:25 1993
***************
*** 33,39 ****
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)version.c	8.6.1.2 (Berkeley) 10/15/93";
  #endif /* not lint */
  
! char	Version[] = "8.6.2";
--- 33,39 ----
   */
  
  #ifndef lint
! static char sccsid[] = "@(#)version.c	8.6.1.3 (Berkeley) 10/24/93";
  #endif /* not lint */
  
! char	Version[] = "8.6.3";
*** cf/cf/mail.cs.mc.OLD	Fri Oct 15 17:58:27 1993
--- cf/cf/mail.cs.mc	Fri Oct 15 18:18:38 1993
***************
*** 34,42 ****
  #
  
  include(`../m4/cf.m4')
! VERSIONID(`@(#)mail.cs.mc	8.2 (Berkeley) 8/12/93')
  OSTYPE(ultrix4.1)dnl
! DOMAIN(cs.hidden)dnl
  FEATURE(notsticky)dnl
  MAILER(local)dnl
  MAILER(smtp)dnl
--- 34,43 ----
  #
  
  include(`../m4/cf.m4')
! VERSIONID(`@(#)mail.cs.mc	8.3 (Berkeley) 10/15/93')
  OSTYPE(ultrix4.1)dnl
! DOMAIN(Berkeley)dnl
! MASQUERADE_AS(CS.Berkeley.EDU)dnl
  FEATURE(notsticky)dnl
  MAILER(local)dnl
  MAILER(smtp)dnl
*** cf/m4/version.m4.OLD	Sat Oct 23 13:47:44 1993
--- cf/m4/version.m4	Sun Oct 24 10:38:33 1993
***************
*** 32,39 ****
  # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  # SUCH DAMAGE.
  #
! VERSIONID(`@(#)version.m4	8.6.1.2 (Berkeley) 10/15/93')
  #
  divert(0)
  # Configuration version number
! DZ8.6.2
--- 32,39 ----
  # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  # SUCH DAMAGE.
  #
! VERSIONID(`@(#)version.m4	8.6.1.3 (Berkeley) 10/24/93')
  #
  divert(0)
  # Configuration version number
! DZ8.6.3
*** cf/mailer/local.m4.OLD	Sat Oct 23 14:35:05 1993
--- cf/mailer/local.m4	Sat Oct 23 17:25:16 1993
***************
*** 44,52 ****
  ###   Local and Program Mailer specification   ###
  ##################################################
  
! VERSIONID(`@(#)local.m4	8.4 (Berkeley) 8/8/93')
  
! Mlocal,		P=LOCAL_MAILER_PATH, F=CONCAT(`lsDFM', LOCAL_MAILER_FLAGS), S=10, R=20,
  		A=LOCAL_MAILER_ARGS
  Mprog,		P=LOCAL_SHELL_PATH, F=CONCAT(`lsDFM', LOCAL_SHELL_FLAGS), S=10, R=20, D=$z:/,
  		A=LOCAL_SHELL_ARGS
--- 44,52 ----
  ###   Local and Program Mailer specification   ###
  ##################################################
  
! VERSIONID(`@(#)local.m4	8.5 (Berkeley) 10/23/93')
  
! Mlocal,		P=LOCAL_MAILER_PATH, F=CONCAT(`lsDFM', LOCAL_MAILER_FLAGS), S=10, R=20/40,
  		A=LOCAL_MAILER_ARGS
  Mprog,		P=LOCAL_SHELL_PATH, F=CONCAT(`lsDFM', LOCAL_SHELL_FLAGS), S=10, R=20, D=$z:/,
  		A=LOCAL_SHELL_ARGS
***************
*** 53,58 ****
--- 53,64 ----
  
  S10
  R<@>			$n			errors to mailer-daemon
+ R$+			$: $>40 $1
+ 
+ S20
+ R$+ < @ $* >		$: $1			strip host part
+ 
+ S40
  ifdef(`_ALWAYS_ADD_DOMAIN_',
  `R$* < @ $* > $*		$@ $1 < @ $2 > $3	already fully qualified
  R$*			$: $1 @ $M		add local qualification
*** cf/mailer/smtp.m4.OLD	Sat Oct 23 14:35:12 1993
--- cf/mailer/smtp.m4	Sat Oct 23 17:23:23 1993
***************
*** 40,85 ****
  ###   SMTP Mailer specification   ###
  #####################################
  
! VERSIONID(`@(#)smtp.m4	8.5 (Berkeley) 9/19/93')
  
! Msmtp,		P=[IPC], F=CONCAT(mDFMuX, SMTP_MAILER_FLAGS), S=11, R=ifdef(`_ALL_MASQUERADE_', `11', `21'), E=\r\n,
  		ifdef(`_OLD_SENDMAIL_',, `L=990, ')A=IPC $h
! Mesmtp,		P=[IPC], F=CONCAT(mDFMuXa, SMTP_MAILER_FLAGS), S=11, R=ifdef(`_ALL_MASQUERADE_', `11', `21'), E=\r\n,
  		ifdef(`_OLD_SENDMAIL_',, `L=990, ')A=IPC $h
! Mrelay,		P=[IPC], F=CONCAT(mDFMuXa, SMTP_MAILER_FLAGS), S=11, R=19, E=\r\n,
  		ifdef(`_OLD_SENDMAIL_',, `L=2040, ')A=IPC $h
  
  S11
  
! # do sender/recipient common rewriting
! R$+			$: $>19 $1
! 
! # if already @ qualified, we are done
  R$* < @ $* > $*		$@ $1 < @ $2 > $3		already qualified
  
- # do not qualify list:; syntax
- R$* :; <@>		$@ $1 :;
  
! # unqualified names (e.g., "eric") "come from" $M
! R$=E			$@ $1 < @ $j>			show exposed names
! R$+			$: $1 < @ $M >			user w/o host
! R$+ <@>			$: $1 < @ $j >			in case $M undefined
  
- ifdef(`_ALL_MASQUERADE_', `dnl',
- `S21
- 
  # do sender/recipient common rewriting
  R$+			$: $>19 $1
  
! # if already @ qualified, we are done
  R$* < @ $* > $*		$@ $1 < @ $2 > $3		already qualified
  
- # do not qualify list:; syntax
- R$* :; <@>		$@ $1 :;
  
! # unqualified names (e.g., "eric") are qualified by local host
! R$+			$: $1 < @ $j >')
  
  S19
  
  # pass <route-addr>s through
--- 40,101 ----
  ###   SMTP Mailer specification   ###
  #####################################
  
! VERSIONID(`@(#)smtp.m4	8.6 (Berkeley) 10/23/93')
  
! Msmtp,		P=[IPC], F=CONCAT(mDFMuX, SMTP_MAILER_FLAGS), S=11/31, R=ifdef(`_ALL_MASQUERADE_', `11/31', `21'), E=\r\n,
  		ifdef(`_OLD_SENDMAIL_',, `L=990, ')A=IPC $h
! Mesmtp,		P=[IPC], F=CONCAT(mDFMuXa, SMTP_MAILER_FLAGS), S=11/31, R=ifdef(`_ALL_MASQUERADE_', `11/31', `21'), E=\r\n,
  		ifdef(`_OLD_SENDMAIL_',, `L=990, ')A=IPC $h
! Mrelay,		P=[IPC], F=CONCAT(mDFMuXa, SMTP_MAILER_FLAGS), S=11/31, R=19, E=\r\n,
  		ifdef(`_OLD_SENDMAIL_',, `L=2040, ')A=IPC $h
  
+ #
+ #  envelope sender and masquerading recipient rewriting
+ #
  S11
+ R$+			$: $>19 $1			sender/recipient common
+ R$* :; <@>		$@ $1 :;			list:; special case
  
! # handle unqualified names
  R$* < @ $* > $*		$@ $1 < @ $2 > $3		already qualified
+ R$*			$@ $>29 $1
  
  
! #
! #  header recipient rewriting if not masquerading recipients
! #
! S21
  
  # do sender/recipient common rewriting
  R$+			$: $>19 $1
  
! # unqualified names (e.g., "eric") are qualified by local host
  R$* < @ $* > $*		$@ $1 < @ $2 > $3		already qualified
+ R$+			$: $1 < @ $j >			add local domain
  
  
! #
! #  header sender and masquerading recipient rewriting
! #
! S31
! R$+			$: $>19 $1			sender/recipient common
! R$* :; <@>		$@ $1 :;			list:; special case
  
+ # do special header rewriting
+ R$* <@> $*		$@ $1 <@> $2			pass null host through
+ R< @ $* > $*		$@ < @ $1 > $2			pass route-addr through
+ R$=E < @ $=w . >	$@ $1 < @ $2 >			exposed user as is
+ R$* < @ $=w . >		$: $1 < @ $M >			masquerade as domain
+ R$* < @ >		$: $1 < @ $j >			in case $M undefined
+ 
+ # handle unqualified names
+ R$* < @ $* > $*		$@ $1 < @ $2 > $3		already qualified
+ R$*			$@ $>29 $1
+ 
+ 
+ #
+ #  common rewriting for all SMTP addresses
+ #
  S19
  
  # pass <route-addr>s through
***************
*** 96,98 ****
--- 112,123 ----
  	`dnl')
  ifdef(`_NO_UUCP_', `dnl',
  `R$+ <@ $+ . UUCP >	$: $2 ! $1 < @ $j >		user@host.UUCP')
+ 
+ 
+ #
+ #  common sender and masquerading recipient rewriting
+ #
+ S29
+ R$=E			$@ $1 < @ $j>			show exposed names
+ R$+			$: $1 < @ $M >			user w/o host
+ R$+ <@>			$: $1 < @ $j >			in case $M undefined
