summaryrefslogtreecommitdiffstats
path: root/usr.sbin/sendmail/src
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-11-18 02:26:51 +0000
committerpeter <peter@FreeBSD.org>1996-11-18 02:26:51 +0000
commit8e0d5faaa77159b266e4ab922edf43a79f52e0c0 (patch)
treedc9912f7544cf0388bda667e714af24cd2fc24f8 /usr.sbin/sendmail/src
parentc25f71c7e501b060767f7d67d9448d649a801c95 (diff)
downloadFreeBSD-src-8e0d5faaa77159b266e4ab922edf43a79f52e0c0.zip
FreeBSD-src-8e0d5faaa77159b266e4ab922edf43a79f52e0c0.tar.gz
Import sendmail-8.8.3 - this contains the official fix to replace the
previous workaround patch that I used. Obtained from: Eric Allman <eric@sendmail.org>
Diffstat (limited to 'usr.sbin/sendmail/src')
-rw-r--r--usr.sbin/sendmail/src/READ_ME37
-rw-r--r--usr.sbin/sendmail/src/collect.c5
-rw-r--r--usr.sbin/sendmail/src/conf.c137
-rw-r--r--usr.sbin/sendmail/src/conf.h43
-rw-r--r--usr.sbin/sendmail/src/daemon.c48
-rw-r--r--usr.sbin/sendmail/src/deliver.c110
-rw-r--r--usr.sbin/sendmail/src/domain.c29
-rw-r--r--usr.sbin/sendmail/src/envelope.c24
-rw-r--r--usr.sbin/sendmail/src/main.c64
-rw-r--r--usr.sbin/sendmail/src/map.c36
-rw-r--r--usr.sbin/sendmail/src/mci.c53
-rw-r--r--usr.sbin/sendmail/src/mime.c183
-rw-r--r--usr.sbin/sendmail/src/queue.c131
-rw-r--r--usr.sbin/sendmail/src/readcf.c8
-rw-r--r--usr.sbin/sendmail/src/sendmail.h11
-rw-r--r--usr.sbin/sendmail/src/srvrsmtp.c21
-rw-r--r--usr.sbin/sendmail/src/usersmtp.c168
-rw-r--r--usr.sbin/sendmail/src/util.c60
-rw-r--r--usr.sbin/sendmail/src/version.c4
19 files changed, 841 insertions, 331 deletions
diff --git a/usr.sbin/sendmail/src/READ_ME b/usr.sbin/sendmail/src/READ_ME
index 779f828..afeac1b 100644
--- a/usr.sbin/sendmail/src/READ_ME
+++ b/usr.sbin/sendmail/src/READ_ME
@@ -30,7 +30,7 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
-# @(#)READ_ME 8.125 (Berkeley) 10/18/96
+# @(#)READ_ME 8.130 (Berkeley) 11/10/96
#
This directory contains the source files for sendmail.
@@ -168,7 +168,7 @@ LDAPMAP Lightweight Directory Lookup Protocol support. You will
this flag.
>>> NOTE WELL for NEWDB support: it is CRITICAL that you remove ndbm.o
->>> from libdb.a and ndbm.h from the appropriate include directories if
+>>> from libdb.a before you install it and DO NOT install ndbm.h if
>>> you want to get ndbm support. If you don't delete these, there is
>>> absolutely no point to including -DNDBM, since it will just get you
>>> another (inferior) API to the same format database. These files
@@ -355,11 +355,20 @@ LA_TYPE The type of load average your kernel supports. These
the dg_sys_info system call.
LA_HPUX (10) is an HP-UX specific version that uses the
pstat_getdynamic system call.
+ LA_IRIX6 (11) is an IRIX 6.x specific version that adapts
+ to 32 or 64 bit kernels; it is otherwise very similar
+ to LA_INT.
+ LA_KSTAT (12) uses the (Solaris-specific) kstat(3k)
+ implementation.
+ LA_DEVSHORT (13) reads a short from a system file (default:
+ /dev/table/avenrun) and scales it in the same manner
+ as LA_SHORT.
LA_INT, LA_SHORT, LA_FLOAT, and LA_READKSYM have several
other parameters that they try to divine: the name of your
kernel, the name of the variable in the kernel to examine,
the number of bits of precision in a fixed point load average,
- and so forth.
+ and so forth. LA_DEVSHORT uses _PATH_AVENRUN to find the
+ device to be read to find the load average.
In desperation, use LA_ZERO. The actual code is in
conf.c -- it can be tweaked if you are brave.
FSHIFT For LA_INT, LA_SHORT, and LA_READKSYM, this is the number
@@ -809,6 +818,26 @@ IRIX
the developers' option in order to get the necessary include
files.
+ If you compile with -lmalloc (the fast memory allocator), you may
+ get warning messages such as the following:
+
+ ld32: WARNING 85: definition of _calloc in /usr/lib32/libmalloc.so
+ preempts that definition in /usr/lib32/mips3/libc.so.
+ ld32: WARNING 85: definition of _malloc in /usr/lib32/libmalloc.so
+ preempts that definition in /usr/lib32/mips3/libc.so.
+ ld32: WARNING 85: definition of _realloc in /usr/lib32/libmalloc.so
+ preempts that definition in /usr/lib32/mips3/libc.so.
+ ld32: WARNING 85: definition of _free in /usr/lib32/libmalloc.so
+ preempts that definition in /usr/lib32/mips3/libc.so.
+ ld32: WARNING 85: definition of _cfree in /usr/lib32/libmalloc.so
+ preempts that definition in /usr/lib32/mips3/libc.so.
+
+ These are unavoidable and innocuous -- just ignore them.
+
+ According to Dave Sill <de5@ornl.gov>, there is a version of the
+ Berkeley db library patched to run on Irix 6.2 available from
+ http://reality.sgi.com/ariel/db-1.85-irix.tar.Z .
+
NeXT or NEXTSTEP
NEXTSTEP 3.3 and earlier ship with the old DBM library. You will
need to acquire the new Berkeley DB from ftp.cs.berkeley.edu.
@@ -1348,4 +1377,4 @@ version.c The version number and information about this
Eric Allman
-(Version 8.125, last update 10/18/96 07:32:40)
+(Version 8.130, last update 11/10/96 11:15:30)
diff --git a/usr.sbin/sendmail/src/collect.c b/usr.sbin/sendmail/src/collect.c
index 233c247..48b5b89 100644
--- a/usr.sbin/sendmail/src/collect.c
+++ b/usr.sbin/sendmail/src/collect.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)collect.c 8.58 (Berkeley) 9/18/96";
+static char sccsid[] = "@(#)collect.c 8.60 (Berkeley) 11/15/96";
#endif /* not lint */
# include <errno.h>
@@ -488,7 +488,7 @@ readerr:
** Examples are who is the from person & the date.
*/
- eatheader(e, !requeueflag);
+ eatheader(e, TRUE);
if (GrabTo && e->e_sendqueue == NULL)
usrerr("No recipient addresses found in header");
@@ -557,6 +557,7 @@ readerr:
/* check for message too large */
if (MaxMessageSize > 0 && e->e_msgsize > MaxMessageSize)
{
+ e->e_flags |= EF_NO_BODY_RETN;
e->e_status = "5.2.3";
usrerr("552 Message exceeds maximum fixed size (%ld)",
MaxMessageSize);
diff --git a/usr.sbin/sendmail/src/conf.c b/usr.sbin/sendmail/src/conf.c
index 0799047..6f3fd95 100644
--- a/usr.sbin/sendmail/src/conf.c
+++ b/usr.sbin/sendmail/src/conf.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)conf.c 8.312 (Berkeley) 10/17/96";
+static char sccsid[] = "@(#)conf.c 8.315 (Berkeley) 11/10/96";
#endif /* not lint */
# include "sendmail.h"
@@ -1188,8 +1188,19 @@ init_md(argc, argv)
/* keep gethostby*() from stripping the local domain name */
set_domain_trim_off();
#endif
-#if SECUREWARE
+#if SECUREWARE || defined(_SCO_unix_)
set_auth_parameters(argc, argv);
+
+# ifdef _SCO_unix_
+ /*
+ ** This is required for highest security levels (the kernel
+ ** won't let it call set*uid() or run setuid binaries without
+ ** it). It may be necessary on other SECUREWARE systems.
+ */
+
+ if (getluid() == -1)
+ setluid(0);
+# endif
#endif
#ifdef VENDOR_DEFAULT
@@ -1245,6 +1256,8 @@ init_vendor_macros(e)
#define LA_DGUX 9 /* special DGUX implementation */
#define LA_HPUX 10 /* special HPUX implementation */
#define LA_IRIX6 11 /* special IRIX 6.2 implementation */
+#define LA_KSTAT 12 /* special Solaris kstat(3k) implementation */
+#define LA_DEVSHORT 13 /* read short from a device */
/* do guesses based on general OS type */
#ifndef LA_TYPE
@@ -1780,8 +1793,100 @@ int getla(void)
}
#endif
+#if LA_TYPE == LA_KSTAT
+
+#include <kstat.h>
+
+int
+getla()
+{
+ kstat_ctl_t *kc;
+ kstat_t *ksp;
+ kstat_named_t *ksn;
+ int la;
+
+ kc = kstat_open();
+ if (kc == NULL)
+ {
+ if (tTd(3, 1))
+ printf("getla: kstat_open(): %s\n",
+ errstring(errno));
+ return -1;
+ }
+ ksp = kstat_lookup(kc, "unix", 0, "system_misc"); /* NULL on error */
+ if (ksp == NULL)
+ {
+ if (tTd(3, 1))
+ printf("getla: kstat_lookup(): %s\n",
+ errstring(errno);
+ return -1;
+ }
+ if (kstat_read(kc, ksp, NULL) < 0)
+ {
+ if (tTd(3, 1))
+ printf("getla: kstat_read(): %s\n",
+ errstring(errno);
+ return -1;
+ }
+ ksn = (kstat_named_t *) kstat_data_lookup(ksp, "avenrun_1min");
+ la = (ksn->value.ul + FSCALE/2) >> FSHIFT;
+ kstat_close(kc);
+ return la;
+}
+
+#endif /* LA_TYPE == LA_KSTAT */
+
+#if LA_TYPE == LA_DEVSHORT
+
+/*
+** Read /dev/table/avenrun for the load average. This should contain
+** three shorts for the 1, 5, and 15 minute loads. We only read the
+** first, since that's all we care about.
+**
+** Intended for SCO OpenServer 5.
+*/
+
+# ifndef _PATH_AVENRUN
+# define _PATH_AVENRUN "/dev/table/avenrun"
+# endif
+
+int
+getla()
+{
+ static int afd = -1;
+ short avenrun;
+ int loadav;
+ int r;
+
+ errno = EBADF;
+
+ if (afd == -1 || lseek(afd, 0L, SEEK_SET) == -1)
+ {
+ if (errno != EBADF)
+ return -1;
+ afd = open(_PATH_AVENRUN, O_RDONLY|O_SYNC);
+ if (afd < 0)
+ {
+ syslog(LOG_ERR, "can't open %s: %m", _PATH_AVENRUN);
+ return -1;
+ }
+ }
+
+ r = read(afd, &avenrun, sizeof avenrun);
+
+ if (tTd(3, 5))
+ printf("getla: avenrun = %d\n", avenrun);
+ loadav = (int) (avenrun + FSCALE/2) >> FSHIFT;
+ if (tTd(3, 1))
+ printf("getla: %d\n", loadav);
+ return loadav;
+}
+
+#endif /* LA_TYPE == LA_DEVSHORT */
+
#if LA_TYPE == LA_ZERO
+int
getla()
{
if (tTd(3, 1))
@@ -1941,8 +2046,10 @@ refuseconnections(port)
syslog(LOG_INFO, "rejecting connections on port %d: load average: %d",
port, CurrentLA);
#endif
+ return TRUE;
}
- else if (!enoughdiskspace(MinBlocksFree + 1))
+
+ if (!enoughdiskspace(MinBlocksFree + 1))
{
setproctitle("rejecting connections on port %d: min free: %d",
port, MinBlocksFree);
@@ -1951,20 +2058,26 @@ refuseconnections(port)
syslog(LOG_INFO, "rejecting connections on port %d: min free: %d",
port, MinBlocksFree);
#endif
+ return TRUE;
}
- else if (MaxChildren > 0 && CurChildren >= MaxChildren)
+
+ if (MaxChildren > 0 && CurChildren >= MaxChildren)
{
- setproctitle("rejecting connections on port %d: %d children, max %d",
- port, CurChildren, MaxChildren);
-#ifdef LOG
- if (LogLevel >= 14)
- syslog(LOG_INFO, "rejecting connections on port %d: %d children, max %d",
+ proc_list_probe();
+ if (CurChildren >= MaxChildren)
+ {
+ setproctitle("rejecting connections on port %d: %d children, max %d",
port, CurChildren, MaxChildren);
+#ifdef LOG
+ if (LogLevel >= 14)
+ syslog(LOG_INFO, "rejecting connections on port %d: %d children, max %d",
+ port, CurChildren, MaxChildren);
#endif
+ return TRUE;
+ }
}
- else
- return FALSE;
- return TRUE;
+
+ return FALSE;
}
/*
** SETPROCTITLE -- set process title for ps
diff --git a/usr.sbin/sendmail/src/conf.h b/usr.sbin/sendmail/src/conf.h
index 69558c2..cf7cbe5 100644
--- a/usr.sbin/sendmail/src/conf.h
+++ b/usr.sbin/sendmail/src/conf.h
@@ -31,7 +31,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)conf.h 8.267 (Berkeley) 10/17/96
+ * @(#)conf.h 8.272 (Berkeley) 11/16/96
*/
/*
@@ -41,7 +41,9 @@
** included in the next release.
*/
+#ifdef __GNUC__
struct rusage; /* forward declaration to get gcc to shut up in wait.h */
+#endif
# include <sys/param.h>
# include <sys/types.h>
@@ -216,7 +218,11 @@ extern void hard_syslog(int, char *, ...);
#ifdef _AIX4
# define _AIX3 1 /* pull in AIX3 stuff */
-# define HASSETREUID 1 /* setreuid(2) works */
+# define USESETEUID 1 /* seteuid(2) works */
+# define TZ_TYPE TZ_NAME /* use tzname[] vector */
+# if _AIX4 >= 40200
+# define HASSETREUID 1 /* setreuid(2) works as of AIX 4.2 */
+# endif
#endif
@@ -409,6 +415,9 @@ typedef int pid_t;
# define snprintf __snprintf /* but names it oddly in 2.5 */
# define vsnprintf __vsnprintf
# endif
+# ifndef LA_TYPE
+# define LA_TYPE LA_KSTAT /* use kstat(3k) -- may work in < 2.5 */
+# endif
# endif
# ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */
@@ -588,6 +597,7 @@ extern long dgux_inet_addr();
# define WAITUNION 1 /* use "union wait" as wait argument type */
# define UID_T int /* compiler gripes on uid_t */
# define GID_T int /* ditto for gid_t */
+# define MODE_T int /* and mode_t */
# define sleep sleepX
# define setpgid setpgrp
# ifndef LA_TYPE
@@ -791,31 +801,43 @@ extern int errno;
** The third is for SCO UNIX 3.2v4.0/Open Desktop 2.0 and earlier.
*/
+/* SCO OpenServer 5 */
#if _SCO_DS >= 1
# include <paths.h>
# define _SCO_unix_4_2
-# define HASSNPRINTF 1 /* has snprintf() call */
-# define HASFCHMOD 1 /* has fchmod() call */
-# define HASSETRLIMIT 1 /* has setrlimit() call */
+# define HASSNPRINTF 1 /* has snprintf(3) call */
+# define HASFCHMOD 1 /* has fchmod(2) call */
+# define HASSETRLIMIT 1 /* has setrlimit(2) call */
+# define USESETEUID 1 /* has seteuid(2) call */
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define HASGETDTABLESIZE 1 /* has getdtablesize(2) call */
# define RLIMIT_NEEDS_SYS_TIME_H 1
+# ifndef LA_TYPE
+# define LA_TYPE LA_DEVSHORT
+# endif
+# define _PATH_AVENRUN "/dev/table/avenrun"
#endif
-
+/* SCO UNIX 3.2v4.2/Open Desktop 3.0 */
#ifdef _SCO_unix_4_2
# define _SCO_unix_
# define HASSETREUID 1 /* has setreuid(2) call */
#endif
+/* SCO UNIX 3.2v4.0 Open Desktop 2.0 and earlier */
#ifdef _SCO_unix_
# include <sys/stream.h> /* needed for IP_SRCROUTE */
# define SYSTEM5 1 /* include all the System V defines */
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# define NOFTRUNCATE 0 /* has (simulated) ftruncate call */
# define MAXPATHLEN PATHSIZE
-# define LA_TYPE LA_SHORT
# define SFS_TYPE SFS_4ARGS /* use <sys/statfs.h> 4-arg impl */
# define SFS_BAVAIL f_bfree /* alternate field name */
# define SPT_TYPE SPT_SCO /* write kernel u. area */
# define TZ_TYPE TZ_TM_NAME /* use tm->tm_name */
+# define UID_T uid_t
+# define GID_T gid_t
+# define GIDSET_T gid_t
# define _PATH_UNIX "/unix"
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
# ifndef _PATH_SENDMAILPID
@@ -828,9 +850,10 @@ extern int errno;
# endif
# ifndef _SCO_DS
-# define NOFTRUNCATE 0 /* does not have ftruncate(3) call */
+# define ftruncate chsize /* use chsize(2) to emulate ftruncate */
# define NEEDFSYNC 1 /* needs the fsync(2) call stub */
# define NETUNIX 0 /* no unix domain socket support */
+# define LA_TYPE LA_SHORT
# endif
#endif
@@ -1850,6 +1873,10 @@ extern int errno;
# define SIZE_T size_t
#endif
+#ifndef MODE_T
+# define MODE_T mode_t
+#endif
+
#ifndef ARGV_T
# define ARGV_T char **
#endif
diff --git a/usr.sbin/sendmail/src/daemon.c b/usr.sbin/sendmail/src/daemon.c
index aead4ff..283d7e4 100644
--- a/usr.sbin/sendmail/src/daemon.c
+++ b/usr.sbin/sendmail/src/daemon.c
@@ -37,9 +37,9 @@
#ifndef lint
#ifdef DAEMON
-static char sccsid[] = "@(#)daemon.c 8.145 (Berkeley) 10/12/96 (with daemon mode)";
+static char sccsid[] = "@(#)daemon.c 8.148 (Berkeley) 11/8/96 (with daemon mode)";
#else
-static char sccsid[] = "@(#)daemon.c 8.145 (Berkeley) 10/12/96 (without daemon mode)";
+static char sccsid[] = "@(#)daemon.c 8.148 (Berkeley) 11/8/96 (without daemon mode)";
#endif
#endif /* not lint */
@@ -193,7 +193,7 @@ getrequests(e)
for (;;)
{
- register int pid;
+ register pid_t pid;
auto int lotherend;
extern bool refuseconnections();
extern int getla();
@@ -244,6 +244,16 @@ getrequests(e)
/* wait for a connection */
setproctitle("accepting connections on port %d",
ntohs(DaemonAddr.sin.sin_port));
+#if 0
+ /*
+ ** Andrew Sun <asun@ieps-sun.ml.com> claims that this will
+ ** fix the SVr4 problem. But it seems to have gone away,
+ ** so is it worth doing this?
+ */
+
+ if (SetNonBlocking(DaemonSocket, FALSE) < 0)
+ log an error here;
+#endif
do
{
errno = 0;
@@ -734,9 +744,8 @@ makeconnection(host, port, mci, e)
extern char MsgBuf[];
usrerr("553 Invalid numeric domain spec \"%s\"", host);
- mci->mci_status = "5.1.2";
- mci->mci_rstatus = newstr(MsgBuf);
- return (EX_NOHOST);
+ mci_setstat(mci, EX_NOHOST, "5.1.2", MsgBuf);
+ return EX_NOHOST;
}
#if NETINET
addr.sin.sin_family = AF_INET; /*XXX*/
@@ -773,11 +782,11 @@ gothostent:
if (errno == ETIMEDOUT || h_errno == TRY_AGAIN ||
(errno == ECONNREFUSED && UseNameServer))
{
- mci->mci_status = "4.4.3";
- mci->mci_rstatus = NULL;
- return (EX_TEMPFAIL);
+ mci_setstat(mci, EX_TEMPFAIL, "4.4.3", NULL);
+ return EX_TEMPFAIL;
}
#endif
+ mci_setstat(mci, EX_NOHOST, "5.1.2", NULL);
return (EX_NOHOST);
}
addr.sa.sa_family = hp->h_addrtype;
@@ -839,6 +848,7 @@ gothostent:
default:
syserr("Can't connect to address family %d", addr.sa.sa_family);
+ mci_setstat(mci, EX_NOHOST, "5.1.2", NULL);
return (EX_NOHOST);
}
@@ -876,7 +886,11 @@ gothostent:
{
sav_errno = errno;
syserr("makeconnection: cannot create socket");
- goto failure;
+#ifdef XLA
+ xla_host_end(host);
+#endif
+ mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
+ return EX_TEMPFAIL;
}
#ifdef SO_SNDBUF
@@ -964,18 +978,12 @@ gothostent:
continue;
}
- /* failure, decide if temporary or not */
- failure:
+ /* couldn't open connection */
#ifdef XLA
xla_host_end(host);
#endif
- if (transienterror(sav_errno))
- return EX_TEMPFAIL;
- else
- {
- message("%s", errstring(sav_errno));
- return (EX_UNAVAILABLE);
- }
+ mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL);
+ return EX_TEMPFAIL;
}
/* connection ok, put it into canonical form */
@@ -984,9 +992,11 @@ gothostent:
(mci->mci_in = fdopen(s, "r")) == NULL)
{
syserr("cannot open SMTP client channel, fd=%d", s);
+ mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
return EX_TEMPFAIL;
}
+ mci_setstat(mci, EX_OK, NULL, NULL);
return (EX_OK);
}
/*
diff --git a/usr.sbin/sendmail/src/deliver.c b/usr.sbin/sendmail/src/deliver.c
index f446f53..c019d2b 100644
--- a/usr.sbin/sendmail/src/deliver.c
+++ b/usr.sbin/sendmail/src/deliver.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)deliver.c 8.246 (Berkeley) 10/17/96";
+static char sccsid[] = "@(#)deliver.c 8.251 (Berkeley) 11/11/96";
#endif /* not lint */
#include "sendmail.h"
@@ -78,7 +78,7 @@ sendall(e, mode)
ENVELOPE *splitenv = NULL;
bool oldverbose = Verbose;
bool somedeliveries = FALSE;
- int pid;
+ pid_t pid;
extern void sendenvelope();
/*
@@ -760,7 +760,7 @@ sendenvelope(e, mode)
int
dofork()
{
- register int pid = -1;
+ register pid_t pid = -1;
DOFORK(fork);
return (pid);
@@ -813,11 +813,12 @@ deliver(e, firstto)
ADDRESS *volatile tochain = NULL; /* users chain in this mailer call */
int rcode; /* response code */
char *firstsig; /* signature of firstto */
- int pid = -1;
+ pid_t pid = -1;
char *volatile curhost;
register volatile u_short port = 0;
time_t xstart;
bool suidwarn;
+ bool anyok; /* at least one address was OK */
int mpvect[2];
int rpvect[2];
char *pv[MAXPV+1];
@@ -1314,7 +1315,7 @@ tryhost:
if (mci_lock_host(mci) != EX_OK)
{
- mci->mci_exitstat = EX_TEMPFAIL;
+ mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
continue;
}
@@ -1840,6 +1841,7 @@ tryhost:
extern int smtpmailfrom __P((MAILER *, MCI *, ENVELOPE *));
extern int smtprcpt __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *));
extern int smtpdata __P((MAILER *, MCI *, ENVELOPE *));
+ extern int smtpgetstat __P((MAILER *, MCI *, ENVELOPE *));
/*
** Send the MAIL FROM: protocol
@@ -1883,10 +1885,6 @@ tryhost:
e->e_to = tobuf + 1;
rcode = smtpdata(m, mci, e);
}
-
- /* now close the connection */
- if (!bitset(MCIF_CACHED, mci->mci_flags))
- smtpquit(m, mci, e);
}
if (rcode == EX_TEMPFAIL && curhost != NULL && *curhost != '\0')
{
@@ -1917,11 +1915,17 @@ tryhost:
*/
give_up:
- if (tobuf[0] != '\0')
- giveresponse(rcode, m, mci, ctladdr, xstart, e);
- if (rcode == EX_OK)
- markstats(e, tochain);
- mci_store_persistent(mci);
+#ifdef SMTP
+# if FFR_LMTP
+ if (bitnset(M_LMTP, m->m_flags))
+ {
+ tobuf[0] = '\0';
+ anyok = FALSE;
+ }
+ else
+# endif
+#endif
+ anyok = rcode == EX_OK;
for (to = tochain; to != NULL; to = to->q_tchain)
{
@@ -1929,11 +1933,37 @@ tryhost:
if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
continue;
- /* mark bad addresses */
- if (rcode != EX_OK)
+#ifdef SMTP
+# if FFR_LMTP
+ /* if running LMTP, get the status for each address */
+ if (bitnset(M_LMTP, m->m_flags))
{
- markfailure(e, to, mci, rcode);
- continue;
+ rcode = smtpgetstat(m, mci, e);
+ if (rcode == EX_OK)
+ {
+ strcat(tobuf, ",");
+ strcat(tobuf, to->q_paddr);
+ anyok = TRUE;
+ }
+ else
+ {
+ e->e_to = to->q_paddr;
+ markfailure(e, to, mci, rcode);
+ giveresponse(rcode, m, mci, ctladdr, xstart, e);
+ e->e_to = tobuf + 1;
+ continue;
+ }
+ }
+ else
+# endif
+#endif
+ {
+ /* mark bad addresses */
+ if (rcode != EX_OK)
+ {
+ markfailure(e, to, mci, rcode);
+ continue;
+ }
}
/* successful delivery */
@@ -1958,6 +1988,38 @@ tryhost:
}
}
+#ifdef SMTP
+# if FFR_LMTP
+ if (bitnset(M_LMTP, m->m_flags))
+ {
+ /*
+ ** Global information applies to the last recipient only;
+ ** clear it out to avoid bogus errors.
+ */
+
+ rcode = EX_OK;
+ e->e_statmsg = NULL;
+
+ /* reset the mci state for the next transaction */
+ if (mci->mci_state == MCIS_ACTIVE)
+ mci->mci_state = MCIS_OPEN;
+ }
+# endif
+#endif
+
+ if (tobuf[0] != '\0')
+ giveresponse(rcode, m, mci, ctladdr, xstart, e);
+ if (anyok)
+ markstats(e, tochain);
+ mci_store_persistent(mci);
+
+#ifdef SMTP
+ /* now close the connection */
+ if (clever && mci->mci_state != MCIS_CLOSED &&
+ !bitset(MCIF_CACHED, mci->mci_flags))
+ smtpquit(m, mci, e);
+#endif
+
/*
** Restore state and return.
*/
@@ -2142,7 +2204,7 @@ endmailer(mci, e, pv)
st = waitfor(mci->mci_pid);
if (st == -1)
{
- syserr("endmailer %s: wait", pv[0]);
+ syserr("endmailer %s: wait", mci->mci_mailer->m_name);
return (EX_SOFTWARE);
}
@@ -2951,7 +3013,7 @@ mailfile(filename, ctladdr, sfflags, e)
register ENVELOPE *e;
{
register FILE *f;
- register int pid = -1;
+ register pid_t pid = -1;
int mode;
bool suidwarn = geteuid() == 0;
@@ -3146,9 +3208,9 @@ mailfile(filename, ctladdr, sfflags, e)
/* reset ISUID & ISGID bits for paranoid systems */
#if HASFCHMOD
- (void) fchmod(fileno(f), (int) stb.st_mode);
+ (void) fchmod(fileno(f), (MODE_T) stb.st_mode);
#else
- (void) chmod(filename, (int) stb.st_mode);
+ (void) chmod(filename, (MODE_T) stb.st_mode);
#endif
(void) xfclose(f, "mailfile", filename);
(void) fflush(stdout);
@@ -3259,10 +3321,10 @@ hostsignature(m, host, e)
/* update the connection info for this host */
mci = mci_get(hp, m);
- mci->mci_lastuse = curtime();
- mci->mci_exitstat = rcode;
mci->mci_errno = errno;
mci->mci_herrno = h_errno;
+ mci->mci_lastuse = curtime();
+ mci_setstat(mci, rcode, NULL, NULL);
/* use the original host name as signature */
nmx = 1;
diff --git a/usr.sbin/sendmail/src/domain.c b/usr.sbin/sendmail/src/domain.c
index a494baf..9203651 100644
--- a/usr.sbin/sendmail/src/domain.c
+++ b/usr.sbin/sendmail/src/domain.c
@@ -36,9 +36,9 @@
#ifndef lint
#if NAMED_BIND
-static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (with name server)";
+static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (with name server)";
#else
-static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (without name server)";
+static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (without name server)";
#endif
#endif /* not lint */
@@ -48,10 +48,23 @@ static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (without name serve
#include <resolv.h>
#include <arpa/inet.h>
+/*
+** The standard udp packet size PACKETSZ (512) is not sufficient for some
+** nameserver answers containing very many resource records. The resolver
+** may switch to tcp and retry if it detects udp packet overflow.
+** Also note that the resolver routines res_query and res_search return
+** the size of the *un*truncated answer in case the supplied answer buffer
+** it not big enough to accommodate the entire answer.
+*/
+
+#ifndef MAXPACKET
+# define MAXPACKET 8192 /* max packet size used internally by BIND */
+#endif
+
typedef union
{
HEADER qb1;
- u_char qb2[PACKETSZ];
+ u_char qb2[MAXPACKET];
} querybuf;
#ifndef MXHOSTBUFSIZE
@@ -206,6 +219,10 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
return (-1);
}
+ /* avoid problems after truncation in tcp packets */
+ if (n > sizeof(answer))
+ n = sizeof(answer);
+
/* find first satisfactory answer */
hp = (HEADER *)&answer;
cp = (u_char *)&answer + HFIXEDSZ;
@@ -515,7 +532,7 @@ dns_getcanonname(host, hbsize, trymx, statp)
int qtype;
int loopcnt;
char *xp;
- char nbuf[MAX(PACKETSZ, MAXDNAME*2+2)];
+ char nbuf[MAX(MAXPACKET, MAXDNAME*2+2)];
char *searchlist[MAXDNSRCH+2];
extern char *gethostalias();
@@ -648,6 +665,10 @@ cnameloop:
else if (tTd(8, 7))
printf("\tYES\n");
+ /* avoid problems after truncation in tcp packets */
+ if (ret > sizeof(answer))
+ ret = sizeof(answer);
+
/*
** Appear to have a match. Confirm it by searching for A or
** CNAME records. If we don't have a local domain
diff --git a/usr.sbin/sendmail/src/envelope.c b/usr.sbin/sendmail/src/envelope.c
index 66b9773..80e5ce6 100644
--- a/usr.sbin/sendmail/src/envelope.c
+++ b/usr.sbin/sendmail/src/envelope.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)envelope.c 8.93 (Berkeley) 9/26/96";
+static char sccsid[] = "@(#)envelope.c 8.96 (Berkeley) 11/11/96";
#endif /* not lint */
#include "sendmail.h"
@@ -153,9 +153,24 @@ dropenvelope(e, fulldrop)
e->e_flags &= ~EF_QUEUERUN;
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
{
- if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags) ||
- bitset(QQUEUEUP, q->q_flags))
+ if (bitset(QQUEUEUP, q->q_flags) &&
+ bitset(QDONTSEND, q->q_flags))
+ {
+ /* I'm not sure how this happens..... */
+ if (tTd(50, 2))
+ {
+ printf("Bogus flags: ");
+ printaddr(q, FALSE);
+ }
+ q->q_flags &= ~QDONTSEND;
+ }
+ if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags))
queueit = TRUE;
+#if XDEBUG
+ else if (bitset(QQUEUEUP, q->q_flags))
+ syslog(LOG_DEBUG, "%s: q_flags = %x",
+ e->e_id, q->q_flags);
+#endif
/* see if a notification is needed */
if (bitset(QPINGONFAILURE, q->q_flags) &&
@@ -203,8 +218,7 @@ dropenvelope(e, fulldrop)
fprintf(e->e_xfp, "Message will be deleted from queue\n");
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
{
- if (bitset(QQUEUEUP, q->q_flags) ||
- !bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags))
+ if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags))
{
q->q_flags |= QBADADDR;
q->q_status = "4.4.7";
diff --git a/usr.sbin/sendmail/src/main.c b/usr.sbin/sendmail/src/main.c
index 8947d11..29b5ac1 100644
--- a/usr.sbin/sendmail/src/main.c
+++ b/usr.sbin/sendmail/src/main.c
@@ -39,7 +39,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)main.c 8.211 (Berkeley) 10/12/96";
+static char sccsid[] = "@(#)main.c 8.215 (Berkeley) 11/16/96";
#endif /* not lint */
#define _DEFINE
@@ -387,12 +387,18 @@ main(argc, argv, envp)
OpMode = MD_DELIVER;
FullName = getextenv("NAME");
+ /*
+ ** Initialize name server if it is going to be used.
+ */
+
#if NAMED_BIND
- if (tTd(8, 8))
- {
+ if (!bitset(RES_INIT, _res.options))
res_init();
+ if (tTd(8, 8))
_res.options |= RES_DEBUG;
- }
+# ifdef RES_NOALIASES
+ _res.options |= RES_NOALIASES;
+# endif
#endif
errno = 0;
@@ -513,15 +519,7 @@ main(argc, argv, envp)
{
case MD_DAEMON:
case MD_FGDAEMON:
-# ifdef DAEMON
- if (RealUid != 0)
- {
- usrerr("Permission denied");
- exit(EX_USAGE);
- }
- vendor_daemon_setup(CurEnv);
- /* fall through ... */
-# else
+# ifndef DAEMON
usrerr("Daemon mode not implemented");
ExitStat = EX_USAGE;
break;
@@ -534,8 +532,6 @@ main(argc, argv, envp)
# endif /* SMTP */
case MD_INITALIAS:
- /* fall through ... */
-
case MD_DELIVER:
case MD_VERIFY:
case MD_TEST:
@@ -845,18 +841,6 @@ main(argc, argv, envp)
}
/*
- ** Initialize name server if it is going to be used.
- */
-
-#if NAMED_BIND
- if (UseNameServer && !bitset(RES_INIT, _res.options))
- res_init();
-# ifdef RES_NOALIASES
- _res.options |= RES_NOALIASES;
-# endif
-#endif
-
- /*
** Do more command line checking -- these are things that
** have to modify the results of reading the config file.
*/
@@ -897,8 +881,8 @@ main(argc, argv, envp)
/* check for sane configuration level */
if (ConfigLevel > MAXCONFIGLEVEL)
{
- syserr("Warning: .cf version level (%d) exceeds program functionality (%d)",
- ConfigLevel, MAXCONFIGLEVEL);
+ syserr("Warning: .cf version level (%d) exceeds sendmail version %s functionality (%d)",
+ ConfigLevel, Version, MAXCONFIGLEVEL);
}
/* need MCI cache to have persistence */
@@ -931,6 +915,19 @@ main(argc, argv, envp)
/* fall through ... */
case MD_DAEMON:
+ /* check for permissions */
+ if (RealUid != 0)
+ {
+#ifdef LOG
+ if (LogLevel > 1)
+ syslog(LOG_ALERT, "user %d attempted to run daemon",
+ RealUid);
+#endif
+ usrerr("Permission denied");
+ exit(EX_USAGE);
+ }
+ vendor_daemon_setup(CurEnv);
+
/* remove things that don't make sense in daemon mode */
FullName = NULL;
GrabTo = FALSE;
@@ -1964,6 +1961,15 @@ sighup()
syslog(LOG_INFO, "restarting %s on signal", SaveArgv[0]);
#endif
releasesignal(SIGHUP);
+ if (setgid(RealGid) < 0 || setuid(RealUid) < 0)
+ {
+#ifdef LOG
+ if (LogLevel > 0)
+ syslog(LOG_ALERT, "could not set[ug]id(%d, %d): %m",
+ RealUid, RealGid);
+#endif
+ exit(EX_OSERR);
+ }
execv(SaveArgv[0], (ARGV_T) SaveArgv);
#ifdef LOG
if (LogLevel > 0)
diff --git a/usr.sbin/sendmail/src/map.c b/usr.sbin/sendmail/src/map.c
index 796e472..34e6fce 100644
--- a/usr.sbin/sendmail/src/map.c
+++ b/usr.sbin/sendmail/src/map.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)map.c 8.140 (Berkeley) 10/12/96";
+static char sccsid[] = "@(#)map.c 8.144 (Berkeley) 11/16/96";
#endif /* not lint */
#include "sendmail.h"
@@ -107,7 +107,7 @@ static char sccsid[] = "@(#)map.c 8.140 (Berkeley) 10/12/96";
extern bool aliaswait __P((MAP *, char *, int));
extern bool extract_canonname __P((char *, char *, char[], int));
-#if defined(O_EXLOCK) && HASFLOCK
+#if O_EXLOCK && HASFLOCK
# define LOCK_ON_OPEN 1 /* we can open/create a locked file */
#else
# define LOCK_ON_OPEN 0 /* no such luck -- bend over backwards */
@@ -690,6 +690,8 @@ extract_canonname(name, line, cbuf, cbuflen)
p = get_column(line, i, '\0', nbuf, sizeof nbuf);
if (p == NULL)
break;
+ if (*p == '\0')
+ continue;
if (cbuf[0] == '\0' ||
(strchr(cbuf, '.') == NULL && strchr(p, '.') != NULL))
{
@@ -1034,17 +1036,30 @@ ndbm_map_close(map)
** be pokey about it. That's hard to do.
*/
-extern bool db_map_open __P((MAP *, int, DBTYPE));
+extern bool db_map_open __P((MAP *, int, DBTYPE, const void *));
+
+/* these should be K line arguments */
+#ifndef DB_CACHE_SIZE
+# define DB_CACHE_SIZE (1024 * 1024) /* database memory cache size */
+#endif
+#ifndef DB_HASH_NELEM
+# define DB_HASH_NELEM 4096 /* (starting) size of hash table */
+#endif
bool
bt_map_open(map, mode)
MAP *map;
int mode;
{
+ BTREEINFO btinfo;
+
if (tTd(38, 2))
printf("bt_map_open(%s, %s, %d)\n",
map->map_mname, map->map_file, mode);
- return db_map_open(map, mode, DB_BTREE);
+
+ bzero(&btinfo, sizeof btinfo);
+ btinfo.cachesize = DB_CACHE_SIZE;
+ return db_map_open(map, mode, DB_BTREE, &btinfo);
}
bool
@@ -1052,17 +1067,24 @@ hash_map_open(map, mode)
MAP *map;
int mode;
{
+ HASHINFO hinfo;
+
if (tTd(38, 2))
printf("hash_map_open(%s, %s, %d)\n",
map->map_mname, map->map_file, mode);
- return db_map_open(map, mode, DB_HASH);
+
+ bzero(&hinfo, sizeof hinfo);
+ hinfo.nelem = DB_HASH_NELEM;
+ hinfo.cachesize = DB_CACHE_SIZE;
+ return db_map_open(map, mode, DB_HASH, &hinfo);
}
bool
-db_map_open(map, mode, dbtype)
+db_map_open(map, mode, dbtype, openinfo)
MAP *map;
int mode;
DBTYPE dbtype;
+ const void *openinfo;
{
DB *db;
int i;
@@ -1113,7 +1135,7 @@ db_map_open(map, mode, dbtype)
omode |= O_TRUNC;
#endif
- db = dbopen(buf, omode, DBMMODE, dbtype, NULL);
+ db = dbopen(buf, omode, DBMMODE, dbtype, openinfo);
saveerrno = errno;
#if !LOCK_ON_OPEN
diff --git a/usr.sbin/sendmail/src/mci.c b/usr.sbin/sendmail/src/mci.c
index f901ea8..18e951a 100644
--- a/usr.sbin/sendmail/src/mci.c
+++ b/usr.sbin/sendmail/src/mci.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)mci.c 8.44 (Berkeley) 10/9/96";
+static char sccsid[] = "@(#)mci.c 8.46 (Berkeley) 11/3/96";
#endif /* not lint */
#include "sendmail.h"
@@ -362,6 +362,7 @@ mci_get(host, m)
**
** Parameters:
** mci -- the MCI structure to set.
+** xstat -- the exit status code.
** dstat -- the DSN status code.
** rstat -- the SMTP status code.
**
@@ -370,18 +371,19 @@ mci_get(host, m)
*/
void
-mci_setstat(mci, dstat, rstat)
+mci_setstat(mci, xstat, dstat, rstat)
MCI *mci;
+ int xstat;
char *dstat;
char *rstat;
{
+ mci->mci_exitstat = xstat;
mci->mci_status = dstat;
+ if (mci->mci_rstatus != NULL)
+ free(mci->mci_rstatus);
if (rstat != NULL)
- {
- if (mci->mci_rstatus != NULL)
- free(mci->mci_rstatus);
- mci->mci_rstatus = newstr(rstat);
- }
+ rstat = newstr(rstat);
+ mci->mci_rstatus = rstat;
}
/*
** MCI_DUMP -- dump the contents of an MCI structure.
@@ -1032,6 +1034,7 @@ mci_print_persistent(pathname, hostname)
int status;
int width = Verbose ? 78 : 25;
bool locked;
+ char *p;
MCI mcib;
if (!initflag)
@@ -1061,16 +1064,34 @@ mci_print_persistent(pathname, hostname)
locked = !lockfile(fileno(fp), pathname, "", LOCK_EX|LOCK_NB);
fclose(fp);
- if (mcib.mci_rstatus == NULL)
- printf("%c%-39s %12s %.*s\n",
- locked ? '*' : ' ', hostname,
- pintvl(curtime() - mcib.mci_lastuse, TRUE),
- width, errstring(mcib.mci_errno));
+ printf("%c%-39s %12s ",
+ locked ? '*' : ' ', hostname,
+ pintvl(curtime() - mcib.mci_lastuse, TRUE));
+ if (mcib.mci_rstatus != NULL)
+ printf("%.*s\n", width, mcib.mci_rstatus);
+ else if (mcib.mci_exitstat == EX_TEMPFAIL && mcib.mci_errno != 0)
+ printf("Deferred: %.*s\n", width - 10, errstring(mcib.mci_errno));
+ else if (mcib.mci_exitstat != 0)
+ {
+ int i = mcib.mci_exitstat - EX__BASE;
+ extern int N_SysEx;
+ extern char *SysExMsg[];
+
+ if (i < 0 || i > N_SysEx)
+ {
+ char buf[80];
+
+ snprintf(buf, sizeof buf, "Unknown mailer error %d",
+ mcib.mci_exitstat);
+ printf("%.*s\n", width, buf);
+ }
+ else
+ printf("%.*s\n", width, &(SysExMsg[i])[5]);
+ }
+ else if (mcib.mci_errno == 0)
+ printf("OK\n");
else
- printf("%c%-39s %12s %.*s\n",
- locked ? '*' : ' ', hostname,
- pintvl(curtime() - mcib.mci_lastuse, TRUE),
- width, mcib.mci_rstatus);
+ printf("OK: %.*s\n", width - 4, errstring(mcib.mci_errno));
return 0;
}
diff --git a/usr.sbin/sendmail/src/mime.c b/usr.sbin/sendmail/src/mime.c
index 670a6cd..9ee726a 100644
--- a/usr.sbin/sendmail/src/mime.c
+++ b/usr.sbin/sendmail/src/mime.c
@@ -36,7 +36,7 @@
# include <string.h>
#ifndef lint
-static char sccsid[] = "@(#)mime.c 8.48 (Berkeley) 10/18/96";
+static char sccsid[] = "@(#)mime.c 8.49 (Berkeley) 10/30/96";
#endif /* not lint */
/*
@@ -932,9 +932,23 @@ isboundary(line, boundaries)
** none.
*/
-extern void mime_from64 __P((u_char *, u_char *, int));
extern int mime_fromqp __P((u_char *, u_char **, int, int));
+static char index_64[128] =
+{
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
+ 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
+ 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
+ -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
+ 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
+};
+
+#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
+
+
void
mime7to8(mci, header, e)
register MCI *mci;
@@ -996,29 +1010,82 @@ mime7to8(mci, header, e)
if (strcasecmp(cte, "base64") == 0)
{
+ int nchar = 0;
+ int c1, c2, c3, c4;
+
fbufp = fbuf;
- while (fgets(buf, sizeof buf, e->e_dfp) != NULL)
+ while ((c1 = fgetc(e->e_dfp)) != EOF)
{
- obufp = obuf;
- mime_from64((u_char *) buf, obuf, MAXLINE);
- while ((ch = *obufp++) != '\0')
+ if (isascii(c1) && isspace(c1))
+ continue;
+
+ do
{
- *fbufp++ = ch;
- if (ch == '\n' || fbufp >= &fbuf[MAXLINE])
- {
- *fbufp = '\0';
- putline((char *) fbuf, mci);
- fbufp = fbuf;
- }
- }
+ c2 = fgetc(e->e_dfp);
+ } while (isascii(c2) && isspace(c2));
+ if (c2 == EOF)
+ break;
- /* force out partial last line */
- if (fbufp > fbuf)
+ do
{
+ c3 = fgetc(e->e_dfp);
+ } while (isascii(c3) && isspace(c3));
+ if (c3 == EOF)
+ break;
+
+ do
+ {
+ c4 = fgetc(e->e_dfp);
+ } while (isascii(c4) && isspace(c4));
+ if (c4 == EOF)
+ break;
+
+ if (c1 == '=' || c2 == '=')
+ continue;
+ c1 = CHAR64(c1);
+ c2 = CHAR64(c2);
+
+ *fbufp = (c1 << 2) | ((c2 & 0x30) >> 4);
+ if (*fbufp++ == '\n' || fbuf >= &fbuf[MAXLINE])
+ {
+ if (*--fbufp != '\n' || *--fbufp != '\r')
+ fbufp++;
+ *fbufp = '\0';
+ putline((char *) fbuf, mci);
+ fbufp = fbuf;
+ }
+ if (c3 == '=')
+ continue;
+ c3 = CHAR64(c3);
+ *fbufp = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
+ if (*fbufp++ == '\n' || fbuf >= &fbuf[MAXLINE])
+ {
+ if (*--fbufp != '\n' || *--fbufp != '\r')
+ fbufp++;
+ *fbufp = '\0';
+ putline((char *) fbuf, mci);
+ fbufp = fbuf;
+ }
+ if (c4 == '=')
+ continue;
+ c4 = CHAR64(c4);
+ *fbufp = ((c3 & 0x03) << 6) | c4;
+ if (*fbufp++ == '\n' || fbuf >= &fbuf[MAXLINE])
+ {
+ if (*--fbufp != '\n' || *--fbufp != '\r')
+ fbufp++;
*fbufp = '\0';
putline((char *) fbuf, mci);
+ fbufp = fbuf;
}
}
+
+ /* force out partial last line */
+ if (fbufp > fbuf)
+ {
+ *fbufp = '\0';
+ putline((char *) fbuf, mci);
+ }
}
else
{
@@ -1113,89 +1180,5 @@ mime_fromqp(infile, outfile, state, maxlen)
return 1;
}
-static char index_64[128] =
-{
- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
- 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
- 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
- -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
- 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
-};
-
-#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
-
-void
-mime_from64(infile, outfile, maxlen)
- u_char *infile;
- u_char *outfile;
- int maxlen;
-{
- int nchar = 0;
- int c1, c2, c3, c4;
-
- while ((c1 = *infile++) != '\0')
- {
- if (isascii(c1) && isspace(c1))
- continue;
-
- do
- {
- c2 = *infile++;
- } while (isascii(c2) && isspace(c2));
- if (c2 == '\0')
- break;
-
- do
- {
- c3 = *infile++;
- } while (isascii(c3) && isspace(c3));
- if (c3 == '\0')
- break;
-
- do
- {
- c4 = *infile++;
- } while (isascii(c4) && isspace(c4));
- if (c4 == '\0')
- break;
-
- if (c1 == '=' || c2 == '=')
- {
- continue;
- }
- c1 = CHAR64(c1);
- c2 = CHAR64(c2);
-
- if (++nchar > maxlen)
- break;
-
- *outfile++ = (c1 << 2) | ((c2 & 0x30) >> 4);
-
- if (c3 != '=')
- {
- c3 = CHAR64(c3);
-
- if (++nchar > maxlen)
- break;
-
- *outfile++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
- if (c4 != '=')
- {
- c4 = CHAR64(c4);
-
- if (++nchar > maxlen)
- break;
-
- *outfile++ = ((c3 & 0x03) << 6) | c4;
- }
- }
- }
-
- *outfile = '\0';
- return;
-}
#endif /* MIME7TO8 */
diff --git a/usr.sbin/sendmail/src/queue.c b/usr.sbin/sendmail/src/queue.c
index 75263b7..299a016 100644
--- a/usr.sbin/sendmail/src/queue.c
+++ b/usr.sbin/sendmail/src/queue.c
@@ -36,9 +36,9 @@
#ifndef lint
#ifdef QUEUE
-static char sccsid[] = "@(#)queue.c 8.125 (Berkeley) 10/12/96 (with queueing)";
+static char sccsid[] = "@(#)queue.c 8.131 (Berkeley) 11/8/96 (with queueing)";
#else
-static char sccsid[] = "@(#)queue.c 8.125 (Berkeley) 10/12/96 (without queueing)";
+static char sccsid[] = "@(#)queue.c 8.131 (Berkeley) 11/8/96 (without queueing)";
#endif
#endif /* not lint */
@@ -296,40 +296,45 @@ queueup(e, announce)
printctladdr(NULL, NULL);
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
{
- if (bitset(QQUEUEUP, q->q_flags) ||
- !bitset(QDONTSEND|QBADADDR|QSENT, q->q_flags))
+ if (bitset(QDONTSEND|QBADADDR|QSENT, q->q_flags))
{
- printctladdr(q, tfp);
- if (q->q_orcpt != NULL)
- fprintf(tfp, "Q%s\n",
- denlstring(q->q_orcpt, TRUE, FALSE));
- putc('R', tfp);
- if (bitset(QPRIMARY, q->q_flags))
- putc('P', tfp);
- if (bitset(QHASNOTIFY, q->q_flags))
- putc('N', tfp);
- if (bitset(QPINGONSUCCESS, q->q_flags))
- putc('S', tfp);
- if (bitset(QPINGONFAILURE, q->q_flags))
- putc('F', tfp);
- if (bitset(QPINGONDELAY, q->q_flags))
- putc('D', tfp);
- putc(':', tfp);
- fprintf(tfp, "%s\n", denlstring(q->q_paddr, TRUE, FALSE));
- if (announce)
- {
- e->e_to = q->q_paddr;
- message("queued");
- if (LogLevel > 8)
- logdelivery(q->q_mailer, NULL, "queued",
- NULL, (time_t) 0, e);
- e->e_to = NULL;
- }
- if (tTd(40, 1))
- {
- printf("queueing ");
- printaddr(q, FALSE);
- }
+#if XDEBUG
+ if (bitset(QQUEUEUP, q->q_flags))
+ syslog(LOG_DEBUG, "%s: q_flags = %x",
+ e->e_id, q->q_flags);
+#endif
+ continue;
+ }
+ printctladdr(q, tfp);
+ if (q->q_orcpt != NULL)
+ fprintf(tfp, "Q%s\n",
+ denlstring(q->q_orcpt, TRUE, FALSE));
+ putc('R', tfp);
+ if (bitset(QPRIMARY, q->q_flags))
+ putc('P', tfp);
+ if (bitset(QHASNOTIFY, q->q_flags))
+ putc('N', tfp);
+ if (bitset(QPINGONSUCCESS, q->q_flags))
+ putc('S', tfp);
+ if (bitset(QPINGONFAILURE, q->q_flags))
+ putc('F', tfp);
+ if (bitset(QPINGONDELAY, q->q_flags))
+ putc('D', tfp);
+ putc(':', tfp);
+ fprintf(tfp, "%s\n", denlstring(q->q_paddr, TRUE, FALSE));
+ if (announce)
+ {
+ e->e_to = q->q_paddr;
+ message("queued");
+ if (LogLevel > 8)
+ logdelivery(q->q_mailer, NULL, "queued",
+ NULL, (time_t) 0, e);
+ e->e_to = NULL;
+ }
+ if (tTd(40, 1))
+ {
+ printf("queueing ");
+ printaddr(q, FALSE);
}
}
@@ -574,7 +579,7 @@ runqueue(forkflag)
if (forkflag)
{
- int pid;
+ pid_t pid;
extern void intsig();
#ifdef SIGCHLD
extern void reapchild();
@@ -625,6 +630,15 @@ runqueue(forkflag)
/* force it to run expensive jobs */
NoConnect = FALSE;
+ /* drop privileges */
+ if (geteuid() == (uid_t) 0)
+ {
+ if (RunAsGid != (gid_t) 0)
+ (void) setgid(RunAsGid);
+ if (RunAsUid != (uid_t) 0)
+ (void) setuid(RunAsUid);
+ }
+
/*
** Create ourselves an envelope
*/
@@ -1387,6 +1401,7 @@ readqf(e)
struct stat st;
char *bp;
int qfver = 0;
+ long hdrsize = 0;
register char *p;
char *orcpt = NULL;
bool nomore = FALSE;
@@ -1579,6 +1594,7 @@ readqf(e)
case 'H': /* header */
(void) chompheader(&bp[1], FALSE, NULL, e);
+ hdrsize += strlen(&bp[1]);
break;
case 'M': /* message */
@@ -1611,6 +1627,26 @@ readqf(e)
case 'N': /* number of delivery attempts */
e->e_ntries = atoi(&buf[1]);
+
+ /* if this has been tried recently, let it be */
+ if (e->e_ntries > 0 &&
+ (curtime() - e->e_dtime) < MinQueueAge)
+ {
+ char *howlong = pintvl(curtime() - e->e_dtime, TRUE);
+ extern void unlockqueue();
+
+ if (Verbose || tTd(40, 8))
+ printf("%s: too young (%s)\n",
+ e->e_id, howlong);
+#ifdef LOG
+ if (LogLevel > 19)
+ syslog(LOG_DEBUG, "%s: too young (%s)",
+ e->e_id, howlong);
+#endif
+ e->e_id = NULL;
+ unlockqueue(e);
+ return FALSE;
+ }
break;
case 'P': /* message priority */
@@ -1694,25 +1730,6 @@ readqf(e)
return TRUE;
}
- /* if this has been tried recently, let it be */
- if (e->e_ntries > 0 && (curtime() - e->e_dtime) < MinQueueAge)
- {
- char *howlong = pintvl(curtime() - e->e_dtime, TRUE);
- extern void unlockqueue();
-
- if (Verbose || tTd(40, 8))
- printf("%s: too young (%s)\n",
- e->e_id, howlong);
-#ifdef LOG
- if (LogLevel > 19)
- syslog(LOG_DEBUG, "%s: too young (%s)",
- e->e_id, howlong);
-#endif
- e->e_id = NULL;
- unlockqueue(e);
- return FALSE;
- }
-
/*
** Arrange to read the data file.
*/
@@ -1728,7 +1745,7 @@ readqf(e)
e->e_flags |= EF_HAS_DF;
if (fstat(fileno(e->e_dfp), &st) >= 0)
{
- e->e_msgsize = st.st_size;
+ e->e_msgsize = st.st_size + hdrsize;
e->e_dfdev = st.st_dev;
e->e_dfino = st.st_ino;
}
@@ -1971,7 +1988,7 @@ queuename(e, type)
register ENVELOPE *e;
int type;
{
- static int pid = -1;
+ static pid_t pid = -1;
static char c0;
static char c1;
static char c2;
diff --git a/usr.sbin/sendmail/src/readcf.c b/usr.sbin/sendmail/src/readcf.c
index e3cb3a1..c95a6f3 100644
--- a/usr.sbin/sendmail/src/readcf.c
+++ b/usr.sbin/sendmail/src/readcf.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)readcf.c 8.174 (Berkeley) 10/9/96";
+static char sccsid[] = "@(#)readcf.c 8.176 (Berkeley) 11/10/96";
#endif /* not lint */
# include "sendmail.h"
@@ -715,7 +715,7 @@ fileclass(class, filename, fmt, safe, optional)
{
FILE *f;
int sff;
- int pid;
+ pid_t pid;
register char *p;
char buf[MAXLINE];
@@ -1024,6 +1024,10 @@ makemailer(line)
m->m_uid = strtol(p, &q, 0);
p = q;
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (*p != '\0')
+ p++;
}
while (isascii(*p) && isspace(*p))
p++;
diff --git a/usr.sbin/sendmail/src/sendmail.h b/usr.sbin/sendmail/src/sendmail.h
index 62b0bb9..2dc30e4 100644
--- a/usr.sbin/sendmail/src/sendmail.h
+++ b/usr.sbin/sendmail/src/sendmail.h
@@ -31,7 +31,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)sendmail.h 8.206 (Berkeley) 10/17/96
+ * @(#)sendmail.h 8.209 (Berkeley) 11/8/96
*/
/*
@@ -41,7 +41,7 @@
# ifdef _DEFINE
# define EXTERN
# ifndef lint
-static char SmailSccsId[] = "@(#)sendmail.h 8.206 10/17/96";
+static char SmailSccsId[] = "@(#)sendmail.h 8.209 11/8/96";
# endif
# else /* _DEFINE */
# define EXTERN extern
@@ -275,6 +275,7 @@ struct mailer
# define M_HASPWENT 'w' /* check for /etc/passwd entry */
/* 'x' CF: include Full-Name: */
# define M_XDOT 'X' /* use hidden-dot algorithm */
+# define M_LMTP 'z' /* run Local Mail Transport Protocol */
# define M_NOMX '0' /* turn off MX lookups */
# define M_EBCDIC '3' /* extend Q-P encoding for EBCDIC */
# define M_TRYRULESET5 '5' /* use ruleset 5 after local aliasing */
@@ -310,7 +311,7 @@ MCI
long mci_maxsize; /* max size this server will accept */
FILE *mci_in; /* input side of connection */
FILE *mci_out; /* output side of connection */
- int mci_pid; /* process id of subordinate proc */
+ pid_t mci_pid; /* process id of subordinate proc */
char *mci_phase; /* SMTP phase string */
struct mailer *mci_mailer; /* ptr to the mailer for this conn */
char *mci_host; /* host name */
@@ -1095,7 +1096,7 @@ EXTERN gid_t RealGid; /* real gid of caller */
EXTERN uid_t DefUid; /* default uid to run as */
EXTERN gid_t DefGid; /* default gid to run as */
EXTERN char *DefUser; /* default user to run as (from DefUid) */
-EXTERN int OldUmask; /* umask when sendmail starts up */
+EXTERN MODE_T OldUmask; /* umask when sendmail starts up */
EXTERN int Errors; /* set if errors (local to single pass) */
EXTERN int ExitStat; /* exit status code */
EXTERN int LineNumber; /* line number in current input */
@@ -1303,7 +1304,7 @@ extern void inittimeouts __P((char *));
extern void logdelivery __P((MAILER *, MCI *, const char *, ADDRESS *, time_t, ENVELOPE *));
extern void giveresponse __P((int, MAILER *, MCI *, ADDRESS *, time_t, ENVELOPE *));
extern void buildfname __P((char *, char *, char *, int));
-extern void mci_setstat __P((MCI *, char *, char *));
+extern void mci_setstat __P((MCI *, int, char *, char *));
extern char *smtptodsn __P((int));
extern int rscheck __P((char *, char *, char *, ENVELOPE *e));
extern void mime7to8 __P((MCI *, HDR *, ENVELOPE *));
diff --git a/usr.sbin/sendmail/src/srvrsmtp.c b/usr.sbin/sendmail/src/srvrsmtp.c
index cda3ca8..062acde 100644
--- a/usr.sbin/sendmail/src/srvrsmtp.c
+++ b/usr.sbin/sendmail/src/srvrsmtp.c
@@ -36,9 +36,9 @@
#ifndef lint
#ifdef SMTP
-static char sccsid[] = "@(#)srvrsmtp.c 8.123 (Berkeley) 10/12/96 (with SMTP)";
+static char sccsid[] = "@(#)srvrsmtp.c 8.125 (Berkeley) 11/8/96 (with SMTP)";
#else
-static char sccsid[] = "@(#)srvrsmtp.c 8.123 (Berkeley) 10/12/96 (without SMTP)";
+static char sccsid[] = "@(#)srvrsmtp.c 8.125 (Berkeley) 11/8/96 (without SMTP)";
#endif
#endif /* not lint */
@@ -1270,10 +1270,20 @@ runinchild(label, e)
char *label;
register ENVELOPE *e;
{
- int childpid;
+ pid_t childpid;
+ sigfunc_t chldsig;
if (!OneXact)
{
+ /*
+ ** Disable child process reaping, in case ETRN has preceeded
+ ** MAIL command.
+ */
+
+#ifdef SIGCHLD
+ chldsig = setsignal(SIGCHLD, SIG_IGN);
+#endif
+
childpid = dofork();
if (childpid < 0)
{
@@ -1300,6 +1310,11 @@ runinchild(label, e)
finis();
}
+#ifdef SIGCHLD
+ /* restore the child signal */
+ (void) setsignal(SIGCHLD, chldsig);
+#endif
+
return (1);
}
else
diff --git a/usr.sbin/sendmail/src/usersmtp.c b/usr.sbin/sendmail/src/usersmtp.c
index 1b684fb..1be0d84 100644
--- a/usr.sbin/sendmail/src/usersmtp.c
+++ b/usr.sbin/sendmail/src/usersmtp.c
@@ -36,9 +36,9 @@
#ifndef lint
#ifdef SMTP
-static char sccsid[] = "@(#)usersmtp.c 8.72 (Berkeley) 9/15/96 (with SMTP)";
+static char sccsid[] = "@(#)usersmtp.c 8.75 (Berkeley) 11/6/96 (with SMTP)";
#else
-static char sccsid[] = "@(#)usersmtp.c 8.72 (Berkeley) 9/15/96 (without SMTP)";
+static char sccsid[] = "@(#)usersmtp.c 8.75 (Berkeley) 11/6/96 (without SMTP)";
#endif
#endif /* not lint */
@@ -143,8 +143,10 @@ smtpinit(m, mci, e)
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)
+ if (r < 0)
goto tempfail1;
+ if (REPLYTYPE(r) == 4)
+ goto tempfail2;
if (REPLYTYPE(r) != 2)
goto unavailable;
@@ -153,11 +155,24 @@ smtpinit(m, mci, e)
** My mother taught me to always introduce myself.
*/
+#if FFR_LMTP
+ if (bitnset(M_ESMTP, m->m_flags) || bitnset(M_LMTP, m->m_flags))
+#else
if (bitnset(M_ESMTP, m->m_flags))
+#endif
mci->mci_flags |= MCIF_ESMTP;
tryhelo:
+#if FFR_LMTP
+ if (bitnset(M_LMTP, m->m_flags))
+ {
+ smtpmessage("LHLO %s", m, mci, MyHostName);
+ SmtpPhase = mci->mci_phase = "client LHLO";
+ }
+ else if (bitset(MCIF_ESMTP, mci->mci_flags))
+#else
if (bitset(MCIF_ESMTP, mci->mci_flags))
+#endif
{
smtpmessage("EHLO %s", m, mci, MyHostName);
SmtpPhase = mci->mci_phase = "client EHLO";
@@ -173,7 +188,12 @@ tryhelo:
goto tempfail1;
else if (REPLYTYPE(r) == 5)
{
+#if FFR_LMTP
+ if (bitset(MCIF_ESMTP, mci->mci_flags) &&
+ !bitnset(M_LMTP, m->m_flags))
+#else
if (bitset(MCIF_ESMTP, mci->mci_flags))
+#endif
{
/* try old SMTP instead */
mci->mci_flags &= ~MCIF_ESMTP;
@@ -182,7 +202,7 @@ tryhelo:
goto unavailable;
}
else if (REPLYTYPE(r) != 2)
- goto tempfail1;
+ goto tempfail2;
/*
** Check to see if we actually ended up talking to ourself.
@@ -194,11 +214,14 @@ tryhelo:
if (p != NULL)
*p = '\0';
if (!bitnset(M_NOLOOPCHECK, m->m_flags) &&
+#if FFR_LMTP
+ !bitnset(M_LMTP, m->m_flags) &&
+#endif
strcasecmp(&SmtpReplyBuffer[4], MyHostName) == 0)
{
syserr("553 %s config error: mail loops back to me (MX problem?)",
mci->mci_host);
- mci->mci_exitstat = EX_CONFIG;
+ mci_setstat(mci, EX_CONFIG, NULL, NULL);
mci->mci_errno = 0;
smtpquit(m, mci, e);
return;
@@ -215,7 +238,7 @@ tryhelo:
smtpmessage("VERB", m, mci);
r = reply(m, mci, e, TimeOuts.to_miscshort, NULL);
if (r < 0)
- goto tempfail2;
+ goto tempfail1;
}
if (mci->mci_state != MCIS_CLOSED)
@@ -227,17 +250,25 @@ tryhelo:
/* got a 421 error code during startup */
tempfail1:
+ if (mci->mci_errno == 0)
+ mci->mci_errno = errno;
+ mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL);
+ if (mci->mci_state != MCIS_CLOSED)
+ smtpquit(m, mci, e);
+ return;
+
tempfail2:
- mci->mci_exitstat = EX_TEMPFAIL;
if (mci->mci_errno == 0)
mci->mci_errno = errno;
+ /* XXX should use code from other end iff ENHANCEDSTATUSCODES */
+ mci_setstat(mci, EX_TEMPFAIL, "4.5.0", SmtpReplyBuffer);
if (mci->mci_state != MCIS_CLOSED)
smtpquit(m, mci, e);
return;
unavailable:
- mci->mci_exitstat = EX_UNAVAILABLE;
mci->mci_errno = errno;
+ mci_setstat(mci, EX_UNAVAILABLE, "5.5.0", SmtpReplyBuffer);
smtpquit(m, mci, e);
return;
}
@@ -387,7 +418,7 @@ smtpmailfrom(m, mci, e)
extern char MsgBuf[];
usrerr("%s does not support 8BITMIME", mci->mci_host);
- mci_setstat(mci, "5.6.3", MsgBuf);
+ mci_setstat(mci, EX_DATAERR, "5.6.3", MsgBuf);
return EX_DATAERR;
}
@@ -447,17 +478,24 @@ smtpmailfrom(m, mci, e)
SmtpPhase = mci->mci_phase = "client MAIL";
setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
r = reply(m, mci, e, TimeOuts.to_mail, NULL);
- if (r < 0 || r == 421)
+ if (r < 0)
{
- /* communications failure/service shutting down */
- mci->mci_exitstat = EX_TEMPFAIL;
+ /* communications failure */
mci->mci_errno = errno;
+ mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL);
+ smtpquit(m, mci, e);
+ return EX_TEMPFAIL;
+ }
+ else if (r == 421)
+ {
+ /* service shutting down */
+ mci_setstat(mci, EX_TEMPFAIL, "4.5.0", SmtpReplyBuffer);
smtpquit(m, mci, e);
return EX_TEMPFAIL;
}
else if (REPLYTYPE(r) == 4)
{
- mci_setstat(mci, smtptodsn(r), SmtpReplyBuffer);
+ mci_setstat(mci, EX_TEMPFAIL, smtptodsn(r), SmtpReplyBuffer);
return EX_TEMPFAIL;
}
else if (REPLYTYPE(r) == 2)
@@ -467,25 +505,25 @@ smtpmailfrom(m, mci, e)
else if (r == 501)
{
/* syntax error in arguments */
- mci_setstat(mci, "5.5.2", SmtpReplyBuffer);
+ mci_setstat(mci, EX_DATAERR, "5.5.2", SmtpReplyBuffer);
return EX_DATAERR;
}
else if (r == 553)
{
/* mailbox name not allowed */
- mci_setstat(mci, "5.1.3", SmtpReplyBuffer);
+ mci_setstat(mci, EX_DATAERR, "5.1.3", SmtpReplyBuffer);
return EX_DATAERR;
}
else if (r == 552)
{
/* exceeded storage allocation */
- mci_setstat(mci, "5.2.2", SmtpReplyBuffer);
+ mci_setstat(mci, EX_UNAVAILABLE, "5.2.2", SmtpReplyBuffer);
return EX_UNAVAILABLE;
}
else if (REPLYTYPE(r) == 5)
{
/* unknown error */
- mci_setstat(mci, "5.0.0", SmtpReplyBuffer);
+ mci_setstat(mci, EX_UNAVAILABLE, "5.0.0", SmtpReplyBuffer);
return EX_UNAVAILABLE;
}
@@ -499,7 +537,7 @@ smtpmailfrom(m, mci, e)
#endif
/* protocol error -- close up */
- mci_setstat(mci, "5.5.1", SmtpReplyBuffer);
+ mci_setstat(mci, EX_PROTOCOL, "5.5.1", SmtpReplyBuffer);
smtpquit(m, mci, e);
return EX_PROTOCOL;
}
@@ -536,7 +574,8 @@ smtprcpt(to, m, mci, e)
{
/* NOTIFY= parameter */
if (bitset(QHASNOTIFY, to->q_flags) &&
- bitset(QPRIMARY, to->q_flags))
+ bitset(QPRIMARY, to->q_flags) &&
+ !bitnset(M_LOCALMAILER, m->m_flags))
{
bool firstone = TRUE;
@@ -622,6 +661,7 @@ smtprcpt(to, m, mci, e)
**
** Parameters:
** m -- mailer being sent to.
+** mci -- the mailer connection information.
** e -- the envelope for this message.
**
** Returns:
@@ -642,6 +682,7 @@ smtpdata(m, mci, e)
{
register int r;
register EVENT *ev;
+ int rstat;
time_t timeout;
/*
@@ -690,8 +731,8 @@ smtpdata(m, mci, e)
if (setjmp(CtxDataTimeout) != 0)
{
mci->mci_errno = errno;
- mci->mci_exitstat = EX_TEMPFAIL;
mci->mci_state = MCIS_ERROR;
+ mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL);
syserr("451 timeout writing message to %s", mci->mci_host);
smtpquit(m, mci, e);
return EX_TEMPFAIL;
@@ -720,8 +761,8 @@ smtpdata(m, mci, e)
{
/* error during processing -- don't send the dot */
mci->mci_errno = EIO;
- mci->mci_exitstat = EX_IOERR;
mci->mci_state = MCIS_ERROR;
+ mci_setstat(mci, EX_IOERR, "4.4.2", NULL);
smtpquit(m, mci, e);
return EX_IOERR;
}
@@ -734,8 +775,12 @@ smtpdata(m, mci, e)
nmessage(">>> .");
/* check for the results of the transaction */
- SmtpPhase = mci->mci_phase = "client DATA 250";
+ SmtpPhase = mci->mci_phase = "client DATA status";
setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
+#if FFR_LMTP
+ if (bitnset(M_LMTP, m->m_flags))
+ return EX_OK;
+#endif
r = reply(m, mci, e, TimeOuts.to_datafinal, NULL);
if (r < 0)
{
@@ -743,16 +788,22 @@ smtpdata(m, mci, e)
return EX_TEMPFAIL;
}
mci->mci_state = MCIS_OPEN;
- mci_setstat(mci, smtptodsn(r), SmtpReplyBuffer);
- e->e_statmsg = newstr(&SmtpReplyBuffer[4]);
if (REPLYTYPE(r) == 4)
- return EX_TEMPFAIL;
+ rstat = EX_TEMPFAIL;
else if (REPLYCLASS(r) != 5)
- /* fall through */ ;
+ rstat = EX_PROTOCOL;
else if (REPLYTYPE(r) == 2)
- return EX_OK;
+ rstat = EX_OK;
else if (REPLYTYPE(r) == 5)
- return EX_UNAVAILABLE;
+ rstat = EX_UNAVAILABLE;
+ else
+ rstat = EX_PROTOCOL;
+ mci_setstat(mci, rstat, smtptodsn(r), SmtpReplyBuffer);
+ if (e->e_statmsg != NULL)
+ free(e->e_statmsg);
+ e->e_statmsg = newstr(&SmtpReplyBuffer[4]);
+ if (rstat != EX_PROTOCOL)
+ return rstat;
#ifdef LOG
if (LogLevel > 1)
{
@@ -761,7 +812,7 @@ smtpdata(m, mci, e)
shortenstring(SmtpReplyBuffer, 403));
}
#endif
- return EX_PROTOCOL;
+ return rstat;
}
@@ -771,10 +822,66 @@ datatimeout()
longjmp(CtxDataTimeout, 1);
}
/*
+** SMTPGETSTAT -- get status code from DATA in LMTP
+**
+** Parameters:
+** m -- the mailer to which we are sending the message.
+** mci -- the mailer connection structure.
+** e -- the current envelope.
+**
+** Returns:
+** The exit status corresponding to the reply code.
+*/
+
+#if FFR_LMTP
+
+int
+smtpgetstat(m, mci, e)
+ MAILER *m;
+ MCI *mci;
+ ENVELOPE *e;
+{
+ int r;
+ int stat;
+
+ /* check for the results of the transaction */
+ r = reply(m, mci, e, TimeOuts.to_datafinal, NULL);
+ if (r < 0)
+ {
+ smtpquit(m, mci, e);
+ return EX_TEMPFAIL;
+ }
+ if (e->e_statmsg != NULL)
+ free(e->e_statmsg);
+ e->e_statmsg = newstr(&SmtpReplyBuffer[4]);
+ if (REPLYTYPE(r) == 4)
+ stat = EX_TEMPFAIL;
+ else if (REPLYCLASS(r) != 5)
+ stat = EX_PROTOCOL;
+ else if (REPLYTYPE(r) == 2)
+ stat = EX_OK;
+ else if (REPLYTYPE(r) == 5)
+ stat = EX_UNAVAILABLE;
+ mci_setstat(mci, stat, smtptodsn(r), SmtpReplyBuffer);
+#ifdef LOG
+ if (LogLevel > 1 && stat == EX_PROTOCOL)
+ {
+ syslog(LOG_CRIT, "%s: %.100s: SMTP DATA-3 protocol error: %s",
+ e->e_id, mci->mci_host,
+ shortenstring(SmtpReplyBuffer, 403));
+ }
+#endif
+ return stat;
+}
+
+#endif
+ /*
** SMTPQUIT -- close the SMTP connection.
**
** Parameters:
** m -- a pointer to the mailer.
+** mci -- the mailer connection information.
+** e -- the current envelope.
**
** Returns:
** none.
@@ -927,6 +1034,7 @@ reply(m, mci, e, timeout, pfunc)
if (p == NULL)
{
bool oldholderrs;
+ extern char MsgBuf[];
/* if the remote end closed early, fake an error */
if (errno == 0)
@@ -937,10 +1045,10 @@ reply(m, mci, e, timeout, pfunc)
# endif /* ECONNRESET */
mci->mci_errno = errno;
- mci->mci_exitstat = EX_TEMPFAIL;
oldholderrs = HoldErrs;
HoldErrs = TRUE;
usrerr("451 reply: read error from %s", mci->mci_host);
+ mci_setstat(mci, EX_TEMPFAIL, "4.4.2", MsgBuf);
/* if debugging, pause so we can see state */
if (tTd(18, 100))
diff --git a/usr.sbin/sendmail/src/util.c b/usr.sbin/sendmail/src/util.c
index 49d2a65..822aaf35 100644
--- a/usr.sbin/sendmail/src/util.c
+++ b/usr.sbin/sendmail/src/util.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)util.c 8.105 (Berkeley) 10/12/96";
+static char sccsid[] = "@(#)util.c 8.109 (Berkeley) 11/16/96";
#endif /* not lint */
# include "sendmail.h"
@@ -1012,6 +1012,15 @@ putxline(l, mci, pxflags)
if (TrafficLogFile != NULL)
(void) putc('.', TrafficLogFile);
}
+ else if (l[0] == 'F' && slop == 0 &&
+ bitset(PXLF_MAPFROM, pxflags) &&
+ strncmp(l, "From ", 5) == 0 &&
+ bitnset(M_ESCFROM, mci->mci_mailer->m_flags))
+ {
+ (void) putc('>', mci->mci_out);
+ if (TrafficLogFile != NULL)
+ (void) putc('>', TrafficLogFile);
+ }
if (TrafficLogFile != NULL)
fprintf(TrafficLogFile, "%.*s\n", p - l, l);
for ( ; l < p; ++l)
@@ -2197,6 +2206,7 @@ proc_list_add(pid)
pid_t pid;
{
int i;
+ extern void proc_list_probe __P((void));
for (i = 0; i < ProcListSize; i++)
{
@@ -2205,6 +2215,18 @@ proc_list_add(pid)
}
if (i >= ProcListSize)
{
+ /* probe the existing vector to avoid growing infinitely */
+ proc_list_probe();
+
+ /* now scan again */
+ for (i = 0; i < ProcListSize; i++)
+ {
+ if (ProcListVec[i] == NO_PID)
+ break;
+ }
+ }
+ if (i >= ProcListSize)
+ {
/* grow process list */
pid_t *npv;
@@ -2244,8 +2266,42 @@ proc_list_drop(pid)
if (ProcListVec[i] == pid)
{
ProcListVec[i] = NO_PID;
- CurChildren--;
break;
}
}
+ if (CurChildren > 0)
+ CurChildren--;
+}
+ /*
+** PROC_LIST_PROBE -- probe processes in the list to see if they still exist
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*/
+
+void
+proc_list_probe()
+{
+ int i;
+
+ for (i = 0; i < ProcListSize; i++)
+ {
+ if (ProcListVec[i] == NO_PID)
+ continue;
+ if (kill(ProcListVec[i], 0) < 0)
+ {
+#ifdef LOG
+ if (LogLevel > 3)
+ syslog(LOG_DEBUG, "proc_list_probe: lost pid %d",
+ ProcListVec[i]);
+#endif
+ ProcListVec[i] = NO_PID;
+ CurChildren--;
+ }
+ }
+ if (CurChildren < 0)
+ CurChildren = 0;
}
diff --git a/usr.sbin/sendmail/src/version.c b/usr.sbin/sendmail/src/version.c
index 7544a9a..8a53f29 100644
--- a/usr.sbin/sendmail/src/version.c
+++ b/usr.sbin/sendmail/src/version.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)version.c 8.8.2.1 (Berkeley) 10/18/96";
+static char sccsid[] = "@(#)version.c 8.8.3.2 (Berkeley) 11/16/96";
#endif /* not lint */
-char Version[] = "8.8.2";
+char Version[] = "8.8.3";
OpenPOWER on IntegriCloud