summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/sendmail/cf/cf/Makefile145
-rw-r--r--usr.sbin/sendmail/contrib/bitdomain.c6
-rw-r--r--usr.sbin/sendmail/makemap/makemap.c131
-rw-r--r--usr.sbin/sendmail/src/Makefile13
-rw-r--r--usr.sbin/sendmail/src/Makefile.386BSD42
-rw-r--r--usr.sbin/sendmail/src/Makefile.AIX113
-rw-r--r--usr.sbin/sendmail/src/Makefile.AUX105
-rw-r--r--usr.sbin/sendmail/src/Makefile.BSD43123
-rw-r--r--usr.sbin/sendmail/src/Makefile.BSDI32
-rw-r--r--usr.sbin/sendmail/src/Makefile.CLIX115
-rw-r--r--usr.sbin/sendmail/src/Makefile.ConvexOS105
-rw-r--r--usr.sbin/sendmail/src/Makefile.DGUX101
-rw-r--r--usr.sbin/sendmail/src/Makefile.Dell113
-rw-r--r--usr.sbin/sendmail/src/Makefile.DomainOS123
-rw-r--r--usr.sbin/sendmail/src/Makefile.Dynix113
-rw-r--r--usr.sbin/sendmail/src/Makefile.FreeBSD50
-rw-r--r--usr.sbin/sendmail/src/Makefile.HP-UX105
-rw-r--r--usr.sbin/sendmail/src/Makefile.IRIX109
-rw-r--r--usr.sbin/sendmail/src/Makefile.Linux120
-rw-r--r--usr.sbin/sendmail/src/Makefile.Mach386107
-rw-r--r--usr.sbin/sendmail/src/Makefile.NCR3000109
-rw-r--r--usr.sbin/sendmail/src/Makefile.NeXT114
-rw-r--r--usr.sbin/sendmail/src/Makefile.NetBSD46
-rw-r--r--usr.sbin/sendmail/src/Makefile.OSF1109
-rw-r--r--usr.sbin/sendmail/src/Makefile.PTX114
-rw-r--r--usr.sbin/sendmail/src/Makefile.RISCos117
-rw-r--r--usr.sbin/sendmail/src/Makefile.SCO104
-rw-r--r--usr.sbin/sendmail/src/Makefile.SVR4113
-rw-r--r--usr.sbin/sendmail/src/Makefile.Solaris115
-rw-r--r--usr.sbin/sendmail/src/Makefile.SunOS111
-rw-r--r--usr.sbin/sendmail/src/Makefile.SunOS.4.0.3113
-rw-r--r--usr.sbin/sendmail/src/Makefile.SunOS.5.1115
-rw-r--r--usr.sbin/sendmail/src/Makefile.SunOS.5.2115
-rw-r--r--usr.sbin/sendmail/src/Makefile.SunOS.5.x115
-rw-r--r--usr.sbin/sendmail/src/Makefile.Titan114
-rw-r--r--usr.sbin/sendmail/src/Makefile.ULTRIX107
-rw-r--r--usr.sbin/sendmail/src/Makefile.UMAX114
-rw-r--r--usr.sbin/sendmail/src/Makefile.Utah40
-rw-r--r--usr.sbin/sendmail/src/Makefile.dist107
-rw-r--r--usr.sbin/sendmail/src/collect.c652
-rw-r--r--usr.sbin/sendmail/src/conf.c2020
-rw-r--r--usr.sbin/sendmail/src/conf.h936
-rw-r--r--usr.sbin/sendmail/src/daemon.c538
-rw-r--r--usr.sbin/sendmail/src/deliver.c1199
-rw-r--r--usr.sbin/sendmail/src/domain.c325
-rw-r--r--usr.sbin/sendmail/src/headers.c435
-rw-r--r--usr.sbin/sendmail/src/main.c1081
-rw-r--r--usr.sbin/sendmail/src/parseaddr.c541
-rw-r--r--usr.sbin/sendmail/src/readcf.c1301
-rw-r--r--usr.sbin/sendmail/src/recipient.c615
-rw-r--r--usr.sbin/sendmail/src/savemail.c785
-rw-r--r--usr.sbin/sendmail/src/sendmail.817
-rw-r--r--usr.sbin/sendmail/src/sendmail.h593
-rw-r--r--usr.sbin/sendmail/src/srvrsmtp.c635
-rw-r--r--usr.sbin/sendmail/src/sysexits.h118
-rw-r--r--usr.sbin/sendmail/src/udb.c236
-rw-r--r--usr.sbin/sendmail/src/usersmtp.c296
-rw-r--r--usr.sbin/sendmail/src/util.c740
58 files changed, 10213 insertions, 6713 deletions
diff --git a/usr.sbin/sendmail/cf/cf/Makefile b/usr.sbin/sendmail/cf/cf/Makefile
index 3d0ab69..90372b7 100644
--- a/usr.sbin/sendmail/cf/cf/Makefile
+++ b/usr.sbin/sendmail/cf/cf/Makefile
@@ -1,7 +1,18 @@
-# @(#)Makefile 8.5 (Berkeley) 12/1/93
+# @(#)Makefile 8.17 (Berkeley) 9/12/95
+
+#
+# This Makefile uses the new Berkeley "make" program. See Makefile.dist
+# for a more vanilla version.
+#
+# Configuration files are created using "m4 file.mc > file.cf";
+# this may be easier than tweaking the Makefile. You do need to
+# have a fairly modern M4 available (GNU m4 works). On SunOS, use
+# /usr/5bin/m4.
+#
M4= m4
#M4= /usr/src/usr.bin/m4/obj/m4
+CFDIR= ..
CHMOD= chmod
ROMODE= 444
RM= rm -f
@@ -10,73 +21,87 @@ RM= rm -f
.mc.cf:
$(RM) $@
- (cd ${.CURDIR} && $(M4) ${@:R}.mc ) > $@
+ (cd ${.CURDIR} && $(M4) ${CFDIR}/m4/cf.m4 ${@:R}.mc > $@)
$(CHMOD) $(ROMODE) $@
-CLEANFILES= cs-hidden.cf cs-exposed.cf \
- hpux-cs-exposed.cf hpux-cs-hidden.cf \
- riscos-cs-exposed.cf \
- sunos3.5-cs-exposed.cf sunos3.5-cs-hidden.cf \
- sunos4.1-cs-exposed.cf sunos4.1-cs-hidden.cf \
- ultrix4.1-cs-exposed.cf ultrix4.1-cs-hidden.cf \
- osf1-cs-exposed.cf osf1-cs-hidden.cf \
- mail.cs.cf mail.eecs.cf ucbvax.cf vangogh.cf \
- chez.cf knecht.cf cogsci.cf alpha.cf s2k.cf auspex.cf \
- python.cf \
- clientproto.cf tcpproto.cf uucpproto.cf
+ALL= generic-bsd4.4.cf generic-hpux9.cf generic-hpux10.cf \
+ generic-osf1.cf generic-solaris2.cf \
+ generic-sunos4.1.cf generic-ultrix4.cf \
+ cs-hpux9.cf cs-osf1.cf cs-solaris2.cf \
+ cs-sunos4.1.cf cs-ultrix4.cf \
+ s2k-osf1.cf s2k-ultrix4.cf \
+ chez.cs.cf huginn.cs.cf mail.cs.cf mail.eecs.cf mailspool.cs.cf \
+ python.cs.cf ucbarpa.cf ucbvax.cf vangogh.cs.cf
-all: $(CLEANFILES)
+all: $(ALL)
depend install:
# this is overkill, but....
M4FILES=\
- ../domain/Berkeley.m4 \
- ../domain/cs.exposed.m4 \
- ../domain/cs.hidden.m4 \
- ../domain/eecs.hidden.m4 \
- ../domain/s2k.m4 \
- ../feature/allmasquerade.m4 \
- ../feature/always_add_domain.m4 \
- ../feature/bitdomain.m4 \
- ../feature/domaintable.m4 \
- ../feature/mailertable.m4 \
- ../feature/nocanonify.m4 \
- ../feature/nodns.m4 \
- ../feature/notsticky.m4 \
- ../feature/nouucp.m4 \
- ../feature/nullclient.m4 \
- ../feature/redirect.m4 \
- ../feature/use_cw_file.m4 \
- ../feature/uucpdomain.m4 \
- ../hack/cssubdomain.m4 \
- ../m4/cf.m4 \
- ../m4/nullrelay.m4 \
- ../m4/proto.m4 \
- ../m4/version.m4 \
- ../mailer/fax.m4 \
- ../mailer/local.m4 \
- ../mailer/smtp.m4 \
- ../mailer/usenet.m4 \
- ../mailer/uucp.m4 \
- ../ostype/aix3.m4 \
- ../ostype/bsd4.3.m4 \
- ../ostype/bsd4.4.m4 \
- ../ostype/hpux.m4 \
- ../ostype/irix.m4 \
- ../ostype/linux.m4 \
- ../ostype/nextstep.m4 \
- ../ostype/osf1.m4 \
- ../ostype/riscos4.5.m4 \
- ../ostype/solaris2.m4 \
- ../ostype/sunos3.5.m4 \
- ../ostype/sunos4.1.m4 \
- ../ostype/svr4.m4 \
- ../ostype/ultrix4.1.m4 \
- ../siteconfig/uucp.cogsci.m4 \
- ../siteconfig/uucp.old.arpa.m4 \
- ../siteconfig/uucp.ucbarpa.m4 \
- ../siteconfig/uucp.ucbvax.m4 \
+ ${CFDIR}/domain/Berkeley.EDU.m4 \
+ ${CFDIR}/domain/CS.Berkeley.EDU.m4 \
+ ${CFDIR}/domain/EECS.Berkeley.EDU.m4 \
+ ${CFDIR}/domain/S2K.Berkeley.EDU.m4 \
+ ${CFDIR}/feature/allmasquerade.m4 \
+ ${CFDIR}/feature/always_add_domain.m4 \
+ ${CFDIR}/feature/bestmx_is_local.m4 \
+ ${CFDIR}/feature/bitdomain.m4 \
+ ${CFDIR}/feature/domaintable.m4 \
+ ${CFDIR}/feature/local_procmail.m4 \
+ ${CFDIR}/feature/mailertable.m4 \
+ ${CFDIR}/feature/nocanonify.m4 \
+ ${CFDIR}/feature/nodns.m4 \
+ ${CFDIR}/feature/notsticky.m4 \
+ ${CFDIR}/feature/nouucp.m4 \
+ ${CFDIR}/feature/nullclient.m4 \
+ ${CFDIR}/feature/redirect.m4 \
+ ${CFDIR}/feature/smrsh.m4 \
+ ${CFDIR}/feature/stickyhost.m4 \
+ ${CFDIR}/feature/use_cw_file.m4 \
+ ${CFDIR}/feature/uucpdomain.m4 \
+ ${CFDIR}/hack/cssubdomain.m4 \
+ ${CFDIR}/m4/cf.m4 \
+ ${CFDIR}/m4/cfhead.m4 \
+ ${CFDIR}/m4/nullrelay.m4 \
+ ${CFDIR}/m4/proto.m4 \
+ ${CFDIR}/m4/version.m4 \
+ ${CFDIR}/mailer/cyrus.m4 \
+ ${CFDIR}/mailer/fax.m4 \
+ ${CFDIR}/mailer/local.m4 \
+ ${CFDIR}/mailer/mail11.m4 \
+ ${CFDIR}/mailer/pop.m4 \
+ ${CFDIR}/mailer/procmail.m4 \
+ ${CFDIR}/mailer/smtp.m4 \
+ ${CFDIR}/mailer/usenet.m4 \
+ ${CFDIR}/mailer/uucp.m4 \
+ ${CFDIR}/ostype/aix3.m4 \
+ ${CFDIR}/ostype/amdahl-uts.m4 \
+ ${CFDIR}/ostype/aux.m4 \
+ ${CFDIR}/ostype/bsd4.3.m4 \
+ ${CFDIR}/ostype/bsd4.4.m4 \
+ ${CFDIR}/ostype/bsdi1.0.m4 \
+ ${CFDIR}/ostype/dgux.m4 \
+ ${CFDIR}/ostype/domainos.m4 \
+ ${CFDIR}/ostype/dynix3.2.m4 \
+ ${CFDIR}/ostype/hpux9.m4 \
+ ${CFDIR}/ostype/irix4.m4 \
+ ${CFDIR}/ostype/irix5.m4 \
+ ${CFDIR}/ostype/linux.m4 \
+ ${CFDIR}/ostype/nextstep.m4 \
+ ${CFDIR}/ostype/osf1.m4 \
+ ${CFDIR}/ostype/ptx2.m4 \
+ ${CFDIR}/ostype/riscos4.5.m4 \
+ ${CFDIR}/ostype/sco3.2.m4 \
+ ${CFDIR}/ostype/solaris2.m4 \
+ ${CFDIR}/ostype/sunos3.5.m4 \
+ ${CFDIR}/ostype/sunos4.1.m4 \
+ ${CFDIR}/ostype/svr4.m4 \
+ ${CFDIR}/ostype/ultrix4.m4 \
+ ${CFDIR}/siteconfig/uucp.cogsci.m4 \
+ ${CFDIR}/siteconfig/uucp.old.arpa.m4 \
+ ${CFDIR}/siteconfig/uucp.ucbarpa.m4 \
+ ${CFDIR}/siteconfig/uucp.ucbvax.m4 \
$(ALL): $(M4FILES)
diff --git a/usr.sbin/sendmail/contrib/bitdomain.c b/usr.sbin/sendmail/contrib/bitdomain.c
index d5e8549..720b9a1 100644
--- a/usr.sbin/sendmail/contrib/bitdomain.c
+++ b/usr.sbin/sendmail/contrib/bitdomain.c
@@ -1,6 +1,6 @@
/*
* By John G. Myers, jgm+@cmu.edu
- * Version 1.1
+ * Version 1.2
*
* Process a BITNET "internet.listing" file, producing output
* suitable for input to makemap.
@@ -154,7 +154,7 @@ char *domainlen;
* if "domain" doesn't have a domain expansion already.
*/
p = lookup(domain);
- if (!p || !index(p, '.')) remember(domain, otherdomain);
+ if (!p || !strchr(p, '.')) remember(domain, otherdomain);
}
}
else {
@@ -167,7 +167,7 @@ char *domainlen;
* have a domain expansion, give it the expansion "domain".
*/
p = lookup(otherdomain);
- if (!p || !index(p, '.')) remember(otherdomain, domain);
+ if (!p || !strchr(p, '.')) remember(otherdomain, domain);
}
}
else {
diff --git a/usr.sbin/sendmail/makemap/makemap.c b/usr.sbin/sendmail/makemap/makemap.c
index 14548bd..c48a1c9 100644
--- a/usr.sbin/sendmail/makemap/makemap.c
+++ b/usr.sbin/sendmail/makemap/makemap.c
@@ -33,15 +33,18 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)makemap.c 8.6.1.1 (Berkeley) 3/6/95";
+static char sccsid[] = "@(#)makemap.c 8.14 (Berkeley) 11/5/95";
#endif /* not lint */
#include <stdio.h>
#include <sysexits.h>
#include <sys/types.h>
-#include <sys/file.h>
#include <ctype.h>
#include <string.h>
+#include <sys/errno.h>
+#ifndef ISC_UNIX
+# include <sys/file.h>
+#endif
#include "useful.h"
#include "conf.h"
@@ -80,6 +83,7 @@ main(argc, argv)
bool inclnull = FALSE;
bool notrunc = FALSE;
bool allowreplace = FALSE;
+ bool allowdups = FALSE;
bool verbose = FALSE;
bool foldcase = TRUE;
int exitstat;
@@ -87,10 +91,12 @@ main(argc, argv)
char *typename;
char *mapname;
char *ext;
+ char *lext;
int lineno;
int st;
int mode;
enum type type;
+ int fd;
union
{
#ifdef NDBM
@@ -102,14 +108,19 @@ main(argc, argv)
void *dbx;
} dbp;
union dbent key, val;
+#ifdef NEWDB
+ BTREEINFO bti;
+#endif
char ibuf[BUFSIZE];
char fbuf[MAXNAME];
+ char lbuf[MAXNAME];
extern char *optarg;
extern int optind;
+ extern bool lockfile();
progname = argv[0];
- while ((opt = getopt(argc, argv, "Nforv")) != EOF)
+ while ((opt = getopt(argc, argv, "Ndforv")) != EOF)
{
switch (opt)
{
@@ -117,6 +128,10 @@ main(argc, argv)
inclnull = TRUE;
break;
+ case 'd':
+ allowdups = TRUE;
+ break;
+
case 'f':
foldcase = FALSE;
break;
@@ -148,10 +163,12 @@ main(argc, argv)
typename = argv[0];
mapname = argv[1];
ext = NULL;
+ lext = NULL;
if (strcmp(typename, "dbm") == 0)
{
type = T_DBM;
+ lext = ".dir";
}
else if (strcmp(typename, "btree") == 0)
{
@@ -170,7 +187,7 @@ main(argc, argv)
switch (type)
{
case T_ERR:
- fprintf(stderr, "Usage: %s [-N] [-o] [-v] type mapname\n", progname);
+ fprintf(stderr, "Usage: %s [-N] [-d] [-f] [-o] [-r] [-v] type mapname\n", progname);
exit(EX_USAGE);
case T_UNKNOWN:
@@ -188,6 +205,26 @@ main(argc, argv)
fprintf(stderr, "%s: Type %s not supported in this version\n",
progname, typename);
exit(EX_UNAVAILABLE);
+
+#ifdef NEWDB
+ case T_BTREE:
+ bzero(&bti, sizeof bti);
+ if (allowdups)
+ bti.flags |= R_DUP;
+ break;
+
+ case T_HASH:
+#endif
+#ifdef NDBM
+ case T_DBM:
+#endif
+ if (allowdups)
+ {
+ fprintf(stderr, "%s: Type %s does not support -d (allow dups)\n",
+ progname, typename);
+ exit(EX_UNAVAILABLE);
+ }
+ break;
}
/*
@@ -208,6 +245,10 @@ main(argc, argv)
}
}
+ strcpy(lbuf, mapname);
+ if (lext != NULL)
+ strcat(lbuf, lext);
+
/*
** Create the database.
*/
@@ -215,6 +256,19 @@ main(argc, argv)
mode = O_RDWR;
if (!notrunc)
mode |= O_CREAT|O_TRUNC;
+#ifdef O_EXLOCK
+ mode |= O_EXLOCK;
+#else
+ /* pre-lock the database */
+ fd = open(lbuf, mode & ~O_TRUNC, 0644);
+ if (fd < 0)
+ {
+ fprintf(stderr, "%s: cannot create type %s map %s\n",
+ progname, typename, mapname);
+ exit(EX_CANTCREAT);
+ }
+ (void) lockfile(fd);
+#endif
switch (type)
{
#ifdef NDBM
@@ -227,13 +281,25 @@ main(argc, argv)
case T_HASH:
dbp.db = dbopen(mapname, mode, 0644, DB_HASH, NULL);
if (dbp.db != NULL)
+ {
+# if OLD_NEWDB
+ (void) (*dbp.db->sync)(dbp.db);
+# else
(void) (*dbp.db->sync)(dbp.db, 0);
+# endif
+ }
break;
case T_BTREE:
- dbp.db = dbopen(mapname, mode, 0644, DB_BTREE, NULL);
+ dbp.db = dbopen(mapname, mode, 0644, DB_BTREE, &bti);
if (dbp.db != NULL)
+ {
+# if OLD_NEWDB
+ (void) (*dbp.db->sync)(dbp.db);
+# else
(void) (*dbp.db->sync)(dbp.db, 0);
+# endif
+ }
break;
#endif
@@ -244,7 +310,7 @@ main(argc, argv)
if (dbp.dbx == NULL)
{
- fprintf(stderr, "%s: cannot create type %s map %s\n",
+ fprintf(stderr, "%s: cannot open type %s map %s\n",
progname, typename, mapname);
exit(EX_CANTCREAT);
}
@@ -373,5 +439,58 @@ main(argc, argv)
#endif
}
+#ifndef O_EXLOCK
+ /* release locks */
+ close(fd);
+#endif
+
exit (exitstat);
}
+ /*
+** LOCKFILE -- lock a file using flock or (shudder) fcntl locking
+**
+** Parameters:
+** fd -- the file descriptor of the file.
+**
+** Returns:
+** TRUE if the lock was acquired.
+** FALSE otherwise.
+*/
+
+bool
+lockfile(fd)
+ int fd;
+{
+# if !HASFLOCK
+ int action;
+ struct flock lfd;
+ extern int errno;
+
+ bzero(&lfd, sizeof lfd);
+ lfd.l_type = F_WRLCK;
+ action = F_SETLKW;
+
+ if (fcntl(fd, action, &lfd) >= 0)
+ return TRUE;
+
+ /*
+ ** On SunOS, if you are testing using -oQ/tmp/mqueue or
+ ** -oA/tmp/aliases or anything like that, and /tmp is mounted
+ ** as type "tmp" (that is, served from swap space), the
+ ** previous fcntl will fail with "Invalid argument" errors.
+ ** Since this is fairly common during testing, we will assume
+ ** that this indicates that the lock is successfully grabbed.
+ */
+
+ if (errno == EINVAL)
+ return TRUE;
+
+# else /* HASFLOCK */
+
+ if (flock(fd, LOCK_EX) >= 0)
+ return TRUE;
+
+# endif
+
+ return FALSE;
+}
diff --git a/usr.sbin/sendmail/src/Makefile b/usr.sbin/sendmail/src/Makefile
index 6295846..c3919d2 100644
--- a/usr.sbin/sendmail/src/Makefile
+++ b/usr.sbin/sendmail/src/Makefile
@@ -1,4 +1,9 @@
-# @(#)Makefile 8.4 (Berkeley) 2/3/94
+# @(#)Makefile 8.7 (Berkeley) 10/31/95
+
+#########################################################################
+# This Makefile is for 4.4BSD only!!! For all other systems, use #
+# the "makesendmail" script. #
+#########################################################################
PROG= sendmail
@@ -10,14 +15,14 @@ PROG= sendmail
# databases are read, but the new format will be used on any rebuilds. On
# really gnarly systems, you can set this to null; it will crawl like a high
# spiral snail, but it will work.
-DBMDEF= -DNEWDB -DNDBM
+DBMDEF= -DNEWDB
CFLAGS+=-I${.CURDIR} ${DBMDEF} -DNETISO
SRCS= alias.c arpadate.c clock.c collect.c conf.c convtime.c daemon.c \
deliver.c domain.c envelope.c err.c headers.c macro.c main.c map.c \
- mci.c parseaddr.c queue.c readcf.c recipient.c savemail.c srvrsmtp.c \
- stab.c stats.c sysexits.c trace.c udb.c usersmtp.c \
+ mci.c mime.c parseaddr.c queue.c readcf.c recipient.c savemail.c \
+ srvrsmtp.c stab.c stats.c sysexits.c trace.c udb.c usersmtp.c \
util.c version.c
DPADD=
LDADD=
diff --git a/usr.sbin/sendmail/src/Makefile.386BSD b/usr.sbin/sendmail/src/Makefile.386BSD
deleted file mode 100644
index 397ce8b..0000000
--- a/usr.sbin/sendmail/src/Makefile.386BSD
+++ /dev/null
@@ -1,42 +0,0 @@
-# @(#)Makefile.386BSD 8.1 (Berkeley) 2/26/94
-
-PROG= sendmail
-
-# define the database format to use for aliases et al. Can be -DNEWDB (for
-# the new BSD database package -- this is preferred) or -DNDBM for the NDBM
-# database package. The old putrescent V7 DBM package is no longer
-# supported.
-# You can define both NEWDB and NDBM during a transition period; old
-# databases are read, but the new format will be used on any rebuilds. On
-# really gnarly systems, you can set this to null; it will crawl like a high
-# spiral snail, but it will work.
-DBMDEF= -DNEWDB
-
-CFLAGS+=-I${.CURDIR} ${DBMDEF} -DMIME
-
-SRCS= alias.c arpadate.c clock.c collect.c conf.c convtime.c daemon.c \
- deliver.c domain.c envelope.c err.c headers.c macro.c main.c map.c \
- mci.c parseaddr.c queue.c readcf.c recipient.c savemail.c srvrsmtp.c \
- stab.c stats.c sysexits.c trace.c udb.c usersmtp.c \
- util.c version.c
-DPADD=
-LDADD= $(LIBUTIL)
-MAN1= newaliases.0 mailq.0
-MAN5= aliases.0
-MAN8= sendmail.0
-LINKS= /usr/sbin/sendmail /usr/bin/newaliases \
- /usr/sbin/sendmail /usr/bin/mailq
-BINDIR= /usr/sbin
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-beforeinstall:
-# install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \
-# ${DESTDIR}/etc/sendmail.fc
- install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \
- ${DESTDIR}/var/log/sendmail.st
- install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/sendmail.hf \
- ${DESTDIR}/usr/share/misc
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/sendmail/src/Makefile.AIX b/usr.sbin/sendmail/src/Makefile.AIX
deleted file mode 100644
index 5d3041d..0000000
--- a/usr.sbin/sendmail/src/Makefile.AIX
+++ /dev/null
@@ -1,113 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on AIX 3.1.5 and 3.2.3e.
-#
-# @(#)Makefile.AIX 8.3 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-# you can use -O3 on AIX 3.2.4 or greater ONLY!
-O= -g
-
-# define the database mechanism used for alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM -DNEWDB -DNIS
-#
-# If you did not install the NEWDB on your AIX platform, use:
-#DBMDEF=-DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= -D_AIX3
-
-# see also conf.h for additional compilation flags
-
-# include directories
-#INCDIRS=-I/usr/sww/include/db
-
-# library directories
-#LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS= -ldbm -ldb
-#
-# If you did not install the NEWDB on your AIX platform, use:
-#LIBS= -ldbm
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/sbin
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/etc
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-INSTALL=/usr/ucb/install
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/sbin/newaliases ${DESTDIR}/usr/sbin/mailq
-BINOWN= root
-BINGRP= system
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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} -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \
- ${STDIR}/sendmail.st
- ${INSTALL} -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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.AUX b/usr.sbin/sendmail/src/Makefile.AUX
deleted file mode 100644
index dc84b21..0000000
--- a/usr.sbin/sendmail/src/Makefile.AUX
+++ /dev/null
@@ -1,105 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# @(#)Makefile.AUX 8.3 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF=
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=-I/usr/sww/include/db
-
-# loader options
-LDOPTS=
-
-# library directories
-LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS= -ldbm -lposix
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/sbin
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/var/log
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/share/misc
-
-# additional .o files needed
-OBJADD=
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.BSD43 b/usr.sbin/sendmail/src/Makefile.BSD43
deleted file mode 100644
index 4177c3b..0000000
--- a/usr.sbin/sendmail/src/Makefile.BSD43
+++ /dev/null
@@ -1,123 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This is based on work from Jim Oldroyd -- I believe he was
-# using a fairly old Mt Xinu port.
-#
-# It should also work on UMIPS-BSD from MIPS, if you still have
-# any lying around.
-#
-# @(#)Makefile.BSD43 8.3 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanism used for alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= -DoldBSD43
-
-# see also conf.h for additional compilation flags
-
-# include directories
-#INCDIRS=-I/usr/sww/include/db
-
-# library directories
-#LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS= -ldbm -lresolv -ll
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-# additional pseudo-sources needed
-BEFORE= unistd.h stddef.h stdlib.h dirent.h sys/time.h
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-unistd.h stddef.h stdlib.h sys/time.h:
- cp /dev/null $@
-
-sys/time.h: sys
-
-sys:
- mkdir sys
-
-dirent.h:
- echo "#include <sys/dir.h>" > dirent.h
- echo "#define dirent direct" >> dirent.h
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.BSDI b/usr.sbin/sendmail/src/Makefile.BSDI
deleted file mode 100644
index a45016d..0000000
--- a/usr.sbin/sendmail/src/Makefile.BSDI
+++ /dev/null
@@ -1,32 +0,0 @@
-# @(#)Makefile.BSDI 8.1 (Berkeley) 2/26/94
-
-PROG= sendmail
-DBMDEF= -DNEWDB
-CFLAGS+=-I${.CURDIR} ${DBMDEF} -DNETISO
-
-SRCS= alias.c arpadate.c clock.c collect.c conf.c convtime.c daemon.c \
- deliver.c domain.c envelope.c err.c headers.c macro.c main.c map.c \
- mci.c parseaddr.c queue.c readcf.c recipient.c savemail.c srvrsmtp.c \
- stab.c stats.c sysexits.c trace.c udb.c usersmtp.c \
- util.c version.c
-DPADD= ${LIBUTIL} ${LIBKVM}
-LDADD= -lutil -lkvm
-MAN1= mailq.0 newaliases.0
-MAN5= aliases.0
-MAN8= sendmail.0
-LINKS= /usr/sbin/sendmail /usr/bin/newaliases \
- /usr/sbin/sendmail /usr/bin/mailq
-BINDIR= /usr/sbin
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-beforeinstall:
-# install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \
-# ${DESTDIR}/etc/sendmail.fc
- install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \
- ${DESTDIR}/var/log/sendmail.st
- install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/sendmail.hf \
- ${DESTDIR}/usr/share/misc
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/sendmail/src/Makefile.CLIX b/usr.sbin/sendmail/src/Makefile.CLIX
deleted file mode 100644
index 7e54e36..0000000
--- a/usr.sbin/sendmail/src/Makefile.CLIX
+++ /dev/null
@@ -1,115 +0,0 @@
-#
-# This makefile is for clipper-based Intergraph systems running CLIX.
-# It and the defines supporting it in the source tree should be considered
-# alpha-quality and used at own risk.
-#
-# Porting done for CICNet, Inc., on behalf the Michigan State Department
-# of Natural Resources.
-#
-# --Paul Southworth <pauls@cic.net>
-#
-# @(#)Makefile.CLIX 8.1 (Berkeley) 4/12/94
-#
-
-# make sure the shell constructs below use the right shell
-SHELL= /bin/sh
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-CC= gcc
-
-# define the database mechanism used for alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= -DCLIX
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS= -I/usr/include
-
-# library directories
-LIBDIRS=
-
-# libraries required on your system
-LIBS= -lnsl -lbsd
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD= getusershell.o
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/bin/newaliases ${DESTDIR}/usr/bin/mailq
-BINOWN= root
-BINGRP= mail
-BINMODE=6555
-INSTALL=cp
-
-ALL= sendmail # aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail #install-docs
-
-install-sendmail: sendmail
- #${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} sendmail ${BINDIR}
- ${INSTALL} sendmail ${BINDIR}
- chmod ${BINMODE} ${BINDIR}/sendmail
- for i in ${LINKS}; do rm -f $$i; ln -s ${BINDIR}/sendmail $$i; done
- #${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \
- # ${STDIR}/sendmail.st
- ${INSTALL} /dev/null ${STDIR}/sendmail.st
- #${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 sendmail.hf ${HFDIR}
- ${INSTALL} sendmail.hf ${HFDIR}
-
-# doesn't actually install them -- you may want to install pre-nroff versions
-install-docs: aliases.0 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail #aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.ConvexOS b/usr.sbin/sendmail/src/Makefile.ConvexOS
deleted file mode 100644
index 82a77d5..0000000
--- a/usr.sbin/sendmail/src/Makefile.ConvexOS
+++ /dev/null
@@ -1,105 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on CxOS 11.0 beta 1 and 10.x.
-#
-# @(#)Makefile.ConvexOS 8.3 (Berkeley) 4/11/94
-#
-
-
-# use O=-O (usual) or O=-g (debugging)
-O= -g -tm c1 -D__STDC__ -d non_int_bit_field
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM -DYPCOMPAT -DNIS
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF=
-
-# see also conf.h for additional compilation flags
-
-# include directories
-#INCDIRS=-I/usr/sww/include/db
-
-# library directories
-#LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS=
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.DGUX b/usr.sbin/sendmail/src/Makefile.DGUX
deleted file mode 100644
index d7f63af..0000000
--- a/usr.sbin/sendmail/src/Makefile.DGUX
+++ /dev/null
@@ -1,101 +0,0 @@
-#
-# Tested on DG/UX 5.4.2 by A. Bryan Curnutt <bryan@Stoner.COM>.
-#
-# @(#)Makefile.DGUX 8.3 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM -DNIS
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF=-DDGUX
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=-I/usr/sww/include/db
-
-# loader options
-LDOPTS=
-
-# library directories
-LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS= -ldbm
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/bin
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/etc
-
-# additional .o files needed
-OBJADD=
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= bin
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.Dell b/usr.sbin/sendmail/src/Makefile.Dell
deleted file mode 100644
index 39bc1e8..0000000
--- a/usr.sbin/sendmail/src/Makefile.Dell
+++ /dev/null
@@ -1,113 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# Based on a Makefile for Dell SVR4 Issue 2.2 from Kimmo Suominen
-# <kim@grendel.lut.fi> -- I haven't tested this myself. It may
-# work on other SVR4 ports.
-#
-# @(#)Makefile.Dell 8.3 (Berkeley) 4/11/94
-#
-
-# make sure the shell constructs below use the right shell
-SHELL= /bin/sh
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O2
-
-CC= gcc
-#DESTDIR=/usr/local/sendmail
-
-# define the database mechanism used for alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNEWDB -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= -D__svr4__
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=
-
-# library directories
-LIBDIRS=
-
-# libraries required on your system
-LIBS= -ldb -ldbm -lresolv -lsocket -lnsl -lelf
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/ucblib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/usr/ucblib
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/ucblib
-
-# additional .o files needed
-OBJADD=
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= mail
-BINMODE=6555
-INSTALL=/usr/ucb/install
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.DomainOS b/usr.sbin/sendmail/src/Makefile.DomainOS
deleted file mode 100644
index 5564ecb..0000000
--- a/usr.sbin/sendmail/src/Makefile.DomainOS
+++ /dev/null
@@ -1,123 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on DomainOS 10.3.5
-#
-# @(#)Makefile.DomainOS 8.5 (Berkeley) 4/12/94
-#
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNDBM -DNEWDB -DYPCOMPAT -- use both plus YP compatility
-# -DNIS -- include client NIS support
-# The really old (V7) DBM library is no longer supported.
-# If YPCOMPAT is defined and /var/yp/Makefile exists, sendmail will build
-# both the NEWDB and DBM libraries (the DBM just for YP).
-#
-
-DBMDEF= -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF=
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=
-
-# loader options
-LDOPTS=
-
-# library directories
-LIBDIRS=
-
-# libraries required on your system
-# You might want to use the BIND 4.9 resolver library here
-#LIBS= -ldb -ldbm
-LIBS= -ldbm -lresolv
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-# additional pseudo-sources needed
-BEFORE= unistd.h dirent.h
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. -A nansi $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS}
-
-unistd.h:
- cp /dev/null unistd.h
-
-dirent.h:
- echo "#include <sys/dir.h>" > dirent.h
- echo "#define dirent direct" >> dirent.h
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.Dynix b/usr.sbin/sendmail/src/Makefile.Dynix
deleted file mode 100644
index 344a9b7..0000000
--- a/usr.sbin/sendmail/src/Makefile.Dynix
+++ /dev/null
@@ -1,113 +0,0 @@
-#
-# Tested on Dynix 3.2.0.
-#
-# From Jim Davis <jdavis@cs.arizona.edu>.
-#
-# ``There is no strtol in libc (well there is in the 'att universe'
-# libc, but I couldn't figure out how to link that in), so I
-# got the Chris Torek strtol.c from bsd-sources on uunet and
-# compiled that. There is no native ndbm either; I couldn't
-# get db 1.72 to pass it's regression test, so I used gdbm-1.7
-# instead. I compiled it with gcc 1.40a. The -lseq is to pick
-# up getopt.''
-#
-# @(#)Makefile.Dynix 8.3 (Berkeley) 4/11/94
-#
-
-CC= gcc
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O -g
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF=
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=
-
-# loader options
-LDOPTS=
-
-# library directories
-LIBDIRS=
-
-# libraries required on your system
-LIBS= -lseq -lgdbm
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=strtol.o
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= staff # no kmem group,
-BINMODE=4555 # so not setgid
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.FreeBSD b/usr.sbin/sendmail/src/Makefile.FreeBSD
deleted file mode 100644
index 242c805..0000000
--- a/usr.sbin/sendmail/src/Makefile.FreeBSD
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# Makefile for FreeBSD
-#
-# @(#)Makefile.FreeBSD 8.1 (Berkeley) 2/26/94
-
-PROG= sendmail
-
-# define the database format to use for aliases et al. Can be -DNEWDB (for
-# the new BSD database package -- this is preferred) or -DNDBM for the NDBM
-# database package. The old putrescent V7 DBM package is no longer
-# supported.
-# You can define both NEWDB and NDBM during a transition period; old
-# databases are read, but the new format will be used on any rebuilds. On
-# really gnarly systems, you can set this to null; it will crawl like a high
-# spiral snail, but it will work.
-DBMDEF= -DNEWDB
-
-# FreeBSD 1.0 RELEASE has uname(2) now. Use -DUSEUNAME in order to use it.
-CFLAGS+=-I${.CURDIR} ${DBMDEF} -DMIME -DUSEUNAME
-
-SRCS= alias.c arpadate.c clock.c collect.c conf.c convtime.c daemon.c \
- deliver.c domain.c envelope.c err.c headers.c macro.c main.c map.c \
- mci.c parseaddr.c queue.c readcf.c recipient.c savemail.c srvrsmtp.c \
- stab.c stats.c sysexits.c trace.c udb.c usersmtp.c \
- util.c version.c
-DPADD=
-LDADD= $(LIBUTIL)
-#
-# FreeBSD 1.0 RELEASE has GNU man and doesn't need preformatted man pages anymore
-# (assuming you consider a slower "man" command a feature)
-#
-MAN1= mailq.1 newaliases.1
-MAN5= aliases.5
-MAN8= sendmail.8
-LINKS= /usr/sbin/sendmail /usr/bin/newaliases \
- /usr/sbin/sendmail /usr/bin/mailq
-BINDIR= /usr/sbin
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-beforeinstall:
-# ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \
-# ${DESTDIR}/etc/sendmail.fc
- ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \
- ${DESTDIR}/var/log/sendmail.st
- ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/sendmail.hf \
- ${DESTDIR}/usr/share/misc
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/sendmail/src/Makefile.HP-UX b/usr.sbin/sendmail/src/Makefile.HP-UX
deleted file mode 100644
index c1b51ec..0000000
--- a/usr.sbin/sendmail/src/Makefile.HP-UX
+++ /dev/null
@@ -1,105 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on HP-UX 8.07 on 7xx series.
-#
-# @(#)Makefile.HP-UX 8.3 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-# +O is OK on 7xx, and 300xx at 9.0
-O= +O1
-
-# define the database mechanism used for alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM -DNEWDB -DNIS
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF=
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=-I/usr/sww/include/db
-
-# library directories
-LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS= -ldb -ldbm
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/bin/newaliases ${DESTDIR}/usr/bin/mailq
-BINOWN= root
-BINGRP= mail
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-install-sendmail: sendmail
- cpset sendmail ${BINDIR} ${BINMODE} ${BINOWN} ${BINGRP}
- for i in ${LINKS}; do rm -f $$i; ln -s ${BINDIR}/sendmail $$i; done
- cpset /dev/null ${STDIR}/sendmail.st 644 ${BINOWN} ${BINGRP}
- cpset sendmail.hf ${HFDIR} 444 ${BINOWN} ${BINGRP}
-
-# doesn't actually install them -- you may want to install pre-nroff versions
-install-docs: aliases.0 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.IRIX b/usr.sbin/sendmail/src/Makefile.IRIX
deleted file mode 100644
index 30e8f1c..0000000
--- a/usr.sbin/sendmail/src/Makefile.IRIX
+++ /dev/null
@@ -1,109 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on IRIX 4.0.4.
-#
-# @(#)Makefile.IRIX 8.4 (Berkeley) 4/11/94
-#
-SHELL= /bin/sh
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-CC=gcc
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB (requires -ldb)
-# -DNIS -- include NIS support (requires -lsun)
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= -DIRIX
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=
-
-# library directories
-LIBDIRS=
-
-# libraries required on your system
-LIBS= -lmld
-#LIBS= -lsun -ldb -lmld
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/bsd/newaliases ${DESTDIR}/usr/bsd/mailq
-BINOWN= root
-BINGRP= sys
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-install-sendmail: sendmail
- install -u ${BINOWN} -g ${BINGRP} -m ${BINMODE} -f ${BINDIR} sendmail
- for i in ${LINKS}; do rm -f $$i; ln -s ${BINDIR}/sendmail $$i; done
- cp /dev/null ${STDIR}/sendmail.st
- chmod 644 ${STDIR}/sendmail.st
- chown ${BINOWN} ${STDIR}/sendmail.st
- chgrp ${BINGRP} ${STDIR}/sendmail.st
- install -u ${BINOWN} -g ${BINGRP} -m 444 -f ${HFDIR} sendmail.hf
-
-# doesn't actually install them -- you may want to install pre-nroff versions
-install-docs: aliases.0 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.Linux b/usr.sbin/sendmail/src/Makefile.Linux
deleted file mode 100644
index 3c8f3e5..0000000
--- a/usr.sbin/sendmail/src/Makefile.Linux
+++ /dev/null
@@ -1,120 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on Linux 0.99p10.
-#
-# Linux doesn't really have standard places to install things, so this
-# Makefile is likely to require a lot of customization. Read it over
-# carefully before proceeding.
-#
-# @(#)Makefile.Linux 8.7 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF=
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=-I/usr/local/include
-
-# library directories
-LIBDIRS=-L/usr/local/lib
-
-# libraries required on your system
-LIBS= -lndbm
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/sbin
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/etc
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-# additional pseudo-sources needed
-BEFORE=
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/bin/newaliases ${DESTDIR}/usr/bin/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-unistd.h:
- cp /dev/null unistd.h
-
-dirent.h:
- echo "#include <sys/dir.h>" > dirent.h
- echo "#define dirent direct" >> dirent.h
-
-NROFF= nroff
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 ${STDIR}/sendmail.st
- chown ${BINOWN} ${STDIR}/sendmail.st
- chgrp ${BINGRP} ${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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.Mach386 b/usr.sbin/sendmail/src/Makefile.Mach386
deleted file mode 100644
index eaed6ca..0000000
--- a/usr.sbin/sendmail/src/Makefile.Mach386
+++ /dev/null
@@ -1,107 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# @(#)Makefile.Mach386 8.3 (Berkeley) 4/11/94
-#
-
-CC= gcc
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF=
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=
-
-# loader options
-LDOPTS=
-
-# library directories
-LIBDIRS=
-
-# libraries required on your system
-LIBS= -ldbm
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.NCR3000 b/usr.sbin/sendmail/src/Makefile.NCR3000
deleted file mode 100644
index a556951..0000000
--- a/usr.sbin/sendmail/src/Makefile.NCR3000
+++ /dev/null
@@ -1,109 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# NCR 3000 support from Kevin Darcy <kevin@tech.mis.cfc.com>.
-#
-# @(#)Makefile.NCR3000 8.2 (Berkeley) 4/16/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= -DNCR3000
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=-I/usr/ucbinclude
-
-# loader options
-LDOPTS=
-
-# library directories
-LIBDIRS=-L/usr/ucblib
-
-# libraries required on your system
-LIBS= -lsocket -lc -lelf -lucb -ldbm -lnet -lnsl
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/ucblib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/var/ucblib
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/ucblib
-
-# additional .o files needed
-OBJADD=
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-INSTALL=install
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.NeXT b/usr.sbin/sendmail/src/Makefile.NeXT
deleted file mode 100644
index de0dc7f..0000000
--- a/usr.sbin/sendmail/src/Makefile.NeXT
+++ /dev/null
@@ -1,114 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on NeXT 2.1.
-#
-# @(#)Makefile.NeXT 8.3 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= -DNeXT -DNETINFO
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=
-
-# library directories
-LIBDIRS=-L/usr/local/lib
-
-# libraries required on your system
-LIBS= -ldbm
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/etc/sendmail
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-# additional pseudo-sources needed
-BEFORE= unistd.h dirent.h
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-unistd.h:
- cp /dev/null unistd.h
-
-dirent.h:
- echo "#include <sys/dir.h>" > dirent.h
- echo "#define dirent direct" >> dirent.h
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.NetBSD b/usr.sbin/sendmail/src/Makefile.NetBSD
deleted file mode 100644
index b253c0b..0000000
--- a/usr.sbin/sendmail/src/Makefile.NetBSD
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# NetBSD Makefile
-#
-# @(#)Makefile.NetBSD 8.1 (Berkeley) 2/26/94
-# @Id: Makefile.NetBSD,v 1.3 1994/02/01 05:33:44 glass Exp $
-#
-
-PROG= sendmail
-
-# define the database format to use for aliases et al. Can be -DNEWDB (for
-# the new BSD database package -- this is preferred) or -DNDBM for the NDBM
-# database package. The old putrescent V7 DBM package is no longer
-# supported.
-# You can define both NEWDB and NDBM during a transition period; old
-# databases are read, but the new format will be used on any rebuilds. On
-# really gnarly systems, you can set this to null; it will crawl like a high
-# spiral snail, but it will work.
-DBMDEF= -DNEWDB -DNIS
-
-#nasty warning about gcc 2.4.x caused bugs
-CFLAGS=-I${.CURDIR} ${DBMDEF} -DNETISO
-#CFLAGS+=-I${.CURDIR} ${DBMDEF} -DNETISO
-
-SRCS= alias.c arpadate.c clock.c collect.c conf.c convtime.c daemon.c \
- deliver.c domain.c envelope.c err.c headers.c macro.c main.c map.c \
- mci.c parseaddr.c queue.c readcf.c recipient.c savemail.c srvrsmtp.c \
- stab.c stats.c sysexits.c trace.c udb.c usersmtp.c \
- util.c version.c
-MAN1= mailq.0 newaliases.0
-MAN5= aliases.0
-MAN8= sendmail.0
-LINKS= /usr/sbin/sendmail /usr/bin/newaliases \
- /usr/sbin/sendmail /usr/bin/mailq
-BINDIR= /usr/sbin
-BINOWN= root
-BINMODE=4555
-
-beforeinstall:
-# install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \
-# ${DESTDIR}/etc/sendmail.fc
- install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \
- ${DESTDIR}/var/log/sendmail.st
- install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/sendmail.hf \
- ${DESTDIR}/usr/share/misc
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/sendmail/src/Makefile.OSF1 b/usr.sbin/sendmail/src/Makefile.OSF1
deleted file mode 100644
index c79b2bb..0000000
--- a/usr.sbin/sendmail/src/Makefile.OSF1
+++ /dev/null
@@ -1,109 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on OSF/1 1.3
-#
-# @(#)Makefile.OSF1 8.3 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanism used for alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= -Olimit 1000
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=-I/usr/sww/include/db
-
-# library directories
-LIBDIRS=-L/usr/sww/lib -L/usr/shlib -L/usr/lib
-
-# libraries required on your system
-LIBS= -ldbm
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/sbin
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/var/adm/sendmail
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/share/lib
-
-# additional .o files needed
-OBJADD=
-
-# additional link flags
-#LDADD= -non_shared
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${BINDIR}/newaliases ${BINDIR}/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${LDADD} ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-install-sendmail: sendmail
- installbsd -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 644 ${STDIR}/sendmail.st
- chown ${BINOWN}.${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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.PTX b/usr.sbin/sendmail/src/Makefile.PTX
deleted file mode 100644
index f27238b..0000000
--- a/usr.sbin/sendmail/src/Makefile.PTX
+++ /dev/null
@@ -1,114 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# For Sequent DYNIX/ptx.
-#
-# From Tim "Pinball Wizard" Wright <timw@sequent.com>.
-#
-# @(#)Makefile.PTX 8.3 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -g
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF=
-
-# see also conf.h for additional compilation flags
-
-# include directories
-#INCDIRS=-I/usr/sww/include/db
-INCDIRS=
-
-# loader options
-LDOPTS=
-
-# library directories
-#LIBDIRS=-L/usr/sww/lib
-LIBDIRS=
-
-# libraries required on your system
-#LIBS= -ldb -ldbm
-LIBS= -lsocket -linet -lnsl -lseq
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/bin/newaliases ${DESTDIR}/usr/bin/mailq
-BINOWN= root
-BINGRP= sys
-BINMODE=6555
-
-ALL= sendmail aliases.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: $& ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-INSTALL=install
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.RISCos b/usr.sbin/sendmail/src/Makefile.RISCos
deleted file mode 100644
index b4c4b36..0000000
--- a/usr.sbin/sendmail/src/Makefile.RISCos
+++ /dev/null
@@ -1,117 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# For Mips RISC/os 4.52.
-#
-# @(#)Makefile.RISCos 8.3 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# be sure we are compiling in BSD mode
-CC= cc -systype bsd43
-
-# define the database mechanism used for alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= -DRISCOS -Olimit 800
-
-# see also conf.h for additional compilation flags
-
-# include directories
-#INCDIRS=-I/usr/sww/include/db
-
-# library directories
-#LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS= -lmld
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/etc
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-# additional pseudo-sources needed
-BEFORE= stdlib.h dirent.h
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-stdlib.h:
- cp /dev/null $@
-
-dirent.h:
- echo "#include <sys/dir.h>" > dirent.h
- echo "#define dirent direct" >> dirent.h
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.SCO b/usr.sbin/sendmail/src/Makefile.SCO
deleted file mode 100644
index 0eccdab..0000000
--- a/usr.sbin/sendmail/src/Makefile.SCO
+++ /dev/null
@@ -1,104 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on SCO.
-#
-# @(#)Makefile.SCO 8.4 (Berkeley) 4/12/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF=
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= -D_SCO_unix_
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=
-
-# library directories
-LIBDIRS=
-
-# libraries required on your system
-LIBS= -lsocket
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.SVR4 b/usr.sbin/sendmail/src/Makefile.SVR4
deleted file mode 100644
index 92de6dd..0000000
--- a/usr.sbin/sendmail/src/Makefile.SVR4
+++ /dev/null
@@ -1,113 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# Based on a Makefile for Dell SVR4 Issue 2.2 from Kimmo Suominen
-# <kim@grendel.lut.fi> -- I haven't tested this myself. It may
-# work on other SVR4 ports.
-#
-# @(#)Makefile.SVR4 8.3 (Berkeley) 4/11/94
-#
-
-# make sure the shell constructs below use the right shell
-SHELL= /bin/sh
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-CC= gcc
-#DESTDIR=/usr/local/sendmail
-
-# define the database mechanism used for alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNEWDB -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= -D__svr4__
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=
-
-# library directories
-LIBDIRS=
-
-# libraries required on your system
-LIBS= -ldb -ldbm -lresolv -lsocket -lnsl -lelf
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/ucblib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/usr/ucblib
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/ucblib
-
-# additional .o files needed
-OBJADD=
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= mail
-BINMODE=6555
-INSTALL=/usr/ucb/install
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.Solaris b/usr.sbin/sendmail/src/Makefile.Solaris
deleted file mode 100644
index 8256a3e..0000000
--- a/usr.sbin/sendmail/src/Makefile.Solaris
+++ /dev/null
@@ -1,115 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on Solaris 2.1 and 2.2.
-#
-# @(#)Makefile.Solaris 8.5 (Berkeley) 4/12/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-# warning: do not use -O with gcc
-O=
-
-CC= gcc
-
-# define the database mechanism used for alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM -DNIS
-
-# environment definitions (e.g., -D_AIX3)
-# include -DSOLARIS_2_3 for version 2.3 and higher
-ENVDEF= -DSOLARIS
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=-I/usr/sww/include/db
-
-# library directories
-LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS= -lresolv -lsocket -lnsl -lelf
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/var/log
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/etc/mail
-
-# additional .o files needed
-OBJADD=
-
-# things to be made before compilation begins
-BEFORE= sysexits.h
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= sys
-BINMODE=6555
-INSTALL=/usr/ucb/install
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-sysexits.h: /usr/ucbinclude/sysexits.h
- ln -s /usr/ucbinclude/sysexits.h
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.SunOS b/usr.sbin/sendmail/src/Makefile.SunOS
deleted file mode 100644
index ee3025f..0000000
--- a/usr.sbin/sendmail/src/Makefile.SunOS
+++ /dev/null
@@ -1,111 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on SunOS 4.1.[12].
-# For SunOS 4.0.3, add -DSUNOS403 to the ENVDEF macro, and
-# create empty files stdlib.h and stddef.h in your
-# compile directory.
-#
-# @(#)Makefile.SunOS 8.3 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM -DNEWDB -DNIS
-
-# environment definitions (e.g., -D_AIX3)
-# need to add -DSUNOS403 if you are on a SunOS 4.0.3 system
-ENVDEF=
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=-I/usr/sww/include/db
-
-# loader options
-LDOPTS= -Bstatic
-
-# library directories
-LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS= -ldb -ldbm -lresolv
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/etc
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.SunOS.4.0.3 b/usr.sbin/sendmail/src/Makefile.SunOS.4.0.3
deleted file mode 100644
index 126ac64..0000000
--- a/usr.sbin/sendmail/src/Makefile.SunOS.4.0.3
+++ /dev/null
@@ -1,113 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# You may find you need to find versions of some routines
-# such as strcasecmp in order to link this on SunOS 4.0.3.
-#
-# @(#)Makefile.SunOS.4.0.3 8.3 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM -DNEWDB -DNIS
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= -DSUNOS403
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=-I/usr/sww/include/db
-
-# loader options
-LDOPTS= -Bstatic
-
-# library directories
-LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS= -ldb -ldbm -lresolv
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/etc
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-BEFORE= stdlib.h stddef.h
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS}
-
-stddef.h stdlib.h:
- cp /dev/null $@
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.SunOS.5.1 b/usr.sbin/sendmail/src/Makefile.SunOS.5.1
deleted file mode 100644
index 8256a3e..0000000
--- a/usr.sbin/sendmail/src/Makefile.SunOS.5.1
+++ /dev/null
@@ -1,115 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on Solaris 2.1 and 2.2.
-#
-# @(#)Makefile.Solaris 8.5 (Berkeley) 4/12/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-# warning: do not use -O with gcc
-O=
-
-CC= gcc
-
-# define the database mechanism used for alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM -DNIS
-
-# environment definitions (e.g., -D_AIX3)
-# include -DSOLARIS_2_3 for version 2.3 and higher
-ENVDEF= -DSOLARIS
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=-I/usr/sww/include/db
-
-# library directories
-LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS= -lresolv -lsocket -lnsl -lelf
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/var/log
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/etc/mail
-
-# additional .o files needed
-OBJADD=
-
-# things to be made before compilation begins
-BEFORE= sysexits.h
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= sys
-BINMODE=6555
-INSTALL=/usr/ucb/install
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-sysexits.h: /usr/ucbinclude/sysexits.h
- ln -s /usr/ucbinclude/sysexits.h
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.SunOS.5.2 b/usr.sbin/sendmail/src/Makefile.SunOS.5.2
deleted file mode 100644
index 8256a3e..0000000
--- a/usr.sbin/sendmail/src/Makefile.SunOS.5.2
+++ /dev/null
@@ -1,115 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on Solaris 2.1 and 2.2.
-#
-# @(#)Makefile.Solaris 8.5 (Berkeley) 4/12/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-# warning: do not use -O with gcc
-O=
-
-CC= gcc
-
-# define the database mechanism used for alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM -DNIS
-
-# environment definitions (e.g., -D_AIX3)
-# include -DSOLARIS_2_3 for version 2.3 and higher
-ENVDEF= -DSOLARIS
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=-I/usr/sww/include/db
-
-# library directories
-LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS= -lresolv -lsocket -lnsl -lelf
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/var/log
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/etc/mail
-
-# additional .o files needed
-OBJADD=
-
-# things to be made before compilation begins
-BEFORE= sysexits.h
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= sys
-BINMODE=6555
-INSTALL=/usr/ucb/install
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-sysexits.h: /usr/ucbinclude/sysexits.h
- ln -s /usr/ucbinclude/sysexits.h
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.SunOS.5.x b/usr.sbin/sendmail/src/Makefile.SunOS.5.x
deleted file mode 100644
index 1b7d268..0000000
--- a/usr.sbin/sendmail/src/Makefile.SunOS.5.x
+++ /dev/null
@@ -1,115 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on Solaris 2.3.
-#
-# @(#)Makefile.SunOS.5.x 8.5 (Berkeley) 4/12/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-# warning: do not use -O with gcc
-O=
-
-CC= gcc
-
-# define the database mechanism used for alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM -DNIS
-
-# environment definitions (e.g., -D_AIX3)
-# include -DSOLARIS_2_3 for version 2.3 and higher
-ENVDEF= -DSOLARIS_2_3
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=-I/usr/sww/include/db
-
-# library directories
-LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS= -lresolv -lsocket -lnsl -lelf
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/var/log
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/etc/mail
-
-# additional .o files needed
-OBJADD=
-
-# things to be made before compilation begins
-BEFORE= sysexits.h
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= sys
-BINMODE=6555
-INSTALL=/usr/ucb/install
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${OBJS} ${LIBDIRS} ${LIBS}
-
-sysexits.h: /usr/ucbinclude/sysexits.h
- ln -s /usr/ucbinclude/sysexits.h
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.Titan b/usr.sbin/sendmail/src/Makefile.Titan
deleted file mode 100644
index 89b156a..0000000
--- a/usr.sbin/sendmail/src/Makefile.Titan
+++ /dev/null
@@ -1,114 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# @(#)Makefile.Titan 8.3 (Berkeley) 4/11/94
-#
-
-# put the compiler in BSD mode
-CC= cc -43
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF=
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=
-
-# loader options
-LDOPTS=
-
-# library directories
-LIBDIRS=
-
-# libraries required on your system
-LIBS= -ldbm
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/var/log
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/share/misc
-
-# additional .o files needed
-OBJADD=
-
-# additional pseudo-sources needed
-BEFORE= stddef.h stdlib.h
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS}
-
-stddef.h stdlib.h:
- cp /dev/null $@
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.ULTRIX b/usr.sbin/sendmail/src/Makefile.ULTRIX
deleted file mode 100644
index a3f222e..0000000
--- a/usr.sbin/sendmail/src/Makefile.ULTRIX
+++ /dev/null
@@ -1,107 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on Ultrix 4.2A and 4.3A.
-#
-# @(#)Makefile.ULTRIX 8.3 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM -DNEWDB -DNIS
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= -Olimit 800
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=-I/usr/sww/include/db
-
-# loader options
-LDOPTS=
-
-# library directories
-LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS= -ldb
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/var/log
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.UMAX b/usr.sbin/sendmail/src/Makefile.UMAX
deleted file mode 100644
index c69e2b6..0000000
--- a/usr.sbin/sendmail/src/Makefile.UMAX
+++ /dev/null
@@ -1,114 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# This has been tested on Encore UMAX V
-#
-# @(#)Makefile.UMAX 8.3 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNIS
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= -DUMAXV
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=
-
-# loader options
-LDOPTS=
-
-# library directories
-LIBDIRS=
-
-# libraries required on your system
-LIBS= -lyp -lrpc
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/lib
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/var/log
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/lib
-
-# additional .o files needed
-OBJADD=
-
-# things to do before compilation
-BEFORE= stddef.h
-
-stddef.h:
- echo "#define _STDDEF_H" > stddef.h
- chmod 444 stddef.h
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/Makefile.Utah b/usr.sbin/sendmail/src/Makefile.Utah
deleted file mode 100644
index 84f2403..0000000
--- a/usr.sbin/sendmail/src/Makefile.Utah
+++ /dev/null
@@ -1,40 +0,0 @@
-# @(#)Makefile.Utah 8.1 (Berkeley) 2/26/94
-
-PROG= sendmail
-
-# define the database format to use for aliases et al. Can be -DNEWDB (for
-# the new BSD database package -- this is preferred) or -DNDBM for the NDBM
-# database package. The old putrescent V7 DBM package is no longer
-# supported.
-# You can define both NEWDB and NDBM during a transition period; old
-# databases are read, but the new format will be used on any rebuilds. On
-# really gnarly systems, you can set this to null; it will crawl like a high
-# spiral snail, but it will work.
-DBMDEF= -DNEWDB -DNDBM -DOLD_NEWDB
-
-CFLAGS+=-I${.CURDIR} ${DBMDEF} -Dsetpgid=setpgrp
-
-SRCS= alias.c arpadate.c clock.c collect.c conf.c convtime.c daemon.c \
- deliver.c domain.c envelope.c err.c headers.c macro.c main.c map.c \
- mci.c parseaddr.c queue.c readcf.c recipient.c savemail.c srvrsmtp.c \
- stab.c stats.c sysexits.c trace.c udb.c usersmtp.c \
- util.c version.c
-DPADD= ${LIBDBM} ${LIBCOMPAT}
-LDADD=
-MAN1= mailq.0 newaliases.0
-MAN5= aliases.0
-MAN8= sendmail.0
-LINKS= ${DESTDIR}/usr/sbin/sendmail ${DESTDIR}/usr/bin/newaliases \
- ${DESTDIR}/usr/sbin/sendmail ${DESTDIR}/usr/bin/mailq
-BINDIR= /usr/sbin
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-beforeinstall:
- install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \
- ${DESTDIR}/var/log/sendmail.st
- install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/sendmail.hf \
- ${DESTDIR}/usr/share/misc
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/sendmail/src/Makefile.dist b/usr.sbin/sendmail/src/Makefile.dist
deleted file mode 100644
index 5fab596..0000000
--- a/usr.sbin/sendmail/src/Makefile.dist
+++ /dev/null
@@ -1,107 +0,0 @@
-#
-# This Makefile is designed to work on the old "make" program. It does
-# not use the obj subdirectory. It also does not install documentation
-# automatically -- think of it as a quick start for sites that have the
-# old make program (I recommend that you get and port the new make if you
-# are going to be doing any signficant work on sendmail).
-#
-# @(#)Makefile.dist 8.12 (Berkeley) 4/11/94
-#
-
-# use O=-O (usual) or O=-g (debugging)
-O= -O
-
-# define the database mechanisms available for map & alias lookups:
-# -DNDBM -- use new DBM
-# -DNEWDB -- use new Berkeley DB
-# -DNIS -- include NIS support
-# The really old (V7) DBM library is no longer supported.
-# See READ_ME for a description of how these flags interact.
-#
-DBMDEF= -DNDBM -DNEWDB
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF=
-
-# see also conf.h for additional compilation flags
-
-# include directories
-INCDIRS=-I/usr/sww/include/db
-
-# loader options
-LDOPTS=
-
-# library directories
-LIBDIRS=-L/usr/sww/lib
-
-# libraries required on your system
-LIBS= -ldb -ldbm
-
-# location of sendmail binary (usually /usr/sbin or /usr/lib)
-BINDIR= ${DESTDIR}/usr/sbin
-
-# location of sendmail.st file (usually /var/log or /usr/lib)
-STDIR= ${DESTDIR}/var/log
-
-# location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
-HFDIR= ${DESTDIR}/usr/share/misc
-
-# additional .o files needed
-OBJADD=
-
-################### end of user configuration flags ######################
-
-CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF}
-
-OBJS= alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o \
- deliver.o domain.o envelope.o err.o headers.o macro.o main.o \
- map.o mci.o parseaddr.o queue.o readcf.o recipient.o \
- savemail.o srvrsmtp.o stab.o stats.o sysexits.o \
- trace.o udb.o usersmtp.o util.o version.o ${OBJADD}
-
-LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq
-BINOWN= root
-BINGRP= kmem
-BINMODE=6555
-
-ALL= sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-all: ${ALL}
-
-sendmail: ${BEFORE} ${OBJS}
- ${CC} -o sendmail ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS}
-
-NROFF= nroff -h
-
-aliases.0: aliases.5
- ${NROFF} -mandoc aliases.5 > aliases.0
-
-mailq.0: mailq.1
- ${NROFF} -mandoc mailq.1 > mailq.0
-
-newaliases.0: newaliases.1
- ${NROFF} -mandoc newaliases.1 > newaliases.0
-
-sendmail.0: sendmail.8
- ${NROFF} -mandoc sendmail.8 > sendmail.0
-
-INSTALL=install
-
-install: install-sendmail install-docs
-
-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 644 /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 mailq.0 newaliases.0 sendmail.0
-
-clean:
- rm -f ${OBJS} sendmail aliases.0 mailq.0 newaliases.0 sendmail.0
-
-# dependencies
-# gross overkill, and yet still not quite enough....
-${OBJS}: sendmail.h conf.h
diff --git a/usr.sbin/sendmail/src/collect.c b/usr.sbin/sendmail/src/collect.c
index 29546ce..7e43c5f 100644
--- a/usr.sbin/sendmail/src/collect.c
+++ b/usr.sbin/sendmail/src/collect.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)collect.c 8.14 (Berkeley) 4/18/94";
+static char sccsid[] = "@(#)collect.c 8.49 (Berkeley) 10/29/95";
#endif /* not lint */
# include <errno.h>
@@ -47,12 +47,14 @@ static char sccsid[] = "@(#)collect.c 8.14 (Berkeley) 4/18/94";
** stripped off (after important information is extracted).
**
** Parameters:
+** fp -- file to read.
** smtpmode -- if set, we are running SMTP: give an RFC821
** style message to say we are ready to collect
** input, and never ignore a single dot to mean
** end of message.
** requeueflag -- this message will be requeued later, so
** don't do final processing on it.
+** hdrp -- the location to stash the header.
** e -- the current envelope.
**
** Returns:
@@ -63,37 +65,77 @@ static char sccsid[] = "@(#)collect.c 8.14 (Berkeley) 4/18/94";
** The from person may be set.
*/
-char *CollectErrorMessage;
-bool CollectErrno;
-
-collect(smtpmode, requeueflag, e)
+static jmp_buf CtxCollectTimeout;
+static void collecttimeout();
+static bool CollectProgress;
+static EVENT *CollectTimeout;
+
+/* values for input state machine */
+#define IS_NORM 0 /* middle of line */
+#define IS_BOL 1 /* beginning of line */
+#define IS_DOT 2 /* read a dot at beginning of line */
+#define IS_DOTCR 3 /* read ".\r" at beginning of line */
+#define IS_CR 4 /* read a carriage return */
+
+/* values for message state machine */
+#define MS_UFROM 0 /* reading Unix from line */
+#define MS_HEADER 1 /* reading message header */
+#define MS_BODY 2 /* reading message body */
+
+void
+collect(fp, smtpmode, requeueflag, hdrp, e)
+ FILE *fp;
bool smtpmode;
bool requeueflag;
+ HDR **hdrp;
register ENVELOPE *e;
{
register FILE *tf;
bool ignrdot = smtpmode ? FALSE : IgnrDot;
time_t dbto = smtpmode ? TimeOuts.to_datablock : 0;
- char buf[MAXLINE], buf2[MAXLINE];
- register char *workbuf, *freebuf;
+ register char *bp;
+ int c = '\0';
bool inputerr = FALSE;
- extern char *hvalue();
- extern bool isheader(), flusheol();
-
- CollectErrorMessage = NULL;
- CollectErrno = 0;
+ bool headeronly;
+ char *buf;
+ int buflen;
+ int istate;
+ int mstate;
+ char *pbp;
+ char peekbuf[8];
+ char dfname[20];
+ char bufbuf[MAXLINE];
+ extern bool isheader();
+ extern void eatheader();
+ extern void tferror();
+
+ headeronly = hdrp != NULL;
/*
** Create the temp file name and create the file.
*/
- e->e_df = queuename(e, 'd');
- e->e_df = newstr(e->e_df);
- if ((tf = dfopen(e->e_df, O_WRONLY|O_CREAT|O_TRUNC, FileMode)) == NULL)
+ if (!headeronly)
{
- syserr("Cannot create %s", e->e_df);
- NoReturn = TRUE;
- finis();
+ struct stat stbuf;
+
+ strcpy(dfname, queuename(e, 'd'));
+ if ((tf = dfopen(dfname, O_WRONLY|O_CREAT|O_TRUNC, FileMode)) == NULL)
+ {
+ syserr("Cannot create %s", dfname);
+ e->e_flags |= EF_NO_BODY_RETN;
+ finis();
+ }
+ if (fstat(fileno(tf), &stbuf) < 0)
+ e->e_dfino = -1;
+ else
+ {
+ e->e_dfdev = stbuf.st_dev;
+ e->e_dfino = stbuf.st_ino;
+ }
+ HasEightBits = FALSE;
+ e->e_msgsize = 0;
+ e->e_flags |= EF_HAS_DF;
}
/*
@@ -103,223 +145,296 @@ collect(smtpmode, requeueflag, e)
if (smtpmode)
message("354 Enter mail, end with \".\" on a line by itself");
- /* set global timer to monitor progress */
- sfgetset(dbto);
+ if (tTd(30, 2))
+ printf("collect\n");
/*
- ** Try to read a UNIX-style From line
+ ** Read the message.
+ **
+ ** This is done using two interleaved state machines.
+ ** The input state machine is looking for things like
+ ** hidden dots; the message state machine is handling
+ ** the larger picture (e.g., header versus body).
*/
- if (sfgets(buf, MAXLINE, InChannel, dbto,
- "initial message read") == NULL)
- goto readerr;
- fixcrlf(buf, FALSE);
-# ifndef NOTUNIX
- if (!SaveFrom && strncmp(buf, "From ", 5) == 0)
+ buf = bp = bufbuf;
+ buflen = sizeof bufbuf;
+ pbp = peekbuf;
+ istate = IS_BOL;
+ mstate = SaveFrom ? MS_HEADER : MS_UFROM;
+ CollectProgress = FALSE;
+
+ if (dbto != 0)
{
- if (!flusheol(buf, InChannel))
- goto readerr;
- eatfrom(buf, e);
- if (sfgets(buf, MAXLINE, InChannel, dbto,
- "message header read") == NULL)
+ /* handle possible input timeout */
+ if (setjmp(CtxCollectTimeout) != 0)
+ {
+#ifdef LOG
+ syslog(LOG_NOTICE,
+ "timeout waiting for input from %s during message collect",
+ CurHostName ? CurHostName : "<local machine>");
+#endif
+ errno = 0;
+ usrerr("451 timeout waiting for input during message collect");
goto readerr;
- fixcrlf(buf, FALSE);
+ }
+ CollectTimeout = setevent(dbto, collecttimeout, dbto);
}
-# endif /* NOTUNIX */
- /*
- ** Copy InChannel to temp file & do message editing.
- ** To keep certain mailers from getting confused,
- ** and to keep the output clean, lines that look
- ** like UNIX "From" lines are deleted in the header.
- */
-
- workbuf = buf; /* `workbuf' contains a header field */
- freebuf = buf2; /* `freebuf' can be used for read-ahead */
for (;;)
{
- char *curbuf;
- int curbuffree;
- register int curbuflen;
- char *p;
-
- /* first, see if the header is over */
- if (!isheader(workbuf))
- {
- fixcrlf(workbuf, TRUE);
- break;
- }
-
- /* if the line is too long, throw the rest away */
- if (!flusheol(workbuf, InChannel))
- goto readerr;
-
- /* it's okay to toss '\n' now (flusheol() needed it) */
- fixcrlf(workbuf, TRUE);
-
- curbuf = workbuf;
- curbuflen = strlen(curbuf);
- curbuffree = MAXLINE - curbuflen;
- p = curbuf + curbuflen;
-
- /* get the rest of this field */
+ if (tTd(30, 35))
+ printf("top, istate=%d, mstate=%d\n", istate, mstate);
for (;;)
{
- int clen;
-
- if (sfgets(freebuf, MAXLINE, InChannel, dbto,
- "message header read") == NULL)
+ if (pbp > peekbuf)
+ c = *--pbp;
+ else
{
- freebuf[0] = '\0';
- break;
+ while (!feof(fp) && !ferror(fp))
+ {
+ errno = 0;
+ c = getc(fp);
+ if (errno != EINTR)
+ break;
+ clearerr(fp);
+ }
+ CollectProgress = TRUE;
+ if (TrafficLogFile != NULL && !headeronly)
+ {
+ if (istate == IS_BOL)
+ fprintf(TrafficLogFile, "%05d <<< ",
+ getpid());
+ if (c == EOF)
+ fprintf(TrafficLogFile, "[EOF]\n");
+ else
+ putc(c, TrafficLogFile);
+ }
+ if (c == EOF)
+ goto readerr;
+ if (SevenBitInput)
+ c &= 0x7f;
+ else
+ HasEightBits |= bitset(0x80, c);
+ if (!headeronly)
+ e->e_msgsize++;
}
+ if (tTd(30, 94))
+ printf("istate=%d, c=%c (0x%x)\n",
+ istate, c, c);
+ switch (istate)
+ {
+ case IS_BOL:
+ if (c == '.')
+ {
+ istate = IS_DOT;
+ continue;
+ }
+ break;
- /* is this a continuation line? */
- if (*freebuf != ' ' && *freebuf != '\t')
+ case IS_DOT:
+ if (c == '\n' && !ignrdot &&
+ !bitset(EF_NL_NOT_EOL, e->e_flags))
+ goto readerr;
+ else if (c == '\r' &&
+ !bitset(EF_CRLF_NOT_EOL, e->e_flags))
+ {
+ istate = IS_DOTCR;
+ continue;
+ }
+ else if (c != '.' ||
+ (OpMode != MD_SMTP &&
+ OpMode != MD_DAEMON &&
+ OpMode != MD_ARPAFTP))
+ {
+ *pbp++ = c;
+ c = '.';
+ }
break;
- if (!flusheol(freebuf, InChannel))
- goto readerr;
+ case IS_DOTCR:
+ if (c == '\n')
+ goto readerr;
+ else
+ {
+ /* push back the ".\rx" */
+ *pbp++ = c;
+ *pbp++ = '\r';
+ c = '.';
+ }
+ break;
- fixcrlf(freebuf, TRUE);
- clen = strlen(freebuf) + 1;
+ case IS_CR:
+ if (c == '\n')
+ istate = IS_BOL;
+ else
+ {
+ ungetc(c, fp);
+ c = '\r';
+ istate = IS_NORM;
+ }
+ goto bufferchar;
+ }
- /* if insufficient room, dynamically allocate buffer */
- if (clen >= curbuffree)
+ if (c == '\r' && !bitset(EF_CRLF_NOT_EOL, e->e_flags))
{
- /* reallocate buffer */
- int nbuflen = ((p - curbuf) + clen) * 2;
- char *nbuf = xalloc(nbuflen);
-
- p = nbuf + curbuflen;
- curbuffree = nbuflen - curbuflen;
- bcopy(curbuf, nbuf, curbuflen);
- if (curbuf != buf && curbuf != buf2)
- free(curbuf);
- curbuf = nbuf;
+ istate = IS_CR;
+ continue;
}
- *p++ = '\n';
- bcopy(freebuf, p, clen - 1);
- p += clen - 1;
- curbuffree -= clen;
- curbuflen += clen;
- }
- *p++ = '\0';
-
- e->e_msgsize += curbuflen;
-
- /*
- ** The working buffer now becomes the free buffer, since
- ** the free buffer contains a new header field.
- **
- ** This is premature, since we still havent called
- ** chompheader() to process the field we just created
- ** (so the call to chompheader() will use `freebuf').
- ** This convolution is necessary so that if we break out
- ** of the loop due to H_EOH, `workbuf' will always be
- ** the next unprocessed buffer.
- */
+ else if (c == '\n' && !bitset(EF_NL_NOT_EOL, e->e_flags))
+ istate = IS_BOL;
+ else
+ istate = IS_NORM;
- {
- register char *tmp = workbuf;
- workbuf = freebuf;
- freebuf = tmp;
- }
+bufferchar:
+ if (mstate == MS_BODY)
+ {
+ /* just put the character out */
+ if (MaxMessageSize <= 0 ||
+ e->e_msgsize <= MaxMessageSize)
+ putc(c, tf);
+ continue;
+ }
- /*
- ** Snarf header away.
- */
+ /* header -- buffer up */
+ if (bp >= &buf[buflen - 2])
+ {
+ char *obuf;
+
+ if (mstate != MS_HEADER)
+ break;
+
+ /* out of space for header */
+ obuf = buf;
+ if (buflen < MEMCHUNKSIZE)
+ buflen *= 2;
+ else
+ buflen += MEMCHUNKSIZE;
+ buf = xalloc(buflen);
+ bcopy(obuf, buf, bp - obuf);
+ bp = &buf[bp - obuf];
+ if (obuf != bufbuf)
+ free(obuf);
+ }
+ if (c != '\0')
+ *bp++ = c;
+ if (istate == IS_BOL)
+ break;
+ }
+ *bp = '\0';
- if (bitset(H_EOH, chompheader(curbuf, FALSE, e)))
- break;
+nextstate:
+ if (tTd(30, 35))
+ printf("nextstate, istate=%d, mstate=%d, line = \"%s\"\n",
+ istate, mstate, buf);
+ switch (mstate)
+ {
+ extern int chompheader();
- /*
- ** If the buffer was dynamically allocated, free it.
- */
+ case MS_UFROM:
+ mstate = MS_HEADER;
+#ifndef NOTUNIX
+ if (strncmp(buf, "From ", 5) == 0)
+ {
+ extern void eatfrom();
- if (curbuf != buf && curbuf != buf2)
- free(curbuf);
- }
+ bp = buf;
+ eatfrom(buf, e);
+ continue;
+ }
+#endif
+ /* fall through */
- if (tTd(30, 1))
- printf("EOH\n");
+ case MS_HEADER:
+ if (!isheader(buf))
+ {
+ mstate = MS_BODY;
+ goto nextstate;
+ }
- if (*workbuf == '\0')
- {
- /* throw away a blank line */
- if (sfgets(buf, MAXLINE, InChannel, dbto,
- "message separator read") == NULL)
- goto readerr;
- }
- else if (workbuf == buf2) /* guarantee `buf' contains data */
- (void) strcpy(buf, buf2);
+ /* check for possible continuation line */
+ do
+ {
+ clearerr(fp);
+ errno = 0;
+ c = getc(fp);
+ } while (errno == EINTR);
+ if (c != EOF)
+ ungetc(c, fp);
+ if (c == ' ' || c == '\t')
+ {
+ /* yep -- defer this */
+ continue;
+ }
- /*
- ** Collect the body of the message.
- */
+ /* trim off trailing CRLF or NL */
+ if (*--bp != '\n' || *--bp != '\r')
+ bp++;
+ *bp = '\0';
+ if (bitset(H_EOH, chompheader(buf, FALSE, hdrp, e)))
+ mstate = MS_BODY;
+ break;
- for (;;)
- {
- register char *bp = buf;
+ case MS_BODY:
+ if (tTd(30, 1))
+ printf("EOH\n");
+ if (headeronly)
+ goto readerr;
+ bp = buf;
- fixcrlf(buf, TRUE);
+ /* toss blank line */
+ if ((!bitset(EF_CRLF_NOT_EOL, e->e_flags) &&
+ bp[0] == '\r' && bp[1] == '\n') ||
+ (!bitset(EF_NL_NOT_EOL, e->e_flags) &&
+ bp[0] == '\n'))
+ {
+ break;
+ }
- /* check for end-of-message */
- if (!ignrdot && buf[0] == '.' && (buf[1] == '\n' || buf[1] == '\0'))
+ /* if not a blank separator, write it out */
+ if (MaxMessageSize <= 0 ||
+ e->e_msgsize <= MaxMessageSize)
+ {
+ while (*bp != '\0')
+ putc(*bp++, tf);
+ }
break;
-
- /* check for transparent dot */
- if ((OpMode == MD_SMTP || OpMode == MD_DAEMON) &&
- bp[0] == '.' && bp[1] == '.')
- bp++;
-
- /*
- ** Figure message length, output the line to the temp
- ** file, and insert a newline if missing.
- */
-
- e->e_msgsize += strlen(bp) + 1;
- fputs(bp, tf);
- fputs("\n", tf);
- if (ferror(tf))
- tferror(tf, e);
- if (sfgets(buf, MAXLINE, InChannel, dbto,
- "message body read") == NULL)
- goto readerr;
+ }
+ bp = buf;
}
- if (feof(InChannel) || ferror(InChannel))
- {
readerr:
+ if ((feof(fp) && smtpmode) || ferror(fp))
+ {
+ const char *errmsg = errstring(errno);
+
if (tTd(30, 1))
- printf("collect: read error\n");
+ printf("collect: premature EOM: %s\n", errmsg);
+#ifdef LOG
+ if (LogLevel >= 2)
+ syslog(LOG_WARNING, "collect: premature EOM: %s", errmsg);
+#endif
inputerr = TRUE;
}
/* reset global timer */
- sfgetset((time_t) 0);
+ clrevent(CollectTimeout);
- if (fflush(tf) != 0)
- tferror(tf, e);
- if (fsync(fileno(tf)) < 0 || fclose(tf) < 0)
+ if (headeronly)
+ return;
+
+ if (tf != NULL &&
+ (fflush(tf) != 0 || ferror(tf) || fsync(fileno(tf)) < 0 ||
+ fclose(tf) < 0))
{
tferror(tf, e);
+ flush_errors(TRUE);
finis();
}
- if (CollectErrorMessage != NULL && Errors <= 0)
- {
- if (CollectErrno != 0)
- {
- errno = CollectErrno;
- syserr(CollectErrorMessage, e->e_df);
- finis();
- }
- usrerr(CollectErrorMessage);
- }
- else if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
+ /* An EOF when running SMTP is an error */
+ if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
{
- /* An EOF when running SMTP is an error */
char *host;
char *problem;
@@ -327,24 +442,28 @@ readerr:
if (host == NULL)
host = "localhost";
- if (feof(InChannel))
+ if (feof(fp))
problem = "unexpected close";
- else if (ferror(InChannel))
+ else if (ferror(fp))
problem = "I/O error";
else
problem = "read timeout";
# ifdef LOG
- if (LogLevel > 0 && feof(InChannel))
+ if (LogLevel > 0 && feof(fp))
syslog(LOG_NOTICE,
- "collect: %s on connection from %s, sender=%s: %s\n",
- problem, host, e->e_from.q_paddr, errstring(errno));
+ "collect: %s on connection from %.100s, sender=%s: %s",
+ problem, host,
+ shortenstring(e->e_from.q_paddr, 203),
+ errstring(errno));
# endif
- if (feof(InChannel))
+ if (feof(fp))
usrerr("451 collect: %s on connection from %s, from=%s",
- problem, host, e->e_from.q_paddr);
+ problem, host,
+ shortenstring(e->e_from.q_paddr, 203));
else
syserr("451 collect: %s on connection from %s, from=%s",
- problem, host, e->e_from.q_paddr);
+ problem, host,
+ shortenstring(e->e_from.q_paddr, 203));
/* don't return an error indication */
e->e_to = NULL;
@@ -364,84 +483,128 @@ readerr:
eatheader(e, !requeueflag);
+ if (GrabTo && e->e_sendqueue == NULL)
+ usrerr("No recipient addresses found in header");
+
/* collect statistics */
if (OpMode != MD_VERIFY)
+ {
+ extern void markstats();
+
markstats(e, (ADDRESS *) NULL);
+ }
/*
** Add an Apparently-To: line if we have no recipient lines.
*/
- if (hvalue("to", e) == NULL && hvalue("cc", e) == NULL &&
- hvalue("bcc", e) == NULL && hvalue("apparently-to", e) == NULL)
+ if (hvalue("to", e->e_header) != NULL ||
+ hvalue("cc", e->e_header) != NULL ||
+ hvalue("apparently-to", e->e_header) != NULL)
{
+ /* have a valid recipient header -- delete Bcc: headers */
+ e->e_flags |= EF_DELETE_BCC;
+ }
+ else if (hvalue("bcc", e->e_header) == NULL)
+ {
+ /* no valid recipient headers */
register ADDRESS *q;
+ char *hdr = NULL;
+ extern void addheader();
/* create an Apparently-To: field */
/* that or reject the message.... */
- for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+ switch (NoRecipientAction)
{
- if (q->q_alias != NULL)
- continue;
- if (tTd(30, 3))
- printf("Adding Apparently-To: %s\n", q->q_paddr);
- addheader("Apparently-To", q->q_paddr, e);
+ case NRA_ADD_APPARENTLY_TO:
+ hdr = "Apparently-To";
+ break;
+
+ case NRA_ADD_TO:
+ hdr = "To";
+ break;
+
+ case NRA_ADD_BCC:
+ addheader("Bcc", "", &e->e_header);
+ break;
+
+ case NRA_ADD_TO_UNDISCLOSED:
+ addheader("To", "undisclosed-recipients:;", &e->e_header);
+ break;
+ }
+
+ if (hdr != NULL)
+ {
+ for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+ {
+ if (q->q_alias != NULL)
+ continue;
+ if (tTd(30, 3))
+ printf("Adding %s: %s\n",
+ hdr, q->q_paddr);
+ addheader(hdr, q->q_paddr, &e->e_header);
+ }
}
}
/* check for message too large */
if (MaxMessageSize > 0 && e->e_msgsize > MaxMessageSize)
{
+ e->e_status = "5.2.3";
usrerr("552 Message exceeds maximum fixed size (%ld)",
MaxMessageSize);
+# ifdef LOG
+ if (LogLevel > 6)
+ syslog(LOG_NOTICE, "%s: message size (%ld) exceeds maximum (%ld)",
+ e->e_id, e->e_msgsize, MaxMessageSize);
+# endif
}
- if ((e->e_dfp = fopen(e->e_df, "r")) == NULL)
+ /* check for illegal 8-bit data */
+ if (HasEightBits)
+ {
+ e->e_flags |= EF_HAS8BIT;
+ if (!bitset(MM_PASS8BIT|MM_MIME8BIT, MimeMode))
+ {
+ e->e_status = "5.6.1";
+ usrerr("554 Eight bit data not allowed");
+ }
+ }
+ else
+ {
+ /* if it claimed to be 8 bits, well, it lied.... */
+ if (e->e_bodytype != NULL &&
+ strcasecmp(e->e_bodytype, "8BITMIME") == 0)
+ e->e_bodytype = "7BIT";
+ }
+
+ if ((e->e_dfp = fopen(dfname, "r")) == NULL)
{
/* we haven't acked receipt yet, so just chuck this */
- syserr("Cannot reopen %s", e->e_df);
+ syserr("Cannot reopen %s", dfname);
finis();
}
}
- /*
-** FLUSHEOL -- if not at EOL, throw away rest of input line.
-**
-** Parameters:
-** buf -- last line read in (checked for '\n'),
-** fp -- file to be read from.
-**
-** Returns:
-** FALSE on error from sfgets(), TRUE otherwise.
-**
-** Side Effects:
-** none.
-*/
-bool
-flusheol(buf, fp)
- char *buf;
- FILE *fp;
-{
- register char *p = buf;
- char junkbuf[MAXLINE];
- while (strchr(p, '\n') == NULL)
- {
- CollectErrorMessage = "553 header line too long";
- CollectErrno = 0;
- if (sfgets(junkbuf, MAXLINE, fp, TimeOuts.to_datablock,
- "long line flush") == NULL)
- return (FALSE);
- p = junkbuf;
- }
+static void
+collecttimeout(timeout)
+ time_t timeout;
+{
+ /* if no progress was made, die now */
+ if (!CollectProgress)
+ longjmp(CtxCollectTimeout, 1);
- return (TRUE);
+ /* otherwise reset the timeout */
+ CollectTimeout = setevent(timeout, collecttimeout, timeout);
+ CollectProgress = FALSE;
}
/*
** TFERROR -- signal error on writing the temporary file.
**
** Parameters:
** tf -- the file pointer for the temporary file.
+** e -- the current envelope.
**
** Returns:
** none.
@@ -451,21 +614,22 @@ flusheol(buf, fp)
** Arranges for following output to go elsewhere.
*/
+void
tferror(tf, e)
FILE *tf;
register ENVELOPE *e;
{
- CollectErrno = errno;
+ setstat(EX_IOERR);
if (errno == ENOSPC)
{
struct stat st;
long avail;
long bsize;
- NoReturn = TRUE;
+ e->e_flags |= EF_NO_BODY_RETN;
if (fstat(fileno(tf), &st) < 0)
st.st_size = 0;
- (void) freopen(e->e_df, "w", tf);
+ (void) freopen(queuename(e, 'd'), "w", tf);
if (st.st_size <= 0)
fprintf(tf, "\n*** Mail could not be accepted");
else if (sizeof st.st_size > sizeof (long))
@@ -476,7 +640,7 @@ tferror(tf, e)
st.st_size);
fprintf(tf, "*** at %s due to lack of disk space for temp file.\n",
MyHostName);
- avail = freespace(QueueDir, &bsize);
+ avail = freediskspace(QueueDir, &bsize);
if (avail > 0)
{
if (bsize > 1024)
@@ -486,12 +650,11 @@ tferror(tf, e)
fprintf(tf, "*** Currently, %ld kilobytes are available for mail temp files.\n",
avail);
}
- CollectErrorMessage = "452 Out of disk space for temp file";
+ e->e_status = "4.3.1";
+ usrerr("452 Out of disk space for temp file");
}
else
- {
- CollectErrorMessage = "cannot write message body to disk (%s)";
- }
+ syserr("collect: Cannot write tf%s", e->e_id);
(void) freopen("/dev/null", "w", tf);
}
/*
@@ -525,6 +688,7 @@ char *MonthList[] =
NULL
};
+void
eatfrom(fm, e)
char *fm;
register ENVELOPE *e;
diff --git a/usr.sbin/sendmail/src/conf.c b/usr.sbin/sendmail/src/conf.c
index de71851..ee47763 100644
--- a/usr.sbin/sendmail/src/conf.c
+++ b/usr.sbin/sendmail/src/conf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -33,15 +33,13 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)conf.c 8.89.1.3 (Berkeley) 3/7/95";
+static char sccsid[] = "@(#)conf.c 8.243 (Berkeley) 11/20/95";
#endif /* not lint */
# include "sendmail.h"
# include "pathnames.h"
# include <sys/ioctl.h>
# include <sys/param.h>
-# include <netdb.h>
-# include <pwd.h>
/*
** CONF.C -- Sendmail Configuration Tables.
@@ -80,44 +78,47 @@ static char sccsid[] = "@(#)conf.c 8.89.1.3 (Berkeley) 3/7/95";
struct hdrinfo HdrInfo[] =
{
/* originator fields, most to least significant */
- "resent-sender", H_FROM|H_RESENT,
- "resent-from", H_FROM|H_RESENT,
- "resent-reply-to", H_FROM|H_RESENT,
- "sender", H_FROM,
- "from", H_FROM,
- "reply-to", H_FROM,
- "full-name", H_ACHECK,
- "return-receipt-to", H_FROM|H_RECEIPTTO,
- "errors-to", H_FROM|H_ERRORSTO,
+ "resent-sender", H_FROM|H_RESENT,
+ "resent-from", H_FROM|H_RESENT,
+ "resent-reply-to", H_FROM|H_RESENT,
+ "sender", H_FROM,
+ "from", H_FROM,
+ "reply-to", H_FROM,
+ "full-name", H_ACHECK,
+ "return-receipt-to", H_FROM|H_RECEIPTTO,
+ "errors-to", H_FROM|H_ERRORSTO,
/* destination fields */
- "to", H_RCPT,
- "resent-to", H_RCPT|H_RESENT,
- "cc", H_RCPT,
- "resent-cc", H_RCPT|H_RESENT,
- "bcc", H_RCPT|H_ACHECK,
- "resent-bcc", H_RCPT|H_ACHECK|H_RESENT,
- "apparently-to", H_RCPT,
+ "to", H_RCPT,
+ "resent-to", H_RCPT|H_RESENT,
+ "cc", H_RCPT,
+ "resent-cc", H_RCPT|H_RESENT,
+ "bcc", H_RCPT|H_BCC,
+ "resent-bcc", H_RCPT|H_BCC|H_RESENT,
+ "apparently-to", H_RCPT,
/* message identification and control */
- "message-id", 0,
- "resent-message-id", H_RESENT,
- "message", H_EOH,
- "text", H_EOH,
+ "message-id", 0,
+ "resent-message-id", H_RESENT,
+ "message", H_EOH,
+ "text", H_EOH,
/* date fields */
- "date", 0,
- "resent-date", H_RESENT,
+ "date", 0,
+ "resent-date", H_RESENT,
/* trace fields */
- "received", H_TRACE|H_FORCE,
- "x400-received", H_TRACE|H_FORCE,
- "via", H_TRACE|H_FORCE,
- "mail-from", H_TRACE|H_FORCE,
+ "received", H_TRACE|H_FORCE,
+ "x400-received", H_TRACE|H_FORCE,
+ "via", H_TRACE|H_FORCE,
+ "mail-from", H_TRACE|H_FORCE,
/* miscellaneous fields */
- "comments", H_FORCE,
- "return-path", H_FORCE|H_ACHECK,
+ "comments", H_FORCE,
+ "return-path", H_FORCE|H_ACHECK,
+ "content-transfer-encoding", H_CTE,
+ "content-type", H_CTYPE,
+ "content-length", H_ACHECK,
NULL, 0,
};
@@ -159,25 +160,6 @@ struct prival PrivacyValues[] =
*/
int DtableSize = 50; /* max open files; reset in 4.2bsd */
-
-
-/*
-** Following should be config parameters (and probably will be in
-** future releases). In the meantime, setting these is considered
-** unsupported, and is intentionally undocumented.
-*/
-
-#ifdef BROKENSMTPPEERS
-bool BrokenSmtpPeers = TRUE; /* set if you have broken SMTP peers */
-#else
-bool BrokenSmtpPeers = FALSE; /* set if you have broken SMTP peers */
-#endif
-#ifdef NOLOOPBACKCHECK
-bool CheckLoopBack = FALSE; /* set to check HELO loopback */
-#else
-bool CheckLoopBack = TRUE; /* set to check HELO loopback */
-#endif
-
/*
** SETDEFAULTS -- set default values
**
@@ -195,11 +177,24 @@ bool CheckLoopBack = TRUE; /* set to check HELO loopback */
** default values.
*/
-#define DAYS * 24 * 60 * 60
+#define MINUTES * 60
+#define HOURS * 60 MINUTES
+#define DAYS * 24 HOURS
+
+#ifndef MAXRULERECURSION
+# define MAXRULERECURSION 50 /* max ruleset recursion depth */
+#endif
+void
setdefaults(e)
register ENVELOPE *e;
{
+ int i;
+ extern void inittimeouts();
+ extern void setdefuser();
+ extern void setupmaps();
+ extern void setupmailers();
+
SpaceSub = ' '; /* option B */
QueueLA = 8; /* option x */
RefuseLA = 12; /* option X */
@@ -215,14 +210,29 @@ setdefaults(e)
MaxHopCount = 25; /* option h */
e->e_sendmode = SM_FORK; /* option d */
e->e_errormode = EM_PRINT; /* option e */
- SevenBit = FALSE; /* option 7 */
+ SevenBitInput = FALSE; /* option 7 */
MaxMciCache = 1; /* option k */
- MciCacheTimeout = 300; /* option K */
+ MciCacheTimeout = 5 MINUTES; /* option K */
LogLevel = 9; /* option L */
- settimeouts(NULL); /* option r */
- TimeOuts.to_q_return = 5 DAYS; /* option T */
- TimeOuts.to_q_warning = 0; /* option T */
+ inittimeouts(NULL); /* option r */
PrivacyFlags = 0; /* option p */
+#if MIME8TO7
+ MimeMode = MM_CVTMIME|MM_PASS8BIT; /* option 8 */
+#else
+ MimeMode = MM_PASS8BIT;
+#endif
+ for (i = 0; i < MAXTOCLASS; i++)
+ {
+ TimeOuts.to_q_return[i] = 5 DAYS; /* option T */
+ TimeOuts.to_q_warning[i] = 0; /* option T */
+ }
+ ServiceSwitchFile = "/etc/service.switch";
+ HostsFile = _PATH_HOSTS;
+ MustQuoteChars = "@,;:\\()[].'";
+ MciInfoTimeout = 30 MINUTES;
+ MaxRuleRecursion = MAXRULERECURSION;
+ MaxAliasRecursion = 10;
+ ColonOkInAddr = TRUE;
setdefuser();
setupmaps();
setupmailers();
@@ -233,13 +243,14 @@ setdefaults(e)
** SETDEFUSER -- set/reset DefUser using DefUid (for initgroups())
*/
+void
setdefuser()
{
struct passwd *defpwent;
static char defuserbuf[40];
DefUser = defuserbuf;
- if ((defpwent = getpwuid(DefUid)) != NULL)
+ if ((defpwent = sm_getpwuid(DefUid)) != NULL)
strcpy(defuserbuf, defpwent->pw_name);
else
strcpy(defuserbuf, "nobody");
@@ -248,6 +259,8 @@ setdefuser()
** HOST_MAP_INIT -- initialize host class structures
*/
+bool host_map_init __P((MAP *map, char *args));
+
bool
host_map_init(MAP *map, char *args)
{
@@ -278,14 +291,16 @@ host_map_init(MAP *map, char *args)
** SETUPMAILERS -- initialize default mailers
*/
+void
setupmailers()
{
char buf[100];
+ extern void makemailer();
- strcpy(buf, "prog, P=/bin/sh, F=lsD, A=sh -c $u");
+ strcpy(buf, "prog, P=/bin/sh, F=lsoD, T=DNS/RFC822/X-Unix, A=sh -c \201u");
makemailer(buf);
- strcpy(buf, "*file*, P=/dev/null, F=lsDFMPEu, A=FILE");
+ strcpy(buf, "*file*, P=[FILE], F=lsDFMPEou, T=DNS/RFC822/X-Unix, A=FILE");
makemailer(buf);
strcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE");
@@ -313,6 +328,7 @@ setupmailers()
s->s_mapclass.map_store = store; \
}
+void
setupmaps()
{
register STAB *s;
@@ -321,6 +337,7 @@ setupmaps()
MAPDEF("hash", ".db", MCF_ALIASOK|MCF_REBUILDABLE,
map_parseargs, hash_map_open, db_map_close,
db_map_lookup, db_map_store);
+
MAPDEF("btree", ".db", MCF_ALIASOK|MCF_REBUILDABLE,
map_parseargs, bt_map_open, db_map_close,
db_map_lookup, db_map_store);
@@ -334,40 +351,490 @@ setupmaps()
#ifdef NIS
MAPDEF("nis", NULL, MCF_ALIASOK,
- map_parseargs, nis_map_open, nis_map_close,
- nis_map_lookup, nis_map_store);
+ map_parseargs, nis_map_open, null_map_close,
+ nis_map_lookup, null_map_store);
#endif
+#ifdef NISPLUS
+ MAPDEF("nisplus", NULL, MCF_ALIASOK,
+ map_parseargs, nisplus_map_open, null_map_close,
+ nisplus_map_lookup, null_map_store);
+#endif
+
+#ifdef HESIOD
+ MAPDEF("hesiod", NULL, MCF_ALIASOK|MCF_ALIASONLY,
+ map_parseargs, hes_map_open, null_map_close,
+ hes_map_lookup, null_map_store);
+#endif
+
+#if NETINFO
+ MAPDEF("netinfo", NULL, MCF_ALIASOK,
+ map_parseargs, ni_map_open, null_map_close,
+ ni_map_lookup, null_map_store);
+#endif
+
+#if 0
+ MAPDEF("dns", NULL, 0,
+ dns_map_init, null_map_open, null_map_close,
+ dns_map_lookup, null_map_store);
+#endif
+
+#if NAMED_BIND
+ /* best MX DNS lookup */
+ MAPDEF("bestmx", NULL, MCF_OPTFILE,
+ map_parseargs, null_map_open, null_map_close,
+ bestmx_map_lookup, null_map_store);
+#endif
+
+ MAPDEF("host", NULL, 0,
+ host_map_init, null_map_open, null_map_close,
+ host_map_lookup, null_map_store);
+
+ MAPDEF("text", NULL, MCF_ALIASOK,
+ map_parseargs, text_map_open, null_map_close,
+ text_map_lookup, null_map_store);
+
MAPDEF("stab", NULL, MCF_ALIASOK|MCF_ALIASONLY,
- map_parseargs, stab_map_open, stab_map_close,
+ map_parseargs, stab_map_open, null_map_close,
stab_map_lookup, stab_map_store);
MAPDEF("implicit", NULL, MCF_ALIASOK|MCF_ALIASONLY|MCF_REBUILDABLE,
map_parseargs, impl_map_open, impl_map_close,
impl_map_lookup, impl_map_store);
- /* host DNS lookup */
- MAPDEF("host", NULL, 0,
- host_map_init, null_map_open, null_map_close,
- host_map_lookup, null_map_store);
+ /* access to system passwd file */
+ MAPDEF("user", NULL, MCF_OPTFILE,
+ map_parseargs, user_map_open, null_map_close,
+ user_map_lookup, null_map_store);
/* dequote map */
MAPDEF("dequote", NULL, 0,
dequote_init, null_map_open, null_map_close,
dequote_map, null_map_store);
-#if 0
-# ifdef USERDB
+#if USERDB
/* user database */
- MAPDEF("udb", ".db", 0,
- udb_map_parse, null_map_open, null_map_close,
+ MAPDEF("userdb", ".db", 0,
+ map_parseargs, null_map_open, null_map_close,
udb_map_lookup, null_map_store);
-# endif
#endif
+
+ /* arbitrary programs */
+ MAPDEF("program", NULL, MCF_ALIASOK,
+ map_parseargs, null_map_open, null_map_close,
+ prog_map_lookup, null_map_store);
+
+ /* sequenced maps */
+ MAPDEF("sequence", NULL, MCF_ALIASOK,
+ seq_map_parse, null_map_open, null_map_close,
+ seq_map_lookup, seq_map_store);
+
+ /* switched interface to sequenced maps */
+ MAPDEF("switch", NULL, MCF_ALIASOK,
+ map_parseargs, switch_map_open, null_map_close,
+ seq_map_lookup, seq_map_store);
+
+ /* null map lookup -- really for internal use only */
+ MAPDEF("null", NULL, MCF_ALIASOK|MCF_OPTFILE,
+ map_parseargs, null_map_open, null_map_close,
+ null_map_lookup, null_map_store);
}
#undef MAPDEF
/*
+** INITHOSTMAPS -- initial host-dependent maps
+**
+** This should act as an interface to any local service switch
+** provided by the host operating system.
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+**
+** Side Effects:
+** Should define maps "host" and "users" as necessary
+** for this OS. If they are not defined, they will get
+** a default value later. It should check to make sure
+** they are not defined first, since it's possible that
+** the config file has provided an override.
+*/
+
+void
+inithostmaps()
+{
+ register int i;
+ int nmaps;
+ char *maptype[MAXMAPSTACK];
+ short mapreturn[MAXMAPACTIONS];
+ char buf[MAXLINE];
+
+ /*
+ ** Set up default hosts maps.
+ */
+
+#if 0
+ nmaps = switch_map_find("hosts", maptype, mapreturn);
+ for (i = 0; i < nmaps; i++)
+ {
+ if (strcmp(maptype[i], "files") == 0 &&
+ stab("hosts.files", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "hosts.files text -k 0 -v 1 /etc/hosts");
+ (void) makemapentry(buf);
+ }
+#if NAMED_BIND
+ else if (strcmp(maptype[i], "dns") == 0 &&
+ stab("hosts.dns", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "hosts.dns dns A");
+ (void) makemapentry(buf);
+ }
+#endif
+#ifdef NISPLUS
+ else if (strcmp(maptype[i], "nisplus") == 0 &&
+ stab("hosts.nisplus", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "hosts.nisplus nisplus -k name -v address -d hosts.org_dir");
+ (void) makemapentry(buf);
+ }
+#endif
+#ifdef NIS
+ else if (strcmp(maptype[i], "nis") == 0 &&
+ stab("hosts.nis", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "hosts.nis nis -d -k 0 -v 1 hosts.byname");
+ (void) makemapentry(buf);
+ }
+#endif
+#if NETINFO
+ else if (strcmp(maptype[i], "netinfo") == 0) &&
+ stab("hosts.netinfo", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "hosts.netinfo netinfo -v name /machines");
+ (void) makemapentry(buf);
+ }
+#endif
+ }
+#endif
+
+ /*
+ ** Make sure we have a host map.
+ */
+
+ if (stab("host", ST_MAP, ST_FIND) == NULL)
+ {
+ /* user didn't initialize: set up host map */
+ strcpy(buf, "host host");
+#if NAMED_BIND
+ if (ConfigLevel >= 2)
+ strcat(buf, " -a.");
+#endif
+ (void) makemapentry(buf);
+ }
+
+ /*
+ ** Set up default aliases maps
+ */
+
+ nmaps = switch_map_find("aliases", maptype, mapreturn);
+ for (i = 0; i < nmaps; i++)
+ {
+ if (strcmp(maptype[i], "files") == 0 &&
+ stab("aliases.files", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "aliases.files null");
+ (void) makemapentry(buf);
+ }
+#ifdef NISPLUS
+ else if (strcmp(maptype[i], "nisplus") == 0 &&
+ stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion -d mail_aliases.org_dir");
+ (void) makemapentry(buf);
+ }
+#endif
+#ifdef NIS
+ else if (strcmp(maptype[i], "nis") == 0 &&
+ stab("aliases.nis", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "aliases.nis nis -d mail.aliases");
+ (void) makemapentry(buf);
+ }
+#endif
+#ifdef NETINFO
+ else if (strcmp(maptype[i], "netinfo") == 0 &&
+ stab("aliases.netinfo", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "aliases.netinfo netinfo /aliases");
+ (void) makemapentry(buf);
+ }
+#endif
+#ifdef HESIOD
+ else if (strcmp(maptype[i], "hesiod") == 0 &&
+ stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "aliases.hesiod hesiod aliases");
+ (void) makemapentry(buf);
+ }
+#endif
+ }
+ if (stab("aliases", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "aliases switch aliases");
+ (void) makemapentry(buf);
+ }
+
+#if 0 /* "user" map class is a better choice */
+ /*
+ ** Set up default users maps.
+ */
+
+ nmaps = switch_map_find("passwd", maptype, mapreturn);
+ for (i = 0; i < nmaps; i++)
+ {
+ if (strcmp(maptype[i], "files") == 0 &&
+ stab("users.files", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "users.files text -m -z: -k0 -v6 /etc/passwd");
+ (void) makemapentry(buf);
+ }
+#ifdef NISPLUS
+ else if (strcmp(maptype[i], "nisplus") == 0 &&
+ stab("users.nisplus", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "users.nisplus nisplus -m -kname -vhome -d passwd.org_dir");
+ (void) makemapentry(buf);
+ }
+#endif
+#ifdef NIS
+ else if (strcmp(maptype[i], "nis") == 0 &&
+ stab("users.nis", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "users.nis nis -m -d passwd.byname");
+ (void) makemapentry(buf);
+ }
+#endif
+#ifdef HESIOD
+ else if (strcmp(maptype[i], "hesiod") == 0) &&
+ stab("users.hesiod", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "users.hesiod hesiod");
+ (void) makemapentry(buf);
+ }
+#endif
+ }
+ if (stab("users", ST_MAP, ST_FIND) == NULL)
+ {
+ strcpy(buf, "users switch -m passwd");
+ (void) makemapentry(buf);
+ }
+#endif
+}
+ /*
+** SWITCH_MAP_FIND -- find the list of types associated with a map
+**
+** This is the system-dependent interface to the service switch.
+**
+** Parameters:
+** service -- the name of the service of interest.
+** maptype -- an out-array of strings containing the types
+** of access to use for this service. There can
+** be at most MAXMAPSTACK types for a single service.
+** mapreturn -- an out-array of return information bitmaps
+** for the map.
+**
+** Returns:
+** The number of map types filled in, or -1 for failure.
+*/
+
+#if defined(SOLARIS) || (defined(sony_news) && defined(__svr4))
+# define _USE_SUN_NSSWITCH_
+#endif
+
+#ifdef _USE_SUN_NSSWITCH_
+# include <nsswitch.h>
+#endif
+
+#if defined(ultrix) || (defined(__osf__) && defined(__alpha))
+# define _USE_DEC_SVC_CONF_
+#endif
+
+#ifdef _USE_DEC_SVC_CONF_
+# include <sys/svcinfo.h>
+#endif
+
+int
+switch_map_find(service, maptype, mapreturn)
+ char *service;
+ char *maptype[MAXMAPSTACK];
+ short mapreturn[MAXMAPACTIONS];
+{
+ register FILE *fp;
+ int svcno;
+ static char buf[MAXLINE];
+
+#ifdef _USE_SUN_NSSWITCH_
+ struct __nsw_switchconfig *nsw_conf;
+ enum __nsw_parse_err pserr;
+ struct __nsw_lookup *lk;
+ int nsw_rc;
+ static struct __nsw_lookup lkp0 =
+ { "files", {1, 0, 0, 0}, NULL, NULL };
+ static struct __nsw_switchconfig lkp_default =
+ { 0, "sendmail", 3, &lkp0 };
+
+ for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
+ mapreturn[svcno] = 0;
+
+ if ((nsw_conf = __nsw_getconfig(service, &pserr)) == NULL)
+ lk = lkp_default.lookups;
+ else
+ lk = nsw_conf->lookups;
+ svcno = 0;
+ while (lk != NULL)
+ {
+ maptype[svcno] = lk->service_name;
+ if (lk->actions[__NSW_NOTFOUND] == __NSW_RETURN)
+ mapreturn[MA_NOTFOUND] |= 1 << svcno;
+ if (lk->actions[__NSW_TRYAGAIN] == __NSW_RETURN)
+ mapreturn[MA_TRYAGAIN] |= 1 << svcno;
+ if (lk->actions[__NSW_UNAVAIL] == __NSW_RETURN)
+ mapreturn[MA_TRYAGAIN] |= 1 << svcno;
+ svcno++;
+ lk = lk->next;
+ }
+ return svcno;
+#endif
+
+#ifdef _USE_DEC_SVC_CONF_
+ struct svcinfo *svcinfo;
+ int svc;
+
+ for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
+ mapreturn[svcno] = 0;
+
+ svcinfo = getsvc();
+ if (svcinfo == NULL)
+ goto punt;
+ if (strcmp(service, "hosts") == 0)
+ svc = SVC_HOSTS;
+ else if (strcmp(service, "aliases") == 0)
+ svc = SVC_ALIASES;
+ else if (strcmp(service, "passwd") == 0)
+ svc = SVC_PASSWD;
+ else
+ return -1;
+ for (svcno = 0; svcno < SVC_PATHSIZE; svcno++)
+ {
+ switch (svcinfo->svcpath[svc][svcno])
+ {
+ case SVC_LOCAL:
+ maptype[svcno] = "files";
+ break;
+
+ case SVC_YP:
+ maptype[svcno] = "nis";
+ break;
+
+ case SVC_BIND:
+ maptype[svcno] = "dns";
+ break;
+
+#ifdef SVC_HESIOD
+ case SVC_HESIOD:
+ maptype[svcno] = "hesiod";
+ break;
+#endif
+
+ case SVC_LAST:
+ return svcno;
+ }
+ }
+ return svcno;
+#endif
+
+#if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_)
+ /*
+ ** Fall-back mechanism.
+ */
+
+ for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
+ mapreturn[svcno] = 0;
+
+ svcno = 0;
+ fp = fopen(ServiceSwitchFile, "r");
+ if (fp != NULL)
+ {
+ while (fgets(buf, sizeof buf, fp) != NULL)
+ {
+ register char *p;
+
+ p = strpbrk(buf, "#\n");
+ if (p != NULL)
+ *p = '\0';
+ p = strpbrk(buf, " \t");
+ if (p != NULL)
+ *p++ = '\0';
+ if (strcmp(buf, service) != 0)
+ continue;
+
+ /* got the right service -- extract data */
+ do
+ {
+ while (isspace(*p))
+ p++;
+ if (*p == '\0')
+ break;
+ maptype[svcno++] = p;
+ p = strpbrk(p, " \t");
+ if (p != NULL)
+ *p++ = '\0';
+ } while (p != NULL);
+ fclose(fp);
+ return svcno;
+ }
+
+ /* service was not found -- use compiled in default */
+ fclose(fp);
+ }
+#endif
+
+ /* if the service file doesn't work, use an absolute fallback */
+ punt:
+ for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
+ mapreturn[svcno] = 0;
+ svcno = 0;
+ if (strcmp(service, "aliases") == 0)
+ {
+ maptype[svcno++] = "files";
+#ifdef AUTO_NIS_ALIASES
+# ifdef NISPLUS
+ maptype[svcno++] = "nisplus";
+# endif
+# ifdef NIS
+ maptype[svcno++] = "nis";
+# endif
+#endif
+ return svcno;
+ }
+ if (strcmp(service, "hosts") == 0)
+ {
+# if NAMED_BIND
+ maptype[svcno++] = "dns";
+# else
+# if defined(sun) && !defined(BSD) && !defined(_USE_SUN_NSSWITCH_)
+ /* SunOS */
+ maptype[svcno++] = "nis";
+# endif
+# endif
+ maptype[svcno++] = "files";
+ return svcno;
+ }
+ return -1;
+}
+ /*
** USERNAME -- return the user id of the logged in user.
**
** Parameters:
@@ -396,7 +863,7 @@ username()
myname = getlogin();
if (myname == NULL || myname[0] == '\0')
{
- pw = getpwuid(RealUid);
+ pw = sm_getpwuid(RealUid);
if (pw != NULL)
myname = newstr(pw->pw_name);
}
@@ -405,10 +872,10 @@ username()
uid_t uid = RealUid;
myname = newstr(myname);
- if ((pw = getpwnam(myname)) == NULL ||
+ if ((pw = sm_getpwnam(myname)) == NULL ||
(uid != 0 && uid != pw->pw_uid))
{
- pw = getpwuid(uid);
+ pw = sm_getpwuid(uid);
if (pw != NULL)
myname = newstr(pw->pw_name);
}
@@ -485,11 +952,14 @@ ttypath()
** forwarding or registration of users.
**
** If the hosts are found to be incompatible, an error
-** message should be given using "usrerr" and 0 should
-** be returned.
+** message should be given using "usrerr" and an EX_ code
+** should be returned. You can also set to->q_status to
+** a DSN-style status code.
**
-** 'NoReturn' can be set to suppress the return-to-sender
-** function; this should be done on huge messages.
+** EF_NO_BODY_RETN can be set in e->e_flags to suppress the
+** body during the return-to-sender function; this should be done
+** on huge messages. This bit may already be set by the ESMTP
+** protocol.
**
** Parameters:
** to -- the person being sent to.
@@ -501,6 +971,7 @@ ttypath()
** none (unless you include the usrerr stuff)
*/
+int
checkcompat(to, e)
register ADDRESS *to;
register ENVELOPE *e;
@@ -519,11 +990,12 @@ checkcompat(to, e)
register STAB *s;
s = stab("arpa", ST_MAILER, ST_FIND);
- if (s != NULL && e->e_from.q_mailer != LocalMailer &&
+ if (s != NULL && strcmp(e->e_from.q_mailer->m_name, "local") != 0 &&
to->q_mailer == s->s_mailer)
{
usrerr("553 No ARPA mail through this machine: see your system administration");
- /* NoReturn = TRUE; to supress return copy */
+ /* e->e_flags |= EF_NO_BODY_RETN; to supress body on return */
+ to->q_status = "5.7.1";
return (EX_UNAVAILABLE);
}
# endif /* EXAMPLE_CODE */
@@ -540,19 +1012,47 @@ setsignal(sig, handler)
int sig;
sigfunc_t handler;
{
-#if defined(SYS5SIGNALS) || defined(BSD4_3) || defined(_AUX_SOURCE)
+#if defined(SYS5SIGNALS) || defined(BSD4_3)
return signal(sig, handler);
#else
struct sigaction n, o;
bzero(&n, sizeof n);
n.sa_handler = handler;
+# ifdef SA_RESTART
+ n.sa_flags = SA_RESTART;
+# endif
if (sigaction(sig, &n, &o) < 0)
return SIG_ERR;
return o.sa_handler;
#endif
}
/*
+** RELEASESIGNAL -- release a held signal
+**
+** Parameters:
+** sig -- the signal to release.
+**
+** Returns:
+** 0 on success.
+** -1 on failure.
+*/
+
+int
+releasesignal(sig)
+ int sig;
+{
+#ifdef BSD4_3
+ return sigsetmask(sigblock(0) & ~(1 << sig));
+#else
+ sigset_t sset;
+
+ sigemptyset(&sset);
+ sigaddset(&sset, sig);
+ return sigprocmask(SIG_UNBLOCK, &sset, NULL);
+#endif
+}
+ /*
** HOLDSIGS -- arrange to hold all signals
**
** Parameters:
@@ -565,6 +1065,7 @@ setsignal(sig, handler)
** Arranges that signals are held.
*/
+void
holdsigs()
{
}
@@ -583,6 +1084,7 @@ holdsigs()
** Arranges that signals are released.
*/
+void
rlsesigs()
{
}
@@ -597,6 +1099,7 @@ rlsesigs()
# include <compat.h>
#endif
+void
init_md(argc, argv)
int argc;
char **argv;
@@ -604,6 +1107,32 @@ init_md(argc, argv)
#ifdef _AUX_SOURCE
setcompat(getcompat() | COMPAT_BSDPROT);
#endif
+
+#ifdef VENDOR_DEFAULT
+ VendorCode = VENDOR_DEFAULT;
+#else
+ VendorCode = VENDOR_BERKELEY;
+#endif
+}
+ /*
+** INIT_VENDOR_MACROS -- vendor-dependent macro initializations
+**
+** Called once, on startup.
+**
+** Parameters:
+** e -- the global envelope.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** vendor-dependent.
+*/
+
+void
+init_vendor_macros(e)
+ register ENVELOPE *e;
+{
}
/*
** GETLA -- get the current load average
@@ -628,15 +1157,36 @@ init_md(argc, argv)
#define LA_MACH 5 /* MACH load averages (as on NeXT boxes) */
#define LA_SHORT 6 /* read kmem for avenrun; interpret as short */
#define LA_PROCSTR 7 /* read string ("1.17") from /proc/loadavg */
+#define LA_READKSYM 8 /* SVR4: use MIOC_READKSYM ioctl call */
+#define LA_DGUX 9 /* special DGUX implementation */
+#define LA_HPUX 10 /* special HPUX implementation */
/* do guesses based on general OS type */
#ifndef LA_TYPE
# define LA_TYPE LA_ZERO
#endif
-#if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT)
+#ifndef FSHIFT
+# if defined(unixpc)
+# define FSHIFT 5
+# endif
-#include <nlist.h>
+# if defined(__alpha) || defined(IRIX)
+# define FSHIFT 10
+# endif
+
+# if defined(_AIX3)
+# define FSHIFT 16
+# endif
+#endif
+
+#ifndef FSHIFT
+# define FSHIFT 8
+#endif
+
+#ifndef FSCALE
+# define FSCALE (1 << FSHIFT)
+#endif
#ifndef LA_AVENRUN
# ifdef SYSTEM5
@@ -646,39 +1196,38 @@ init_md(argc, argv)
# endif
#endif
+/* _PATH_KMEM should be defined in <paths.h> */
+#ifndef _PATH_KMEM
+# define _PATH_KMEM "/dev/kmem"
+#endif
+
+#if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT)
+
+#include <nlist.h>
+
+#ifdef IRIX64
+# define nlist nlist64
+#endif
+
/* _PATH_UNIX should be defined in <paths.h> */
#ifndef _PATH_UNIX
# if defined(SYSTEM5)
# define _PATH_UNIX "/unix"
# else
-# define _PATH_UNIX "/kernel"
+# define _PATH_UNIX "/vmunix"
# endif
#endif
-struct nlist Nl[] =
+#ifdef _AUX_SOURCE
+struct nlist Nl[2];
+#else
+struct nlist Nl[] =
{
{ LA_AVENRUN },
-#define X_AVENRUN 0
{ 0 },
};
-
-#ifndef FSHIFT
-# if defined(unixpc)
-# define FSHIFT 5
-# endif
-
-# if defined(__alpha) || defined(IRIX)
-# define FSHIFT 10
-# endif
-#endif
-
-#ifndef FSHIFT
-# define FSHIFT 8
-#endif
-
-#ifndef FSCALE
-# define FSCALE (1 << FSHIFT)
#endif
+#define X_AVENRUN 0
getla()
{
@@ -692,12 +1241,12 @@ getla()
double avenrun[3];
# endif
#endif
- extern off_t lseek();
extern int errno;
+ extern off_t lseek();
if (kmem < 0)
{
- kmem = open("/dev/kmem", 0, 0);
+ kmem = open(_PATH_KMEM, 0, 0);
if (kmem < 0)
{
if (tTd(3, 1))
@@ -706,7 +1255,17 @@ getla()
return (-1);
}
(void) fcntl(kmem, F_SETFD, 1);
+
+#ifdef _AUX_SOURCE
+ strcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN);
+ Nl[1].n_name[0] = '\0';
+#endif
+
+#ifdef _AIX3
+ if (knlist(Nl, 1, sizeof Nl[0]) < 0)
+#else
if (nlist(_PATH_UNIX, Nl) < 0)
+#endif
{
if (tTd(3, 1))
printf("getla: nlist(%s): %s\n", _PATH_UNIX,
@@ -720,13 +1279,13 @@ getla()
_PATH_UNIX, LA_AVENRUN);
return (-1);
}
-#ifdef IRIX
- Nl[X_AVENRUN].n_value &= 0x7fffffff;
+#ifdef NAMELISTMASK
+ Nl[X_AVENRUN].n_value &= NAMELISTMASK;
#endif
}
if (tTd(3, 20))
printf("getla: symbol address = %#x\n", Nl[X_AVENRUN].n_value);
- if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 ||
+ if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, SEEK_SET) == -1 ||
read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
{
/* thank you Ian */
@@ -734,7 +1293,7 @@ getla()
printf("getla: lseek or read: %s\n", errstring(errno));
return (-1);
}
-#if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT)
+# if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT)
if (tTd(3, 5))
{
printf("getla: avenrun = %d", avenrun[0]);
@@ -745,7 +1304,7 @@ getla()
if (tTd(3, 1))
printf("getla: %d\n", (int) (avenrun[0] + FSCALE/2) >> FSHIFT);
return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
-#else
+# else /* LA_TYPE == LA_FLOAT */
if (tTd(3, 5))
{
printf("getla: avenrun = %g", avenrun[0]);
@@ -756,28 +1315,113 @@ getla()
if (tTd(3, 1))
printf("getla: %d\n", (int) (avenrun[0] +0.5));
return ((int) (avenrun[0] + 0.5));
-#endif
+# endif
}
-#else
-#if LA_TYPE == LA_SUBR
+#endif /* LA_TYPE == LA_INT or LA_SHORT or LA_FLOAT */
+
+#if LA_TYPE == LA_READKSYM
+
+# include <sys/ksym.h>
+
+getla()
+{
+ static int kmem = -1;
+ long avenrun[3];
+ extern int errno;
+ struct mioc_rksym mirk;
+
+ if (kmem < 0)
+ {
+ kmem = open("/dev/kmem", 0, 0);
+ if (kmem < 0)
+ {
+ if (tTd(3, 1))
+ printf("getla: open(/dev/kmem): %s\n",
+ errstring(errno));
+ return (-1);
+ }
+ (void) fcntl(kmem, F_SETFD, 1);
+ }
+ mirk.mirk_symname = LA_AVENRUN;
+ mirk.mirk_buf = avenrun;
+ mirk.mirk_buflen = sizeof(avenrun);
+ if (ioctl(kmem, MIOC_READKSYM, &mirk) < 0)
+ {
+ if (tTd(3, 1))
+ printf("getla: ioctl(MIOC_READKSYM) failed: %s\n",
+ errstring(errno));
+ return -1;
+ }
+ if (tTd(3, 5))
+ {
+ printf("getla: avenrun = %d", avenrun[0]);
+ if (tTd(3, 15))
+ printf(", %d, %d", avenrun[1], avenrun[2]);
+ printf("\n");
+ }
+ if (tTd(3, 1))
+ printf("getla: %d\n", (int) (avenrun[0] + FSCALE/2) >> FSHIFT);
+ return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
+}
-#ifdef DGUX
+#endif /* LA_TYPE == LA_READKSYM */
-#include <sys/dg_sys_info.h>
+#if LA_TYPE == LA_DGUX
-int getla()
+# include <sys/dg_sys_info.h>
+
+int
+getla()
{
struct dg_sys_info_load_info load_info;
dg_sys_info((long *)&load_info,
DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0);
+ if (tTd(3, 1))
+ printf("getla: %d\n", (int) (load_info.one_minute + 0.5));
+
return((int) (load_info.one_minute + 0.5));
}
-#else
+#endif /* LA_TYPE == LA_DGUX */
+
+#if LA_TYPE == LA_HPUX
+
+/* forward declarations to keep gcc from complaining */
+struct pst_dynamic;
+struct pst_status;
+struct pst_static;
+struct pst_vminfo;
+struct pst_diskinfo;
+struct pst_processor;
+struct pst_lv;
+struct pst_swapinfo;
+
+# include <sys/param.h>
+# include <sys/pstat.h>
+
+int
+getla()
+{
+ struct pst_dynamic pstd;
+
+ if (pstat_getdynamic(&pstd, sizeof(struct pst_dynamic),
+ (size_t) 1, 0) == -1)
+ return 0;
+
+ if (tTd(3, 1))
+ printf("getla: %d\n", (int) (pstd.psd_avg_1_min + 0.5));
+
+ return (int) (pstd.psd_avg_1_min + 0.5);
+}
+
+#endif /* LA_TYPE == LA_HPUX */
+#if LA_TYPE == LA_SUBR
+
+int
getla()
{
double avenrun[3];
@@ -793,8 +1437,8 @@ getla()
return ((int) (avenrun[0] + 0.5));
}
-#endif /* DGUX */
-#else
+#endif /* LA_TYPE == LA_SUBR */
+
#if LA_TYPE == LA_MACH
/*
@@ -828,8 +1472,8 @@ getla()
return (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE;
}
+#endif /* LA_TYPE == LA_MACH */
-#else
#if LA_TYPE == LA_PROCSTR
/*
@@ -875,7 +1519,9 @@ getla()
return ((int) (avenrun + 0.5));
}
-#else
+#endif /* LA_TYPE == LA_PROCSTR */
+
+#if LA_TYPE == LA_ZERO
getla()
{
@@ -884,10 +1530,7 @@ getla()
return (0);
}
-#endif
-#endif
-#endif
-#endif
+#endif /* LA_TYPE == LA_ZERO */
/*
@@ -915,7 +1558,7 @@ getla()
/* Non Apollo stuff removed by Don Lewis 11/15/93 */
#ifndef lint
-static char rcsid[] = "@(#)$Id: conf.c,v 1.6 1995/03/10 05:08:13 pst Exp $";
+static char rcsid[] = "@(#)$Id: conf.c,v 1.7 1995/05/30 03:52:08 rgrimes Exp $";
#endif /* !lint */
#ifdef apollo
@@ -958,11 +1601,28 @@ shouldqueue(pri, ctime)
long pri;
time_t ctime;
{
+ bool rval;
+
+ if (tTd(3, 30))
+ printf("shouldqueue: CurrentLA=%d, pri=%d: ", CurrentLA, pri);
if (CurrentLA < QueueLA)
+ {
+ if (tTd(3, 30))
+ printf("FALSE (CurrentLA < QueueLA)\n");
return (FALSE);
- if (CurrentLA >= RefuseLA)
+ }
+#if 0 /* this code is reported to cause oscillation around RefuseLA */
+ if (CurrentLA >= RefuseLA && QueueLA < RefuseLA)
+ {
+ if (tTd(3, 30))
+ printf("TRUE (CurrentLA >= RefuseLA)\n");
return (TRUE);
- return (pri > (QueueFactor / (CurrentLA - QueueLA + 1)));
+ }
+#endif
+ rval = pri > (QueueFactor / (CurrentLA - QueueLA + 1));
+ if (tTd(3, 30))
+ printf("%s (by calculation)\n", rval ? "TRUE" : "FALSE");
+ return rval;
}
/*
** REFUSECONNECTIONS -- decide if connections should be refused
@@ -976,19 +1636,38 @@ shouldqueue(pri, ctime)
** FALSE if we should accept new work.
**
** Side Effects:
-** none.
+** Sets process title when it is rejecting connections.
*/
bool
refuseconnections()
{
+ extern bool enoughdiskspace();
+ extern void setproctitle __P((const char *, ...));
+
#ifdef XLA
if (!xla_smtp_ok())
return TRUE;
#endif
- /* this is probably too simplistic */
- return (CurrentLA >= RefuseLA);
+ if (CurrentLA >= RefuseLA)
+ {
+ setproctitle("rejecting connections: load average: %d",
+ CurrentLA);
+ }
+ else if (!enoughdiskspace(MinBlocksFree + 1))
+ {
+ setproctitle("rejecting connections: min free: %d",
+ MinBlocksFree);
+ }
+ else if (MaxChildren > 0 && CurChildren >= MaxChildren)
+ {
+ setproctitle("rejecting connections: maximum children: %d",
+ CurChildren);
+ }
+ else
+ return FALSE;
+ return TRUE;
}
/*
** SETPROCTITLE -- set process title for ps
@@ -1005,58 +1684,139 @@ refuseconnections()
** display the title.
*/
-#ifdef SETPROCTITLE
-# ifdef HASSETPROCTITLE
- *** ERROR *** Cannot have both SETPROCTITLE and HASSETPROCTITLE defined
-# endif
-# ifdef __hpux
+#define SPT_NONE 0 /* don't use it at all */
+#define SPT_REUSEARGV 1 /* cover argv with title information */
+#define SPT_BUILTIN 2 /* use libc builtin */
+#define SPT_PSTAT 3 /* use pstat(PSTAT_SETCMD, ...) */
+#define SPT_PSSTRINGS 4 /* use PS_STRINGS->... */
+#define SPT_SYSMIPS 5 /* use sysmips() supported by NEWS-OS 6 */
+#define SPT_SCO 6 /* write kernel u. area */
+
+#ifndef SPT_TYPE
+# define SPT_TYPE SPT_REUSEARGV
+#endif
+
+#if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN
+
+# if SPT_TYPE == SPT_PSTAT
# include <sys/pstat.h>
# endif
-# ifdef BSD4_4
+# if SPT_TYPE == SPT_PSSTRINGS
# include <machine/vmparam.h>
# include <sys/exec.h>
-# ifdef __bsdi__
-# undef PS_STRINGS /* BSDI 1.0 doesn't do PS_STRINGS as we expect */
-# define PROCTITLEPAD '\0'
-# endif
# ifdef __FreeBSD__
# undef PS_STRINGS /* XXX This is broken due to needing<machine/pmap.h> */
# define PROCTITLEPAD '\0'
# endif
-# ifdef PS_STRINGS
-# define SETPROC_STATIC static
+# ifndef PS_STRINGS /* hmmmm.... apparently not available after all */
+# undef SPT_TYPE
+# define SPT_TYPE SPT_REUSEARGV
+# else
+# ifndef NKPDE /* FreeBSD 2.0 */
+# define NKPDE 63
+typedef unsigned int *pt_entry_t;
+# endif
# endif
# endif
-# ifndef SETPROC_STATIC
+
+# if SPT_TYPE == SPT_PSSTRINGS
+# define SETPROC_STATIC static
+# else
# define SETPROC_STATIC
# endif
-#endif
-#ifndef PROCTITLEPAD
-# define PROCTITLEPAD ' '
-#endif
+# if SPT_TYPE == SPT_SYSMIPS
+# include <sys/sysmips.h>
+# include <sys/sysnews.h>
+# endif
+
+# if SPT_TYPE == SPT_SCO
+# include <sys/immu.h>
+# include <sys/dir.h>
+# include <sys/user.h>
+# include <sys/fs/s5param.h>
+# if PSARGSZ > MAXLINE
+# define SPT_BUFSIZE PSARGSZ
+# endif
+# endif
+
+# ifndef SPT_PADCHAR
+# define SPT_PADCHAR ' '
+# endif
+
+# ifndef SPT_BUFSIZE
+# define SPT_BUFSIZE MAXLINE
+# endif
+
+#endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */
+
+/*
+** Pointers for setproctitle.
+** This allows "ps" listings to give more useful information.
+*/
+
+char **Argv = NULL; /* pointer to argument vector */
+char *LastArgv = NULL; /* end of argv */
+
+void
+initsetproctitle(argc, argv, envp)
+ int argc;
+ char **argv;
+ char **envp;
+{
+ register int i;
+ extern char **environ;
+
+ /*
+ ** Move the environment so setproctitle can use the space at
+ ** the top of memory.
+ */
+
+ for (i = 0; envp[i] != NULL; i++)
+ continue;
+ environ = (char **) xalloc(sizeof (char *) * (i + 1));
+ for (i = 0; envp[i] != NULL; i++)
+ environ[i] = newstr(envp[i]);
+ environ[i] = NULL;
+
+ /*
+ ** Save start and extent of argv for setproctitle.
+ */
+
+ Argv = argv;
+ if (i > 0)
+ LastArgv = envp[i - 1] + strlen(envp[i - 1]);
+ else
+ LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);
+}
+
+#if SPT_TYPE != SPT_BUILTIN
-#ifndef HASSETPROCTITLE
/*VARARGS1*/
-#ifdef __STDC__
-setproctitle(char *fmt, ...)
-#else
+void
+# ifdef __STDC__
+setproctitle(const char *fmt, ...)
+# else
setproctitle(fmt, va_alist)
- char *fmt;
+ const char *fmt;
va_dcl
-#endif
+# endif
{
-# ifdef SETPROCTITLE
+# if SPT_TYPE != SPT_NONE
register char *p;
register int i;
- SETPROC_STATIC char buf[MAXLINE];
+ SETPROC_STATIC char buf[SPT_BUFSIZE];
VA_LOCAL_DECL
-# ifdef __hpux
+# if SPT_TYPE == SPT_PSTAT
union pstun pst;
# endif
- extern char **Argv;
- extern char *LastArgv;
+# if SPT_TYPE == SPT_SCO
+ off_t seek_off;
+ static int kmem = -1;
+ static int kmempid = -1;
+ struct user u;
+# endif
p = buf;
@@ -1066,19 +1826,39 @@ setproctitle(fmt, va_alist)
/* print the argument string */
VA_START(fmt);
- (void) vsprintf(p, fmt, ap);
+ (void) vsnprintf(p, sizeof buf - (p - buf), fmt, ap);
VA_END;
i = strlen(buf);
-# ifdef __hpux
+# if SPT_TYPE == SPT_PSTAT
pst.pst_command = buf;
pstat(PSTAT_SETCMD, pst, i, 0, 0);
-# else
-# ifdef PS_STRINGS
+# endif
+# if SPT_TYPE == SPT_PSSTRINGS
PS_STRINGS->ps_nargvstr = 1;
PS_STRINGS->ps_argvstr = buf;
-# else
+# endif
+# if SPT_TYPE == SPT_SYSMIPS
+ sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf);
+# endif
+# if SPT_TYPE == SPT_SCO
+ if (kmem < 0 || kmempid != getpid())
+ {
+ if (kmem >= 0)
+ close(kmem);
+ kmem = open(_PATH_KMEM, O_RDWR, 0);
+ if (kmem < 0)
+ return;
+ (void) fcntl(kmem, F_SETFD, 1);
+ kmempid = getpid();
+ }
+ buf[PSARGSZ - 1] = '\0';
+ seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u;
+ if (lseek(kmem, (char *) seek_off, SEEK_SET) == seek_off)
+ (void) write(kmem, buf, PSARGSZ);
+# endif
+# if SPT_TYPE == SPT_REUSEARGV
if (i > LastArgv - Argv[0] - 2)
{
i = LastArgv - Argv[0] - 2;
@@ -1087,18 +1867,18 @@ setproctitle(fmt, va_alist)
(void) strcpy(Argv[0], buf);
p = &Argv[0][i];
while (p < LastArgv)
- *p++ = PROCTITLEPAD;
-# endif
+ *p++ = SPT_PADCHAR;
+ Argv[1] = NULL;
# endif
-# endif /* SETPROCTITLE */
+# endif /* SPT_TYPE != SPT_NONE */
}
-#endif
+#endif /* SPT_TYPE != SPT_BUILTIN */
/*
** REAPCHILD -- pick up the body of my child, lest it become a zombie
**
** Parameters:
-** none.
+** sig -- the signal that got us here (unused).
**
** Returns:
** none.
@@ -1108,7 +1888,8 @@ setproctitle(fmt, va_alist)
*/
void
-reapchild()
+reapchild(sig)
+ int sig;
{
int olderrno = errno;
# ifdef HASWAITPID
@@ -1127,18 +1908,19 @@ reapchild()
#endif
break;
}
+ CurChildren--;
}
# else
# ifdef WNOHANG
union wait status;
while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0)
- continue;
+ CurChildren--;
# else /* WNOHANG */
auto int status;
while (wait(&status) > 0)
- continue;
+ CurChildren--;
# endif /* WNOHANG */
# endif
# ifdef SYS5SIGNALS
@@ -1147,6 +1929,107 @@ reapchild()
errno = olderrno;
}
/*
+** PUTENV -- emulation of putenv() in terms of setenv()
+**
+** Not needed on Posix-compliant systems.
+** This doesn't have full Posix semantics, but it's good enough
+** for sendmail.
+**
+** Parameter:
+** env -- the environment to put.
+**
+** Returns:
+** none.
+*/
+
+#ifdef NEEDPUTENV
+
+# if NEEDPUTENV == 2 /* no setenv(3) call available */
+
+int
+putenv(str)
+ char *str;
+{
+ char **current;
+ int matchlen, envlen=0;
+ char *tmp;
+ char **newenv;
+ static int first=1;
+ extern char **environ;
+
+ /*
+ * find out how much of str to match when searching
+ * for a string to replace.
+ */
+ if ((tmp = index(str, '=')) == NULL || tmp == str)
+ matchlen = strlen(str);
+ else
+ matchlen = (int) (tmp - str);
+ ++matchlen;
+
+ /*
+ * Search for an existing string in the environment and find the
+ * length of environ. If found, replace and exit.
+ */
+ for (current=environ; *current; current++) {
+ ++envlen;
+
+ if (strncmp(str, *current, matchlen) == 0) {
+ /* found it, now insert the new version */
+ *current = (char *)str;
+ return(0);
+ }
+ }
+
+ /*
+ * There wasn't already a slot so add space for a new slot.
+ * If this is our first time through, use malloc(), else realloc().
+ */
+ if (first) {
+ newenv = (char **) malloc(sizeof(char *) * (envlen + 2));
+ if (newenv == NULL)
+ return(-1);
+
+ first=0;
+ (void) memcpy(newenv, environ, sizeof(char *) * envlen);
+ } else {
+ newenv = (char **) realloc((char *)environ, sizeof(char *) * (envlen + 2));
+ if (newenv == NULL)
+ return(-1);
+ }
+
+ /* actually add in the new entry */
+ environ = newenv;
+ environ[envlen] = (char *)str;
+ environ[envlen+1] = NULL;
+
+ return(0);
+}
+
+#else /* implement putenv() in terms of setenv() */
+
+int
+putenv(env)
+ char *env;
+{
+ char *p;
+ int l;
+ char nbuf[100];
+
+ p = strchr(env, '=');
+ if (p == NULL)
+ return 0;
+ l = p - env;
+ if (l > sizeof nbuf - 1)
+ l = sizeof nbuf - 1;
+ bcopy(env, nbuf, l);
+ nbuf[l] = '\0';
+ return setenv(nbuf, ++p, 1);
+}
+
+# endif
+#endif
+ /*
** UNSETENV -- remove a variable from the environment
**
** Not needed on newer systems.
@@ -1353,10 +2236,11 @@ fsync(fd)
** DGUX_INET_ADDR -- inet_addr for DG/UX
**
** Data General DG/UX version of inet_addr returns a struct in_addr
-** instead of a long. This patches things.
+** instead of a long. This patches things. Only needed on versions
+** prior to 5.4.3.
*/
-#ifdef DGUX
+#ifdef DGUX_5_4_2
#undef inet_addr
@@ -1399,13 +2283,14 @@ static char sccsid[] = "@(#)getopt.c 4.3 (Berkeley) 3/9/86";
* get option letter from argument vector
*/
#ifdef _CONVEX_SOURCE
-extern int optind, opterr;
+extern int optind, opterr, optopt;
+extern char *optarg;
#else
int opterr = 1; /* if error message should be printed */
int optind = 1; /* index into parent argv vector */
-#endif
int optopt = 0; /* character checked for validity */
char *optarg = NULL; /* argument associated with option */
+#endif
#define BADCH (int)'?'
#define EMSG ""
@@ -1467,12 +2352,12 @@ getopt(nargc,nargv,ostr)
#define MAXARG 16
vfprintf(fp, fmt, ap)
- FILE * fp;
- char * fmt;
- char ** ap;
+ FILE *fp;
+ char *fmt;
+ char **ap;
{
- char * bp[MAXARG];
- int i = 0;
+ char *bp[MAXARG];
+ int i = 0;
while (*ap && i < MAXARG)
bp[i++] = *ap++;
@@ -1483,12 +2368,12 @@ vfprintf(fp, fmt, ap)
}
vsprintf(s, fmt, ap)
- char * s;
- char * fmt;
- char ** ap;
+ char *s;
+ char *fmt;
+ char **ap;
{
- char * bp[MAXARG];
- int i = 0;
+ char *bp[MAXARG];
+ int i = 0;
while (*ap && i < MAXARG)
bp[i++] = *ap++;
@@ -1500,9 +2385,60 @@ vsprintf(s, fmt, ap)
#endif
/*
+** SNPRINTF, VSNPRINT -- counted versions of printf
+**
+** These are at best crude emulations.
+*/
+
+#if !HASSNPRINTF
+
+void
+# ifdef __STDC__
+snprintf(char *buf, size_t bufsize, const char *fmt, ...)
+# else
+snprintf(buf, bufsize, fmt, va_alist)
+ char *buf;
+ size_t bufsize;
+ const char *fmt;
+ va_dcl
+# endif
+{
+ VA_LOCAL_DECL
+
+ VA_START(fmt);
+ vsprintf(buf, fmt, ap);
+ VA_END;
+# if defined(XDEBUG) && defined(LOG)
+ if (strlen(buf) > bufsize)
+ syslog(LOG_ALERT, "INTERNAL ERROR: snprintf overflow: %s",
+ shortenstring(buf, 200));
+# endif
+}
+
+
+#ifndef luna2
+void
+vsnprintf(buf, bufsize, fmt, ap)
+ char *buf;
+ size_t bufsize;
+ const char *fmt;
+ va_list ap;
+{
+ vsprintf(buf, fmt, ap);
+# if defined(XDEBUG) && defined(LOG)
+ if (strlen(buf) > bufsize)
+ syslog(LOG_ALERT, "INTERNAL ERROR: vsnprintf overflow: %s",
+ shortenstring(buf, 200));
+# endif
+}
+#endif
+
+#endif
+ /*
** USERSHELLOK -- tell if a user's shell is ok for unrestricted use
**
** Parameters:
+** user -- the name of the user we are checking.
** shell -- the user's shell from /etc/passwd
**
** Returns:
@@ -1516,19 +2452,45 @@ vsprintf(s, fmt, ap)
# define _PATH_SHELLS "/etc/shells"
# endif
+# ifdef _AIX3
+# include <userconf.h>
+# include <usersec.h>
+# endif
+
char *DefaultUserShells[] =
{
- "/bin/sh",
+ "/bin/sh", /* standard shell */
"/usr/bin/sh",
- "/bin/csh",
+ "/bin/csh", /* C shell */
"/usr/bin/csh",
#ifdef __hpux
- "/bin/rsh",
- "/bin/ksh",
- "/bin/rksh",
+# ifdef V4FS
+ "/usr/bin/rsh", /* restricted Bourne shell */
+ "/usr/bin/ksh", /* Korn shell */
+ "/usr/bin/rksh", /* restricted Korn shell */
+ "/usr/bin/pam",
+ "/usr/bin/keysh", /* key shell (extended Korn shell) */
+ "/usr/bin/posix/sh",
+# else
+ "/bin/rsh", /* restricted Bourne shell */
+ "/bin/ksh", /* Korn shell */
+ "/bin/rksh", /* restricted Korn shell */
"/bin/pam",
- "/usr/bin/keysh",
+ "/usr/bin/keysh", /* key shell (extended Korn shell) */
"/bin/posix/sh",
+# endif
+#endif
+#ifdef _AIX3
+ "/bin/ksh", /* Korn shell */
+ "/usr/bin/ksh",
+ "/bin/tsh", /* trusted shell */
+ "/usr/bin/tsh",
+ "/bin/bsh", /* Bourne shell */
+ "/usr/bin/bsh",
+#endif
+#ifdef __svr4__
+ "/bin/ksh", /* Korn shell */
+ "/usr/bin/ksh",
#endif
NULL
};
@@ -1538,14 +2500,16 @@ char *DefaultUserShells[] =
#define WILDCARD_SHELL "/SENDMAIL/ANY/SHELL/"
bool
-usershellok(shell)
+usershellok(user, shell)
+ char *user;
char *shell;
{
#if HASGETUSERSHELL
register char *p;
extern char *getusershell();
- if (shell == NULL || shell[0] == '\0')
+ if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') ||
+ ConfigLevel <= 1)
return TRUE;
setusershell();
@@ -1555,12 +2519,41 @@ usershellok(shell)
endusershell();
return p != NULL;
#else
+# if USEGETCONFATTR
+ auto char *v;
+# endif
register FILE *shellf;
char buf[MAXLINE];
- if (shell == NULL || shell[0] == '\0')
+ if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't'))
return TRUE;
+# if USEGETCONFATTR
+ /*
+ ** Naturally IBM has a "better" idea.....
+ **
+ ** What a crock. This interface isn't documented, it is
+ ** considered part of the security library (-ls), and it
+ ** only works if you are running as root (since the list
+ ** of valid shells is obviously a source of great concern).
+ ** I recommend that you do NOT define USEGETCONFATTR,
+ ** especially since you are going to have to set up an
+ ** /etc/shells anyhow to handle the cases where getconfattr
+ ** fails.
+ */
+
+ if (getconfattr(SC_SYS_LOGIN, SC_SHELLS, &v, SEC_LIST) == 0 && v != NULL)
+ {
+ while (*v != '\0')
+ {
+ if (strcmp(v, shell) == 0 || strcmp(v, WILDCARD_SHELL) == 0)
+ return TRUE;
+ v += strlen(v) + 1;
+ }
+ return FALSE;
+ }
+# endif
+
shellf = fopen(_PATH_SHELLS, "r");
if (shellf == NULL)
{
@@ -1599,7 +2592,7 @@ usershellok(shell)
#endif
}
/*
-** FREESPACE -- see how much free space is on the queue filesystem
+** FREEDISKSPACE -- see how much free space is on the queue filesystem
**
** Only implemented if you have statfs.
**
@@ -1646,7 +2639,7 @@ usershellok(shell)
#endif
long
-freespace(dir, bsize)
+freediskspace(dir, bsize)
char *dir;
long *bsize;
{
@@ -1655,26 +2648,25 @@ freespace(dir, bsize)
struct ustat fs;
struct stat statbuf;
# define FSBLOCKSIZE DEV_BSIZE
-# define f_bavail f_tfree
+# define SFS_BAVAIL f_tfree
# else
# if defined(ultrix)
struct fs_data fs;
-# define f_bavail fd_bfreen
-# define FSBLOCKSIZE fs.fd_bsize
+# define SFS_BAVAIL fd_bfreen
+# define FSBLOCKSIZE 1024L
# else
# if SFS_TYPE == SFS_STATVFS
struct statvfs fs;
-# define FSBLOCKSIZE fs.f_bsize
+# define FSBLOCKSIZE fs.f_frsize
# else
struct statfs fs;
# define FSBLOCKSIZE fs.f_bsize
-# if defined(_SCO_unix_) || defined(IRIX) || defined(apollo)
-# define f_bavail f_bfree
-# endif
# endif
# endif
# endif
- extern int errno;
+# ifndef SFS_BAVAIL
+# define SFS_BAVAIL f_bavail
+# endif
# if SFS_TYPE == SFS_USTAT
if (stat(dir, &statbuf) == 0 && ustat(statbuf.st_dev, &fs) == 0)
@@ -1682,23 +2674,30 @@ freespace(dir, bsize)
# if SFS_TYPE == SFS_4ARGS
if (statfs(dir, &fs, sizeof fs, 0) == 0)
# else
-# if defined(ultrix)
- if (statfs(dir, &fs) > 0)
+# if SFS_TYPE == SFS_STATVFS
+ if (statvfs(dir, &fs) == 0)
# else
+# if defined(ultrix)
+ if (statfs(dir, &fs) > 0)
+# else
if (statfs(dir, &fs) == 0)
+# endif
# endif
# endif
# endif
{
if (bsize != NULL)
*bsize = FSBLOCKSIZE;
- return (fs.f_bavail);
+ if (fs.SFS_BAVAIL < 0)
+ return 0;
+ else
+ return fs.SFS_BAVAIL;
}
#endif
return (-1);
}
/*
-** ENOUGHSPACE -- check to see if there is enough free space on the queue fs
+** ENOUGHDISKSPACE -- is there enough free space on the queue fs?
**
** Only implemented if you have statfs.
**
@@ -1713,7 +2712,7 @@ freespace(dir, bsize)
*/
bool
-enoughspace(msize)
+enoughdiskspace(msize)
long msize;
{
long bfree, bsize;
@@ -1721,14 +2720,14 @@ enoughspace(msize)
if (MinBlocksFree <= 0 && msize <= 0)
{
if (tTd(4, 80))
- printf("enoughspace: no threshold\n");
+ printf("enoughdiskspace: no threshold\n");
return TRUE;
}
- if ((bfree = freespace(QueueDir, &bsize)) >= 0)
+ if ((bfree = freediskspace(QueueDir, &bsize)) >= 0)
{
if (tTd(4, 80))
- printf("enoughspace: bavail=%ld, need=%ld\n",
+ printf("enoughdiskspace: bavail=%ld, need=%ld\n",
bfree, msize);
/* convert msize to block count */
@@ -1742,14 +2741,16 @@ enoughspace(msize)
if (LogLevel > 0)
syslog(LOG_ALERT,
"%s: low on space (have %ld, %s needs %ld in %s)",
- CurEnv->e_id, bfree,
- CurHostName, msize, QueueDir);
+ CurEnv->e_id == NULL ? "[NOQUEUE]" : CurEnv->e_id,
+ bfree,
+ CurHostName == NULL ? "SMTP-DAEMON" : CurHostName,
+ msize, QueueDir);
#endif
return FALSE;
}
}
else if (tTd(4, 80))
- printf("enoughspace failure: min=%ld, need=%ld: %s\n",
+ printf("enoughdiskspace failure: min=%ld, need=%ld: %s\n",
MinBlocksFree, msize, errstring(errno));
return TRUE;
}
@@ -1850,6 +2851,7 @@ transienterror(err)
#if defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR))
case ENOSR: /* Out of streams resources */
#endif
+ case EOPENTIMEOUT: /* PSEUDO: open timed out */
return TRUE;
}
@@ -2011,7 +3013,7 @@ chownsafe(fd)
rval = fchown(tfd, DefUid, DefGid) != 0;
close(tfd);
unlink(s);
- setreuid(o_uid, o_euid);
+ setresuid(o_uid, o_euid, -1);
setresgid(o_gid, o_egid, -1);
return rval;
#else
@@ -2023,18 +3025,62 @@ chownsafe(fd)
# endif
# else
# ifdef _PC_CHOWN_RESTRICTED
- return fpathconf(fd, _PC_CHOWN_RESTRICTED) > 0;
-# else
-# ifdef BSD
+ int rval;
+
+ /*
+ ** Some systems (e.g., SunOS) seem to have the call and the
+ ** #define _PC_CHOWN_RESTRICTED, but don't actually implement
+ ** the call. This heuristic checks for that.
+ */
+
+ errno = 0;
+ rval = fpathconf(fd, _PC_CHOWN_RESTRICTED);
+ if (errno == 0)
+ return rval > 0;
+# endif
+# ifdef BSD
return TRUE;
-# else
+# else
return FALSE;
-# endif
# endif
# endif
#endif
}
/*
+** RESETLIMITS -- reset system controlled resource limits
+**
+** This is to avoid denial-of-service attacks
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*/
+
+#if HASSETRLIMIT
+# ifdef apollo
+# include <sys/time.h>
+# endif
+# include <sys/resource.h>
+#endif
+
+void
+resetlimits()
+{
+#if HASSETRLIMIT
+ struct rlimit lim;
+
+ lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
+ (void) setrlimit(RLIMIT_CPU, &lim);
+ (void) setrlimit(RLIMIT_FSIZE, &lim);
+#else
+# if HASULIMIT
+ (void) ulimit(2, 0x3fffff);
+# endif
+#endif
+}
+ /*
** GETCFNAME -- return the name of the .cf file.
**
** Some systems (e.g., NeXT) determine this dynamically.
@@ -2043,18 +3089,21 @@ chownsafe(fd)
char *
getcfname()
{
+
if (ConfFile != NULL)
return ConfFile;
-#ifdef NETINFO
+#if NETINFO
{
extern char *ni_propval();
char *cflocation;
- cflocation = ni_propval("/locations/sendmail", "sendmail.cf");
+ cflocation = ni_propval("/locations", NULL, "sendmail",
+ "sendmail.cf", '\0');
if (cflocation != NULL)
return cflocation;
}
#endif
+
return _PATH_SENDMAILCF;
}
/*
@@ -2079,13 +3128,49 @@ setvendor(vendor)
char *vendor;
{
if (strcasecmp(vendor, "Berkeley") == 0)
+ {
+ VendorCode = VENDOR_BERKELEY;
return TRUE;
+ }
/* add vendor extensions here */
+#ifdef SUN_EXTENSIONS
+ if (strcasecmp(vendor, "Sun") == 0)
+ {
+ VendorCode = VENDOR_SUN;
+ return TRUE;
+ }
+#endif
+
return FALSE;
}
/*
+** VENDOR_PRE_DEFAULTS, VENDOR_POST_DEFAULTS -- set vendor-specific defaults
+**
+** Vendor_pre_defaults is called before reading the configuration
+** file; vendor_post_defaults is called immediately after.
+**
+** Parameters:
+** e -- the global environment to initialize.
+**
+** Returns:
+** none.
+*/
+
+void
+vendor_pre_defaults(e)
+ ENVELOPE *e;
+{
+}
+
+
+void
+vendor_post_defaults(e)
+ ENVELOPE *e;
+{
+}
+ /*
** STRTOL -- convert string to long integer
**
** For systems that don't have it in the C library.
@@ -2191,40 +3276,127 @@ strtol(nptr, endptr, base)
#endif
/*
-** SOLARIS_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX
+** STRSTR -- find first substring in string
+**
+** Parameters:
+** big -- the big (full) string.
+** little -- the little (sub) string.
**
-** Solaris versions prior through 2.3 don't properly deliver a
-** canonical h_name field. This tries to work around it.
+** Returns:
+** A pointer to the first instance of little in big.
+** big if little is the null string.
+** NULL if little is not contained in big.
*/
-#ifdef SOLARIS
+#ifdef NEEDSTRSTR
+
+char *
+strstr(big, little)
+ char *big;
+ char *little;
+{
+ register char *p = big;
+ int l;
-extern int h_errno;
+ if (*little == '\0')
+ return big;
+ l = strlen(little);
+
+ while ((p = strchr(p, *little)) != NULL)
+ {
+ if (strncmp(p, little, l) == 0)
+ return p;
+ p++;
+ }
+ return NULL;
+}
+
+#endif
+ /*
+** SM_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX
+**
+** Some operating systems have wierd problems with the gethostbyXXX
+** routines. For example, Solaris versions at least through 2.3
+** don't properly deliver a canonical h_name field. This tries to
+** work around these problems.
+*/
struct hostent *
-solaris_gethostbyname(name)
- const char *name;
+sm_gethostbyname(name)
+ char *name;
{
-# ifdef SOLARIS_2_3
+ struct hostent *h;
+#if defined(SOLARIS) && SOLARIS < 204 || defined(sony_news) && defined(__svr4)
+# if SOLARIS == 203
static struct hostent hp;
static char buf[1000];
extern struct hostent *_switch_gethostbyname_r();
- return _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno);
+ if (tTd(61, 10))
+ printf("_switch_gethostbyname_r(%s)... ", name);
+ h = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno);
# else
extern struct hostent *__switch_gethostbyname();
- return __switch_gethostbyname(name);
+ if (tTd(61, 10))
+ printf("__switch_gethostbyname(%s)... ", name);
+ h = __switch_gethostbyname(name);
# endif
+#else
+ int nmaps;
+ char *maptype[MAXMAPSTACK];
+ short mapreturn[MAXMAPACTIONS];
+ char hbuf[MAXNAME];
+
+ if (tTd(61, 10))
+ printf("gethostbyname(%s)... ", name);
+ h = gethostbyname(name);
+ if (h == NULL)
+ {
+ if (tTd(61, 10))
+ printf("failure\n");
+
+ nmaps = switch_map_find("hosts", maptype, mapreturn);
+ while (--nmaps >= 0)
+ if (strcmp(maptype[nmaps], "nis") == 0 ||
+ strcmp(maptype[nmaps], "files") == 0)
+ break;
+ if (nmaps >= 0)
+ {
+ /* try short name */
+ if (strlen(name) > sizeof hbuf - 1)
+ return NULL;
+ strcpy(hbuf, name);
+ shorten_hostname(hbuf);
+
+ /* if it hasn't been shortened, there's no point */
+ if (strcmp(hbuf, name) != 0)
+ {
+ if (tTd(61, 10))
+ printf("gethostbyname(%s)... ", hbuf);
+ h = gethostbyname(hbuf);
+ }
+ }
+ }
+#endif
+ if (tTd(61, 10))
+ {
+ if (h == NULL)
+ printf("failure\n");
+ else
+ printf("%s\n", h->h_name);
+ }
+ return h;
}
struct hostent *
-solaris_gethostbyaddr(addr, len, type)
- const char *addr;
+sm_gethostbyaddr(addr, len, type)
+ char *addr;
int len;
int type;
{
-# ifdef SOLARIS_2_3
+#if defined(SOLARIS) && SOLARIS < 204
+# if SOLARIS == 203
static struct hostent hp;
static char buf[1000];
extern struct hostent *_switch_gethostbyaddr_r();
@@ -2235,122 +3407,155 @@ solaris_gethostbyaddr(addr, len, type)
return __switch_gethostbyaddr(addr, len, type);
# endif
+#else
+ return gethostbyaddr(addr, len, type);
+#endif
}
+ /*
+** SM_GETPW{NAM,UID} -- wrapper for getpwnam and getpwuid
+*/
-#endif
+struct passwd *
+sm_getpwnam(user)
+ char *user;
+{
+ return getpwnam(user);
+}
+
+struct passwd *
+sm_getpwuid(uid)
+ UID_T uid;
+{
+ return getpwuid(uid);
+}
/*
-** NI_PROPVAL -- netinfo property value lookup routine
+** LOAD_IF_NAMES -- load interface-specific names into $=w
**
** Parameters:
-** directory -- the Netinfo directory name.
-** propname -- the Netinfo property name.
+** none.
**
** Returns:
-** NULL -- if:
-** 1. the directory is not found
-** 2. the property name is not found
-** 3. the property contains multiple values
-** 4. some error occured
-** else -- the location of the config file.
+** none.
**
-** Notes:
-** Caller should free the return value of ni_proval
+** Side Effects:
+** Loads $=w with the names of all the interfaces.
*/
-#ifdef NETINFO
-
-# include <netinfo/ni.h>
-
-# define LOCAL_NETINFO_DOMAIN "."
-# define PARENT_NETINFO_DOMAIN ".."
-# define MAX_NI_LEVELS 256
+#ifdef SIOCGIFCONF
+struct rtentry;
+struct mbuf;
+# include <arpa/inet.h>
+# ifndef SUNOS403
+# include <sys/time.h>
+# endif
+# include <net/if.h>
+#endif
-char *
-ni_propval(directory, propname)
- char *directory;
- char *propname;
+void
+load_if_names()
{
- char *propval = NULL;
+#ifdef SIOCGIFCONF
+ int s;
int i;
- void *ni = NULL;
- void *lastni = NULL;
- ni_status nis;
- ni_id nid;
- ni_namelist ninl;
+ struct ifconf ifc;
+ char interfacebuf[1024];
- /*
- ** If the passed directory and property name are found
- ** in one of netinfo domains we need to search (starting
- ** from the local domain moving all the way back to the
- ** root domain) set propval to the property's value
- ** and return it.
- */
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s == -1)
+ return;
- for (i = 0; i < MAX_NI_LEVELS; ++i)
+ /* get the list of known IP address from the kernel */
+ ifc.ifc_buf = interfacebuf;
+ ifc.ifc_len = sizeof interfacebuf;
+ if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
{
- if (i == 0)
- {
- nis = ni_open(NULL, LOCAL_NETINFO_DOMAIN, &ni);
- }
- else
- {
- if (lastni != NULL)
- ni_free(lastni);
- lastni = ni;
- nis = ni_open(lastni, PARENT_NETINFO_DOMAIN, &ni);
- }
+ if (tTd(0, 4))
+ printf("SIOGIFCONF failed: %s\n", errstring(errno));
+ close(s);
+ return;
+ }
+ close(s);
- /*
- ** Don't bother if we didn't get a handle on a
- ** proper domain. This is not necessarily an error.
- ** We would get a positive ni_status if, for instance
- ** we never found the directory or property and tried
- ** to open the parent of the root domain!
- */
+ /* scan the list of IP address */
+ if (tTd(0, 40))
+ printf("scanning for interface specific names, ifc_len=%d\n",
+ ifc.ifc_len);
- if (nis != 0)
- break;
+ for (i = 0; i < ifc.ifc_len; )
+ {
+ struct ifreq *ifr = (struct ifreq *) &ifc.ifc_buf[i];
+ struct sockaddr *sa = &ifr->ifr_addr;
+ struct in_addr ia;
+ struct hostent *hp;
+ char ip_addr[256];
+ extern char *inet_ntoa();
+ extern struct hostent *gethostbyaddr();
+
+#ifdef BSD4_4_SOCKADDR
+ if (sa->sa_len > sizeof ifr->ifr_addr)
+ i += sizeof ifr->ifr_name + sa->sa_len;
+ else
+#endif
+ i += sizeof *ifr;
- /*
- ** Find the path to the server information.
- */
+ if (tTd(0, 20))
+ printf("%s\n", anynet_ntoa((SOCKADDR *) sa));
- if (ni_pathsearch(ni, &nid, directory) != 0)
+ /* for some reason gcc 2.3 pukes on || here */
+ if (!bitset(IFF_UP, ifr->ifr_flags))
continue;
-
- /*
- ** Find "host" information.
- */
-
- if (ni_lookupprop(ni, &nid, propname, &ninl) != 0)
+ if (ifr->ifr_addr.sa_family != AF_INET)
continue;
- /*
- ** If there's only one name in
- ** the list, assume we've got
- ** what we want.
- */
+ /* extract IP address from the list*/
+ ia = (((struct sockaddr_in *) sa)->sin_addr);
- if (ninl.ni_namelist_len == 1)
+ /* save IP address in text from */
+ (void) sprintf(ip_addr, "[%.*s]",
+ sizeof ip_addr - 3,
+ inet_ntoa(((struct sockaddr_in *) sa)->sin_addr));
+ if (!wordinclass(ip_addr, 'w'))
{
- propval = ni_name_dup(ninl.ni_namelist_val[0]);
- break;
+ setclass('w', ip_addr);
+ if (tTd(0, 4))
+ printf("\ta.k.a.: %s\n", ip_addr);
}
- }
- /*
- ** Clean up.
- */
+ /* skip "loopback" interface "lo" */
+ if (strcmp("lo0", ifr->ifr_name) == 0)
+ continue;
- if (ni != NULL)
- ni_free(ni);
- if (lastni != NULL && ni != lastni)
- ni_free(lastni);
+ /* lookup name with IP address */
+ hp = sm_gethostbyaddr((char *) &ia, sizeof(ia), AF_INET);
+ if (hp == NULL)
+ {
+ syslog(LOG_CRIT, "gethostbyaddr() failed for %.100s\n",
+ inet_ntoa(ia));
+ continue;
+ }
- return propval;
-}
+ /* save its cname */
+ if (!wordinclass((char *) hp->h_name, 'w'))
+ {
+ setclass('w', (char *) hp->h_name);
+ if (tTd(0, 4))
+ printf("\ta.k.a.: %s\n", hp->h_name);
+ }
-#endif /* NETINFO */
+ /* save all it aliases name */
+ while (*hp->h_aliases)
+ {
+ if (!wordinclass(*hp->h_aliases, 'w'))
+ {
+ setclass('w', *hp->h_aliases);
+ if (tTd(0, 4))
+ printf("\ta.k.a.: %s\n", *hp->h_aliases);
+ }
+ hp->h_aliases++;
+ }
+ }
+#endif
+}
/*
** HARD_SYSLOG -- call syslog repeatedly until it works
**
@@ -2364,6 +3569,7 @@ ni_propval(directory, propname)
# undef syslog
# ifdef __STDC__
+void
hard_syslog(int pri, char *msg, ...)
# else
hard_syslog(pri, msg, va_alist)
@@ -2377,7 +3583,7 @@ hard_syslog(pri, msg, va_alist)
VA_LOCAL_DECL;
VA_START(msg);
- vsprintf(buf, msg, ap);
+ vsnprintf(buf, sizeof buf, msg, ap);
VA_END;
for (i = MAXSYSLOGTRIES; --i >= 0 && syslog(pri, "%s", buf) < 0; )
@@ -2385,3 +3591,167 @@ hard_syslog(pri, msg, va_alist)
}
#endif
+ /*
+** LOCAL_HOSTNAME_LENGTH
+**
+** This is required to get sendmail to compile against BIND 4.9.x
+** on Ultrix.
+*/
+
+#if defined(ultrix) && NAMED_BIND
+
+# include <resolv.h>
+# if __RES >= 19931104 && __RES < 19950621
+
+int
+local_hostname_length(hostname)
+ char *hostname;
+{
+ int len_host, len_domain;
+
+ if (!*_res.defdname)
+ res_init();
+ len_host = strlen(hostname);
+ len_domain = strlen(_res.defdname);
+ if (len_host > len_domain &&
+ (strcasecmp(hostname + len_host - len_domain,_res.defdname) == 0) &&
+ hostname[len_host - len_domain - 1] == '.')
+ return len_host - len_domain - 1;
+ else
+ return 0;
+}
+
+# endif
+#endif
+ /*
+** Compile-Time options
+*/
+
+char *CompileOptions[] =
+{
+#if HESIOD
+ "HESIOD",
+#endif
+#if HES_GETMAILHOST
+ "HES_GETMAILHOST",
+#endif
+#ifdef LOG
+ "LOG",
+#endif
+#if MATCHGECOS
+ "MATCHGECOS",
+#endif
+#if MIME8TO7
+ "MIME8TO7",
+#endif
+#if NAMED_BIND
+ "NAMED_BIND",
+#endif
+#if NDBM
+ "NDBM",
+#endif
+#if NETINET
+ "NETINET",
+#endif
+#if NETINFO
+ "NETINFO",
+#endif
+#if NETISO
+ "NETISO",
+#endif
+#if NETNS
+ "NETNS",
+#endif
+#if NETUNIX
+ "NETUNIX",
+#endif
+#if NETX25
+ "NETX25",
+#endif
+#if NEWDB
+ "NEWDB",
+#endif
+#if NIS
+ "NIS",
+#endif
+#if NISPLUS
+ "NISPLUS",
+#endif
+#if SCANF
+ "SCANF",
+#endif
+#if SUID_ROOT_FILES_OK
+ "SUID_ROOT_FILES_OK",
+#endif
+#if USERDB
+ "USERDB",
+#endif
+#if XDEBUG
+ "XDEBUG",
+#endif
+#if XLA
+ "XLA",
+#endif
+ NULL
+};
+
+
+/*
+** OS compile options.
+*/
+
+char *OsCompileOptions[] =
+{
+#if HASFCHMOD
+ "HASFCHMOD",
+#endif
+#if HASFLOCK
+ "HASFLOCK",
+#endif
+#if HASGETUSERSHELL
+ "HASGETUSERSHELL",
+#endif
+#if HASINITGROUPS
+ "HASINITGROUPS",
+#endif
+#if HASLSTAT
+ "HASLSTAT",
+#endif
+#if HASSETREUID
+ "HASSETREUID",
+#endif
+#if HASSETSID
+ "HASSETSID",
+#endif
+#if HASSETVBUF
+ "HASSETVBUF",
+#endif
+#if HASSNPRINTF
+ "HASSNPRINTF",
+#endif
+#if HASUNAME
+ "HASUNAME",
+#endif
+#if IDENTPROTO
+ "IDENTPROTO",
+#endif
+#if IP_SRCROUTE
+ "IP_SRCROUTE",
+#endif
+#if NEEDFSYNC
+ "NEEDFSYNC",
+#endif
+#if NOFTRUNCATE
+ "NOFTRUNCATE",
+#endif
+#if SYS5SETPGRP
+ "SYS5SETPGRP",
+#endif
+#if SYSTEM5
+ "SYSTEM5",
+#endif
+#if USESETEUID
+ "USESETEUID",
+#endif
+ NULL
+};
diff --git a/usr.sbin/sendmail/src/conf.h b/usr.sbin/sendmail/src/conf.h
index 10a8d3d..30bb9d1 100644
--- a/usr.sbin/sendmail/src/conf.h
+++ b/usr.sbin/sendmail/src/conf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -31,20 +31,28 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)conf.h 8.104 (Berkeley) 4/17/94
+ * @(#)conf.h 8.219 (Berkeley) 11/11/95
*/
/*
** CONF.H -- All user-configurable parameters for sendmail
+**
+** Send updates to sendmail@Sendmail.ORG so they will be
+** included in the next release.
*/
+struct rusage; /* forward declaration to get gcc to shut up in wait.h */
+
# include <sys/param.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/file.h>
# include <sys/wait.h>
+# include <limits.h>
# include <fcntl.h>
# include <signal.h>
+# include <netdb.h>
+# include <pwd.h>
/**********************************************************************
** Table sizes, etc....
@@ -56,7 +64,7 @@
# define MAXPV 40 /* max # of parms to mailers */
# define MAXATOM 200 /* max atoms per address */
# define MAXMAILERS 25 /* maximum mailers known to system */
-# define MAXRWSETS 100 /* max # of sets of rewriting rules */
+# define MAXRWSETS 200 /* max # of sets of rewriting rules */
# define MAXPRIORITIES 25 /* max values for Precedence: field */
# define MAXMXHOSTS 20 /* max # of MX records */
# define SMTPLINELIM 990 /* maximum SMTP line length */
@@ -64,46 +72,68 @@
# define MEMCHUNKSIZE 1024 /* chunk size for memory allocation */
# define MAXUSERENVIRON 100 /* max envars saved, must be >= 3 */
# define MAXALIASDB 12 /* max # of alias databases */
-
-# ifndef QUEUESIZE
-# define QUEUESIZE 1000 /* max # of jobs per queue run */
-# endif
+# define MAXMAPSTACK 12 /* max # of stacked or sequenced maps */
+# define MAXTOCLASS 8 /* max # of message timeout classes */
+# define MAXMIMEARGS 20 /* max args in Content-Type: */
+# define MAXMIMENESTING 20 /* max MIME multipart nesting */
+# define QUEUESEGSIZE 1000 /* increment for queue size */
/**********************************************************************
** Compilation options.
-**
-** #define these if they are available; comment them out otherwise.
+** #define these to 1 if they are available;
+** #define them to 0 otherwise.
+** All can be overridden from Makefile.
**********************************************************************/
-# define LOG 1 /* enable logging */
-# define UGLYUUCP 1 /* output ugly UUCP From lines */
-# define NETUNIX 1 /* include unix domain support */
-# define NETINET 1 /* include internet support */
-# define SETPROCTITLE 1 /* munge argv to display current status */
-# define MATCHGECOS 1 /* match user names from gecos field */
-# define XDEBUG 1 /* enable extended debugging */
-# ifdef NEWDB
-# define USERDB 1 /* look in user database (requires NEWDB) */
+# ifndef NETINET
+# define NETINET 1 /* include internet support */
# endif
-/**********************************************************************
-** 0/1 Compilation options.
-** #define these to 1 if they are available;
-** #define them to 0 otherwise.
-**********************************************************************/
+# ifndef NETISO
+# define NETISO 0 /* do not include ISO socket support */
+# endif
# ifndef NAMED_BIND
# define NAMED_BIND 1 /* use Berkeley Internet Domain Server */
# endif
-/*
-** Most systems have symbolic links today, so default them on. You
-** can turn them off by #undef'ing this below.
-*/
+# ifndef XDEBUG
+# define XDEBUG 1 /* enable extended debugging */
+# endif
-# define HASLSTAT 1 /* has lstat(2) call */
+# ifndef MATCHGECOS
+# define MATCHGECOS 1 /* match user names from gecos field */
+# endif
-/*
+# ifndef DSN
+# define DSN 1 /* include delivery status notification code */
+# endif
+
+# if !defined(USERDB) && (defined(NEWDB) || defined(HESIOD))
+# define USERDB 1 /* look in user database */
+# endif
+
+# ifndef MIME8TO7
+# define MIME8TO7 1 /* 8->7 bit MIME conversions */
+# endif
+
+# ifndef MIME7TO8
+# define MIME7TO8 1 /* 7->8 bit MIME conversions */
+# endif
+
+/**********************************************************************
+** "Hard" compilation options.
+** #define these if they are available; comment them out otherwise.
+** These cannot be overridden from the Makefile, and should really not
+** be turned off unless absolutely necessary.
+**********************************************************************/
+
+# define LOG /* enable logging -- don't turn off */
+
+/**********************************************************************
+** End of site-specific configuration.
+**********************************************************************/
+ /*
** General "standard C" defines.
**
** These may be undone later, to cope with systems that claim to
@@ -118,7 +148,12 @@
# define HASSETVBUF 1 /* we have setvbuf(3) in libc */
#endif
-/**********************************************************************
+/*
+** Assume you have standard calls; can be #undefed below if necessary.
+*/
+
+# define HASLSTAT 1 /* has lstat(2) call */
+ /**********************************************************************
** Operating system configuration.
**
** Unless you are porting to a new OS, you shouldn't have to
@@ -126,80 +161,125 @@
**********************************************************************/
/*
-** Per-Operating System defines
-*/
-
-
-/*
** HP-UX -- tested for 8.07, 9.00, and 9.01.
+**
+** If V4FS is defined, compile for HP-UX 10.0.
*/
-# ifdef __hpux
-/* avoid m_flags conflict between db.h & sys/sysmacros.h on HP 300 */
-# undef m_flags
+#ifdef __hpux
+ /* common definitions for HP-UX 9.x and 10.x */
+# undef m_flags /* conflict between db.h & sys/sysmacros.h on HP 300 */
# define SYSTEM5 1 /* include all the System V defines */
# define HASINITGROUPS 1 /* has initgroups(3) call */
-# define HASSETREUID 1 /* has setreuid(2) call */
-# define setreuid(r, e) setresuid(r, e, -1)
-# define LA_TYPE LA_FLOAT
+# define HASFCHMOD 1 /* has fchmod(2) syscall */
+# define USESETEUID 1 /* has useable seteuid(2) call */
+# define seteuid(e) setresuid(-1, e, -1)
+# define IP_SRCROUTE 1 /* can check IP source routing */
+# define LA_TYPE LA_HPUX
+# define SPT_TYPE SPT_PSTAT
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
# define GIDSET_T gid_t
-# define _PATH_UNIX "/hp-ux"
-# ifndef _PATH_SENDMAILCF
-# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
-# endif
-# ifndef IDENTPROTO
-# define IDENTPROTO 0 /* TCP/IP implementation is broken */
-# endif
# ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */
# endif
# define syslog hard_syslog
# ifdef __STDC__
-extern int syslog(int, char *, ...);
+extern void hard_syslog(int, char *, ...);
# endif
+
+# ifdef V4FS
+ /* HP-UX 10.x */
+# define _PATH_UNIX "/stand/vmunix"
+# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf"
+# ifndef _PATH_SENDMAILPID
+# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid"
+# endif
+# ifndef IDENTPROTO
+# define IDENTPROTO 1 /* TCP/IP implementation fixed in 10.0 */
+# endif
+
+# else
+ /* HP-UX 9.x */
+# define _PATH_UNIX "/hp-ux"
+# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
+# ifndef IDENTPROTO
+# define IDENTPROTO 0 /* TCP/IP implementation is broken */
+# endif
# endif
+#endif
+
/*
** IBM AIX 3.x -- actually tested for 3.2.3
*/
-# ifdef _AIX3
+#ifdef _AIX3
+# include <paths.h>
# define HASINITGROUPS 1 /* has initgroups(3) call */
# define HASUNAME 1 /* use System V uname(2) system call */
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# define HASFCHMOD 1 /* has fchmod(2) syscall */
+# define IP_SRCROUTE 0 /* Something is broken with getsockopt() */
# define FORK fork /* no vfork primitive available */
-# undef SETPROCTITLE /* setproctitle confuses AIX */
+# define GIDSET_T gid_t
# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */
-# endif
+# define SPT_PADCHAR '\0' /* pad process title with nulls */
+# define LA_TYPE LA_INT
+# define LA_AVENRUN "avenrun"
+#endif
/*
** Silicon Graphics IRIX
**
** Compiles on 4.0.1.
+**
+** Use IRIX64 instead of IRIX for 64-bit IRIX (6.0).
+** Use IRIX5 instead of IRIX for IRIX 5.x.
+**
+** IRIX64 changes from Mark R. Levinson <ml@cvdev.rochester.edu>.
+** IRIX5 changes from Kari E. Hurtta <Kari.Hurtta@fmi.fi>.
*/
-# ifdef IRIX
+#if defined(IRIX64) || defined(IRIX5)
+# define IRIX
+#endif
+
+#ifdef IRIX
# define SYSTEM5 1 /* this is a System-V derived system */
# define HASSETREUID 1 /* has setreuid(2) call */
# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define HASFCHMOD 1 /* has fchmod(2) syscall */
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# define IP_SRCROUTE 1 /* can check IP source routing */
# define FORK fork /* no vfork primitive available */
-# define WAITUNION 1 /* use "union wait" as wait argument type */
# define setpgid BSDsetpgrp
# define GIDSET_T gid_t
# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */
+# define SFS_BAVAIL f_bfree /* alternate field name */
# define LA_TYPE LA_INT
+# ifdef IRIX64
+# define NAMELISTMASK 0x7fffffffffffffff /* mask for nlist() values */
+# else
+# define NAMELISTMASK 0x7fffffff /* mask for nlist() values */
# endif
+# if defined(IRIX64) || defined(IRIX5)
+# define ARGV_T char *const *
+# define HASSETRLIMIT 1 /* has setrlimit(2) syscall */
+# define HASGETDTABLESIZE 1 /* has getdtablesize(2) syscall */
+# else
+# define ARGV_T const char **
+# define WAITUNION 1 /* use "union wait" as wait argument type */
+# endif
+#endif
/*
** SunOS and Solaris
**
** Tested on SunOS 4.1.x (a.k.a. Solaris 1.1.x) and
-** Solaris 2.2 (a.k.a. SunOS 5.2).
+** Solaris 2.4 (a.k.a. SunOS 5.4).
*/
#if defined(sun) && !defined(BSD)
@@ -207,10 +287,12 @@ extern int syslog(int, char *, ...);
# define HASINITGROUPS 1 /* has initgroups(3) call */
# define HASUNAME 1 /* use System V uname(2) system call */
# define HASGETUSERSHELL 1 /* DOES have getusershell(3) call in libc */
+# define HASFCHMOD 1 /* has fchmod(2) syscall */
+# define IP_SRCROUTE 1 /* can check IP source routing */
# define LA_TYPE LA_INT
# ifdef SOLARIS_2_3
-# define SOLARIS
+# define SOLARIS 203 /* for back compat only -- use -DSOLARIS=203 */
# endif
# ifdef SOLARIS
@@ -219,18 +301,17 @@ extern int syslog(int, char *, ...);
# define __svr4__ /* use all System V Releae 4 defines below */
# endif
# include <sys/time.h>
-# define gethostbyname solaris_gethostbyname /* get working version */
-# define gethostbyaddr solaris_gethostbyaddr /* get working version */
# define GIDSET_T gid_t
# ifndef _PATH_UNIX
-# define _PATH_UNIX "/kernel/unix"
-# endif
-# ifndef _PATH_SENDMAILCF
-# define _PATH_SENDMAILCF "/etc/mail/sendmail.cf"
+# define _PATH_UNIX "/dev/ksyms"
# endif
+# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf"
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid"
# endif
+# ifndef _PATH_HOSTS
+# define _PATH_HOSTS "/etc/inet/hosts"
+# endif
# ifndef SYSLOG_BUFSIZE
# define SYSLOG_BUFSIZE 1024 /* allow full size syslog buffer */
# endif
@@ -242,12 +323,14 @@ extern int syslog(int, char *, ...);
# define HASFLOCK 1 /* has flock(2) call */
# endif
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
+# define TZ_TYPE TZ_TM_ZONE /* use tm->tm_zone */
# include <vfork.h>
# ifdef SUNOS403
/* special tweaking for SunOS 4.0.3 */
# include <malloc.h>
-# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
+# define BSD4_3 1 /* 4.3 BSD-based */
+# define NEEDSTRSTR 1 /* need emulation of strstr(3) routine */
# define WAITUNION 1 /* use "union wait" as wait argument type */
# undef WIFEXITED
# undef WEXITSTATUS
@@ -268,29 +351,41 @@ extern char *getenv();
/*
** DG/UX
**
-** Tested on 5.4.2
+** Tested on 5.4.2 and 5.4.3. Use DGUX_5_4_2 to get the
+** older support.
+** 5.4.3 changes from Mark T. Robinson <mtr@ornl.gov>.
*/
+#ifdef DGUX_5_4_2
+# define DGUX 1
+#endif
+
#ifdef DGUX
# define SYSTEM5 1
-# define LA_TYPE LA_SUBR
+# define LA_TYPE LA_DGUX
# define HASSETREUID 1 /* has setreuid(2) call */
# define HASUNAME 1 /* use System V uname(2) system call */
# define HASSETSID 1 /* has Posix setsid(2) call */
# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define IP_SRCROUTE 0 /* does not have <netinet/ip_var.h> */
# define HASGETUSERSHELL 0 /* does not have getusershell(3) */
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
# endif
-# undef SETPROCTITLE
+# define SPT_TYPE SPT_NONE /* don't use setproctitle */
# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */
/* these include files must be included early on DG/UX */
# include <netinet/in.h>
# include <arpa/inet.h>
-# define inet_addr dgux_inet_addr
+/* compiler doesn't understand const? */
+# define const
+
+# ifdef DGUX_5_4_2
+# define inet_addr dgux_inet_addr
extern long dgux_inet_addr();
+# endif
#endif
@@ -307,11 +402,14 @@ extern long dgux_inet_addr();
# define HASUNSETENV 1 /* has unsetenv(3) call */
# define HASINITGROUPS 1 /* has initgroups(3) call */
# define HASUNAME 1 /* use System V uname(2) system call */
+# define HASFCHMOD 1 /* has fchmod(2) syscall */
# ifndef HASFLOCK
# define HASFLOCK 1 /* has flock(2) call */
# endif
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
-# define BROKEN_RES_SEARCH 1 /* res_search(unknown) returns h_errno=0 */
+# ifndef BROKEN_RES_SEARCH
+# define BROKEN_RES_SEARCH 1 /* res_search(unknown) returns h_errno=0 */
+# endif
# ifdef vax
# define LA_TYPE LA_FLOAT
# else
@@ -320,19 +418,50 @@ extern long dgux_inet_addr();
# endif
# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
# ifndef IDENTPROTO
-# define IDENTPROTO 0 /* TCP/IP implementation is broken */
+# define IDENTPROTO 0 /* pre-4.4 TCP/IP implementation is broken */
# endif
#endif
/*
+** OSF/1 for KSR.
+**
+** Contributed by Todd C. Miller <Todd.Miller@cs.colorado.edu>
+*/
+
+#ifdef __ksr__
+# define __osf__ 1 /* get OSF/1 defines below */
+# define FORK fork /* no vfork primitive available */
+# define _PATH_VENDOR_CF "/var/adm/sendmail/sendmail.cf"
+# ifndef TZ_TYPE
+# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */
+# endif
+#endif
+
+
+/*
+** OSF/1 for Intel Paragon.
+**
+** Contributed by Jeff A. Earickson <jeff@ssd.intel.com>
+** of Intel Scalable Systems Divison.
+*/
+
+#ifdef __PARAGON__
+# define __osf__ 1 /* get OSF/1 defines below */
+# define _PATH_VENDOR_CF "/var/adm/sendmail/sendmail.cf"
+#endif
+
+
+/*
** OSF/1 (tested on Alpha)
*/
#ifdef __osf__
# define HASUNSETENV 1 /* has unsetenv(3) call */
-# define HASSETREUID 1 /* has setreuid(2) call */
+# define USESETEUID 1 /* has useable seteuid(2) call */
# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define HASFCHMOD 1 /* has fchmod(2) syscall */
+# define IP_SRCROUTE 1 /* can check IP source routing */
# ifndef HASFLOCK
# define HASFLOCK 1 /* has flock(2) call */
# endif
@@ -350,11 +479,13 @@ extern long dgux_inet_addr();
#ifdef NeXT
# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define NEEDPUTENV 2 /* need putenv(3) call; no setenv(3) call */
# ifndef HASFLOCK
# define HASFLOCK 1 /* has flock(2) call */
# endif
# define NEEDGETOPT 1 /* need a replacement for getopt(3) */
# define WAITUNION 1 /* use "union wait" as wait argument type */
+# define UID_T int /* compiler gripes on uid_t */
# define sleep sleepX
# define setpgid setpgrp
# ifndef LA_TYPE
@@ -366,9 +497,7 @@ typedef int pid_t;
# undef WEXITSTATUS
# undef WIFEXITED
# endif
-# ifndef _PATH_SENDMAILCF
-# define _PATH_SENDMAILCF "/etc/sendmail/sendmail.cf"
-# endif
+# define _PATH_VENDOR_CF "/etc/sendmail/sendmail.cf"
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/sendmail/sendmail.pid"
# endif
@@ -381,14 +510,20 @@ typedef int pid_t;
** See also BSD defines.
*/
-#ifdef BSD4_4
+#if defined(BSD4_4) && !defined(__bsdi__)
# define HASUNSETENV 1 /* has unsetenv(3) call */
+# define USESETEUID 1 /* has useable seteuid(2) call */
+# define HASFCHMOD 1 /* has fchmod(2) syscall */
+# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */
# include <sys/cdefs.h>
# define ERRLIST_PREDEFINED /* don't declare sys_errlist */
+# define BSD4_4_SOCKADDR /* has sa_len */
+# define NETLINK 1 /* supports AF_LINK */
# ifndef LA_TYPE
# define LA_TYPE LA_SUBR
# endif
# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
+# define SPT_TYPE SPT_PSSTRINGS /* use PS_STRINGS pointer */
#endif
@@ -400,31 +535,39 @@ typedef int pid_t;
#ifdef __bsdi__
# define HASUNSETENV 1 /* has the unsetenv(3) call */
# define HASSETSID 1 /* has the setsid(2) POSIX syscall */
+# define USESETEUID 1 /* has useable seteuid(2) call */
+# define HASFCHMOD 1 /* has fchmod(2) syscall */
+# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */
+# define HASUNAME 1 /* has uname(2) syscall */
# include <sys/cdefs.h>
# define ERRLIST_PREDEFINED /* don't declare sys_errlist */
+# define BSD4_4_SOCKADDR /* has sa_len */
+# define NETLINK 1 /* supports AF_LINK */
# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
# ifndef LA_TYPE
# define LA_TYPE LA_SUBR
# endif
+# define GIDSET_T gid_t
# if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199312
/* version 1.1 or later */
-# define HASSETPROCTITLE 1 /* setproctitle is in libc */
-# undef SETPROCTITLE /* so don't redefine it in conf.c */
+# undef SPT_TYPE
+# define SPT_TYPE SPT_BUILTIN /* setproctitle is in libc */
# else
/* version 1.0 or earlier */
# ifndef OLD_NEWDB
# define OLD_NEWDB 1 /* old version of newdb library */
# endif
+# define SPT_PADCHAR '\0' /* pad process title with nulls */
# endif
#endif
/*
-** 386BSD / FreeBSD 1.0E / NetBSD (all architectures, all versions)
+** FreeBSD / NetBSD (all architectures, all versions)
**
-** Were 4.3BSD clone, closer to 4.4BSD
-** Now real 4.4BSD.
+** 4.3BSD clone, closer to 4.4BSD for FreeBSD 1.x and NetBSD 0.9x
+** 4.4BSD-Lite based for FreeBSD 2.x and NetBSD 1.x
**
** See also BSD defines.
*/
@@ -432,14 +575,24 @@ typedef int pid_t;
#if defined(__FreeBSD__) || defined(__NetBSD__)
# define HASUNSETENV 1 /* has unsetenv(3) call */
# define HASSETSID 1 /* has the setsid(2) POSIX syscall */
+# define USESETEUID 1 /* has useable seteuid(2) call */
+# define HASFCHMOD 1 /* has fchmod(2) syscall */
+# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */
# define HASUNAME 1 /* has uname(2) syscall */
-# define GIDSET_T gid_t
# include <sys/cdefs.h>
# define ERRLIST_PREDEFINED /* don't declare sys_errlist */
+# define BSD4_4_SOCKADDR /* has sa_len */
+# define NETLINK 1 /* supports AF_LINK */
+# define GIDSET_T gid_t
# ifndef LA_TYPE
# define LA_TYPE LA_SUBR
# endif
# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
+# if defined(__NetBSD__) && (NetBSD > 199307 || NetBSD0_9 > 1)
+# undef SPT_TYPE
+# define SPT_TYPE SPT_BUILTIN /* setproctitle is in libc */
+# define setreuid __setreuid
+# endif
#endif
@@ -466,9 +619,7 @@ typedef int pid_t;
# undef HASSETVBUF /* don't actually have setvbuf(3) */
# undef WEXITSTATUS
# undef WIFEXITED
-# ifndef _PATH_SENDMAILCF
-# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
-# endif
+# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/sendmail.pid"
# endif
@@ -492,9 +643,7 @@ typedef int pid_t;
# ifndef LA_TYPE
# define LA_TYPE LA_FLOAT
# endif
-# ifndef _PATH_SENDMAILCF
-# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
-# endif
+# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
# endif
@@ -516,25 +665,85 @@ extern int errno;
#ifdef _SCO_unix_4_2
# define _SCO_unix_
# define HASSETREUID 1 /* has setreuid(2) call */
-# define NEEDFSYNC 1 /* needs the fsync(2) call stub */
-# define _PATH_UNIX "/unix"
-# ifndef _PATH_SENDMAILCF
-# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
-# endif
+# define _PATH_UNIX "/unix"
+# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/sendmail.pid"
# endif
#endif
#ifdef _SCO_unix_
+# include <sys/stream.h> /* needed for IP_SRCROUTE */
+# define SYSTEM5 1 /* include all the System V defines */
+# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
+# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# define NEEDFSYNC 1 /* needs the fsync(2) call stub */
+# define FORK fork
+# 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 NETUNIX 0 /* no unix domain socket support */
+#endif
+
+
+/*
+** ISC (SunSoft) Unix.
+**
+** Contributed by J.J. Bailey <jjb@jagware.bcc.com>
+*/
+
+#ifdef ISC_UNIX
+# include <net/errno.h>
+# include <sys/stream.h> /* needed for IP_SRCROUTE */
+# include <sys/bsdtypes.h>
# define SYSTEM5 1 /* include all the System V defines */
# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# define HASSETREUID 1 /* has setreuid(2) call */
+# define NEEDFSYNC 1 /* needs the fsync(2) call stub */
+# define NETUNIX 0 /* no unix domain socket support */
+# define FORK fork
+# define MAXPATHLEN 1024
+# define LA_TYPE LA_SHORT
+# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */
+# define SFS_BAVAIL f_bfree /* alternate field name */
+# define _PATH_UNIX "/unix"
+# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
+# ifndef _PATH_SENDMAILPID
+# define _PATH_SENDMAILPID "/etc/sendmail.pid"
+# endif
+
+#endif
+
+
+/*
+** Altos System V.
+** Contributed by Tim Rice <timr@crl.com>.
+*/
+
+#ifdef ALTOS_SYS_V
+# define SYSTEM5 1 /* include all the System V defines */
+# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
+# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# define WAITUNION 1 /* use "union wait" as wait argument type */
+# define NEEDFSYNC 1 /* no fsync(2) in system library */
# define FORK fork
# define MAXPATHLEN PATHSIZE
# define LA_TYPE LA_SHORT
# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */
-# undef NETUNIX /* no unix domain socket support */
+# define SFS_BAVAIL f_bfree /* alternate field name */
+# define TZ_TYPE TZ_TM_NAME /* use tm->tm_name */
+# define NETUNIX 0 /* no unix domain socket support */
+# undef WIFEXITED
+# undef WEXITSTATUS
+# define strtoul strtol /* gcc library bogosity */
+
+typedef unsigned short uid_t;
+typedef unsigned short gid_t;
+typedef short pid_t;
#endif
@@ -550,11 +759,10 @@ extern int errno;
# define HASUNAME 1 /* use System V uname(2) system call */
# define HASSETSID 1 /* has POSIX setsid(2) call */
# define NEEDGETOPT 1 /* need replacement for getopt(3) */
+# define IP_SRCROUTE 0 /* Something is broken with getsockopt() */
# define LA_TYPE LA_FLOAT
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
-# ifndef _PATH_SENDMAILCF
-# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
-# endif
+# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
# ifndef S_IREAD
# define S_IREAD _S_IREAD
# define S_IWRITE _S_IWRITE
@@ -583,6 +791,9 @@ extern int errno;
# endif
# define WAITUNION 1 /* use "union wait" as wait argument type */
# define NEEDGETOPT 1 /* need a replacement for getopt(3) */
+# define NEEDPUTENV 1 /* need putenv(3) call */
+# define NEEDSTRSTR 1 /* need emulation of the strstr(3) call */
+# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
# define LA_TYPE LA_INT
# define LA_AVENRUN "avenrun"
# define _PATH_UNIX "/unix"
@@ -597,6 +808,8 @@ typedef int (*sigfunc_t)();
extern char *getenv();
extern void *malloc();
+# include <sys/time.h>
+
#endif
@@ -606,13 +819,13 @@ extern void *malloc();
** Thanks to, in reverse order of contact:
**
** John Kennedy <warlock@csuchico.edu>
+** Andrew Pam <avatar@aus.xanadu.com>
** Florian La Roche <rzsfl@rz.uni-sb.de>
** Karl London <karl@borg.demon.co.uk>
**
-** Last compiled against: [03/02/94 @ 05:34 PM (Wednesday)]
-** sendmail 8.6.6.b9 named 4.9.2-931205-p1 db-1.73
-** gcc 2.5.8 libc.so.4.5.19
-** slackware 1.1.2 linux 0.99.15
+** Last compiled against: [09/06/95 @ 10:20:58 AM (Wednesday)]
+** sendmail 8.7-b14 named 4.9.3-beta17 db-1.85
+** gcc 2.7.0 libc-5.2.7 linux 1.2.13
*/
#ifdef __linux__
@@ -620,12 +833,24 @@ extern void *malloc();
# define NEEDGETOPT 1 /* need a replacement for getopt(3) */
# define HASUNAME 1 /* use System V uname(2) system call */
# define HASUNSETENV 1 /* has unsetenv(3) call */
+# ifndef HASSNPRINTF
+# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */
+# endif
# define ERRLIST_PREDEFINED /* don't declare sys_errlist */
# define GIDSET_T gid_t /* from <linux/types.h> */
+# define HASGETUSERSHELL 0 /* getusershell(3) broken in Slackware 2.0 */
+# define IP_SRCROUTE 0 /* linux <= 1.2.8 doesn't support IP_OPTIONS */
+# ifndef HASFLOCK
+# define HASFLOCK 0 /* flock(2) is broken after 0.99.13 */
+# endif
# ifndef LA_TYPE
# define LA_TYPE LA_PROCSTR
# endif
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() impl */
+# ifndef _PATH_SENDMAILPID
+# define _PATH_SENDMAILPID "/var/run/sendmail.pid"
+# endif
+# define TZ_TYPE TZ_TNAME
# include <sys/sysmacros.h>
# undef atol /* wounded in <stdlib.h> */
#endif
@@ -656,20 +881,28 @@ extern void *malloc();
#ifdef _AUX_SOURCE
# include <sys/sysmacros.h>
# define BSD /* has BSD routines */
+# define HASSETRLIMIT 0 /* ... but not setrlimit(2) */
+# define BROKEN_RES_SEARCH 1 /* res_search(unknown) returns h_errno=0 */
# define HASUNAME 1 /* use System V uname(2) system call */
+# define HASFCHMOD 1 /* has fchmod(2) syscall */
+# define HASINITGROUPS 1 /* has initgroups(3) call */
# define HASSETVBUF 1 /* we have setvbuf(3) in libc */
# define SIGFUNC_DEFINED /* sigfunc_t already defined */
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
# endif
# define FORK fork
-# ifndef _PATH_SENDMAILCF
-# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
-# endif
# ifndef LA_TYPE
-# define LA_TYPE LA_ZERO
+# define LA_TYPE LA_INT
+# define FSHIFT 16
# endif
+# define LA_AVENRUN "avenrun"
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
+# define TZ_TYPE TZ_TZNAME
+# ifndef _PATH_UNIX
+# define _PATH_UNIX "/unix" /* should be in <paths.h> */
+# endif
+# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
# undef WIFEXITED
# undef WEXITSTATUS
#endif
@@ -682,7 +915,6 @@ extern void *malloc();
*/
#ifdef UMAXV
-# include <limits.h>
# define HASUNAME 1 /* use System V uname(2) system call */
# define HASSETVBUF 1 /* we have setvbuf(3) in libc */
# define HASINITGROUPS 1 /* has initgroups(3) call */
@@ -749,11 +981,9 @@ typedef int pid_t;
# endif
# ifndef _PATH_UNIX
-# define _PATH_UNIX "/dynix"
-# endif
-# ifndef _PATH_SENDMAILCF
-# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
+# define _PATH_UNIX "/dynix"
# endif
+# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
#endif
@@ -775,13 +1005,11 @@ typedef int pid_t;
# define GIDSET_T gid_t
# define LA_TYPE LA_INT
# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */
-# undef SETPROCTITLE
+# define SPT_TYPE SPT_NONE /* don't use setproctitle */
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
# endif
-# ifndef _PATH_SENDMAILCF
-# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
-# endif
+# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/sendmail.pid"
# endif
@@ -800,6 +1028,7 @@ typedef int pid_t;
# define MAXPATHLEN PATHSIZE
# define LA_TYPE LA_ZERO
# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */
+# define SFS_BAVAIL f_bfree /* alternate field name */
#endif
@@ -808,19 +1037,20 @@ typedef int pid_t;
**
** From Todd Martin <tmartint@tus.ssi1.com> & Don Lewis <gdonl@gv.ssi1.com>
**
-** 15 Jan 1994
+** 15 Jan 1994; updated 2 Aug 1995
**
*/
#ifdef apollo
# define HASSETREUID 1 /* has setreuid(2) call */
# define HASINITGROUPS 1 /* has initgroups(2) call */
-# undef SETPROCTITLE
+# define IP_SRCROUTE 0 /* does not have <netinet/ip_var.h> */
+# define SPT_TYPE SPT_NONE /* don't use setproctitle */
# define LA_TYPE LA_SUBR /* use getloadavg.c */
# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */
-# ifndef _PATH_SENDMAILCF
-# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
-# endif
+# define SFS_BAVAIL f_bfree /* alternate field name */
+# define TZ_TYPE TZ_TZNAME
+# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/sendmail.pid"
# endif
@@ -834,26 +1064,37 @@ typedef int pid_t;
/*
-** UnixWare
+** UnixWare 2.x
+*/
+
+#ifdef UNIXWARE2
+# define UNIXWARE 1
+# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */
+#endif
+
+
+/*
+** UnixWare 1.1.2.
**
+** Updated by Petr Lampa <lampa@fee.vutbr.cz>.
** From Evan Champion <evanc@spatial.synapse.org>.
*/
#ifdef UNIXWARE
+# include <sys/mkdev.h>
# define SYSTEM5 1
-# ifndef HASGETUSERSHELL
-# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
-# endif
-# define GIDSET_T int
-# define SLEEP_T int
+# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# define HASSETREUID 1
+# define HASSETSID 1
+# define HASINITGROUPS 1
+# define GIDSET_T gid_t
+# define SLEEP_T unsigned
# define SFS_TYPE SFS_STATVFS
# define LA_TYPE LA_ZERO
# undef WIFEXITED
# undef WEXITSTATUS
# define _PATH_UNIX "/unix"
-# ifndef _PATH_SENDMAILCF
-# define _PATH_SENDMAILCF "/usr/ucblib/sendmail.cf"
-# endif
+# define _PATH_VENDOR_CF "/usr/ucblib/sendmail.cf"
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid"
# endif
@@ -883,24 +1124,257 @@ typedef int pid_t;
/*
** NCR 3000 Series (SysVr4)
**
-** From From: Kevin Darcy <kevin@tech.mis.cfc.com>.
+** From Kevin Darcy <kevin@tech.mis.cfc.com>.
*/
#ifdef NCR3000
+# include <sys/sockio.h>
# define __svr4__
+# define IP_SRCROUTE 0 /* Something is broken with getsockopt() */
# undef BSD
# define LA_AVENRUN "avenrun"
+# define SYSLOG_BUFSIZE 1024
+#endif
+
+
+/*
+** Tandem NonStop-UX SVR4
+**
+** From Rick McCarty <mccarty@mpd.tandem.com>.
+*/
+
+#ifdef NonStop_UX_BXX
+# define __svr4__
+#endif
+
+
+/*
+** Hitachi 3050R & 3050RX Workstations running HI-UX/WE2.
+**
+** Tested for 1.04 and 1.03
+** From Akihiro Hashimoto ("Hash") <hash@dominic.ipc.chiba-u.ac.jp>.
+*/
+
+#ifdef __H3050R
+# define SYSTEM5 1 /* include all the System V defines */
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define setreuid(r, e) setresuid(r, e, -1)
+# define LA_TYPE LA_FLOAT
+# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
+# define HASSETVBUF /* HI-UX has no setlinebuf */
+# ifndef GIDSET_T
+# define GIDSET_T gid_t
+# endif
+# ifndef _PATH_UNIX
+# define _PATH_UNIX "/HI-UX"
+# endif
+# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
+# ifndef IDENTPROTO
+# define IDENTPROTO 0 /* TCP/IP implementation is broken */
+# endif
+# ifndef HASGETUSERSHELL
+# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */
+# endif
+
+/* avoid m_flags conflict between db.h & sys/sysmacros.h on HIUX 3050 */
+# undef m_flags
+
+# ifdef __STDC__
+extern int syslog(int, char *, ...);
+# endif
+
+#endif
+
+
+/*
+** Amdahl UTS System V 2.1.5 (SVr3-based)
+**
+** From: Janet Jackson <janet@dialix.oz.au>.
+*/
+
+#ifdef _UTS
+# include <sys/sysmacros.h>
+# undef HASLSTAT /* has symlinks, but they cause problems */
+# define NEEDFSYNC 1 /* system fsync(2) fails on non-EFS filesys */
+# define SYS5SIGNALS 1 /* System V signal semantics */
+# define SYS5SETPGRP 1 /* use System V setpgrp(2) syscall */
+# define HASUNAME 1 /* use System V uname(2) system call */
+# define HASINITGROUPS 1 /* has initgroups(3) function */
+# define HASSETVBUF 1 /* has setvbuf(3) function */
+# define HASSIGSETMASK 0 /* does not have sigsetmask(2) function */
+# ifndef HASGETUSERSHELL
+# define HASGETUSERSHELL 0 /* does not have getusershell(3) function */
+# endif
+# define GIDSET_T gid_t /* type of 2nd arg to getgroups(2) isn't int */
+# define LA_TYPE LA_ZERO /* doesn't have load average */
+# define SFS_TYPE SFS_4ARGS /* use 4-arg statfs() */
+# define SFS_BAVAIL f_bfree /* alternate field name */
+# define _PATH_UNIX "/unix"
+# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
+#endif
+
+/*
+** Cray Computer Corporation's CSOS
+**
+** From Scott Bolte <scott@craycos.com>.
+*/
+
+#ifdef _CRAYCOM
+# define SYSTEM5 1 /* include all the System V defines */
+# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
+# define NEEDFSYNC 1 /* no fsync in system library */
+# define MAXPATHLEN PATHSIZE
+# define LA_TYPE LA_ZERO
+# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */
+# define SFS_BAVAIL f_bfree /* alternate field name */
+# define _POSIX_CHOWN_RESTRICTED -1
+extern struct group *getgrent(), *getgrnam(), *getgrgid();
+#endif
+
+
+/*
+** Sony NEWS-OS 4.2.1R and 6.0.3
+**
+** From Motonori NAKAMURA <motonori@cs.ritsumei.ac.jp>.
+*/
+
+#ifdef sony_news
+# ifndef __svr4
+ /* NEWS-OS 4.2.1R */
+# ifndef BSD
+# define BSD /* has BSD routines */
+# endif
+# define HASUNSETENV 1 /* has unsetenv(2) call */
+# undef HASSETVBUF /* don't actually have setvbuf(3) */
+# define WAITUNION 1 /* use "union wait" as wait argument type */
+# define LA_TYPE LA_INT
+# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
+# ifndef HASFLOCK
+# define HASFLOCK 1 /* has flock(2) call */
+# endif
+# define setpgid setpgrp
+# undef WIFEXITED
+# undef WEXITSTATUS
+typedef int pid_t;
+typedef int (*sigfunc_t)();
+# define SIGFUNC_DEFINED
+
+# else
+ /* NEWS-OS 6.0.3 with /bin/cc */
+# ifndef __svr4__
+# define __svr4__ /* use all System V Releae 4 defines below */
+# endif
+# define HASSETSID 1 /* has Posix setsid(2) call */
+# define HASGETUSERSHELL 1 /* DOES have getusershell(3) call in libc */
+# define LA_TYPE LA_READKSYM /* use MIOC_READKSYM ioctl */
+# ifndef SPT_TYPE
+# define SPT_TYPE SPT_SYSMIPS /* use sysmips() (OS 6.0.2 or later) */
+# endif
+# define GIDSET_T gid_t
+# undef WIFEXITED
+# undef WEXITSTATUS
+# ifndef SYSLOG_BUFSIZE
+# define SYSLOG_BUFSIZE 1024
+# endif
+# define _PATH_UNIX "/stand/unix"
+# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf"
+# ifndef _PATH_SENDMAILPID
+# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid"
+# endif
+
+# endif
+#endif
+
+
+/*
+** Omron LUNA/UNIOS-B 3.0, LUNA2/Mach and LUNA88K Mach
+**
+** From Motonori NAKAMURA <motonori@cs.ritsumei.ac.jp>.
+*/
+
+#ifdef luna
+# ifndef IDENTPROTO
+# define IDENTPROTO 0 /* TCP/IP implementation is broken */
+# endif
+# define HASUNSETENV 1 /* has unsetenv(2) call */
+# define NEEDPUTENV 1 /* need putenv(3) call */
+# define NEEDGETOPT 1 /* need a replacement for getopt(3) */
+# define NEEDSTRSTR 1 /* need emulation of the strstr(3) call */
+# define WAITUNION 1 /* use "union wait" as wait argument type */
+# ifdef uniosb
+# include <sys/time.h>
+# define NEEDVPRINTF 1 /* need a replacement for vprintf(3) */
+# define LA_TYPE LA_INT
+# define TZ_TYPE TZ_TM_ZONE /* use tm->tm_zone */
+# endif
+# ifdef luna2
+# define LA_TYPE LA_SUBR
+# define TZ_TYPE TZ_TM_ZONE /* use tm->tm_zone */
+# endif
+# ifdef luna88k
+# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */
+# define LA_TYPE LA_INT
+# endif
+# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
+# define setpgid setpgrp
+# undef WIFEXITED
+# undef WEXITSTATUS
+typedef int pid_t;
+typedef int (*sigfunc_t)();
+# define SIGFUNC_DEFINED
+extern char *getenv();
+extern int errno;
+# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
+#endif
+
+
+/*
+** NEC EWS-UX/V 4.2 (with /usr/ucb/cc)
+**
+** From Motonori NAKAMURA <motonori@cs.ritsumei.ac.jp>.
+*/
+
+#if defined(nec_ews_svr4) || defined(_nec_ews_svr4)
+# ifndef __svr4__
+# define __svr4__ /* use all System V Releae 4 defines below */
+# endif
+# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
+# define HASSETSID 1 /* has Posix setsid(2) call */
+# define LA_TYPE LA_READKSYM /* use MIOC_READSYM ioctl */
+# define SFS_TYPE SFS_USTAT /* use System V ustat(2) syscall */
+# define GIDSET_T gid_t
+# undef WIFEXITED
+# undef WEXITSTATUS
+# define NAMELISTMASK 0x7fffffff /* mask for nlist() values */
+# ifndef SYSLOG_BUFSIZE
+# define SYSLOG_BUFSIZE 1024 /* allow full size syslog buffer */
+# endif
#endif
+/*
+** Fujitsu/ICL UXP/DS (For the DS/90 Series)
+**
+** From Diego R. Lopez <drlopez@cica.es>.
+*/
+
+#ifdef UXPDS
+# define __svr4__
+# define HASGETUSERSHELL 1
+# define HASFLOCK 0
+# define _PATH_UNIX "/stand/unix"
+# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf"
+# ifndef _PATH_SENDMAILPID
+# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid"
+# endif
+#endif
/**********************************************************************
** End of Per-Operating System defines
**********************************************************************/
-
-/**********************************************************************
+ /**********************************************************************
** More general defines
**********************************************************************/
@@ -908,26 +1382,39 @@ typedef int pid_t;
#ifdef BSD
# define HASGETDTABLESIZE 1 /* has getdtablesize(2) call */
# define HASSETREUID 1 /* has setreuid(2) call */
-# define HASINITGROUPS 1 /* has initgroups(2) call */
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# ifndef IP_SRCROUTE
+# define IP_SRCROUTE 1 /* can check IP source routing */
+# endif
+# ifndef HASSETRLIMIT
+# define HASSETRLIMIT 1 /* has setrlimit(2) call */
+# endif
# ifndef HASFLOCK
# define HASFLOCK 1 /* has flock(2) call */
# endif
+# ifndef TZ_TYPE
+# define TZ_TYPE TZ_TM_ZONE /* use tm->tm_zone variable */
+# endif
#endif
/* general System V Release 4 defines */
#ifdef __svr4__
# define SYSTEM5 1
-# define HASSETREUID 1 /* has seteuid(2) call & working saved uids */
+# define USESETEUID 1 /* has useable seteuid(2) call */
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define BSD_COMP 1 /* get BSD ioctl calls */
+# ifndef HASSETRLIMIT
+# define HASSETRLIMIT 1 /* has setrlimit(2) call */
+# endif
# ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
# endif
-# define setreuid(r, e) seteuid(e)
# ifndef _PATH_UNIX
# define _PATH_UNIX "/unix"
# endif
-# ifndef _PATH_SENDMAILCF
-# define _PATH_SENDMAILCF "/usr/ucblib/sendmail.cf"
+# ifndef _PATH_VENDOR_CF
+# define _PATH_VENDOR_CF "/usr/ucblib/sendmail.cf"
# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid"
@@ -935,6 +1422,13 @@ typedef int pid_t;
# ifndef SYSLOG_BUFSIZE
# define SYSLOG_BUFSIZE 128
# endif
+# ifndef SFS_TYPE
+# define SFS_TYPE SFS_STATVFS
+# endif
+
+# define jmp_buf sigjmp_buf
+# define setjmp(env) sigsetjmp(env, 1)
+# define longjmp(env, val) siglongjmp(env, val)
#endif
/* general System V defines */
@@ -943,12 +1437,22 @@ typedef int pid_t;
# define HASUNAME 1 /* use System V uname(2) system call */
# define SYS5SETPGRP 1 /* use System V setpgrp(2) syscall */
# define HASSETVBUF 1 /* we have setvbuf(3) in libc */
+# ifndef HASULIMIT
+# define HASULIMIT 1 /* has the ulimit(2) syscall */
+# endif
# ifndef LA_TYPE
-# define LA_TYPE LA_INT /* assume integer load average */
+# ifdef MIOC_READKSYM
+# define LA_TYPE LA_READKSYM /* use MIOC_READKSYM ioctl */
+# else
+# define LA_TYPE LA_INT /* assume integer load average */
+# endif
# endif
# ifndef SFS_TYPE
# define SFS_TYPE SFS_USTAT /* use System V ustat(2) syscall */
# endif
+# ifndef TZ_TYPE
+# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */
+# endif
# define bcopy(s, d, l) (memmove((d), (s), (l)))
# define bzero(d, l) (memset((d), '\0', (l)))
# define bcmp(s, d, l) (memcmp((s), (d), (l)))
@@ -958,25 +1462,31 @@ typedef int pid_t;
#ifdef _POSIX_VERSION
# define HASSETSID 1 /* has Posix setsid(2) call */
# define HASWAITPID 1 /* has Posix waitpid(2) call */
+# if _POSIX_VERSION >= 199500 && !defined(USESETEUID)
+# define USESETEUID 1 /* has useable seteuid(2) call */
+# endif
#endif
-
-/*
-** If no type for argument two of getgroups call is defined, assume
-** it's an integer -- unfortunately, there seem to be several choices
-** here.
+ /*
+** Tweaking for systems that (for example) claim to be BSD or POSIX
+** but don't have all the standard BSD or POSIX routines (boo hiss).
*/
-#ifndef GIDSET_T
-# define GIDSET_T int
+#ifdef titan
+# undef HASINITGROUPS /* doesn't have initgroups(3) call */
#endif
-/*
-** Tweaking for systems that (for example) claim to be BSD but
-** don't have all the standard BSD routines (boo hiss).
-*/
+#ifdef _CRAYCOM
+# undef HASSETSID /* despite POSIX claim, doesn't have setsid */
+#endif
-#ifdef titan
-# undef HASINITGROUPS /* doesn't have initgroups(3) call */
+#ifdef ISC_UNIX
+# undef bcopy /* despite SystemV claim, uses BSD bcopy */
+#endif
+
+#ifdef ALTOS_SYS_V
+# undef bcopy /* despite SystemV claim, uses BSD bcopy */
+# undef bzero /* despite SystemV claim, uses BSD bzero */
+# undef bcmp /* despite SystemV claim, uses BSD bcmp */
#endif
@@ -995,20 +1505,77 @@ typedef int pid_t;
# define IDENTPROTO 1 /* use IDENT proto (RFC 1413) */
#endif
+#ifndef IP_SRCROUTE
+# define IP_SRCROUTE 1 /* Detect IP source routing */
+#endif
+
#ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 1 /* libc has getusershell(3) call */
#endif
+#ifndef NETUNIX
+# define NETUNIX 1 /* include unix domain support */
+#endif
+
#ifndef HASFLOCK
# define HASFLOCK 0 /* assume no flock(2) support */
#endif
+#ifndef HASSETREUID
+# define HASSETREUID 0 /* assume no setreuid(2) call */
+#endif
+
+#ifndef HASFCHMOD
+# define HASFCHMOD 0 /* assume no fchmod(2) syscall */
+#endif
+
+#ifndef USESETEUID
+# define USESETEUID 0 /* assume no seteuid(2) call or no saved ids */
+#endif
+
+#ifndef HASSETRLIMIT
+# define HASSETRLIMIT 0 /* assume no setrlimit(2) support */
+#endif
+
+#ifndef HASULIMIT
+# define HASULIMIT 0 /* assume no ulimit(2) support */
+#endif
+
#ifndef OLD_NEWDB
# define OLD_NEWDB 0 /* assume newer version of newdb */
#endif
+/* heuristic setting of HASSETSIGMASK; can override above */
+#ifndef HASSIGSETMASK
+# ifdef SIGVTALRM
+# define HASSETSIGMASK 1
+# else
+# define HASSETSIGMASK 0
+# endif
+#endif
+
+/*
+** If no type for argument two of getgroups call is defined, assume
+** it's an integer -- unfortunately, there seem to be several choices
+** here.
+*/
-/**********************************************************************
+#ifndef GIDSET_T
+# define GIDSET_T int
+#endif
+
+#ifndef UID_T
+# define UID_T uid_t
+#endif
+
+#ifndef SIZE_T
+# define SIZE_T size_t
+#endif
+
+#ifndef ARGV_T
+# define ARGV_T char **
+#endif
+ /**********************************************************************
** Remaining definitions should never have to be changed. They are
** primarily to provide back compatibility for older systems -- for
** example, it includes some POSIX compatibility definitions
@@ -1021,11 +1588,14 @@ typedef int pid_t;
#if !defined(S_ISLNK) && defined(S_IFLNK)
# define S_ISLNK(foo) ((foo & S_IFMT) == S_IFLNK)
#endif
+#ifndef S_IWUSR
+# define S_IWUSR 0200
+#endif
#ifndef S_IWGRP
-#define S_IWGRP 020
+# define S_IWGRP 0020
#endif
#ifndef S_IWOTH
-#define S_IWOTH 002
+# define S_IWOTH 0002
#endif
/*
@@ -1063,11 +1633,45 @@ typedef int pid_t;
# include "cdefs.h"
#endif
+#if NAMED_BIND
+# include <arpa/nameser.h>
+# ifdef __svr4__
+# ifdef NOERROR
+# undef NOERROR /* avoid compiler conflict with stream.h */
+# endif
+# endif
+# ifndef __ksr__
+extern int h_errno;
+# endif
+#endif
+
+/*
+** The size of an IP address -- can't use sizeof because of problems
+** on Crays, where everything is 64 bits. This will break if/when
+** IP addresses are expanded to eight bytes.
+*/
+
+#ifndef INADDRSZ
+# define INADDRSZ 4
+#endif
+
+/*
+** The size of various known types -- for reading network protocols.
+** Again, we can't use sizeof because of compiler randomness.
+*/
+
+#ifndef INT16SZ
+# define INT16SZ 2
+#endif
+#ifndef INT32SZ
+# define INT32SZ 4
+#endif
+
/*
** Do some required dependencies
*/
-#if defined(NETINET) || defined(NETISO)
+#if NETINET || NETISO
# define SMTP 1 /* enable user and server SMTP */
# define QUEUE 1 /* enable queueing */
# define DAEMON 1 /* include the daemon (requires IPC & SMTP) */
@@ -1109,7 +1713,7 @@ struct utsname
};
#endif /* HASUNAME */
-#if !defined(MAXHOSTNAMELEN) && !defined(_SCO_unix_)
+#if !defined(MAXHOSTNAMELEN) && !defined(_SCO_unix_) && !defined(NonStop_UX_BXX) && !defined(ALTOS_SYS_V)
# define MAXHOSTNAMELEN 256
#endif
@@ -1118,15 +1722,15 @@ struct utsname
#endif
#ifndef STDIN_FILENO
-#define STDIN_FILENO 0
+# define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
-#define STDOUT_FILENO 1
+# define STDOUT_FILENO 1
#endif
#ifndef STDERR_FILENO
-#define STDERR_FILENO 2
+# define STDERR_FILENO 2
#endif
#ifndef LOCK_SH
@@ -1136,6 +1740,12 @@ struct utsname
# define LOCK_UN 0x08 /* unlock */
#endif
+#ifndef SEEK_SET
+# define SEEK_SET 0
+# define SEEK_CUR 1
+# define SEEK_END 2
+#endif
+
#ifndef SIG_ERR
# define SIG_ERR ((void (*)()) -1)
#endif
@@ -1163,13 +1773,19 @@ typedef void (*sigfunc_t) __P((int));
*/
#ifndef TOBUFSIZE
-# if (SYSLOG_BUFSIZE) > 512
-# define TOBUFSIZE (SYSLOG_BUFSIZE - 256)
+# if (SYSLOG_BUFSIZE) > 768
+# define TOBUFSIZE (SYSLOG_BUFSIZE - 512)
# else
# define TOBUFSIZE 256
# endif
#endif
+/* TOBUFSIZE must never be permitted to exceed MAXLINE - 128 */
+#if TOBUFSIZE > (MAXLINE - 128)
+# undef TOBUFSIZE
+# define TOBUFSIZE (MAXLINE - 128)
+#endif
+
/*
** Size of prescan buffer.
** Despite comments in the _sendmail_ book, this probably should
@@ -1183,9 +1799,9 @@ typedef void (*sigfunc_t) __P((int));
# endif
/*
-** If we are going to link scanf anyway, use it in readcf
+** Default to using scanf in readcf.
*/
-#if !defined(HASUNAME) && !defined(SCANF)
+#ifndef SCANF
# define SCANF 1
#endif
diff --git a/usr.sbin/sendmail/src/daemon.c b/usr.sbin/sendmail/src/daemon.c
index b4b4e8b..c2f5327 100644
--- a/usr.sbin/sendmail/src/daemon.c
+++ b/usr.sbin/sendmail/src/daemon.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -37,20 +37,27 @@
#ifndef lint
#ifdef DAEMON
-static char sccsid[] = "@(#)daemon.c 8.48.1.5 (Berkeley) 3/28/95 (with daemon mode)";
+static char sccsid[] = "@(#)daemon.c 8.118 (Berkeley) 10/8/95 (with daemon mode)";
#else
-static char sccsid[] = "@(#)daemon.c 8.48.1.5 (Berkeley) 3/28/95 (without daemon mode)";
+static char sccsid[] = "@(#)daemon.c 8.118 (Berkeley) 10/8/95 (without daemon mode)";
#endif
#endif /* not lint */
#ifdef DAEMON
-# include <netdb.h>
# include <arpa/inet.h>
#if NAMED_BIND
-# include <arpa/nameser.h>
# include <resolv.h>
+# ifndef NO_DATA
+# define NO_DATA NO_ADDRESS
+# endif
+#endif
+
+#if IP_SRCROUTE
+# include <netinet/in_systm.h>
+# include <netinet/ip.h>
+# include <netinet/ip_var.h>
#endif
/*
@@ -106,13 +113,14 @@ int ListenQueueSize = 10; /* size of listen queue */
int TcpRcvBufferSize = 0; /* size of TCP receive buffer */
int TcpSndBufferSize = 0; /* size of TCP send buffer */
+void
getrequests()
{
int t;
bool refusingconnections = TRUE;
FILE *pidf;
int socksize;
-#ifdef XDEBUG
+#if XDEBUG
bool j_has_dot;
#endif
extern void reapchild();
@@ -167,11 +175,11 @@ getrequests()
fclose(pidf);
}
-#ifdef XDEBUG
+#if XDEBUG
{
char jbuf[MAXHOSTNAMELEN];
- expand("\201j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
+ expand("\201j", jbuf, sizeof jbuf, CurEnv);
j_has_dot = strchr(jbuf, '.') != NULL;
}
#endif
@@ -184,6 +192,7 @@ getrequests()
register int pid;
auto int lotherend;
extern bool refuseconnections();
+ extern int getla();
/* see if we are rejecting connections */
CurrentLA = getla();
@@ -196,29 +205,24 @@ getrequests()
DaemonSocket = -1;
}
refusingconnections = TRUE;
- setproctitle("rejecting connections: load average: %d",
- CurrentLA);
sleep(15);
continue;
}
+ /* arrange to (re)open the socket if necessary */
if (refusingconnections)
{
- /* start listening again */
(void) opendaemonsocket(FALSE);
- setproctitle("accepting connections");
refusingconnections = FALSE;
}
-#ifdef XDEBUG
+#if XDEBUG
/* check for disaster */
{
- register STAB *s;
char jbuf[MAXHOSTNAMELEN];
- expand("\201j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
- if ((s = stab(jbuf, ST_CLASS, ST_FIND)) == NULL ||
- !bitnset('w', s->s_class))
+ expand("\201j", jbuf, sizeof jbuf, CurEnv);
+ if (!wordinclass(jbuf, 'w'))
{
dumpstate("daemon lost $j");
syslog(LOG_ALERT, "daemon process doesn't have $j in $=w; see syslog");
@@ -234,6 +238,7 @@ getrequests()
#endif
/* wait for a connection */
+ setproctitle("accepting connections");
do
{
errno = 0;
@@ -244,6 +249,11 @@ getrequests()
if (t < 0)
{
syserr("getrequests: accept");
+
+ /* arrange to re-open the socket next time around */
+ (void) close(DaemonSocket);
+ DaemonSocket = -1;
+ refusingconnections = TRUE;
sleep(5);
continue;
}
@@ -268,6 +278,8 @@ getrequests()
{
char *p;
extern char *hostnamebyanyaddr();
+ extern void intsig();
+ FILE *inchannel, *outchannel;
/*
** CHILD -- return to caller.
@@ -276,34 +288,31 @@ getrequests()
*/
(void) setsignal(SIGCHLD, SIG_DFL);
- DisConnected = FALSE;
+ (void) setsignal(SIGHUP, intsig);
+ (void) close(DaemonSocket);
setproctitle("startup with %s",
anynet_ntoa(&RealHostAddr));
/* determine host name */
p = hostnamebyanyaddr(&RealHostAddr);
+ if (strlen(p) > MAXNAME)
+ p[MAXNAME] = '\0';
RealHostName = newstr(p);
setproctitle("startup with %s", p);
-#ifdef LOG
- if (LogLevel > 11)
- {
- /* log connection information */
- syslog(LOG_INFO, "connect from %s (%s)",
- RealHostName, anynet_ntoa(&RealHostAddr));
- }
-#endif
-
- (void) close(DaemonSocket);
- if ((InChannel = fdopen(t, "r")) == NULL ||
+ if ((inchannel = fdopen(t, "r")) == NULL ||
(t = dup(t)) < 0 ||
- (OutChannel = fdopen(t, "w")) == NULL)
+ (outchannel = fdopen(t, "w")) == NULL)
{
syserr("cannot open SMTP server channel, fd=%d", t);
exit(0);
}
+ InChannel = inchannel;
+ OutChannel = outchannel;
+ DisConnected = FALSE;
+
/* should we check for illegal connection here? XXX */
#ifdef XLA
if (!xla_host_ok(RealHostName))
@@ -318,6 +327,8 @@ getrequests()
return;
}
+ CurChildren++;
+
/* close the port so that others will hang (for a while) */
(void) close(t);
}
@@ -347,7 +358,7 @@ opendaemonsocket(firsttime)
bool firsttime;
{
int on = 1;
- int socksize;
+ int socksize = 0;
int ntries = 0;
int saveerrno;
@@ -363,7 +374,6 @@ opendaemonsocket(firsttime)
DaemonSocket = socket(DaemonAddr.sa.sa_family, SOCK_STREAM, 0);
if (DaemonSocket < 0)
{
- /* probably another daemon already */
saveerrno = errno;
syserr("opendaemonsocket: can't create server SMTP socket");
severe:
@@ -393,19 +403,19 @@ opendaemonsocket(firsttime)
SO_RCVBUF,
(char *) &TcpRcvBufferSize,
sizeof(TcpRcvBufferSize)) < 0)
- syserr("getrequests: setsockopt(SO_RCVBUF)");
+ syserr("opendaemonsocket: setsockopt(SO_RCVBUF)");
}
#endif
switch (DaemonAddr.sa.sa_family)
{
-# ifdef NETINET
+# if NETINET
case AF_INET:
socksize = sizeof DaemonAddr.sin;
break;
# endif
-# ifdef NETISO
+# if NETISO
case AF_ISO:
socksize = sizeof DaemonAddr.siso;
break;
@@ -418,8 +428,9 @@ opendaemonsocket(firsttime)
if (bind(DaemonSocket, &DaemonAddr.sa, socksize) < 0)
{
+ /* probably another daemon already */
saveerrno = errno;
- syserr("getrequests: cannot bind");
+ syserr("opendaemonsocket: cannot bind");
(void) close(DaemonSocket);
goto severe;
}
@@ -427,12 +438,13 @@ opendaemonsocket(firsttime)
if (!firsttime && listen(DaemonSocket, ListenQueueSize) < 0)
{
saveerrno = errno;
- syserr("getrequests: cannot listen");
+ syserr("opendaemonsocket: cannot listen");
(void) close(DaemonSocket);
goto severe;
}
return socksize;
} while (ntries++ < MAXOPENTRIES && transienterror(saveerrno));
+ syserr("!opendaemonsocket: server SMTP socket wedged: exiting");
finis();
}
/*
@@ -448,6 +460,7 @@ opendaemonsocket(firsttime)
** releases any resources used by the passive daemon.
*/
+void
clrdaemon()
{
if (DaemonSocket >= 0)
@@ -464,6 +477,7 @@ clrdaemon()
** none.
*/
+void
setdaemonoptions(p)
register char *p;
{
@@ -488,25 +502,27 @@ setdaemonoptions(p)
continue;
while (isascii(*++v) && isspace(*v))
continue;
+ if (isascii(*f) && islower(*f))
+ *f = toupper(*f);
switch (*f)
{
case 'F': /* address family */
if (isascii(*v) && isdigit(*v))
DaemonAddr.sa.sa_family = atoi(v);
-#ifdef NETINET
+#if NETINET
else if (strcasecmp(v, "inet") == 0)
DaemonAddr.sa.sa_family = AF_INET;
#endif
-#ifdef NETISO
+#if NETISO
else if (strcasecmp(v, "iso") == 0)
DaemonAddr.sa.sa_family = AF_ISO;
#endif
-#ifdef NETNS
+#if NETNS
else if (strcasecmp(v, "ns") == 0)
DaemonAddr.sa.sa_family = AF_NS;
#endif
-#ifdef NETX25
+#if NETX25
else if (strcasecmp(v, "x.25") == 0)
DaemonAddr.sa.sa_family = AF_CCITT;
#endif
@@ -517,10 +533,10 @@ setdaemonoptions(p)
case 'A': /* address */
switch (DaemonAddr.sa.sa_family)
{
-#ifdef NETINET
+#if NETINET
case AF_INET:
if (isascii(*v) && isdigit(*v))
- DaemonAddr.sin.sin_addr.s_addr = inet_network(v);
+ DaemonAddr.sin.sin_addr.s_addr = htonl(inet_network(v));
else
{
register struct netent *np;
@@ -546,7 +562,7 @@ setdaemonoptions(p)
{
short port;
-#ifdef NETINET
+#if NETINET
case AF_INET:
if (isascii(*v) && isdigit(*v))
DaemonAddr.sin.sin_port = htons(atoi(v));
@@ -563,7 +579,7 @@ setdaemonoptions(p)
break;
#endif
-#ifdef NETISO
+#if NETISO
case AF_ISO:
/* assume two byte transport selector */
if (isascii(*v) && isdigit(*v))
@@ -600,6 +616,9 @@ setdaemonoptions(p)
case 'R': /* receive buffer size */
TcpRcvBufferSize = atoi(v);
break;
+
+ default:
+ syserr("554 DaemonPortOptions parameter \"%s\" unknown", f);
}
}
}
@@ -622,6 +641,15 @@ setdaemonoptions(p)
** none.
*/
+static jmp_buf CtxConnectTimeout;
+
+static void
+connecttimeout()
+{
+ errno = ETIMEDOUT;
+ longjmp(CtxConnectTimeout, 1);
+}
+
SOCKADDR CurHostAddr; /* address of current host */
int
@@ -631,14 +659,14 @@ makeconnection(host, port, mci, usesecureport)
register MCI *mci;
bool usesecureport;
{
- register int i, s;
+ register int i = 0;
+ register int s;
register struct hostent *hp = (struct hostent *)NULL;
SOCKADDR addr;
int sav_errno;
int addrlen;
-#if NAMED_BIND
- extern int h_errno;
-#endif
+ bool firstconnect;
+ EVENT *ev;
/*
** Set up the address for the mailer.
@@ -661,18 +689,26 @@ makeconnection(host, port, mci, usesecureport)
if (p != NULL)
{
*p = '\0';
-#ifdef NETINET
+#if NETINET
hid = inet_addr(&host[1]);
if (hid == -1)
#endif
{
/* try it as a host name (avoid MX lookup) */
- hp = gethostbyname(&host[1]);
+ hp = sm_gethostbyname(&host[1]);
if (hp == NULL && p[-1] == '.')
{
+#if NAMED_BIND
+ int oldopts = _res.options;
+
+ _res.options &= ~(RES_DEFNAMES|RES_DNSRCH);
+#endif
p[-1] = '\0';
- hp = gethostbyname(&host[1]);
+ hp = sm_gethostbyname(&host[1]);
p[-1] = '.';
+#if NAMED_BIND
+ _res.options = oldopts;
+#endif
}
*p = ']';
goto gothostent;
@@ -682,9 +718,10 @@ makeconnection(host, port, mci, usesecureport)
if (p == NULL)
{
usrerr("553 Invalid numeric domain spec \"%s\"", host);
+ mci->mci_status = "5.1.2";
return (EX_NOHOST);
}
-#ifdef NETINET
+#if NETINET
addr.sin.sin_family = AF_INET; /*XXX*/
addr.sin.sin_addr.s_addr = hid;
#endif
@@ -693,34 +730,43 @@ makeconnection(host, port, mci, usesecureport)
{
register char *p = &host[strlen(host) - 1];
- hp = gethostbyname(host);
+ hp = sm_gethostbyname(host);
if (hp == NULL && *p == '.')
{
+#if NAMED_BIND
+ int oldopts = _res.options;
+
+ _res.options &= ~(RES_DEFNAMES|RES_DNSRCH);
+#endif
*p = '\0';
- hp = gethostbyname(host);
+ hp = sm_gethostbyname(host);
*p = '.';
+#if NAMED_BIND
+ _res.options = oldopts;
+#endif
}
gothostent:
if (hp == NULL)
{
#if NAMED_BIND
- if (errno == ETIMEDOUT || h_errno == TRY_AGAIN)
- return (EX_TEMPFAIL);
-
- /* if name server is specified, assume temp fail */
- if (errno == ECONNREFUSED && UseNameServer)
+ /* check for name server timeouts */
+ if (errno == ETIMEDOUT || h_errno == TRY_AGAIN ||
+ (errno == ECONNREFUSED && UseNameServer))
+ {
+ mci->mci_status = "4.4.3";
return (EX_TEMPFAIL);
+ }
#endif
return (EX_NOHOST);
}
addr.sa.sa_family = hp->h_addrtype;
switch (hp->h_addrtype)
{
-#ifdef NETINET
+#if NETINET
case AF_INET:
bcopy(hp->h_addr,
&addr.sin.sin_addr,
- sizeof addr.sin.sin_addr);
+ INADDRSZ);
break;
#endif
@@ -737,15 +783,16 @@ gothostent:
** Determine the port number.
*/
- if (port != 0)
- port = htons(port);
- else
+ if (port == 0)
{
register struct servent *sp = getservbyname("smtp", "tcp");
if (sp == NULL)
{
- syserr("554 makeconnection: service \"smtp\" unknown");
+#ifdef LOG
+ if (LogLevel > 2)
+ syslog(LOG_ERR, "makeconnection: service \"smtp\" unknown");
+#endif
port = htons(25);
}
else
@@ -754,14 +801,14 @@ gothostent:
switch (addr.sa.sa_family)
{
-#ifdef NETINET
+#if NETINET
case AF_INET:
addr.sin.sin_port = port;
addrlen = sizeof (struct sockaddr_in);
break;
#endif
-#ifdef NETISO
+#if NETISO
case AF_ISO:
/* assume two byte transport selector */
bcopy((char *) &port, TSEL((struct sockaddr_iso *) &addr), 2);
@@ -784,6 +831,7 @@ gothostent:
return EX_TEMPFAIL;
#endif
+ firstconnect = TRUE;
for (;;)
{
if (tTd(16, 1))
@@ -806,7 +854,7 @@ gothostent:
if (s < 0)
{
sav_errno = errno;
- syserr("makeconnection: no socket");
+ syserr("makeconnection: cannot create socket");
goto failure;
}
@@ -833,24 +881,54 @@ gothostent:
if (CurEnv->e_xfp != NULL)
(void) fflush(CurEnv->e_xfp); /* for debugging */
errno = 0; /* for debugging */
- if (connect(s, (struct sockaddr *) &addr, addrlen) >= 0)
- break;
- /* couldn't connect.... figure out why */
+ /*
+ ** Linux seems to hang in connect for 90 minutes (!!!).
+ ** Time out the connect to avoid this problem.
+ */
+
+ if (setjmp(CtxConnectTimeout) == 0)
+ {
+ if (TimeOuts.to_connect == 0)
+ ev = NULL;
+ else
+ ev = setevent(TimeOuts.to_connect, connecttimeout, 0);
+ if (connect(s, (struct sockaddr *) &addr, addrlen) >= 0)
+ {
+ if (ev != NULL)
+ clrevent(ev);
+ break;
+ }
+ }
sav_errno = errno;
+ if (ev != NULL)
+ clrevent(ev);
+
+ /* if running demand-dialed connection, try again */
+ if (DialDelay > 0 && firstconnect)
+ {
+ if (tTd(16, 1))
+ printf("Connect failed (%s); trying again...\n",
+ errstring(sav_errno));
+ firstconnect = FALSE;
+ sleep(DialDelay);
+ continue;
+ }
+
+ /* couldn't connect.... figure out why */
(void) close(s);
- if (hp && hp->h_addr_list[i])
+ if (hp != NULL && hp->h_addr_list[i])
{
if (tTd(16, 1))
printf("Connect failed (%s); trying new address....\n",
errstring(sav_errno));
switch (addr.sa.sa_family)
{
-#ifdef NETINET
+#if NETINET
case AF_INET:
bcopy(hp->h_addr_list[i++],
&addr.sin.sin_addr,
- sizeof addr.sin.sin_addr);
+ INADDRSZ);
break;
#endif
@@ -902,61 +980,77 @@ gothostent:
** Adds numeric codes to $=w.
*/
-char **
+struct hostent *
myhostname(hostbuf, size)
char hostbuf[];
int size;
{
register struct hostent *hp;
- extern struct hostent *gethostbyname();
+ extern bool getcanonname();
if (gethostname(hostbuf, size) < 0)
{
(void) strcpy(hostbuf, "localhost");
}
- hp = gethostbyname(hostbuf);
+ hp = sm_gethostbyname(hostbuf);
if (hp == NULL)
+ return NULL;
+ if (strchr(hp->h_name, '.') != NULL || strchr(hostbuf, '.') == NULL)
{
- syserr("!My host name (%s) does not seem to exist!", hostbuf);
+ (void) strncpy(hostbuf, hp->h_name, size - 1);
+ hostbuf[size - 1] = '\0';
}
- (void) strncpy(hostbuf, hp->h_name, size - 1);
- hostbuf[size - 1] = '\0';
-#if NAMED_BIND
- /* if still no dot, try DNS directly (i.e., avoid NIS problems) */
+ /*
+ ** If there is still no dot in the name, try looking for a
+ ** dotted alias.
+ */
+
if (strchr(hostbuf, '.') == NULL)
{
- extern bool getcanonname();
- extern int h_errno;
+ char **ha;
- /* try twice in case name server not yet started up */
- if (!getcanonname(hostbuf, size, TRUE) &&
- UseNameServer &&
- (h_errno != TRY_AGAIN ||
- (sleep(30), !getcanonname(hostbuf, size, TRUE))))
+ for (ha = hp->h_aliases; *ha != NULL; ha++)
{
- errno = h_errno + E_DNSBASE;
- syserr("!My host name (%s) not known to DNS",
- hostbuf);
+ if (strchr(*ha, '.') != NULL)
+ {
+ (void) strncpy(hostbuf, *ha, size - 1);
+ hostbuf[size - 1] = '\0';
+ break;
+ }
}
}
-#endif
- if (hp->h_addrtype == AF_INET && hp->h_length == 4)
- {
- register int i;
+ /*
+ ** If _still_ no dot, wait for a while and try again -- it is
+ ** possible that some service is starting up. This can result
+ ** in excessive delays if the system is badly configured, but
+ ** there really isn't a way around that, particularly given that
+ ** the config file hasn't been read at this point.
+ ** All in all, a bit of a mess.
+ */
- for (i = 0; hp->h_addr_list[i] != NULL; i++)
+ if (strchr(hostbuf, '.') == NULL &&
+ !getcanonname(hostbuf, size, TRUE))
+ {
+#ifdef LOG
+ syslog(LOG_CRIT, "My unqualifed host name (%s) unknown; sleeping for retry",
+ hostbuf);
+#endif
+ message("My unqualifed host name (%s) unknown; sleeping for retry",
+ hostbuf);
+ sleep(60);
+ if (!getcanonname(hostbuf, size, TRUE))
{
- char ipbuf[100];
-
- sprintf(ipbuf, "[%s]",
- inet_ntoa(*((struct in_addr *) hp->h_addr_list[i])));
- setclass('w', ipbuf);
+#ifdef LOG
+ syslog(LOG_ALERT, "unable to qualify my own domain name (%s) -- using short name",
+ hostbuf);
+#endif
+ message("WARNING: unable to qualify my own domain name (%s) -- using short name",
+ hostbuf);
}
}
-
- return (hp->h_aliases);
+ return (hp);
}
/*
** GETAUTHINFO -- get the real host name asociated with a file descriptor
@@ -970,41 +1064,34 @@ myhostname(hostbuf, size)
** The user@host information associated with this descriptor.
*/
-#if IDENTPROTO
-
static jmp_buf CtxAuthTimeout;
-static
+static void
authtimeout()
{
longjmp(CtxAuthTimeout, 1);
}
-#endif
-
char *
getauthinfo(fd)
int fd;
{
int falen;
register char *p;
-#if IDENTPROTO
SOCKADDR la;
int lalen;
register struct servent *sp;
- int s;
+ volatile int s;
int i;
EVENT *ev;
int nleft;
char ibuf[MAXNAME + 1];
-#endif
static char hbuf[MAXNAME * 2 + 2];
extern char *hostnamebyanyaddr();
- extern char RealUserName[]; /* main.c */
falen = sizeof RealHostAddr;
- if (getpeername(fd, &RealHostAddr.sa, &falen) < 0 || falen <= 0 ||
- RealHostAddr.sa.sa_family == 0)
+ if (isatty(fd) || getpeername(fd, &RealHostAddr.sa, &falen) < 0 ||
+ falen <= 0 || RealHostAddr.sa.sa_family == 0)
{
(void) sprintf(hbuf, "%s@localhost", RealUserName);
if (tTd(9, 1))
@@ -1018,7 +1105,6 @@ getauthinfo(fd)
RealHostName = newstr(hostnamebyanyaddr(&RealHostAddr));
}
-#if IDENTPROTO
if (TimeOuts.to_ident == 0)
goto noident;
@@ -1120,6 +1206,14 @@ getauthinfo(fd)
}
/* p now points to the OSTYPE field */
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (strncasecmp(p, "other", 5) == 0 &&
+ (p[5] == ':' || p[5] == ' ' || p[5] == ',' || p[5] == '\0'))
+ {
+ /* not useful information */
+ goto noident;
+ }
p = strchr(p, ':');
if (p == NULL)
{
@@ -1136,14 +1230,12 @@ getauthinfo(fd)
i = strlen(hbuf);
hbuf[i++] = '@';
strcpy(&hbuf[i], RealHostName == NULL ? "localhost" : RealHostName);
- goto finish;
+ goto postident;
closeident:
(void) close(s);
clrevent(ev);
-#endif /* IDENTPROTO */
-
noident:
if (RealHostName == NULL)
{
@@ -1153,12 +1245,92 @@ noident:
}
(void) strcpy(hbuf, RealHostName);
-finish:
+postident:
+#if IP_SRCROUTE
+ /*
+ ** Extract IP source routing information.
+ **
+ ** Format of output for a connection from site a through b
+ ** through c to d:
+ ** loose: @site-c@site-b:site-a
+ ** strict: !@site-c@site-b:site-a
+ **
+ ** o - pointer within ipopt_list structure.
+ ** q - pointer within ls/ss rr route data
+ ** p - pointer to hbuf
+ */
+
+ if (RealHostAddr.sa.sa_family == AF_INET)
+ {
+ int ipoptlen, j;
+ u_char *q;
+ u_char *o;
+ struct in_addr addr;
+ struct ipoption ipopt;
+
+ ipoptlen = sizeof ipopt;
+ if (getsockopt(fd, IPPROTO_IP, IP_OPTIONS,
+ (char *) &ipopt, &ipoptlen) < 0)
+ goto noipsr;
+ if (ipoptlen == 0)
+ goto noipsr;
+ o = (u_char *) ipopt.ipopt_list;
+ while (o != NULL && o < (u_char *) &ipopt + ipoptlen)
+ {
+ switch (*o)
+ {
+ case IPOPT_EOL:
+ o = NULL;
+ break;
+
+ case IPOPT_NOP:
+ o++;
+ break;
+
+ case IPOPT_SSRR:
+ case IPOPT_LSRR:
+ p = &hbuf[strlen(hbuf)];
+ sprintf(p, " [%s@%.120s",
+ *o == IPOPT_SSRR ? "!" : "",
+ inet_ntoa(ipopt.ipopt_dst));
+ p += strlen(p);
+
+ /* o[1] is option length */
+ j = *++o / sizeof(struct in_addr) - 1;
+
+ /* q skips length and router pointer to data */
+ q = o + 2;
+ for ( ; j >= 0; j--)
+ {
+ memcpy(&addr, q, sizeof(addr));
+ sprintf(p, "%c%.120s",
+ j ? '@' : ':',
+ inet_ntoa(addr));
+ p += strlen(p);
+ q += sizeof(struct in_addr);
+ }
+ o += *o;
+ break;
+
+ default:
+ /* Skip over option */
+ o += o[1];
+ break;
+ }
+ }
+ strcat(hbuf,"]");
+ goto postipsr;
+ }
+#endif
+
+noipsr:
if (RealHostName != NULL && RealHostName[0] != '[')
{
p = &hbuf[strlen(hbuf)];
- (void) sprintf(p, " [%s]", anynet_ntoa(&RealHostAddr));
+ (void) sprintf(p, " [%.100s]", anynet_ntoa(&RealHostAddr));
}
+
+postipsr:
if (tTd(9, 1))
printf("getauthinfo: %s\n", hbuf);
return hbuf;
@@ -1192,15 +1364,10 @@ host_map_lookup(map, name, av, statp)
int *statp;
{
register struct hostent *hp;
- u_long in_addr;
+ struct in_addr in_addr;
char *cp;
- int i;
register STAB *s;
- char hbuf[MAXNAME];
- extern struct hostent *gethostbyaddr();
-#if NAMED_BIND
- extern int h_errno;
-#endif
+ char hbuf[MAXNAME + 1];
/*
** See if we have already looked up this name. If so, just
@@ -1212,22 +1379,39 @@ host_map_lookup(map, name, av, statp)
{
if (tTd(9, 1))
printf("host_map_lookup(%s) => CACHE %s\n",
- name, s->s_namecanon.nc_cname);
+ name,
+ s->s_namecanon.nc_cname == NULL
+ ? "NULL"
+ : s->s_namecanon.nc_cname);
errno = s->s_namecanon.nc_errno;
#if NAMED_BIND
h_errno = s->s_namecanon.nc_herrno;
#endif
*statp = s->s_namecanon.nc_stat;
- if (CurEnv->e_message == NULL && *statp == EX_TEMPFAIL)
+ if (*statp == EX_TEMPFAIL)
{
- sprintf(hbuf, "%s: Name server timeout",
+ CurEnv->e_status = "4.4.3";
+ message("851 %s: Name server timeout",
shortenstring(name, 33));
- CurEnv->e_message = newstr(hbuf);
}
return s->s_namecanon.nc_cname;
}
/*
+ ** If we are running without a regular network connection (usually
+ ** dial-on-demand) and we are just queueing, we want to avoid DNS
+ ** lookups because those could try to connect to a server.
+ */
+
+ if (CurEnv->e_sendmode == SM_DEFER)
+ {
+ if (tTd(9, 1))
+ printf("host_map_lookup(%s) => DEFERRED\n", name);
+ *statp = EX_TEMPFAIL;
+ return NULL;
+ }
+
+ /*
** If first character is a bracket, then it is an address
** lookup. Address is copied into a temporary buffer to
** strip the brackets and to preserve name if address is
@@ -1241,8 +1425,14 @@ host_map_lookup(map, name, av, statp)
if (tTd(9, 1))
printf("host_map_lookup(%s) => ", name);
s->s_namecanon.nc_flags |= NCF_VALID; /* will be soon */
- (void) strcpy(hbuf, name);
- if (getcanonname(hbuf, sizeof hbuf - 1, TRUE))
+ if (strlen(name) < sizeof hbuf)
+ (void) strcpy(hbuf, name);
+ else
+ {
+ bcopy(name, hbuf, sizeof hbuf - 1);
+ hbuf[sizeof hbuf - 1] = '\0';
+ }
+ if (getcanonname(hbuf, sizeof hbuf - 1, !HasWildcardMX))
{
if (tTd(9, 1))
printf("%s\n", hbuf);
@@ -1264,16 +1454,15 @@ host_map_lookup(map, name, av, statp)
case TRY_AGAIN:
if (UseNameServer)
{
- sprintf(hbuf, "%s: Name server timeout",
+ CurEnv->e_status = "4.4.3";
+ message("851 %s: Name server timeout",
shortenstring(name, 33));
- message("%s", hbuf);
- if (CurEnv->e_message == NULL)
- CurEnv->e_message = newstr(hbuf);
}
*statp = EX_TEMPFAIL;
break;
case HOST_NOT_FOUND:
+ case NO_DATA:
*statp = EX_NOHOST;
break;
@@ -1291,34 +1480,16 @@ host_map_lookup(map, name, av, statp)
*statp = EX_NOHOST;
#endif
s->s_namecanon.nc_stat = *statp;
- if (*statp != EX_TEMPFAIL || UseNameServer)
- return NULL;
-
- /*
- ** Try to look it up in /etc/hosts
- */
-
- hp = gethostbyname(name);
- if (hp == NULL)
- {
- /* no dice there either */
- s->s_namecanon.nc_stat = *statp = EX_NOHOST;
- return NULL;
- }
-
- s->s_namecanon.nc_stat = *statp = EX_OK;
- cp = map_rewrite(map, hp->h_name, strlen(hp->h_name), av);
- s->s_namecanon.nc_cname = newstr(cp);
- return cp;
+ return NULL;
}
}
if ((cp = strchr(name, ']')) == NULL)
return (NULL);
*cp = '\0';
- in_addr = inet_addr(&name[1]);
+ in_addr.s_addr = inet_addr(&name[1]);
/* nope -- ask the name server */
- hp = gethostbyaddr((char *)&in_addr, sizeof(struct in_addr), AF_INET);
+ hp = sm_gethostbyaddr((char *)&in_addr, INADDRSZ, AF_INET);
s->s_namecanon.nc_errno = errno;
#if NAMED_BIND
s->s_namecanon.nc_herrno = h_errno;
@@ -1331,7 +1502,7 @@ host_map_lookup(map, name, av, statp)
}
/* found a match -- copy out */
- cp = map_rewrite(map, hp->h_name, strlen(hp->h_name), av);
+ cp = map_rewrite(map, (char *) hp->h_name, strlen(hp->h_name), av);
s->s_namecanon.nc_stat = *statp = EX_OK;
s->s_namecanon.nc_cname = newstr(cp);
return cp;
@@ -1346,6 +1517,10 @@ host_map_lookup(map, name, av, statp)
** A printable version of that sockaddr.
*/
+#if NETLINK
+# include <net/if_dl.h>
+#endif
+
char *
anynet_ntoa(sap)
register SOCKADDR *sap;
@@ -1363,8 +1538,7 @@ anynet_ntoa(sap)
switch (sap->sa.sa_family)
{
-#ifdef MAYBENEXTRELEASE /*** UNTESTED *** UNTESTED *** UNTESTED ***/
-#ifdef NETUNIX
+#if NETUNIX
case AF_UNIX:
if (sap->sunix.sun_path[0] != '\0')
sprintf(buf, "[UNIX: %.64s]", sap->sunix.sun_path);
@@ -1372,16 +1546,22 @@ anynet_ntoa(sap)
sprintf(buf, "[UNIX: localhost]");
return buf;
#endif
-#endif
-#ifdef NETINET
+#if NETINET
case AF_INET:
- return inet_ntoa(((struct sockaddr_in *) sap)->sin_addr);
+ return inet_ntoa(sap->sin.sin_addr);
#endif
+#if NETLINK
+ case AF_LINK:
+ sprintf(buf, "[LINK: %s]",
+ link_ntoa((struct sockaddr_dl *) &sap->sa));
+ return buf;
+#endif
default:
- /* this case is only to ensure syntactic correctness */
- break;
+ /* this case is needed when nothing is #defined */
+ /* in order to keep the switch syntactically correct */
+ break;
}
/* unknown family -- just dump bytes */
@@ -1424,30 +1604,28 @@ hostnamebyanyaddr(sap)
switch (sap->sa.sa_family)
{
-#ifdef NETINET
+#if NETINET
case AF_INET:
- hp = gethostbyaddr((char *) &sap->sin.sin_addr,
- sizeof sap->sin.sin_addr,
+ hp = sm_gethostbyaddr((char *) &sap->sin.sin_addr,
+ INADDRSZ,
AF_INET);
break;
#endif
-#ifdef NETISO
+#if NETISO
case AF_ISO:
- hp = gethostbyaddr((char *) &sap->siso.siso_addr,
+ hp = sm_gethostbyaddr((char *) &sap->siso.siso_addr,
sizeof sap->siso.siso_addr,
AF_ISO);
break;
#endif
-#ifdef MAYBENEXTRELEASE /*** UNTESTED *** UNTESTED *** UNTESTED ***/
case AF_UNIX:
hp = NULL;
break;
-#endif
default:
- hp = gethostbyaddr(sap->sa.sa_data,
+ hp = sm_gethostbyaddr(sap->sa.sa_data,
sizeof sap->sa.sa_data,
sap->sa.sa_family);
break;
@@ -1458,13 +1636,13 @@ hostnamebyanyaddr(sap)
#endif /* NAMED_BIND */
if (hp != NULL)
- return hp->h_name;
+ return (char *) hp->h_name;
else
{
/* produce a dotted quad */
- static char buf[512];
+ static char buf[203];
- (void) sprintf(buf, "[%s]", anynet_ntoa(sap));
+ (void) sprintf(buf, "[%.200s]", anynet_ntoa(sap));
return buf;
}
}
@@ -1548,7 +1726,7 @@ host_map_lookup(map, name, avp, statp)
{
register struct hostent *hp;
- hp = gethostbyname(name);
+ hp = sm_gethostbyname(name);
if (hp != NULL)
return hp->h_name;
*statp = EX_NOHOST;
diff --git a/usr.sbin/sendmail/src/deliver.c b/usr.sbin/sendmail/src/deliver.c
index 437b1ad..51367ce 100644
--- a/usr.sbin/sendmail/src/deliver.c
+++ b/usr.sbin/sendmail/src/deliver.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -33,20 +33,20 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)deliver.c 8.84.1.4 (Berkeley) 3/28/95";
+static char sccsid[] = "@(#)deliver.c 8.185 (Berkeley) 11/18/95";
#endif /* not lint */
#include "sendmail.h"
-#include <netdb.h>
#include <errno.h>
#if NAMED_BIND
-#include <arpa/nameser.h>
#include <resolv.h>
extern int h_errno;
#endif
+#ifdef SMTP
extern char SmtpError[];
+#endif
/*
** SENDALL -- actually send all the messages.
@@ -66,6 +66,7 @@ extern char SmtpError[];
** appropriate action.
*/
+void
sendall(e, mode)
ENVELOPE *e;
char mode;
@@ -75,7 +76,10 @@ sendall(e, mode)
int otherowners;
register ENVELOPE *ee;
ENVELOPE *splitenv = NULL;
- bool announcequeueup;
+ bool oldverbose = Verbose;
+ bool somedeliveries = FALSE;
+ int pid;
+ extern void sendenvelope();
/*
** If we have had global, fatal errors, don't bother sending
@@ -96,19 +100,20 @@ sendall(e, mode)
if (mode == SM_DEFAULT)
{
mode = e->e_sendmode;
- if (mode != SM_VERIFY &&
+ if (mode != SM_VERIFY && mode != SM_DEFER &&
shouldqueue(e->e_msgpriority, e->e_ctime))
mode = SM_QUEUE;
- announcequeueup = mode == SM_QUEUE;
}
- else
- announcequeueup = FALSE;
if (tTd(13, 1))
{
+ extern void printenvflags();
+
printf("\n===== SENDALL: mode %c, id %s, e_from ",
mode, e->e_id);
printaddr(&e->e_from, FALSE);
+ printf("\te_flags = ");
+ printenvflags(e);
printf("sendqueue:\n");
printaddr(e->e_sendqueue, TRUE);
}
@@ -124,12 +129,15 @@ sendall(e, mode)
if (e->e_hopcount > MaxHopCount)
{
errno = 0;
- queueup(e, TRUE, announcequeueup);
+#ifdef QUEUE
+ queueup(e, mode == SM_QUEUE || mode == SM_DEFER);
+#endif
e->e_flags |= EF_FATALERRS|EF_PM_NOTIFY|EF_CLRQUEUE;
- syserr("554 too many hops %d (%d max): from %s via %s, to %s",
+ syserr("554 Too many hops %d (%d max): from %s via %s, to %s",
e->e_hopcount, MaxHopCount, e->e_from.q_paddr,
RealHostName == NULL ? "localhost" : RealHostName,
e->e_sendqueue->q_paddr);
+ e->e_sendqueue->q_status = "5.4.6";
return;
}
@@ -151,7 +159,7 @@ sendall(e, mode)
printaddr(&e->e_from, FALSE);
}
e->e_from.q_flags |= QDONTSEND;
- (void) recipient(&e->e_from, &e->e_sendqueue, e);
+ (void) recipient(&e->e_from, &e->e_sendqueue, 0, e);
}
/*
@@ -185,8 +193,17 @@ sendall(e, mode)
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
{
+ if (tTd(13, 30))
+ {
+ printf("Checking ");
+ printaddr(q, FALSE);
+ }
if (bitset(QDONTSEND, q->q_flags))
+ {
+ if (tTd(13, 30))
+ printf(" ... QDONTSEND\n");
continue;
+ }
if (q->q_owner != NULL)
{
@@ -210,6 +227,35 @@ sendall(e, mode)
{
otherowners++;
}
+
+ /*
+ ** If this mailer is expensive, and if we don't
+ ** want to make connections now, just mark these
+ ** addresses and return. This is useful if we
+ ** want to batch connections to reduce load. This
+ ** will cause the messages to be queued up, and a
+ ** daemon will come along to send the messages later.
+ */
+
+ if (bitset(QBADADDR|QQUEUEUP, q->q_flags))
+ {
+ if (tTd(13, 30))
+ printf(" ... QBADADDR|QQUEUEUP\n");
+ continue;
+ }
+ if (NoConnect && !Verbose &&
+ bitnset(M_EXPENSIVE, q->q_mailer->m_flags))
+ {
+ if (tTd(13, 30))
+ printf(" ... expensive\n");
+ q->q_flags |= QQUEUEUP;
+ }
+ else
+ {
+ if (tTd(13, 30))
+ printf(" ... deliverable\n");
+ somedeliveries = TRUE;
+ }
}
if (owner != NULL && otherowners > 0)
@@ -233,7 +279,7 @@ sendall(e, mode)
ee->e_header = copyheader(e->e_header);
ee->e_sendqueue = copyqueue(e->e_sendqueue);
ee->e_errorqueue = copyqueue(e->e_errorqueue);
- ee->e_flags = e->e_flags & ~(EF_INQUEUE|EF_CLRQUEUE|EF_FATALERRS|EF_SENDRECEIPT);
+ ee->e_flags = e->e_flags & ~(EF_INQUEUE|EF_CLRQUEUE|EF_FATALERRS|EF_SENDRECEIPT|EF_RET_PARAM);
ee->e_flags |= EF_NORECEIPT;
setsender(owner, ee, NULL, TRUE);
if (tTd(13, 5))
@@ -244,33 +290,61 @@ sendall(e, mode)
ee->e_from.q_flags |= QDONTSEND;
ee->e_dfp = NULL;
ee->e_xfp = NULL;
- ee->e_df = NULL;
ee->e_errormode = EM_MAIL;
ee->e_sibling = splitenv;
splitenv = ee;
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+ {
if (q->q_owner == owner)
{
q->q_flags |= QDONTSEND;
q->q_flags &= ~QQUEUEUP;
}
+ }
for (q = ee->e_sendqueue; q != NULL; q = q->q_next)
+ {
if (q->q_owner != owner)
{
q->q_flags |= QDONTSEND;
q->q_flags &= ~QQUEUEUP;
}
+ else
+ {
+ /* clear DSN parameters */
+ q->q_flags &= ~(QHASNOTIFY|QPINGONSUCCESS);
+ q->q_flags |= QPINGONFAILURE|QPINGONDELAY;
+ }
+ }
- if (e->e_df != NULL && mode != SM_VERIFY)
+ if (mode != SM_VERIFY && bitset(EF_HAS_DF, e->e_flags))
{
+ char df1buf[20], df2buf[20];
+
ee->e_dfp = NULL;
- ee->e_df = queuename(ee, 'd');
- ee->e_df = newstr(ee->e_df);
- if (link(e->e_df, ee->e_df) < 0)
+ strcpy(df1buf, queuename(e, 'd'));
+ strcpy(df2buf, queuename(ee, 'd'));
+ if (link(df1buf, df2buf) < 0)
{
+ int saverrno = errno;
+
syserr("sendall: link(%s, %s)",
- e->e_df, ee->e_df);
+ df1buf, df2buf);
+ if (saverrno == EEXIST)
+ {
+ if (unlink(df2buf) < 0)
+ {
+ syserr("!sendall: unlink(%s): permanent",
+ df2buf);
+ /*NOTREACHED*/
+ }
+ if (link(df1buf, df2buf) < 0)
+ {
+ syserr("!sendall: link(%s, %s): permanent",
+ df1buf, df2buf);
+ /*NOTREACHED*/
+ }
+ }
}
}
#ifdef LOG
@@ -294,65 +368,33 @@ sendall(e, mode)
e->e_flags |= EF_NORECEIPT;
}
+ /* if nothing to be delivered, just queue up everything */
+ if (!somedeliveries && mode != SM_QUEUE && mode != SM_DEFER &&
+ mode != SM_VERIFY)
+ {
+ if (tTd(13, 29))
+ printf("No deliveries: auto-queuing\n");
+ mode = SM_QUEUE;
+ }
+
# ifdef QUEUE
- if ((mode == SM_QUEUE || mode == SM_FORK ||
+ if ((mode == SM_QUEUE || mode == SM_DEFER || mode == SM_FORK ||
(mode != SM_VERIFY && SuperSafe)) &&
!bitset(EF_INQUEUE, e->e_flags))
{
/* be sure everything is instantiated in the queue */
- queueup(e, TRUE, announcequeueup);
+ queueup(e, mode == SM_QUEUE || mode == SM_DEFER);
for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
- queueup(ee, TRUE, announcequeueup);
+ queueup(ee, mode == SM_QUEUE || mode == SM_DEFER);
}
#endif /* QUEUE */
- if (splitenv != NULL)
- {
- if (tTd(13, 1))
- {
- printf("\nsendall: Split queue; remaining queue:\n");
- printaddr(e->e_sendqueue, TRUE);
- }
-
- for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
- {
- CurEnv = ee;
- if (mode != SM_VERIFY)
- openxscript(ee);
- sendenvelope(ee, mode);
- dropenvelope(ee);
- }
-
- CurEnv = e;
- }
- sendenvelope(e, mode);
-}
-
-sendenvelope(e, mode)
- register ENVELOPE *e;
- char mode;
-{
- bool oldverbose;
- int pid;
- register ADDRESS *q;
- char *qf;
- char *id;
-
/*
- ** If we have had global, fatal errors, don't bother sending
- ** the message at all if we are in SMTP mode. Local errors
- ** (e.g., a single address failing) will still cause the other
- ** addresses to be sent.
+ ** If we belong in background, fork now.
*/
- if (bitset(EF_FATALERRS, e->e_flags) &&
- (OpMode == MD_SMTP || OpMode == MD_DAEMON))
- {
- e->e_flags |= EF_CLRQUEUE;
- return;
- }
-
- oldverbose = Verbose;
+ if (tTd(13, 20))
+ printf("sendall: final mode = %c\n", mode);
switch (mode)
{
case SM_VERIFY:
@@ -360,8 +402,10 @@ sendenvelope(e, mode)
break;
case SM_QUEUE:
+ case SM_DEFER:
queueonly:
- e->e_flags |= EF_INQUEUE|EF_KEEPQUEUE;
+ if (e->e_nrcpts > 0)
+ e->e_flags |= EF_INQUEUE;
return;
case SM_FORK:
@@ -376,15 +420,17 @@ sendenvelope(e, mode)
** then restart from scratch in the child.
*/
- /* save id for future use */
- id = e->e_id;
+ {
+ /* save id for future use */
+ char *qid = e->e_id;
- /* now drop the envelope in the parent */
- e->e_flags |= EF_INQUEUE|EF_KEEPQUEUE;
- dropenvelope(e);
+ /* now drop the envelope in the parent */
+ e->e_flags |= EF_INQUEUE;
+ dropenvelope(e);
- /* and reacquire in the child */
- (void) dowork(id, TRUE, FALSE, e);
+ /* and reacquire in the child */
+ (void) dowork(qid, TRUE, FALSE, e);
+ }
return;
@@ -400,15 +446,16 @@ sendenvelope(e, mode)
/* be sure we leave the temp files to our child */
/* can't call unlockqueue to avoid unlink of xfp */
if (e->e_lockfp != NULL)
- (void) xfclose(e->e_lockfp, "sendenvelope", "lockfp");
+ (void) xfclose(e->e_lockfp, "sendenvelope lockfp", e->e_id);
e->e_lockfp = NULL;
/* close any random open files in the envelope */
closexscript(e);
if (e->e_dfp != NULL)
- (void) xfclose(e->e_dfp, "sendenvelope", e->e_df);
+ (void) xfclose(e->e_dfp, "sendenvelope dfp", e->e_id);
e->e_dfp = NULL;
- e->e_id = e->e_df = NULL;
+ e->e_id = NULL;
+ e->e_flags &= ~EF_HAS_DF;
/* catch intermediate zombie */
(void) waitfor(pid);
@@ -426,7 +473,7 @@ sendenvelope(e, mode)
/* prevent parent from waiting if there was an error */
if (pid < 0)
{
- e->e_flags |= EF_INQUEUE|EF_KEEPQUEUE;
+ e->e_flags |= EF_INQUEUE;
finis();
}
@@ -447,6 +494,64 @@ sendenvelope(e, mode)
break;
}
+ if (splitenv != NULL)
+ {
+ if (tTd(13, 2))
+ {
+ printf("\nsendall: Split queue; remaining queue:\n");
+ printaddr(e->e_sendqueue, TRUE);
+ }
+
+ for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
+ {
+ CurEnv = ee;
+ if (mode != SM_VERIFY)
+ openxscript(ee);
+ sendenvelope(ee, mode);
+ dropenvelope(ee);
+ }
+
+ CurEnv = e;
+ }
+ sendenvelope(e, mode);
+ Verbose = oldverbose;
+ if (mode == SM_FORK)
+ finis();
+}
+
+void
+sendenvelope(e, mode)
+ register ENVELOPE *e;
+ char mode;
+{
+ register ADDRESS *q;
+ bool didany;
+
+ if (tTd(13, 10))
+ printf("sendenvelope(%s) e_flags=0x%x\n",
+ e->e_id == NULL ? "[NOQUEUE]" : e->e_id,
+ e->e_flags);
+#ifdef LOG
+ if (LogLevel > 80)
+ syslog(LOG_DEBUG, "%s: sendenvelope, flags=0x%x",
+ e->e_id == NULL ? "[NOQUEUE]" : e->e_id,
+ e->e_flags);
+#endif
+
+ /*
+ ** If we have had global, fatal errors, don't bother sending
+ ** the message at all if we are in SMTP mode. Local errors
+ ** (e.g., a single address failing) will still cause the other
+ ** addresses to be sent.
+ */
+
+ if (bitset(EF_FATALERRS, e->e_flags) &&
+ (OpMode == MD_SMTP || OpMode == MD_DAEMON))
+ {
+ e->e_flags |= EF_CLRQUEUE;
+ return;
+ }
+
/*
** Run through the list and send everything.
**
@@ -456,14 +561,15 @@ sendenvelope(e, mode)
e->e_nsent = 0;
e->e_flags |= EF_GLOBALERRS;
+ didany = FALSE;
/* now run through the queue */
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
{
-#ifdef XDEBUG
+#if XDEBUG
char wbuf[MAXNAME + 20];
- (void) sprintf(wbuf, "sendall(%s)", q->q_paddr);
+ (void) sprintf(wbuf, "sendall(%.*s)", MAXNAME, q->q_paddr);
checkfd012(wbuf);
#endif
if (mode == SM_VERIFY)
@@ -491,21 +597,23 @@ sendenvelope(e, mode)
if (e->e_nsent >= CheckpointInterval)
{
- queueup(e, TRUE, FALSE);
+ queueup(e, FALSE);
e->e_nsent = 0;
}
# endif /* QUEUE */
(void) deliver(e, q);
+ didany = TRUE;
}
}
- Verbose = oldverbose;
+ if (didany)
+ {
+ e->e_dtime = curtime();
+ e->e_ntries++;
+ }
-#ifdef XDEBUG
+#if XDEBUG
checkfd012("end of sendenvelope");
#endif
-
- if (mode == SM_FORK)
- finis();
}
/*
** DOFORK -- do a fork, retrying a couple of times on failure.
@@ -563,9 +671,10 @@ sendenvelope(e, mode)
** returns twice, once in parent and once in child.
*/
+int
dofork()
{
- register int pid;
+ register int pid = -1;
DOFORK(fork);
return (pid);
@@ -592,6 +701,7 @@ dofork()
** The standard input is passed off to someone.
*/
+int
deliver(e, firstto)
register ENVELOPE *e;
ADDRESS *firstto;
@@ -602,22 +712,24 @@ deliver(e, firstto)
register char **mvp;
register char *p;
register MAILER *m; /* mailer for this recipient */
- ADDRESS *ctladdr;
- register MCI *mci;
+ ADDRESS *volatile ctladdr;
+ register MCI *volatile mci;
register ADDRESS *to = firstto;
- bool clever = FALSE; /* running user smtp to this mailer */
- ADDRESS *tochain = NULL; /* chain of users in this mailer call */
+ volatile bool clever = FALSE; /* running user smtp to this mailer */
+ ADDRESS *volatile tochain = NULL; /* users chain in this mailer call */
int rcode; /* response code */
char *firstsig; /* signature of firstto */
- int pid;
- char *curhost;
+ int pid = -1;
+ char *volatile curhost;
+ time_t xstart;
int mpvect[2];
int rpvect[2];
char *pv[MAXPV+1];
char tobuf[TOBUFSIZE]; /* text line of to people */
- char buf[MAXNAME];
- char rpathbuf[MAXNAME]; /* translated return path */
+ char buf[MAXNAME + 1];
+ char rpathbuf[MAXNAME + 1]; /* translated return path */
extern int checkcompat();
+ extern void markfailure __P((ENVELOPE *, ADDRESS *, MCI *, int));
errno = 0;
if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags))
@@ -636,7 +748,10 @@ deliver(e, firstto)
host = to->q_host;
CurEnv = e; /* just in case */
e->e_statmsg = NULL;
+#ifdef SMTP
SmtpError[0] = '\0';
+#endif
+ xstart = curtime();
if (tTd(10, 1))
printf("\n--deliver, id=%s, mailer=%s, host=`%s', first user=`%s'\n",
@@ -645,33 +760,6 @@ deliver(e, firstto)
printopenfds(FALSE);
/*
- ** If this mailer is expensive, and if we don't want to make
- ** connections now, just mark these addresses and return.
- ** This is useful if we want to batch connections to
- ** reduce load. This will cause the messages to be
- ** queued up, and a daemon will come along to send the
- ** messages later.
- ** This should be on a per-mailer basis.
- */
-
- if (NoConnect && bitnset(M_EXPENSIVE, m->m_flags) && !Verbose)
- {
- for (; to != NULL; to = to->q_next)
- {
- if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags) ||
- to->q_mailer != m)
- continue;
- to->q_flags |= QQUEUEUP;
- e->e_to = to->q_paddr;
- message("queued");
- if (LogLevel > 8)
- logdelivery(m, NULL, "queued", NULL, e);
- }
- e->e_to = NULL;
- return (0);
- }
-
- /*
** Do initial argv setup.
** Insert the mailer name. Notice that $x expansion is
** NOT done on the mailer name. Then, if the mailer has
@@ -684,7 +772,11 @@ deliver(e, firstto)
/* rewrite from address, using rewriting rules */
rcode = EX_OK;
- (void) strcpy(rpathbuf, remotename(e->e_from.q_paddr, m,
+ if (bitnset(M_UDBENVELOPE, e->e_from.q_mailer->m_flags))
+ p = e->e_sender;
+ else
+ p = e->e_from.q_paddr;
+ (void) strcpy(rpathbuf, remotename(p, m,
RF_SENDERADDR|RF_CANONICAL,
&rcode, e));
define('g', rpathbuf, e); /* translated return path */
@@ -726,7 +818,7 @@ deliver(e, firstto)
break;
/* this entry is safe -- go ahead and process it */
- expand(*mvp, buf, &buf[sizeof buf - 1], e);
+ expand(*mvp, buf, sizeof buf, e);
*pvp++ = newstr(buf);
if (pvp >= &pv[MAXPV - 3])
{
@@ -788,11 +880,15 @@ deliver(e, firstto)
}
/* compute effective uid/gid when sending */
- /* XXX perhaps this should be to->q_mailer != LocalMailer ?? */
- /* XXX perhaps it should be a mailer flag? */
- if (to->q_mailer == ProgMailer || to->q_mailer == FileMailer)
+ if (bitnset(M_RUNASRCPT, to->q_mailer->m_flags))
ctladdr = getctladdr(to);
+ if (tTd(10, 2))
+ {
+ printf("ctladdr=");
+ printaddr(ctladdr, FALSE);
+ }
+
user = to->q_user;
e->e_to = to->q_paddr;
if (tTd(10, 5))
@@ -809,16 +905,20 @@ deliver(e, firstto)
if (m->m_maxsize != 0 && e->e_msgsize > m->m_maxsize)
{
- NoReturn = TRUE;
+ e->e_flags |= EF_NO_BODY_RETN;
+ to->q_status = "5.2.3";
usrerr("552 Message is too large; %ld bytes max", m->m_maxsize);
- giveresponse(EX_UNAVAILABLE, m, NULL, ctladdr, e);
+ giveresponse(EX_UNAVAILABLE, m, NULL, ctladdr, xstart, e);
continue;
}
+#if NAMED_BIND
+ h_errno = 0;
+#endif
rcode = checkcompat(to, e);
if (rcode != EX_OK)
{
- markfailure(e, to, rcode);
- giveresponse(rcode, m, NULL, ctladdr, e);
+ markfailure(e, to, NULL, rcode);
+ giveresponse(rcode, m, NULL, ctladdr, xstart, e);
continue;
}
@@ -860,12 +960,25 @@ deliver(e, firstto)
** with the others, so we fudge on the To person.
*/
- if (m == FileMailer)
+ if (strcmp(m->m_mailer, "[FILE]") == 0)
{
- rcode = mailfile(user, ctladdr, e);
- giveresponse(rcode, m, NULL, ctladdr, e);
+ rcode = mailfile(user, ctladdr, SFF_CREAT, e);
+ giveresponse(rcode, m, NULL, ctladdr, xstart, e);
+ e->e_nsent++;
if (rcode == EX_OK)
+ {
to->q_flags |= QSENT;
+ if (bitnset(M_LOCALMAILER, m->m_flags) &&
+ (e->e_receiptto != NULL ||
+ bitset(QPINGONSUCCESS, to->q_flags)))
+ {
+ to->q_flags |= QDELIVERED;
+ to->q_status = "2.1.5";
+ fprintf(e->e_xfp, "%s... Successfully delivered\n",
+ to->q_paddr);
+ }
+ }
+ to->q_statdate = curtime();
continue;
}
@@ -893,7 +1006,7 @@ deliver(e, firstto)
if (!clever)
{
- expand(*mvp, buf, &buf[sizeof buf - 1], e);
+ expand(*mvp, buf, sizeof buf, e);
*pvp++ = newstr(buf);
if (pvp >= &pv[MAXPV - 2])
{
@@ -919,7 +1032,7 @@ deliver(e, firstto)
while (!clever && *++mvp != NULL)
{
- expand(*mvp, buf, &buf[sizeof buf - 1], e);
+ expand(*mvp, buf, sizeof buf, e);
*pvp++ = newstr(buf);
if (pvp >= &pv[MAXPV])
syserr("554 deliver: pv overflow after $u for %s", pv[0]);
@@ -935,7 +1048,7 @@ deliver(e, firstto)
*/
/*XXX this seems a bit wierd */
- if (ctladdr == NULL && m != ProgMailer &&
+ if (ctladdr == NULL && m != ProgMailer && m != FileMailer &&
bitset(QGOODUID, e->e_from.q_flags))
ctladdr = &e->e_from;
@@ -950,6 +1063,9 @@ deliver(e, firstto)
printav(pv);
}
errno = 0;
+#if NAMED_BIND
+ h_errno = 0;
+#endif
CurHostName = NULL;
@@ -966,16 +1082,31 @@ deliver(e, firstto)
SmtpPhase = NULL;
mci = NULL;
-#ifdef XDEBUG
+#if XDEBUG
{
char wbuf[MAXLINE];
/* make absolutely certain 0, 1, and 2 are in use */
- sprintf(wbuf, "%s... openmailer(%s)", e->e_to, m->m_name);
+ sprintf(wbuf, "%s... openmailer(%s)",
+ shortenstring(e->e_to, 203), m->m_name);
checkfd012(wbuf);
}
#endif
+ /* check for 8-bit available */
+ if (bitset(EF_HAS8BIT, e->e_flags) &&
+ bitnset(M_7BITS, m->m_flags) &&
+ (bitset(EF_DONT_MIME, e->e_flags) ||
+ !(bitset(MM_MIME8BIT, MimeMode) ||
+ (bitset(EF_IS_MIME, e->e_flags) &&
+ bitset(MM_CVTMIME, MimeMode)))))
+ {
+ usrerr("554 Cannot send 8-bit data to 7-bit destination");
+ rcode = EX_DATAERR;
+ e->e_status = "5.6.3";
+ goto give_up;
+ }
+
/* check for Local Person Communication -- not for mortals!!! */
if (strcmp(m->m_mailer, "[LPC]") == 0)
{
@@ -991,7 +1122,7 @@ deliver(e, firstto)
{
#ifdef DAEMON
register int i;
- register u_short port;
+ register volatile u_short port = 0;
if (pv[0] == NULL || pv[1] == NULL || pv[1][0] == '\0')
{
@@ -1017,14 +1148,23 @@ deliver(e, firstto)
goto give_up;
}
if (pv[2] != NULL)
- port = atoi(pv[2]);
- else
- port = 0;
+ {
+ port = htons(atoi(pv[2]));
+ if (port == 0)
+ {
+ struct servent *sp = getservbyname(pv[2], "tcp");
+
+ if (sp == NULL)
+ syserr("Service %s unknown", pv[2]);
+ else
+ port = sp->s_port;
+ }
+ }
tryhost:
while (*curhost != '\0')
{
register char *p;
- static char hostbuf[MAXNAME];
+ static char hostbuf[MAXNAME + 1];
/* pull the next host from the signature */
p = strchr(curhost, ':');
@@ -1053,6 +1193,9 @@ tryhost:
mci_dump(mci, FALSE);
}
CurHostName = mci->mci_host;
+ message("Using cached %sSMTP connection to %s via %s...",
+ bitset(MCIF_ESMTP, mci->mci_flags) ? "E" : "",
+ hostbuf, m->m_name);
break;
}
mci->mci_mailer = m;
@@ -1061,10 +1204,11 @@ tryhost:
/* try the connection */
setproctitle("%s %s: %s", e->e_id, hostbuf, "user open");
- message("Connecting to %s (%s)...",
+ message("Connecting to %s via %s...",
hostbuf, m->m_name);
i = makeconnection(hostbuf, port, mci,
bitnset(M_SECURE_PORT, m->m_flags));
+ mci->mci_lastuse = curtime();
mci->mci_exitstat = i;
mci->mci_errno = errno;
#if NAMED_BIND
@@ -1105,6 +1249,14 @@ tryhost:
}
else
{
+ /* flush any expired connections */
+ (void) mci_scan(NULL);
+
+ /* announce the connection to verbose listeners */
+ if (host == NULL || host[0] == '\0')
+ message("Connecting to %s...", m->m_name);
+ else
+ message("Connecting to %s via %s...", host, m->m_name);
if (TrafficLogFile != NULL)
{
char **av;
@@ -1119,7 +1271,7 @@ tryhost:
if (pipe(mpvect) < 0)
{
syserr("%s... openmailer(%s): pipe (to mailer)",
- e->e_to, m->m_name);
+ shortenstring(e->e_to, 203), m->m_name);
if (tTd(11, 1))
printf("openmailer: NULL\n");
rcode = EX_OSERR;
@@ -1127,10 +1279,11 @@ tryhost:
}
/* if this mailer speaks smtp, create a return pipe */
+#ifdef SMTP
if (clever && pipe(rpvect) < 0)
{
syserr("%s... openmailer(%s): pipe (from mailer)",
- e->e_to, m->m_name);
+ shortenstring(e->e_to, 203), m->m_name);
(void) close(mpvect[0]);
(void) close(mpvect[1]);
if (tTd(11, 1))
@@ -1138,6 +1291,7 @@ tryhost:
rcode = EX_OSERR;
goto give_up;
}
+#endif
/*
** Actually fork the mailer process.
@@ -1159,14 +1313,16 @@ tryhost:
{
/* failure */
syserr("%s... openmailer(%s): cannot fork",
- e->e_to, m->m_name);
+ shortenstring(e->e_to, 203), m->m_name);
(void) close(mpvect[0]);
(void) close(mpvect[1]);
+#ifdef SMTP
if (clever)
{
(void) close(rpvect[0]);
(void) close(rpvect[1]);
}
+#endif
if (tTd(11, 1))
printf("openmailer: NULL\n");
rcode = EX_OSERR;
@@ -1176,9 +1332,7 @@ tryhost:
{
int i;
int saveerrno;
- char **ep;
- char *env[MAXUSERENVIRON];
- extern char **environ;
+ struct stat stb;
extern int DtableSize;
if (e->e_lockfp != NULL)
@@ -1189,23 +1343,61 @@ tryhost:
(void) setsignal(SIGHUP, SIG_IGN);
(void) setsignal(SIGTERM, SIG_DFL);
- /* reset user and group */
- if (!bitnset(M_RESTR, m->m_flags))
+ if (m != FileMailer || stat(tochain->q_user, &stb) < 0)
+ stb.st_mode = 0;
+
+ /* tweak niceness */
+ if (m->m_nice != 0)
+ nice(m->m_nice);
+
+ /* reset group id */
+ if (bitnset(M_SPECIFIC_UID, m->m_flags))
+ (void) setgid(m->m_gid);
+ else if (bitset(S_ISGID, stb.st_mode))
+ (void) setgid(stb.st_gid);
+ else if (ctladdr != NULL && ctladdr->q_gid != 0)
{
- if (ctladdr == NULL || ctladdr->q_uid == 0)
- {
+ if (!DontInitGroups)
+ (void) initgroups(ctladdr->q_ruser != NULL ?
+ ctladdr->q_ruser : ctladdr->q_user,
+ ctladdr->q_gid);
+ (void) setgid(ctladdr->q_gid);
+ }
+ else
+ {
+ if (!DontInitGroups)
(void) initgroups(DefUser, DefGid);
+ if (m->m_gid == 0)
(void) setgid(DefGid);
+ else
+ (void) setgid(m->m_gid);
+ }
+
+ /* reset user id */
+ endpwent();
+ if (bitnset(M_SPECIFIC_UID, m->m_flags))
+ {
+#if USESETEUID
+ (void) seteuid(m->m_uid);
+#else
+# if HASSETREUID
+ (void) setreuid(-1, m->m_uid);
+# else
+ if (m->m_uid != geteuid())
+ (void) setuid(m->m_uid);
+# endif
+#endif
+ }
+ else if (bitset(S_ISUID, stb.st_mode))
+ (void) setuid(stb.st_uid);
+ else if (ctladdr != NULL && ctladdr->q_uid != 0)
+ (void) setuid(ctladdr->q_uid);
+ else
+ {
+ if (m->m_uid == 0)
(void) setuid(DefUid);
- }
else
- {
- (void) initgroups(ctladdr->q_ruser?
- ctladdr->q_ruser: ctladdr->q_user,
- ctladdr->q_gid);
- (void) setgid(ctladdr->q_gid);
- (void) setuid(ctladdr->q_uid);
- }
+ (void) setuid(m->m_uid);
}
if (tTd(11, 2))
@@ -1216,14 +1408,14 @@ tryhost:
if (m->m_execdir != NULL)
{
char *p, *q;
- char buf[MAXLINE];
+ char buf[MAXLINE + 1];
for (p = m->m_execdir; p != NULL; p = q)
{
q = strchr(p, ':');
if (q != NULL)
*q = '\0';
- expand(p, buf, &buf[sizeof buf] - 1, e);
+ expand(p, buf, sizeof buf, e);
if (q != NULL)
*q++ = ':';
if (tTd(11, 20))
@@ -1235,13 +1427,15 @@ tryhost:
}
/* arrange to filter std & diag output of command */
+#ifdef SMTP
if (clever)
{
(void) close(rpvect[0]);
if (dup2(rpvect[1], STDOUT_FILENO) < 0)
{
syserr("%s... openmailer(%s): cannot dup pipe %d for stdout",
- e->e_to, m->m_name, rpvect[1]);
+ shortenstring(e->e_to, 203),
+ m->m_name, rpvect[1]);
_exit(EX_OSERR);
}
(void) close(rpvect[1]);
@@ -1253,15 +1447,16 @@ tryhost:
if (dup2(fileno(e->e_xfp), STDOUT_FILENO) < 0)
{
syserr("%s... openmailer(%s): cannot dup xscript %d for stdout",
- e->e_to, m->m_name,
- fileno(e->e_xfp));
+ shortenstring(e->e_to, 203),
+ m->m_name, fileno(e->e_xfp));
_exit(EX_OSERR);
}
}
+#endif
if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0)
{
syserr("%s... openmailer(%s): cannot dup stdout for stderr",
- e->e_to, m->m_name);
+ shortenstring(e->e_to, 203), m->m_name);
_exit(EX_OSERR);
}
@@ -1270,7 +1465,8 @@ tryhost:
if (dup2(mpvect[0], STDIN_FILENO) < 0)
{
syserr("%s... openmailer(%s): cannot dup pipe %d for stdin",
- e->e_to, m->m_name, mpvect[0]);
+ shortenstring(e->e_to, 203),
+ m->m_name, mpvect[0]);
_exit(EX_OSERR);
}
(void) close(mpvect[0]);
@@ -1284,32 +1480,15 @@ tryhost:
(void) fcntl(i, F_SETFD, j | 1);
}
- /*
- ** Set up the mailer environment
- ** TZ is timezone information.
- ** SYSTYPE is Apollo software sys type (required).
- ** ISP is Apollo hardware system type (required).
- */
-
- i = 0;
- env[i++] = "AGENT=sendmail";
- for (ep = environ; *ep != NULL; ep++)
- {
- if (strncmp(*ep, "TZ=", 3) == 0 ||
- strncmp(*ep, "ISP=", 4) == 0 ||
- strncmp(*ep, "SYSTYPE=", 8) == 0)
- env[i++] = *ep;
- }
- env[i++] = NULL;
-
/* run disconnected from terminal */
(void) setsid();
/* try to execute the mailer */
- execve(m->m_mailer, pv, env);
+ execve(m->m_mailer, (ARGV_T) pv, (ARGV_T) UserEnviron);
saveerrno = errno;
syserr("Cannot exec %s", m->m_mailer);
- if (m == LocalMailer || transienterror(saveerrno))
+ if (bitnset(M_LOCALMAILER, m->m_flags) ||
+ transienterror(saveerrno))
_exit(EX_OSERR);
_exit(EX_UNAVAILABLE);
}
@@ -1330,14 +1509,17 @@ tryhost:
syserr("deliver: cannot create mailer output channel, fd=%d",
mpvect[1]);
(void) close(mpvect[1]);
+#ifdef SMTP
if (clever)
{
(void) close(rpvect[0]);
(void) close(rpvect[1]);
}
+#endif
rcode = EX_OSERR;
goto give_up;
}
+#ifdef SMTP
if (clever)
{
(void) close(rpvect[1]);
@@ -1354,6 +1536,7 @@ tryhost:
}
}
else
+#endif
{
mci->mci_flags |= MCIF_TEMP;
mci->mci_in = NULL;
@@ -1364,10 +1547,21 @@ tryhost:
** If we are in SMTP opening state, send initial protocol.
*/
+ if (bitnset(M_7BITS, m->m_flags) &&
+ (!clever || mci->mci_state == MCIS_CLOSED))
+ mci->mci_flags |= MCIF_7BIT;
+#ifdef SMTP
if (clever && mci->mci_state != MCIS_CLOSED)
- {
smtpinit(m, mci, e);
- }
+#endif
+
+ if (bitset(EF_HAS8BIT, e->e_flags) &&
+ !bitset(EF_DONT_MIME, e->e_flags) &&
+ bitnset(M_7BITS, m->m_flags))
+ mci->mci_flags |= MCIF_CVT8TO7;
+ else
+ mci->mci_flags &= ~MCIF_CVT8TO7;
+
if (tTd(11, 1))
{
printf("openmailer: ");
@@ -1389,11 +1583,13 @@ tryhost:
rcode, mci->mci_state, firstsig);
rcode = EX_SOFTWARE;
}
- else if (rcode == EX_TEMPFAIL && curhost != NULL && *curhost != '\0')
+#ifdef DAEMON
+ else if (curhost != NULL && *curhost != '\0')
{
/* try next MX site */
goto tryhost;
}
+#endif
}
else if (!clever)
{
@@ -1402,8 +1598,7 @@ tryhost:
*/
putfromline(mci, e);
- (*e->e_puthdr)(mci, e);
- putline("\n", mci);
+ (*e->e_puthdr)(mci, e->e_header, e);
(*e->e_putbody)(mci, e, NULL);
/* get the exit status */
@@ -1429,8 +1624,8 @@ tryhost:
e->e_to = to->q_paddr;
if ((i = smtprcpt(to, m, mci, e)) != EX_OK)
{
- markfailure(e, to, i);
- giveresponse(i, m, mci, ctladdr, e);
+ markfailure(e, to, mci, i);
+ giveresponse(i, m, mci, ctladdr, xstart, e);
}
else
{
@@ -1494,21 +1689,40 @@ tryhost:
give_up:
if (tobuf[0] != '\0')
- giveresponse(rcode, m, mci, ctladdr, e);
+ giveresponse(rcode, m, mci, ctladdr, xstart, e);
for (to = tochain; to != NULL; to = to->q_tchain)
{
+ /* see if address already marked */
+ if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
+ continue;
+
+ /* mark bad addresses */
if (rcode != EX_OK)
- markfailure(e, to, rcode);
- else
{
- to->q_flags |= QSENT;
- e->e_nsent++;
- if (e->e_receiptto != NULL &&
- bitnset(M_LOCALMAILER, m->m_flags))
- {
- fprintf(e->e_xfp, "%s... Successfully delivered\n",
- to->q_paddr);
- }
+ markfailure(e, to, mci, rcode);
+ continue;
+ }
+
+ /* successful delivery */
+ to->q_flags |= QSENT;
+ to->q_statdate = curtime();
+ e->e_nsent++;
+ if (bitnset(M_LOCALMAILER, m->m_flags) &&
+ (e->e_receiptto != NULL ||
+ bitset(QPINGONSUCCESS, to->q_flags)))
+ {
+ to->q_flags |= QDELIVERED;
+ to->q_status = "2.1.5";
+ fprintf(e->e_xfp, "%s... Successfully delivered\n",
+ to->q_paddr);
+ }
+ else if (bitset(QPINGONSUCCESS, to->q_flags) &&
+ bitset(QPRIMARY, to->q_flags) &&
+ !bitset(MCIF_DSN, mci->mci_flags))
+ {
+ to->q_flags |= QRELAYED;
+ fprintf(e->e_xfp, "%s... relayed; expect no further notifications\n",
+ to->q_paddr);
}
}
@@ -1516,13 +1730,14 @@ tryhost:
** Restore state and return.
*/
-#ifdef XDEBUG
+#if XDEBUG
{
char wbuf[MAXLINE];
/* make absolutely certain 0, 1, and 2 are in use */
sprintf(wbuf, "%s... end of deliver(%s)",
- e->e_to == NULL ? "NO-TO-LIST" : e->e_to,
+ e->e_to == NULL ? "NO-TO-LIST"
+ : shortenstring(e->e_to, 203),
m->m_name);
checkfd012(wbuf);
}
@@ -1538,6 +1753,7 @@ tryhost:
** Parameters:
** e -- the envelope we are sending.
** q -- the address to mark.
+** mci -- mailer connection information.
** rcode -- the code signifying the particular failure.
**
** Returns:
@@ -1549,12 +1765,14 @@ tryhost:
** the message will be queued, as appropriate.
*/
-markfailure(e, q, rcode)
+void
+markfailure(e, q, mci, rcode)
register ENVELOPE *e;
register ADDRESS *q;
+ register MCI *mci;
int rcode;
{
- char buf[MAXLINE];
+ char *stat = NULL;
switch (rcode)
{
@@ -1571,6 +1789,71 @@ markfailure(e, q, rcode)
q->q_flags |= QBADADDR;
break;
}
+
+ /* find most specific error code possible */
+ if (q->q_status == NULL && mci != NULL)
+ q->q_status = mci->mci_status;
+ if (q->q_status == NULL)
+ q->q_status = e->e_status;
+ if (q->q_status == NULL)
+ {
+ switch (rcode)
+ {
+ case EX_USAGE:
+ stat = "5.5.4";
+ break;
+
+ case EX_DATAERR:
+ stat = "5.5.2";
+ break;
+
+ case EX_NOUSER:
+ stat = "5.1.1";
+ break;
+
+ case EX_NOHOST:
+ stat = "5.1.2";
+ break;
+
+ case EX_NOINPUT:
+ case EX_CANTCREAT:
+ case EX_NOPERM:
+ stat = "5.3.0";
+ break;
+
+ case EX_UNAVAILABLE:
+ case EX_SOFTWARE:
+ case EX_OSFILE:
+ case EX_PROTOCOL:
+ case EX_CONFIG:
+ stat = "5.5.0";
+ break;
+
+ case EX_OSERR:
+ case EX_IOERR:
+ stat = "4.5.0";
+ break;
+
+ case EX_TEMPFAIL:
+ stat = "4.2.0";
+ break;
+ }
+ if (stat != NULL)
+ q->q_status = stat;
+ }
+
+ q->q_statdate = curtime();
+ if (CurHostName != NULL && CurHostName[0] != '\0')
+ q->q_statmta = newstr(CurHostName);
+ if (rcode != EX_OK && q->q_rstatus == NULL &&
+ q->q_mailer != NULL && q->q_mailer->m_diagtype != NULL &&
+ strcasecmp(q->q_mailer->m_diagtype, "UNIX") == 0)
+ {
+ char buf[30];
+
+ (void) sprintf(buf, "%d", rcode);
+ q->q_rstatus = newstr(buf);
+ }
}
/*
** ENDMAILER -- Wait for mailer to terminate.
@@ -1593,6 +1876,7 @@ markfailure(e, q, rcode)
** none.
*/
+int
endmailer(mci, e, pv)
register MCI *mci;
register ENVELOPE *e;
@@ -1656,6 +1940,8 @@ endmailer(mci, e, pv)
** response is given before the connection is made.
** ctladdr -- the controlling address for the recipient
** address(es).
+** xstart -- the transaction start time, for computing
+** transaction delays.
** e -- the current envelope.
**
** Returns:
@@ -1666,11 +1952,13 @@ endmailer(mci, e, pv)
** ExitStat may be set.
*/
-giveresponse(stat, m, mci, ctladdr, e)
+void
+giveresponse(stat, m, mci, ctladdr, xstart, e)
int stat;
register MAILER *m;
register MCI *mci;
ADDRESS *ctladdr;
+ time_t xstart;
ENVELOPE *e;
{
register const char *statmsg;
@@ -1689,7 +1977,8 @@ giveresponse(stat, m, mci, ctladdr, e)
statmsg = "250 Sent";
if (e->e_statmsg != NULL)
{
- (void) sprintf(buf, "%s (%s)", statmsg, e->e_statmsg);
+ (void) sprintf(buf, "%s (%s)",
+ statmsg, shortenstring(e->e_statmsg, 403));
statmsg = buf;
}
}
@@ -1773,7 +2062,7 @@ giveresponse(stat, m, mci, ctladdr, e)
*/
if (LogLevel > ((stat == EX_TEMPFAIL) ? 8 : (stat == EX_OK) ? 7 : 6))
- logdelivery(m, mci, &statmsg[4], ctladdr, e);
+ logdelivery(m, mci, &statmsg[4], ctladdr, xstart, e);
if (tTd(11, 2))
printf("giveresponse: stat=%d, e->e_message=%s\n",
@@ -1805,6 +2094,8 @@ giveresponse(stat, m, mci, ctladdr, e)
** log is occuring when no connection is active.
** stat -- the message to print for the status.
** ctladdr -- the controlling address for the to list.
+** xstart -- the transaction start time, used for
+** computing transaction delay.
** e -- the current envelope.
**
** Returns:
@@ -1814,20 +2105,25 @@ giveresponse(stat, m, mci, ctladdr, e)
** none
*/
-logdelivery(m, mci, stat, ctladdr, e)
+#define SPACELEFT(bp) (sizeof buf - ((bp) - buf))
+
+void
+logdelivery(m, mci, stat, ctladdr, xstart, e)
MAILER *m;
register MCI *mci;
- char *stat;
+ const char *stat;
ADDRESS *ctladdr;
+ time_t xstart;
register ENVELOPE *e;
{
# ifdef LOG
register char *bp;
register char *p;
int l;
- char buf[512];
+ char buf[1024];
# if (SYSLOG_BUFSIZE) >= 256
+ /* ctladdr: max 106 bytes */
bp = buf;
if (ctladdr != NULL)
{
@@ -1836,35 +2132,48 @@ logdelivery(m, mci, stat, ctladdr, e)
bp += strlen(bp);
if (bitset(QGOODUID, ctladdr->q_flags))
{
- (void) sprintf(bp, " (%d/%d)",
+ (void) snprintf(bp, SPACELEFT(bp), " (%d/%d)",
ctladdr->q_uid, ctladdr->q_gid);
bp += strlen(bp);
}
}
- (void) sprintf(bp, ", delay=%s", pintvl(curtime() - e->e_ctime, TRUE));
+ /* delay & xdelay: max 41 bytes */
+ snprintf(bp, SPACELEFT(bp), ", delay=%s",
+ pintvl(curtime() - e->e_ctime, TRUE));
bp += strlen(bp);
+ if (xstart != (time_t) 0)
+ {
+ snprintf(bp, SPACELEFT(bp), ", xdelay=%s",
+ pintvl(curtime() - xstart, TRUE));
+ bp += strlen(bp);
+ }
+
+ /* mailer: assume about 19 bytes (max 10 byte mailer name) */
if (m != NULL)
{
- (void) strcpy(bp, ", mailer=");
- (void) strcat(bp, m->m_name);
+ snprintf(bp, SPACELEFT(bp), ", mailer=%s", m->m_name);
bp += strlen(bp);
}
+ /* relay: max 66 bytes for IPv4 addresses */
if (mci != NULL && mci->mci_host != NULL)
{
# ifdef DAEMON
extern SOCKADDR CurHostAddr;
# endif
- (void) strcpy(bp, ", relay=");
- (void) strcat(bp, mci->mci_host);
+ snprintf(bp, SPACELEFT(bp), ", relay=%s",
+ shortenstring(mci->mci_host, 40));
+ bp += strlen(bp);
# ifdef DAEMON
- (void) strcat(bp, " [");
- (void) strcat(bp, anynet_ntoa(&CurHostAddr));
- (void) strcat(bp, "]");
+ if (CurHostAddr.sa.sa_family != 0)
+ {
+ snprintf(bp, SPACELEFT(bp), " [%s]",
+ anynet_ntoa(&CurHostAddr));
+ }
# endif
}
else if (strcmp(stat, "queued") != 0)
@@ -1873,8 +2182,8 @@ logdelivery(m, mci, stat, ctladdr, e)
if (p != NULL && p[0] != '\0')
{
- (void) strcpy(bp, ", relay=");
- (void) strcat(bp, p);
+ snprintf(bp, SPACELEFT(bp), ", relay=%s",
+ shortenstring(p, 40));
}
}
bp += strlen(bp);
@@ -1889,6 +2198,7 @@ logdelivery(m, mci, stat, ctladdr, e)
# define STATLEN 203
#endif
+ /* stat: max 210 bytes */
if ((bp - buf) > (sizeof buf - ((STATLEN) + 20)))
{
/* desperation move -- truncate data */
@@ -1901,10 +2211,11 @@ logdelivery(m, mci, stat, ctladdr, e)
bp += strlen(bp);
(void) strcpy(bp, shortenstring(stat, (STATLEN)));
-
+
+ /* id, to: max 13 + TOBUFSIZE bytes */
l = SYSLOG_BUFSIZE - 100 - strlen(buf);
p = e->e_to;
- while (strlen(p) >= l)
+ while (strlen(p) >= (SIZE_T) l)
{
register char *q = strchr(p + l, ',');
@@ -1950,13 +2261,18 @@ logdelivery(m, mci, stat, ctladdr, e)
bp = buf;
sprintf(bp, "delay=%s", pintvl(curtime() - e->e_ctime, TRUE));
bp += strlen(bp);
+ if (xstart != (time_t) 0)
+ {
+ sprintf(bp, ", xdelay=%s", pintvl(curtime() - xstart, TRUE));
+ bp += strlen(bp);
+ }
if (m != NULL)
{
sprintf(bp, ", mailer=%s", m->m_name);
bp += strlen(bp);
}
- syslog(LOG_INFO, "%s: %s", e->e_id, buf);
+ syslog(LOG_INFO, "%s: %.1000s", e->e_id, buf);
buf[0] = '\0';
if (mci != NULL && mci->mci_host != NULL)
@@ -1965,12 +2281,11 @@ logdelivery(m, mci, stat, ctladdr, e)
extern SOCKADDR CurHostAddr;
# endif
- sprintf(buf, "relay=%s", mci->mci_host);
+ sprintf(buf, "relay=%.100s", mci->mci_host);
# ifdef DAEMON
- (void) strcat(buf, " [");
- (void) strcat(buf, anynet_ntoa(&CurHostAddr));
- (void) strcat(buf, "]");
+ if (CurHostAddr.sa.sa_family != 0)
+ sprintf(bp, " [%.100s]", anynet_ntoa(&CurHostAddr));
# endif
}
else if (strcmp(stat, "queued") != 0)
@@ -1978,15 +2293,17 @@ logdelivery(m, mci, stat, ctladdr, e)
char *p = macvalue('h', e);
if (p != NULL && p[0] != '\0')
- sprintf(buf, "relay=%s", p);
+ sprintf(buf, "relay=%.100s", p);
}
if (buf[0] != '\0')
- syslog(LOG_INFO, "%s: %s", e->e_id, buf);
+ syslog(LOG_INFO, "%s: %.1000s", e->e_id, buf);
syslog(LOG_INFO, "%s: stat=%s", e->e_id, shortenstring(stat, 63));
# endif /* short log buffer */
# endif /* LOG */
}
+
+#undef SPACELEFT
/*
** PUTFROMLINE -- output a UNIX-style from line (or whatever)
**
@@ -2008,23 +2325,23 @@ logdelivery(m, mci, stat, ctladdr, e)
** outputs some text to fp.
*/
+void
putfromline(mci, e)
register MCI *mci;
ENVELOPE *e;
{
- char *template = "\201l\n";
+ char *template = UnixFromLine;
char buf[MAXLINE];
if (bitnset(M_NHDR, mci->mci_mailer->m_flags))
return;
-# ifdef UGLYUUCP
if (bitnset(M_UGLYUUCP, mci->mci_mailer->m_flags))
{
char *bang;
char xbuf[MAXLINE];
- expand("\201g", buf, &buf[sizeof buf - 1], e);
+ expand("\201g", buf, sizeof buf, e);
bang = strchr(buf, '!');
if (bang == NULL)
{
@@ -2034,13 +2351,13 @@ putfromline(mci, e)
else
{
*bang++ = '\0';
- (void) sprintf(xbuf, "From %s \201d remote from %s\n", bang, buf);
+ (void) sprintf(xbuf, "From %.800s \201d remote from %.100s\n",
+ bang, buf);
template = xbuf;
}
}
-# endif /* UGLYUUCP */
- expand(template, buf, &buf[sizeof buf - 1], e);
- putline(buf, mci);
+ expand(template, buf, sizeof buf, e);
+ putxline(buf, mci, PXLF_NOTHINGSPECIAL);
}
/*
** PUTBODY -- put the body of a message.
@@ -2058,6 +2375,12 @@ putfromline(mci, e)
** The message is written onto fp.
*/
+/* values for output state variable */
+#define OS_HEAD 0 /* at beginning of line */
+#define OS_CR 1 /* read a carriage return */
+#define OS_INLINE 2 /* putting rest of line */
+
+void
putbody(mci, e, separator)
register MCI *mci;
register ENVELOPE *e;
@@ -2069,45 +2392,244 @@ putbody(mci, e, separator)
** Output the body of the message
*/
+ if (e->e_dfp == NULL && bitset(EF_HAS_DF, e->e_flags))
+ {
+ char *df = queuename(e, 'd');
+
+ e->e_dfp = fopen(df, "r");
+ if (e->e_dfp == NULL)
+ syserr("putbody: Cannot open %s for %s from %s",
+ df, e->e_to, e->e_from.q_paddr);
+ }
if (e->e_dfp == NULL)
{
- if (e->e_df != NULL)
+ if (bitset(MCIF_INHEADER, mci->mci_flags))
{
- e->e_dfp = fopen(e->e_df, "r");
- if (e->e_dfp == NULL)
- syserr("putbody: Cannot open %s for %s from %s",
- e->e_df, e->e_to, e->e_from.q_paddr);
+ putline("", mci);
+ mci->mci_flags &= ~MCIF_INHEADER;
}
+ putline("<<< No Message Collected >>>", mci);
+ goto endofmessage;
+ }
+ if (e->e_dfino == (ino_t) 0)
+ {
+ struct stat stbuf;
+
+ if (fstat(fileno(e->e_dfp), &stbuf) < 0)
+ e->e_dfino = -1;
else
- putline("<<< No Message Collected >>>", mci);
+ {
+ e->e_dfdev = stbuf.st_dev;
+ e->e_dfino = stbuf.st_ino;
+ }
}
- if (e->e_dfp != NULL)
+ rewind(e->e_dfp);
+
+#if MIME8TO7
+ if (bitset(MCIF_CVT8TO7, mci->mci_flags))
{
- rewind(e->e_dfp);
- while (!ferror(mci->mci_out) && fgets(buf, sizeof buf, e->e_dfp) != NULL)
+ char *boundaries[MAXMIMENESTING + 1];
+
+ /*
+ ** Do 8 to 7 bit MIME conversion.
+ */
+
+ /* make sure it looks like a MIME message */
+ if (hvalue("MIME-Version", e->e_header) == NULL)
+ putline("MIME-Version: 1.0", mci);
+
+ if (hvalue("Content-Type", e->e_header) == NULL)
{
- if (buf[0] == 'F' &&
- bitnset(M_ESCFROM, mci->mci_mailer->m_flags) &&
- strncmp(buf, "From ", 5) == 0)
- (void) putc('>', mci->mci_out);
- if (buf[0] == '-' && buf[1] == '-' && separator != NULL)
+ sprintf(buf, "Content-Type: text/plain; charset=%s",
+ defcharset(e));
+ putline(buf, mci);
+ }
+
+ /* now do the hard work */
+ boundaries[0] = NULL;
+ mime8to7(mci, e->e_header, e, boundaries, M87F_OUTER);
+ }
+ else
+#endif
+ {
+ int ostate;
+ register char *bp;
+ register char *pbp;
+ register int c;
+ int padc;
+ char *buflim;
+ int pos = 0;
+ char peekbuf[10];
+
+ /* we can pass it through unmodified */
+ if (bitset(MCIF_INHEADER, mci->mci_flags))
+ {
+ putline("", mci);
+ mci->mci_flags &= ~MCIF_INHEADER;
+ }
+
+ /* determine end of buffer; allow for short mailer lines */
+ buflim = &buf[sizeof buf - 1];
+ if (mci->mci_mailer->m_linelimit > 0 &&
+ mci->mci_mailer->m_linelimit < sizeof buf - 1)
+ buflim = &buf[mci->mci_mailer->m_linelimit - 1];
+
+ /* copy temp file to output with mapping */
+ ostate = OS_HEAD;
+ bp = buf;
+ pbp = peekbuf;
+ while (!ferror(mci->mci_out))
+ {
+ register char *xp;
+
+ if (pbp > peekbuf)
+ c = *--pbp;
+ else if ((c = getc(e->e_dfp)) == EOF)
+ break;
+ if (bitset(MCIF_7BIT, mci->mci_flags))
+ c &= 0x7f;
+ switch (ostate)
{
- /* possible separator */
- int sl = strlen(separator);
+ case OS_HEAD:
+ if (c != '\r' && c != '\n' && bp < buflim)
+ {
+ *bp++ = c;
+ break;
+ }
+
+ /* check beginning of line for special cases */
+ *bp = '\0';
+ pos = 0;
+ padc = EOF;
+ if (buf[0] == 'F' &&
+ bitnset(M_ESCFROM, mci->mci_mailer->m_flags) &&
+ strncmp(buf, "From ", 5) == 0)
+ {
+ padc = '>';
+ }
+ if (buf[0] == '-' && buf[1] == '-' &&
+ separator != NULL)
+ {
+ /* possible separator */
+ int sl = strlen(separator);
+
+ if (strncmp(&buf[2], separator, sl) == 0)
+ padc = ' ';
+ }
+ if (buf[0] == '.' &&
+ bitnset(M_XDOT, mci->mci_mailer->m_flags))
+ {
+ padc = '.';
+ }
+
+ /* now copy out saved line */
+ if (TrafficLogFile != NULL)
+ {
+ fprintf(TrafficLogFile, "%05d >>> ", getpid());
+ if (padc != EOF)
+ putc(padc, TrafficLogFile);
+ for (xp = buf; xp < bp; xp++)
+ putc(*xp, TrafficLogFile);
+ if (c == '\n')
+ fputs(mci->mci_mailer->m_eol,
+ TrafficLogFile);
+ }
+ if (padc != EOF)
+ {
+ putc(padc, mci->mci_out);
+ pos++;
+ }
+ for (xp = buf; xp < bp; xp++)
+ putc(*xp, mci->mci_out);
+ if (c == '\n')
+ {
+ fputs(mci->mci_mailer->m_eol,
+ mci->mci_out);
+ pos = 0;
+ }
+ else
+ {
+ pos += bp - buf;
+ if (c != '\r')
+ *pbp++ = c;
+ }
+ bp = buf;
- if (strncmp(&buf[2], separator, sl) == 0)
- (void) putc(' ', mci->mci_out);
+ /* determine next state */
+ if (c == '\n')
+ ostate = OS_HEAD;
+ else if (c == '\r')
+ ostate = OS_CR;
+ else
+ ostate = OS_INLINE;
+ continue;
+
+ case OS_CR:
+ if (c == '\n')
+ {
+ /* got CRLF */
+ fputs(mci->mci_mailer->m_eol, mci->mci_out);
+ if (TrafficLogFile != NULL)
+ {
+ fputs(mci->mci_mailer->m_eol,
+ TrafficLogFile);
+ }
+ ostate = OS_HEAD;
+ continue;
+ }
+
+ /* had a naked carriage return */
+ *pbp++ = c;
+ c = '\r';
+ goto putch;
+
+ case OS_INLINE:
+ if (c == '\r')
+ {
+ ostate = OS_CR;
+ continue;
+ }
+putch:
+ if (mci->mci_mailer->m_linelimit > 0 &&
+ pos > mci->mci_mailer->m_linelimit &&
+ c != '\n')
+ {
+ putc('!', mci->mci_out);
+ fputs(mci->mci_mailer->m_eol, mci->mci_out);
+ if (TrafficLogFile != NULL)
+ {
+ fprintf(TrafficLogFile, "!%s",
+ mci->mci_mailer->m_eol);
+ }
+ ostate = OS_HEAD;
+ *pbp++ = c;
+ continue;
+ }
+ if (TrafficLogFile != NULL)
+ putc(c, TrafficLogFile);
+ putc(c, mci->mci_out);
+ pos++;
+ ostate = c == '\n' ? OS_HEAD : OS_INLINE;
+ break;
}
- putline(buf, mci);
}
- if (ferror(e->e_dfp))
+ /* make sure we are at the beginning of a line */
+ if (bp > buf)
{
- syserr("putbody: %s: read error", e->e_df);
- ExitStat = EX_IOERR;
+ *bp = '\0';
+ fputs(buf, mci->mci_out);
+ fputs(mci->mci_mailer->m_eol, mci->mci_out);
}
}
+ if (ferror(e->e_dfp))
+ {
+ syserr("putbody: df%s: read error", e->e_id);
+ ExitStat = EX_IOERR;
+ }
+
+endofmessage:
/* some mailers want extra blank line at end of message */
if (bitnset(M_BLANKEND, mci->mci_mailer->m_flags) &&
buf[0] != '\0' && buf[0] != '\n')
@@ -2139,6 +2661,8 @@ putbody(mci, e, separator)
** filename -- the name of the file to send to.
** ctladdr -- the controlling address header -- includes
** the userid/groupid to be when sending.
+** sfflags -- flags for opening.
+** e -- the current envelope.
**
** Returns:
** The exit code associated with the operation.
@@ -2147,13 +2671,15 @@ putbody(mci, e, separator)
** none.
*/
-mailfile(filename, ctladdr, e)
+int
+mailfile(filename, ctladdr, sfflags, e)
char *filename;
ADDRESS *ctladdr;
+ int sfflags;
register ENVELOPE *e;
{
register FILE *f;
- register int pid;
+ register int pid = -1;
int mode;
if (tTd(11, 1))
@@ -2184,22 +2710,27 @@ mailfile(filename, ctladdr, e)
int oflags = O_WRONLY|O_APPEND;
if (e->e_lockfp != NULL)
- {
- fclose(e->e_lockfp);
- e->e_lockfp = NULL;
- }
+ (void) close(fileno(e->e_lockfp));
(void) setsignal(SIGINT, SIG_DFL);
(void) setsignal(SIGHUP, SIG_DFL);
(void) setsignal(SIGTERM, SIG_DFL);
(void) umask(OldUmask);
+ e->e_to = filename;
+ ExitStat = EX_OK;
+#ifdef HASLSTAT
+ if ((SafeFileEnv != NULL ? lstat(filename, &stb)
+ : stat(filename, &stb)) < 0)
+#else
if (stat(filename, &stb) < 0)
+#endif
{
stb.st_mode = FileMode;
oflags |= O_CREAT|O_EXCL;
}
- else if (bitset(0111, stb.st_mode))
+ else if (bitset(0111, stb.st_mode) || stb.st_nlink != 1 ||
+ (SafeFileEnv != NULL && !S_ISREG(stb.st_mode)))
exit(EX_CANTCREAT);
mode = stb.st_mode;
@@ -2207,59 +2738,108 @@ mailfile(filename, ctladdr, e)
errno = 0;
ExitStat = EX_OK;
- if (ctladdr != NULL)
+ if (ctladdr != NULL || bitset(SFF_RUNASREALUID, sfflags))
{
/* ignore setuid and setgid bits */
mode &= ~(S_ISGID|S_ISUID);
}
/* we have to open the dfile BEFORE setuid */
- if (e->e_dfp == NULL && e->e_df != NULL)
+ if (e->e_dfp == NULL && bitset(EF_HAS_DF, e->e_flags))
{
- e->e_dfp = fopen(e->e_df, "r");
+ char *df = queuename(e, 'd');
+
+ e->e_dfp = fopen(df, "r");
if (e->e_dfp == NULL)
{
syserr("mailfile: Cannot open %s for %s from %s",
- e->e_df, e->e_to, e->e_from.q_paddr);
+ df, e->e_to, e->e_from.q_paddr);
}
}
- if (!bitset(S_ISGID, mode) || setgid(stb.st_gid) < 0)
+ /* select a new user to run as */
+ if (!bitset(SFF_RUNASREALUID, sfflags))
{
- if (ctladdr == NULL || ctladdr->q_uid == 0)
+ if (bitset(S_ISUID, mode))
{
- (void) initgroups(DefUser, DefGid);
+ RealUserName = NULL;
+ RealUid = stb.st_uid;
+ }
+ else if (ctladdr != NULL && ctladdr->q_uid != 0)
+ {
+ if (ctladdr->q_ruser != NULL)
+ RealUserName = ctladdr->q_ruser;
+ else
+ RealUserName = ctladdr->q_user;
+ RealUid = ctladdr->q_uid;
+ }
+ else if (FileMailer != NULL && FileMailer->m_uid != 0)
+ {
+ RealUserName = DefUser;
+ RealUid = FileMailer->m_uid;
}
else
{
- (void) initgroups(ctladdr->q_ruser ?
- ctladdr->q_ruser : ctladdr->q_user,
- ctladdr->q_gid);
+ RealUserName = DefUser;
+ RealUid = DefUid;
}
+
+ /* select a new group to run as */
+ if (bitset(S_ISGID, mode))
+ RealGid = stb.st_gid;
+ else if (ctladdr != NULL && ctladdr->q_uid != 0)
+ RealGid = ctladdr->q_gid;
+ else if (FileMailer != NULL && FileMailer->m_gid != 0)
+ RealGid = FileMailer->m_gid;
+ else
+ RealGid = DefGid;
}
- if (!bitset(S_ISUID, mode) || setuid(stb.st_uid) < 0)
+
+ /* last ditch */
+ if (!bitset(SFF_ROOTOK, sfflags))
{
- if (ctladdr == NULL || ctladdr->q_uid == 0)
- (void) setuid(DefUid);
- else
- (void) setuid(ctladdr->q_uid);
+ if (RealUid == 0)
+ RealUid = DefUid;
+ if (RealGid == 0)
+ RealGid = DefGid;
+ }
+
+ /* now set the group and user ids */
+ endpwent();
+ if (RealUserName != NULL && !DontInitGroups)
+ (void) initgroups(RealUserName, RealGid);
+ (void) setgid(RealGid);
+ (void) setuid(RealUid);
+
+ /* if you have a safe environment, go into it */
+ if (SafeFileEnv != NULL && SafeFileEnv[0] != '\0')
+ {
+ int i;
+
+ if (chroot(SafeFileEnv) < 0)
+ {
+ syserr("mailfile: Cannot chroot(%s)",
+ SafeFileEnv);
+ exit(EX_CANTCREAT);
+ }
+ i = strlen(SafeFileEnv);
+ if (strncmp(SafeFileEnv, filename, i) == 0)
+ filename += i;
}
- FileName = filename;
- LineNumber = 0;
- f = dfopen(filename, oflags, FileMode);
+ if (chdir("/") < 0)
+ syserr("mailfile: cannot chdir(/)");
+
+ sfflags |= SFF_NOPATHCHECK;
+ sfflags &= ~SFF_OPENASROOT;
+ f = safefopen(filename, oflags, FileMode, sfflags);
if (f == NULL)
{
message("554 cannot open: %s", errstring(errno));
exit(EX_CANTCREAT);
}
- if (fstat(fileno(f), &fsb) < 0 ||
- !bitset(O_CREAT, oflags) &&
- (stb.st_nlink != fsb.st_nlink ||
- stb.st_dev != fsb.st_dev ||
- stb.st_ino != fsb.st_ino ||
- stb.st_uid != fsb.st_uid))
+ if (fstat(fileno(f), &stb) < 0)
{
- message("554 cannot write: file changed after open");
+ message("554 cannot fstat %s", errstring(errno));
exit(EX_CANTCREAT);
}
@@ -2270,20 +2850,23 @@ mailfile(filename, ctladdr, e)
mcibuf.mci_flags |= MCIF_7BIT;
putfromline(&mcibuf, e);
- (*e->e_puthdr)(&mcibuf, e);
- putline("\n", &mcibuf);
+ (*e->e_puthdr)(&mcibuf, e->e_header, e);
(*e->e_putbody)(&mcibuf, e, NULL);
putline("\n", &mcibuf);
- if (ferror(f))
+ if (fflush(f) < 0 || ferror(f))
{
message("451 I/O error: %s", errstring(errno));
setstat(EX_IOERR);
}
- (void) xfclose(f, "mailfile", filename);
- (void) fflush(stdout);
/* reset ISUID & ISGID bits for paranoid systems */
+#if HASFCHMOD
+ (void) fchmod(fileno(f), (int) stb.st_mode);
+#else
(void) chmod(filename, (int) stb.st_mode);
+#endif
+ (void) xfclose(f, "mailfile", filename);
+ (void) fflush(stdout);
exit(ExitStat);
/*NOTREACHED*/
}
@@ -2337,7 +2920,7 @@ hostsignature(m, host, e)
auto int rcode;
char *hp;
char *endp;
- int oldoptions;
+ int oldoptions = _res.options;
char *mxhosts[MAXMXHOSTS + 1];
#endif
@@ -2366,10 +2949,7 @@ hostsignature(m, host, e)
#if NAMED_BIND
if (ConfigLevel < 2)
- {
- oldoptions = _res.options;
_res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */
- }
for (hp = host; hp != NULL; hp = endp)
{
@@ -2385,11 +2965,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;
-#if NAMED_BIND
mci->mci_herrno = h_errno;
-#endif
/* and return the original host name as the signature */
nmx = 1;
diff --git a/usr.sbin/sendmail/src/domain.c b/usr.sbin/sendmail/src/domain.c
index da2a795..8058330 100644
--- a/usr.sbin/sendmail/src/domain.c
+++ b/usr.sbin/sendmail/src/domain.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1986 Eric P. Allman
+ * Copyright (c) 1986, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -36,23 +36,21 @@
#ifndef lint
#if NAMED_BIND
-static char sccsid[] = "@(#)domain.c 8.19.1.1 (Berkeley) 3/6/95 (with name server)";
+static char sccsid[] = "@(#)domain.c 8.54 (Berkeley) 9/28/95 (with name server)";
#else
-static char sccsid[] = "@(#)domain.c 8.19.1.1 (Berkeley) 3/6/95 (without name server)";
+static char sccsid[] = "@(#)domain.c 8.54 (Berkeley) 9/28/95 (without name server)";
#endif
#endif /* not lint */
#if NAMED_BIND
#include <errno.h>
-#include <arpa/nameser.h>
#include <resolv.h>
-#include <netdb.h>
typedef union
{
HEADER qb1;
- char qb2[PACKETSZ];
+ u_char qb2[PACKETSZ];
} querybuf;
static char MXHostBuf[MAXMXHOSTS*PACKETSZ];
@@ -69,15 +67,17 @@ static char MXHostBuf[MAXMXHOSTS*PACKETSZ];
# define NO_DATA NO_ADDRESS
#endif
-#ifndef HEADERSZ
-# define HEADERSZ sizeof(HEADER)
+#ifndef HFIXEDSZ
+# define HFIXEDSZ 12 /* sizeof(HEADER) */
#endif
-/* don't use sizeof because sizeof(long) is different on 64-bit machines */
-#define SHORTSIZE 2 /* size of a short (really, must be 2) */
-#define LONGSIZE 4 /* size of a long (really, must be 4) */
-
#define MAXCNAMEDEPTH 10 /* maximum depth of CNAME recursion */
+
+#if defined(__RES) && (__RES >= 19940415)
+# define RES_UNC_T char *
+#else
+# define RES_UNC_T u_char *
+#endif
/*
** GETMXRR -- get MX resource records for a domain
**
@@ -96,13 +96,13 @@ static char MXHostBuf[MAXMXHOSTS*PACKETSZ];
** and 1 is returned.
*/
+int
getmxrr(host, mxhosts, droplocalhost, rcode)
char *host;
char **mxhosts;
bool droplocalhost;
int *rcode;
{
- extern int h_errno;
register u_char *eom, *cp;
register int i, j, n;
int nmx = 0;
@@ -111,11 +111,13 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
querybuf answer;
int ancount, qdcount, buflen;
bool seenlocal = FALSE;
- u_short pref, localpref, type;
+ u_short pref, type;
+ u_short localpref = 256;
char *fallbackMX = FallBackMX;
static bool firsttime = TRUE;
- STAB *st;
bool trycanon = FALSE;
+ int (*resfunc)();
+ extern int res_query(), res_search();
u_short prefer[MAXMXHOSTS];
int weight[MAXMXHOSTS];
extern bool getcanonname();
@@ -125,15 +127,14 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
if (fallbackMX != NULL)
{
- if (firsttime && res_query(FallBackMX, C_IN, T_A,
- (char *) &answer, sizeof answer) < 0)
+ if (firsttime &&
+ res_query(FallBackMX, C_IN, T_A,
+ (u_char *) &answer, sizeof answer) < 0)
{
/* this entry is bogus */
fallbackMX = FallBackMX = NULL;
}
- else if (droplocalhost &&
- (st = stab(fallbackMX, ST_CLASS, ST_FIND)) != NULL &&
- bitnset('w', st->s_class))
+ else if (droplocalhost && wordinclass(fallbackMX, 'w'))
{
/* don't use fallback for this pass */
fallbackMX = NULL;
@@ -141,12 +142,29 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
firsttime = FALSE;
}
+ *rcode = EX_OK;
+
/* efficiency hack -- numeric or non-MX lookups */
if (host[0] == '[')
goto punt;
+ /*
+ ** If we don't have MX records in our host switch, don't
+ ** try for MX records. Note that this really isn't "right",
+ ** since we might be set up to try NIS first and then DNS;
+ ** if the host is found in NIS we really shouldn't be doing
+ ** MX lookups. However, that should be a degenerate case.
+ */
+
+ if (!UseNameServer)
+ goto punt;
+ if (HasWildcardMX && ConfigLevel >= 6)
+ resfunc = res_query;
+ else
+ resfunc = res_search;
+
errno = 0;
- n = res_search(host, C_IN, T_MX, (char *)&answer, sizeof(answer));
+ n = (*resfunc)(host, C_IN, T_MX, (u_char *) &answer, sizeof(answer));
if (n < 0)
{
if (tTd(8, 1))
@@ -163,25 +181,22 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
goto punt;
case HOST_NOT_FOUND:
-#ifdef BROKEN_RES_SEARCH
- /* Ultrix resolver returns failure w/ h_errno=0 */
- case 0:
+#if BROKEN_RES_SEARCH
+ case 0: /* Ultrix resolver retns failure w/ h_errno=0 */
#endif
- /* the host just doesn't exist */
+ /* host doesn't exist in DNS; might be in /etc/hosts */
+ trycanon = TRUE;
*rcode = EX_NOHOST;
-
- if (!UseNameServer)
- {
- /* might exist in /etc/hosts */
- goto punt;
- }
- break;
+ goto punt;
case TRY_AGAIN:
/* couldn't connect to the name server */
- if (!UseNameServer && errno == ECONNREFUSED)
- goto punt;
-
+ if (fallbackMX != NULL)
+ {
+ /* name server is hosed -- push to fallback */
+ mxhosts[nmx++] = fallbackMX;
+ return nmx;
+ }
/* it might come up later; better queue it up */
*rcode = EX_TEMPFAIL;
break;
@@ -199,7 +214,7 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
/* find first satisfactory answer */
hp = (HEADER *)&answer;
- cp = (u_char *)&answer + HEADERSZ;
+ cp = (u_char *)&answer + HFIXEDSZ;
eom = (u_char *)&answer + n;
for (qdcount = ntohs(hp->qdcount); qdcount--; cp += n + QFIXEDSZ)
if ((n = dn_skipname(cp, eom)) < 0)
@@ -210,11 +225,11 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
while (--ancount >= 0 && cp < eom && nmx < MAXMXHOSTS - 1)
{
if ((n = dn_expand((u_char *)&answer,
- eom, cp, (u_char *)bp, buflen)) < 0)
+ eom, cp, (RES_UNC_T) bp, buflen)) < 0)
break;
cp += n;
GETSHORT(type, cp);
- cp += SHORTSIZE + LONGSIZE;
+ cp += INT16SZ + INT32SZ;
GETSHORT(n, cp);
if (type != T_MX)
{
@@ -226,22 +241,25 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
}
GETSHORT(pref, cp);
if ((n = dn_expand((u_char *)&answer, eom, cp,
- (u_char *)bp, buflen)) < 0)
+ (RES_UNC_T) bp, buflen)) < 0)
break;
cp += n;
- if (droplocalhost &&
- (st = stab(bp, ST_CLASS, ST_FIND)) != NULL &&
- bitnset('w', st->s_class))
+ if (wordinclass(bp, 'w'))
{
if (tTd(8, 3))
printf("found localhost (%s) in MX list, pref=%d\n",
bp, pref);
- if (!seenlocal || pref < localpref)
- localpref = pref;
- seenlocal = TRUE;
- continue;
+ if (droplocalhost)
+ {
+ if (!seenlocal || pref < localpref)
+ localpref = pref;
+ seenlocal = TRUE;
+ continue;
+ }
+ weight[nmx] = 0;
}
- weight[nmx] = mxrand(bp);
+ else
+ weight[nmx] = mxrand(bp);
prefer[nmx] = pref;
mxhosts[nmx++] = bp;
n = strlen(bp);
@@ -284,11 +302,25 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
}
}
+ /* delete duplicates from list (yes, some bozos have duplicates) */
+ for (i = 0; i < nmx - 1; )
+ {
+ if (strcasecmp(mxhosts[i], mxhosts[i + 1]) != 0)
+ i++;
+ else
+ {
+ /* compress out duplicate */
+ for (j = i + 1; j < nmx; j++)
+ mxhosts[j] = mxhosts[j + 1];
+ nmx--;
+ }
+ }
+
if (nmx == 0)
{
punt:
if (seenlocal &&
- (!TryNullMXList || gethostbyname(host) == NULL))
+ (!TryNullMXList || sm_gethostbyname(host) == NULL))
{
/*
** If we have deleted all MX entries, this is
@@ -336,8 +368,8 @@ punt:
*bp++ = '.';
*bp = '\0';
}
+ nmx = 1;
}
- nmx = 1;
}
/* if we have a default lowest preference, include that */
@@ -364,6 +396,7 @@ punt:
** none.
*/
+int
mxrand(host)
register char *host;
{
@@ -391,13 +424,43 @@ mxrand(host)
}
hfunc &= 0xff;
+ hfunc++;
if (tTd(17, 9))
printf(" = %d\n", hfunc);
return hfunc;
}
/*
-** GETCANONNAME -- get the canonical name for named host
+** BESTMX -- find the best MX for a name
+**
+** This is really a hack, but I don't see any obvious way
+** to generalize it at the moment.
+*/
+
+char *
+bestmx_map_lookup(map, name, av, statp)
+ MAP *map;
+ char *name;
+ char **av;
+ int *statp;
+{
+ int nmx;
+ auto int rcode;
+ int saveopts = _res.options;
+ char *mxhosts[MAXMXHOSTS + 1];
+
+ _res.options &= ~(RES_DNSRCH|RES_DEFNAMES);
+ nmx = getmxrr(name, mxhosts, FALSE, &rcode);
+ _res.options = saveopts;
+ if (nmx <= 0)
+ return NULL;
+ if (bitset(MF_MATCHONLY, map->map_mflags))
+ return map_rewrite(map, name, strlen(name), NULL);
+ else
+ return map_rewrite(map, mxhosts[0], strlen(mxhosts[0]), av);
+}
+ /*
+** DNS_GETCANONNAME -- get the canonical name for named host using DNS
**
** This algorithm tries to be smart about wildcard MX records.
** This is hard to do because DNS doesn't tell is if we matched
@@ -419,6 +482,7 @@ mxrand(host)
** This is a value-result parameter.
** hbsize -- the size of the host buffer.
** trymx -- if set, try MX records as well as A and CNAME.
+** statp -- pointer to place to store status.
**
** Returns:
** TRUE -- if the host matched.
@@ -426,12 +490,12 @@ mxrand(host)
*/
bool
-getcanonname(host, hbsize, trymx)
+dns_getcanonname(host, hbsize, trymx, statp)
char *host;
int hbsize;
bool trymx;
+ int *statp;
{
- extern int h_errno;
register u_char *eom, *ap;
register char *cp;
register int n;
@@ -444,7 +508,7 @@ getcanonname(host, hbsize, trymx)
char **dp;
char *mxmatch;
bool amatch;
- bool gotmx;
+ bool gotmx = FALSE;
int qtype;
int loopcnt;
char *xp;
@@ -453,10 +517,13 @@ getcanonname(host, hbsize, trymx)
extern char *gethostalias();
if (tTd(8, 2))
- printf("getcanonname(%s)\n", host);
+ printf("dns_getcanonname(%s, trymx=%d)\n", host, trymx);
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
- return (FALSE);
+ {
+ *statp = EX_UNAVAILABLE;
+ return FALSE;
+ }
/*
** Initialize domain search list. If there is at least one
@@ -470,10 +537,15 @@ getcanonname(host, hbsize, trymx)
loopcnt = 0;
cnameloop:
- for (cp = host, n = 0; *cp; cp++)
+ /* Check for dots in the name */
+ for (cp = host, n = 0; *cp != '\0'; cp++)
if (*cp == '.')
n++;
+ /*
+ ** If this is a simple name, determine whether it matches an
+ ** alias in the file defined by the environment variable HOSTALIASES.
+ */
if (n == 0 && (xp = gethostalias(host)) != NULL)
{
if (loopcnt++ > MAXCNAMEDEPTH)
@@ -488,6 +560,17 @@ cnameloop:
}
}
+ /*
+ ** Build the search list.
+ ** If there is at least one dot in name, start with a null
+ ** domain to search the unmodified name first.
+ ** If name does not end with a dot and search up local domain
+ ** tree desired, append each local domain component to the
+ ** search list; if name contains no dots and default domain
+ ** name is desired, append default domain name to search list;
+ ** else if name ends in a dot, remove that dot.
+ */
+
dp = searchlist;
if (n > 0)
*dp++ = "";
@@ -507,7 +590,8 @@ cnameloop:
*dp = NULL;
/*
- ** Now run through the search list for the name in question.
+ ** Now loop through the search list, appending each domain in turn
+ ** name and searching for a match.
*/
mxmatch = NULL;
@@ -518,11 +602,12 @@ cnameloop:
if (qtype == T_ANY)
gotmx = FALSE;
if (tTd(8, 5))
- printf("getcanonname: trying %s.%s (%s)\n", host, *dp,
+ printf("dns_getcanonname: trying %s.%s (%s)\n",
+ host, *dp,
qtype == T_ANY ? "ANY" : qtype == T_A ? "A" :
qtype == T_MX ? "MX" : "???");
ret = res_querydomain(host, *dp, C_IN, qtype,
- (u_char *) &answer, sizeof(answer));
+ answer.qb2, sizeof(answer.qb2));
if (ret <= 0)
{
if (tTd(8, 7))
@@ -533,6 +618,7 @@ cnameloop:
{
/* the name server seems to be down */
h_errno = TRY_AGAIN;
+ *statp = EX_TEMPFAIL;
return FALSE;
}
@@ -551,13 +637,7 @@ cnameloop:
}
}
- if (mxmatch != NULL)
- {
- /* we matched before -- use that one */
- break;
- }
-
- /* otherwise, try the next name */
+ /* definite no -- try the next domain */
dp++;
qtype = T_ANY;
continue;
@@ -566,13 +646,13 @@ cnameloop:
printf("\tYES\n");
/*
- ** This might be a bogus match. Search for A or
- ** CNAME records. If we don't have a matching
+ ** Appear to have a match. Confirm it by searching for A or
+ ** CNAME records. If we don't have a local domain
** wild card MX record, we will accept MX as well.
*/
hp = (HEADER *) &answer;
- ap = (u_char *) &answer + HEADERSZ;
+ ap = (u_char *) &answer + HFIXEDSZ;
eom = (u_char *) &answer + ret;
/* skip question part of response -- we know what we asked */
@@ -583,44 +663,66 @@ cnameloop:
if (tTd(8, 20))
printf("qdcount failure (%d)\n",
ntohs(hp->qdcount));
+ *statp = EX_SOFTWARE;
return FALSE; /* ???XXX??? */
}
}
amatch = FALSE;
- for (ancount = ntohs(hp->ancount); --ancount >= 0 && ap < eom; ap += n)
+ for (ancount = ntohs(hp->ancount); --ancount >= 0 && ap < eom;
+ ap += n)
{
n = dn_expand((u_char *) &answer, eom, ap,
- (u_char *) nbuf, sizeof nbuf);
+ (RES_UNC_T) nbuf, sizeof nbuf);
if (n < 0)
break;
ap += n;
GETSHORT(type, ap);
- ap += SHORTSIZE + LONGSIZE;
+ ap += INT16SZ + INT32SZ;
GETSHORT(n, ap);
switch (type)
{
case T_MX:
gotmx = TRUE;
- if (**dp != '\0')
+ if (**dp != '\0' && HasWildcardMX)
{
- /* got a match -- save that info */
+ /*
+ ** If we are using MX matches and have
+ ** not yet gotten one, save this one
+ ** but keep searching for an A or
+ ** CNAME match.
+ */
+
if (trymx && mxmatch == NULL)
mxmatch = *dp;
continue;
}
- /* exact MX matches are as good as an A match */
- /* fall through */
+ /*
+ ** If we did not append a domain name, this
+ ** must have been a canonical name to start
+ ** with. Even if we did append a domain name,
+ ** in the absence of a wildcard MX this must
+ ** still be a real MX match.
+ ** Such MX matches are as good as an A match,
+ ** fall through.
+ */
case T_A:
- /* good show */
+ /* Flag that a good match was found */
amatch = TRUE;
/* continue in case a CNAME also exists */
continue;
case T_CNAME:
+ if (DontExpandCnames)
+ {
+ /* got CNAME -- guaranteed canonical */
+ amatch = TRUE;
+ break;
+ }
+
if (loopcnt++ > MAXCNAMEDEPTH)
{
/*XXX should notify postmaster XXX*/
@@ -630,17 +732,18 @@ cnameloop:
{
char ebuf[MAXLINE];
- sprintf(ebuf, "Deferred: DNS failure: CNAME loop for %s",
+ sprintf(ebuf, "Deferred: DNS failure: CNAME loop for %.100s",
host);
CurEnv->e_message = newstr(ebuf);
}
h_errno = NO_RECOVERY;
+ *statp = EX_CONFIG;
return FALSE;
}
/* value points at name */
if ((ret = dn_expand((u_char *)&answer,
- eom, ap, (u_char *)nbuf, sizeof(nbuf))) < 0)
+ eom, ap, (RES_UNC_T) nbuf, sizeof(nbuf))) < 0)
break;
(void)strncpy(host, nbuf, hbsize); /* XXX */
host[hbsize - 1] = '\0';
@@ -661,14 +764,24 @@ cnameloop:
if (amatch)
{
- /* got an A record and no CNAME */
+ /*
+ ** Got a good match -- either an A, CNAME, or an
+ ** exact MX record. Save it and get out of here.
+ */
+
mxmatch = *dp;
break;
}
/*
- ** If this was a T_ANY query, we may have the info but
- ** need an explicit query. Try T_A, then T_MX.
+ ** Nothing definitive yet.
+ ** If this was a T_ANY query, we don't really know what
+ ** was returned -- it might have been a T_NS,
+ ** for example. Try T_A to be more specific
+ ** during the next pass.
+ ** If this was a T_A query and we haven't yet found a MX
+ ** match, try T_MX if allowed to do so.
+ ** Otherwise, try the next domain.
*/
if (qtype == T_ANY)
@@ -677,39 +790,51 @@ cnameloop:
qtype = T_MX;
else
{
- /* really nothing in this domain; try the next */
qtype = T_ANY;
dp++;
}
}
+ /* if nothing was found, we are done */
if (mxmatch == NULL)
+ {
+ *statp = EX_NOHOST;
return FALSE;
+ }
+
+ /*
+ ** Create canonical name and return.
+ ** If saved domain name is null, name was already canonical.
+ ** Otherwise append the saved domain name.
+ */
- /* create matching name and return */
(void) sprintf(nbuf, "%.*s%s%.*s", MAXDNAME, host,
*mxmatch == '\0' ? "" : ".",
MAXDNAME, mxmatch);
strncpy(host, nbuf, hbsize);
host[hbsize - 1] = '\0';
+ if (tTd(8, 5))
+ printf("dns_getcanonname: %s\n", host);
+ *statp = EX_OK;
return TRUE;
}
+
char *
gethostalias(host)
char *host;
{
char *fname;
FILE *fp;
- register char *p;
+ register char *p = NULL;
char buf[MAXLINE];
static char hbuf[MAXDNAME];
fname = getenv("HOSTALIASES");
- if (fname == NULL || (fp = fopen(fname, "r")) == NULL)
+ if (fname == NULL ||
+ (fp = safefopen(fname, O_RDONLY, 0, SFF_REGONLY)) == NULL)
return NULL;
- setbuf(fp, NULL);
while (fgets(buf, sizeof buf, fp) != NULL)
{
for (p = buf; p != '\0' && !(isascii(*p) && isspace(*p)); p++)
@@ -743,28 +868,4 @@ gethostalias(host)
return hbuf;
}
-
-#else /* not NAMED_BIND */
-
-#include <netdb.h>
-
-bool
-getcanonname(host, hbsize, trymx)
- char *host;
- int hbsize;
- bool trymx;
-{
- struct hostent *hp;
-
- hp = gethostbyname(host);
- if (hp == NULL)
- return (FALSE);
-
- if (strlen(hp->h_name) >= hbsize)
- return (FALSE);
-
- (void) strcpy(host, hp->h_name);
- return (TRUE);
-}
-
-#endif /* not NAMED_BIND */
+#endif /* NAMED_BIND */
diff --git a/usr.sbin/sendmail/src/headers.c b/usr.sbin/sendmail/src/headers.c
index a55ba95..9bad1f8 100644
--- a/usr.sbin/sendmail/src/headers.c
+++ b/usr.sbin/sendmail/src/headers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)headers.c 8.32 (Berkeley) 4/14/94";
+static char sccsid[] = "@(#)headers.c 8.82 (Berkeley) 10/28/95";
#endif /* not lint */
# include <errno.h>
@@ -47,6 +47,7 @@ static char sccsid[] = "@(#)headers.c 8.32 (Berkeley) 4/14/94";
** Parameters:
** line -- header as a text line.
** def -- if set, this is a default value.
+** hdrp -- a pointer to the place to save the header.
** e -- the envelope including this header.
**
** Returns:
@@ -57,9 +58,11 @@ static char sccsid[] = "@(#)headers.c 8.32 (Berkeley) 4/14/94";
** Contents of 'line' are destroyed.
*/
-chompheader(line, def, e)
+int
+chompheader(line, def, hdrp, e)
char *line;
bool def;
+ HDR **hdrp;
register ENVELOPE *e;
{
register char *p;
@@ -69,11 +72,20 @@ chompheader(line, def, e)
char *fvalue;
struct hdrinfo *hi;
bool cond = FALSE;
+ bool headeronly;
BITMAP mopts;
- char buf[MAXNAME];
+ char buf[MAXNAME + 1];
if (tTd(31, 6))
- printf("chompheader: %s\n", line);
+ {
+ printf("chompheader: ");
+ xputs(line);
+ printf("\n");
+ }
+
+ headeronly = hdrp != NULL;
+ if (!headeronly)
+ hdrp = &e->e_header;
/* strip off options */
clrbitmap(mopts);
@@ -91,7 +103,7 @@ chompheader(line, def, e)
p = q;
}
else
- usrerr("553 header syntax error, line \"%s\"", line);
+ syserr("553 header syntax error, line \"%s\"", line);
cond = TRUE;
}
@@ -114,6 +126,10 @@ chompheader(line, def, e)
if (*fvalue == ' ')
fvalue++;
+ /* security scan: long field names are end-of-header */
+ if (strlen(fname) > 100)
+ return H_EOH;
+
/* see if it is a known type */
for (hi = HdrInfo; hi->hi_field != NULL; hi++)
{
@@ -126,17 +142,38 @@ chompheader(line, def, e)
if (hi->hi_field == NULL)
printf("no header match\n");
else
- printf("header match, hi_flags=%o\n", hi->hi_flags);
+ printf("header match, hi_flags=%x\n", hi->hi_flags);
}
/* see if this is a resent message */
- if (!def && bitset(H_RESENT, hi->hi_flags))
+ if (!def && !headeronly && bitset(H_RESENT, hi->hi_flags))
e->e_flags |= EF_RESENT;
+ /* if this is an Errors-To: header keep track of it now */
+ if (UseErrorsTo && !def && !headeronly &&
+ bitset(H_ERRORSTO, hi->hi_flags))
+ (void) sendtolist(fvalue, NULLADDR, &e->e_errorqueue, 0, e);
+
/* if this means "end of header" quit now */
if (bitset(H_EOH, hi->hi_flags))
return (hi->hi_flags);
+#ifdef LOTUS_NOTES_HACK
+ /*
+ ** Horrible hack to work around problem with Lotus Notes SMTP
+ ** mail gateway, which generates From: headers with newlines in
+ ** them and the <address> on the second line. Although this is
+ ** legal RFC 822, many MUAs don't handle this properly and thus
+ ** never find the actual address.
+ */
+
+ if (bitset(H_FROM, hi->hi_flags) && SingleLineFromHeader)
+ {
+ while ((p = strchr(fvalue, '\n')) != NULL)
+ *p = ' ';
+ }
+#endif
+
/*
** Drop explicit From: if same as what we would generate.
** This is to make MH (which doesn't always give a full name)
@@ -146,7 +183,8 @@ chompheader(line, def, e)
p = "resent-from";
if (!bitset(EF_RESENT, e->e_flags))
p += 7;
- if (!def && !bitset(EF_QUEUERUN, e->e_flags) && strcasecmp(fname, p) == 0)
+ if (!def && !headeronly && !bitset(EF_QUEUERUN, e->e_flags) &&
+ strcasecmp(fname, p) == 0)
{
if (tTd(31, 2))
{
@@ -158,7 +196,7 @@ chompheader(line, def, e)
strcmp(fvalue, e->e_from.q_user) == 0))
return (hi->hi_flags);
#ifdef MAYBENEXTRELEASE /* XXX UNTESTED XXX UNTESTED XXX UNTESTED XXX */
-#ifdef USERDB
+#if USERDB
else
{
auto ADDRESS a;
@@ -183,13 +221,13 @@ chompheader(line, def, e)
SuprErrs = TRUE;
fancy = crackaddr(fvalue);
if (parseaddr(fvalue, &a, RF_COPYNONE, '\0', NULL, e) != NULL &&
- a.q_mailer == LocalMailer &&
+ bitnset(M_CHECKUDB, a.q_mailer->m_flags) &&
(p = udbsender(a.q_user)) != NULL)
{
char *oldg = macvalue('g', e);
define('g', p, e);
- expand(fancy, buf, &buf[sizeof buf], e);
+ expand(fancy, buf, sizeof buf, e);
define('g', oldg, e);
fvalue = buf;
}
@@ -200,12 +238,20 @@ chompheader(line, def, e)
}
/* delete default value for this header */
- for (hp = &e->e_header; (h = *hp) != NULL; hp = &h->h_link)
+ for (hp = hdrp; (h = *hp) != NULL; hp = &h->h_link)
{
if (strcasecmp(fname, h->h_field) == 0 &&
bitset(H_DEFAULT, h->h_flags) &&
!bitset(H_FORCE, h->h_flags))
+ {
h->h_value = NULL;
+ if (!cond)
+ {
+ /* copy conditions from default case */
+ bcopy((char *)h->h_mflags, (char *)mopts,
+ sizeof mopts);
+ }
+ }
}
/* create a new node */
@@ -222,7 +268,7 @@ chompheader(line, def, e)
h->h_flags |= H_CHECK;
/* hack to see if this is a new format message */
- if (!def && bitset(H_RCPT|H_FROM, h->h_flags) &&
+ if (!def && !headeronly && bitset(H_RCPT|H_FROM, h->h_flags) &&
(strchr(fvalue, ',') != NULL || strchr(fvalue, '(') != NULL ||
strchr(fvalue, '<') != NULL || strchr(fvalue, ';') != NULL))
{
@@ -239,7 +285,7 @@ chompheader(line, def, e)
** Parameters:
** field -- the name of the header field.
** value -- the value of the field.
-** e -- the envelope to add them to.
+** hp -- an indirect pointer to the header structure list.
**
** Returns:
** none.
@@ -248,10 +294,11 @@ chompheader(line, def, e)
** adds the field on the list of headers for this envelope.
*/
-addheader(field, value, e)
+void
+addheader(field, value, hdrlist)
char *field;
char *value;
- ENVELOPE *e;
+ HDR **hdrlist;
{
register HDR *h;
register struct hdrinfo *hi;
@@ -265,7 +312,7 @@ addheader(field, value, e)
}
/* find current place in list -- keep back pointer? */
- for (hp = &e->e_header; (h = *hp) != NULL; hp = &h->h_link)
+ for (hp = hdrlist; (h = *hp) != NULL; hp = &h->h_link)
{
if (strcasecmp(field, h->h_field) == 0)
break;
@@ -288,7 +335,7 @@ addheader(field, value, e)
**
** Parameters:
** field -- the field name.
-** e -- the envelope containing the header.
+** header -- the header list.
**
** Returns:
** pointer to the value part.
@@ -299,13 +346,13 @@ addheader(field, value, e)
*/
char *
-hvalue(field, e)
+hvalue(field, header)
char *field;
- register ENVELOPE *e;
+ HDR *header;
{
register HDR *h;
- for (h = e->e_header; h != NULL; h = h->h_link)
+ for (h = header; h != NULL; h = h->h_link)
{
if (!bitset(H_DEFAULT, h->h_flags) &&
strcasecmp(h->h_field, field) == 0)
@@ -319,11 +366,17 @@ hvalue(field, e)
** A line is a header if it has a single word followed by
** optional white space followed by a colon.
**
+** Header fields beginning with two dashes, although technically
+** permitted by RFC822, are automatically rejected in order
+** to make MIME work out. Without this we could have a technically
+** legal header such as ``--"foo:bar"'' that would also be a legal
+** MIME separator.
+**
** Parameters:
-** s -- string to check for possible headerness.
+** h -- string to check for possible headerness.
**
** Returns:
-** TRUE if s is a header.
+** TRUE if h is a header.
** FALSE otherwise.
**
** Side Effects:
@@ -331,12 +384,20 @@ hvalue(field, e)
*/
bool
-isheader(s)
- register char *s;
+isheader(h)
+ char *h;
{
+ register char *s = h;
+
+ if (s[0] == '-' && s[1] == '-')
+ return FALSE;
+
while (*s > ' ' && *s != ':' && *s != '\0')
s++;
+ if (h == s)
+ return FALSE;
+
/* following technically violates RFC822 */
while (isascii(*s) && isspace(*s))
s++;
@@ -349,7 +410,9 @@ isheader(s)
** Parameters:
** e -- the envelope to process.
** full -- if set, do full processing (e.g., compute
-** message priority).
+** message priority). This should not be set
+** when reading a queue file because some info
+** needed to compute the priority is wrong.
**
** Returns:
** none.
@@ -360,6 +423,7 @@ isheader(s)
** Aborts the message if the hop count is exceeded.
*/
+void
eatheader(e, full)
register ENVELOPE *e;
bool full;
@@ -382,28 +446,42 @@ eatheader(e, full)
define('u', NULL, e);
/* full name of from person */
- p = hvalue("full-name", e);
+ p = hvalue("full-name", e->e_header);
if (p != NULL)
define('x', p, e);
if (tTd(32, 1))
printf("----- collected header -----\n");
- msgid = "<none>";
+ msgid = NULL;
for (h = e->e_header; h != NULL; h = h->h_link)
{
+ if (tTd(32, 1))
+ printf("%s: ", h->h_field);
if (h->h_value == NULL)
{
if (tTd(32, 1))
- printf("%s: <NULL>\n", h->h_field);
+ printf("<NULL>\n");
continue;
}
/* do early binding */
if (bitset(H_DEFAULT, h->h_flags))
{
- expand(h->h_value, buf, &buf[sizeof buf], e);
+ if (tTd(32, 1))
+ {
+ printf("(");
+ xputs(h->h_value);
+ printf(") ");
+ }
+ expand(h->h_value, buf, sizeof buf, e);
if (buf[0] != '\0')
{
+ if (bitset(H_FROM, h->h_flags))
+ {
+ extern char *crackaddr();
+
+ expand(crackaddr(buf), buf, sizeof buf, e);
+ }
h->h_value = newstr(buf);
h->h_flags &= ~H_DEFAULT;
}
@@ -411,7 +489,6 @@ eatheader(e, full)
if (tTd(32, 1))
{
- printf("%s: ", h->h_field);
xputs(h->h_value);
printf("\n");
}
@@ -428,7 +505,7 @@ eatheader(e, full)
int saveflags = e->e_flags;
(void) sendtolist(h->h_value, NULLADDR,
- &e->e_sendqueue, e);
+ &e->e_sendqueue, 0, e);
/* delete fatal errors generated by this address */
if (!GrabTo && !bitset(EF_FATALERRS, saveflags))
@@ -436,7 +513,10 @@ eatheader(e, full)
}
/* save the message-id for logging */
- if (full && strcasecmp(h->h_field, "message-id") == 0)
+ p = "resent-message-id";
+ if (!bitset(EF_RESENT, e->e_flags))
+ p += 7;
+ if (strcasecmp(h->h_field, p) == 0)
{
msgid = h->h_value;
while (isascii(*msgid) && isspace(*msgid))
@@ -446,11 +526,6 @@ eatheader(e, full)
/* see if this is a return-receipt header */
if (bitset(H_RECEIPTTO, h->h_flags))
e->e_receiptto = h->h_value;
-
- /* see if this is an errors-to header */
- if (UseErrorsTo && bitset(H_ERRORSTO, h->h_flags))
- (void) sendtolist(h->h_value, NULLADDR,
- &e->e_errorqueue, e);
}
if (tTd(32, 1))
printf("----------------------------\n");
@@ -464,21 +539,60 @@ eatheader(e, full)
e->e_hopcount = hopcnt;
/* message priority */
- p = hvalue("precedence", e);
+ p = hvalue("precedence", e->e_header);
if (p != NULL)
e->e_class = priencode(p);
+ if (e->e_class < 0)
+ e->e_timeoutclass = TOC_NONURGENT;
+ else if (e->e_class > 0)
+ e->e_timeoutclass = TOC_URGENT;
if (full)
+ {
e->e_msgpriority = e->e_msgsize
- e->e_class * WkClassFact
+ e->e_nrcpts * WkRecipFact;
+ }
+
+ /* message timeout priority */
+ p = hvalue("priority", e->e_header);
+ if (p != NULL)
+ {
+ /* (this should be in the configuration file) */
+ if (strcasecmp(p, "urgent"))
+ e->e_timeoutclass = TOC_URGENT;
+ else if (strcasecmp(p, "normal"))
+ e->e_timeoutclass = TOC_NORMAL;
+ else if (strcasecmp(p, "non-urgent"))
+ e->e_timeoutclass = TOC_NONURGENT;
+ }
/* date message originated */
- p = hvalue("posted-date", e);
+ p = hvalue("posted-date", e->e_header);
if (p == NULL)
- p = hvalue("date", e);
+ p = hvalue("date", e->e_header);
if (p != NULL)
define('a', p, e);
+ /* check to see if this is a MIME message */
+ if ((e->e_bodytype != NULL &&
+ strcasecmp(e->e_bodytype, "8BITMIME") == 0) ||
+ hvalue("MIME-Version", e->e_header) != NULL)
+ {
+ e->e_flags |= EF_IS_MIME;
+ if (HasEightBits)
+ e->e_bodytype = "8BITMIME";
+ }
+ else if ((p = hvalue("Content-Type", e->e_header)) != NULL)
+ {
+ /* this may be an RFC 1049 message */
+ p = strpbrk(p, ";/");
+ if (p == NULL || *p == ';')
+ {
+ /* yep, it is */
+ e->e_flags |= EF_DONT_MIME;
+ }
+ }
+
/*
** From person in antiquated ARPANET mode
** required by UK Grey Book e-mail gateways (sigh)
@@ -493,7 +607,7 @@ eatheader(e, full)
if (bitset(H_FROM, hi->hi_flags) &&
(!bitset(H_RESENT, hi->hi_flags) ||
bitset(EF_RESENT, e->e_flags)) &&
- (p = hvalue(hi->hi_field, e)) != NULL)
+ (p = hvalue(hi->hi_field, e->e_header)) != NULL)
break;
}
if (hi->hi_field != NULL)
@@ -510,7 +624,7 @@ eatheader(e, full)
*/
# ifdef LOG
- if (full && LogLevel > 4)
+ if (bitset(EF_LOGSENDER, e->e_flags) && LogLevel > 4)
logsender(e, msgid);
# endif /* LOG */
e->e_flags &= ~EF_LOGSENDER;
@@ -526,6 +640,7 @@ eatheader(e, full)
** none
*/
+void
logsender(e, msgid)
register ENVELOPE *e;
char *msgid;
@@ -534,8 +649,23 @@ logsender(e, msgid)
char *name;
register char *sbp;
register char *p;
- char hbuf[MAXNAME];
- char sbuf[MAXLINE];
+ int l;
+ char hbuf[MAXNAME + 1];
+ char sbuf[MAXLINE + 1];
+ char mbuf[MAXNAME + 1];
+
+ /* don't allow newlines in the message-id */
+ if (msgid != NULL)
+ {
+ l = strlen(msgid);
+ if (l > sizeof mbuf - 1)
+ l = sizeof mbuf - 1;
+ bcopy(msgid, mbuf, l);
+ mbuf[l] = '\0';
+ p = mbuf;
+ while ((p = strchr(p, '\n')) != NULL)
+ *p++ = ' ';
+ }
if (bitset(EF_RESPONSE, e->e_flags))
name = "[RESPONSE]";
@@ -552,7 +682,7 @@ logsender(e, msgid)
if (RealHostAddr.sa.sa_family != 0)
{
p = &hbuf[strlen(hbuf)];
- (void) sprintf(p, " (%s)",
+ (void) sprintf(p, " (%.100s)",
anynet_ntoa(&RealHostAddr));
}
}
@@ -561,12 +691,12 @@ logsender(e, msgid)
# if (SYSLOG_BUFSIZE) >= 256
sbp = sbuf;
sprintf(sbp, "from=%.200s, size=%ld, class=%d, pri=%ld, nrcpts=%d",
- e->e_from.q_paddr, e->e_msgsize, e->e_class,
- e->e_msgpriority, e->e_nrcpts);
+ e->e_from.q_paddr == NULL ? "<NONE>" : e->e_from.q_paddr,
+ e->e_msgsize, e->e_class, e->e_msgpriority, e->e_nrcpts);
sbp += strlen(sbp);
if (msgid != NULL)
{
- sprintf(sbp, ", msgid=%.100s", msgid);
+ sprintf(sbp, ", msgid=%.100s", mbuf);
sbp += strlen(sbp);
}
if (e->e_bodytype != NULL)
@@ -577,33 +707,35 @@ logsender(e, msgid)
p = macvalue('r', e);
if (p != NULL)
(void) sprintf(sbp, ", proto=%.20s", p);
- syslog(LOG_INFO, "%s: %s, relay=%s",
+ syslog(LOG_INFO, "%s: %.850s, relay=%.100s",
e->e_id, sbuf, name);
# else /* short syslog buffer */
syslog(LOG_INFO, "%s: from=%s",
- e->e_id, shortenstring(e->e_from.q_paddr, 83));
+ e->e_id, e->e_from.q_paddr == NULL ? "<NONE>" :
+ shortenstring(e->e_from.q_paddr, 83));
syslog(LOG_INFO, "%s: size=%ld, class=%ld, pri=%ld, nrcpts=%d",
e->e_id, e->e_msgsize, e->e_class,
e->e_msgpriority, e->e_nrcpts);
if (msgid != NULL)
- syslog(LOG_INFO, "%s: msgid=%s", e->e_id, msgid);
+ syslog(LOG_INFO, "%s: msgid=%s",
+ e->e_id, shortenstring(mbuf, 83));
sbp = sbuf;
sprintf(sbp, "%s:", e->e_id);
sbp += strlen(sbp);
if (e->e_bodytype != NULL)
{
- sprintf(sbp, " bodytype=%s,", e->e_bodytype);
+ sprintf(sbp, " bodytype=%.20s,", e->e_bodytype);
sbp += strlen(sbp);
}
p = macvalue('r', e);
if (p != NULL)
{
- sprintf(sbp, " proto=%s,", p);
+ sprintf(sbp, " proto=%.20s,", p);
sbp += strlen(sbp);
}
- syslog(LOG_INFO, "%s relay=%s", sbuf, name);
+ syslog(LOG_INFO, "%.400s relay=%.100s", sbuf, name);
# endif
# endif
}
@@ -620,6 +752,7 @@ logsender(e, msgid)
** none.
*/
+int
priencode(p)
char *p;
{
@@ -678,9 +811,12 @@ crackaddr(addr)
bool putgmac = FALSE;
bool quoteit = FALSE;
bool gotangle = FALSE;
+ bool gotcolon = FALSE;
register char *bp;
char *buflim;
- static char buf[MAXNAME];
+ char *bufhead;
+ char *addrhead;
+ static char buf[MAXNAME + 1];
if (tTd(33, 1))
printf("crackaddr(%s)\n", addr);
@@ -694,9 +830,9 @@ crackaddr(addr)
** adjusted later if we find them.
*/
- bp = buf;
+ bp = bufhead = buf;
buflim = &buf[sizeof buf - 5];
- p = addr;
+ p = addrhead = addr;
copylev = anglelev = realanglelev = cmtlev = realcmtlev = 0;
qmode = realqmode = FALSE;
@@ -780,8 +916,80 @@ crackaddr(addr)
bp--;
}
+ /* check for group: list; syntax */
+ if (c == ':' && anglelev <= 0 && !gotcolon && !ColonOkInAddr)
+ {
+ register char *q;
+
+ if (*p == ':')
+ {
+ /* special case -- :: syntax */
+ if (cmtlev <= 0 && !qmode)
+ quoteit = TRUE;
+ if (copylev > 0 && !skipping)
+ {
+ *bp++ = c;
+ *bp++ = c;
+ }
+ p++;
+ goto putg;
+ }
+
+ gotcolon = TRUE;
+
+ bp = bufhead;
+ if (quoteit)
+ {
+ *bp++ = '"';
+
+ /* back up over the ':' and any spaces */
+ --p;
+ while (isascii(*--p) && isspace(*p))
+ continue;
+ p++;
+ }
+ for (q = addrhead; q < p; )
+ {
+ c = *q++;
+ if (bp < buflim)
+ {
+ if (quoteit && c == '"')
+ *bp++ = '\\';
+ *bp++ = c;
+ }
+ }
+ if (quoteit)
+ {
+ if (bp == &bufhead[1])
+ bp--;
+ else
+ *bp++ = '"';
+ while ((c = *p++) != ':')
+ {
+ if (bp < buflim)
+ *bp++ = c;
+ }
+ *bp++ = c;
+ }
+
+ /* any trailing white space is part of group: */
+ while (isascii(*p) && isspace(*p) && bp < buflim)
+ *bp++ = *p++;
+ copylev = 0;
+ putgmac = quoteit = FALSE;
+ bufhead = bp;
+ addrhead = p;
+ continue;
+ }
+
+ if (c == ';' && copylev <= 0 && !ColonOkInAddr)
+ {
+ if (bp < buflim)
+ *bp++ = c;
+ }
+
/* check for characters that may have to be quoted */
- if (strchr(".'@,;:\\()[]", c) != NULL)
+ if (strchr(MustQuoteChars, c) != NULL)
{
/*
** If these occur as the phrase part of a <>
@@ -809,7 +1017,7 @@ crackaddr(addr)
if (!skipping)
realanglelev = 1;
- bp = buf;
+ bp = bufhead;
if (quoteit)
{
*bp++ = '"';
@@ -820,7 +1028,7 @@ crackaddr(addr)
continue;
p++;
}
- for (q = addr; q < p; )
+ for (q = addrhead; q < p; )
{
c = *q++;
if (bp < buflim)
@@ -901,6 +1109,7 @@ crackaddr(addr)
**
** Parameters:
** mci -- the connection information.
+** h -- the header to put.
** e -- envelope to use.
**
** Returns:
@@ -917,27 +1126,45 @@ crackaddr(addr)
# define MAX(a,b) (((a)>(b))?(a):(b))
#endif
-putheader(mci, e)
+void
+putheader(mci, h, e)
register MCI *mci;
+ register HDR *h;
register ENVELOPE *e;
{
char buf[MAX(MAXLINE,BUFSIZ)];
- register HDR *h;
char obuf[MAXLINE];
if (tTd(34, 1))
printf("--- putheader, mailer = %s ---\n",
mci->mci_mailer->m_name);
- for (h = e->e_header; h != NULL; h = h->h_link)
+ mci->mci_flags |= MCIF_INHEADER;
+ for (; h != NULL; h = h->h_link)
{
- register char *p;
+ register char *p = h->h_value;
extern bool bitintersect();
if (tTd(34, 11))
{
printf(" %s: ", h->h_field);
- xputs(h->h_value);
+ xputs(p);
+ }
+
+ /* suppress Content-Transfer-Encoding: if we are MIMEing */
+ if (bitset(H_CTE, h->h_flags) &&
+ bitset(MCIF_CVT8TO7|MCIF_INMIME, mci->mci_flags))
+ {
+ if (tTd(34, 11))
+ printf(" (skipped (content-transfer-encoding))\n");
+ continue;
+ }
+
+ if (bitset(MCIF_INMIME, mci->mci_flags))
+ {
+ if (tTd(34, 11))
+ printf("\n");
+ goto vanilla;
}
if (bitset(H_CHECK|H_ACHECK, h->h_flags) &&
@@ -966,10 +1193,9 @@ putheader(mci, e)
}
/* macro expand value if generated internally */
- p = h->h_value;
if (bitset(H_DEFAULT, h->h_flags))
{
- expand(p, buf, &buf[sizeof buf], e);
+ expand(p, buf, sizeof buf, e);
p = buf;
if (p == NULL || *p == '\0')
{
@@ -979,6 +1205,23 @@ putheader(mci, e)
}
}
+ if (bitset(H_BCC, h->h_flags))
+ {
+ /* Bcc: field -- either truncate or delete */
+ if (bitset(EF_DELETE_BCC, e->e_flags))
+ {
+ if (tTd(34, 11))
+ printf(" (skipped -- bcc)\n");
+ }
+ else
+ {
+ /* no other recipient headers: truncate value */
+ (void) sprintf(obuf, "%s:", h->h_field);
+ putline(obuf, mci);
+ }
+ continue;
+ }
+
if (tTd(34, 11))
printf("\n");
@@ -995,21 +1238,51 @@ putheader(mci, e)
{
/* vanilla header line */
register char *nlp;
+ register char *obp;
- (void) sprintf(obuf, "%s: ", h->h_field);
+vanilla:
+ (void) sprintf(obuf, "%.200s: ", h->h_field);
+ obp = obuf + strlen(obuf);
while ((nlp = strchr(p, '\n')) != NULL)
{
+
*nlp = '\0';
- (void) strcat(obuf, p);
+ sprintf(obp, "%.*s",
+ sizeof obuf - (obp - obuf) - 1, p);
*nlp = '\n';
putline(obuf, mci);
p = ++nlp;
- obuf[0] = '\0';
+ obp = obuf;
}
- (void) strcat(obuf, p);
+ sprintf(obp, "%.*s", sizeof obuf - (obp - obuf) - 1, p);
+ putline(obuf, mci);
+ }
+ }
+
+ /*
+ ** If we are converting this to a MIME message, add the
+ ** MIME headers.
+ */
+
+#if MIME8TO7
+ if (bitset(MM_MIME8BIT, MimeMode) &&
+ bitset(EF_HAS8BIT, e->e_flags) &&
+ !bitset(EF_DONT_MIME, e->e_flags) &&
+ !bitnset(M_8BITS, mci->mci_mailer->m_flags) &&
+ !bitset(MCIF_CVT8TO7, mci->mci_flags))
+ {
+ if (hvalue("MIME-Version", e->e_header) == NULL)
+ putline("MIME-Version: 1.0", mci);
+ if (hvalue("Content-Type", e->e_header) == NULL)
+ {
+ sprintf(obuf, "Content-Type: text/plain; charset=%s",
+ defcharset(e));
putline(obuf, mci);
}
+ if (hvalue("Content-Transfer-Encoding", e->e_header) == NULL)
+ putline("Content-Transfer-Encoding: 8bit", mci);
}
+#endif
}
/*
** COMMAIZE -- output a header field, making a comma-translated list.
@@ -1051,7 +1324,7 @@ commaize(h, p, oldstyle, mci, e)
printf("commaize(%s: %s)\n", h->h_field, p);
obp = obuf;
- (void) sprintf(obp, "%s: ", h->h_field);
+ (void) sprintf(obp, "%.200s: ", h->h_field);
opos = strlen(h->h_field) + 2;
obp += opos;
omax = mci->mci_mailer->m_linelimit - 2;
@@ -1088,7 +1361,7 @@ commaize(h, p, oldstyle, mci, e)
char pvpbuf[PSBUFSIZE];
(void) prescan(p, oldstyle ? ' ' : ',', pvpbuf,
- sizeof pvpbuf, &oldp);
+ sizeof pvpbuf, &oldp, NULL);
p = oldp;
/* look to see if we have an at sign */
@@ -1119,6 +1392,18 @@ commaize(h, p, oldstyle, mci, e)
flags = RF_HEADERADDR|RF_ADDDOMAIN;
if (bitset(H_FROM, h->h_flags))
flags |= RF_SENDERADDR;
+#if USERDB
+ else if (e->e_from.q_mailer != NULL &&
+ bitnset(M_UDBRECIPIENT, e->e_from.q_mailer->m_flags))
+ {
+ extern char *udbsender();
+ char *q;
+
+ q = udbsender(name);
+ if (q != NULL)
+ name = q;
+ }
+#endif
stat = EX_OK;
name = remotename(name, mci->mci_mailer, flags, &stat, e);
if (*name == '\0')
diff --git a/usr.sbin/sendmail/src/main.c b/usr.sbin/sendmail/src/main.c
index bae41d5..1b2b9da 100644
--- a/usr.sbin/sendmail/src/main.c
+++ b/usr.sbin/sendmail/src/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -39,17 +39,15 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)main.c 8.55.1.7 (Berkeley) 3/5/95";
+static char sccsid[] = "@(#)main.c 8.162 (Berkeley) 11/18/95";
#endif /* not lint */
#define _DEFINE
#include "sendmail.h"
#if NAMED_BIND
-#include <arpa/nameser.h>
#include <resolv.h>
#endif
-#include <pwd.h>
# ifdef lint
char edata, end;
@@ -94,21 +92,9 @@ ENVELOPE BlankEnvelope; /* a "blank" envelope */
ENVELOPE MainEnvelope; /* the envelope around the basic letter */
ADDRESS NullAddress = /* a null address */
{ "", "", NULL, "" };
-char *UserEnviron[MAXUSERENVIRON + 2];
- /* saved user environment */
-char RealUserName[256]; /* the actual user id on this host */
char *CommandLineArgs; /* command line args for pid file */
bool Warn_Q_option = FALSE; /* warn about Q option use */
-
-/*
-** Pointers for setproctitle.
-** This allows "ps" listings to give more useful information.
-*/
-
-# ifdef SETPROCTITLE
-char **Argv = NULL; /* pointer to argument vector */
-char *LastArgv = NULL; /* end of argv */
-# endif /* SETPROCTITLE */
+char **SaveArgv; /* argument vector for re-execing */
static void obsolete();
@@ -118,8 +104,9 @@ ERROR %%%% Cannot have daemon mode without SMTP %%%% ERROR
#endif /* SMTP */
#endif /* DAEMON */
-#define MAXCONFIGLEVEL 5 /* highest config version level known */
+#define MAXCONFIGLEVEL 6 /* highest config version level known */
+int
main(argc, argv, envp)
int argc;
char **argv;
@@ -127,7 +114,6 @@ main(argc, argv, envp)
{
register char *p;
char **av;
- extern int finis();
extern char Version[];
char *ep, *from;
typedef int (*fnptr)();
@@ -139,22 +125,25 @@ main(argc, argv, envp)
bool warn_C_flag = FALSE;
char warn_f_flag = '\0';
static bool reenter = FALSE;
- char *argv0 = argv[0];
struct passwd *pw;
struct stat stb;
+ struct hostent *hp;
char jbuf[MAXHOSTNAMELEN]; /* holds MyHostName */
+ static char rnamebuf[MAXNAME]; /* holds RealUserName */
extern int DtableSize;
extern int optind;
+ extern int opterr;
extern time_t convtime();
- extern putheader(), putbody();
extern void intsig();
- extern char **myhostname();
+ extern struct hostent *myhostname();
extern char *arpadate();
extern char *getauthinfo();
extern char *getcfname();
extern char *optarg;
extern char **environ;
extern void sigusr1();
+ extern void sighup();
+ extern void initmacros __P((ENVELOPE *));
/*
** Check to see if we reentered.
@@ -172,8 +161,8 @@ main(argc, argv, envp)
/* do machine-dependent initializations */
init_md(argc, argv);
- /* arrange to dump state on signal */
#ifdef SIGUSR1
+ /* arrange to dump state on user-1 signal */
setsignal(SIGUSR1, sigusr1);
#endif
@@ -211,7 +200,9 @@ main(argc, argv, envp)
# else
openlog("sendmail", LOG_PID);
# endif
-#endif
+#endif
+
+ tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
/* set up the blank envelope */
BlankEnvelope.e_puthdr = putheader;
@@ -231,25 +222,29 @@ main(argc, argv, envp)
RealUid = getuid();
RealGid = getgid();
- pw = getpwuid(RealUid);
+ pw = sm_getpwuid(RealUid);
if (pw != NULL)
- (void) strcpy(RealUserName, pw->pw_name);
+ (void) strcpy(rnamebuf, pw->pw_name);
else
- (void) sprintf(RealUserName, "Unknown UID %d", RealUid);
+ (void) sprintf(rnamebuf, "Unknown UID %d", RealUid);
+ RealUserName = rnamebuf;
/* save command line arguments */
i = 0;
for (av = argv; *av != NULL; )
i += strlen(*av++) + 1;
+ SaveArgv = (char **) xalloc(sizeof (char *) * (argc + 1));
CommandLineArgs = xalloc(i);
p = CommandLineArgs;
- for (av = argv; *av != NULL; )
+ for (av = argv, i = 0; *av != NULL; )
{
+ SaveArgv[i++] = newstr(*av);
if (av != argv)
*p++ = ' ';
strcpy(p, *av++);
p += strlen(p);
}
+ SaveArgv[i] = NULL;
/* Handle any non-getoptable constructions. */
obsolete(argv);
@@ -259,63 +254,98 @@ main(argc, argv, envp)
*/
#if defined(__osf__) || defined(_AIX3)
-# define OPTIONS "B:b:C:cd:e:F:f:h:Iimno:p:q:r:sTtvX:x"
-#endif
-#if defined(ultrix)
-# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mno:p:q:r:sTtvX:"
+# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mnO:o:p:q:r:sTtvX:x"
#endif
-#if defined(NeXT)
-# define OPTIONS "B:b:C:cd:e:F:f:h:IimnOo:p:q:r:sTtvX:"
+#if defined(sony_news)
+# define OPTIONS "B:b:C:cd:E:e:F:f:h:IiJ:M:mnO:o:p:q:r:sTtvX:"
#endif
#ifndef OPTIONS
-# define OPTIONS "B:b:C:cd:e:F:f:h:Iimno:p:q:r:sTtvX:"
+# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mnO:o:p:q:r:sTtvX:"
#endif
+ opterr = 0;
while ((j = getopt(argc, argv, OPTIONS)) != EOF)
{
switch (j)
{
case 'd':
- tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
tTflag(optarg);
setbuf(stdout, (char *) NULL);
- printf("Version %s\n", Version);
break;
}
}
+ opterr = 1;
- InChannel = stdin;
- OutChannel = stdout;
-
- /*
- ** Move the environment so setproctitle can use the space at
- ** the top of memory.
- */
+ if (tTd(0, 1))
+ {
+ int ll;
+ extern char *CompileOptions[];
- for (i = j = 0; j < MAXUSERENVIRON && (p = envp[i]) != NULL; i++)
+ printf("Version %s\n Compiled with:", Version);
+ av = CompileOptions;
+ ll = 7;
+ while (*av != NULL)
+ {
+ if (ll + strlen(*av) > 63)
+ {
+ putchar('\n');
+ ll = 0;
+ }
+ if (ll == 0)
+ {
+ putchar('\t');
+ putchar('\t');
+ }
+ else
+ putchar(' ');
+ printf("%s", *av);
+ ll += strlen(*av++) + 1;
+ }
+ putchar('\n');
+ }
+ if (tTd(0, 10))
{
- if (strncmp(p, "IFS=", 4) == 0 || strncmp(p, "LD_", 3) == 0)
- continue;
- UserEnviron[j++] = newstr(p);
+ int ll;
+ extern char *OsCompileOptions[];
+
+ printf(" OS Defines:", Version);
+ av = OsCompileOptions;
+ ll = 7;
+ while (*av != NULL)
+ {
+ if (ll + strlen(*av) > 63)
+ {
+ putchar('\n');
+ ll = 0;
+ }
+ if (ll == 0)
+ {
+ putchar('\t');
+ putchar('\t');
+ }
+ else
+ putchar(' ');
+ printf("%s", *av);
+ ll += strlen(*av++) + 1;
+ }
+ putchar('\n');
+#ifdef _PATH_UNIX
+ printf("Kernel symbols:\t%s\n", _PATH_UNIX);
+#endif
+ printf(" Config file:\t%s\n", getcfname());
+ printf(" Pid file:\t%s\n", PidFile);
}
- UserEnviron[j] = NULL;
- environ = UserEnviron;
-# ifdef SETPROCTITLE
- /*
- ** Save start and extent of argv for setproctitle.
- */
+ InChannel = stdin;
+ OutChannel = stdout;
- Argv = argv;
- if (i > 0)
- LastArgv = envp[i - 1] + strlen(envp[i - 1]);
- else
- LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);
-# endif /* SETPROCTITLE */
+ /* initialize for setproctitle */
+ initsetproctitle(argc, argv, envp);
+
+ /* prime the child environment */
+ setuserenv("AGENT", "sendmail");
if (setsignal(SIGINT, SIG_IGN) != SIG_IGN)
(void) setsignal(SIGINT, intsig);
- if (setsignal(SIGHUP, SIG_IGN) != SIG_IGN)
- (void) setsignal(SIGHUP, intsig);
(void) setsignal(SIGTERM, intsig);
(void) setsignal(SIGPIPE, SIG_IGN);
OldUmask = umask(022);
@@ -335,12 +365,13 @@ main(argc, argv, envp)
/* initialize some macros, etc. */
initmacros(CurEnv);
+ init_vendor_macros(CurEnv);
/* version */
define('v', Version, CurEnv);
/* hostname */
- av = myhostname(jbuf, sizeof jbuf);
+ hp = myhostname(jbuf, sizeof jbuf);
if (jbuf[0] != '\0')
{
struct utsname utsname;
@@ -357,7 +388,6 @@ main(argc, argv, envp)
if (p[1] != '\0')
{
define('m', newstr(&p[1]), CurEnv);
- setclass('m', &p[1]);
}
while (p != NULL && strchr(&p[1], '.') != NULL)
{
@@ -378,19 +408,42 @@ main(argc, argv, envp)
p = jbuf;
}
if (tTd(0, 4))
- printf("UUCP nodename: %s\n", p);
+ printf(" UUCP nodename: %s\n", p);
p = newstr(p);
define('k', p, CurEnv);
setclass('k', p);
setclass('w', p);
}
- while (av != NULL && *av != NULL)
+ if (hp != NULL)
{
- if (tTd(0, 4))
- printf("\ta.k.a.: %s\n", *av);
- setclass('w', *av++);
+ for (av = hp->h_aliases; av != NULL && *av != NULL; av++)
+ {
+ if (tTd(0, 4))
+ printf("\ta.k.a.: %s\n", *av);
+ setclass('w', *av);
+ }
+#if NETINET
+ if (hp->h_addrtype == AF_INET && hp->h_length == INADDRSZ)
+ {
+ register int i;
+
+ for (i = 0; hp->h_addr_list[i] != NULL; i++)
+ {
+ char ipbuf[103];
+
+ sprintf(ipbuf, "[%.100s]",
+ inet_ntoa(*((struct in_addr *) hp->h_addr_list[i])));
+ if (tTd(0, 4))
+ printf("\ta.k.a.: %s\n", ipbuf);
+ setclass('w', ipbuf);
+ }
+ }
+#endif
}
+ /* probe interfaces and locate any additional names */
+ load_if_names();
+
/* current time */
define('b', arpadate((char *) NULL), CurEnv);
@@ -447,9 +500,7 @@ main(argc, argv, envp)
case MD_TEST:
case MD_INITALIAS:
case MD_PRINT:
-#ifdef MAYBE_NEXT_RELEASE
case MD_ARPAFTP:
-#endif
OpMode = j;
break;
@@ -466,17 +517,14 @@ main(argc, argv, envp)
break;
case 'B': /* body type */
- if (strcasecmp(optarg, "7bit") == 0 ||
- strcasecmp(optarg, "8bitmime") == 0)
- CurEnv->e_bodytype = newstr(optarg);
- else
- usrerr("Illegal body type %s", optarg);
+ CurEnv->e_bodytype = optarg;
break;
case 'C': /* select configuration file (already done) */
if (RealUid != 0)
warn_C_flag = TRUE;
ConfFile = optarg;
+ endpwent();
(void) setgid(RealGid);
(void) setuid(RealUid);
safecf = FALSE;
@@ -520,6 +568,10 @@ main(argc, argv, envp)
setoption(*optarg, optarg + 1, FALSE, TRUE, CurEnv);
break;
+ case 'O': /* set option (long form) */
+ setoption(' ', optarg, FALSE, TRUE, CurEnv);
+ break;
+
case 'p': /* set protocol */
p = strchr(optarg, ':');
if (p != NULL)
@@ -574,6 +626,7 @@ main(argc, argv, envp)
break;
case 'X': /* traffic log file */
+ endpwent();
setgid(RealGid);
setuid(RealUid);
TrafficLogFile = fopen(optarg, "a");
@@ -599,9 +652,7 @@ main(argc, argv, envp)
break;
case 'e': /* error message disposition */
-# if defined(ultrix)
case 'M': /* define macro */
-# endif
setoption(j, optarg, FALSE, TRUE, CurEnv);
break;
@@ -619,8 +670,10 @@ main(argc, argv, envp)
case 'x': /* random flag that OSF/1 & AIX mailx passes */
break;
# endif
-# if defined(NeXT)
- case 'O': /* random flag that NeXT Mail.app passes */
+# if defined(sony_news)
+ case 'E':
+ case 'J': /* ignore flags for Japanese code conversion
+ impremented on Sony NEWS */
break;
# endif
@@ -638,23 +691,42 @@ main(argc, argv, envp)
** Extract special fields for local use.
*/
-#ifdef XDEBUG
+ /* set up ${opMode} for use in config file */
+ {
+ char mbuf[2];
+
+ mbuf[0] = OpMode;
+ mbuf[1] = '\0';
+ define(MID_OPMODE, newstr(mbuf), CurEnv);
+ }
+
+#if XDEBUG
checkfd012("before readcf");
#endif
+ vendor_pre_defaults(CurEnv);
readcf(getcfname(), safecf, CurEnv);
+ vendor_post_defaults(CurEnv);
+
+ /* suppress error printing if errors mailed back or whatever */
+ if (CurEnv->e_errormode != EM_PRINT)
+ HoldErrs = TRUE;
+
+ /* set up the $=m class now, after .cf has a chance to redefine $m */
+ expand("\201m", jbuf, sizeof jbuf, CurEnv);
+ setclass('m', jbuf);
if (tTd(0, 1))
{
- printf("SYSTEM IDENTITY (after readcf):");
- printf("\n\t (short domain name) $w = ");
+ printf("\n============ SYSTEM IDENTITY (after readcf) ============");
+ printf("\n (short domain name) $w = ");
xputs(macvalue('w', CurEnv));
- printf("\n\t(canonical domain name) $j = ");
+ printf("\n (canonical domain name) $j = ");
xputs(macvalue('j', CurEnv));
- printf("\n\t (subdomain name) $m = ");
+ printf("\n (subdomain name) $m = ");
xputs(macvalue('m', CurEnv));
- printf("\n\t (node name) $k = ");
+ printf("\n (node name) $k = ");
xputs(macvalue('k', CurEnv));
- printf("\n");
+ printf("\n========================================================\n\n");
}
/*
@@ -662,47 +734,48 @@ main(argc, argv, envp)
*/
#if NAMED_BIND
- if (!bitset(RES_INIT, _res.options))
+ if (UseNameServer && !bitset(RES_INIT, _res.options))
res_init();
+# ifdef RES_NOALIASES
+ _res.options |= RES_NOALIASES;
+# endif
#endif
/*
- ** Process authorization warnings from command line.
+ ** Do more command line checking -- these are things that
+ ** have to modify the results of reading the config file.
*/
+ /* process authorization warnings from command line */
if (warn_C_flag)
auth_warning(CurEnv, "Processed by %s with -C %s",
RealUserName, ConfFile);
-/*
- if (warn_f_flag != '\0')
- auth_warning(CurEnv, "%s set sender to %s using -%c",
- RealUserName, from, warn_f_flag);
-*/
if (Warn_Q_option)
auth_warning(CurEnv, "Processed from queue %s", QueueDir);
+ /* check body type for legality */
+ if (CurEnv->e_bodytype == NULL)
+ /* nothing */ ;
+ else if (strcasecmp(CurEnv->e_bodytype, "7BIT") == 0)
+ SevenBitInput = TRUE;
+ else if (strcasecmp(CurEnv->e_bodytype, "8BITMIME") == 0)
+ SevenBitInput = FALSE;
+ else
+ {
+ usrerr("Illegal body type %s", CurEnv->e_bodytype);
+ CurEnv->e_bodytype = NULL;
+ }
+
/* Enforce use of local time (null string overrides this) */
if (TimeZoneSpec == NULL)
unsetenv("TZ");
else if (TimeZoneSpec[0] != '\0')
- {
- char **evp = UserEnviron;
- char tzbuf[100];
-
- strcpy(tzbuf, "TZ=");
- strcpy(&tzbuf[3], TimeZoneSpec);
-
- while (*evp != NULL && strncmp(*evp, "TZ=", 3) != 0)
- evp++;
- if (*evp == NULL)
- {
- *evp++ = newstr(tzbuf);
- *evp = NULL;
- }
- else
- *evp++ = newstr(tzbuf);
- }
+ setuserenv("TZ", TimeZoneSpec);
+ else
+ setuserenv("TZ", NULL);
+ tzset();
+ /* check for sane configuration level */
if (ConfigLevel > MAXCONFIGLEVEL)
{
syserr("Warning: .cf version level (%d) exceeds program functionality (%d)",
@@ -712,32 +785,24 @@ main(argc, argv, envp)
if (MeToo)
BlankEnvelope.e_flags |= EF_METOO;
-# ifdef QUEUE
- if (queuemode && RealUid != 0 && bitset(PRIV_RESTRICTQRUN, PrivacyFlags))
+ switch (OpMode)
{
- struct stat stbuf;
+ case MD_DAEMON:
+ /* remove things that don't make sense in daemon mode */
+ FullName = NULL;
+ GrabTo = FALSE;
- /* check to see if we own the queue directory */
- if (stat(QueueDir, &stbuf) < 0)
- syserr("main: cannot stat %s", QueueDir);
- if (stbuf.st_uid != RealUid)
- {
- /* nope, really a botch */
- usrerr("You do not have permission to process the queue");
- exit (EX_NOPERM);
- }
- }
-# endif /* QUEUE */
+ /* arrange to restart on hangup signal */
+ setsignal(SIGHUP, sighup);
+ break;
- switch (OpMode)
- {
case MD_INITALIAS:
Verbose = TRUE;
- break;
+ /* fall through... */
- case MD_DAEMON:
- /* remove things that don't make sense in daemon mode */
- FullName = NULL;
+ default:
+ /* arrange to exit cleanly on hangup signal */
+ setsignal(SIGHUP, intsig);
break;
}
@@ -760,31 +825,56 @@ main(argc, argv, envp)
UseErrorsTo = TRUE;
}
+ /* set options that were previous macros */
+ if (SmtpGreeting == NULL)
+ {
+ if (ConfigLevel < 7 && (p = macvalue('e', CurEnv)) != NULL)
+ SmtpGreeting = newstr(p);
+ else
+ SmtpGreeting = "\201j Sendmail \201v ready at \201b";
+ }
+ if (UnixFromLine == NULL)
+ {
+ if (ConfigLevel < 7 && (p = macvalue('l', CurEnv)) != NULL)
+ UnixFromLine = newstr(p);
+ else
+ UnixFromLine = "From \201g \201d";
+ }
+
/* our name for SMTP codes */
- expand("\201j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
+ expand("\201j", jbuf, sizeof jbuf, CurEnv);
MyHostName = jbuf;
+ if (strchr(jbuf, '.') == NULL)
+ message("WARNING: local host name (%s) is not qualified; fix $j in config file",
+ jbuf);
/* make certain that this name is part of the $=w class */
setclass('w', MyHostName);
/* the indices of built-in mailers */
st = stab("local", ST_MAILER, ST_FIND);
- if (st == NULL)
- syserr("No local mailer defined");
- else
+ if (st != NULL)
LocalMailer = st->s_mailer;
+ else if (OpMode != MD_TEST || !warn_C_flag)
+ syserr("No local mailer defined");
st = stab("prog", ST_MAILER, ST_FIND);
if (st == NULL)
syserr("No prog mailer defined");
else
+ {
ProgMailer = st->s_mailer;
+ clrbitn(M_MUSER, ProgMailer->m_flags);
+ }
st = stab("*file*", ST_MAILER, ST_FIND);
if (st == NULL)
syserr("No *file* mailer defined");
else
+ {
FileMailer = st->s_mailer;
+ clrbitn(M_MUSER, FileMailer->m_flags);
+ }
st = stab("*include*", ST_MAILER, ST_FIND);
if (st == NULL)
@@ -792,6 +882,39 @@ main(argc, argv, envp)
else
InclMailer = st->s_mailer;
+ if (ConfigLevel < 6)
+ {
+ /* heuristic tweaking of local mailer for back compat */
+ if (LocalMailer != NULL)
+ {
+ setbitn(M_ALIASABLE, LocalMailer->m_flags);
+ setbitn(M_HASPWENT, LocalMailer->m_flags);
+ setbitn(M_TRYRULESET5, LocalMailer->m_flags);
+ setbitn(M_CHECKINCLUDE, LocalMailer->m_flags);
+ setbitn(M_CHECKPROG, LocalMailer->m_flags);
+ setbitn(M_CHECKFILE, LocalMailer->m_flags);
+ setbitn(M_CHECKUDB, LocalMailer->m_flags);
+ }
+ if (ProgMailer != NULL)
+ setbitn(M_RUNASRCPT, ProgMailer->m_flags);
+ if (FileMailer != NULL)
+ setbitn(M_RUNASRCPT, FileMailer->m_flags);
+
+ /* propogate some envariables into children */
+ setuserenv("ISP", NULL);
+ setuserenv("SYSTYPE", NULL);
+ }
+
+ /* MIME Content-Types that cannot be transfer encoded */
+ setclass('n', "multipart/signed");
+
+ /* MIME message/* subtypes that can be treated as messages */
+ setclass('s', "rfc822");
+
+ /* MIME Content-Transfer-Encodings that can be encoded */
+ setclass('e', "7bit");
+ setclass('e', "8bit");
+ setclass('e', "binary");
/* operate in queue directory */
if (OpMode != MD_TEST && chdir(QueueDir) < 0)
@@ -800,14 +923,32 @@ main(argc, argv, envp)
ExitStat = EX_SOFTWARE;
}
+# ifdef QUEUE
+ if (queuemode && RealUid != 0 && bitset(PRIV_RESTRICTQRUN, PrivacyFlags))
+ {
+ struct stat stbuf;
+
+ /* check to see if we own the queue directory */
+ if (stat(".", &stbuf) < 0)
+ syserr("main: cannot stat %s", QueueDir);
+ if (stbuf.st_uid != RealUid)
+ {
+ /* nope, really a botch */
+ usrerr("You do not have permission to process the queue");
+ exit (EX_NOPERM);
+ }
+ }
+# endif /* QUEUE */
+
/* if we've had errors so far, exit now */
if (ExitStat != EX_OK && OpMode != MD_TEST)
{
+ endpwent();
setuid(RealUid);
exit(ExitStat);
}
-#ifdef XDEBUG
+#if XDEBUG
checkfd012("before main() initmaps");
#endif
@@ -822,6 +963,7 @@ main(argc, argv, envp)
#ifdef QUEUE
dropenvelope(CurEnv);
printqueue();
+ endpwent();
setuid(RealUid);
exit(EX_OK);
#else /* QUEUE */
@@ -832,10 +974,12 @@ main(argc, argv, envp)
case MD_INITALIAS:
/* initialize alias database */
initmaps(TRUE, CurEnv);
+ endpwent();
setuid(RealUid);
exit(EX_OK);
case MD_DAEMON:
+ case MD_SMTP:
/* don't open alias database -- done in srvrsmtp */
break;
@@ -848,35 +992,12 @@ main(argc, argv, envp)
if (tTd(0, 15))
{
/* print configuration table (or at least part of it) */
- printrules();
+ if (tTd(0, 90))
+ printrules();
for (i = 0; i < MAXMAILERS; i++)
{
- register struct mailer *m = Mailer[i];
- int j;
-
- if (m == NULL)
- continue;
- printf("mailer %d (%s): P=%s S=%d/%d R=%d/%d M=%ld F=", i, m->m_name,
- m->m_mailer, m->m_se_rwset, m->m_sh_rwset,
- m->m_re_rwset, m->m_rh_rwset, m->m_maxsize);
- for (j = '\0'; j <= '\177'; j++)
- if (bitnset(j, m->m_flags))
- (void) putchar(j);
- printf(" E=");
- xputs(m->m_eol);
- if (m->m_argv != NULL)
- {
- char **a = m->m_argv;
-
- printf(" A=");
- while (*a != NULL)
- {
- if (a != m->m_argv)
- printf(" ");
- xputs(*a++);
- }
- }
- printf("\n");
+ if (Mailer[i] != NULL)
+ printmailer(Mailer[i]);
}
}
@@ -894,6 +1015,7 @@ main(argc, argv, envp)
if (OpMode == MD_TEST)
{
char buf[MAXLINE];
+ void intindebug();
if (isatty(fileno(stdin)))
Verbose = TRUE;
@@ -903,69 +1025,24 @@ main(argc, argv, envp)
printf("ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)\n");
printf("Enter <ruleset> <address>\n");
}
+ if (setjmp(TopFrame) > 0)
+ printf("\n");
+ (void) setsignal(SIGINT, intindebug);
for (;;)
{
- register char **pvp;
- char *q;
- auto char *delimptr;
- extern bool invalidaddr();
- extern char *crackaddr();
+ extern void testmodeline __P((char *, ENVELOPE *));
if (Verbose)
printf("> ");
(void) fflush(stdout);
if (fgets(buf, sizeof buf, stdin) == NULL)
finis();
+ p = strchr(buf, '\n');
+ if (p != NULL)
+ *p = '\0';
if (!Verbose)
- printf("> %s", buf);
- switch (buf[0])
- {
- case '#':
- continue;
-
-#ifdef MAYBENEXTRELEASE
- case 'C': /* try crackaddr */
- q = crackaddr(&buf[1]);
- xputs(q);
- printf("\n");
- continue;
-#endif
- }
-
- for (p = buf; isascii(*p) && isspace(*p); p++)
- continue;
- q = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
- p++;
- if (*p == '\0')
- {
- printf("No address!\n");
- continue;
- }
- *p = '\0';
- if (invalidaddr(p + 1, NULL))
- continue;
- do
- {
- char pvpbuf[PSBUFSIZE];
-
- pvp = prescan(++p, ',', pvpbuf, sizeof pvpbuf,
- &delimptr);
- if (pvp == NULL)
- continue;
- p = q;
- while (*p != '\0')
- {
- int stat;
-
- stat = rewrite(pvp, atoi(p), 0, CurEnv);
- if (stat != EX_OK)
- printf("== Ruleset %s status %d\n",
- p, stat);
- while (*p != '\0' && *p++ != ',')
- continue;
- }
- } while (*(p = delimptr) != '\0');
+ printf("> %s\n", buf);
+ testmodeline(buf, CurEnv);
}
}
@@ -976,6 +1053,7 @@ main(argc, argv, envp)
if (queuemode && OpMode != MD_DAEMON && QueueIntvl == 0)
{
+ (void) unsetenv("HOSTALIASES");
runqueue(FALSE);
finis();
}
@@ -994,7 +1072,7 @@ main(argc, argv, envp)
{
char dtype[200];
- if (!tTd(0, 1))
+ if (!tTd(99, 100))
{
/* put us in background */
i = fork();
@@ -1066,11 +1144,12 @@ main(argc, argv, envp)
{
CurEnv->e_sendmode = SM_VERIFY;
CurEnv->e_errormode = EM_QUIET;
+ PostMasterCopy = NULL;
}
else
{
/* interactive -- all errors are global */
- CurEnv->e_flags |= EF_GLOBALERRS;
+ CurEnv->e_flags |= EF_GLOBALERRS|EF_LOGSENDER;
}
/*
@@ -1078,6 +1157,9 @@ main(argc, argv, envp)
*/
initsys(CurEnv);
+ if (warn_f_flag != '\0' && !wordinclass(RealUserName, 't'))
+ auth_warning(CurEnv, "%s set sender to %s using -%c",
+ RealUserName, from, warn_f_flag);
setsender(from, CurEnv, NULL, FALSE);
if (macvalue('s', CurEnv) == NULL)
define('s', RealHostName, CurEnv);
@@ -1089,7 +1171,7 @@ main(argc, argv, envp)
/* collect body for UUCP return */
if (OpMode != MD_VERIFY)
- collect(FALSE, FALSE, CurEnv);
+ collect(InChannel, FALSE, FALSE, NULL, CurEnv);
finis();
}
@@ -1111,7 +1193,7 @@ main(argc, argv, envp)
if (OpMode != MD_VERIFY || GrabTo)
{
CurEnv->e_flags |= EF_GLOBALERRS;
- collect(FALSE, FALSE, CurEnv);
+ collect(InChannel, FALSE, FALSE, NULL, CurEnv);
}
errno = 0;
@@ -1139,6 +1221,15 @@ main(argc, argv, envp)
finis();
}
+
+
+void
+intindebug()
+{
+ longjmp(TopFrame, 1);
+}
+
+
/*
** FINIS -- Clean up and exit.
**
@@ -1152,12 +1243,18 @@ main(argc, argv, envp)
** exits sendmail
*/
+void
finis()
{
if (tTd(2, 1))
- printf("\n====finis: stat %d e_flags %o, e_id=%s\n",
- ExitStat, CurEnv->e_flags,
+ {
+ extern void printenvflags();
+
+ printf("\n====finis: stat %d e_id=%s e_flags=",
+ ExitStat,
CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id);
+ printenvflags(CurEnv);
+ }
if (tTd(2, 9))
printopenfds(FALSE);
@@ -1178,10 +1275,11 @@ finis()
if (LogLevel > 78)
syslog(LOG_DEBUG, "finis, pid=%d", getpid());
# endif /* LOG */
- if (ExitStat == EX_TEMPFAIL)
+ if (ExitStat == EX_TEMPFAIL || CurEnv->e_errormode == EM_BERKNET)
ExitStat = EX_OK;
/* reset uid for process accounting */
+ endpwent();
setuid(RealUid);
exit(ExitStat);
@@ -1212,6 +1310,7 @@ intsig()
#endif
/* reset uid for process accounting */
+ endpwent();
setuid(RealUid);
exit(EX_OK);
@@ -1255,12 +1354,18 @@ struct metamac MetaMacros[] =
'\0'
};
+#define MACBINDING(name, mid) \
+ stab(name, ST_MACRO, ST_ENTER)->s_macro = mid; \
+ MacroName[mid] = name;
+
+void
initmacros(e)
register ENVELOPE *e;
{
register struct metamac *m;
- char buf[5];
register int c;
+ char buf[5];
+ extern char *MacroName[256];
for (m = MetaMacros; m->metaname != '\0'; m++)
{
@@ -1277,11 +1382,11 @@ initmacros(e)
}
/* set defaults for some macros sendmail will use later */
- define('e', "\201j Sendmail \201v ready at \201b", e);
- define('l', "From \201g \201d", e);
define('n', "MAILER-DAEMON", e);
- define('o', ".:@[]", e);
- define('q', "<\201g>", e);
+
+ /* set up external names for some internal macros */
+ MACBINDING("opMode", MID_OPMODE);
+ /*XXX should probably add equivalents for all short macros here XXX*/
}
/*
** DISCONNECT -- remove our connection with any foreground process
@@ -1303,6 +1408,7 @@ initmacros(e)
** the controlling tty.
*/
+void
disconnect(droplev, e)
int droplev;
register ENVELOPE *e;
@@ -1312,14 +1418,13 @@ disconnect(droplev, e)
if (tTd(52, 1))
printf("disconnect: In %d Out %d, e=%x\n",
fileno(InChannel), fileno(OutChannel), e);
- if (tTd(52, 5))
+ if (tTd(52, 100))
{
printf("don't\n");
return;
}
/* be sure we don't get nasty signals */
- (void) setsignal(SIGHUP, SIG_IGN);
(void) setsignal(SIGINT, SIG_IGN);
(void) setsignal(SIGQUIT, SIG_IGN);
@@ -1363,7 +1468,7 @@ disconnect(droplev, e)
errno = 0;
}
-#ifdef XDEBUG
+#if XDEBUG
checkfd012("disconnect");
#endif
@@ -1391,7 +1496,11 @@ obsolete(argv)
/* skip over options that do have a value */
op = strchr(OPTIONS, ap[1]);
if (op != NULL && *++op == ':' && ap[2] == '\0' &&
- ap[1] != 'd' && argv[1] != NULL && argv[1][0] != '-')
+ ap[1] != 'd' &&
+#if defined(sony_news)
+ ap[1] != 'E' && ap[1] != 'J' &&
+#endif
+ argv[1] != NULL && argv[1][0] != '-')
{
argv++;
continue;
@@ -1414,6 +1523,16 @@ obsolete(argv)
/* if -d doesn't have an argument, use 0-99.1 */
if (ap[1] == 'd' && ap[2] == '\0')
*argv = "-d0-99.1";
+
+# if defined(sony_news)
+ /* if -E doesn't have an argument, use -EC */
+ if (ap[1] == 'E' && ap[2] == '\0')
+ *argv = "-EC";
+
+ /* if -J doesn't have an argument, use -JJ */
+ if (ap[1] == 'J' && ap[2] == '\0')
+ *argv = "-JJ";
+# endif
}
}
/*
@@ -1445,7 +1564,7 @@ auth_warning(e, msg, va_alist)
{
register char *p;
static char hostbuf[48];
- extern char **myhostname();
+ extern struct hostent *myhostname();
if (hostbuf[0] == '\0')
(void) myhostname(hostbuf, sizeof hostbuf);
@@ -1453,10 +1572,67 @@ auth_warning(e, msg, va_alist)
(void) sprintf(buf, "%s: ", hostbuf);
p = &buf[strlen(buf)];
VA_START(msg);
- vsprintf(p, msg, ap);
+ vsnprintf(p, sizeof buf - (p - buf), msg, ap);
VA_END;
- addheader("X-Authentication-Warning", buf, e);
+ addheader("X-Authentication-Warning", buf, &e->e_header);
+#ifdef LOG
+ if (LogLevel > 3)
+ syslog(LOG_INFO, "%s: Authentication-Warning: %.400s",
+ e->e_id == NULL ? "[NOQUEUE]" : e->e_id, buf);
+#endif
+ }
+}
+ /*
+** SETUSERENV -- set an environment in the propogated environment
+**
+** Parameters:
+** envar -- the name of the environment variable.
+** value -- the value to which it should be set. If
+** null, this is extracted from the incoming
+** environment. If that is not set, the call
+** to setuserenv is ignored.
+**
+** Returns:
+** none.
+*/
+
+void
+setuserenv(envar, value)
+ const char *envar;
+ const char *value;
+{
+ int i;
+ char **evp = UserEnviron;
+ char *p;
+
+ if (value == NULL)
+ {
+ value = getenv(envar);
+ if (value == NULL)
+ return;
+ }
+
+ i = strlen(envar);
+ p = (char *) xalloc(strlen(value) + i + 2);
+ strcpy(p, envar);
+ p[i++] = '=';
+ strcpy(&p[i], value);
+
+ while (*evp != NULL && strncmp(*evp, p, i) != 0)
+ evp++;
+ if (*evp != NULL)
+ {
+ *evp++ = p;
+ }
+ else if (evp < &UserEnviron[MAXUSERENVIRON])
+ {
+ *evp++ = p;
+ *evp = NULL;
}
+
+ /* make sure it is in our environment as well */
+ if (putenv(p) < 0)
+ syserr("setuserenv: putenv(%s) failed", p);
}
/*
** DUMPSTATE -- dump state
@@ -1470,17 +1646,16 @@ dumpstate(when)
{
#ifdef LOG
register char *j = macvalue('j', CurEnv);
- register STAB *s;
syslog(LOG_DEBUG, "--- dumping state on %s: $j = %s ---",
when,
j == NULL ? "<NULL>" : j);
if (j != NULL)
{
- s = stab(j, ST_CLASS, ST_FIND);
- if (s == NULL || !bitnset('w', s->s_class))
+ if (!wordinclass(j, 'w'))
syslog(LOG_DEBUG, "*** $j not in $=w ***");
}
+ syslog(LOG_DEBUG, "CurChildren = %d", CurChildren);
syslog(LOG_DEBUG, "--- open file descriptors: ---");
printopenfds(TRUE);
syslog(LOG_DEBUG, "--- connection cache: ---");
@@ -1508,3 +1683,431 @@ sigusr1()
{
dumpstate("user signal");
}
+
+
+void
+sighup()
+{
+#ifdef LOG
+ if (LogLevel > 3)
+ syslog(LOG_INFO, "restarting %s on signal", SaveArgv[0]);
+#endif
+ releasesignal(SIGHUP);
+ execv(SaveArgv[0], (ARGV_T) SaveArgv);
+#ifdef LOG
+ if (LogLevel > 0)
+ syslog(LOG_ALERT, "could not exec %s: %m", SaveArgv[0]);
+#endif
+ exit(EX_OSFILE);
+}
+ /*
+** TESTMODELINE -- process a test mode input line
+**
+** Parameters:
+** line -- the input line.
+** e -- the current environment.
+** Syntax:
+** # a comment
+** .X process X as a configuration line
+** =X dump a configuration item (such as mailers)
+** $X dump a macro or class
+** /X try an activity
+** X normal process through rule set X
+*/
+
+void
+testmodeline(line, e)
+ char *line;
+ ENVELOPE *e;
+{
+ register char *p;
+ char *q;
+ auto char *delimptr;
+ int mid;
+ int i, rs;
+ STAB *map;
+ char **s;
+ struct rewrite *rw;
+ ADDRESS a;
+ static int tryflags = RF_COPYNONE;
+ char exbuf[MAXLINE];
+ extern bool invalidaddr __P((char *, char *));
+ extern char *crackaddr __P((char *));
+ extern void dump_class __P((STAB *, int));
+ extern void translate_dollars __P((char *));
+
+ switch (line[0])
+ {
+ case '#':
+ case 0:
+ return;
+
+ case '?':
+ help("-bt");
+ return;
+
+ case '.': /* config-style settings */
+ switch (line[1])
+ {
+ case 'D':
+ mid = macid(&line[2], &delimptr);
+ if (mid == '\0')
+ return;
+ translate_dollars(delimptr);
+ define(mid, newstr(delimptr), e);
+ break;
+
+ case 'C':
+ if (line[2] == '\0') /* not to call syserr() */
+ return;
+
+ mid = macid(&line[2], &delimptr);
+ if (mid == '\0')
+ return;
+ translate_dollars(delimptr);
+ expand(delimptr, exbuf, sizeof exbuf, e);
+ p = exbuf;
+ while (*p != '\0')
+ {
+ register char *wd;
+ char delim;
+
+ while (*p != '\0' && isascii(*p) && isspace(*p))
+ p++;
+ wd = p;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ delim = *p;
+ *p = '\0';
+ if (wd[0] != '\0')
+ setclass(mid, wd);
+ *p = delim;
+ }
+ break;
+
+ case '\0':
+ printf("Usage: .[DC]macro value(s)\n");
+ break;
+
+ default:
+ printf("Unknown \".\" command %s\n", line);
+ break;
+ }
+ return;
+
+ case '=': /* config-style settings */
+ switch (line[1])
+ {
+ case 'S': /* dump rule set */
+ rs = strtorwset(&line[2], NULL, ST_FIND);
+ if (rs < 0)
+ return;
+ rw = RewriteRules[rs];
+ if (rw == NULL)
+ return;
+ do
+ {
+ putchar('R');
+ s = rw->r_lhs;
+ while (*s != NULL)
+ {
+ xputs(*s++);
+ putchar(' ');
+ }
+ putchar('\t');
+ putchar('\t');
+ s = rw->r_rhs;
+ while (*s != NULL)
+ {
+ xputs(*s++);
+ putchar(' ');
+ }
+ putchar('\n');
+ } while (rw = rw->r_next);
+ break;
+
+ case 'M':
+ for (i = 0; i < MAXMAILERS; i++)
+ {
+ if (Mailer[i] != NULL)
+ printmailer(Mailer[i]);
+ }
+ break;
+
+ case '\0':
+ printf("Usage: =Sruleset or =M\n");
+ break;
+
+ default:
+ printf("Unknown \"=\" command %s\n", line);
+ break;
+ }
+ return;
+
+ case '-': /* set command-line-like opts */
+ switch (line[1])
+ {
+ case 'd':
+ tTflag(&line[2]);
+ break;
+
+ case '\0':
+ printf("Usage: -d{debug arguments}\n");
+ break;
+
+ default:
+ printf("Unknown \"-\" command %s\n", line);
+ break;
+ }
+ return;
+
+ case '$':
+ if (line[1] == '=')
+ {
+ mid = macid(&line[2], NULL);
+ if (mid != '\0')
+ stabapply(dump_class, mid);
+ return;
+ }
+ mid = macid(&line[1], NULL);
+ if (mid == '\0')
+ return;
+ p = macvalue(mid, e);
+ if (p == NULL)
+ printf("Undefined\n");
+ else
+ {
+ xputs(p);
+ printf("\n");
+ }
+ return;
+
+ case '/': /* miscellaneous commands */
+ p = &line[strlen(line)];
+ while (--p >= line && isascii(*p) && isspace(*p))
+ *p = '\0';
+ p = strpbrk(line, " \t");
+ if (p != NULL)
+ {
+ while (isascii(*p) && isspace(*p))
+ *p++ = '\0';
+ }
+ else
+ p = "";
+ if (line[1] == '\0')
+ {
+ printf("Usage: /[canon|map|mx|parse|try|tryflags]\n");
+ return;
+ }
+ if (strcasecmp(&line[1], "mx") == 0)
+ {
+#if NAMED_BIND
+ /* look up MX records */
+ int nmx;
+ auto int rcode;
+ char *mxhosts[MAXMXHOSTS + 1];
+
+ if (*p == '\0')
+ {
+ printf("Usage: /mx address\n");
+ return;
+ }
+ nmx = getmxrr(p, mxhosts, FALSE, &rcode);
+ printf("getmxrr(%s) returns %d value(s):\n", p, nmx);
+ for (i = 0; i < nmx; i++)
+ printf("\t%s\n", mxhosts[i]);
+#else
+ printf("No MX code compiled in\n");
+#endif
+ }
+ else if (strcasecmp(&line[1], "canon") == 0)
+ {
+ auto int rcode = EX_OK;
+ char host[MAXHOSTNAMELEN];
+
+ if (*p == '\0')
+ {
+ printf("Usage: /canon address\n");
+ return;
+ }
+ strcpy(host, p);
+ getcanonname(host, sizeof(host), HasWildcardMX, &rcode);
+ printf("getcanonname(%s) returns %s (%d)\n",
+ p, host, rcode);
+ }
+ else if (strcasecmp(&line[1], "map") == 0)
+ {
+ auto int rcode = EX_OK;
+
+ if (*p == '\0')
+ {
+ printf("Usage: /map mapname key\n");
+ return;
+ }
+ for (q = p; *q != '\0' && !isspace(*q); q++)
+ continue;
+ if (*q == '\0')
+ {
+ printf("No key specified\n");
+ return;
+ }
+ *q++ = '\0';
+ map = stab(p, ST_MAP, ST_FIND);
+ if (map == NULL)
+ {
+ printf("Map named \"%s\" not found\n", p);
+ return;
+ }
+ printf("map_lookup: %s (%s) ", p, q);
+ p = (*map->s_map.map_class->map_lookup)
+ (&map->s_map, q, NULL, &rcode);
+ if (p == NULL)
+ printf("no match (%d)\n", rcode);
+ else
+ printf("returns %s (%d)\n", p, rcode);
+ }
+ else if (strcasecmp(&line[1], "try") == 0)
+ {
+ MAILER *m;
+ STAB *s;
+ auto int rcode = EX_OK;
+
+ q = strpbrk(p, " \t");
+ if (q != NULL)
+ {
+ while (isascii(*q) && isspace(*q))
+ *q++ = '\0';
+ }
+ if (q == NULL || *q == '\0')
+ {
+ printf("Usage: /try mailer address\n");
+ return;
+ }
+ s = stab(p, ST_MAILER, ST_FIND);
+ if (s == NULL)
+ {
+ printf("Unknown mailer %s\n", p);
+ return;
+ }
+ m = s->s_mailer;
+ printf("Trying %s %s address %s for mailer %s\n",
+ bitset(RF_HEADERADDR, tryflags) ? "header" : "envelope",
+ bitset(RF_SENDERADDR, tryflags) ? "sender" : "recipient",
+ q, p);
+ p = remotename(q, m, tryflags, &rcode, CurEnv);
+ printf("Rcode = %d, addr = %s\n",
+ rcode, p == NULL ? "<NULL>" : p);
+ }
+ else if (strcasecmp(&line[1], "tryflags") == 0)
+ {
+ if (*p == '\0')
+ {
+ printf("Usage: /tryflags [Hh|Ee][Ss|Rr]\n");
+ return;
+ }
+ for (; *p != '\0'; p++)
+ {
+ switch (*p)
+ {
+ case 'H':
+ case 'h':
+ tryflags |= RF_HEADERADDR;
+ break;
+
+ case 'E':
+ case 'e':
+ tryflags &= ~RF_HEADERADDR;
+ break;
+
+ case 'S':
+ case 's':
+ tryflags |= RF_SENDERADDR;
+ break;
+
+ case 'R':
+ case 'r':
+ tryflags &= ~RF_SENDERADDR;
+ break;
+ }
+ }
+ }
+ else if (strcasecmp(&line[1], "parse") == 0)
+ {
+ if (*p == '\0')
+ {
+ printf("Usage: /parse address\n");
+ return;
+ }
+ q = crackaddr(p);
+ printf("Cracked address = ");
+ xputs(q);
+ printf("\nParsing %s %s address\n",
+ bitset(RF_HEADERADDR, tryflags) ? "header" : "envelope",
+ bitset(RF_SENDERADDR, tryflags) ? "sender" : "recipient");
+ if (parseaddr(p, &a, tryflags, '\0', NULL, e) == NULL)
+ printf("Cannot parse\n");
+ else if (a.q_host != NULL && a.q_host[0] != '\0')
+ printf("mailer %s, host %s, user %s\n",
+ a.q_mailer->m_name, a.q_host, a.q_user);
+ else
+ printf("mailer %s, user %s\n",
+ a.q_mailer->m_name, a.q_user);
+ }
+ else
+ {
+ printf("Unknown \"/\" command %s\n", line);
+ }
+ return;
+ }
+
+ for (p = line; isascii(*p) && isspace(*p); p++)
+ continue;
+ q = p;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ if (*p == '\0')
+ {
+ printf("No address!\n");
+ return;
+ }
+ *p = '\0';
+ if (invalidaddr(p + 1, NULL))
+ return;
+ do
+ {
+ register char **pvp;
+ char pvpbuf[PSBUFSIZE];
+
+ pvp = prescan(++p, ',', pvpbuf, sizeof pvpbuf,
+ &delimptr, NULL);
+ if (pvp == NULL)
+ continue;
+ p = q;
+ while (*p != '\0')
+ {
+ int stat;
+ int rs = strtorwset(p, NULL, ST_FIND);
+
+ if (rs < 0)
+ break;
+ stat = rewrite(pvp, rs, 0, e);
+ if (stat != EX_OK)
+ printf("== Ruleset %s (%d) status %d\n",
+ p, rs, stat);
+ while (*p != '\0' && *p++ != ',')
+ continue;
+ }
+ } while (*(p = delimptr) != '\0');
+}
+
+
+void
+dump_class(s, id)
+ register STAB *s;
+ int id;
+{
+ if (s->s_type != ST_CLASS)
+ return;
+ if (bitnset(id & 0xff, s->s_class))
+ printf("%s\n", s->s_name);
+}
diff --git a/usr.sbin/sendmail/src/parseaddr.c b/usr.sbin/sendmail/src/parseaddr.c
index 2683728..debccdf 100644
--- a/usr.sbin/sendmail/src/parseaddr.c
+++ b/usr.sbin/sendmail/src/parseaddr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)parseaddr.c 8.31 (Berkeley) 4/15/94";
+static char sccsid[] = "@(#)parseaddr.c 8.86 (Berkeley) 9/28/95";
#endif /* not lint */
# include "sendmail.h"
@@ -91,6 +91,7 @@ parseaddr(addr, a, flags, delim, delimptr, e)
char pvpbuf[PSBUFSIZE];
extern ADDRESS *buildaddr();
extern bool invalidaddr();
+ extern void allocaddr __P((ADDRESS *, int, char *));
/*
** Initialize and prescan address.
@@ -103,7 +104,7 @@ parseaddr(addr, a, flags, delim, delimptr, e)
if (delimptr == NULL)
delimptr = &delimptrbuf;
- pvp = prescan(addr, delim, pvpbuf, sizeof pvpbuf, delimptr);
+ pvp = prescan(addr, delim, pvpbuf, sizeof pvpbuf, delimptr, NULL);
if (pvp == NULL)
{
if (tTd(20, 1))
@@ -172,12 +173,15 @@ parseaddr(addr, a, flags, delim, delimptr, e)
{
char *msg = "Transient parse error -- message queued for future delivery";
+ if (e->e_sendmode == SM_DEFER)
+ msg = "Deferring message until queue run";
if (tTd(20, 1))
printf("parseaddr: queuing message\n");
message(msg);
- if (e->e_message == NULL)
+ if (e->e_message == NULL && e->e_sendmode != SM_DEFER)
e->e_message = newstr(msg);
a->q_flags |= QQUEUEUP;
+ a->q_status = "4.4.3";
}
/*
@@ -208,7 +212,7 @@ invalidaddr(addr, delimptr)
register char *addr;
char *delimptr;
{
- char savedelim;
+ char savedelim = '\0';
if (delimptr != NULL)
{
@@ -231,14 +235,14 @@ invalidaddr(addr, delimptr)
}
if (*addr == '\0')
{
- if (savedelim != '\0' && delimptr != NULL)
+ if (delimptr != NULL && savedelim != '\0')
*delimptr = savedelim;
return FALSE;
}
setstat(EX_USAGE);
usrerr("553 Address contained invalid control characters");
addrfailure:
- if (savedelim != '\0' && delimptr != NULL)
+ if (delimptr != NULL && savedelim != '\0')
*delimptr = savedelim;
return TRUE;
}
@@ -260,13 +264,14 @@ invalidaddr(addr, delimptr)
** Copies portions of a into local buffers as requested.
*/
+void
allocaddr(a, flags, paddr)
register ADDRESS *a;
int flags;
char *paddr;
{
if (tTd(24, 4))
- printf("allocaddr(flags=%o, paddr=%s)\n", flags, paddr);
+ printf("allocaddr(flags=%x, paddr=%s)\n", flags, paddr);
a->q_paddr = paddr;
@@ -311,6 +316,8 @@ allocaddr(a, flags, paddr)
** pvpbsize -- size of pvpbuf.
** delimptr -- if non-NULL, set to the location of the
** terminating delimiter.
+** toktab -- if set, a token table to use for parsing.
+** If NULL, use the default table.
**
** Returns:
** A pointer to a vector of tokens.
@@ -323,8 +330,9 @@ allocaddr(a, flags, paddr)
# define QST 2 /* in quoted string */
# define SPC 3 /* chewing up spaces */
# define ONE 4 /* pick up one character */
+# define ILL 5 /* illegal character */
-# define NSTATES 5 /* number of states */
+# define NSTATES 6 /* number of states */
# define TYPE 017 /* mask to select state type */
/* meta bits for table */
@@ -334,46 +342,102 @@ allocaddr(a, flags, paddr)
static short StateTab[NSTATES][NSTATES] =
{
- /* oldst chtype> OPR ATM QST SPC ONE */
- /*OPR*/ OPR|B, ATM|B, QST|B, SPC|MB, ONE|B,
- /*ATM*/ OPR|B, ATM, QST|B, SPC|MB, ONE|B,
- /*QST*/ QST, QST, OPR, QST, QST,
- /*SPC*/ OPR, ATM, QST, SPC|M, ONE,
- /*ONE*/ OPR, OPR, OPR, OPR, OPR,
+ /* oldst chtype> OPR ATM QST SPC ONE ILL */
+ /*OPR*/ OPR|B, ATM|B, QST|B, SPC|MB, ONE|B, ILL|MB,
+ /*ATM*/ OPR|B, ATM, QST|B, SPC|MB, ONE|B, ILL|MB,
+ /*QST*/ QST, QST, OPR, QST, QST, QST,
+ /*SPC*/ OPR, ATM, QST, SPC|M, ONE, ILL|MB,
+ /*ONE*/ OPR, OPR, OPR, OPR, OPR, ILL|MB,
+ /*ILL*/ OPR|B, ATM|B, QST|B, SPC|MB, ONE|B, ILL|M,
};
/* token type table -- it gets modified with $o characters */
-static TokTypeTab[256] =
+static u_char TokTypeTab[256] =
{
- ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,SPC,SPC,SPC,SPC,SPC,ATM,ATM,
- ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
- SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM,ATM,SPC,ATM,ATM,ATM,ATM,ATM,ATM,
- ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
- ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
- ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
- ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
- ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
- OPR,OPR,ONE,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,
- OPR,OPR,OPR,ONE,ONE,ONE,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,
- ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
- ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
- ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
- ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
- ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
- ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,SPC,SPC,SPC,SPC,SPC,ATM,ATM,
+ /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ /* sp ! " # $ % & ' ( ) * + , - . / */
+ SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM, ATM,SPC,ATM,ATM,ATM,ATM,ATM,ATM,
+ /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ /* @ A B C D E F G H I J K L M N O */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ /* P Q R S T U V W X Y Z [ \ ] ^ _ */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ /* ` a b c d e f g h i j k l m n o */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ /* p q r s t u v w x y z { | } ~ del */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+
+ /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */
+ OPR,OPR,ONE,OPR,OPR,OPR,OPR,OPR, OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,
+ /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */
+ OPR,OPR,OPR,ONE,ONE,ONE,OPR,OPR, OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,
+ /* sp ! " # $ % & ' ( ) * + , - . / */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ /* @ A B C D E F G H I J K L M N O */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ /* P Q R S T U V W X Y Z [ \ ] ^ _ */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ /* ` a b c d e f g h i j k l m n o */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ /* p q r s t u v w x y z { | } ~ del */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
};
-#define toktype(c) ((int) TokTypeTab[(c) & 0xff])
+/* token type table for MIME parsing */
+u_char MimeTokenTab[256] =
+{
+ /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */
+ ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,SPC,SPC,SPC,SPC,SPC,ILL,ILL,
+ /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */
+ ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
+ /* sp ! " # $ % & ' ( ) * + , - . / */
+ SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM, ATM,SPC,ATM,ATM,OPR,ATM,ATM,OPR,
+ /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,OPR,OPR,OPR,OPR,OPR,OPR,
+ /* @ A B C D E F G H I J K L M N O */
+ OPR,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ /* P Q R S T U V W X Y Z [ \ ] ^ _ */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,OPR,OPR,OPR,ATM,ATM,
+ /* ` a b c d e f g h i j k l m n o */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ /* p q r s t u v w x y z { | } ~ del */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+
+ /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */
+ ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
+ /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */
+ ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
+ /* sp ! " # $ % & ' ( ) * + , - . / */
+ ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
+ /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
+ ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
+ /* @ A B C D E F G H I J K L M N O */
+ ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
+ /* P Q R S T U V W X Y Z [ \ ] ^ _ */
+ ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
+ /* ` a b c d e f g h i j k l m n o */
+ ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
+ /* p q r s t u v w x y z { | } ~ del */
+ ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL,
+};
# define NOCHAR -1 /* signal nothing in lookahead token */
char **
-prescan(addr, delim, pvpbuf, pvpbsize, delimptr)
+prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab)
char *addr;
- char delim;
+ int delim;
char pvpbuf[];
+ int pvpbsize;
char **delimptr;
+ u_char *toktab;
{
register char *p;
register char *q;
@@ -396,7 +460,14 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr)
char obuf[50];
firsttime = FALSE;
- expand("\201o", obuf, &obuf[sizeof obuf - sizeof DELIMCHARS], CurEnv);
+ if (OperatorChars == NULL)
+ {
+ if (ConfigLevel < 7)
+ OperatorChars = macvalue('o', CurEnv);
+ if (OperatorChars == NULL)
+ OperatorChars = ".:@[]";
+ }
+ expand(OperatorChars, obuf, sizeof obuf - sizeof DELIMCHARS, CurEnv);
strcat(obuf, DELIMCHARS);
for (p = obuf; *p != '\0'; p++)
{
@@ -404,6 +475,8 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr)
TokTypeTab[*p & 0xff] = OPR;
}
}
+ if (toktab == NULL)
+ toktab = TokTypeTab;
/* make sure error messages don't have garbage on them */
errno = 0;
@@ -437,6 +510,8 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr)
if (q >= &pvpbuf[pvpbsize - 5])
{
usrerr("553 Address too long");
+ if (strlen(addr) > MAXNAME)
+ addr[MAXNAME] = '\0';
returnnull:
if (delimptr != NULL)
*delimptr = p;
@@ -546,10 +621,17 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr)
if (c == delim && anglecnt <= 0 && state != QST)
break;
- newstate = StateTab[state][toktype(c)];
+ newstate = StateTab[state][toktab[c & 0xff]];
if (tTd(22, 101))
printf("ns=%02o\n", newstate);
state = newstate & TYPE;
+ if (state == ILL)
+ {
+ if (isascii(c) && isprint(c))
+ usrerr("653 Illegal character %c", c);
+ else
+ usrerr("653 Illegal character 0x%02x", c);
+ }
if (bitset(M, newstate))
c = NOCHAR;
if (bitset(B, newstate))
@@ -642,10 +724,6 @@ struct match
# define MAXMATCH 9 /* max params per rewrite */
-# ifndef MAXRULERECURSION
-# define MAXRULERECURSION 50 /* max recursion depth */
-# endif
-
int
rewrite(pvp, ruleset, reclevel, e)
@@ -666,7 +744,7 @@ rewrite(pvp, ruleset, reclevel, e)
struct match mlist[MAXMATCH]; /* stores match on LHS */
char *npvp[MAXATOM+1]; /* temporary space for rebuild */
- if (OpMode == MD_TEST || tTd(21, 2))
+ if (OpMode == MD_TEST || tTd(21, 1))
{
printf("rewrite: ruleset %2d input:", ruleset);
printav(pvp);
@@ -676,9 +754,10 @@ rewrite(pvp, ruleset, reclevel, e)
syserr("554 rewrite: illegal ruleset number %d", ruleset);
return EX_CONFIG;
}
- if (reclevel++ > MAXRULERECURSION)
+ if (reclevel++ > MaxRuleRecursion)
{
- syserr("rewrite: infinite recursion, ruleset %d", ruleset);
+ syserr("rewrite: excessive recursion (max %d), ruleset %d",
+ MaxRuleRecursion, ruleset);
return EX_CONFIG;
}
if (pvp == NULL)
@@ -740,7 +819,6 @@ rewrite(pvp, ruleset, reclevel, e)
switch (*rp & 0377)
{
- register STAB *s;
char buf[MAXLINE];
case MATCHCLASS:
@@ -753,8 +831,7 @@ rewrite(pvp, ruleset, reclevel, e)
goto backup;
mlp->last = avp++;
cataddr(mlp->first, mlp->last, buf, sizeof buf, '\0');
- s = stab(buf, ST_CLASS, ST_FIND);
- if (s == NULL || !bitnset(rp[1], s->s_class))
+ if (!wordinclass(buf, rp[1]))
{
if (tTd(21, 36))
{
@@ -773,8 +850,7 @@ rewrite(pvp, ruleset, reclevel, e)
case MATCHNCLASS:
/* match any token not in a class */
- s = stab(ap, ST_CLASS, ST_FIND);
- if (s != NULL && bitnset(rp[1], s->s_class))
+ if (wordinclass(ap, rp[1]))
goto backup;
/* fall through */
@@ -1097,10 +1173,22 @@ rewrite(pvp, ruleset, reclevel, e)
/* look it up */
cataddr(key_rvp, NULL, buf, sizeof buf, '\0');
argvect[0] = buf;
- if (map != NULL && bitset(MF_OPEN, map->s_map.map_mflags))
+ if (e->e_sendmode == SM_DEFER)
+ {
+ /* don't do any map lookups */
+ if (tTd(60, 1))
+ printf("map_lookup(%s, %s) => DEFERRED\n",
+ mapname, buf);
+ replac = NULL;
+ rstat = EX_TEMPFAIL;
+ }
+ else if (map != NULL && bitset(MF_OPEN, map->s_map.map_mflags))
{
auto int stat = EX_OK;
+ if (!bitset(MF_KEEPQUOTES, map->s_map.map_mflags))
+ stripquotes(buf);
+
/* XXX should try to auto-open the map here */
if (tTd(60, 1))
@@ -1115,7 +1203,21 @@ rewrite(pvp, ruleset, reclevel, e)
/* should recover if stat == EX_TEMPFAIL */
if (stat == EX_TEMPFAIL)
- rstat = stat;
+ {
+ rstat = EX_TEMPFAIL;
+ if (tTd(60, 1))
+ printf("map_lookup(%s, %s) tempfail: errno=%d\n",
+ mapname, buf, errno);
+ if (e->e_message == NULL)
+ {
+ char mbuf[300];
+
+ sprintf(mbuf, "%.80s map: lookup (%s): deferred",
+ mapname,
+ shortenstring(buf, 203));
+ e->e_message = newstr(mbuf);
+ }
+ }
}
else
replac = NULL;
@@ -1142,7 +1244,7 @@ rewrite(pvp, ruleset, reclevel, e)
{
/* scan the new replacement */
xpvp = prescan(replac, '\0', pvpbuf,
- sizeof pvpbuf, NULL);
+ sizeof pvpbuf, NULL, NULL);
if (xpvp == NULL)
{
/* prescan already printed error */
@@ -1182,11 +1284,15 @@ rewrite(pvp, ruleset, reclevel, e)
}
else
{
+ int ruleset;
+ STAB *s;
+
bcopy((char *) &npvp[2], (char *) pvp,
(int) (avp - npvp - 2) * sizeof *avp);
if (tTd(21, 3))
printf("-----callsubr %s\n", npvp[1]);
- stat = rewrite(pvp, atoi(npvp[1]), reclevel, e);
+ ruleset = strtorwset(npvp[1], NULL, ST_FIND);
+ stat = rewrite(pvp, ruleset, reclevel, e);
if (rstat == EX_OK || stat == EX_TEMPFAIL)
rstat = stat;
if (*pvp != NULL && (**pvp & 0377) == CANONNET)
@@ -1205,7 +1311,7 @@ rewrite(pvp, ruleset, reclevel, e)
}
}
- if (OpMode == MD_TEST || tTd(21, 2))
+ if (OpMode == MD_TEST || tTd(21, 1))
{
printf("rewrite: ruleset %2d returns:", ruleset);
printav(pvp);
@@ -1260,15 +1366,17 @@ buildaddr(tv, a, flags, e)
{
struct mailer **mp;
register struct mailer *m;
- char *bp;
- int spaceleft;
+ register char *p;
+ char *mname;
+ char **hostp;
+ char hbuf[MAXNAME + 1];
static MAILER errormailer;
static char *errorargv[] = { "ERROR", NULL };
- static char buf[MAXNAME];
+ static char ubuf[MAXNAME + 1];
if (tTd(24, 5))
{
- printf("buildaddr, flags=%o, tv=", flags);
+ printf("buildaddr, flags=%x, tv=", flags);
printav(tv);
}
@@ -1276,10 +1384,13 @@ buildaddr(tv, a, flags, e)
a = (ADDRESS *) xalloc(sizeof *a);
bzero((char *) a, sizeof *a);
+ /* set up default error return flags */
+ a->q_flags |= QPINGONFAILURE|QPINGONDELAY;
+
/* figure out what net/mailer to use */
if (*tv == NULL || (**tv & 0377) != CANONNET)
{
- syserr("554 buildaddr: no net");
+ syserr("554 buildaddr: no mailer in parsed address");
badaddr:
a->q_flags |= QBADADDR;
a->q_mailer = &errormailer;
@@ -1292,91 +1403,97 @@ badaddr:
}
return a;
}
- tv++;
- if (strcasecmp(*tv, "error") == 0)
+ mname = *++tv;
+
+ /* extract host and user portions */
+ if ((**++tv & 0377) == CANONHOST)
+ hostp = ++tv;
+ else
+ hostp = NULL;
+ while (*tv != NULL && (**tv & 0377) != CANONUSER)
+ tv++;
+ if (*tv == NULL)
{
- if ((**++tv & 0377) == CANONHOST)
+ syserr("554 buildaddr: no user");
+ goto badaddr;
+ }
+ if (tv == hostp)
+ hostp = NULL;
+ else if (hostp != NULL)
+ cataddr(hostp, tv - 1, hbuf, sizeof hbuf, '\0');
+ cataddr(++tv, NULL, ubuf, sizeof ubuf, ' ');
+
+ /* save away the host name */
+ if (strcasecmp(mname, "error") == 0)
+ {
+ if (hostp != NULL)
{
register struct errcodes *ep;
- if (isascii(**++tv) && isdigit(**tv))
+ if (strchr(hbuf, '.') != NULL)
+ {
+ a->q_status = newstr(hbuf);
+ setstat(dsntoexitstat(hbuf));
+ }
+ else if (isascii(hbuf[0]) && isdigit(hbuf[0]))
{
- setstat(atoi(*tv));
+ setstat(atoi(hbuf));
}
else
{
for (ep = ErrorCodes; ep->ec_name != NULL; ep++)
- if (strcasecmp(ep->ec_name, *tv) == 0)
+ if (strcasecmp(ep->ec_name, hbuf) == 0)
break;
setstat(ep->ec_code);
}
- tv++;
}
else
setstat(EX_UNAVAILABLE);
- if ((**tv & 0377) != CANONUSER)
- syserr("554 buildaddr: error: no user");
- cataddr(++tv, NULL, buf, sizeof buf, ' ');
- stripquotes(buf);
- if (isascii(buf[0]) && isdigit(buf[0]) &&
- isascii(buf[1]) && isdigit(buf[1]) &&
- isascii(buf[2]) && isdigit(buf[2]) &&
- buf[3] == ' ')
+ stripquotes(ubuf);
+ if (isascii(ubuf[0]) && isdigit(ubuf[0]) &&
+ isascii(ubuf[1]) && isdigit(ubuf[1]) &&
+ isascii(ubuf[2]) && isdigit(ubuf[2]) &&
+ ubuf[3] == ' ')
{
char fmt[10];
- strncpy(fmt, buf, 3);
+ strncpy(fmt, ubuf, 3);
strcpy(&fmt[3], " %s");
- usrerr(fmt, buf + 4);
+ usrerr(fmt, ubuf + 4);
+
+ /*
+ ** If this is a 4xx code and we aren't running
+ ** SMTP on our input, bounce this message;
+ ** otherwise it disappears without a trace.
+ */
+
+ if (fmt[0] == '4' && OpMode != MD_SMTP &&
+ OpMode != MD_DAEMON)
+ {
+ e->e_flags |= EF_FATALERRS;
+ }
}
else
{
- usrerr("553 %s", buf);
+ usrerr("553 %s", ubuf);
}
goto badaddr;
}
for (mp = Mailer; (m = *mp++) != NULL; )
{
- if (strcasecmp(m->m_name, *tv) == 0)
+ if (strcasecmp(m->m_name, mname) == 0)
break;
}
if (m == NULL)
{
- syserr("554 buildaddr: unknown mailer %s", *tv);
+ syserr("554 buildaddr: unknown mailer %s", mname);
goto badaddr;
}
a->q_mailer = m;
/* figure out what host (if any) */
- tv++;
- if ((**tv & 0377) == CANONHOST)
- {
- bp = buf;
- spaceleft = sizeof buf - 1;
- while (*++tv != NULL && (**tv & 0377) != CANONUSER)
- {
- int i = strlen(*tv);
-
- if (i > spaceleft)
- {
- /* out of space for this address */
- if (spaceleft >= 0)
- syserr("554 buildaddr: host too long (%.40s...)",
- buf);
- i = spaceleft;
- spaceleft = 0;
- }
- if (i <= 0)
- continue;
- bcopy(*tv, bp, i);
- bp += i;
- spaceleft -= i;
- }
- *bp = '\0';
- a->q_host = newstr(buf);
- }
- else
+ if (hostp == NULL)
{
if (!bitnset(M_LOCALMAILER, m->m_flags))
{
@@ -1385,47 +1502,38 @@ badaddr:
}
a->q_host = NULL;
}
+ else
+ a->q_host = newstr(hbuf);
/* figure out the user */
- if (*tv == NULL || (**tv & 0377) != CANONUSER)
+ p = ubuf;
+ if (bitnset(M_CHECKUDB, m->m_flags) && *p == '@')
{
- syserr("554 buildaddr: no user");
- goto badaddr;
+ p++;
+ tv++;
+ a->q_flags |= QNOTREMOTE;
}
- tv++;
/* do special mapping for local mailer */
- if (m == LocalMailer && *tv != NULL)
+ if (*p == '"')
+ p++;
+ if (*p == '|' && bitnset(M_CHECKPROG, m->m_flags))
+ a->q_mailer = m = ProgMailer;
+ else if (*p == '/' && bitnset(M_CHECKFILE, m->m_flags))
+ a->q_mailer = m = FileMailer;
+ else if (*p == ':' && bitnset(M_CHECKINCLUDE, m->m_flags))
{
- register char *p = *tv;
-
- if (*p == '"')
- p++;
- if (*p == '|')
- a->q_mailer = m = ProgMailer;
- else if (*p == '/')
- a->q_mailer = m = FileMailer;
- else if (*p == ':')
+ /* may be :include: */
+ stripquotes(ubuf);
+ if (strncasecmp(ubuf, ":include:", 9) == 0)
{
- /* may be :include: */
- cataddr(tv, NULL, buf, sizeof buf, '\0');
- stripquotes(buf);
- if (strncasecmp(buf, ":include:", 9) == 0)
- {
- /* if :include:, don't need further rewriting */
- a->q_mailer = m = InclMailer;
- a->q_user = &buf[9];
- return (a);
- }
+ /* if :include:, don't need further rewriting */
+ a->q_mailer = m = InclMailer;
+ a->q_user = newstr(&ubuf[9]);
+ return a;
}
}
- if (m == LocalMailer && *tv != NULL && strcmp(*tv, "@") == 0)
- {
- tv++;
- a->q_flags |= QNOTREMOTE;
- }
-
/* rewrite according recipient mailer rewriting rules */
define('h', a->q_host, e);
if (!bitset(RF_SENDERADDR|RF_HEADERADDR, flags))
@@ -1438,8 +1546,8 @@ badaddr:
(void) rewrite(tv, 4, 0, e);
/* save the result for the command line/RCPT argument */
- cataddr(tv, NULL, buf, sizeof buf, '\0');
- a->q_user = buf;
+ cataddr(tv, NULL, ubuf, sizeof ubuf, '\0');
+ a->q_user = ubuf;
/*
** Do mapping to lower case as requested by mailer
@@ -1450,7 +1558,12 @@ badaddr:
if (!bitnset(M_USR_UPPER, m->m_flags))
makelower(a->q_user);
- return (a);
+ if (tTd(24, 6))
+ {
+ printf("buildaddr => ");
+ printaddr(a, FALSE);
+ }
+ return a;
}
/*
** CATADDR -- concatenate pieces of addresses (putting in <LWSP> subs)
@@ -1471,12 +1584,13 @@ badaddr:
** Destroys buf.
*/
+void
cataddr(pvp, evp, buf, sz, spacesub)
char **pvp;
char **evp;
char *buf;
register int sz;
- char spacesub;
+ int spacesub;
{
bool oatomtok = FALSE;
bool natomtok = FALSE;
@@ -1495,7 +1609,7 @@ cataddr(pvp, evp, buf, sz, spacesub)
sz -= 2;
while (*pvp != NULL && (i = strlen(*pvp)) < sz)
{
- natomtok = (toktype(**pvp) == ATM);
+ natomtok = (TokTypeTab[**pvp & 0xff] == ATM);
if (oatomtok && natomtok)
*p++ = spacesub;
(void) strcpy(p, *pvp);
@@ -1580,17 +1694,55 @@ sameaddr(a, b)
** none.
*/
+struct qflags
+{
+ char *qf_name;
+ u_long qf_bit;
+};
+
+struct qflags AddressFlags[] =
+{
+ "QDONTSEND", QDONTSEND,
+ "QBADADDR", QBADADDR,
+ "QGOODUID", QGOODUID,
+ "QPRIMARY", QPRIMARY,
+ "QQUEUEUP", QQUEUEUP,
+ "QSENT", QSENT,
+ "QNOTREMOTE", QNOTREMOTE,
+ "QSELFREF", QSELFREF,
+ "QVERIFIED", QVERIFIED,
+ "QBOGUSSHELL", QBOGUSSHELL,
+ "QUNSAFEADDR", QUNSAFEADDR,
+ "QPINGONSUCCESS", QPINGONSUCCESS,
+ "QPINGONFAILURE", QPINGONFAILURE,
+ "QPINGONDELAY", QPINGONDELAY,
+ "QHASNOTIFY", QHASNOTIFY,
+ "QRELAYED", QRELAYED,
+ "QEXPANDED", QEXPANDED,
+ "QDELIVERED", QDELIVERED,
+ "QDELAYED", QDELAYED,
+ "QTHISPASS", QTHISPASS,
+ NULL
+};
+
+void
printaddr(a, follow)
register ADDRESS *a;
bool follow;
{
- bool first = TRUE;
register MAILER *m;
MAILER pseudomailer;
+ register struct qflags *qfp;
+ bool firstone;
+
+ if (a == NULL)
+ {
+ printf("[NULL]\n");
+ return;
+ }
while (a != NULL)
{
- first = FALSE;
printf("%x=", a);
(void) fflush(stdout);
@@ -1603,25 +1755,60 @@ printaddr(a, follow)
m->m_name = "NULL";
}
- printf("%s:\n\tmailer %d (%s), host `%s', user `%s', ruser `%s'\n",
- a->q_paddr, m->m_mno, m->m_name,
- a->q_host, a->q_user,
- a->q_ruser ? a->q_ruser : "<null>");
- printf("\tnext=%x, flags=%o, alias %x, uid %d, gid %d\n",
- a->q_next, a->q_flags, a->q_alias, a->q_uid, a->q_gid);
+ printf("%s:\n\tmailer %d (%s), host `%s'\n",
+ a->q_paddr == NULL ? "<null>" : a->q_paddr,
+ m->m_mno, m->m_name,
+ a->q_host == NULL ? "<null>" : a->q_host);
+ printf("\tuser `%s', ruser `%s'\n",
+ a->q_user,
+ a->q_ruser == NULL ? "<null>" : a->q_ruser);
+ printf("\tnext=%x, alias %x, uid %d, gid %d\n",
+ a->q_next, a->q_alias, a->q_uid, a->q_gid);
+ printf("\tflags=%lx<", a->q_flags);
+ firstone = TRUE;
+ for (qfp = AddressFlags; qfp->qf_name != NULL; qfp++)
+ {
+ if (!bitset(qfp->qf_bit, a->q_flags))
+ continue;
+ if (!firstone)
+ printf(",");
+ firstone = FALSE;
+ printf("%s", qfp->qf_name);
+ }
+ printf(">\n");
printf("\towner=%s, home=\"%s\", fullname=\"%s\"\n",
a->q_owner == NULL ? "(none)" : a->q_owner,
a->q_home == NULL ? "(none)" : a->q_home,
a->q_fullname == NULL ? "(none)" : a->q_fullname);
+ printf("\torcpt=\"%s\", statmta=%s, rstatus=%s\n",
+ a->q_orcpt == NULL ? "(none)" : a->q_orcpt,
+ a->q_statmta == NULL ? "(none)" : a->q_statmta,
+ a->q_rstatus == NULL ? "(none)" : a->q_rstatus);
if (!follow)
return;
a = a->q_next;
}
- if (first)
- printf("[NULL]\n");
}
+ /*
+** EMPTYADDR -- return TRUE if this address is empty (``<>'')
+**
+** Parameters:
+** a -- pointer to the address
+**
+** Returns:
+** TRUE -- if this address is "empty" (i.e., no one should
+** ever generate replies to it.
+** FALSE -- if it is a "regular" (read: replyable) address.
+*/
+bool
+emptyaddr(a)
+ register ADDRESS *a;
+{
+ return a->q_paddr == NULL || strcmp(a->q_paddr, "<>") == 0 ||
+ a->q_user == NULL || strcmp(a->q_user, "<>") == 0;
+}
/*
** REMOTENAME -- return the name relative to the current mailer
**
@@ -1657,8 +1844,8 @@ remotename(name, m, flags, pstat, e)
char *fancy;
char *oldg = macvalue('g', e);
int rwset;
- static char buf[MAXNAME];
- char lbuf[MAXNAME];
+ static char buf[MAXNAME + 1];
+ char lbuf[MAXNAME + 1];
char pvpbuf[PSBUFSIZE];
extern char *crackaddr();
@@ -1693,7 +1880,7 @@ remotename(name, m, flags, pstat, e)
** domain will be appended.
*/
- pvp = prescan(name, '\0', pvpbuf, sizeof pvpbuf, NULL);
+ pvp = prescan(name, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL);
if (pvp == NULL)
return (name);
if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)
@@ -1760,9 +1947,9 @@ remotename(name, m, flags, pstat, e)
/* need to make sure route-addrs have <angle brackets> */
if (bitset(RF_CANONICAL, flags) && lbuf[0] == '@')
- expand("<\201g>", buf, &buf[sizeof buf - 1], e);
+ expand("<\201g>", buf, sizeof buf, e);
else
- expand(fancy, buf, &buf[sizeof buf - 1], e);
+ expand(fancy, buf, sizeof buf, e);
define('g', oldg, e);
@@ -1777,14 +1964,18 @@ remotename(name, m, flags, pstat, e)
** a -- the address to map (but just the user name part).
** sendq -- the sendq in which to install any replacement
** addresses.
+** aliaslevel -- the alias nesting depth.
+** e -- the envelope.
**
** Returns:
** none.
*/
-maplocaluser(a, sendq, e)
+void
+maplocaluser(a, sendq, aliaslevel, e)
register ADDRESS *a;
ADDRESS **sendq;
+ int aliaslevel;
ENVELOPE *e;
{
register char **pvp;
@@ -1797,7 +1988,7 @@ maplocaluser(a, sendq, e)
printf("maplocaluser: ");
printaddr(a, FALSE);
}
- pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, &delimptr);
+ pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, &delimptr, NULL);
if (pvp == NULL)
return;
@@ -1818,8 +2009,8 @@ maplocaluser(a, sendq, e)
printaddr(a, FALSE);
}
a1->q_alias = a;
- allocaddr(a1, RF_COPYALL, NULL);
- (void) recipient(a1, sendq, e);
+ allocaddr(a1, RF_COPYALL, a->q_paddr);
+ (void) recipient(a1, sendq, aliaslevel, e);
}
/*
** DEQUOTE_INIT -- initialize dequote map
@@ -1841,6 +2032,7 @@ dequote_init(map, args)
{
register char *p = args;
+ map->map_mflags |= MF_KEEPQUOTES;
for (;;)
{
while (isascii(*p) && isspace(*p))
@@ -1852,6 +2044,10 @@ dequote_init(map, args)
case 'a':
map->map_app = ++p;
break;
+
+ case 's':
+ map->map_coldelim = *++p;
+ break;
}
while (*p != '\0' && !(isascii(*p) && isspace(*p)))
p++;
@@ -1888,19 +2084,13 @@ dequote_map(map, name, av, statp)
register char *p;
register char *q;
register char c;
- int anglecnt;
- int cmntcnt;
- int quotecnt;
- int spacecnt;
- bool quotemode;
- bool bslashmode;
-
- anglecnt = 0;
- cmntcnt = 0;
- quotecnt = 0;
- spacecnt = 0;
- quotemode = FALSE;
- bslashmode = FALSE;
+ int anglecnt = 0;
+ int cmntcnt = 0;
+ int quotecnt = 0;
+ int spacecnt = 0;
+ bool quotemode = FALSE;
+ bool bslashmode = FALSE;
+ char spacesub = map->map_coldelim;
for (p = q = name; (c = *p++) != '\0'; )
{
@@ -1911,6 +2101,9 @@ dequote_map(map, name, av, statp)
continue;
}
+ if (c == ' ' && spacesub != '\0')
+ c = spacesub;
+
switch (c)
{
case '\\':
diff --git a/usr.sbin/sendmail/src/readcf.c b/usr.sbin/sendmail/src/readcf.c
index 4a2a820..4811e6d 100644
--- a/usr.sbin/sendmail/src/readcf.c
+++ b/usr.sbin/sendmail/src/readcf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -33,14 +33,12 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)readcf.c 8.23.1.3 (Berkeley) 3/5/95";
+static char sccsid[] = "@(#)readcf.c 8.138 (Berkeley) 11/20/95";
#endif /* not lint */
# include "sendmail.h"
-# include <pwd.h>
# include <grp.h>
#if NAMED_BIND
-# include <arpa/nameser.h>
# include <resolv.h>
#endif
@@ -76,6 +74,7 @@ static char sccsid[] = "@(#)readcf.c 8.23.1.3 (Berkeley) 3/5/95";
** Kmapname mapclass arguments....
** Define keyed lookup of a given class.
** Arguments are class dependent.
+** Eenvar=value Set the environment value to the given value.
**
** Parameters:
** cfname -- control file name.
@@ -90,6 +89,7 @@ static char sccsid[] = "@(#)readcf.c 8.23.1.3 (Berkeley) 3/5/95";
** Builds several internal tables.
*/
+void
readcf(cfname, safe, e)
char *cfname;
bool safe;
@@ -104,14 +104,18 @@ readcf(cfname, safe, e)
int nfuzzy;
char *file;
bool optional;
+ int mid;
char buf[MAXLINE];
register char *p;
extern char **copyplist();
struct stat statb;
char exbuf[MAXLINE];
char pvpbuf[MAXLINE + MAXATOM];
- extern char *munchstring();
- extern void makemapentry();
+ static char *null_list[1] = { NULL };
+ extern char *munchstring __P((char *, char **));
+ extern void fileclass __P((int, char *, char *, bool, bool));
+ extern void toomany __P((int, int));
+ extern void translate_dollars __P((char *));
FileName = cfname;
LineNumber = 0;
@@ -137,7 +141,7 @@ readcf(cfname, safe, e)
if (OpMode != MD_TEST && bitset(S_IWGRP|S_IWOTH, statb.st_mode))
{
- if (OpMode == MD_DAEMON || OpMode == MD_FREEZE)
+ if (OpMode == MD_DAEMON || OpMode == MD_INITALIAS)
fprintf(stderr, "%s: WARNING: dangerous write permissions\n",
FileName);
#ifdef LOG
@@ -160,52 +164,8 @@ readcf(cfname, safe, e)
continue;
}
- /* map $ into \201 for macro expansion */
- for (p = bp; *p != '\0'; p++)
- {
- if (*p == '#' && p > bp && ConfigLevel >= 3)
- {
- /* this is an on-line comment */
- register char *e;
-
- switch (*--p & 0377)
- {
- case MACROEXPAND:
- /* it's from $# -- let it go through */
- p++;
- break;
-
- case '\\':
- /* it's backslash escaped */
- (void) strcpy(p, p + 1);
- break;
-
- default:
- /* delete preceeding white space */
- while (isascii(*p) && isspace(*p) && p > bp)
- p--;
- if ((e = strchr(++p, '\n')) != NULL)
- (void) strcpy(p, e);
- else
- p[0] = p[1] = '\0';
- break;
- }
- continue;
- }
-
- if (*p != '$')
- continue;
-
- if (p[1] == '$')
- {
- /* actual dollar sign.... */
- (void) strcpy(p, p + 1);
- continue;
- }
-
- /* convert to macro expansion character */
- *p = MACROEXPAND;
- }
+ /* do macro expansion mappings */
+ translate_dollars(bp);
/* interpret this line */
errno = 0;
@@ -240,9 +200,9 @@ readcf(cfname, safe, e)
/* expand and save the LHS */
*p = '\0';
- expand(&bp[1], exbuf, &exbuf[sizeof exbuf], e);
+ expand(&bp[1], exbuf, sizeof exbuf, e);
rwp->r_lhs = prescan(exbuf, '\t', pvpbuf,
- sizeof pvpbuf, NULL);
+ sizeof pvpbuf, NULL, NULL);
nfuzzy = 0;
if (rwp->r_lhs != NULL)
{
@@ -316,7 +276,10 @@ readcf(cfname, safe, e)
}
}
else
+ {
syserr("R line: null LHS");
+ rwp->r_lhs = null_list;
+ }
/* expand and save the RHS */
while (*++p == '\t')
@@ -325,9 +288,9 @@ readcf(cfname, safe, e)
while (*p != '\0' && *p != '\t')
p++;
*p = '\0';
- expand(q, exbuf, &exbuf[sizeof exbuf], e);
+ expand(q, exbuf, sizeof exbuf, e);
rwp->r_rhs = prescan(exbuf, '\t', pvpbuf,
- sizeof pvpbuf, NULL);
+ sizeof pvpbuf, NULL, NULL);
if (rwp->r_rhs != NULL)
{
register char **ap;
@@ -377,40 +340,51 @@ readcf(cfname, safe, e)
}
}
else
+ {
syserr("R line: null RHS");
+ rwp->r_rhs = null_list;
+ }
break;
case 'S': /* select rewriting set */
- for (p = &bp[1]; isascii(*p) && isspace(*p); p++)
- continue;
- if (!isascii(*p) || !isdigit(*p))
- {
- syserr("invalid argument to S line: \"%.20s\"",
- &bp[1]);
+ expand(&bp[1], exbuf, sizeof exbuf, e);
+ ruleset = strtorwset(exbuf, NULL, ST_ENTER);
+ if (ruleset < 0)
break;
- }
- ruleset = atoi(p);
- if (ruleset >= MAXRWSETS || ruleset < 0)
+ rwp = RewriteRules[ruleset];
+ if (rwp != NULL)
{
- syserr("bad ruleset %d (%d max)", ruleset, MAXRWSETS);
- ruleset = 0;
+ while (rwp->r_next != NULL)
+ rwp = rwp->r_next;
+ fprintf(stderr, "WARNING: Ruleset %s redefined\n",
+ &bp[1]);
}
- rwp = NULL;
break;
case 'D': /* macro definition */
- p = munchstring(&bp[2], NULL);
- define(bp[1], newstr(p), e);
+ mid = macid(&bp[1], &ep);
+ p = munchstring(ep, NULL);
+ define(mid, newstr(p), e);
break;
case 'H': /* required header line */
- (void) chompheader(&bp[1], TRUE, e);
+ (void) chompheader(&bp[1], TRUE, NULL, e);
break;
case 'C': /* word class */
- /* scan the list of words and set class for all */
- expand(&bp[2], exbuf, &exbuf[sizeof exbuf], e);
- for (p = exbuf; *p != '\0'; )
+ case 'T': /* trusted user (set class `t') */
+ if (bp[0] == 'C')
+ {
+ mid = macid(&bp[1], &ep);
+ expand(ep, exbuf, sizeof exbuf, e);
+ p = exbuf;
+ }
+ else
+ {
+ mid = 't';
+ p = &bp[1];
+ }
+ while (*p != '\0')
{
register char *wd;
char delim;
@@ -423,13 +397,14 @@ readcf(cfname, safe, e)
delim = *p;
*p = '\0';
if (wd[0] != '\0')
- setclass(bp[1], wd);
+ setclass(mid, wd);
*p = delim;
}
break;
case 'F': /* word class from file */
- for (p = &bp[2]; isascii(*p) && isspace(*p); )
+ mid = macid(&bp[1], &ep);
+ for (p = ep; isascii(*p) && isspace(*p); )
p++;
if (p[0] == '-' && p[1] == 'o')
{
@@ -437,22 +412,27 @@ readcf(cfname, safe, e)
while (*p != '\0' && !(isascii(*p) && isspace(*p)))
p++;
while (isascii(*p) && isspace(*p))
- *p++;
+ p++;
}
else
optional = FALSE;
file = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
- p++;
- if (*p == '\0')
+ if (*file == '|')
p = "%s";
else
{
- *p = '\0';
- while (isascii(*++p) && isspace(*p))
- continue;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ if (*p == '\0')
+ p = "%s";
+ else
+ {
+ *p = '\0';
+ while (isascii(*++p) && isspace(*p))
+ continue;
+ }
}
- fileclass(bp[1], file, p, safe, optional);
+ fileclass(mid, file, p, safe, optional);
break;
#ifdef XLA
@@ -475,7 +455,7 @@ readcf(cfname, safe, e)
toomany('P', MAXPRIORITIES);
break;
}
- for (p = &bp[1]; *p != '\0' && *p != '=' && *p != '\t'; p++)
+ for (p = &bp[1]; *p != '\0' && *p != '='; p++)
continue;
if (*p == '\0')
goto badline;
@@ -485,10 +465,6 @@ readcf(cfname, safe, e)
NumPriorities++;
break;
- case 'T': /* trusted user(s) */
- /* this option is obsolete, but will be ignored */
- break;
-
case 'V': /* configuration syntax version */
for (p = &bp[1]; isascii(*p) && isspace(*p); p++)
continue;
@@ -499,13 +475,28 @@ readcf(cfname, safe, e)
break;
}
ConfigLevel = strtol(p, &ep, 10);
+
+ /*
+ ** Do heuristic tweaking for back compatibility.
+ */
+
if (ConfigLevel >= 5)
{
/* level 5 configs have short name in $w */
p = macvalue('w', e);
if (p != NULL && (p = strchr(p, '.')) != NULL)
*p = '\0';
+ define('w', macvalue('w', e), e);
}
+ if (ConfigLevel >= 6)
+ {
+ ColonOkInAddr = FALSE;
+ }
+
+ /*
+ ** Look for vendor code.
+ */
+
if (*ep++ == '/')
{
/* extract vendor code */
@@ -520,7 +511,15 @@ readcf(cfname, safe, e)
break;
case 'K':
- makemapentry(&bp[1]);
+ expand(&bp[1], exbuf, sizeof exbuf, e);
+ (void) makemapentry(exbuf);
+ break;
+
+ case 'E':
+ p = strchr(bp, '=');
+ if (p != NULL)
+ *p++ = '\0';
+ setuserenv(&bp[1], p);
break;
default:
@@ -532,24 +531,133 @@ readcf(cfname, safe, e)
}
if (ferror(cf))
{
- syserr("I/O read error", cfname);
+ syserr("I/O read error");
exit(EX_OSFILE);
}
fclose(cf);
FileName = NULL;
- if (stab("host", ST_MAP, ST_FIND) == NULL)
+ /* initialize host maps from local service tables */
+ inithostmaps();
+
+ /* determine if we need to do special name-server frotz */
{
- /* user didn't initialize: set up host map */
- strcpy(buf, "host host");
-#if NAMED_BIND
- if (ConfigLevel >= 2)
- strcat(buf, " -a.");
+ int nmaps;
+ char *maptype[MAXMAPSTACK];
+ short mapreturn[MAXMAPACTIONS];
+
+ nmaps = switch_map_find("hosts", maptype, mapreturn);
+ UseNameServer = FALSE;
+ if (nmaps > 0 && nmaps <= MAXMAPSTACK)
+ {
+ register int mapno;
+
+ for (mapno = 0; mapno < nmaps && !UseNameServer; mapno++)
+ {
+ if (strcmp(maptype[mapno], "dns") == 0)
+ UseNameServer = TRUE;
+ }
+ }
+
+#ifdef HESIOD
+ nmaps = switch_map_find("passwd", maptype, mapreturn);
+ UseHesiod = FALSE;
+ if (nmaps > 0 && nmaps <= MAXMAPSTACK)
+ {
+ register int mapno;
+
+ for (mapno = 0; mapno < nmaps && !UseHesiod; mapno++)
+ {
+ if (strcmp(maptype[mapno], "hesiod") == 0)
+ UseHesiod = TRUE;
+ }
+ }
#endif
- makemapentry(buf);
}
}
/*
+** TRANSLATE_DOLLARS -- convert $x into internal form
+**
+** Actually does all appropriate pre-processing of a config line
+** to turn it into internal form.
+**
+** Parameters:
+** bp -- the buffer to translate.
+**
+** Returns:
+** None. The buffer is translated in place. Since the
+** translations always make the buffer shorter, this is
+** safe without a size parameter.
+*/
+
+void
+translate_dollars(bp)
+ char *bp;
+{
+ register char *p;
+ auto char *ep;
+
+ for (p = bp; *p != '\0'; p++)
+ {
+ if (*p == '#' && p > bp && ConfigLevel >= 3)
+ {
+ /* this is an on-line comment */
+ register char *e;
+
+ switch (*--p & 0377)
+ {
+ case MACROEXPAND:
+ /* it's from $# -- let it go through */
+ p++;
+ break;
+
+ case '\\':
+ /* it's backslash escaped */
+ (void) strcpy(p, p + 1);
+ break;
+
+ default:
+ /* delete preceeding white space */
+ while (isascii(*p) && isspace(*p) &&
+ *p != '\n' && p > bp)
+ p--;
+ if ((e = strchr(++p, '\n')) != NULL)
+ (void) strcpy(p, e);
+ else
+ *p-- = '\0';
+ break;
+ }
+ continue;
+ }
+
+ if (*p != '$' || p[1] == '\0')
+ continue;
+
+ if (p[1] == '$')
+ {
+ /* actual dollar sign.... */
+ (void) strcpy(p, p + 1);
+ continue;
+ }
+
+ /* convert to macro expansion character */
+ *p++ = MACROEXPAND;
+
+ /* special handling for $=, $~, $&, and $? */
+ if (*p == '=' || *p == '~' || *p == '&' || *p == '?')
+ p++;
+
+ /* convert macro name to code */
+ *p = macid(p, &ep);
+ if (ep != p)
+ strcpy(p + 1, ep);
+ }
+
+ /* strip trailing white space from the line */
+ while (--p > bp && isascii(*p) && isspace(*p))
+ *p = '\0';
+}
+ /*
** TOOMANY -- signal too many of some option
**
** Parameters:
@@ -563,8 +671,9 @@ readcf(cfname, safe, e)
** gives a syserr.
*/
+void
toomany(id, maxcnt)
- char id;
+ int id;
int maxcnt;
{
syserr("too many %c lines, %d max", id, maxcnt);
@@ -589,6 +698,7 @@ toomany(id, maxcnt)
** the named class.
*/
+void
fileclass(class, filename, fmt, safe, optional)
int class;
char *filename;
@@ -597,7 +707,9 @@ fileclass(class, filename, fmt, safe, optional)
bool optional;
{
FILE *f;
- struct stat stbuf;
+ int sff;
+ int pid;
+ register char *p;
char buf[MAXLINE];
if (tTd(37, 2))
@@ -605,42 +717,49 @@ fileclass(class, filename, fmt, safe, optional)
if (filename[0] == '|')
{
- syserr("fileclass: pipes (F%c%s) not supported due to security problems",
- class, filename);
- return;
- }
- if (stat(filename, &stbuf) < 0)
- {
- if (tTd(37, 2))
- printf(" cannot stat (%s)\n", errstring(errno));
- if (!optional)
- syserr("fileclass: cannot stat %s", filename);
- return;
- }
- if (!S_ISREG(stbuf.st_mode))
- {
- syserr("fileclass: %s not a regular file", filename);
- return;
+ auto int fd;
+ int i;
+ char *argv[MAXPV + 1];
+
+ i = 0;
+ for (p = strtok(&filename[1], " \t"); p != NULL; p = strtok(NULL, " \t"))
+ {
+ if (i >= MAXPV)
+ break;
+ argv[i++] = p;
+ }
+ argv[i] = NULL;
+ pid = prog_open(argv, &fd, CurEnv);
+ if (pid < 0)
+ f = NULL;
+ else
+ f = fdopen(fd, "r");
}
- if (!safe && access(filename, R_OK) < 0)
+ else
{
- syserr("fileclass: access denied on %s", filename);
- return;
+ pid = -1;
+ sff = SFF_REGONLY;
+ if (safe)
+ sff |= SFF_OPENASROOT;
+ f = safefopen(filename, O_RDONLY, 0, sff);
}
- f = fopen(filename, "r");
if (f == NULL)
{
- syserr("fileclass: cannot open %s", filename);
+ if (!optional)
+ syserr("fileclass: cannot open %s", filename);
return;
}
while (fgets(buf, sizeof buf, f) != NULL)
{
- register STAB *s;
register char *p;
-# ifdef SCANF
+# if SCANF
char wordbuf[MAXNAME+1];
+# endif
+ if (buf[0] == '#')
+ continue;
+# if SCANF
if (sscanf(buf, fmt, wordbuf) != 1)
continue;
p = wordbuf;
@@ -675,6 +794,8 @@ fileclass(class, filename, fmt, safe, optional)
}
(void) fclose(f);
+ if (pid > 0)
+ (void) waitfor(pid);
}
/*
** MAKEMAILER -- define a new mailer.
@@ -682,12 +803,19 @@ fileclass(class, filename, fmt, safe, optional)
** Parameters:
** line -- description of mailer. This is in labeled
** fields. The fields are:
-** P -- the path to the mailer
-** F -- the flags associated with the mailer
** A -- the argv for this mailer
-** S -- the sender rewriting set
-** R -- the recipient rewriting set
+** C -- the character set for MIME conversions
+** D -- the directory to run in
** E -- the eol string
+** F -- the flags associated with the mailer
+** L -- the maximum line length
+** M -- the maximum message size
+** N -- the niceness at which to run
+** P -- the path to the mailer
+** R -- the recipient rewriting set
+** S -- the sender rewriting set
+** T -- the mailer type (for DSNs)
+** U -- the uid to run as
** The first word is the canonical name of the mailer.
**
** Returns:
@@ -697,6 +825,7 @@ fileclass(class, filename, fmt, safe, optional)
** enters the mailer into the mailer table.
*/
+void
makemailer(line)
char *line;
{
@@ -709,18 +838,20 @@ makemailer(line)
extern int NextMailer;
extern char **makeargv();
extern char *munchstring();
- extern long atol();
/* allocate a mailer and set up defaults */
m = (struct mailer *) xalloc(sizeof *m);
bzero((char *) m, sizeof *m);
m->m_eol = "\n";
+ m->m_uid = m->m_gid = 0;
/* collect the mailer name */
for (p = line; *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p)); p++)
continue;
if (*p != '\0')
*p++ = '\0';
+ if (line[0] == '\0')
+ syserr("name required for mailer");
m->m_name = newstr(line);
/* now scan through and assign info from the fields */
@@ -750,6 +881,8 @@ makemailer(line)
switch (fcode)
{
case 'P': /* pathname */
+ if (*p == '\0')
+ syserr("mailer %s: empty path name", m->m_name);
m->m_mailer = newstr(p);
break;
@@ -761,12 +894,9 @@ makemailer(line)
case 'S': /* sender rewriting ruleset */
case 'R': /* recipient rewriting ruleset */
- i = strtol(p, &endp, 10);
- if (i < 0 || i >= MAXRWSETS)
- {
- syserr("invalid rewrite set, %d max", MAXRWSETS);
+ i = strtorwset(p, &endp, ST_ENTER);
+ if (i < 0)
return;
- }
if (fcode == 'S')
m->m_sh_rwset = m->m_se_rwset = i;
else
@@ -775,13 +905,9 @@ makemailer(line)
p = endp;
if (*p++ == '/')
{
- i = strtol(p, NULL, 10);
- if (i < 0 || i >= MAXRWSETS)
- {
- syserr("invalid rewrite set, %d max",
- MAXRWSETS);
+ i = strtorwset(p, NULL, ST_ENTER);
+ if (i < 0)
return;
- }
if (fcode == 'S')
m->m_sh_rwset = i;
else
@@ -790,10 +916,16 @@ makemailer(line)
break;
case 'E': /* end of line string */
+ if (*p == '\0')
+ syserr("mailer %s: null end-of-line string",
+ m->m_name);
m->m_eol = newstr(p);
break;
case 'A': /* argument vector */
+ if (*p == '\0')
+ syserr("mailer %s: null argument vector",
+ m->m_name);
m->m_argv = makeargv(p);
break;
@@ -805,23 +937,118 @@ makemailer(line)
m->m_linelimit = atoi(p);
break;
+ case 'N': /* run niceness */
+ m->m_nice = atoi(p);
+ break;
+
case 'D': /* working directory */
+ if (*p == '\0')
+ syserr("mailer %s: null working directory",
+ m->m_name);
m->m_execdir = newstr(p);
break;
+
+ case 'C': /* default charset */
+ if (*p == '\0')
+ syserr("mailer %s: null charset", m->m_name);
+ m->m_defcharset = newstr(p);
+ break;
+
+ case 'T': /* MTA-Name/Address/Diagnostic types */
+ /* extract MTA name type; default to "dns" */
+ m->m_mtatype = newstr(p);
+ p = strchr(m->m_mtatype, '/');
+ if (p != NULL)
+ {
+ *p++ = '\0';
+ if (*p == '\0')
+ p = NULL;
+ }
+ if (*m->m_mtatype == '\0')
+ m->m_mtatype = "dns";
+
+ /* extract address type; default to "rfc822" */
+ m->m_addrtype = p;
+ if (p != NULL)
+ p = strchr(p, '/');
+ if (p != NULL)
+ {
+ *p++ = '\0';
+ if (*p == '\0')
+ p = NULL;
+ }
+ if (m->m_addrtype == NULL || *m->m_addrtype == '\0')
+ m->m_addrtype = "rfc822";
+
+ /* extract diagnostic type; default to "smtp" */
+ m->m_diagtype = p;
+ if (m->m_diagtype == NULL || *m->m_diagtype == '\0')
+ m->m_diagtype = "smtp";
+ break;
+
+ case 'U': /* user id */
+ if (isascii(*p) && !isdigit(*p))
+ {
+ char *q = p;
+ struct passwd *pw;
+
+ while (*p != '\0' && isascii(*p) &&
+ (isalnum(*p) || strchr("-_", *p) != NULL))
+ p++;
+ while (isascii(*p) && isspace(*p))
+ *p++ = '\0';
+ if (*p != '\0')
+ *p++ = '\0';
+ if (*q == '\0')
+ syserr("mailer %s: null user name",
+ m->m_name);
+ pw = sm_getpwnam(q);
+ if (pw == NULL)
+ syserr("readcf: mailer U= flag: unknown user %s", q);
+ else
+ {
+ m->m_uid = pw->pw_uid;
+ m->m_gid = pw->pw_gid;
+ }
+ }
+ else
+ {
+ auto char *q;
+
+ m->m_uid = strtol(p, &q, 0);
+ p = q;
+ }
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (*p == '\0')
+ break;
+ if (isascii(*p) && !isdigit(*p))
+ {
+ char *q = p;
+ struct group *gr;
+
+ while (isascii(*p) && isalnum(*p))
+ p++;
+ *p++ = '\0';
+ if (*q == '\0')
+ syserr("mailer %s: null group name",
+ m->m_name);
+ gr = getgrnam(q);
+ if (gr == NULL)
+ syserr("readcf: mailer U= flag: unknown group %s", q);
+ else
+ m->m_gid = gr->gr_gid;
+ }
+ else
+ {
+ m->m_gid = strtol(p, NULL, 0);
+ }
+ break;
}
p = delimptr;
}
- /* do some heuristic cleanup for back compatibility */
- if (bitnset(M_LIMITS, m->m_flags))
- {
- if (m->m_linelimit == 0)
- m->m_linelimit = SMTPLINELIM;
- if (ConfigLevel < 2)
- setbitn(M_7BITS, m->m_flags);
- }
-
/* do some rationality checking */
if (m->m_argv == NULL)
{
@@ -840,6 +1067,27 @@ makemailer(line)
return;
}
+ /* do some heuristic cleanup for back compatibility */
+ if (bitnset(M_LIMITS, m->m_flags))
+ {
+ if (m->m_linelimit == 0)
+ m->m_linelimit = SMTPLINELIM;
+ if (ConfigLevel < 2)
+ setbitn(M_7BITS, m->m_flags);
+ }
+
+ if (strcmp(m->m_mailer, "[IPC]") == 0 ||
+ strcmp(m->m_mailer, "[TCP]") == 0)
+ {
+ if (m->m_mtatype == NULL)
+ m->m_mtatype = "dns";
+ if (m->m_addrtype == NULL)
+ m->m_addrtype = "rfc822";
+ if (m->m_diagtype == NULL)
+ m->m_diagtype = "smtp";
+ }
+
+ /* enter the mailer into the symbol table */
s = stab(m->m_name, ST_MAILER, ST_ENTER);
if (s->s_mailer != NULL)
{
@@ -875,7 +1123,7 @@ munchstring(p, delimptr)
bool quotemode = FALSE;
static char buf[MAXLINE];
- for (q = buf; *p != '\0'; p++)
+ for (q = buf; *p != '\0' && q < &buf[sizeof buf - 1]; p++)
{
if (backslash)
{
@@ -973,6 +1221,7 @@ makeargv(p)
** prints rewrite rules.
*/
+void
printrules()
{
register struct rewrite *rwp;
@@ -993,7 +1242,52 @@ printrules()
}
}
}
+ /*
+** PRINTMAILER -- print mailer structure (for debugging)
+**
+** Parameters:
+** m -- the mailer to print
+**
+** Returns:
+** none.
+*/
+
+void
+printmailer(m)
+ register MAILER *m;
+{
+ int j;
+
+ printf("mailer %d (%s): P=%s S=%d/%d R=%d/%d M=%ld U=%d:%d F=",
+ m->m_mno, m->m_name,
+ m->m_mailer, m->m_se_rwset, m->m_sh_rwset,
+ m->m_re_rwset, m->m_rh_rwset, m->m_maxsize,
+ m->m_uid, m->m_gid);
+ for (j = '\0'; j <= '\177'; j++)
+ if (bitnset(j, m->m_flags))
+ (void) putchar(j);
+ printf(" L=%d E=", m->m_linelimit);
+ xputs(m->m_eol);
+ if (m->m_defcharset != NULL)
+ printf(" C=%s", m->m_defcharset);
+ printf(" T=%s/%s/%s",
+ m->m_mtatype == NULL ? "<undefined>" : m->m_mtatype,
+ m->m_addrtype == NULL ? "<undefined>" : m->m_addrtype,
+ m->m_diagtype == NULL ? "<undefined>" : m->m_diagtype);
+ if (m->m_argv != NULL)
+ {
+ char **a = m->m_argv;
+ printf(" A=");
+ while (*a != NULL)
+ {
+ if (a != m->m_argv)
+ printf(" ");
+ xputs(*a++);
+ }
+ }
+ printf("\n");
+}
/*
** SETOPTION -- set global processing option
**
@@ -1015,6 +1309,7 @@ printrules()
*/
static BITMAP StickyOpt; /* set if option is stuck */
+extern void settimeout __P((char *, char *));
#if NAMED_BIND
@@ -1040,23 +1335,222 @@ struct resolverflags
#endif
+struct optioninfo
+{
+ char *o_name; /* long name of option */
+ u_char o_code; /* short name of option */
+ bool o_safe; /* safe for random people to use */
+} OptionTab[] =
+{
+ "SevenBitInput", '7', TRUE,
+#if MIME8TO7
+ "EightBitMode", '8', TRUE,
+#endif
+ "AliasFile", 'A', FALSE,
+ "AliasWait", 'a', FALSE,
+ "BlankSub", 'B', FALSE,
+ "MinFreeBlocks", 'b', TRUE,
+ "CheckpointInterval", 'C', TRUE,
+ "HoldExpensive", 'c', FALSE,
+ "AutoRebuildAliases", 'D', FALSE,
+ "DeliveryMode", 'd', TRUE,
+ "ErrorHeader", 'E', FALSE,
+ "ErrorMode", 'e', TRUE,
+ "TempFileMode", 'F', FALSE,
+ "SaveFromLine", 'f', FALSE,
+ "MatchGECOS", 'G', FALSE,
+ "HelpFile", 'H', FALSE,
+ "MaxHopCount", 'h', FALSE,
+ "ResolverOptions", 'I', FALSE,
+ "IgnoreDots", 'i', TRUE,
+ "ForwardPath", 'J', FALSE,
+ "SendMimeErrors", 'j', TRUE,
+ "ConnectionCacheSize", 'k', FALSE,
+ "ConnectionCacheTimeout", 'K', FALSE,
+ "UseErrorsTo", 'l', FALSE,
+ "LogLevel", 'L', FALSE,
+ "MeToo", 'm', TRUE,
+ "CheckAliases", 'n', FALSE,
+ "OldStyleHeaders", 'o', TRUE,
+ "DaemonPortOptions", 'O', FALSE,
+ "PrivacyOptions", 'p', TRUE,
+ "PostmasterCopy", 'P', FALSE,
+ "QueueFactor", 'q', FALSE,
+ "QueueDirectory", 'Q', FALSE,
+ "DontPruneRoutes", 'R', FALSE,
+ "Timeout", 'r', TRUE,
+ "StatusFile", 'S', FALSE,
+ "SuperSafe", 's', TRUE,
+ "QueueTimeout", 'T', FALSE,
+ "TimeZoneSpec", 't', FALSE,
+ "UserDatabaseSpec", 'U', FALSE,
+ "DefaultUser", 'u', FALSE,
+ "FallbackMXhost", 'V', FALSE,
+ "Verbose", 'v', TRUE,
+ "TryNullMXList", 'w', TRUE,
+ "QueueLA", 'x', FALSE,
+ "RefuseLA", 'X', FALSE,
+ "RecipientFactor", 'y', FALSE,
+ "ForkEachJob", 'Y', FALSE,
+ "ClassFactor", 'z', FALSE,
+ "RetryFactor", 'Z', FALSE,
+#define O_QUEUESORTORD 0x81
+ "QueueSortOrder", O_QUEUESORTORD, TRUE,
+#define O_HOSTSFILE 0x82
+ "HostsFile", O_HOSTSFILE, FALSE,
+#define O_MQA 0x83
+ "MinQueueAge", O_MQA, TRUE,
+#define O_MHSA 0x84
+/*
+ "MaxHostStatAge", O_MHSA, TRUE,
+*/
+#define O_DEFCHARSET 0x85
+ "DefaultCharSet", O_DEFCHARSET, TRUE,
+#define O_SSFILE 0x86
+ "ServiceSwitchFile", O_SSFILE, FALSE,
+#define O_DIALDELAY 0x87
+ "DialDelay", O_DIALDELAY, TRUE,
+#define O_NORCPTACTION 0x88
+ "NoRecipientAction", O_NORCPTACTION, TRUE,
+#define O_SAFEFILEENV 0x89
+ "SafeFileEnvironment", O_SAFEFILEENV, FALSE,
+#define O_MAXMSGSIZE 0x8a
+ "MaxMessageSize", O_MAXMSGSIZE, FALSE,
+#define O_COLONOKINADDR 0x8b
+ "ColonOkInAddr", O_COLONOKINADDR, TRUE,
+#define O_MAXQUEUERUN 0x8c
+ "MaxQueueRunSize", O_MAXQUEUERUN, TRUE,
+#define O_MAXCHILDREN 0x8d
+/*
+ "MaxDaemonChildren", O_MAXCHILDREN, FALSE,
+*/
+#define O_KEEPCNAMES 0x8e
+ "DontExpandCnames", O_KEEPCNAMES, FALSE,
+#define O_MUSTQUOTE 0x8f
+/*
+ "MustQuoteChars", O_MUSTQUOTE, FALSE,
+*/
+#define O_SMTPGREETING 0x90
+ "SmtpGreetingMessage", O_SMTPGREETING, FALSE,
+#define O_UNIXFROM 0x91
+ "UnixFromLine", O_UNIXFROM, FALSE,
+#define O_OPCHARS 0x92
+ "OperatorChars", O_OPCHARS, FALSE,
+#define O_DONTINITGRPS 0x93
+ "DontInitGroups", O_DONTINITGRPS, TRUE,
+#define O_SLFH 0x94
+#ifdef LOTUS_NOTES_HACK
+ "SingleLineFromHeader", O_SLFH, TRUE,
+#endif
+
+ NULL, '\0', FALSE,
+};
+
+
+
+void
setoption(opt, val, safe, sticky, e)
- char opt;
+ int opt;
char *val;
bool safe;
bool sticky;
register ENVELOPE *e;
{
register char *p;
+ register struct optioninfo *o;
+ char *subopt;
+ char buf[50];
extern bool atobool();
extern time_t convtime();
extern int QueueLA;
extern int RefuseLA;
extern bool Warn_Q_option;
- extern bool trusteduser();
+
+ errno = 0;
+ if (opt == ' ')
+ {
+ /* full word options */
+ struct optioninfo *sel;
+
+ p = strchr(val, '=');
+ if (p == NULL)
+ p = &val[strlen(val)];
+ while (*--p == ' ')
+ continue;
+ while (*++p == ' ')
+ *p = '\0';
+ if (p == val)
+ {
+ syserr("readcf: null option name");
+ return;
+ }
+ if (*p == '=')
+ *p++ = '\0';
+ while (*p == ' ')
+ p++;
+ subopt = strchr(val, '.');
+ if (subopt != NULL)
+ *subopt++ = '\0';
+ sel = NULL;
+ for (o = OptionTab; o->o_name != NULL; o++)
+ {
+ if (strncasecmp(o->o_name, val, strlen(val)) != 0)
+ continue;
+ if (strlen(o->o_name) == strlen(val))
+ {
+ /* completely specified -- this must be it */
+ sel = NULL;
+ break;
+ }
+ if (sel != NULL)
+ break;
+ sel = o;
+ }
+ if (sel != NULL && o->o_name == NULL)
+ o = sel;
+ else if (o->o_name == NULL)
+ {
+ syserr("readcf: unknown option name %s", val);
+ return;
+ }
+ else if (sel != NULL)
+ {
+ syserr("readcf: ambiguous option name %s (matches %s and %s)",
+ val, sel->o_name, o->o_name);
+ return;
+ }
+ if (strlen(val) != strlen(o->o_name))
+ {
+ bool oldVerbose = Verbose;
+
+ Verbose = TRUE;
+ message("Option %s used as abbreviation for %s",
+ val, o->o_name);
+ Verbose = oldVerbose;
+ }
+ opt = o->o_code;
+ val = p;
+ }
+ else
+ {
+ for (o = OptionTab; o->o_name != NULL; o++)
+ {
+ if (o->o_code == opt)
+ break;
+ }
+ subopt = NULL;
+ }
if (tTd(37, 1))
- printf("setoption %c=%s", opt, val);
+ {
+ printf(isascii(opt) && isprint(opt) ?
+ "setoption %s (%c).%s=" :
+ "setoption %s (0x%x).%s=",
+ o->o_name == NULL ? "<unknown>" : o->o_name,
+ opt,
+ subopt == NULL ? "" : subopt);
+ xputs(val);
+ }
/*
** See if this option is preset for us.
@@ -1075,7 +1569,7 @@ setoption(opt, val, safe, sticky, e)
if (!safe && RealUid == 0)
safe = TRUE;
- if (!safe && strchr("bCdeijLmoprsvw7", opt) == NULL)
+ if (!safe && !o->o_safe)
{
if (opt != 'M' || (val[0] != 'r' && val[0] != 's'))
{
@@ -1085,6 +1579,7 @@ setoption(opt, val, safe, sticky, e)
{
if (tTd(37, 1))
printf("(Resetting uid)");
+ endpwent();
(void) setgid(RealGid);
(void) setuid(RealUid);
}
@@ -1093,12 +1588,53 @@ setoption(opt, val, safe, sticky, e)
if (tTd(37, 1))
printf("\n");
- switch (opt)
+ switch (opt & 0xff)
{
case '7': /* force seven-bit input */
- SevenBit = atobool(val);
+ SevenBitInput = atobool(val);
break;
+#if MIME8TO7
+ case '8': /* handling of 8-bit input */
+ switch (*val)
+ {
+ case 'm': /* convert 8-bit, convert MIME */
+ MimeMode = MM_CVTMIME|MM_MIME8BIT;
+ break;
+
+ case 'p': /* pass 8 bit, convert MIME */
+ MimeMode = MM_CVTMIME|MM_PASS8BIT;
+ break;
+
+ case 's': /* strict adherence */
+ MimeMode = MM_CVTMIME;
+ break;
+
+#if 0
+ case 'r': /* reject 8-bit, don't convert MIME */
+ MimeMode = 0;
+ break;
+
+ case 'j': /* "just send 8" */
+ MimeMode = MM_PASS8BIT;
+ break;
+
+ case 'a': /* encode 8 bit if available */
+ MimeMode = MM_MIME8BIT|MM_PASS8BIT|MM_CVTMIME;
+ break;
+
+ case 'c': /* convert 8 bit to MIME, never 7 bit */
+ MimeMode = MM_MIME8BIT;
+ break;
+#endif
+
+ default:
+ syserr("Unknown 8-bit mode %c", *val);
+ exit(EX_USAGE);
+ }
+ break;
+#endif
+
case 'A': /* set default alias file */
if (val[0] == '\0')
setalias("aliases");
@@ -1145,8 +1681,9 @@ setoption(opt, val, safe, sticky, e)
break;
case SM_QUEUE: /* queue only */
+ case SM_DEFER: /* queue only and defer map lookups */
#ifndef QUEUE
- syserr("need QUEUE to set -odqueue");
+ syserr("need QUEUE to set -odqueue or -oddefer");
#endif /* QUEUE */
/* fall through..... */
@@ -1177,9 +1714,6 @@ setoption(opt, val, safe, sticky, e)
case EM_MAIL: /* mail back */
case EM_BERKNET: /* do berknet error processing */
case EM_WRITE: /* write back (or mail) */
- HoldErrs = TRUE;
- /* fall through... */
-
case EM_PRINT: /* print errors normally (default) */
e->e_errormode = *val;
break;
@@ -1199,6 +1733,7 @@ setoption(opt, val, safe, sticky, e)
break;
case 'g': /* default gid */
+ g_opt:
if (isascii(*val) && isdigit(*val))
DefGid = atoi(val);
else
@@ -1208,7 +1743,8 @@ setoption(opt, val, safe, sticky, e)
DefGid = -1;
gr = getgrnam(val);
if (gr == NULL)
- syserr("readcf: option g: unknown group %s", val);
+ syserr("readcf: option %c: unknown group %s",
+ opt, val);
else
DefGid = gr->gr_gid;
}
@@ -1227,7 +1763,6 @@ setoption(opt, val, safe, sticky, e)
case 'I': /* use internet domain name server */
#if NAMED_BIND
- UseNameServer = TRUE;
for (p = val; *p != 0; )
{
bool clearmode;
@@ -1249,6 +1784,11 @@ setoption(opt, val, safe, sticky, e)
p++;
if (*p != '\0')
*p++ = '\0';
+ if (strcasecmp(q, "HasWildcardMX") == 0)
+ {
+ HasWildcardMX = !clearmode;
+ continue;
+ }
for (rfp = ResolverFlags; rfp->rf_name != NULL; rfp++)
{
if (strcasecmp(q, rfp->rf_name) == 0)
@@ -1262,7 +1802,8 @@ setoption(opt, val, safe, sticky, e)
_res.options |= rfp->rf_bits;
}
if (tTd(8, 2))
- printf("_res.options = %x\n", _res.options);
+ printf("_res.options = %x, HasWildcardMX = %d\n",
+ _res.options, HasWildcardMX);
#else
usrerr("name server (I option) specified but BIND not compiled in");
#endif
@@ -1318,7 +1859,11 @@ setoption(opt, val, safe, sticky, e)
/* 'N' available -- was "net name" */
case 'O': /* daemon options */
+#ifdef DAEMON
setdaemonoptions(val);
+#else
+ syserr("DaemonPortOptions (O option) set but DAEMON not compiled in");
+#endif
break;
case 'o': /* assume old style headers */
@@ -1379,7 +1924,10 @@ setoption(opt, val, safe, sticky, e)
break;
case 'r': /* read timeout */
- settimeouts(val);
+ if (subopt == NULL)
+ inittimeouts(val);
+ else
+ settimeout(subopt, val);
break;
case 'S': /* status file */
@@ -1398,9 +1946,9 @@ setoption(opt, val, safe, sticky, e)
if (p != NULL)
{
*p++ = '\0';
- TimeOuts.to_q_warning = convtime(p, 'd');
+ settimeout("queuewarn", p);
}
- TimeOuts.to_q_return = convtime(val, 'h');
+ settimeout("queuereturn", val);
break;
case 't': /* time zone name */
@@ -1412,6 +1960,14 @@ setoption(opt, val, safe, sticky, e)
break;
case 'u': /* set default uid */
+ for (p = val; *p != '\0'; p++)
+ {
+ if (*p == '.' || *p == '/' || *p == ':')
+ {
+ *p++ = '\0';
+ break;
+ }
+ }
if (isascii(*val) && isdigit(*val))
DefUid = atoi(val);
else
@@ -1419,14 +1975,22 @@ setoption(opt, val, safe, sticky, e)
register struct passwd *pw;
DefUid = -1;
- pw = getpwnam(val);
+ pw = sm_getpwnam(val);
if (pw == NULL)
syserr("readcf: option u: unknown user %s", val);
else
+ {
DefUid = pw->pw_uid;
+ DefGid = pw->pw_gid;
+ }
}
setdefuser();
- break;
+
+ /* handle the group if it is there */
+ if (*p == '\0')
+ break;
+ val = p;
+ goto g_opt;
case 'V': /* fallback MX host */
FallBackMX = newstr(val);
@@ -1466,19 +2030,133 @@ setoption(opt, val, safe, sticky, e)
WkTimeFact = atoi(val);
break;
+ case O_QUEUESORTORD: /* queue sorting order */
+ switch (*val)
+ {
+ case 'h': /* Host first */
+ case 'H':
+ QueueSortOrder = QS_BYHOST;
+ break;
+
+ case 'p': /* Priority order */
+ case 'P':
+ QueueSortOrder = QS_BYPRIORITY;
+ break;
+
+ default:
+ syserr("Invalid queue sort order \"%s\"", val);
+ }
+ break;
+
+ case O_HOSTSFILE: /* pathname of /etc/hosts file */
+ HostsFile = newstr(val);
+ break;
+
+ case O_MQA: /* minimum queue age between deliveries */
+ MinQueueAge = convtime(val, 'm');
+ break;
+
+ case O_MHSA: /* maximum age of cached host status */
+ MaxHostStatAge = convtime(val, 'm');
+ break;
+
+ case O_DEFCHARSET: /* default character set for mimefying */
+ DefaultCharSet = newstr(denlstring(val, TRUE, TRUE));
+ break;
+
+ case O_SSFILE: /* service switch file */
+ ServiceSwitchFile = newstr(val);
+ break;
+
+ case O_DIALDELAY: /* delay for dial-on-demand operation */
+ DialDelay = convtime(val, 's');
+ break;
+
+ case O_NORCPTACTION: /* what to do if no recipient */
+ if (strcasecmp(val, "none") == 0)
+ NoRecipientAction = NRA_NO_ACTION;
+ else if (strcasecmp(val, "add-to") == 0)
+ NoRecipientAction = NRA_ADD_TO;
+ else if (strcasecmp(val, "add-apparently-to") == 0)
+ NoRecipientAction = NRA_ADD_APPARENTLY_TO;
+ else if (strcasecmp(val, "add-bcc") == 0)
+ NoRecipientAction = NRA_ADD_BCC;
+ else if (strcasecmp(val, "add-to-undisclosed") == 0)
+ NoRecipientAction = NRA_ADD_TO_UNDISCLOSED;
+ else
+ syserr("Invalid NoRecipientAction: %s", val);
+ break;
+
+ case O_SAFEFILEENV: /* chroot() environ for writing to files */
+ SafeFileEnv = newstr(val);
+ break;
+
+ case O_MAXMSGSIZE: /* maximum message size */
+ MaxMessageSize = atol(val);
+ break;
+
+ case O_COLONOKINADDR: /* old style handling of colon addresses */
+ ColonOkInAddr = atobool(val);
+ break;
+
+ case O_MAXQUEUERUN: /* max # of jobs in a single queue run */
+ MaxQueueRun = atol(val);
+ break;
+
+ case O_MAXCHILDREN: /* max # of children of daemon */
+ MaxChildren = atoi(val);
+ break;
+
+ case O_KEEPCNAMES: /* don't expand CNAME records */
+ DontExpandCnames = atobool(val);
+ break;
+
+ case O_MUSTQUOTE: /* must quote these characters in phrases */
+ strcpy(buf, "@,;:\\()[]");
+ if (strlen(val) < sizeof buf - 10)
+ strcat(buf, val);
+ MustQuoteChars = newstr(buf);
+ break;
+
+ case O_SMTPGREETING: /* SMTP greeting message (old $e macro) */
+ SmtpGreeting = newstr(munchstring(val, NULL));
+ break;
+
+ case O_UNIXFROM: /* UNIX From_ line (old $l macro) */
+ UnixFromLine = newstr(munchstring(val, NULL));
+ break;
+
+ case O_OPCHARS: /* operator characters (old $o macro) */
+ OperatorChars = newstr(munchstring(val, NULL));
+ break;
+
+ case O_DONTINITGRPS: /* don't call initgroups(3) */
+ DontInitGroups = atobool(val);
+ break;
+
+ case O_SLFH: /* make sure from fits on one line */
+ SingleLineFromHeader = atobool(val);
+ break;
+
default:
+ if (tTd(37, 1))
+ {
+ if (isascii(opt) && isprint(opt))
+ printf("Warning: option %c unknown\n", opt);
+ else
+ printf("Warning: option 0x%x unknown\n", opt);
+ }
break;
}
if (sticky)
setbitn(opt, StickyOpt);
- return;
}
/*
-** SETCLASS -- set a word into a class
+** SETCLASS -- set a string into a class
**
** Parameters:
-** class -- the class to put the word in.
-** word -- the word to enter
+** class -- the class to put the string in.
+** str -- the string to enter
**
** Returns:
** none.
@@ -1487,15 +2165,16 @@ setoption(opt, val, safe, sticky, e)
** puts the word into the symbol table.
*/
-setclass(class, word)
+void
+setclass(class, str)
int class;
- char *word;
+ char *str;
{
register STAB *s;
if (tTd(37, 8))
- printf("setclass(%c, %s)\n", class, word);
- s = stab(word, ST_CLASS, ST_ENTER);
+ printf("setclass(%s, %s)\n", macname(class), str);
+ s = stab(str, ST_CLASS, ST_ENTER);
setbitn(class, s->s_class);
}
/*
@@ -1505,14 +2184,14 @@ setclass(class, word)
** line -- the config file line
**
** Returns:
-** TRUE if it successfully entered the map entry.
-** FALSE otherwise (usually syntax error).
+** A pointer to the map that has been created.
+** NULL if there was a syntax error.
**
** Side Effects:
** Enters the map into the dictionary.
*/
-void
+MAP *
makemapentry(line)
char *line;
{
@@ -1527,11 +2206,11 @@ makemapentry(line)
if (!(isascii(*p) && isalnum(*p)))
{
syserr("readcf: config K line: no map name");
- return;
+ return NULL;
}
mapname = p;
- while (isascii(*++p) && isalnum(*p))
+ while ((isascii(*++p) && isalnum(*p)) || *p == '_' || *p == '.')
continue;
if (*p != '\0')
*p++ = '\0';
@@ -1540,7 +2219,7 @@ makemapentry(line)
if (!(isascii(*p) && isalnum(*p)))
{
syserr("readcf: config K line, map %s: no map class", mapname);
- return;
+ return NULL;
}
classname = p;
while (isascii(*++p) && isalnum(*p))
@@ -1555,7 +2234,7 @@ makemapentry(line)
if (class == NULL)
{
syserr("readcf: map %s: class %s not available", mapname, classname);
- return;
+ return NULL;
}
/* enter the map */
@@ -1577,9 +2256,128 @@ makemapentry(line)
s->s_map.map_domain == NULL ? "(null)" : s->s_map.map_domain,
s->s_map.map_rebuild == NULL ? "(null)" : s->s_map.map_rebuild);
}
+
+ return &s->s_map;
}
/*
-** SETTIMEOUTS -- parse and set timeout values
+** STRTORWSET -- convert string to rewriting set number
+**
+** Parameters:
+** p -- the pointer to the string to decode.
+** endp -- if set, store the trailing delimiter here.
+** stabmode -- ST_ENTER to create this entry, ST_FIND if
+** it must already exist.
+**
+** Returns:
+** The appropriate ruleset number.
+** -1 if it is not valid (error already printed)
+*/
+
+int
+strtorwset(p, endp, stabmode)
+ char *p;
+ char **endp;
+ int stabmode;
+{
+ int ruleset;
+ static int nextruleset = MAXRWSETS;
+
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (!isascii(*p))
+ {
+ syserr("invalid ruleset name: \"%.20s\"", p);
+ return -1;
+ }
+ if (isdigit(*p))
+ {
+ ruleset = strtol(p, endp, 10);
+ if (ruleset >= MAXRWSETS / 2 || ruleset < 0)
+ {
+ syserr("bad ruleset %d (%d max)",
+ ruleset, MAXRWSETS / 2);
+ ruleset = -1;
+ }
+ }
+ else
+ {
+ STAB *s;
+ char delim;
+ char *q;
+
+ q = p;
+ while (*p != '\0' && isascii(*p) &&
+ (isalnum(*p) || *p == '_'))
+ p++;
+ if (q == p || !isalpha(*q))
+ {
+ /* no valid characters */
+ syserr("invalid ruleset name: \"%.20s\"", q);
+ return -1;
+ }
+ while (isascii(*p) && isspace(*p))
+ *p++ = '\0';
+ delim = *p;
+ if (delim != '\0')
+ *p = '\0';
+ s = stab(q, ST_RULESET, stabmode);
+ if (delim != '\0')
+ *p = delim;
+
+ if (s == NULL)
+ {
+ syserr("unknown ruleset %s", q);
+ return -1;
+ }
+
+ if (stabmode == ST_ENTER && delim == '=')
+ {
+ while (isascii(*++p) && isspace(*p))
+ continue;
+ if (!isdigit(*p))
+ {
+ syserr("bad ruleset definition \"%s\" (number required after `=')", q);
+ ruleset = -1;
+ }
+ else
+ {
+ ruleset = strtol(p, endp, 10);
+ if (ruleset >= MAXRWSETS / 2 || ruleset < 0)
+ {
+ syserr("bad ruleset number %d in \"%s\" (%d max)",
+ ruleset, q, MAXRWSETS / 2);
+ ruleset = -1;
+ }
+ }
+ }
+ else
+ {
+ if (endp != NULL)
+ *endp = p;
+ if (s->s_ruleset > 0)
+ ruleset = s->s_ruleset;
+ else if ((ruleset = --nextruleset) < MAXRWSETS / 2)
+ {
+ syserr("%s: too many named rulesets (%d max)",
+ q, MAXRWSETS / 2);
+ ruleset = -1;
+ }
+ }
+ if (s->s_ruleset > 0 && ruleset >= 0 && ruleset != s->s_ruleset)
+ {
+ syserr("%s: ruleset changed value (old %d, new %d)",
+ q, ruleset, s->s_ruleset);
+ ruleset = s->s_ruleset;
+ }
+ else if (ruleset > 0)
+ {
+ s->s_ruleset = ruleset;
+ }
+ }
+ return ruleset;
+}
+ /*
+** INITTIMEOUTS -- parse and set timeout values
**
** Parameters:
** val -- a pointer to the values. If NULL, do initial
@@ -1596,7 +2394,8 @@ makemapentry(line)
#define MINUTES * 60
#define HOUR * 3600
-settimeouts(val)
+void
+inittimeouts(val)
register char *val;
{
register char *p;
@@ -1604,6 +2403,7 @@ settimeouts(val)
if (val == NULL)
{
+ TimeOuts.to_connect = (time_t) 0 SECONDS;
TimeOuts.to_initial = (time_t) 5 MINUTES;
TimeOuts.to_helo = (time_t) 5 MINUTES;
TimeOuts.to_mail = (time_t) 10 MINUTES;
@@ -1615,7 +2415,12 @@ settimeouts(val)
TimeOuts.to_quit = (time_t) 2 MINUTES;
TimeOuts.to_nextcommand = (time_t) 1 HOUR;
TimeOuts.to_miscshort = (time_t) 2 MINUTES;
+#if IDENTPROTO
TimeOuts.to_ident = (time_t) 30 SECONDS;
+#else
+ TimeOuts.to_ident = (time_t) 0 SECONDS;
+#endif
+ TimeOuts.to_fileopen = (time_t) 60 SECONDS;
return;
}
@@ -1643,43 +2448,107 @@ settimeouts(val)
}
else
{
- register char *q = strchr(val, '=');
- time_t to;
+ register char *q = strchr(val, ':');
- if (q == NULL)
+ if (q == NULL && (q = strchr(val, '=')) == NULL)
{
/* syntax error */
continue;
}
*q++ = '\0';
- to = convtime(q, 'm');
-
- if (strcasecmp(val, "initial") == 0)
- TimeOuts.to_initial = to;
- else if (strcasecmp(val, "mail") == 0)
- TimeOuts.to_mail = to;
- else if (strcasecmp(val, "rcpt") == 0)
- TimeOuts.to_rcpt = to;
- else if (strcasecmp(val, "datainit") == 0)
- TimeOuts.to_datainit = to;
- else if (strcasecmp(val, "datablock") == 0)
- TimeOuts.to_datablock = to;
- else if (strcasecmp(val, "datafinal") == 0)
- TimeOuts.to_datafinal = to;
- else if (strcasecmp(val, "command") == 0)
- TimeOuts.to_nextcommand = to;
- else if (strcasecmp(val, "rset") == 0)
- TimeOuts.to_rset = to;
- else if (strcasecmp(val, "helo") == 0)
- TimeOuts.to_helo = to;
- else if (strcasecmp(val, "quit") == 0)
- TimeOuts.to_quit = to;
- else if (strcasecmp(val, "misc") == 0)
- TimeOuts.to_miscshort = to;
- else if (strcasecmp(val, "ident") == 0)
- TimeOuts.to_ident = to;
- else
- syserr("settimeouts: invalid timeout %s", val);
+ settimeout(val, q);
}
}
}
+ /*
+** SETTIMEOUT -- set an individual timeout
+**
+** Parameters:
+** name -- the name of the timeout.
+** val -- the value of the timeout.
+**
+** Returns:
+** none.
+*/
+
+void
+settimeout(name, val)
+ char *name;
+ char *val;
+{
+ register char *p;
+ time_t to;
+ extern time_t convtime();
+
+ to = convtime(val, 'm');
+ p = strchr(name, '.');
+ if (p != NULL)
+ *p++ = '\0';
+
+ if (strcasecmp(name, "initial") == 0)
+ TimeOuts.to_initial = to;
+ else if (strcasecmp(name, "mail") == 0)
+ TimeOuts.to_mail = to;
+ else if (strcasecmp(name, "rcpt") == 0)
+ TimeOuts.to_rcpt = to;
+ else if (strcasecmp(name, "datainit") == 0)
+ TimeOuts.to_datainit = to;
+ else if (strcasecmp(name, "datablock") == 0)
+ TimeOuts.to_datablock = to;
+ else if (strcasecmp(name, "datafinal") == 0)
+ TimeOuts.to_datafinal = to;
+ else if (strcasecmp(name, "command") == 0)
+ TimeOuts.to_nextcommand = to;
+ else if (strcasecmp(name, "rset") == 0)
+ TimeOuts.to_rset = to;
+ else if (strcasecmp(name, "helo") == 0)
+ TimeOuts.to_helo = to;
+ else if (strcasecmp(name, "quit") == 0)
+ TimeOuts.to_quit = to;
+ else if (strcasecmp(name, "misc") == 0)
+ TimeOuts.to_miscshort = to;
+ else if (strcasecmp(name, "ident") == 0)
+ TimeOuts.to_ident = to;
+ else if (strcasecmp(name, "fileopen") == 0)
+ TimeOuts.to_fileopen = to;
+ else if (strcasecmp(name, "connect") == 0)
+ TimeOuts.to_connect = to;
+ else if (strcasecmp(name, "queuewarn") == 0)
+ {
+ to = convtime(val, 'h');
+ if (p == NULL || strcmp(p, "*") == 0)
+ {
+ TimeOuts.to_q_warning[TOC_NORMAL] = to;
+ TimeOuts.to_q_warning[TOC_URGENT] = to;
+ TimeOuts.to_q_warning[TOC_NONURGENT] = to;
+ }
+ else if (strcasecmp(p, "normal") == 0)
+ TimeOuts.to_q_warning[TOC_NORMAL] = to;
+ else if (strcasecmp(p, "urgent") == 0)
+ TimeOuts.to_q_warning[TOC_URGENT] = to;
+ else if (strcasecmp(p, "non-urgent") == 0)
+ TimeOuts.to_q_warning[TOC_NONURGENT] = to;
+ else
+ syserr("settimeout: invalid queuewarn subtimeout %s", p);
+ }
+ else if (strcasecmp(name, "queuereturn") == 0)
+ {
+ to = convtime(val, 'd');
+ if (p == NULL || strcmp(p, "*") == 0)
+ {
+ TimeOuts.to_q_return[TOC_NORMAL] = to;
+ TimeOuts.to_q_return[TOC_URGENT] = to;
+ TimeOuts.to_q_return[TOC_NONURGENT] = to;
+ }
+ else if (strcasecmp(p, "normal") == 0)
+ TimeOuts.to_q_return[TOC_NORMAL] = to;
+ else if (strcasecmp(p, "urgent") == 0)
+ TimeOuts.to_q_return[TOC_URGENT] = to;
+ else if (strcasecmp(p, "non-urgent") == 0)
+ TimeOuts.to_q_return[TOC_NONURGENT] = to;
+ else
+ syserr("settimeout: invalid queuereturn subtimeout %s", p);
+ }
+ else
+ syserr("settimeout: invalid timeout %s", name);
+}
diff --git a/usr.sbin/sendmail/src/recipient.c b/usr.sbin/sendmail/src/recipient.c
index 0b12c2c..79126e9 100644
--- a/usr.sbin/sendmail/src/recipient.c
+++ b/usr.sbin/sendmail/src/recipient.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -33,11 +33,10 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)recipient.c 8.44.1.6 (Berkeley) 3/5/95";
+static char sccsid[] = "@(#)recipient.c 8.108 (Berkeley) 10/30/95";
#endif /* not lint */
# include "sendmail.h"
-# include <pwd.h>
/*
** SENDTOLIST -- Designate a send list.
@@ -53,6 +52,8 @@ static char sccsid[] = "@(#)recipient.c 8.44.1.6 (Berkeley) 3/5/95";
** expansion.
** sendq -- a pointer to the head of a queue to put
** these people into.
+** aliaslevel -- the current alias nesting depth -- to
+** diagnose loops.
** e -- the envelope in which to add these recipients.
**
** Returns:
@@ -62,12 +63,15 @@ static char sccsid[] = "@(#)recipient.c 8.44.1.6 (Berkeley) 3/5/95";
** none.
*/
-# define MAXRCRSN 10
+/* q_flags bits inherited from ctladdr */
+#define QINHERITEDBITS (QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY|QHASNOTIFY)
-sendtolist(list, ctladdr, sendq, e)
+int
+sendtolist(list, ctladdr, sendq, aliaslevel, e)
char *list;
ADDRESS *ctladdr;
ADDRESS **sendq;
+ int aliaslevel;
register ENVELOPE *e;
{
register char *p;
@@ -128,13 +132,58 @@ sendtolist(list, ctladdr, sendq, e)
a->q_next = al;
a->q_alias = ctladdr;
- /* see if this should be marked as a primary address */
- if (ctladdr == NULL ||
- (firstone && *p == '\0' && bitset(QPRIMARY, ctladdr->q_flags)))
- a->q_flags |= QPRIMARY;
+ /* arrange to inherit attributes from parent */
+ if (ctladdr != NULL)
+ {
+ ADDRESS *b;
+ extern ADDRESS *self_reference();
+
+ /* self reference test */
+ if (sameaddr(ctladdr, a))
+ {
+ if (tTd(27, 5))
+ {
+ printf("sendtolist: QSELFREF ");
+ printaddr(ctladdr, FALSE);
+ }
+ ctladdr->q_flags |= QSELFREF;
+ }
+
+ /* check for address loops */
+ b = self_reference(a, e);
+ if (b != NULL)
+ {
+ b->q_flags |= QSELFREF;
+ if (tTd(27, 5))
+ {
+ printf("sendtolist: QSELFREF ");
+ printaddr(b, FALSE);
+ }
+ if (a != b)
+ {
+ if (tTd(27, 5))
+ {
+ printf("sendtolist: QDONTSEND ");
+ printaddr(a, FALSE);
+ }
+ a->q_flags |= QDONTSEND;
+ b->q_flags |= a->q_flags & QNOTREMOTE;
+ continue;
+ }
+ }
+
+ /* full name */
+ if (a->q_fullname == NULL)
+ a->q_fullname = ctladdr->q_fullname;
+
+ /* various flag bits */
+ a->q_flags &= ~QINHERITEDBITS;
+ a->q_flags |= ctladdr->q_flags & QINHERITEDBITS;
+
+ /* original recipient information */
+ a->q_orcpt = ctladdr->q_orcpt;
+ }
- if (ctladdr != NULL && sameaddr(ctladdr, a))
- ctladdr->q_flags |= QSELFREF;
al = a;
firstone = FALSE;
}
@@ -145,11 +194,7 @@ sendtolist(list, ctladdr, sendq, e)
register ADDRESS *a = al;
al = a->q_next;
- a = recipient(a, sendq, e);
-
- /* arrange to inherit full name */
- if (a->q_fullname == NULL && ctladdr != NULL)
- a->q_fullname = ctladdr->q_fullname;
+ a = recipient(a, sendq, aliaslevel, e);
naddrs++;
}
@@ -168,6 +213,7 @@ sendtolist(list, ctladdr, sendq, e)
** sendq -- a pointer to the head of a queue to put the
** recipient in. Duplicate supression is done
** in this queue.
+** aliaslevel -- the current alias nesting depth.
** e -- the current envelope.
**
** Returns:
@@ -179,9 +225,10 @@ sendtolist(list, ctladdr, sendq, e)
*/
ADDRESS *
-recipient(a, sendq, e)
+recipient(a, sendq, aliaslevel, e)
register ADDRESS *a;
register ADDRESS **sendq;
+ int aliaslevel;
register ENVELOPE *e;
{
register ADDRESS *q;
@@ -190,15 +237,20 @@ recipient(a, sendq, e)
register char *p;
bool quoted = FALSE; /* set if the addr has a quote bit */
int findusercount = 0;
- char buf[MAXNAME]; /* unquoted image of the user name */
+ bool initialdontsend = bitset(QDONTSEND, a->q_flags);
+ int i;
+ char *buf;
+ char buf0[MAXNAME + 1]; /* unquoted image of the user name */
extern int safefile();
e->e_to = a->q_paddr;
m = a->q_mailer;
errno = 0;
+ if (aliaslevel == 0)
+ a->q_flags |= QPRIMARY;
if (tTd(26, 1))
{
- printf("\nrecipient: ");
+ printf("\nrecipient (%d): ", aliaslevel);
printaddr(a, FALSE);
}
@@ -212,9 +264,11 @@ recipient(a, sendq, e)
}
/* break aliasing loops */
- if (AliasLevel > MAXRCRSN)
+ if (aliaslevel > MaxAliasRecursion)
{
- usrerr("554 aliasing/forwarding loop broken");
+ a->q_status = "5.4.6";
+ usrerr("554 aliasing/forwarding loop broken (%d aliases deep; %d max",
+ aliaslevel, MaxAliasRecursion);
return (a);
}
@@ -222,10 +276,12 @@ recipient(a, sendq, e)
** Finish setting up address structure.
*/
- /* set the queue timeout */
- a->q_timeout = TimeOuts.to_q_return;
-
/* get unquoted user for file, program or user.name check */
+ i = strlen(a->q_user);
+ if (i >= sizeof buf0)
+ buf = xalloc(i + 1);
+ else
+ buf = buf0;
(void) strcpy(buf, a->q_user);
for (p = buf; *p != '\0' && !quoted; p++)
{
@@ -240,17 +296,20 @@ recipient(a, sendq, e)
if (a->q_alias == NULL)
{
a->q_flags |= QBADADDR;
+ a->q_status = "5.7.1";
usrerr("550 Cannot mail directly to programs");
}
else if (bitset(QBOGUSSHELL, a->q_alias->q_flags))
{
a->q_flags |= QBADADDR;
+ a->q_status = "5.7.1";
usrerr("550 User %s@%s doesn't have a valid shell for mailing to programs",
a->q_alias->q_ruser, MyHostName);
}
else if (bitset(QUNSAFEADDR, a->q_alias->q_flags))
{
a->q_flags |= QBADADDR;
+ a->q_status = "5.7.1";
usrerr("550 Address %s is unsafe for mailing to programs",
a->q_alias->q_paddr);
}
@@ -283,7 +342,7 @@ recipient(a, sendq, e)
else if (bitset(QSELFREF, q->q_flags))
q->q_flags |= a->q_flags & ~QDONTSEND;
a = q;
- goto testselfdestruct;
+ goto done;
}
}
@@ -308,6 +367,7 @@ recipient(a, sendq, e)
if (a->q_alias == NULL)
{
a->q_flags |= QBADADDR;
+ a->q_status = "5.7.1";
usrerr("550 Cannot mail directly to :include:s");
}
else
@@ -315,25 +375,29 @@ recipient(a, sendq, e)
int ret;
message("including file %s", a->q_user);
- ret = include(a->q_user, FALSE, a, sendq, e);
+ ret = include(a->q_user, FALSE, a, sendq, aliaslevel, e);
if (transienterror(ret))
{
#ifdef LOG
if (LogLevel > 2)
syslog(LOG_ERR, "%s: include %s: transient error: %s",
e->e_id == NULL ? "NOQUEUE" : e->e_id,
- a->q_user, errstring(ret));
+ shortenstring(a->q_user, 203),
+ errstring(ret));
#endif
a->q_flags |= QQUEUEUP;
a->q_flags &= ~QDONTSEND;
usrerr("451 Cannot open %s: %s",
- a->q_user, errstring(ret));
+ shortenstring(a->q_user, 203),
+ errstring(ret));
}
else if (ret != 0)
{
a->q_flags |= QBADADDR;
+ a->q_status = "5.2.4";
usrerr("550 Cannot open %s: %s",
- a->q_user, errstring(ret));
+ shortenstring(a->q_user, 203),
+ errstring(ret));
}
}
}
@@ -345,44 +409,44 @@ recipient(a, sendq, e)
if (a->q_alias == NULL)
{
a->q_flags |= QBADADDR;
+ a->q_status = "5.7.1";
usrerr("550 Cannot mail directly to files");
}
else if (bitset(QBOGUSSHELL, a->q_alias->q_flags))
{
a->q_flags |= QBADADDR;
+ a->q_status = "5.7.1";
usrerr("550 User %s@%s doesn't have a valid shell for mailing to files",
a->q_alias->q_ruser, MyHostName);
}
else if (bitset(QUNSAFEADDR, a->q_alias->q_flags))
{
a->q_flags |= QBADADDR;
+ a->q_status = "5.7.1";
usrerr("550 Address %s is unsafe for mailing to files",
a->q_alias->q_paddr);
}
- else if (!writable(buf, getctladdr(a), SFF_ANYFILE))
+ else if (!writable(buf, a->q_alias, SFF_CREAT))
{
a->q_flags |= QBADADDR;
- giveresponse(EX_CANTCREAT, m, NULL, a->q_alias, e);
+ giveresponse(EX_CANTCREAT, m, NULL, a->q_alias,
+ (time_t) 0, e);
}
}
- if (m != LocalMailer)
- {
- if (!bitset(QDONTSEND, a->q_flags))
- e->e_nrcpts++;
- goto testselfdestruct;
- }
-
/* try aliasing */
- alias(a, sendq, e);
+ if (!quoted && !bitset(QDONTSEND, a->q_flags) &&
+ bitnset(M_ALIASABLE, m->m_flags))
+ alias(a, sendq, aliaslevel, e);
-# ifdef USERDB
+# if USERDB
/* if not aliased, look it up in the user database */
- if (!bitset(QDONTSEND|QNOTREMOTE|QVERIFIED, a->q_flags))
+ if (!bitset(QDONTSEND|QNOTREMOTE|QVERIFIED, a->q_flags) &&
+ bitnset(M_CHECKUDB, m->m_flags))
{
extern int udbexpand();
- if (udbexpand(a, sendq, e) == EX_TEMPFAIL)
+ if (udbexpand(a, sendq, aliaslevel, e) == EX_TEMPFAIL)
{
a->q_flags |= QQUEUEUP;
if (e->e_message == NULL)
@@ -401,10 +465,6 @@ recipient(a, sendq, e)
}
# endif
- /* if it was an alias or a UDB expansion, just return now */
- if (bitset(QDONTSEND|QQUEUEUP|QVERIFIED, a->q_flags))
- goto testselfdestruct;
-
/*
** If we have a level two config file, then pass the name through
** Ruleset 5 before sending it off. Ruleset 5 has the right
@@ -418,10 +478,11 @@ recipient(a, sendq, e)
ConfigLevel, RewriteRules[5]);
printaddr(a, FALSE);
}
- if (!bitset(QNOTREMOTE, a->q_flags) && ConfigLevel >= 2 &&
- RewriteRules[5] != NULL)
+ if (!bitset(QNOTREMOTE|QDONTSEND|QQUEUEUP|QVERIFIED, a->q_flags) &&
+ ConfigLevel >= 2 && RewriteRules[5] != NULL &&
+ bitnset(M_TRYRULESET5, m->m_flags))
{
- maplocaluser(a, sendq, e);
+ maplocaluser(a, sendq, aliaslevel + 1, e);
}
/*
@@ -429,7 +490,8 @@ recipient(a, sendq, e)
** and deliver it.
*/
- if (!bitset(QDONTSEND|QQUEUEUP, a->q_flags))
+ if (!bitset(QDONTSEND|QQUEUEUP|QVERIFIED, a->q_flags) &&
+ bitnset(M_HASPWENT, m->m_flags))
{
auto bool fuzzy;
register struct passwd *pw;
@@ -440,11 +502,13 @@ recipient(a, sendq, e)
if (pw == NULL)
{
a->q_flags |= QBADADDR;
- giveresponse(EX_NOUSER, m, NULL, a->q_alias, e);
+ a->q_status = "5.1.1";
+ giveresponse(EX_NOUSER, m, NULL, a->q_alias,
+ (time_t) 0, e);
}
else
{
- char nbuf[MAXNAME];
+ char nbuf[MAXNAME + 1];
if (fuzzy)
{
@@ -453,9 +517,10 @@ recipient(a, sendq, e)
if (findusercount++ > 3)
{
a->q_flags |= QBADADDR;
+ a->q_status = "5.4.6";
usrerr("554 aliasing/forwarding loop for %s broken",
pw->pw_name);
- return (a);
+ goto done;
}
/* see if it aliases */
@@ -473,36 +538,103 @@ recipient(a, sendq, e)
buildfname(pw->pw_gecos, pw->pw_name, nbuf);
if (nbuf[0] != '\0')
a->q_fullname = newstr(nbuf);
- if (pw->pw_shell != NULL && pw->pw_shell[0] != '\0' &&
- !usershellok(pw->pw_shell))
+ if (!usershellok(pw->pw_name, pw->pw_shell))
{
a->q_flags |= QBOGUSSHELL;
}
- if (!quoted)
- forward(a, sendq, e);
+ if (bitset(EF_VRFYONLY, e->e_flags))
+ {
+ /* don't do any more now */
+ a->q_flags |= QVERIFIED;
+ }
+ else if (!quoted)
+ forward(a, sendq, aliaslevel, e);
}
}
if (!bitset(QDONTSEND, a->q_flags))
e->e_nrcpts++;
testselfdestruct:
+ a->q_flags |= QTHISPASS;
if (tTd(26, 8))
{
printf("testselfdestruct: ");
- printaddr(a, TRUE);
+ printaddr(a, FALSE);
+ if (tTd(26, 10))
+ {
+ printf("SENDQ:\n");
+ printaddr(*sendq, TRUE);
+ printf("----\n");
+ }
}
if (a->q_alias == NULL && a != &e->e_from &&
bitset(QDONTSEND, a->q_flags))
{
- q = *sendq;
- while (q != NULL && bitset(QDONTSEND, q->q_flags))
- q = q->q_next;
+ for (q = *sendq; q != NULL; q = q->q_next)
+ {
+ if (!bitset(QDONTSEND, q->q_flags))
+ break;
+ }
if (q == NULL)
{
a->q_flags |= QBADADDR;
+ a->q_status = "5.4.6";
usrerr("554 aliasing/forwarding loop broken");
}
}
+
+ done:
+ a->q_flags |= QTHISPASS;
+ if (buf != buf0)
+ free(buf);
+
+ /*
+ ** If we are at the top level, check to see if this has
+ ** expanded to exactly one address. If so, it can inherit
+ ** the primaryness of the address.
+ **
+ ** While we're at it, clear the QTHISPASS bits.
+ */
+
+ if (aliaslevel == 0)
+ {
+ int nrcpts = 0;
+ ADDRESS *only;
+
+ for (q = *sendq; q != NULL; q = q->q_next)
+ {
+ if (bitset(QTHISPASS, q->q_flags) &&
+ !bitset(QDONTSEND|QBADADDR, q->q_flags))
+ {
+ nrcpts++;
+ only = q;
+ }
+ q->q_flags &= ~QTHISPASS;
+ }
+ if (nrcpts == 1)
+ {
+ /* check to see if this actually got a new owner */
+ q = only;
+ while ((q = q->q_alias) != NULL)
+ {
+ if (q->q_owner != NULL)
+ break;
+ }
+ if (q == NULL)
+ only->q_flags |= QPRIMARY;
+ }
+ else if (!initialdontsend && nrcpts > 0)
+ {
+ /* arrange for return receipt */
+ e->e_flags |= EF_SENDRECEIPT;
+ a->q_flags |= QEXPANDED;
+ if (e->e_xfp != NULL && bitset(QPINGONSUCCESS, a->q_flags))
+ fprintf(e->e_xfp,
+ "%s... expanded to multiple addresses\n",
+ a->q_paddr);
+ }
+ }
+
return (a);
}
/*
@@ -535,14 +667,14 @@ finduser(name, fuzzyp)
{
register struct passwd *pw;
register char *p;
- extern struct passwd *getpwent();
- extern struct passwd *getpwnam();
+ bool tryagain;
if (tTd(29, 4))
printf("finduser(%s): ", name);
*fuzzyp = FALSE;
+#ifdef HESIOD
/* DEC Hesiod getpwnam accepts numeric strings -- short circuit it */
for (p = name; *p != '\0'; p++)
if (!isascii(*p) || !isdigit(*p))
@@ -553,16 +685,35 @@ finduser(name, fuzzyp)
printf("failed (numeric input)\n");
return NULL;
}
+#endif
/* look up this login name using fast path */
- if ((pw = getpwnam(name)) != NULL)
+ if ((pw = sm_getpwnam(name)) != NULL)
{
if (tTd(29, 4))
printf("found (non-fuzzy)\n");
return (pw);
}
-#ifdef MATCHGECOS
+ /* try mapping it to lower case */
+ tryagain = FALSE;
+ for (p = name; *p != '\0'; p++)
+ {
+ if (isascii(*p) && isupper(*p))
+ {
+ *p = tolower(*p);
+ tryagain = TRUE;
+ }
+ }
+ if (tryagain && (pw = sm_getpwnam(name)) != NULL)
+ {
+ if (tTd(29, 4))
+ printf("found (lower case)\n");
+ *fuzzyp = TRUE;
+ return pw;
+ }
+
+#if MATCHGECOS
/* see if fuzzy matching allowed */
if (!MatchGecos)
{
@@ -580,7 +731,17 @@ finduser(name, fuzzyp)
(void) setpwent();
while ((pw = getpwent()) != NULL)
{
- char buf[MAXNAME];
+ char buf[MAXNAME + 1];
+
+# if 0
+ if (strcasecmp(pw->pw_name, name) == 0)
+ {
+ if (tTd(29, 4))
+ printf("found (case wrapped)\n");
+ *fuzzyp = TRUE;
+ return pw;
+ }
+# endif
buildfname(pw->pw_gecos, pw->pw_name, buf);
if (strchr(buf, ' ') != NULL && !strcasecmp(buf, name))
@@ -632,90 +793,53 @@ writable(filename, ctladdr, flags)
{
uid_t euid;
gid_t egid;
- int bits;
- register char *p;
char *uname;
- struct stat stb;
- extern char RealUserName[];
-
- if (tTd(29, 5))
- printf("writable(%s, %x)\n", filename, flags);
-
-#ifdef HASLSTAT
- if ((bitset(SFF_NOSLINK, flags) ? lstat(filename, &stb)
- : stat(filename, &stb)) < 0)
-#else
- if (stat(filename, &stb) < 0)
-#endif
- {
- /* file does not exist -- see if directory is safe */
- p = strrchr(filename, '/');
- if (p == NULL)
- {
- errno = ENOTDIR;
- return FALSE;
- }
- *p = '\0';
- errno = safefile(filename, RealUid, RealGid, RealUserName,
- SFF_MUSTOWN, S_IWRITE|S_IEXEC);
- *p = '/';
- return errno == 0;
- }
-#ifdef SUID_ROOT_FILES_OK
- /* really ought to be passed down -- and not a good idea */
- flags |= SFF_ROOTOK;
-#endif
+ if (tTd(44, 5))
+ printf("writable(%s, 0x%x)\n", filename, flags);
/*
** File does exist -- check that it is writable.
*/
- if (bitset(0111, stb.st_mode))
- {
- if (tTd(29, 5))
- printf("failed (mode %o: x bits)\n", stb.st_mode);
- errno = EPERM;
- return (FALSE);
- }
-
if (ctladdr != NULL && geteuid() == 0)
{
euid = ctladdr->q_uid;
egid = ctladdr->q_gid;
uname = ctladdr->q_user;
}
- else
+ else if (bitset(SFF_RUNASREALUID, flags))
{
euid = RealUid;
egid = RealGid;
uname = RealUserName;
}
- if (euid == 0)
+ else if (FileMailer != NULL && !bitset(SFF_ROOTOK, flags))
{
- euid = DefUid;
- uname = DefUser;
+ euid = FileMailer->m_uid;
+ egid = FileMailer->m_gid;
+ uname = NULL;
+ }
+ else
+ {
+ euid = egid = 0;
+ uname = NULL;
}
- if (egid == 0)
- egid = DefGid;
- if (geteuid() == 0)
+ if (!bitset(SFF_ROOTOK, flags))
{
- if (bitset(S_ISUID, stb.st_mode) &&
- (stb.st_uid != 0 || bitset(SFF_ROOTOK, flags)))
+ if (euid == 0)
{
- euid = stb.st_uid;
- uname = NULL;
+ euid = DefUid;
+ uname = DefUser;
}
- if (bitset(S_ISGID, stb.st_mode) &&
- (stb.st_gid != 0 || bitset(SFF_ROOTOK, flags)))
- egid = stb.st_gid;
+ if (egid == 0)
+ egid = DefGid;
}
+ if (geteuid() == 0 &&
+ (ctladdr == NULL || !bitset(QGOODUID, ctladdr->q_flags)))
+ flags |= SFF_SETUIDOK;
- if (tTd(29, 5))
- printf("\teu/gid=%d/%d, st_u/gid=%d/%d\n",
- euid, egid, stb.st_uid, stb.st_gid);
-
- errno = safefile(filename, euid, egid, uname, flags, S_IWRITE);
+ errno = safefile(filename, euid, egid, uname, flags, S_IWRITE, NULL);
return errno == 0;
}
/*
@@ -730,6 +854,8 @@ writable(filename, ctladdr, flags)
** the important things.
** sendq -- a pointer to the head of the send queue
** to put these addresses in.
+** aliaslevel -- the alias nesting depth.
+** e -- the current envelope.
**
** Returns:
** open error status
@@ -753,32 +879,29 @@ writable(filename, ctladdr, flags)
*/
static jmp_buf CtxIncludeTimeout;
-static int includetimeout();
-
-#ifndef S_IWOTH
-# define S_IWOTH (S_IWRITE >> 6)
-#endif
+static void includetimeout();
int
-include(fname, forwarding, ctladdr, sendq, e)
+include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
char *fname;
bool forwarding;
ADDRESS *ctladdr;
ADDRESS **sendq;
+ int aliaslevel;
ENVELOPE *e;
{
- register FILE *fp = NULL;
+ FILE *volatile fp = NULL;
char *oldto = e->e_to;
char *oldfilename = FileName;
int oldlinenumber = LineNumber;
register EVENT *ev = NULL;
int nincludes;
register ADDRESS *ca;
- uid_t saveduid, uid;
- gid_t savedgid, gid;
- char *uname;
+ volatile uid_t saveduid, uid;
+ volatile gid_t savedgid, gid;
+ char *volatile uname;
int rval = 0;
- int sfflags = forwarding ? SFF_MUSTOWN : SFF_ANYFILE;
+ int sfflags = SFF_REGONLY;
struct stat st;
char buf[MAXLINE];
#ifdef _POSIX_CHOWN_RESTRICTED
@@ -813,30 +936,47 @@ include(fname, forwarding, ctladdr, sendq, e)
if (tTd(27, 9))
printf("include: old uid = %d/%d\n", getuid(), geteuid());
+ if (forwarding)
+ sfflags |= SFF_MUSTOWN|SFF_ROOTOK|SFF_NOSLINK;
+
ca = getctladdr(ctladdr);
if (ca == NULL)
{
uid = DefUid;
gid = DefGid;
uname = DefUser;
- saveduid = -1;
}
else
{
uid = ca->q_uid;
gid = ca->q_gid;
uname = ca->q_user;
-#ifdef HASSETREUID
- saveduid = geteuid();
- savedgid = getegid();
- if (saveduid == 0)
- {
+ }
+#if HASSETREUID || USESETEUID
+ saveduid = geteuid();
+ savedgid = getegid();
+ if (saveduid == 0)
+ {
+ if (!DontInitGroups)
initgroups(uname, gid);
- if (uid != 0)
- (void) setreuid(0, uid);
+ if (gid != 0)
+ (void) setgid(gid);
+ if (uid != 0)
+ {
+# if USESETEUID
+ if (seteuid(uid) < 0)
+ syserr("seteuid(%d) failure (real=%d, eff=%d)",
+ uid, getuid(), geteuid());
+# else
+ if (setreuid(0, uid) < 0)
+ syserr("setreuid(0, %d) failure (real=%d, eff=%d)",
+ uid, getuid(), geteuid());
+# endif
+ else
+ sfflags |= SFF_NOPATHCHECK;
}
-#endif
}
+#endif
if (tTd(27, 9))
printf("include: new uid = %d/%d\n", getuid(), geteuid());
@@ -855,10 +995,13 @@ include(fname, forwarding, ctladdr, sendq, e)
rval = EOPENTIMEOUT;
goto resetuid;
}
- ev = setevent((time_t) 60, includetimeout, 0);
+ if (TimeOuts.to_fileopen > 0)
+ ev = setevent(TimeOuts.to_fileopen, includetimeout, 0);
+ else
+ ev = NULL;
/* the input file must be marked safe */
- rval = safefile(fname, uid, gid, uname, sfflags, S_IREAD);
+ rval = safefile(fname, uid, gid, uname, sfflags, S_IREAD, NULL);
if (rval != 0)
{
/* don't use this :include: file */
@@ -876,17 +1019,29 @@ include(fname, forwarding, ctladdr, sendq, e)
printf("include: open: %s\n", errstring(rval));
}
}
- clrevent(ev);
+ if (ev != NULL)
+ clrevent(ev);
resetuid:
-#ifdef HASSETREUID
+#if HASSETREUID || USESETEUID
if (saveduid == 0)
{
if (uid != 0)
- if (setreuid(-1, 0) < 0 || setreuid(RealUid, 0) < 0)
+ {
+# if USESETEUID
+ if (seteuid(0) < 0)
+ syserr("seteuid(0) failure (real=%d, eff=%d)",
+ getuid(), geteuid());
+# else
+ if (setreuid(-1, 0) < 0)
+ syserr("setreuid(-1, 0) failure (real=%d, eff=%d)",
+ getuid(), geteuid());
+ if (setreuid(RealUid, 0) < 0)
syserr("setreuid(%d, 0) failure (real=%d, eff=%d)",
RealUid, getuid(), geteuid());
+# endif
+ }
setgid(savedgid);
}
#endif
@@ -924,25 +1079,34 @@ resetuid:
}
else
{
- char *sh;
register struct passwd *pw;
- sh = "/SENDMAIL/ANY/SHELL/";
- pw = getpwuid(st.st_uid);
- if (pw != NULL)
- {
- ctladdr->q_ruser = newstr(pw->pw_name);
- if (safechown)
- sh = pw->pw_shell;
- }
+ pw = sm_getpwuid(st.st_uid);
if (pw == NULL)
ctladdr->q_flags |= QBOGUSSHELL;
- else if(!usershellok(sh))
+ else
{
+ char *sh;
+
+ ctladdr->q_ruser = newstr(pw->pw_name);
if (safechown)
- ctladdr->q_flags |= QBOGUSSHELL;
+ sh = pw->pw_shell;
else
- ctladdr->q_flags |= QUNSAFEADDR;
+ sh = "/SENDMAIL/ANY/SHELL/";
+ if (!usershellok(pw->pw_name, sh))
+ {
+#ifdef LOG
+ if (LogLevel >= 12)
+ syslog(LOG_INFO, "%s: user %s has bad shell %s, marked %s",
+ shortenstring(fname, 203),
+ pw->pw_name, sh,
+ safechown ? "bogus" : "unsafe");
+#endif
+ if (safechown)
+ ctladdr->q_flags |= QBOGUSSHELL;
+ else
+ ctladdr->q_flags |= QUNSAFEADDR;
+ }
}
}
@@ -966,7 +1130,15 @@ resetuid:
*/
if (bitset(S_IWOTH, st.st_mode))
+ {
+#ifdef LOG
+ if (LogLevel >= 12)
+ syslog(LOG_INFO, "%s: world writable %s file, marked unsafe",
+ shortenstring(fname, 203),
+ forwarding ? "forward" : ":include:");
+#endif
ctladdr->q_flags |= QUNSAFEADDR;
+ }
/* read the file -- each line is a comma-separated list. */
FileName = fname;
@@ -982,19 +1154,33 @@ resetuid:
*p = '\0';
if (buf[0] == '#' || buf[0] == '\0')
continue;
+
+ /* <sp>#@# introduces a comment anywhere */
+ /* for Japanese character sets */
+ for (p = buf; (p = strchr(++p, '#')) != NULL; )
+ {
+ if (p[1] == '@' && p[2] == '#' &&
+ isascii(p[-1]) && isspace(p[-1]) &&
+ (p[3] == '\0' || (isascii(p[3]) && isspace(p[3]))))
+ {
+ p[-1] = '\0';
+ break;
+ }
+ }
+ if (buf[0] == '\0')
+ continue;
+
e->e_to = NULL;
message("%s to %s",
forwarding ? "forwarding" : "sending", buf);
#ifdef LOG
if (forwarding && LogLevel > 9)
- syslog(LOG_INFO, "%s: forward %s => %s",
+ syslog(LOG_INFO, "%s: forward %.200s => %s",
e->e_id == NULL ? "NOQUEUE" : e->e_id,
- oldto, buf);
+ oldto, shortenstring(buf, 203));
#endif
- AliasLevel++;
- nincludes += sendtolist(buf, ctladdr, sendq, e);
- AliasLevel--;
+ nincludes += sendtolist(buf, ctladdr, sendq, aliaslevel + 1, e);
}
if (ferror(fp) && tTd(27, 3))
@@ -1016,7 +1202,7 @@ resetuid:
return rval;
}
-static
+static void
includetimeout()
{
longjmp(CtxIncludeTimeout, 1);
@@ -1036,6 +1222,7 @@ includetimeout()
** send queue.
*/
+void
sendtoargv(argv, e)
register char **argv;
register ENVELOPE *e;
@@ -1044,7 +1231,7 @@ sendtoargv(argv, e)
while ((p = *argv++) != NULL)
{
- (void) sendtolist(p, NULLADDR, &e->e_sendqueue, e);
+ (void) sendtolist(p, NULLADDR, &e->e_sendqueue, 0, e);
}
}
/*
@@ -1070,3 +1257,93 @@ getctladdr(a)
a = a->q_alias;
return (a);
}
+ /*
+** SELF_REFERENCE -- check to see if an address references itself
+**
+** The check is done through a chain of aliases. If it is part of
+** a loop, break the loop at the "best" address, that is, the one
+** that exists as a real user.
+**
+** This is to handle the case of:
+** awc: Andrew.Chang
+** Andrew.Chang: awc@mail.server
+** which is a problem only on mail.server.
+**
+** Parameters:
+** a -- the address to check.
+** e -- the current envelope.
+**
+** Returns:
+** The address that should be retained.
+*/
+
+ADDRESS *
+self_reference(a, e)
+ ADDRESS *a;
+ ENVELOPE *e;
+{
+ ADDRESS *b; /* top entry in self ref loop */
+ ADDRESS *c; /* entry that point to a real mail box */
+
+ if (tTd(27, 1))
+ printf("self_reference(%s)\n", a->q_paddr);
+
+ for (b = a->q_alias; b != NULL; b = b->q_alias)
+ {
+ if (sameaddr(a, b))
+ break;
+ }
+
+ if (b == NULL)
+ {
+ if (tTd(27, 1))
+ printf("\t... no self ref\n");
+ return NULL;
+ }
+
+ /*
+ ** Pick the first address that resolved to a real mail box
+ ** i.e has a pw entry. The returned value will be marked
+ ** QSELFREF in recipient(), which in turn will disable alias()
+ ** from marking it QDONTSEND, which mean it will be used
+ ** as a deliverable address.
+ **
+ ** The 2 key thing to note here are:
+ ** 1) we are in a recursive call sequence:
+ ** alias->sentolist->recipient->alias
+ ** 2) normally, when we return back to alias(), the address
+ ** will be marked QDONTSEND, since alias() assumes the
+ ** expanded form will be used instead of the current address.
+ ** This behaviour is turned off if the address is marked
+ ** QSELFREF We set QSELFREF when we return to recipient().
+ */
+
+ c = a;
+ while (c != NULL)
+ {
+ if (bitnset(M_HASPWENT, c->q_mailer->m_flags))
+ {
+ if (tTd(27, 2))
+ printf("\t... getpwnam(%s)... ", c->q_user);
+ if (sm_getpwnam(c->q_user) != NULL)
+ {
+ if (tTd(27, 2))
+ printf("found\n");
+
+ /* ought to cache results here */
+ if (sameaddr(b, c))
+ return b;
+ else
+ return c;
+ }
+ if (tTd(27, 2))
+ printf("failed\n");
+ }
+ c = c->q_alias;
+ }
+
+ if (tTd(27, 1))
+ printf("\t... cannot break loop for \"%s\"\n", a->q_paddr);
+
+ return NULL;
+}
diff --git a/usr.sbin/sendmail/src/savemail.c b/usr.sbin/sendmail/src/savemail.c
index 65c915d..9898cdd 100644
--- a/usr.sbin/sendmail/src/savemail.c
+++ b/usr.sbin/sendmail/src/savemail.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -33,11 +33,10 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)savemail.c 8.29 (Berkeley) 5/10/94";
+static char sccsid[] = "@(#)savemail.c 8.87 (Berkeley) 10/28/95";
#endif /* not lint */
# include "sendmail.h"
-# include <pwd.h>
/*
** SAVEMAIL -- Save mail on error
@@ -49,6 +48,8 @@ static char sccsid[] = "@(#)savemail.c 8.29 (Berkeley) 5/10/94";
**
** Parameters:
** e -- the envelope containing the message in error.
+** sendbody -- if TRUE, also send back the body of the
+** message; otherwise just send the header.
**
** Returns:
** none
@@ -74,8 +75,10 @@ static char sccsid[] = "@(#)savemail.c 8.29 (Berkeley) 5/10/94";
# endif
-savemail(e)
+void
+savemail(e, sendbody)
register ENVELOPE *e;
+ bool sendbody;
{
register struct passwd *pw;
register FILE *fp;
@@ -83,8 +86,8 @@ savemail(e)
auto ADDRESS *q = NULL;
register char *p;
MCI mcibuf;
+ int sfflags;
char buf[MAXLINE+1];
- extern struct passwd *getpwnam();
extern char *ttypath();
typedef int (*fnptr)();
extern bool writable();
@@ -143,11 +146,6 @@ savemail(e)
break;
case EM_BERKNET:
- /* mail back, but return o.k. exit status */
- ExitStat = EX_OK;
-
- /* fall through.... */
-
case EM_MAIL:
state = ESM_MAIL;
break;
@@ -187,7 +185,7 @@ savemail(e)
switch (state)
{
case ESM_QUIET:
- if (e->e_from.q_mailer == LocalMailer)
+ if (bitnset(M_LOCALMAILER, e->e_from.q_mailer->m_flags))
state = ESM_DEADLETTER;
else
state = ESM_MAIL;
@@ -207,7 +205,7 @@ savemail(e)
break;
}
- expand("\201n", buf, &buf[sizeof buf - 1], e);
+ expand("\201n", buf, sizeof buf, e);
printf("\r\nMessage from %s...\r\n", buf);
printf("Errors occurred while sending mail.\r\n");
if (e->e_xfp != NULL)
@@ -256,12 +254,12 @@ savemail(e)
if (ExitStat == EX_CONFIG || ExitStat == EX_SOFTWARE)
{
(void) sendtolist("postmaster",
- NULLADDR, &e->e_errorqueue, e);
+ NULLADDR, &e->e_errorqueue, 0, e);
}
- if (strcmp(e->e_from.q_paddr, "<>") != 0)
+ if (!emptyaddr(&e->e_from))
{
(void) sendtolist(e->e_from.q_paddr,
- NULLADDR, &e->e_errorqueue, e);
+ NULLADDR, &e->e_errorqueue, 0, e);
}
/*
@@ -285,7 +283,7 @@ savemail(e)
break;
}
if (returntosender(e->e_message, e->e_errorqueue,
- (e->e_class >= 0), e) == 0)
+ sendbody, e) == 0)
{
state = ESM_DONE;
break;
@@ -301,15 +299,14 @@ savemail(e)
*/
q = NULL;
- if (sendtolist("postmaster", NULL, &q, e) <= 0)
+ if (sendtolist("postmaster", NULL, &q, 0, e) <= 0)
{
syserr("553 cannot parse postmaster!");
ExitStat = EX_SOFTWARE;
state = ESM_USRTMP;
break;
}
- if (returntosender(e->e_message,
- q, (e->e_class >= 0), e) == 0)
+ if (returntosender(e->e_message, q, sendbody, e) == 0)
{
state = ESM_DONE;
break;
@@ -330,44 +327,36 @@ savemail(e)
*/
p = NULL;
- if (e->e_from.q_mailer == LocalMailer)
+ if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags))
{
if (e->e_from.q_home != NULL)
p = e->e_from.q_home;
- else if ((pw = getpwnam(e->e_from.q_user)) != NULL)
+ else if ((pw = sm_getpwnam(e->e_from.q_user)) != NULL)
p = pw->pw_dir;
}
- if (p == NULL)
+ if (p == NULL || e->e_dfp == NULL)
{
- /* no local directory */
+ /* no local directory or no data file */
state = ESM_MAIL;
break;
}
- if (e->e_dfp != NULL)
+
+ /* we have a home directory; write dead.letter */
+ define('z', p, e);
+ expand("\201z/dead.letter", buf, sizeof buf, e);
+ sfflags = SFF_NOSLINK|SFF_CREAT|SFF_REGONLY|SFF_RUNASREALUID;
+ e->e_to = buf;
+ if (mailfile(buf, NULL, sfflags, e) == EX_OK)
{
bool oldverb = Verbose;
- /* we have a home directory; open dead.letter */
- define('z', p, e);
- expand("\201z/dead.letter", buf, &buf[sizeof buf - 1], e);
Verbose = TRUE;
- message("Saving message in %s", buf);
+ message("Saved message in %s", buf);
Verbose = oldverb;
- e->e_to = buf;
- q = NULL;
- (void) sendtolist(buf, &e->e_from, &q, e);
- if (q != NULL &&
- !bitset(QBADADDR, q->q_flags) &&
- deliver(e, q) == 0)
- state = ESM_DONE;
- else
- state = ESM_MAIL;
- }
- else
- {
- /* no data file -- try mailing back */
- state = ESM_MAIL;
+ state = ESM_DONE;
+ break;
}
+ state = ESM_MAIL;
break;
case ESM_USRTMP:
@@ -381,15 +370,19 @@ savemail(e)
break;
}
- strcpy(buf, _PATH_VARTMP);
- strcat(buf, "dead.letter");
- if (!writable(buf, NULLADDR, SFF_NOSLINK))
+ if (SafeFileEnv != NULL && SafeFileEnv[0] != '\0')
{
state = ESM_PANIC;
break;
}
- fp = dfopen(buf, O_WRONLY|O_CREAT|O_APPEND, FileMode);
- if (fp == NULL)
+
+ strcpy(buf, _PATH_VARTMP);
+ strcat(buf, "dead.letter");
+
+ sfflags = SFF_NOSLINK|SFF_CREAT|SFF_REGONLY|SFF_ROOTOK|SFF_OPENASROOT;
+ if (!writable(buf, NULL, sfflags) ||
+ (fp = safefopen(buf, O_WRONLY|O_CREAT|O_APPEND,
+ FileMode, sfflags)) == NULL)
{
state = ESM_PANIC;
break;
@@ -402,13 +395,26 @@ savemail(e)
mcibuf.mci_flags |= MCIF_7BIT;
putfromline(&mcibuf, e);
- (*e->e_puthdr)(&mcibuf, e);
- putline("\n", &mcibuf);
+ (*e->e_puthdr)(&mcibuf, e->e_header, e);
(*e->e_putbody)(&mcibuf, e, NULL);
putline("\n", &mcibuf);
(void) fflush(fp);
- state = ferror(fp) ? ESM_PANIC : ESM_DONE;
- (void) xfclose(fp, "savemail", "/usr/tmp/dead.letter");
+ if (!ferror(fp))
+ {
+ bool oldverb = Verbose;
+
+ Verbose = TRUE;
+ message("Saved message in %s", buf);
+ Verbose = oldverb;
+#ifdef LOG
+ if (LogLevel > 3)
+ syslog(LOG_NOTICE, "Saved message in %s", buf);
+#endif
+ state = ESM_DONE;
+ break;
+ }
+ state = ESM_PANIC;
+ (void) xfclose(fp, "savemail", buf);
break;
default:
@@ -418,6 +424,7 @@ savemail(e)
case ESM_PANIC:
/* leave the locked queue & transcript files around */
+ loseqfile(e, "savemail panic");
syserr("!554 savemail: cannot save rejected email anywhere");
}
}
@@ -441,24 +448,24 @@ savemail(e)
** mail.
*/
-static bool SendBody;
-
#define MAXRETURNS 6 /* max depth of returning messages */
#define ERRORFUDGE 100 /* nominal size of error message text */
+int
returntosender(msg, returnq, sendbody, e)
char *msg;
ADDRESS *returnq;
bool sendbody;
register ENVELOPE *e;
{
- char buf[MAXNAME];
- extern putheader(), errbody();
register ENVELOPE *ee;
ENVELOPE *oldcur = CurEnv;
ENVELOPE errenvelope;
static int returndepth;
register ADDRESS *q;
+ char *p;
+ char buf[MAXNAME + 1];
+ extern void errbody __P((MCI *, ENVELOPE *, char *));
if (returnq == NULL)
return (-1);
@@ -468,9 +475,14 @@ returntosender(msg, returnq, sendbody, e)
if (tTd(6, 1))
{
- printf("Return To Sender: msg=\"%s\", depth=%d, e=%x, returnq=",
+ printf("\n*** Return To Sender: msg=\"%s\", depth=%d, e=%x, returnq=",
msg, returndepth, e);
printaddr(returnq, TRUE);
+ if (tTd(6, 20))
+ {
+ printf("Sendq=");
+ printaddr(e->e_sendqueue, TRUE);
+ }
}
if (++returndepth >= MAXRETURNS)
@@ -482,9 +494,10 @@ returntosender(msg, returnq, sendbody, e)
return (0);
}
- SendBody = sendbody;
define('g', e->e_from.q_paddr, e);
define('u', NULL, e);
+
+ /* initialize error envelope */
ee = newenvelope(&errenvelope, e);
define('a', "\201b", ee);
define('r', "internal", ee);
@@ -497,45 +510,97 @@ returntosender(msg, returnq, sendbody, e)
ee->e_flags &= ~EF_OLDSTYLE;
ee->e_sendqueue = returnq;
ee->e_msgsize = ERRORFUDGE;
- if (!NoReturn)
+ if (sendbody)
ee->e_msgsize += e->e_msgsize;
+ else
+ ee->e_flags |= EF_NO_BODY_RETN;
initsys(ee);
for (q = returnq; q != NULL; q = q->q_next)
{
if (bitset(QBADADDR, q->q_flags))
continue;
- if (!bitset(QDONTSEND, q->q_flags))
- ee->e_nrcpts++;
-
if (!DontPruneRoutes && pruneroute(q->q_paddr))
+ {
+ register ADDRESS *p;
+
parseaddr(q->q_paddr, q, RF_COPYPARSE, '\0', NULL, e);
+ for (p = returnq; p != NULL; p = p->q_next)
+ {
+ if (p != q && sameaddr(p, q))
+ q->q_flags |= QDONTSEND;
+ }
+ }
+
+ if (!bitset(QDONTSEND, q->q_flags))
+ ee->e_nrcpts++;
if (q->q_alias == NULL)
- addheader("To", q->q_paddr, ee);
+ addheader("To", q->q_paddr, &ee->e_header);
}
# ifdef LOG
if (LogLevel > 5)
- syslog(LOG_INFO, "%s: %s: return to sender: %s",
- e->e_id, ee->e_id, msg);
+ {
+ if (bitset(EF_RESPONSE|EF_WARNING, e->e_flags))
+ p = "return to sender";
+ else
+ p = "postmaster notify";
+ syslog(LOG_INFO, "%s: %s: %s: %s",
+ e->e_id, ee->e_id, p, shortenstring(msg, 203));
+ }
# endif
- (void) sprintf(buf, "Returned mail: %.*s", sizeof buf - 20, msg);
- addheader("Subject", buf, ee);
if (SendMIMEErrors)
{
- addheader("MIME-Version", "1.0", ee);
- (void) sprintf(buf, "%s.%ld/%s",
+ addheader("MIME-Version", "1.0", &ee->e_header);
+
+ (void) sprintf(buf, "%s.%ld/%.100s",
ee->e_id, curtime(), MyHostName);
ee->e_msgboundary = newstr(buf);
- (void) sprintf(buf, "multipart/mixed; boundary=\"%s\"",
- ee->e_msgboundary);
- addheader("Content-Type", buf, ee);
+ (void) sprintf(buf,
+#if DSN
+ "multipart/report; report-type=delivery-status;\n\tboundary=\"%s\"",
+#else
+ "multipart/mixed; boundary=\"%s\"",
+#endif
+ ee->e_msgboundary);
+ addheader("Content-Type", buf, &ee->e_header);
+
+ p = hvalue("Content-Transfer-Encoding", e->e_header);
+ if (p != NULL && strcasecmp(p, "binary") != 0)
+ p = NULL;
+ if (p == NULL && bitset(EF_HAS8BIT, e->e_flags))
+ p = "8bit";
+ if (p != NULL)
+ addheader("Content-Transfer-Encoding", p, &ee->e_header);
+ }
+ if (strncmp(msg, "Warning:", 8) == 0)
+ {
+ addheader("Subject", msg, &ee->e_header);
+ p = "warning-timeout";
+ }
+ else if (strncmp(msg, "Postmaster warning:", 19) == 0)
+ {
+ addheader("Subject", msg, &ee->e_header);
+ p = "postmaster-warning";
+ }
+ else if (strcmp(msg, "Return receipt") == 0)
+ {
+ addheader("Subject", msg, &ee->e_header);
+ p = "return-receipt";
+ }
+ else
+ {
+ sprintf(buf, "Returned mail: %.*s", sizeof buf - 20, msg);
+ addheader("Subject", buf, &ee->e_header);
+ p = "failure";
}
+ (void) sprintf(buf, "auto-generated (%s)", p);
+ addheader("Auto-Submitted", buf, &ee->e_header);
/* fake up an address header for the from person */
- expand("\201n", buf, &buf[sizeof buf - 1], e);
+ expand("\201n", buf, sizeof buf, e);
if (parseaddr(buf, &ee->e_from, RF_COPYALL|RF_SENDERADDR, '\0', NULL, e) == NULL)
{
syserr("553 Can't parse myself!");
@@ -562,8 +627,15 @@ returntosender(msg, returnq, sendbody, e)
CurEnv = oldcur;
returndepth--;
- /* should check for delivery errors here */
- return (0);
+ /* check for delivery errors */
+ if (ee->e_parent == NULL || !bitset(EF_RESPONSE, ee->e_parent->e_flags))
+ return 0;
+ for (q = ee->e_sendqueue; q != NULL; q = q->q_next)
+ {
+ if (bitset(QSENT, q->q_flags))
+ return 0;
+ }
+ return -1;
}
/*
** ERRBODY -- output the body of an error message.
@@ -574,6 +646,8 @@ returntosender(msg, returnq, sendbody, e)
** Parameters:
** mci -- the mailer connection information.
** e -- the envelope we are working in.
+** separator -- any possible MIME separator.
+** flags -- to modify the behaviour.
**
** Returns:
** none
@@ -582,16 +656,25 @@ returntosender(msg, returnq, sendbody, e)
** Outputs the body of an error message.
*/
-errbody(mci, e)
+void
+errbody(mci, e, separator)
register MCI *mci;
register ENVELOPE *e;
+ char *separator;
{
register FILE *xfile;
char *p;
register ADDRESS *q;
bool printheader;
+ bool sendbody;
char buf[MAXLINE];
+ extern char *xuntextify();
+ if (bitset(MCIF_INHEADER, mci->mci_flags))
+ {
+ putline("", mci);
+ mci->mci_flags &= ~MCIF_INHEADER;
+ }
if (e->e_parent == NULL)
{
syserr("errbody: null parent");
@@ -635,7 +718,7 @@ errbody(mci, e)
sprintf(buf, "The original message was received at %s",
arpadate(ctime(&e->e_parent->e_ctime)));
putline(buf, mci);
- expand("from \201_", buf, &buf[sizeof buf - 1], e->e_parent);
+ expand("from \201_", buf, sizeof buf, e->e_parent);
putline(buf, mci);
putline("", mci);
@@ -643,7 +726,7 @@ errbody(mci, e)
** Output error message header (if specified and available).
*/
- if (ErrMsgFile != NULL)
+ if (ErrMsgFile != NULL && !bitset(EF_SENDRECEIPT, e->e_parent->e_flags))
{
if (*ErrMsgFile == '/')
{
@@ -652,7 +735,7 @@ errbody(mci, e)
{
while (fgets(buf, sizeof buf, xfile) != NULL)
{
- expand(buf, buf, &buf[sizeof buf - 1], e);
+ expand(buf, buf, sizeof buf, e);
putline(buf, mci);
}
(void) fclose(xfile);
@@ -661,7 +744,7 @@ errbody(mci, e)
}
else
{
- expand(ErrMsgFile, buf, &buf[sizeof buf - 1], e);
+ expand(ErrMsgFile, buf, sizeof buf, e);
putline(buf, mci);
putline("", mci);
}
@@ -674,27 +757,46 @@ errbody(mci, e)
printheader = TRUE;
for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
{
- if (bitset(QBADADDR|QREPORT, q->q_flags))
+ if (bitset(QBADADDR, q->q_flags))
{
- if (printheader)
- {
- putline(" ----- The following addresses had delivery problems -----",
- mci);
- printheader = FALSE;
- }
- strcpy(buf, q->q_paddr);
- if (bitset(QBADADDR, q->q_flags))
- strcat(buf, " (unrecoverable error)");
+ if (!bitset(QPINGONFAILURE, q->q_flags))
+ continue;
+ p = "unrecoverable error";
+ }
+ else if (!bitset(QPRIMARY, q->q_flags))
+ continue;
+ else if (bitset(QDELAYED, q->q_flags))
+ p = "transient failure";
+ else if (!bitset(QPINGONSUCCESS, q->q_flags))
+ continue;
+ else if (bitset(QRELAYED, q->q_flags))
+ p = "relayed to non-DSN-aware mailer";
+ else if (bitset(QDELIVERED, q->q_flags))
+ {
+ if (bitset(QEXPANDED, q->q_flags))
+ p = "successfully delivered to mailing list";
else
- strcat(buf, " (transient failure)");
+ p = "successfully delivered to mailbox";
+ }
+ else if (bitset(QEXPANDED, q->q_flags))
+ p = "expanded by alias";
+ else
+ continue;
+
+ if (printheader)
+ {
+ putline(" ----- The following addresses have delivery notifications -----",
+ mci);
+ printheader = FALSE;
+ }
+
+ sprintf(buf, "%s (%s)", shortenstring(q->q_paddr, 203), p);
+ putline(buf, mci);
+ if (q->q_alias != NULL)
+ {
+ sprintf(buf, " (expanded from: %s)",
+ shortenstring(q->q_alias->q_paddr, 203));
putline(buf, mci);
- if (q->q_alias != NULL)
- {
- strcpy(buf, " (expanded from: ");
- strcat(buf, q->q_alias->q_paddr);
- strcat(buf, ")");
- putline(buf, mci);
- }
}
}
if (!printheader)
@@ -713,46 +815,256 @@ errbody(mci, e)
}
else
{
- putline(" ----- Transcript of session follows -----\n", mci);
+ printheader = TRUE;
if (e->e_xfp != NULL)
(void) fflush(e->e_xfp);
while (fgets(buf, sizeof buf, xfile) != NULL)
+ {
+ if (printheader)
+ putline(" ----- Transcript of session follows -----\n", mci);
+ printheader = FALSE;
putline(buf, mci);
+ }
(void) xfclose(xfile, "errbody xscript", p);
}
errno = 0;
+#if DSN
+ /*
+ ** Output machine-readable version.
+ */
+
+ if (e->e_msgboundary != NULL)
+ {
+ putline("", mci);
+ (void) sprintf(buf, "--%s", e->e_msgboundary);
+ putline(buf, mci);
+ putline("Content-Type: message/delivery-status", mci);
+ putline("", mci);
+
+ /*
+ ** Output per-message information.
+ */
+
+ /* original envelope id from MAIL FROM: line */
+ if (e->e_parent->e_envid != NULL)
+ {
+ (void) sprintf(buf, "Original-Envelope-Id: %.800s",
+ xuntextify(e->e_parent->e_envid));
+ putline(buf, mci);
+ }
+
+ /* Reporting-MTA: is us (required) */
+ (void) sprintf(buf, "Reporting-MTA: dns; %.800s", MyHostName);
+ putline(buf, mci);
+
+ /* DSN-Gateway: not relevant since we are not translating */
+
+ /* Received-From-MTA: shows where we got this message from */
+ if (RealHostName != NULL)
+ {
+ /* XXX use $s for type? */
+ if (e->e_parent->e_from.q_mailer == NULL ||
+ (p = e->e_parent->e_from.q_mailer->m_mtatype) == NULL)
+ p = "dns";
+ (void) sprintf(buf, "Received-From-MTA: %s; %.800s",
+ p, RealHostName);
+ putline(buf, mci);
+ }
+
+ /* Arrival-Date: -- when it arrived here */
+ (void) sprintf(buf, "Arrival-Date: %s",
+ arpadate(ctime(&e->e_parent->e_ctime)));
+ putline(buf, mci);
+
+ /*
+ ** Output per-address information.
+ */
+
+ for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
+ {
+ register ADDRESS *r;
+ char *action;
+
+ if (bitset(QBADADDR, q->q_flags))
+ action = "failed";
+ else if (!bitset(QPRIMARY, q->q_flags))
+ continue;
+ else if (bitset(QDELIVERED, q->q_flags))
+ {
+ if (bitset(QEXPANDED, q->q_flags))
+ action = "delivered (to mailing list)";
+ else
+ action = "delivered (to mailbox)";
+ }
+ else if (bitset(QRELAYED, q->q_flags))
+ action = "relayed (to non-DSN-aware mailer)";
+ else if (bitset(QEXPANDED, q->q_flags))
+ action = "expanded (to multi-recipient alias)";
+ else if (bitset(QDELAYED, q->q_flags))
+ action = "delayed";
+ else
+ continue;
+
+ putline("", mci);
+
+ /* Original-Recipient: -- passed from on high */
+ if (q->q_orcpt != NULL)
+ {
+ (void) sprintf(buf, "Original-Recipient: %.800s",
+ q->q_orcpt);
+ putline(buf, mci);
+ }
+
+ /* Final-Recipient: -- the name from the RCPT command */
+ p = e->e_parent->e_from.q_mailer->m_addrtype;
+ if (p == NULL)
+ p = "rfc822";
+ for (r = q; r->q_alias != NULL; r = r->q_alias)
+ continue;
+ if (strchr(r->q_user, '@') == NULL)
+ {
+ (void) sprintf(buf, "Final-Recipient: %s; %.700s@%.100s",
+ p, r->q_user, MyHostName);
+ }
+ else
+ {
+ (void) sprintf(buf, "Final-Recipient: %s; %.800s",
+ p, r->q_user);
+ }
+ putline(buf, mci);
+
+ /* X-Actual-Recipient: -- the real problem address */
+ if (r != q && q->q_user[0] != '\0')
+ {
+ if (strchr(q->q_user, '@') == NULL)
+ {
+ (void) sprintf(buf, "X-Actual-Recipient: %s; %.700s@%.100s",
+ p, q->q_user, MyHostName);
+ }
+ else
+ {
+ (void) sprintf(buf, "X-Actual-Recipient: %s; %.800s",
+ p, q->q_user);
+ }
+ putline(buf, mci);
+ }
+
+ /* Action: -- what happened? */
+ sprintf(buf, "Action: %s", action);
+ putline(buf, mci);
+
+ /* Status: -- what _really_ happened? */
+ strcpy(buf, "Status: ");
+ if (q->q_status != NULL)
+ strcat(buf, q->q_status);
+ else if (bitset(QBADADDR, q->q_flags))
+ strcat(buf, "5.0.0");
+ else if (bitset(QQUEUEUP, q->q_flags))
+ strcat(buf, "4.0.0");
+ else
+ strcat(buf, "2.0.0");
+ putline(buf, mci);
+
+ /* Remote-MTA: -- who was I talking to? */
+ if (q->q_statmta != NULL)
+ {
+ if (q->q_mailer == NULL ||
+ (p = q->q_mailer->m_mtatype) == NULL)
+ p = "dns";
+ (void) sprintf(buf, "Remote-MTA: %s; %.800s",
+ p, q->q_statmta);
+ p = &buf[strlen(buf) - 1];
+ if (*p == '.')
+ *p = '\0';
+ putline(buf, mci);
+ }
+
+ /* Diagnostic-Code: -- actual result from other end */
+ if (q->q_rstatus != NULL)
+ {
+ p = q->q_mailer->m_diagtype;
+ if (p == NULL)
+ p = "smtp";
+ (void) sprintf(buf, "Diagnostic-Code: %s; %.800s",
+ p, q->q_rstatus);
+ putline(buf, mci);
+ }
+
+ /* Last-Attempt-Date: -- fine granularity */
+ if (q->q_statdate == (time_t) 0L)
+ q->q_statdate = curtime();
+ (void) sprintf(buf, "Last-Attempt-Date: %s",
+ arpadate(ctime(&q->q_statdate)));
+ putline(buf, mci);
+
+ /* Will-Retry-Until: -- for delayed messages only */
+ if (bitset(QQUEUEUP, q->q_flags) &&
+ !bitset(QBADADDR, q->q_flags))
+ {
+ time_t xdate;
+
+ xdate = e->e_parent->e_ctime +
+ TimeOuts.to_q_return[e->e_parent->e_timeoutclass];
+ sprintf(buf, "Will-Retry-Until: %s",
+ arpadate(ctime(&xdate)));
+ putline(buf, mci);
+ }
+ }
+ }
+#endif
+
/*
** Output text of original message
*/
- if (NoReturn)
- SendBody = FALSE;
putline("", mci);
- if (e->e_parent->e_df != NULL)
+ if (bitset(EF_HAS_DF, e->e_parent->e_flags))
{
- if (SendBody)
- putline(" ----- Original message follows -----\n", mci);
- else
- putline(" ----- Message header follows -----\n", mci);
- (void) fflush(mci->mci_out);
+ sendbody = !bitset(EF_NO_BODY_RETN, e->e_parent->e_flags) &&
+ !bitset(EF_NO_BODY_RETN, e->e_flags);
- if (e->e_msgboundary != NULL)
+ if (e->e_msgboundary == NULL)
+ {
+ if (sendbody)
+ putline(" ----- Original message follows -----\n", mci);
+ else
+ putline(" ----- Message header follows -----\n", mci);
+ (void) fflush(mci->mci_out);
+ }
+ else
{
- putline("", mci);
(void) sprintf(buf, "--%s", e->e_msgboundary);
+
putline(buf, mci);
- putline("Content-Type: message/rfc822", mci);
- putline("", mci);
+ (void) sprintf(buf, "Content-Type: %s",
+ sendbody ? "message/rfc822"
+ : "text/rfc822-headers");
+ putline(buf, mci);
+
+ p = hvalue("Content-Transfer-Encoding", e->e_parent->e_header);
+ if (p != NULL && strcasecmp(p, "binary") != 0)
+ p = NULL;
+ if (p == NULL && bitset(EF_HAS8BIT, e->e_parent->e_flags))
+ p = "8bit";
+ if (p != NULL)
+ {
+ (void) sprintf(buf, "Content-Transfer-Encoding: %s",
+ p);
+ putline(buf, mci);
+ }
}
- putheader(mci, e->e_parent);
putline("", mci);
- if (SendBody)
+ putheader(mci, e->e_parent->e_header, e->e_parent);
+ if (sendbody)
putbody(mci, e->e_parent, e->e_msgboundary);
- else
+ else if (e->e_msgboundary == NULL)
+ {
+ putline("", mci);
putline(" ----- Message body suppressed -----", mci);
+ }
}
- else
+ else if (e->e_msgboundary == NULL)
{
putline(" ----- No message was collected -----\n", mci);
}
@@ -773,8 +1085,250 @@ errbody(mci, e)
syserr("errbody: I/O error");
}
/*
-** PRUNEROUTE -- prune an RFC-822 source route
+** SMTPTODSN -- convert SMTP to DSN status code
**
+** Parameters:
+** smtpstat -- the smtp status code (e.g., 550).
+**
+** Returns:
+** The DSN version of the status code.
+*/
+
+char *
+smtptodsn(smtpstat)
+ int smtpstat;
+{
+ if (smtpstat < 0)
+ return "4.4.2";
+
+ switch (smtpstat)
+ {
+ case 450: /* Req mail action not taken: mailbox unavailable */
+ return "4.2.0";
+
+ case 451: /* Req action aborted: local error in processing */
+ return "4.3.0";
+
+ case 452: /* Req action not taken: insufficient sys storage */
+ return "4.3.1";
+
+ case 500: /* Syntax error, command unrecognized */
+ return "5.5.2";
+
+ case 501: /* Syntax error in parameters or arguments */
+ return "5.5.4";
+
+ case 502: /* Command not implemented */
+ return "5.5.1";
+
+ case 503: /* Bad sequence of commands */
+ return "5.5.1";
+
+ case 504: /* Command parameter not implemented */
+ return "5.5.4";
+
+ case 550: /* Req mail action not taken: mailbox unavailable */
+ return "5.2.0";
+
+ case 551: /* User not local; please try <...> */
+ return "5.1.6";
+
+ case 552: /* Req mail action aborted: exceeded storage alloc */
+ return "5.2.2";
+
+ case 553: /* Req action not taken: mailbox name not allowed */
+ return "5.1.3";
+
+ case 554: /* Transaction failed */
+ return "5.0.0";
+ }
+
+ if ((smtpstat / 100) == 2)
+ return "2.0.0";
+ if ((smtpstat / 100) == 4)
+ return "4.0.0";
+ return "5.0.0";
+}
+ /*
+** XTEXTIFY -- take regular text and turn it into DSN-style xtext
+**
+** Parameters:
+** t -- the text to convert.
+**
+** Returns:
+** The xtext-ified version of the same string.
+*/
+
+char *
+xtextify(t)
+ register char *t;
+{
+ register char *p;
+ int l;
+ int nbogus;
+ static char *bp = NULL;
+ static int bplen = 0;
+
+ /* figure out how long this xtext will have to be */
+ nbogus = l = 0;
+ for (p = t; *p != '\0'; p++)
+ {
+ register int c = (*p & 0xff);
+
+ /* ASCII dependence here -- this is the way the spec words it */
+ if (c < '!' || c > '~' || c == '+' || c == '\\' || c == '(')
+ nbogus++;
+ l++;
+ }
+ if (nbogus == 0)
+ return t;
+ l += nbogus * 2 + 1;
+
+ /* now allocate space if necessary for the new string */
+ if (l > bplen)
+ {
+ if (bp != NULL)
+ free(bp);
+ bp = xalloc(l);
+ bplen = l;
+ }
+
+ /* ok, copy the text with byte expansion */
+ for (p = bp; *t != '\0'; )
+ {
+ register int c = (*t++ & 0xff);
+
+ /* ASCII dependence here -- this is the way the spec words it */
+ if (c < '!' || c > '~' || c == '+' || c == '\\' || c == '(')
+ {
+ *p++ = '+';
+ *p++ = "0123456789abcdef"[c >> 4];
+ *p++ = "0123456789abcdef"[c & 0xf];
+ }
+ else
+ *p++ = c;
+ }
+ *p = '\0';
+ return bp;
+}
+ /*
+** XUNTEXTIFY -- take xtext and turn it into plain text
+**
+** Parameters:
+** t -- the xtextified text.
+**
+** Returns:
+** The decoded text. No attempt is made to deal with
+** null strings in the resulting text.
+*/
+
+char *
+xuntextify(t)
+ register char *t;
+{
+ register char *p;
+ int l;
+ static char *bp = NULL;
+ static int bplen = 0;
+
+ /* heuristic -- if no plus sign, just return the input */
+ if (strchr(t, '+') == NULL)
+ return t;
+
+ /* xtext is always longer than decoded text */
+ l = strlen(t);
+ if (l > bplen)
+ {
+ if (bp != NULL)
+ free(bp);
+ bp = xalloc(l);
+ bplen = l;
+ }
+
+ /* ok, copy the text with byte compression */
+ for (p = bp; *t != '\0'; t++)
+ {
+ register int c = *t & 0xff;
+
+ if (c != '+')
+ {
+ *p++ = c;
+ continue;
+ }
+
+ c = *++t & 0xff;
+ if (!isascii(c) || !isxdigit(c))
+ {
+ /* error -- first digit is not hex */
+ usrerr("bogus xtext: +%c", c);
+ t--;
+ continue;
+ }
+ if (isdigit(c))
+ c -= '0';
+ else if (isupper(c))
+ c -= 'A' - 10;
+ else
+ c -= 'a' - 10;
+ *p = c << 4;
+
+ c = *++t & 0xff;
+ if (!isascii(c) || !isxdigit(c))
+ {
+ /* error -- second digit is not hex */
+ usrerr("bogus xtext: +%x%c", *p >> 4, c);
+ t--;
+ continue;
+ }
+ if (isdigit(c))
+ c -= '0';
+ else if (isupper(c))
+ c -= 'A' - 10;
+ else
+ c -= 'a' - 10;
+ *p++ |= c;
+ }
+ return bp;
+}
+ /*
+** XTEXTOK -- check if a string is legal xtext
+**
+** Xtext is used in Delivery Status Notifications. The spec was
+** taken from draft-ietf-notary-mime-delivery-04.txt.
+**
+** Parameters:
+** s -- the string to check.
+**
+** Returns:
+** TRUE -- if 's' is legal xtext.
+** FALSE -- if it has any illegal characters in it.
+*/
+
+bool
+xtextok(s)
+ char *s;
+{
+ int c;
+
+ while ((c = *s++) != '\0')
+ {
+ if (c == '+')
+ {
+ c = *s++;
+ if (!isascii(c) || !isxdigit(c))
+ return FALSE;
+ c = *s++;
+ if (!isascii(c) || !isxdigit(c))
+ return FALSE;
+ }
+ else if (c < '!' || c > '~' || c == '=')
+ return FALSE;
+ }
+ return TRUE;
+}
+ /*
+** PRUNEROUTE -- prune an RFC-822 source route
+**
** Trims down a source route to the last internet-registered hop.
** This is encouraged by RFC 1123 section 5.3.3.
**
@@ -789,6 +1343,7 @@ errbody(mci, e)
** modifies addr in-place
*/
+bool
pruneroute(addr)
char *addr;
{
diff --git a/usr.sbin/sendmail/src/sendmail.8 b/usr.sbin/sendmail/src/sendmail.8
index f03d3de..5b48ffc 100644
--- a/usr.sbin/sendmail/src/sendmail.8
+++ b/usr.sbin/sendmail/src/sendmail.8
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)sendmail.8 8.4 (Berkeley) 12/11/93
+.\" @(#)sendmail.8 8.6 (Berkeley) 5/27/95
.\"
-.Dd December 11, 1993
+.Dd May 27, 1995
.Dt SENDMAIL 8
.Os BSD 4
.Sh NAME
@@ -209,6 +209,18 @@ is specified,
will run in background.
This option can be used safely with
.Fl bd .
+.It Fl qI Ns Ar substr
+Limit processed jobs to those containing
+.Ar substr
+as a substring of the queue id.
+.It Fl qR Ns Ar substr
+Limit processed jobs to those containing
+.Ar substr
+as a substring of one of the recipients.
+.It Fl qS Ns Ar substr
+Limit processed jobs to those containing
+.Ar substr
+as a substring of the sender.
.It Fl r Ns Ar name
An alternate and obsolete form of the
.Fl f
@@ -259,6 +271,7 @@ successful deliveries (default 10).
This avoids excessive duplicate deliveries
when sending to long mailing lists
interrupted by system crashes.
+.ne 1i
.It Li d Ns Ar x
Set the delivery mode to
.Ar x .
diff --git a/usr.sbin/sendmail/src/sendmail.h b/usr.sbin/sendmail/src/sendmail.h
index e61ebfb..66c7576 100644
--- a/usr.sbin/sendmail/src/sendmail.h
+++ b/usr.sbin/sendmail/src/sendmail.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -31,7 +31,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)sendmail.h 8.43.1.3 (Berkeley) 3/5/95
+ * @(#)sendmail.h 8.159 (Berkeley) 11/18/95
*/
/*
@@ -41,7 +41,7 @@
# ifdef _DEFINE
# define EXTERN
# ifndef lint
-static char SmailSccsId[] = "@(#)sendmail.h 8.43.1.3 3/5/95";
+static char SmailSccsId[] = "@(#)sendmail.h 8.159 11/18/95";
# endif
# else /* _DEFINE */
# define EXTERN extern
@@ -53,10 +53,13 @@ static char SmailSccsId[] = "@(#)sendmail.h 8.43.1.3 3/5/95";
# include <stdio.h>
# include <ctype.h>
# include <setjmp.h>
-# include <sysexits.h>
# include <string.h>
# include <time.h>
# include <errno.h>
+# ifdef EX_OK
+# undef EX_OK /* for SVr4.2 SMP */
+# endif
+# include <sysexits.h>
# include "conf.h"
# include "useful.h"
@@ -68,38 +71,42 @@ static char SmailSccsId[] = "@(#)sendmail.h 8.43.1.3 3/5/95";
# ifdef DAEMON
# include <sys/socket.h>
# endif
-# ifdef NETUNIX
+# if NETUNIX
# include <sys/un.h>
# endif
-# ifdef NETINET
+# if NETINET
# include <netinet/in.h>
# endif
-# ifdef NETISO
+# if NETISO
# include <netiso/iso.h>
# endif
-# ifdef NETNS
+# if NETNS
# include <netns/ns.h>
# endif
-# ifdef NETX25
+# if NETX25
# include <netccitt/x25.h>
# endif
+/* forward references for prototypes */
+typedef struct envelope ENVELOPE;
+typedef struct mailer MAILER;
+
/*
** Data structure for bit maps.
**
** Each bit in this map can be referenced by an ascii character.
-** This is 128 possible bits, or 12 8-bit bytes.
+** This is 256 possible bits, or 32 8-bit bytes.
*/
-#define BITMAPBYTES 16 /* number of bytes in a bit map */
+#define BITMAPBYTES 32 /* number of bytes in a bit map */
#define BYTEBITS 8 /* number of bits in a byte */
/* internal macros */
-#define _BITWORD(bit) (bit / (BYTEBITS * sizeof (int)))
-#define _BITBIT(bit) (1 << (bit % (BYTEBITS * sizeof (int))))
+#define _BITWORD(bit) ((bit) / (BYTEBITS * sizeof (int)))
+#define _BITBIT(bit) (1 << ((bit) % (BYTEBITS * sizeof (int))))
typedef int BITMAP[BITMAPBYTES / sizeof (int)];
@@ -126,7 +133,7 @@ struct address
char *q_ruser; /* real user name, or NULL if q_user */
char *q_host; /* host name */
struct mailer *q_mailer; /* mailer to use */
- u_short q_flags; /* status flags, see below */
+ u_long q_flags; /* status flags, see below */
uid_t q_uid; /* user-id of receiver (if known) */
gid_t q_gid; /* group-id of receiver (if known) */
char *q_home; /* home dir (local mailer only) */
@@ -135,25 +142,51 @@ struct address
struct address *q_alias; /* address this results from */
char *q_owner; /* owner of q_alias */
struct address *q_tchain; /* temporary use chain */
- time_t q_timeout; /* timeout for this address */
+ char *q_orcpt; /* ORCPT parameter from RCPT TO: line */
+ char *q_status; /* status code for DSNs */
+ char *q_rstatus; /* remote status message for DSNs */
+ time_t q_statdate; /* date of status messages */
+ char *q_statmta; /* MTA generating q_rstatus */
+ short q_specificity; /* how "specific" this address is */
};
typedef struct address ADDRESS;
-# define QDONTSEND 000001 /* don't send to this address */
-# define QBADADDR 000002 /* this address is verified bad */
-# define QGOODUID 000004 /* the q_uid q_gid fields are good */
-# define QPRIMARY 000010 /* set from argv */
-# define QQUEUEUP 000020 /* queue for later transmission */
-# define QSENT 000040 /* has been successfully delivered */
-# define QNOTREMOTE 000100 /* not an address for remote forwarding */
-# define QSELFREF 000200 /* this address references itself */
-# define QVERIFIED 000400 /* verified, but not expanded */
-# define QREPORT 001000 /* report this address in return message */
-# define QBOGUSSHELL 002000 /* this entry has an invalid shell listed */
-# define QUNSAFEADDR 004000 /* address aquired through an unsafe path */
+# define QDONTSEND 0x00000001 /* don't send to this address */
+# define QBADADDR 0x00000002 /* this address is verified bad */
+# define QGOODUID 0x00000004 /* the q_uid q_gid fields are good */
+# define QPRIMARY 0x00000008 /* set from RCPT or argv */
+# define QQUEUEUP 0x00000010 /* queue for later transmission */
+# define QSENT 0x00000020 /* has been successfully delivered */
+# define QNOTREMOTE 0x00000040 /* address not for remote forwarding */
+# define QSELFREF 0x00000080 /* this address references itself */
+# define QVERIFIED 0x00000100 /* verified, but not expanded */
+# define QBOGUSSHELL 0x00000400 /* user has no valid shell listed */
+# define QUNSAFEADDR 0x00000800 /* address aquired via unsafe path */
+# define QPINGONSUCCESS 0x00001000 /* give return on successful delivery */
+# define QPINGONFAILURE 0x00002000 /* give return on failure */
+# define QPINGONDELAY 0x00004000 /* give return on message delay */
+# define QHASNOTIFY 0x00008000 /* propogate notify parameter */
+# define QRELAYED 0x00010000 /* DSN: relayed to non-DSN aware sys */
+# define QEXPANDED 0x00020000 /* DSN: undergone list expansion */
+# define QDELIVERED 0x00040000 /* DSN: successful final delivery */
+# define QDELAYED 0x00080000 /* DSN: message delayed */
+# define QTHISPASS 0x80000000 /* temp: address set this pass */
# define NULLADDR ((ADDRESS *) NULL)
+
+/* functions */
+extern ADDRESS *parseaddr __P((char *, ADDRESS *, int, int, char **, ENVELOPE *));
+extern ADDRESS *recipient __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
+extern char **prescan __P((char *, int, char[], int, char **, u_char *));
+extern int rewrite __P((char **, int, int, ENVELOPE *));
+extern char *remotename __P((char *, MAILER *, int, int *, ENVELOPE *));
+extern ADDRESS *getctladdr __P((ADDRESS *));
+extern bool sameaddr __P((ADDRESS *, ADDRESS *));
+extern bool emptyaddr __P((ADDRESS *));
+extern void printaddr __P((ADDRESS *, bool));
+extern void cataddr __P((char **, char **, char *, int, int));
+extern int sendtolist __P((char *, ADDRESS *, ADDRESS **, int, ENVELOPE *));
/*
** Mailer definition structure.
** Every mailer known to the system is declared in this
@@ -170,8 +203,12 @@ struct mailer
{
char *m_name; /* symbolic name of this mailer */
char *m_mailer; /* pathname of the mailer to use */
+ char *m_mtatype; /* type of this MTA */
+ char *m_addrtype; /* type for addresses */
+ char *m_diagtype; /* type for diagnostics */
BITMAP m_flags; /* status flags, see below */
short m_mno; /* mailer number internally */
+ short m_nice; /* niceness to run at (mostly for prog) */
char **m_argv; /* template argument vector */
short m_sh_rwset; /* rewrite set: sender header addresses */
short m_se_rwset; /* rewrite set: sender envelope addresses */
@@ -181,15 +218,18 @@ struct mailer
long m_maxsize; /* size limit on message to this mailer */
int m_linelimit; /* max # characters per line */
char *m_execdir; /* directory to chdir to before execv */
+ uid_t m_uid; /* UID to run as */
+ gid_t m_gid; /* GID to run as */
+ char *m_defcharset; /* default character set */
};
-typedef struct mailer MAILER;
-
/* bits for m_flags */
# define M_ESMTP 'a' /* run Extended SMTP protocol */
+# define M_ALIASABLE 'A' /* user can be LHS of an alias */
# define M_BLANKEND 'b' /* ensure blank line at end of message */
# define M_NOCOMMENT 'c' /* don't include comment part of address */
# define M_CANONICAL 'C' /* make addresses canonical "u@dom" */
+# define M_NOBRACKET 'd' /* never angle bracket envelope route-addrs */
/* 'D' CF: include Date: */
# define M_EXPENSIVE 'e' /* it costs to use this mailer.... */
# define M_ESCFROM 'E' /* escape From lines to >From */
@@ -198,25 +238,39 @@ typedef struct mailer MAILER;
# define M_NO_NULL_FROM 'g' /* sender of errors should be $g */
# define M_HST_UPPER 'h' /* preserve host case distinction */
# define M_PREHEAD 'H' /* MAIL11V3: preview headers */
+# define M_UDBENVELOPE 'i' /* do udbsender rewriting on envelope */
# define M_INTERNAL 'I' /* SMTP to another sendmail site */
+# define M_UDBRECIPIENT 'j' /* do udbsender rewriting on recipient lines */
+# define M_NOLOOPCHECK 'k' /* don't check for loops in HELO command */
# define M_LOCALMAILER 'l' /* delivery is to this host */
# define M_LIMITS 'L' /* must enforce SMTP line limits */
# define M_MUSER 'm' /* can handle multiple users at once */
/* 'M' CF: include Message-Id: */
# define M_NHDR 'n' /* don't insert From line */
# define M_MANYSTATUS 'N' /* MAIL11V3: DATA returns multi-status */
+# define M_RUNASRCPT 'o' /* always run mailer as recipient */
# define M_FROMPATH 'p' /* use reverse-path in MAIL FROM: */
/* 'P' CF: include Return-Path: */
# define M_ROPT 'r' /* mailer takes picky -r flag */
# define M_SECURE_PORT 'R' /* try to send on a reserved TCP port */
# define M_STRIPQ 's' /* strip quote chars from user/host */
-# define M_RESTR 'S' /* must be daemon to execute */
+# define M_SPECIFIC_UID 'S' /* run as specific uid/gid */
# define M_USR_UPPER 'u' /* preserve user case distinction */
# define M_UGLYUUCP 'U' /* this wants an ugly UUCP from line */
+# define M_CONTENT_LEN 'v' /* add Content-Length: header (SVr4) */
/* 'V' UIUC: !-relativize all addresses */
+# define M_HASPWENT 'w' /* check for /etc/passwd entry */
/* 'x' CF: include Full-Name: */
# define M_XDOT 'X' /* use hidden-dot algorithm */
+# define M_EBCDIC '3' /* extend Q-P encoding for EBCDIC */
+# define M_TRYRULESET5 '5' /* use ruleset 5 after local aliasing */
# define M_7BITS '7' /* use 7-bit path */
+# define M_8BITS '8' /* force "just send 8" behaviour */
+# define M_MAKE8BIT '9' /* convert 7 -> 8 bit if appropriate */
+# define M_CHECKINCLUDE ':' /* check for :include: files */
+# define M_CHECKPROG '|' /* check for |program addresses */
+# define M_CHECKFILE '/' /* check for /file addresses */
+# define M_CHECKUDB '@' /* user can be user database key */
EXTERN MAILER *Mailer[MAXMAILERS+1];
@@ -255,18 +309,21 @@ struct hdrinfo
extern struct hdrinfo HdrInfo[];
/* bits for h_flags and hi_flags */
-# define H_EOH 00001 /* this field terminates header */
-# define H_RCPT 00002 /* contains recipient addresses */
-# define H_DEFAULT 00004 /* if another value is found, drop this */
-# define H_RESENT 00010 /* this address is a "Resent-..." address */
-# define H_CHECK 00020 /* check h_mflags against m_flags */
-# define H_ACHECK 00040 /* ditto, but always (not just default) */
-# define H_FORCE 00100 /* force this field, even if default */
-# define H_TRACE 00200 /* this field contains trace information */
-# define H_FROM 00400 /* this is a from-type field */
-# define H_VALID 01000 /* this field has a validated value */
-# define H_RECEIPTTO 02000 /* this field has return receipt info */
-# define H_ERRORSTO 04000 /* this field has error address info */
+# define H_EOH 0x0001 /* this field terminates header */
+# define H_RCPT 0x0002 /* contains recipient addresses */
+# define H_DEFAULT 0x0004 /* if another value is found, drop this */
+# define H_RESENT 0x0008 /* this address is a "Resent-..." address */
+# define H_CHECK 0x0010 /* check h_mflags against m_flags */
+# define H_ACHECK 0x0020 /* ditto, but always (not just default) */
+# define H_FORCE 0x0040 /* force this field, even if default */
+# define H_TRACE 0x0080 /* this field contains trace information */
+# define H_FROM 0x0100 /* this is a from-type field */
+# define H_VALID 0x0200 /* this field has a validated value */
+# define H_RECEIPTTO 0x0400 /* this field has return receipt info */
+# define H_ERRORSTO 0x0800 /* this field has error address info */
+# define H_CTE 0x1000 /* this field is a content-transfer-encoding */
+# define H_CTYPE 0x2000 /* this is a content-type field */
+# define H_BCC 0x4000 /* Bcc: header: strip value or delete */
/*
** Information about currently open connections to mailers, or to
** hosts that we have looked up recently.
@@ -288,20 +345,27 @@ MCI
char *mci_phase; /* SMTP phase string */
struct mailer *mci_mailer; /* ptr to the mailer for this conn */
char *mci_host; /* host name */
+ char *mci_status; /* DSN status to be copied to addrs */
time_t mci_lastuse; /* last usage time */
};
/* flag bits */
-#define MCIF_VALID 000001 /* this entry is valid */
-#define MCIF_TEMP 000002 /* don't cache this connection */
-#define MCIF_CACHED 000004 /* currently in open cache */
-#define MCIF_ESMTP 000010 /* this host speaks ESMTP */
-#define MCIF_EXPN 000020 /* EXPN command supported */
-#define MCIF_SIZE 000040 /* SIZE option supported */
-#define MCIF_8BITMIME 000100 /* BODY=8BITMIME supported */
-#define MCIF_7BIT 000200 /* strip this message to 7 bits */
-#define MCIF_MULTSTAT 000400 /* MAIL11V3: handles MULT status */
+#define MCIF_VALID 0x0001 /* this entry is valid */
+#define MCIF_TEMP 0x0002 /* don't cache this connection */
+#define MCIF_CACHED 0x0004 /* currently in open cache */
+#define MCIF_ESMTP 0x0008 /* this host speaks ESMTP */
+#define MCIF_EXPN 0x0010 /* EXPN command supported */
+#define MCIF_SIZE 0x0020 /* SIZE option supported */
+#define MCIF_8BITMIME 0x0040 /* BODY=8BITMIME supported */
+#define MCIF_7BIT 0x0080 /* strip this message to 7 bits */
+#define MCIF_MULTSTAT 0x0100 /* MAIL11V3: handles MULT status */
+#define MCIF_INHEADER 0x0200 /* currently outputing header */
+#define MCIF_CVT8TO7 0x0400 /* convert from 8 to 7 bits */
+#define MCIF_DSN 0x0800 /* DSN extension supported */
+#define MCIF_8BITOK 0x1000 /* OK to send 8 bit characters */
+#define MCIF_CVT7TO8 0x2000 /* convert from 7 to 8 bits */
+#define MCIF_INMIME 0x4000 /* currently reading MIME header */
/* states */
#define MCIS_CLOSED 0 /* no traffic on this connection */
@@ -311,6 +375,11 @@ MCI
#define MCIS_QUITING 4 /* running quit protocol */
#define MCIS_SSD 5 /* service shutting down */
#define MCIS_ERROR 6 /* I/O error on connection */
+
+/* functions */
+extern MCI *mci_get __P((char *, MAILER *));
+extern void mci_cache __P((MCI *));
+extern void mci_flush __P((bool, MCI *));
/*
** Envelope structure.
** This structure defines the message itself. There is usually
@@ -320,9 +389,7 @@ MCI
** will have their own envelope.
*/
-# define ENVELOPE struct envelope
-
-ENVELOPE
+struct envelope
{
HDR *e_header; /* head of header list */
long e_msgpriority; /* adjusted priority of this message */
@@ -342,14 +409,14 @@ ENVELOPE
short e_nsent; /* number of sends since checkpoint */
short e_sendmode; /* message send mode */
short e_errormode; /* error return mode */
- int (*e_puthdr)__P((MCI *, ENVELOPE *));
+ short e_timeoutclass; /* message timeout class */
+ void (*e_puthdr)__P((MCI *, HDR *, ENVELOPE *));
/* function to put header of message */
- int (*e_putbody)__P((MCI *, ENVELOPE *, char *));
+ void (*e_putbody)__P((MCI *, ENVELOPE *, char *));
/* function to put body of message */
struct envelope *e_parent; /* the message this one encloses */
struct envelope *e_sibling; /* the next envelope of interest */
char *e_bodytype; /* type of message body */
- char *e_df; /* location of temp file */
FILE *e_dfp; /* temporary file */
char *e_id; /* code for this entry in queue */
FILE *e_xfp; /* transcript file */
@@ -358,16 +425,23 @@ ENVELOPE
char *e_statmsg; /* stat msg (changes per delivery) */
char *e_msgboundary; /* MIME-style message part boundary */
char *e_origrcpt; /* original recipient (one only) */
- char *e_macro[128]; /* macro definitions */
+ char *e_envid; /* envelope id from MAIL FROM: line */
+ char *e_status; /* DSN status for this message */
+ time_t e_dtime; /* time of last delivery attempt */
+ int e_ntries; /* number of delivery attempts */
+ dev_t e_dfdev; /* df file's device, for crash recov */
+ ino_t e_dfino; /* df file's ino, for crash recovery */
+ char *e_macro[256]; /* macro definitions */
};
/* values for e_flags */
#define EF_OLDSTYLE 0x0000001 /* use spaces (not commas) in hdrs */
#define EF_INQUEUE 0x0000002 /* this message is fully queued */
+#define EF_NO_BODY_RETN 0x0000004 /* omit message body on error */
#define EF_CLRQUEUE 0x0000008 /* disk copy is no longer needed */
#define EF_SENDRECEIPT 0x0000010 /* send a return receipt */
#define EF_FATALERRS 0x0000020 /* fatal errors occured */
-#define EF_KEEPQUEUE 0x0000040 /* keep queue files always */
+#define EF_DELETE_BCC 0x0000040 /* delete Bcc: headers entirely */
#define EF_RESPONSE 0x0000080 /* this is an error or return receipt */
#define EF_RESENT 0x0000100 /* this message is being forwarded */
#define EF_VRFYONLY 0x0000200 /* verify only (don't expand aliases) */
@@ -378,8 +452,23 @@ ENVELOPE
#define EF_METOO 0x0004000 /* send to me too */
#define EF_LOGSENDER 0x0008000 /* need to log the sender */
#define EF_NORECEIPT 0x0010000 /* suppress all return-receipts */
+#define EF_HAS8BIT 0x0020000 /* at least one 8-bit char in body */
+#define EF_NL_NOT_EOL 0x0040000 /* don't accept raw NL as EOLine */
+#define EF_CRLF_NOT_EOL 0x0080000 /* don't accept CR-LF as EOLine */
+#define EF_RET_PARAM 0x0100000 /* RCPT command had RET argument */
+#define EF_HAS_DF 0x0200000 /* set when df file is instantiated */
+#define EF_IS_MIME 0x0400000 /* really is a MIME message */
+#define EF_DONT_MIME 0x0800000 /* never MIME this message */
EXTERN ENVELOPE *CurEnv; /* envelope currently being processed */
+
+/* functions */
+extern ENVELOPE *newenvelope __P((ENVELOPE *, ENVELOPE *));
+extern void dropenvelope __P((ENVELOPE *));
+extern void clearenvelope __P((ENVELOPE *, bool));
+
+extern void putheader __P((MCI *, HDR *, ENVELOPE *));
+extern void putbody __P((MCI *, ENVELOPE *, char *));
/*
** Message priority classes.
**
@@ -434,35 +523,35 @@ EXTERN struct rewrite *RewriteRules[MAXRWSETS];
*/
/* left hand side items */
-# define MATCHZANY 0220 /* match zero or more tokens */
-# define MATCHANY 0221 /* match one or more tokens */
-# define MATCHONE 0222 /* match exactly one token */
-# define MATCHCLASS 0223 /* match one token in a class */
-# define MATCHNCLASS 0224 /* match anything not in class */
-# define MATCHREPL 0225 /* replacement on RHS for above */
+# define MATCHZANY ((u_char)0220) /* match zero or more tokens */
+# define MATCHANY ((u_char)0221) /* match one or more tokens */
+# define MATCHONE ((u_char)0222) /* match exactly one token */
+# define MATCHCLASS ((u_char)0223) /* match one token in a class */
+# define MATCHNCLASS ((u_char)0224) /* match anything not in class */
+# define MATCHREPL ((u_char)0225) /* replacement on RHS for above */
/* right hand side items */
-# define CANONNET 0226 /* canonical net, next token */
-# define CANONHOST 0227 /* canonical host, next token */
-# define CANONUSER 0230 /* canonical user, next N tokens */
-# define CALLSUBR 0231 /* call another rewriting set */
+# define CANONNET ((u_char)0226) /* canonical net, next token */
+# define CANONHOST ((u_char)0227) /* canonical host, next token */
+# define CANONUSER ((u_char)0230) /* canonical user, next N tokens */
+# define CALLSUBR ((u_char)0231) /* call another rewriting set */
/* conditionals in macros */
-# define CONDIF 0232 /* conditional if-then */
-# define CONDELSE 0233 /* conditional else */
-# define CONDFI 0234 /* conditional fi */
+# define CONDIF ((u_char)0232) /* conditional if-then */
+# define CONDELSE ((u_char)0233) /* conditional else */
+# define CONDFI ((u_char)0234) /* conditional fi */
/* bracket characters for host name lookup */
-# define HOSTBEGIN 0235 /* hostname lookup begin */
-# define HOSTEND 0236 /* hostname lookup end */
+# define HOSTBEGIN ((u_char)0235) /* hostname lookup begin */
+# define HOSTEND ((u_char)0236) /* hostname lookup end */
/* bracket characters for generalized lookup */
-# define LOOKUPBEGIN 0205 /* generalized lookup begin */
-# define LOOKUPEND 0206 /* generalized lookup end */
+# define LOOKUPBEGIN ((u_char)0205) /* generalized lookup begin */
+# define LOOKUPEND ((u_char)0206) /* generalized lookup end */
/* macro substitution character */
-# define MACROEXPAND 0201 /* macro expansion */
-# define MACRODEXPAND 0202 /* deferred macro expansion */
+# define MACROEXPAND ((u_char)0201) /* macro expansion */
+# define MACRODEXPAND ((u_char)0202) /* deferred macro expansion */
/* to make the code clearer */
# define MATCHZERO CANONHOST
@@ -473,6 +562,16 @@ struct metamac
char metaname; /* external code (after $) */
u_char metaval; /* internal code (as above) */
};
+
+/* values for macros with external names only */
+# define MID_OPMODE 0202 /* operation mode */
+
+/* functions */
+extern void expand __P((char *, char *, size_t, ENVELOPE *));
+extern void define __P((int, char *, ENVELOPE *));
+extern char *macvalue __P((int, ENVELOPE *));
+extern char *macname __P((int));
+extern int macid __P((char *, char **));
/*
** Name canonification short circuit.
**
@@ -505,6 +604,7 @@ NAMECANON
# define MAPCLASS struct _mapclass
# define MAP struct _map
+# define MAXMAPACTIONS 3 /* size of map_actions array */
/*
@@ -515,32 +615,47 @@ MAP
{
MAPCLASS *map_class; /* the class of this map */
char *map_mname; /* name of this map */
- int map_mflags; /* flags, see below */
+ long map_mflags; /* flags, see below */
char *map_file; /* the (nominal) filename */
ARBPTR_T map_db1; /* the open database ptr */
ARBPTR_T map_db2; /* an "extra" database pointer */
+ char *map_keycolnm; /* key column name */
+ char *map_valcolnm; /* value column name */
+ u_char map_keycolno; /* key column number */
+ u_char map_valcolno; /* value column number */
+ char map_coldelim; /* column delimiter */
char *map_app; /* to append to successful matches */
char *map_domain; /* the (nominal) NIS domain */
char *map_rebuild; /* program to run to do auto-rebuild */
time_t map_mtime; /* last database modification time */
+ short map_specificity; /* specificity of alaases */
+ MAP *map_stack[MAXMAPSTACK]; /* list for stacked maps */
+ short map_return[MAXMAPACTIONS]; /* return bitmaps for stacked maps */
};
-/* bit values for map_flags */
-# define MF_VALID 0x0001 /* this entry is valid */
-# define MF_INCLNULL 0x0002 /* include null byte in key */
-# define MF_OPTIONAL 0x0004 /* don't complain if map not found */
-# define MF_NOFOLDCASE 0x0008 /* don't fold case in keys */
-# define MF_MATCHONLY 0x0010 /* don't use the map value */
-# define MF_OPEN 0x0020 /* this entry is open */
-# define MF_WRITABLE 0x0040 /* open for writing */
-# define MF_ALIAS 0x0080 /* this is an alias file */
-# define MF_TRY0NULL 0x0100 /* try with no null byte */
-# define MF_TRY1NULL 0x0200 /* try with the null byte */
-# define MF_LOCKED 0x0400 /* this map is currently locked */
-# define MF_ALIASWAIT 0x0800 /* alias map in aliaswait state */
-# define MF_IMPL_HASH 0x1000 /* implicit: underlying hash database */
-# define MF_IMPL_NDBM 0x2000 /* implicit: underlying NDBM database */
-
+/* bit values for map_mflags */
+# define MF_VALID 0x00000001 /* this entry is valid */
+# define MF_INCLNULL 0x00000002 /* include null byte in key */
+# define MF_OPTIONAL 0x00000004 /* don't complain if map not found */
+# define MF_NOFOLDCASE 0x00000008 /* don't fold case in keys */
+# define MF_MATCHONLY 0x00000010 /* don't use the map value */
+# define MF_OPEN 0x00000020 /* this entry is open */
+# define MF_WRITABLE 0x00000040 /* open for writing */
+# define MF_ALIAS 0x00000080 /* this is an alias file */
+# define MF_TRY0NULL 0x00000100 /* try with no null byte */
+# define MF_TRY1NULL 0x00000200 /* try with the null byte */
+# define MF_LOCKED 0x00000400 /* this map is currently locked */
+# define MF_ALIASWAIT 0x00000800 /* alias map in aliaswait state */
+# define MF_IMPL_HASH 0x00001000 /* implicit: underlying hash database */
+# define MF_IMPL_NDBM 0x00002000 /* implicit: underlying NDBM database */
+# define MF_UNSAFEDB 0x00004000 /* this map is world writable */
+# define MF_APPEND 0x00008000 /* append new entry on rebuiled */
+# define MF_KEEPQUOTES 0x00010000 /* don't dequote key before lookup */
+
+/* indices for map_actions */
+# define MA_NOTFOUND 0 /* member map returned "not found" */
+# define MA_UNAVAIL 1 /* member map is not available */
+# define MA_TRYAGAIN 2 /* member map returns temp failure */
/*
** The class of a map -- essentially the functions to call
@@ -567,6 +682,11 @@ MAPCLASS
#define MCF_ALIASOK 0x0001 /* can be used for aliases */
#define MCF_ALIASONLY 0x0002 /* usable only for aliases */
#define MCF_REBUILDABLE 0x0004 /* can rebuild alias files */
+#define MCF_OPTFILE 0x0008 /* file name is optional */
+
+/* functions */
+extern char *map_rewrite __P((MAP *, char *, int, char **));
+extern MAP *makemapentry __P((char *));
/*
** Symbol table definitions
*/
@@ -587,6 +707,8 @@ struct symtab
char *sv_hostsig; /* host signature */
MCI sv_mci; /* mailer connection info */
NAMECANON sv_namecanon; /* canonical name cache */
+ int sv_macro; /* macro name => id mapping */
+ int sv_ruleset; /* ruleset index */
} s_value;
};
@@ -602,6 +724,8 @@ typedef struct symtab STAB;
# define ST_MAP 6 /* mapping function */
# define ST_HOSTSIG 7 /* host signature */
# define ST_NAMECANON 8 /* cached canonical name */
+# define ST_MACRO 9 /* macro name to id mapping */
+# define ST_RULESET 10 /* ruleset index */
# define ST_MCI 16 /* mailer connection info (offset) */
# define s_class s_value.sv_class
@@ -613,6 +737,8 @@ typedef struct symtab STAB;
# define s_hostsig s_value.sv_hostsig
# define s_map s_value.sv_map
# define s_namecanon s_value.sv_namecanon
+# define s_macro s_value.sv_macro
+# define s_ruleset s_value.sv_ruleset
extern STAB *stab __P((char *, int, int));
extern void stabapply __P((void (*)(STAB *, int), int));
@@ -632,7 +758,7 @@ extern void stabapply __P((void (*)(STAB *, int), int));
struct event
{
time_t ev_time; /* time of the function call */
- int (*ev_func)__P((int));
+ void (*ev_func)__P((int));
/* function to call */
int ev_arg; /* argument to ev_func */
int ev_pid; /* pid that set this event */
@@ -642,8 +768,12 @@ struct event
typedef struct event EVENT;
EXTERN EVENT *EventQueue; /* head of event queue */
+
+/* functions */
+extern EVENT *setevent __P((time_t, void(*)(), int));
+extern void clrevent __P((EVENT *));
/*
-** Operation, send, and error modes
+** Operation, send, error, and MIME modes
**
** The operation mode describes the basic operation of sendmail.
** This can be set from the command line, and is "send mail" by
@@ -673,9 +803,9 @@ EXTERN char OpMode; /* operation mode, see below */
/* values for e_sendmode -- send modes */
#define SM_DELIVER 'i' /* interactive delivery */
-#define SM_QUICKD 'j' /* deliver w/o queueing */
#define SM_FORK 'b' /* deliver in background */
#define SM_QUEUE 'q' /* queue, don't deliver */
+#define SM_DEFER 'd' /* defer map lookups as well as queue */
#define SM_VERIFY 'v' /* verify only (used internally) */
/* used only as a parameter to sendall */
@@ -688,6 +818,37 @@ EXTERN char OpMode; /* operation mode, see below */
#define EM_WRITE 'w' /* write back errors */
#define EM_BERKNET 'e' /* special berknet processing */
#define EM_QUIET 'q' /* don't print messages (stat only) */
+
+
+/* MIME processing mode */
+EXTERN int MimeMode;
+
+/* bit values for MimeMode */
+#define MM_CVTMIME 0x0001 /* convert 8 to 7 bit MIME */
+#define MM_PASS8BIT 0x0002 /* just send 8 bit data blind */
+#define MM_MIME8BIT 0x0004 /* convert 8-bit data to MIME */
+
+/* queue sorting order algorithm */
+EXTERN int QueueSortOrder;
+
+#define QS_BYPRIORITY 0 /* sort by message priority */
+#define QS_BYHOST 1 /* sort by first host name */
+
+
+/* how to handle messages without any recipient addresses */
+EXTERN int NoRecipientAction;
+
+#define NRA_NO_ACTION 0 /* just leave it as is */
+#define NRA_ADD_TO 1 /* add To: header */
+#define NRA_ADD_APPARENTLY_TO 2 /* add Apparently-To: header */
+#define NRA_ADD_BCC 3 /* add empty Bcc: header */
+#define NRA_ADD_TO_UNDISCLOSED 4 /* add To: undisclosed:; header */
+
+
+/* flags to putxline */
+#define PXLF_NOTHINGSPECIAL 0 /* no special mapping */
+#define PXLF_MAPFROM 0x0001 /* map From_ to >From_ */
+#define PXLF_STRIP8BIT 0x0002 /* strip 8th bit *e
/*
** Additional definitions
*/
@@ -699,16 +860,16 @@ EXTERN char OpMode; /* operation mode, see below */
*/
#define PRIV_PUBLIC 0 /* what have I got to hide? */
-#define PRIV_NEEDMAILHELO 00001 /* insist on HELO for MAIL, at least */
-#define PRIV_NEEDEXPNHELO 00002 /* insist on HELO for EXPN */
-#define PRIV_NEEDVRFYHELO 00004 /* insist on HELO for VRFY */
-#define PRIV_NOEXPN 00010 /* disallow EXPN command entirely */
-#define PRIV_NOVRFY 00020 /* disallow VRFY command entirely */
-#define PRIV_AUTHWARNINGS 00040 /* flag possible authorization probs */
-#define PRIV_NORECEIPTS 00100 /* disallow return receipts */
-#define PRIV_RESTRICTMAILQ 01000 /* restrict mailq command */
-#define PRIV_RESTRICTQRUN 02000 /* restrict queue run */
-#define PRIV_GOAWAY 00777 /* don't give no info, anyway, anyhow */
+#define PRIV_NEEDMAILHELO 0x0001 /* insist on HELO for MAIL, at least */
+#define PRIV_NEEDEXPNHELO 0x0002 /* insist on HELO for EXPN */
+#define PRIV_NEEDVRFYHELO 0x0004 /* insist on HELO for VRFY */
+#define PRIV_NOEXPN 0x0008 /* disallow EXPN command entirely */
+#define PRIV_NOVRFY 0x0010 /* disallow VRFY command entirely */
+#define PRIV_AUTHWARNINGS 0x0020 /* flag possible authorization probs */
+#define PRIV_NORECEIPTS 0x0040 /* disallow return receipts */
+#define PRIV_RESTRICTMAILQ 0x1000 /* restrict mailq command */
+#define PRIV_RESTRICTQRUN 0x2000 /* restrict queue run */
+#define PRIV_GOAWAY 0x0fff /* don't give no info, anyway, anyhow */
/* struct defining such things */
struct prival
@@ -722,12 +883,12 @@ struct prival
** Flags passed to remotename, parseaddr, allocaddr, and buildaddr.
*/
-#define RF_SENDERADDR 0001 /* this is a sender address */
-#define RF_HEADERADDR 0002 /* this is a header address */
-#define RF_CANONICAL 0004 /* strip comment information */
-#define RF_ADDDOMAIN 0010 /* OK to do domain extension */
-#define RF_COPYPARSE 0020 /* copy parsed user & host */
-#define RF_COPYPADDR 0040 /* copy print address */
+#define RF_SENDERADDR 0x001 /* this is a sender address */
+#define RF_HEADERADDR 0x002 /* this is a header address */
+#define RF_CANONICAL 0x004 /* strip comment information */
+#define RF_ADDDOMAIN 0x008 /* OK to do domain extension */
+#define RF_COPYPARSE 0x010 /* copy parsed user & host */
+#define RF_COPYPADDR 0x020 /* copy print address */
#define RF_COPYALL (RF_COPYPARSE|RF_COPYPADDR)
#define RF_COPYNONE 0
@@ -740,6 +901,23 @@ struct prival
#define SFF_MUSTOWN 0x0001 /* user must own this file */
#define SFF_NOSLINK 0x0002 /* file cannot be a symbolic link */
#define SFF_ROOTOK 0x0004 /* ok for root to own this file */
+#define SFF_RUNASREALUID 0x0008 /* if no ctladdr, run as real uid */
+#define SFF_NOPATHCHECK 0x0010 /* don't bother checking dir path */
+#define SFF_SETUIDOK 0x0020 /* setuid files are ok */
+#define SFF_CREAT 0x0040 /* ok to create file if necessary */
+#define SFF_REGONLY 0x0080 /* regular files only */
+
+/* flags that are actually specific to safefopen */
+#define SFF_OPENASROOT 0x1000 /* open as root instead of real user */
+
+
+/*
+** Flags passed to mime8to7.
+*/
+
+#define M87F_OUTER 0 /* outer context */
+#define M87F_NO8BIT 0x0001 /* can't have 8-bit in this section */
+#define M87F_DIGEST 0x0002 /* processing multipart/digest */
/*
@@ -747,27 +925,56 @@ struct prival
** we are forced to declare a supertype here.
*/
+#ifdef DAEMON
union bigsockaddr
{
struct sockaddr sa; /* general version */
-#ifdef NETUNIX
+#if NETUNIX
struct sockaddr_un sunix; /* UNIX family */
#endif
-#ifdef NETINET
+#if NETINET
struct sockaddr_in sin; /* INET family */
#endif
-#ifdef NETISO
+#if NETISO
struct sockaddr_iso siso; /* ISO family */
#endif
-#ifdef NETNS
+#if NETNS
struct sockaddr_ns sns; /* XNS family */
#endif
-#ifdef NETX25
+#if NETX25
struct sockaddr_x25 sx25; /* X.25 family */
#endif
};
#define SOCKADDR union bigsockaddr
+
+EXTERN SOCKADDR RealHostAddr; /* address of host we are talking to */
+extern char *anynet_ntoa __P((SOCKADDR *));
+
+#endif
+
+
+/*
+** Vendor codes
+**
+** Vendors can customize sendmail to add special behaviour,
+** generally for back compatibility. Ideally, this should
+** be set up in the .cf file using the "V" command. However,
+** it's quite reasonable for some vendors to want the default
+** be their old version; this can be set using
+** -DVENDOR_DEFAULT=VENDOR_xxx
+** in the Makefile.
+**
+** Vendors should apply to sendmail@CS.Berkeley.EDU for
+** unique vendor codes.
+*/
+
+#define VENDOR_BERKELEY 1 /* Berkeley-native configuration file */
+#define VENDOR_SUN 2 /* Sun-native configuration file */
+#define VENDOR_HP 3 /* Hewlett-Packard specific config syntax */
+#define VENDOR_IBM 4 /* IBM specific config syntax */
+
+EXTERN int VendorCode; /* vendor-specific operation enhancements */
/*
** Global variables.
*/
@@ -778,7 +985,6 @@ EXTERN bool IgnrDot; /* don't let dot end messages */
EXTERN bool SaveFrom; /* save leading "From" lines */
EXTERN bool Verbose; /* set if blow-by-blow desired */
EXTERN bool GrabTo; /* if set, get recipients from msg */
-EXTERN bool NoReturn; /* don't return letter to sender */
EXTERN bool SuprErrs; /* set if we are suppressing errors */
EXTERN bool HoldErrs; /* only output errors to transcript */
EXTERN bool NoConnect; /* don't connect to non-local mailers */
@@ -787,20 +993,22 @@ EXTERN bool ForkQueueRuns; /* fork for each job when running the queue */
EXTERN bool AutoRebuild; /* auto-rebuild the alias database as needed */
EXTERN bool CheckAliases; /* parse addresses during newaliases */
EXTERN bool NoAlias; /* suppress aliasing */
-EXTERN bool UseNameServer; /* use internet domain name server */
-EXTERN bool SevenBit; /* force 7-bit data */
+EXTERN bool UseNameServer; /* using DNS -- interpret h_errno & MX RRs */
+EXTERN bool UseHesiod; /* using Hesiod -- interpret Hesiod errors */
+EXTERN bool SevenBitInput; /* force 7-bit data on input */
+EXTERN bool HasEightBits; /* has at least one eight bit input byte */
EXTERN time_t SafeAlias; /* interval to wait until @:@ in alias file */
EXTERN FILE *InChannel; /* input connection */
EXTERN FILE *OutChannel; /* output connection */
-EXTERN uid_t RealUid; /* when Daemon, real uid of caller */
-EXTERN gid_t RealGid; /* when Daemon, real gid of caller */
+EXTERN char *RealUserName; /* real user name of caller */
+EXTERN uid_t RealUid; /* real uid of caller */
+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 int Errors; /* set if errors (local to single pass) */
EXTERN int ExitStat; /* exit status code */
-EXTERN int AliasLevel; /* depth of aliasing */
EXTERN int LineNumber; /* line number in current input */
EXTERN int LogLevel; /* level of logging to perform */
EXTERN int FileMode; /* mode on files */
@@ -817,7 +1025,6 @@ EXTERN char *FileName; /* name to print on error messages */
EXTERN char *SmtpPhase; /* current phase in SMTP processing */
EXTERN char *MyHostName; /* name of this host for SMTP messages */
EXTERN char *RealHostName; /* name of host we are talking to */
-EXTERN SOCKADDR RealHostAddr; /* address of host we are talking to */
EXTERN char *CurHostName; /* current host we are dealing with */
EXTERN jmp_buf TopFrame; /* branch-to-top-of-loop-on-error frame */
EXTERN bool QuickAbort; /* .... but only if we want a quick abort */
@@ -826,9 +1033,10 @@ EXTERN bool SendMIMEErrors; /* send error messages in MIME format */
EXTERN bool MatchGecos; /* look for user names in gecos field */
EXTERN bool UseErrorsTo; /* use Errors-To: header (back compat) */
EXTERN bool TryNullMXList; /* if we are the best MX, try host directly */
-extern bool CheckLoopBack; /* check for loopback on HELO packet */
EXTERN bool InChild; /* true if running in an SMTP subprocess */
EXTERN bool DisConnected; /* running with OutChannel redirected to xf */
+EXTERN bool ColonOkInAddr; /* single colon legal in address */
+EXTERN bool HasWildcardMX; /* don't use MX records when canonifying */
EXTERN char SpaceSub; /* substitution for <lwsp> */
EXTERN int PrivacyFlags; /* privacy flags */
EXTERN char *ConfFile; /* location of configuration file [conf.c] */
@@ -845,16 +1053,38 @@ EXTERN char *ForwardPath; /* path to search for .forward files */
EXTERN long MinBlocksFree; /* min # of blocks free on queue fs */
EXTERN char *FallBackMX; /* fall back MX host */
EXTERN long MaxMessageSize; /* advertised max size we will accept */
+EXTERN time_t MaxHostStatAge; /* max age of cached host status info */
+EXTERN time_t MinQueueAge; /* min delivery interval */
+EXTERN time_t DialDelay; /* delay between dial-on-demand tries */
+EXTERN char *SafeFileEnv; /* chroot location for file delivery */
+EXTERN char *HostsFile; /* path to /etc/hosts file */
+EXTERN int MaxQueueRun; /* maximum number of jobs in one queue run */
+EXTERN int MaxChildren; /* maximum number of daemonic children */
+EXTERN int CurChildren; /* current number of daemonic children */
+EXTERN char *SmtpGreeting; /* SMTP greeting message (old $e macro) */
+EXTERN char *UnixFromLine; /* UNIX From_ line (old $l macro) */
+EXTERN char *OperatorChars; /* operators (old $o macro) */
+EXTERN bool DontInitGroups; /* avoid initgroups() because of NIS cost */
+EXTERN bool SingleLineFromHeader; /* force From: header to be one line */
+EXTERN int MaxAliasRecursion; /* maximum depth of alias recursion */
+EXTERN int MaxRuleRecursion; /* maximum depth of ruleset recursion */
+EXTERN char *MustQuoteChars; /* quote these characters in phrases */
+EXTERN char *ServiceSwitchFile; /* backup service switch */
+EXTERN char *DefaultCharSet; /* default character set for MIME */
+EXTERN int DeliveryNiceness; /* how nice to be during delivery */
EXTERN char *PostMasterCopy; /* address to get errs cc's */
EXTERN int CheckpointInterval; /* queue file checkpoint interval */
EXTERN bool DontPruneRoutes; /* don't prune source routes */
-extern bool BrokenSmtpPeers; /* peers can't handle 2-line greeting */
+EXTERN bool DontExpandCnames; /* do not $[...$] expand CNAMEs */
EXTERN int MaxMciCache; /* maximum entries in MCI cache */
EXTERN time_t MciCacheTimeout; /* maximum idle time on connections */
+EXTERN time_t MciInfoTimeout; /* how long 'til we retry down hosts */
EXTERN char *QueueLimitRecipient; /* limit queue runs to this recipient */
EXTERN char *QueueLimitSender; /* limit queue runs to this sender */
EXTERN char *QueueLimitId; /* limit queue runs to this id */
EXTERN FILE *TrafficLogFile; /* file in which to log all traffic */
+EXTERN char *UserEnviron[MAXUSERENVIRON + 1];
+ /* saved user environment */
extern int errno;
@@ -875,16 +1105,23 @@ EXTERN struct
time_t to_datafinal; /* DATA completion [10m] */
time_t to_nextcommand; /* next command [5m] */
/* following timeouts are not mentioned in RFC 1123 */
+ time_t to_connect; /* initial connection timeout */
time_t to_rset; /* RSET command */
time_t to_helo; /* HELO command */
time_t to_quit; /* QUIT command */
time_t to_miscshort; /* misc short commands (NOOP, VERB, etc) */
time_t to_ident; /* IDENT protocol requests */
+ time_t to_fileopen; /* opening :include: and .forward files */
/* following are per message */
- time_t to_q_return; /* queue return timeout */
- time_t to_q_warning; /* queue warning timeout */
+ time_t to_q_return[MAXTOCLASS]; /* queue return timeouts */
+ time_t to_q_warning[MAXTOCLASS]; /* queue warning timeouts */
} TimeOuts;
+/* timeout classes for return and warning timeouts */
+# define TOC_NORMAL 0 /* normal delivery */
+# define TOC_URGENT 1 /* urgent delivery */
+# define TOC_NONURGENT 2 /* non-urgent delivery */
+
/*
** Trace information
@@ -920,43 +1157,59 @@ EXTERN u_char tTdvect[100];
** Declarations of useful functions
*/
-extern ADDRESS *parseaddr __P((char *, ADDRESS *, int, int, char **, ENVELOPE *));
-extern char *xalloc __P((int));
-extern bool sameaddr __P((ADDRESS *, ADDRESS *));
-extern FILE *dfopen __P((char *, int, int));
-extern EVENT *setevent __P((time_t, int(*)(), int));
-extern char *sfgets __P((char *, int, FILE *, time_t, char *));
-extern char *queuename __P((ENVELOPE *, int));
-extern time_t curtime __P(());
-extern bool transienterror __P((int));
+extern char *xalloc __P((int));
+extern FILE *dfopen __P((char *, int, int));
+extern char *sfgets __P((char *, int, FILE *, time_t, char *));
+extern char *queuename __P((ENVELOPE *, int));
+extern time_t curtime __P(());
+extern bool transienterror __P((int));
+extern char *fgetfolded __P((char *, int, FILE *));
+extern char *username __P(());
+extern char *pintvl __P((time_t, bool));
+extern bool shouldqueue __P((long, time_t));
+extern bool lockfile __P((int, char *, char *, int));
+extern char *hostsignature __P((MAILER *, char *, ENVELOPE *));
+extern void openxscript __P((ENVELOPE *));
+extern void closexscript __P((ENVELOPE *));
+extern char *shortenstring __P((const char *, int));
+extern bool usershellok __P((char *, char *));
+extern void commaize __P((HDR *, char *, bool, MCI *, ENVELOPE *));
+extern char *hvalue __P((char *, HDR *));
+extern char *defcharset __P((ENVELOPE *));
+extern bool wordinclass __P((char *, int));
+extern char *denlstring __P((char *, bool, bool));
+extern void makelower __P((char *));
+extern void rebuildaliases __P((MAP *, bool));
+extern void readaliases __P((MAP *, FILE *, bool, bool));
+extern void finis __P(());
+extern void setsender __P((char *, ENVELOPE *, char **, bool));
+extern FILE *safefopen __P((char *, int, int, int));
+extern void xputs __P((const char *));
+extern void logsender __P((ENVELOPE *, char *));
+extern void smtprset __P((MAILER *, MCI *, ENVELOPE *));
+extern void smtpquit __P((MAILER *, MCI *, ENVELOPE *));
+extern void setuserenv __P((const char *, const char *));
+extern void disconnect __P((int, ENVELOPE *));
+extern void putxline __P((char *, MCI *, int));
+extern void dumpfd __P((int, bool, bool));
+extern void makemailer __P((char *));
+extern void putfromline __P((MCI *, ENVELOPE *));
+extern void setoption __P((int, char *, bool, bool, ENVELOPE *));
+extern void setclass __P((int, char *));
+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 const char *errstring __P((int));
-extern void expand __P((char *, char *, char *, ENVELOPE *));
-extern void define __P((int, char *, ENVELOPE *));
-extern char *macvalue __P((int, ENVELOPE *));
-extern char **prescan __P((char *, int, char[], int, char **));
-extern int rewrite __P((char **, int, int, ENVELOPE *));
-extern char *fgetfolded __P((char *, int, FILE *));
-extern ADDRESS *recipient __P((ADDRESS *, ADDRESS **, ENVELOPE *));
-extern ENVELOPE *newenvelope __P((ENVELOPE *, ENVELOPE *));
-extern void dropenvelope __P((ENVELOPE *));
-extern void clearenvelope __P((ENVELOPE *, int));
-extern char *username __P(());
-extern MCI *mci_get __P((char *, MAILER *));
-extern char *pintvl __P((time_t, int));
-extern char *map_rewrite __P((MAP *, char *, int, char **));
-extern ADDRESS *getctladdr __P((ADDRESS *));
-extern char *anynet_ntoa __P((SOCKADDR *));
-extern char *remotename __P((char *, MAILER *, int, int *, ENVELOPE *));
-extern bool shouldqueue __P((long, time_t));
-extern bool lockfile __P((int, char *, char *, int));
-extern char *hostsignature __P((MAILER *, char *, ENVELOPE *));
-extern void openxscript __P((ENVELOPE *));
-extern void closexscript __P((ENVELOPE *));
extern sigfunc_t setsignal __P((int, sigfunc_t));
-extern char *shortenstring __P((char *, int));
-extern bool usershellok __P((char *));
-extern void commaize __P((HDR *, char *, int, MCI *, ENVELOPE *));
-extern char *denlstring __P((char *, int, int));
+extern struct hostent *sm_gethostbyname __P((char *));
+extern struct hostent *sm_gethostbyaddr __P((char *, int, int));
+extern struct passwd *sm_getpwnam __P((char *));
+extern struct passwd *sm_getpwuid __P((UID_T));
+
+#ifdef XDEBUG
+extern void checkfd012 __P((char *));
+#endif
/* ellipsis is a different case though */
#ifdef __STDC__
@@ -972,3 +1225,13 @@ extern void usrerr();
extern void message();
extern void nmessage();
#endif
+
+#if !HASSNPRINTF
+# ifdef __STDC__
+extern void snprintf(char *, size_t, const char *, ...);
+extern void vsnprintf(char *, size_t, const char *, va_list);
+# else
+extern void snprintf();
+extern void vsnprintf();
+# endif
+#endif
diff --git a/usr.sbin/sendmail/src/srvrsmtp.c b/usr.sbin/sendmail/src/srvrsmtp.c
index e2a09e4..69a4fbe 100644
--- a/usr.sbin/sendmail/src/srvrsmtp.c
+++ b/usr.sbin/sendmail/src/srvrsmtp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -36,9 +36,9 @@
#ifndef lint
#ifdef SMTP
-static char sccsid[] = "@(#)srvrsmtp.c 8.37 (Berkeley) 4/13/94 (with SMTP)";
+static char sccsid[] = "@(#)srvrsmtp.c 8.97 (Berkeley) 11/18/95 (with SMTP)";
#else
-static char sccsid[] = "@(#)srvrsmtp.c 8.37 (Berkeley) 4/13/94 (without SMTP)";
+static char sccsid[] = "@(#)srvrsmtp.c 8.97 (Berkeley) 11/18/95 (without SMTP)";
#endif
#endif /* not lint */
@@ -117,35 +117,34 @@ bool OneXact = FALSE; /* one xaction only this run */
char *CurSmtpClient; /* who's at the other end of channel */
static char *skipword();
-extern char RealUserName[];
#define MAXBADCOMMANDS 25 /* maximum number of bad commands */
+void
smtp(e)
- register ENVELOPE *e;
+ register ENVELOPE *volatile e;
{
register char *p;
register struct cmd *c;
char *cmd;
auto ADDRESS *vrfyqueue;
ADDRESS *a;
- bool gotmail; /* mail command received */
- bool gothello; /* helo command received */
+ volatile bool gotmail; /* mail command received */
+ volatile bool gothello; /* helo command received */
bool vrfy; /* set if this is a vrfy command */
- char *protocol; /* sending protocol */
- char *sendinghost; /* sending hostname */
- unsigned long msize; /* approximate maximum message size */
- char *peerhostname; /* name of SMTP peer or "localhost" */
+ char *volatile protocol; /* sending protocol */
+ char *volatile sendinghost; /* sending hostname */
+ char *volatile peerhostname; /* name of SMTP peer or "localhost" */
auto char *delimptr;
char *id;
- int nrcpts; /* number of RCPT commands */
+ volatile int nrcpts = 0; /* number of RCPT commands */
bool doublequeue;
- int badcommands = 0; /* count of bad commands */
+ volatile int badcommands = 0; /* count of bad commands */
char inp[MAXLINE];
char cmdbuf[MAXLINE];
- extern char Version[];
extern ENVELOPE BlankEnvelope;
+ extern void help __P((char *));
if (fileno(OutChannel) != fileno(stdout))
{
@@ -162,28 +161,41 @@ smtp(e)
CurSmtpClient = CurHostName;
setproctitle("server %s startup", CurSmtpClient);
- expand("\201e", inp, &inp[sizeof inp], e);
- if (BrokenSmtpPeers)
+#ifdef LOG
+ if (LogLevel > 11)
{
- p = strchr(inp, '\n');
- if (p != NULL)
- *p = '\0';
- message("220 %s", inp);
+ /* log connection information */
+ syslog(LOG_INFO, "SMTP connect from %.100s (%.100s)",
+ CurSmtpClient, anynet_ntoa(&RealHostAddr));
}
- else
- {
- char *q = inp;
+#endif
- while (q != NULL)
- {
- p = strchr(q, '\n');
- if (p != NULL)
- *p++ = '\0';
- message("220-%s", q);
- q = p;
- }
- message("220 ESMTP spoken here");
+ /* output the first line, inserting "ESMTP" as second word */
+ expand(SmtpGreeting, inp, sizeof inp, e);
+ p = strchr(inp, '\n');
+ if (p != NULL)
+ *p++ = '\0';
+ id = strchr(inp, ' ');
+ if (id == NULL)
+ id = &inp[strlen(inp)];
+ cmd = p == NULL ? "220 %.*s ESMTP%s" : "220-%.*s ESMTP%s";
+ message(cmd, id - inp, inp, id);
+
+ /* output remaining lines */
+ while ((id = p) != NULL && (p = strchr(id, '\n')) != NULL)
+ {
+ *p++ = '\0';
+ if (isascii(*id) && isspace(*id))
+ id++;
+ message("220-%s", id);
+ }
+ if (id != NULL)
+ {
+ if (isascii(*id) && isspace(*id))
+ id++;
+ message("220 %s", id);
}
+
protocol = NULL;
sendinghost = macvalue('s', e);
gothello = FALSE;
@@ -213,7 +225,7 @@ smtp(e)
/* read the input line */
SmtpPhase = "server cmd read";
- setproctitle("server %s cmd read", CurHostName);
+ setproctitle("server %s cmd read", CurSmtpClient);
p = sfgets(inp, sizeof inp, InChannel, TimeOuts.to_nextcommand,
SmtpPhase);
@@ -226,7 +238,7 @@ smtp(e)
MyHostName, CurSmtpClient);
#ifdef LOG
if (LogLevel > (gotmail ? 1 : 19))
- syslog(LOG_NOTICE, "lost input channel from %s",
+ syslog(LOG_NOTICE, "lost input channel from %.100s",
CurSmtpClient);
#endif
if (InChild)
@@ -285,6 +297,39 @@ smtp(e)
protocol = "SMTP";
SmtpPhase = "server HELO";
}
+
+ /* check for valid domain name (re 1123 5.2.5) */
+ if (*p == '\0')
+ {
+ message("501 %s requires domain address",
+ cmdbuf);
+ break;
+ }
+ else
+ {
+ register char *q;
+
+ for (q = p; *q != '\0'; q++)
+ {
+ if (!isascii(*q))
+ break;
+ if (isalnum(*q))
+ continue;
+ if (isspace(*q))
+ {
+ *q = '\0';
+ break;
+ }
+ if (strchr("[].-_#", *q) == NULL)
+ break;
+ }
+ if (*q != '\0')
+ {
+ message("501 Invalid domain name");
+ break;
+ }
+ }
+
sendinghost = newstr(p);
gothello = TRUE;
if (c->cmdcode != CMDEHLO)
@@ -300,10 +345,19 @@ smtp(e)
MyHostName, CurSmtpClient);
if (!bitset(PRIV_NOEXPN, PrivacyFlags))
message("250-EXPN");
+#if MIME8TO7
+ message("250-8BITMIME");
+#endif
if (MaxMessageSize > 0)
message("250-SIZE %ld", MaxMessageSize);
else
message("250-SIZE");
+#if DSN
+ if (SendMIMEErrors)
+ message("250-DSN");
+#endif
+ message("250-VERB");
+ message("250-ONEX");
message("250 HELP");
break;
@@ -344,7 +398,7 @@ smtp(e)
{
auth_warning(e,
"Host %s didn't use HELO protocol",
- peerhostname);
+ CurSmtpClient);
}
#ifdef PICKY_HELO_CHECK
if (strcasecmp(sendinghost, peerhostname) != 0 &&
@@ -352,7 +406,7 @@ smtp(e)
strcasecmp(sendinghost, MyHostName) != 0))
{
auth_warning(e, "Host %s claimed to be %s",
- peerhostname, sendinghost);
+ CurSmtpClient, sendinghost);
}
#endif
@@ -362,7 +416,7 @@ smtp(e)
define('s', sendinghost, e);
initsys(e);
nrcpts = 0;
- e->e_flags |= EF_LOGSENDER;
+ e->e_flags |= EF_LOGSENDER|EF_CLRQUEUE;
setproctitle("%s %s: %.80s", e->e_id, CurSmtpClient, inp);
/* child -- go do the processing */
@@ -392,19 +446,21 @@ smtp(e)
/* check for possible spoofing */
if (RealUid != 0 && OpMode == MD_SMTP &&
- (e->e_from.q_mailer != LocalMailer &&
- strcmp(e->e_from.q_user, RealUserName) != 0))
+ !wordinclass(RealUserName, 't') &&
+ !bitnset(M_LOCALMAILER, e->e_from.q_mailer->m_flags) &&
+ strcmp(e->e_from.q_user, RealUserName) != 0)
{
auth_warning(e, "%s owned process doing -bs",
RealUserName);
}
/* now parse ESMTP arguments */
- msize = 0;
+ e->e_msgsize = 0;
while (p != NULL && *p != '\0')
{
char *kp;
char *vp = NULL;
+ extern void mail_esmtp_args __P((char *, char *, ENVELOPE *));
/* locate the beginning of the keyword */
while (isascii(*p) && isspace(*p))
@@ -435,59 +491,17 @@ smtp(e)
printf("MAIL: got arg %s=\"%s\"\n", kp,
vp == NULL ? "<null>" : vp);
- if (strcasecmp(kp, "size") == 0)
- {
- if (vp == NULL)
- {
- usrerr("501 SIZE requires a value");
- /* NOTREACHED */
- }
-# ifdef __STDC__
- msize = strtoul(vp, (char **) NULL, 10);
-# else
- msize = strtol(vp, (char **) NULL, 10);
-# endif
- }
- else if (strcasecmp(kp, "body") == 0)
- {
- if (vp == NULL)
- {
- usrerr("501 BODY requires a value");
- /* NOTREACHED */
- }
-# ifdef MIME
- if (strcasecmp(vp, "8bitmime") == 0)
- {
- e->e_bodytype = "8BITMIME";
- SevenBit = FALSE;
- }
- else if (strcasecmp(vp, "7bit") == 0)
- {
- e->e_bodytype = "7BIT";
- SevenBit = TRUE;
- }
- else
- {
- usrerr("501 Unknown BODY type %s",
- vp);
- }
-# endif
- }
- else
- {
- usrerr("501 %s parameter unrecognized", kp);
- /* NOTREACHED */
- }
+ mail_esmtp_args(kp, vp, e);
}
- if (MaxMessageSize > 0 && msize > MaxMessageSize)
+ if (MaxMessageSize > 0 && e->e_msgsize > MaxMessageSize)
{
usrerr("552 Message size exceeds fixed maximum message size (%ld)",
MaxMessageSize);
/* NOTREACHED */
}
-
- if (!enoughspace(msize))
+
+ if (!enoughdiskspace(e->e_msgsize))
{
message("452 Insufficient disk space; try again later");
break;
@@ -517,11 +531,53 @@ smtp(e)
p = skipword(p, "to");
if (p == NULL)
break;
- a = parseaddr(p, NULLADDR, RF_COPYALL, ' ', NULL, e);
+ a = parseaddr(p, NULLADDR, RF_COPYALL, ' ', &delimptr, e);
if (a == NULL)
break;
- a->q_flags |= QPRIMARY;
- a = recipient(a, &e->e_sendqueue, e);
+ p = delimptr;
+
+ /* now parse ESMTP arguments */
+ while (p != NULL && *p != '\0')
+ {
+ char *kp;
+ char *vp = NULL;
+ extern void rcpt_esmtp_args __P((ADDRESS *, char *, char *, ENVELOPE *));
+
+ /* locate the beginning of the keyword */
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (*p == '\0')
+ break;
+ kp = p;
+
+ /* skip to the value portion */
+ while (isascii(*p) && isalnum(*p) || *p == '-')
+ p++;
+ if (*p == '=')
+ {
+ *p++ = '\0';
+ vp = p;
+
+ /* skip to the end of the value */
+ while (*p != '\0' && *p != ' ' &&
+ !(isascii(*p) && iscntrl(*p)) &&
+ *p != '=')
+ p++;
+ }
+
+ if (*p != '\0')
+ *p++ = '\0';
+
+ if (tTd(19, 1))
+ printf("RCPT: got arg %s=\"%s\"\n", kp,
+ vp == NULL ? "<null>" : vp);
+
+ rcpt_esmtp_args(a, kp, vp, e);
+ }
+
+ /* save in recipient list after ESMTP mods */
+ a = recipient(a, &e->e_sendqueue, 0, e);
+
if (Errors != 0)
break;
@@ -575,10 +631,18 @@ smtp(e)
/* collect the text of the message */
SmtpPhase = "collect";
- collect(TRUE, doublequeue, e);
+ buffer_errors();
+ collect(InChannel, TRUE, doublequeue, NULL, e);
+ flush_errors(TRUE);
if (Errors != 0)
goto abortmessage;
- HoldErrs = TRUE;
+
+ /* make sure we actually do delivery */
+ e->e_flags &= ~EF_CLRQUEUE;
+
+ /* from now on, we have to operate silently */
+ buffer_errors();
+ e->e_errormode = EM_MAIL;
/*
** Arrange to send to everyone.
@@ -599,42 +663,32 @@ smtp(e)
*/
SmtpPhase = "delivery";
- if (nrcpts != 1 && !doublequeue)
- {
- HoldErrs = TRUE;
- e->e_errormode = EM_MAIL;
- }
e->e_xfp = freopen(queuename(e, 'x'), "w", e->e_xfp);
id = e->e_id;
- /* send to all recipients */
- sendall(e, doublequeue ? SM_QUEUE : SM_DEFAULT);
- e->e_to = NULL;
-
- /* issue success if appropriate and reset */
- if (Errors == 0 || HoldErrs)
- message("250 %s Message accepted for delivery", id);
-
- if (bitset(EF_FATALERRS, e->e_flags) && !HoldErrs)
+ if (doublequeue)
{
- /* avoid sending back an extra message */
- e->e_flags &= ~EF_FATALERRS;
- e->e_flags |= EF_CLRQUEUE;
+ /* make sure it is in the queue */
+ queueup(e, FALSE);
}
else
{
- /* from now on, we have to operate silently */
- HoldErrs = TRUE;
- e->e_errormode = EM_MAIL;
+ /* send to all recipients */
+ sendall(e, SM_DEFAULT);
+ }
+ e->e_to = NULL;
- /* if we just queued, poke it */
- if (doublequeue && e->e_sendmode != SM_QUEUE)
- {
- extern pid_t dowork();
+ /* issue success message */
+ message("250 %s Message accepted for delivery", id);
- unlockqueue(e);
- (void) dowork(id, TRUE, TRUE, e);
- }
+ /* if we just queued, poke it */
+ if (doublequeue && e->e_sendmode != SM_QUEUE &&
+ e->e_sendmode != SM_DEFER)
+ {
+ extern pid_t dowork();
+
+ unlockqueue(e);
+ (void) dowork(id, TRUE, TRUE, e);
}
abortmessage:
@@ -651,6 +705,9 @@ smtp(e)
case CMDRSET: /* rset -- reset state */
message("250 Reset state");
+
+ /* arrange to ignore any current send list */
+ e->e_sendqueue = NULL;
e->e_flags |= EF_CLRQUEUE;
if (InChild)
finis();
@@ -668,13 +725,14 @@ smtp(e)
PrivacyFlags))
{
if (vrfy)
- message("252 Who's to say?");
+ message("252 Cannot VRFY user; try RCPT to attempt delivery (or try finger)");
else
message("502 Sorry, we do not allow this operation");
#ifdef LOG
if (LogLevel > 5)
- syslog(LOG_INFO, "%s: %s [rejected]",
- CurSmtpClient, inp);
+ syslog(LOG_INFO, "%.100s: %s [rejected]",
+ CurSmtpClient,
+ shortenstring(inp, 203));
#endif
break;
}
@@ -689,14 +747,16 @@ smtp(e)
break;
#ifdef LOG
if (LogLevel > 5)
- syslog(LOG_INFO, "%s: %s", CurSmtpClient, inp);
+ syslog(LOG_INFO, "%.100s: %s",
+ CurSmtpClient,
+ shortenstring(inp, 203));
#endif
vrfyqueue = NULL;
QuickAbort = TRUE;
if (vrfy)
e->e_flags |= EF_VRFYONLY;
while (*p != '\0' && isascii(*p) && isspace(*p))
- *p++;
+ p++;
if (*p == '\0')
{
message("501 Argument required");
@@ -704,7 +764,7 @@ smtp(e)
}
else
{
- (void) sendtolist(p, NULLADDR, &vrfyqueue, e);
+ (void) sendtolist(p, NULLADDR, &vrfyqueue, 0, e);
}
if (Errors != 0)
{
@@ -718,6 +778,8 @@ smtp(e)
}
while (vrfyqueue != NULL)
{
+ extern void printvrfyaddr __P((ADDRESS *, bool));
+
a = vrfyqueue;
while ((a = a->q_next) != NULL &&
bitset(QDONTSEND|QBADADDR, a->q_flags))
@@ -742,6 +804,9 @@ smtp(e)
message("221 %s closing connection", MyHostName);
doquit:
+ /* arrange to ignore any current send list */
+ e->e_sendqueue = NULL;
+
/* avoid future 050 messages */
disconnect(1, e);
@@ -786,8 +851,8 @@ doquit:
# ifdef LOG
if (LogLevel > 0)
syslog(LOG_CRIT,
- "\"%s\" command from %s (%s)",
- c->cmdname, peerhostname,
+ "\"%s\" command from %.100s (%.100s)",
+ c->cmdname, CurSmtpClient,
anynet_ntoa(&RealHostAddr));
# endif
/* FALL THROUGH */
@@ -847,7 +912,7 @@ skipword(p, w)
{
syntax:
message("501 Syntax error in parameters scanning \"%s\"",
- firstp);
+ shortenstring(firstp, 203));
Errors++;
return (NULL);
}
@@ -865,6 +930,183 @@ skipword(p, w)
return (p);
}
/*
+** MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line
+**
+** Parameters:
+** kp -- the parameter key.
+** vp -- the value of that parameter.
+** e -- the envelope.
+**
+** Returns:
+** none.
+*/
+
+void
+mail_esmtp_args(kp, vp, e)
+ char *kp;
+ char *vp;
+ ENVELOPE *e;
+{
+ if (strcasecmp(kp, "size") == 0)
+ {
+ if (vp == NULL)
+ {
+ usrerr("501 SIZE requires a value");
+ /* NOTREACHED */
+ }
+# if defined(__STDC__) && !defined(BROKEN_ANSI_LIBRARY)
+ e->e_msgsize = strtoul(vp, (char **) NULL, 10);
+# else
+ e->e_msgsize = strtol(vp, (char **) NULL, 10);
+# endif
+ }
+ else if (strcasecmp(kp, "body") == 0)
+ {
+ if (vp == NULL)
+ {
+ usrerr("501 BODY requires a value");
+ /* NOTREACHED */
+ }
+ else if (strcasecmp(vp, "8bitmime") == 0)
+ {
+ SevenBitInput = FALSE;
+ }
+ else if (strcasecmp(vp, "7bit") == 0)
+ {
+ SevenBitInput = TRUE;
+ }
+ else
+ {
+ usrerr("501 Unknown BODY type %s",
+ vp);
+ /* NOTREACHED */
+ }
+ e->e_bodytype = newstr(vp);
+ }
+ else if (strcasecmp(kp, "envid") == 0)
+ {
+ if (vp == NULL)
+ {
+ usrerr("501 ENVID requires a value");
+ /* NOTREACHED */
+ }
+ if (!xtextok(vp))
+ {
+ usrerr("501 Syntax error in ENVID parameter value");
+ /* NOTREACHED */
+ }
+ if (e->e_envid != NULL)
+ {
+ usrerr("501 Duplicate ENVID parameter");
+ /* NOTREACHED */
+ }
+ e->e_envid = newstr(vp);
+ }
+ else if (strcasecmp(kp, "ret") == 0)
+ {
+ if (vp == NULL)
+ {
+ usrerr("501 RET requires a value");
+ /* NOTREACHED */
+ }
+ if (bitset(EF_RET_PARAM, e->e_flags))
+ {
+ usrerr("501 Duplicate RET parameter");
+ /* NOTREACHED */
+ }
+ e->e_flags |= EF_RET_PARAM;
+ if (strcasecmp(vp, "hdrs") == 0)
+ e->e_flags |= EF_NO_BODY_RETN;
+ else if (strcasecmp(vp, "full") != 0)
+ {
+ usrerr("501 Bad argument \"%s\" to RET", vp);
+ /* NOTREACHED */
+ }
+ }
+ else
+ {
+ usrerr("501 %s parameter unrecognized", kp);
+ /* NOTREACHED */
+ }
+}
+ /*
+** RCPT_ESMTP_ARGS -- process ESMTP arguments from RCPT line
+**
+** Parameters:
+** a -- the address corresponding to the To: parameter.
+** kp -- the parameter key.
+** vp -- the value of that parameter.
+** e -- the envelope.
+**
+** Returns:
+** none.
+*/
+
+void
+rcpt_esmtp_args(a, kp, vp, e)
+ ADDRESS *a;
+ char *kp;
+ char *vp;
+ ENVELOPE *e;
+{
+ if (strcasecmp(kp, "notify") == 0)
+ {
+ char *p;
+
+ if (vp == NULL)
+ {
+ usrerr("501 NOTIFY requires a value");
+ /* NOTREACHED */
+ }
+ a->q_flags &= ~(QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY);
+ a->q_flags |= QHASNOTIFY;
+ if (strcasecmp(vp, "never") == 0)
+ return;
+ for (p = vp; p != NULL; vp = p)
+ {
+ p = strchr(p, ',');
+ if (p != NULL)
+ *p++ = '\0';
+ if (strcasecmp(vp, "success") == 0)
+ a->q_flags |= QPINGONSUCCESS;
+ else if (strcasecmp(vp, "failure") == 0)
+ a->q_flags |= QPINGONFAILURE;
+ else if (strcasecmp(vp, "delay") == 0)
+ a->q_flags |= QPINGONDELAY;
+ else
+ {
+ usrerr("501 Bad argument \"%s\" to NOTIFY",
+ vp);
+ /* NOTREACHED */
+ }
+ }
+ }
+ else if (strcasecmp(kp, "orcpt") == 0)
+ {
+ if (vp == NULL)
+ {
+ usrerr("501 ORCPT requires a value");
+ /* NOTREACHED */
+ }
+ if (strchr(vp, ';') == NULL || !xtextok(vp))
+ {
+ usrerr("501 Syntax error in ORCPT parameter value");
+ /* NOTREACHED */
+ }
+ if (a->q_orcpt != NULL)
+ {
+ usrerr("501 Duplicate ORCPT parameter");
+ /* NOTREACHED */
+ }
+ a->q_orcpt = newstr(vp);
+ }
+ else
+ {
+ usrerr("501 %s parameter unrecognized", kp);
+ /* NOTREACHED */
+ }
+}
+ /*
** PRINTVRFYADDR -- print an entry in the verify queue
**
** Parameters:
@@ -878,6 +1120,7 @@ skipword(p, w)
** Prints the appropriate 250 codes.
*/
+void
printvrfyaddr(a, last)
register ADDRESS *a;
bool last;
@@ -905,66 +1148,6 @@ printvrfyaddr(a, last)
}
}
/*
-** HELP -- implement the HELP command.
-**
-** Parameters:
-** topic -- the topic we want help for.
-**
-** Returns:
-** none.
-**
-** Side Effects:
-** outputs the help file to message output.
-*/
-
-help(topic)
- char *topic;
-{
- register FILE *hf;
- int len;
- char buf[MAXLINE];
- bool noinfo;
-
- if (HelpFile == NULL || (hf = fopen(HelpFile, "r")) == NULL)
- {
- /* no help */
- errno = 0;
- message("502 HELP not implemented");
- return;
- }
-
- if (topic == NULL || *topic == '\0')
- topic = "smtp";
- else
- makelower(topic);
-
- len = strlen(topic);
- noinfo = TRUE;
-
- while (fgets(buf, sizeof buf, hf) != NULL)
- {
- if (strncmp(buf, topic, len) == 0)
- {
- register char *p;
-
- p = strchr(buf, '\t');
- if (p == NULL)
- p = buf;
- else
- p++;
- fixcrlf(p, TRUE);
- message("214-%s", p);
- noinfo = FALSE;
- }
- }
-
- if (noinfo)
- message("504 HELP topic unknown");
- else
- message("214 End of HELP info");
- (void) fclose(hf);
-}
- /*
** RUNINCHILD -- return twice -- once in the child, then in the parent again
**
** Parameters:
@@ -978,6 +1161,7 @@ help(topic)
** none.
*/
+int
runinchild(label, e)
char *label;
register ENVELOPE *e;
@@ -989,7 +1173,7 @@ runinchild(label, e)
childpid = dofork();
if (childpid < 0)
{
- syserr("%s: cannot fork", label);
+ syserr("451 %s: cannot fork", label);
return (1);
}
if (childpid > 0)
@@ -997,12 +1181,12 @@ runinchild(label, e)
auto int st;
/* parent -- wait for child to complete */
- setproctitle("server %s child wait", CurHostName);
+ setproctitle("server %s child wait", CurSmtpClient);
st = waitfor(childpid);
if (st == -1)
- syserr("%s: lost child", label);
+ syserr("451 %s: lost child", label);
else if (!WIFEXITED(st))
- syserr("%s: died on signal %d",
+ syserr("451 %s: died on signal %d",
label, st & 0177);
/* if we exited on a QUIT command, complete the process */
@@ -1030,3 +1214,72 @@ runinchild(label, e)
}
# endif /* SMTP */
+ /*
+** HELP -- implement the HELP command.
+**
+** Parameters:
+** topic -- the topic we want help for.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** outputs the help file to message output.
+*/
+
+void
+help(topic)
+ char *topic;
+{
+ register FILE *hf;
+ int len;
+ bool noinfo;
+ char buf[MAXLINE];
+ extern char Version[];
+
+
+ if (HelpFile == NULL || (hf = fopen(HelpFile, "r")) == NULL)
+ {
+ /* no help */
+ errno = 0;
+ message("502 Sendmail %s -- HELP not implemented", Version);
+ return;
+ }
+
+ if (topic == NULL || *topic == '\0')
+ {
+ topic = "smtp";
+ message("214-This is Sendmail version %s", Version);
+ noinfo = FALSE;
+ }
+ else
+ {
+ makelower(topic);
+ noinfo = TRUE;
+ }
+
+ len = strlen(topic);
+
+ while (fgets(buf, sizeof buf, hf) != NULL)
+ {
+ if (strncmp(buf, topic, len) == 0)
+ {
+ register char *p;
+
+ p = strchr(buf, '\t');
+ if (p == NULL)
+ p = buf;
+ else
+ p++;
+ fixcrlf(p, TRUE);
+ message("214-%s", p);
+ noinfo = FALSE;
+ }
+ }
+
+ if (noinfo)
+ message("504 HELP topic \"%.10s\" unknown", topic);
+ else
+ message("214 End of HELP info");
+ (void) fclose(hf);
+}
diff --git a/usr.sbin/sendmail/src/sysexits.h b/usr.sbin/sendmail/src/sysexits.h
deleted file mode 100644
index 464cb11..0000000
--- a/usr.sbin/sendmail/src/sysexits.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 1987, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)sysexits.h 8.1 (Berkeley) 6/2/93
- */
-
-#ifndef _SYSEXITS_H_
-#define _SYSEXITS_H_
-
-/*
- * SYSEXITS.H -- Exit status codes for system programs.
- *
- * This include file attempts to categorize possible error
- * exit statuses for system programs, notably delivermail
- * and the Berkeley network.
- *
- * Error numbers begin at EX__BASE to reduce the possibility of
- * clashing with other exit statuses that random programs may
- * already return. The meaning of the codes is approximately
- * as follows:
- *
- * EX_USAGE -- The command was used incorrectly, e.g., with
- * the wrong number of arguments, a bad flag, a bad
- * syntax in a parameter, or whatever.
- * EX_DATAERR -- The input data was incorrect in some way.
- * This should only be used for user's data & not
- * system files.
- * EX_NOINPUT -- An input file (not a system file) did not
- * exist or was not readable. This could also include
- * errors like "No message" to a mailer (if it cared
- * to catch it).
- * EX_NOUSER -- The user specified did not exist. This might
- * be used for mail addresses or remote logins.
- * EX_NOHOST -- The host specified did not exist. This is used
- * in mail addresses or network requests.
- * EX_UNAVAILABLE -- A service is unavailable. This can occur
- * if a support program or file does not exist. This
- * can also be used as a catchall message when something
- * you wanted to do doesn't work, but you don't know
- * why.
- * EX_SOFTWARE -- An internal software error has been detected.
- * This should be limited to non-operating system related
- * errors as possible.
- * EX_OSERR -- An operating system error has been detected.
- * This is intended to be used for such things as "cannot
- * fork", "cannot create pipe", or the like. It includes
- * things like getuid returning a user that does not
- * exist in the passwd file.
- * EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp,
- * etc.) does not exist, cannot be opened, or has some
- * sort of error (e.g., syntax error).
- * EX_CANTCREAT -- A (user specified) output file cannot be
- * created.
- * EX_IOERR -- An error occurred while doing I/O on some file.
- * EX_TEMPFAIL -- temporary failure, indicating something that
- * is not really an error. In sendmail, this means
- * that a mailer (e.g.) could not create a connection,
- * and the request should be reattempted later.
- * EX_PROTOCOL -- the remote system returned something that
- * was "not possible" during a protocol exchange.
- * EX_NOPERM -- You did not have sufficient permission to
- * perform the operation. This is not intended for
- * file system problems, which should use NOINPUT or
- * CANTCREAT, but rather for higher level permissions.
- */
-
-#define EX_OK 0 /* successful termination */
-
-#define EX__BASE 64 /* base value for error messages */
-
-#define EX_USAGE 64 /* command line usage error */
-#define EX_DATAERR 65 /* data format error */
-#define EX_NOINPUT 66 /* cannot open input */
-#define EX_NOUSER 67 /* addressee unknown */
-#define EX_NOHOST 68 /* host name unknown */
-#define EX_UNAVAILABLE 69 /* service unavailable */
-#define EX_SOFTWARE 70 /* internal software error */
-#define EX_OSERR 71 /* system error (e.g., can't fork) */
-#define EX_OSFILE 72 /* critical OS file missing */
-#define EX_CANTCREAT 73 /* can't create (user) output file */
-#define EX_IOERR 74 /* input/output error */
-#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */
-#define EX_PROTOCOL 76 /* remote error in protocol */
-#define EX_NOPERM 77 /* permission denied */
-#define EX_CONFIG 78 /* configuration error */
-
-#define EX__MAX 78 /* maximum listed value */
-
-#endif /* !_SYSEXITS_H_ */
diff --git a/usr.sbin/sendmail/src/udb.c b/usr.sbin/sendmail/src/udb.c
index 4739a08..bb83bef 100644
--- a/usr.sbin/sendmail/src/udb.c
+++ b/usr.sbin/sendmail/src/udb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -35,21 +35,30 @@
#include "sendmail.h"
#ifndef lint
-#ifdef USERDB
-static char sccsid [] = "@(#)udb.c 8.8 (Berkeley) 4/14/94 (with USERDB)";
+#if USERDB
+static char sccsid [] = "@(#)udb.c 8.32 (Berkeley) 11/18/95 (with USERDB)";
#else
-static char sccsid [] = "@(#)udb.c 8.8 (Berkeley) 4/14/94 (without USERDB)";
+static char sccsid [] = "@(#)udb.c 8.32 (Berkeley) 11/18/95 (without USERDB)";
#endif
#endif
-#ifdef USERDB
+#if USERDB
#include <errno.h>
-#include <netdb.h>
-#include <db.h>
+
+#ifdef NEWDB
+# include <db.h>
+#else
+# define DBT struct _data_base_thang_
+DBT
+{
+ void *data; /* pointer to data */
+ size_t size; /* length of data */
+};
+#endif
#ifdef HESIOD
-#include <hesiod.h>
+# include <hesiod.h>
#endif /* HESIOD */
/*
@@ -82,6 +91,7 @@ struct udbent
} udb_forward;
#define udb_fwdhost udb_u.udb_forward._udb_fwdhost
+#ifdef NEWDB
/* type UE_FETCH -- lookup in local database */
struct
{
@@ -90,6 +100,7 @@ struct udbent
} udb_lookup;
#define udb_dbname udb_u.udb_lookup._udb_dbname
#define udb_dbp udb_u.udb_lookup._udb_dbp
+#endif
} udb_u;
};
@@ -114,6 +125,8 @@ struct option
** Parameters:
** a -- address to expand.
** sendq -- pointer to head of sendq to put the expansions in.
+** aliaslevel -- the current alias nesting depth.
+** e -- the current envelope.
**
** Returns:
** EX_TEMPFAIL -- if something "odd" happened -- probably due
@@ -132,13 +145,13 @@ int UdbSock = -1;
bool UdbInitialized = FALSE;
int
-udbexpand(a, sendq, e)
+udbexpand(a, sendq, aliaslevel, e)
register ADDRESS *a;
ADDRESS **sendq;
+ int aliaslevel;
register ENVELOPE *e;
{
int i;
- register char *p;
DBT key;
DBT info;
bool breakout;
@@ -201,6 +214,7 @@ udbexpand(a, sendq, e)
switch (up->udb_type)
{
+#ifdef NEWDB
case UDB_DBFETCH:
key.data = keybuf;
key.size = keylen;
@@ -227,7 +241,6 @@ udbexpand(a, sendq, e)
if (bitset(EF_VRFYONLY, e->e_flags))
{
a->q_flags |= QVERIFIED;
- e->e_nrcpts++;
return EX_OK;
}
@@ -242,12 +255,11 @@ udbexpand(a, sendq, e)
message("expanded to %s", user);
#ifdef LOG
if (LogLevel >= 10)
- syslog(LOG_INFO, "%s: expand %s => %s",
- e->e_id, e->e_to, user);
+ syslog(LOG_INFO, "%s: expand %.100s => %s",
+ e->e_id, e->e_to,
+ shortenstring(user, 203));
#endif
- AliasLevel++;
- naddrs += sendtolist(user, a, sendq, e);
- AliasLevel--;
+ naddrs += sendtolist(user, a, sendq, aliaslevel + 1, e);
if (user != buf)
free(user);
@@ -299,9 +311,11 @@ udbexpand(a, sendq, e)
fprintf(e->e_xfp,
"Message delivered to mailing list %s\n",
a->q_paddr);
- e->e_flags |= EF_SENDRECEIPT;
}
+ e->e_flags |= EF_SENDRECEIPT;
+ a->q_flags |= QDELIVERED|QEXPANDED;
break;
+#endif
#ifdef HESIOD
case UDB_HESIOD:
@@ -312,12 +326,45 @@ udbexpand(a, sendq, e)
keybuf, keylen);
/* look up the key via hesiod */
i = hes_udb_get(&key, &info);
- if (i > 0 || info.size <= 0)
+ if (i < 0)
{
+ syserr("udbexpand: hesiod-get %.*s stat %d",
+ key.size, key.data, i);
+ return EX_TEMPFAIL;
+ }
+ else if (i > 0 || info.size <= 0)
+ {
+#if HES_GETMAILHOST
+ struct hes_postoffice *hp;
+#endif
+
if (tTd(28, 2))
- printf("udbexpand: no match on %s (%d)\n",
- keybuf, keylen);
+ printf("udbexpand: no match on %s (%d)\n",
+ keybuf, keylen);
+#if HES_GETMAILHOST
+ if (tTd(28, 8))
+ printf(" ... trying hes_getmailhost(%s)\n",
+ a->q_user);
+ hp = hes_getmailhost(a->q_user);
+ if (hp == NULL)
+ {
+ if (hes_error() == HES_ER_NET)
+ {
+ syserr("udbexpand: hesiod-getmail %s stat %d",
+ a->q_user, hes_error());
+ return EX_TEMPFAIL;
+ }
+ if (tTd(28, 2))
+ printf("hes_getmailhost(%s): %d\n",
+ a->q_user, hes_error();
+ continue;
+ }
+ sprintf(info.data, "%s@%s",
+ hp->po_name, hp->po_host);
+ info.size = strlen(info.data);
+#else
continue;
+#endif
}
if (tTd(28, 80))
printf("udbexpand: match %.*s: %.*s\n",
@@ -327,8 +374,6 @@ udbexpand(a, sendq, e)
if (bitset(EF_VRFYONLY, e->e_flags))
{
a->q_flags |= QVERIFIED;
- e->e_nrcpts++;
- free(info.data);
return EX_OK;
}
@@ -339,17 +384,15 @@ udbexpand(a, sendq, e)
user = xalloc(info.size + 1);
bcopy(info.data, user, info.size);
user[info.size] = '\0';
- free(info.data);
message("hesioded to %s", user);
#ifdef LOG
if (LogLevel >= 10)
- syslog(LOG_INFO, "%s: hesiod %s => %s",
- e->e_id, e->e_to, user);
+ syslog(LOG_INFO, "%s: hesiod %.100s => %s",
+ e->e_id, e->e_to,
+ shortenstring(user, 203));
#endif
- AliasLevel++;
- naddrs = sendtolist(user, a, sendq, e);
- AliasLevel--;
+ naddrs = sendtolist(user, a, sendq, aliaslevel + 1, e);
if (user != buf)
free(user);
@@ -363,12 +406,6 @@ udbexpand(a, sendq, e)
}
a->q_flags |= QDONTSEND;
}
- if (i < 0)
- {
- syserr("udbexpand: hesiod-get %.*s stat %d",
- key.size, key.data, i);
- return EX_TEMPFAIL;
- }
/*
** If this address has a -request address, reflect
@@ -386,7 +423,6 @@ udbexpand(a, sendq, e)
a->q_owner = xalloc(info.size + 1);
bcopy(info.data, a->q_owner, info.size);
a->q_owner[info.size] = '\0';
- free(info.data);
break;
#endif /* HESIOD */
@@ -405,9 +441,7 @@ udbexpand(a, sendq, e)
(void) sprintf(user, "%s@%s", a->q_user, up->udb_fwdhost);
message("expanded to %s", user);
a->q_flags &= ~QSELFREF;
- AliasLevel++;
- naddrs = sendtolist(user, a, sendq, e);
- AliasLevel--;
+ naddrs = sendtolist(user, a, sendq, aliaslevel + 1, e);
if (naddrs > 0 && !bitset(QSELFREF, a->q_flags))
{
if (tTd(28, 5))
@@ -509,6 +543,7 @@ udbmatch(user, field)
switch (up->udb_type)
{
+#ifdef NEWDB
case UDB_DBFETCH:
key.data = keybuf;
key.size = keylen;
@@ -528,6 +563,7 @@ udbmatch(user, field)
printf("udbmatch ==> %s\n", p);
return p;
break;
+#endif
#ifdef HESIOD
case UDB_HESIOD:
@@ -545,11 +581,9 @@ udbmatch(user, field)
p = xalloc(info.size + 1);
bcopy(info.data, p, info.size);
p[info.size] = '\0';
- free(info.data);
if (tTd(28, 1))
printf("udbmatch ==> %s\n", p);
return p;
- break;
#endif /* HESIOD */
}
}
@@ -572,6 +606,7 @@ udbmatch(user, field)
{
switch (up->udb_type)
{
+#ifdef NEWDB
case UDB_DBFETCH:
/* get the default case for this database */
if (up->udb_default == NULL)
@@ -613,6 +648,7 @@ udbmatch(user, field)
printf("udbmatch ==> %s\n", p);
return p;
break;
+#endif
#ifdef HESIOD
case UDB_HESIOD:
@@ -634,7 +670,6 @@ udbmatch(user, field)
up->udb_default = xalloc(info.size + 1);
bcopy(info.data, up->udb_default, info.size);
up->udb_default[info.size] = '\0';
- free(info.data);
}
else if (up->udb_default[0] == '\0')
continue;
@@ -649,7 +684,6 @@ udbmatch(user, field)
continue;
}
- free(info.data);
/* they exist -- build the actual address */
p = xalloc(strlen(user) + strlen(up->udb_default) + 2);
(void) strcpy(p, user);
@@ -667,6 +701,57 @@ udbmatch(user, field)
return NULL;
}
/*
+** UDB_MAP_LOOKUP -- look up arbitrary entry in user database map
+**
+** Parameters:
+** map -- the map being queried.
+** name -- the name to look up.
+** av -- arguments to the map lookup.
+** statp -- to get any error status.
+**
+** Returns:
+** NULL if name not found in map.
+** The rewritten name otherwise.
+*/
+
+char *
+udb_map_lookup(map, name, av, statp)
+ MAP *map;
+ char *name;
+ char **av;
+ int *statp;
+{
+ char *val;
+ char *key;
+ char keybuf[MAXNAME + 1];
+
+ if (tTd(28, 20) || tTd(38, 20))
+ printf("udb_map_lookup(%s, %s)\n", map->map_mname, name);
+
+ if (bitset(MF_NOFOLDCASE, map->map_mflags))
+ {
+ key = name;
+ }
+ else
+ {
+ int keysize = strlen(name);
+
+ if (keysize > sizeof keybuf - 1)
+ keysize = sizeof keybuf - 1;
+ bcopy(name, keybuf, keysize);
+ keybuf[keysize] = '\0';
+ makelower(keybuf);
+ key = keybuf;
+ }
+ val = udbmatch(key, map->map_file);
+ if (val == NULL)
+ return NULL;
+ if (bitset(MF_MATCHONLY, map->map_mflags))
+ return map_rewrite(map, name, strlen(name), NULL);
+ else
+ return map_rewrite(map, val, strlen(val), av);
+}
+ /*
** _UDBX_INIT -- parse the UDB specification, opening any valid entries.
**
** Parameters:
@@ -688,9 +773,7 @@ int
_udbx_init()
{
register char *p;
- int i;
register struct udbent *up;
- char buf[BUFSIZ];
if (UdbInitialized)
return EX_OK;
@@ -705,11 +788,14 @@ _udbx_init()
while (p != NULL)
{
char *spec;
- auto int rcode;
int nopts;
+# if 0
+ auto int rcode;
int nmx;
+ int i;
register struct hostent *h;
char *mxhosts[MAXMXHOSTS + 1];
+# endif
struct option opts[MAXUDBOPTS + 1];
while (*p == ' ' || *p == '\t' || *p == ',')
@@ -743,10 +829,13 @@ _udbx_init()
** since it always matches the input.
** /dbname -- search the named database on the local
** host using the Berkeley db package.
+ ** Hesiod -- search the named database with BIND
+ ** using the MIT Hesiod package.
*/
switch (*spec)
{
+#if 0
case '+': /* search remote database */
case '*': /* search remote database (expand MX) */
if (*spec == '*')
@@ -776,14 +865,14 @@ _udbx_init()
for (i = 0; i < nmx; i++)
{
- h = gethostbyname(mxhosts[i]);
+ h = sm_gethostbyname(mxhosts[i]);
if (h == NULL)
continue;
up->udb_type = UDB_REMOTE;
up->udb_addr.sin_family = h->h_addrtype;
bcopy(h->h_addr_list[0],
(char *) &up->udb_addr.sin_addr,
- sizeof up->udb_addr.sin_addr);
+ INADDRSZ);
up->udb_addr.sin_port = UdbPort;
up->udb_timeout = UdbTimeout;
up++;
@@ -796,6 +885,7 @@ _udbx_init()
(void) fcntl(UdbSock, F_SETFD, 1);
}
break;
+#endif
case '@': /* forward to remote host */
up->udb_type = UDB_FORWARD;
@@ -803,22 +893,31 @@ _udbx_init()
up++;
break;
+#ifdef HESIOD
case 'h': /* use hesiod */
case 'H':
-#ifdef HESIOD
if (strcasecmp(spec, "hesiod") != 0)
- break;
+ goto badspec;
up->udb_type = UDB_HESIOD;
up++;
-#endif /* HESIOD */
break;
+#endif /* HESIOD */
+#ifdef NEWDB
case '/': /* look up remote name */
up->udb_dbname = spec;
errno = 0;
up->udb_dbp = dbopen(spec, O_RDONLY, 0644, DB_BTREE, NULL);
if (up->udb_dbp == NULL)
{
+ if (tTd(28, 1))
+ {
+ int saveerrno = errno;
+
+ printf("dbopen(%s): %s",
+ spec, errstring(errno));
+ errno = saveerrno;
+ }
if (errno != ENOENT && errno != EACCES)
{
#ifdef LOG
@@ -834,6 +933,12 @@ _udbx_init()
up->udb_type = UDB_DBFETCH;
up++;
break;
+#endif
+
+ default:
+badspec:
+ syserr("Unknown UDB spec %s", spec);
+ break;
}
}
up->udb_type = UDB_EOLIST;
@@ -844,15 +949,21 @@ _udbx_init()
{
switch (up->udb_type)
{
+#ifdef DAEMON
case UDB_REMOTE:
printf("REMOTE: addr %s, timeo %d\n",
anynet_ntoa((SOCKADDR *) &up->udb_addr),
up->udb_timeout);
break;
+#endif
case UDB_DBFETCH:
+#ifdef NEWDB
printf("FETCH: file %s\n",
up->udb_dbname);
+#else
+ printf("FETCH\n");
+#endif
break;
case UDB_FORWARD:
@@ -880,6 +991,7 @@ _udbx_init()
*/
tempfail:
+#ifdef NEWDB
for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++)
{
if (up->udb_type == UDB_DBFETCH)
@@ -887,6 +999,7 @@ _udbx_init()
(*up->udb_dbp->close)(up->udb_dbp);
}
}
+#endif
return EX_TEMPFAIL;
}
@@ -929,20 +1042,24 @@ hes_udb_get(key, info)
{
char *name, *type;
char *p, **hp;
+ char kbuf[MAXKEY + 1];
- name = key->data;
- type = strchr(name, ':');
+ strcpy(kbuf, key->data);
+ name = kbuf;
+ type = strrchr(name, ':');
if (type == NULL)
return 1;
-
*type++ = '\0';
+ if (strchr(name, '@') != NULL)
+ return 1;
if (tTd(28, 1))
printf("hes_udb_get(%s, %s)\n", name, type);
/* make the hesiod query */
hp = hes_resolve(name, type);
- if (hp == NULL)
+ *--type = ':';
+ if (hp == NULL || hp[0] == NULL)
{
/* network problem or timeout */
if (hes_error() == HES_ER_NET)
@@ -954,19 +1071,19 @@ hes_udb_get(key, info)
{
/*
** If there are multiple matches, just return the
- ** first one and free the others.
+ ** first one.
**
** XXX These should really be returned; for example,
** XXX it is legal for :maildrop to be multi-valued.
*/
- for (p = hp[1]; p; p++)
- free(p);
-
info->data = hp[0];
info->size = (size_t) strlen(info->data);
}
+ if (tTd(28, 80))
+ printf("hes_udb_get => %s\n", *hp);
+
return 0;
}
#endif /* HESIOD */
@@ -974,9 +1091,10 @@ hes_udb_get(key, info)
#else /* not USERDB */
int
-udbexpand(a, sendq, e)
+udbexpand(a, sendq, aliaslevel, e)
ADDRESS *a;
ADDRESS **sendq;
+ int aliaslevel;
ENVELOPE *e;
{
return EX_OK;
diff --git a/usr.sbin/sendmail/src/usersmtp.c b/usr.sbin/sendmail/src/usersmtp.c
index 2850def..6233e0f 100644
--- a/usr.sbin/sendmail/src/usersmtp.c
+++ b/usr.sbin/sendmail/src/usersmtp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -36,9 +36,9 @@
#ifndef lint
#ifdef SMTP
-static char sccsid[] = "@(#)usersmtp.c 8.18 (Berkeley) 1/24/94 (with SMTP)";
+static char sccsid[] = "@(#)usersmtp.c 8.65 (Berkeley) 9/28/95 (with SMTP)";
#else
-static char sccsid[] = "@(#)usersmtp.c 8.18 (Berkeley) 1/24/94 (without SMTP)";
+static char sccsid[] = "@(#)usersmtp.c 8.65 (Berkeley) 9/28/95 (without SMTP)";
#endif
#endif /* not lint */
@@ -63,9 +63,7 @@ char SmtpError[MAXLINE] = ""; /* save failure error messages */
int SmtpPid; /* pid of mailer */
bool SmtpNeedIntro; /* need "while talking" in transcript */
-#ifdef __STDC__
-extern smtpmessage(char *f, MAILER *m, MCI *mci, ...);
-#endif
+extern void smtpmessage __P((char *f, MAILER *m, MCI *mci, ...));
/*
** SMTPINIT -- initialize SMTP.
**
@@ -83,6 +81,7 @@ extern smtpmessage(char *f, MAILER *m, MCI *mci, ...);
** creates connection and sends initial protocol.
*/
+void
smtpinit(m, mci, e)
struct mailer *m;
register MCI *mci;
@@ -105,6 +104,8 @@ smtpinit(m, mci, e)
SmtpError[0] = '\0';
CurHostName = mci->mci_host; /* XXX UGLY XXX */
+ if (CurHostName == NULL)
+ CurHostName = MyHostName;
SmtpNeedIntro = TRUE;
switch (mci->mci_state)
{
@@ -186,18 +187,16 @@ tryhelo:
** Check to see if we actually ended up talking to ourself.
** This means we didn't know about an alias or MX, or we managed
** to connect to an echo server.
- **
- ** If this code remains at all, "CheckLoopBack" should be
- ** a mailer flag. This is a MAYBENEXTRELEASE feature.
*/
p = strchr(&SmtpReplyBuffer[4], ' ');
if (p != NULL)
*p = '\0';
- if (CheckLoopBack && strcasecmp(&SmtpReplyBuffer[4], MyHostName) == 0)
+ if (!bitnset(M_NOLOOPCHECK, m->m_flags) &&
+ strcasecmp(&SmtpReplyBuffer[4], MyHostName) == 0)
{
- syserr("553 %s config error: mail loops back to myself",
- MyHostName);
+ syserr("553 %s config error: mail loops back to me (MX problem?)",
+ mci->mci_host);
mci->mci_exitstat = EX_CONFIG;
mci->mci_errno = 0;
smtpquit(m, mci, e);
@@ -244,9 +243,9 @@ tryhelo:
/*
** ESMTP_CHECK -- check to see if this implementation likes ESMTP protocol
**
-**
** Parameters:
** line -- the response line.
+** firstline -- set if this is the first line of the reply.
** m -- the mailer.
** mci -- the mailer connection info.
** e -- the envelope.
@@ -256,23 +255,24 @@ tryhelo:
*/
void
-esmtp_check(line, m, mci, e)
+esmtp_check(line, firstline, m, mci, e)
char *line;
+ bool firstline;
MAILER *m;
register MCI *mci;
ENVELOPE *e;
{
- if (strlen(line) < 5)
- return;
- line += 4;
- if (strncmp(line, "ESMTP ", 6) == 0)
+ if (strstr(line, "ESMTP") != NULL)
mci->mci_flags |= MCIF_ESMTP;
+ if (strstr(line, "8BIT-OK") != NULL)
+ mci->mci_flags |= MCIF_8BITOK;
}
/*
** HELO_OPTIONS -- process the options on a HELO line.
**
** Parameters:
** line -- the response line.
+** firstline -- set if this is the first line of the reply.
** m -- the mailer.
** mci -- the mailer connection info.
** e -- the envelope.
@@ -282,15 +282,19 @@ esmtp_check(line, m, mci, e)
*/
void
-helo_options(line, m, mci, e)
+helo_options(line, firstline, m, mci, e)
char *line;
+ bool firstline;
MAILER *m;
register MCI *mci;
ENVELOPE *e;
{
register char *p;
- if (strlen(line) < 5)
+ if (firstline)
+ return;
+
+ if (strlen(line) < (SIZE_T) 5)
return;
line += 4;
p = strchr(line, ' ');
@@ -309,6 +313,8 @@ helo_options(line, m, mci, e)
}
else if (strcasecmp(line, "expn") == 0)
mci->mci_flags |= MCIF_EXPN;
+ else if (strcasecmp(line, "dsn") == 0)
+ mci->mci_flags |= MCIF_DSN;
}
/*
** SMTPMAILFROM -- send MAIL command
@@ -319,6 +325,7 @@ helo_options(line, m, mci, e)
** e -- the envelope (including the sender to specify).
*/
+int
smtpmailfrom(m, mci, e)
struct mailer *m;
MCI *mci;
@@ -326,7 +333,8 @@ smtpmailfrom(m, mci, e)
{
int r;
char *bufp;
- char buf[MAXNAME];
+ char *bodytype;
+ char buf[MAXNAME + 1];
char optbuf[MAXLINE];
if (tTd(18, 2))
@@ -338,6 +346,64 @@ smtpmailfrom(m, mci, e)
else
strcpy(optbuf, "");
+ bodytype = e->e_bodytype;
+ if (bitset(MCIF_8BITMIME, mci->mci_flags))
+ {
+ if (bodytype == NULL &&
+ bitset(MM_MIME8BIT, MimeMode) &&
+ bitset(EF_HAS8BIT, e->e_flags) &&
+ !bitset(EF_DONT_MIME, e->e_flags) &&
+ !bitnset(M_8BITS, m->m_flags))
+ bodytype = "8BITMIME";
+ if (bodytype != NULL)
+ {
+ strcat(optbuf, " BODY=");
+ strcat(optbuf, bodytype);
+ }
+ }
+ else if (bitnset(M_8BITS, m->m_flags) ||
+ !bitset(EF_HAS8BIT, e->e_flags) ||
+ bitset(MCIF_8BITOK, mci->mci_flags))
+ {
+ /* just pass it through */
+ }
+#if MIME8TO7
+ else if (bitset(MM_CVTMIME, MimeMode) &&
+ !bitset(EF_DONT_MIME, e->e_flags) &&
+ (!bitset(MM_PASS8BIT, MimeMode) ||
+ bitset(EF_IS_MIME, e->e_flags)))
+ {
+ /* must convert from 8bit MIME format to 7bit encoded */
+ mci->mci_flags |= MCIF_CVT8TO7;
+ }
+#endif
+ else if (!bitset(MM_PASS8BIT, MimeMode))
+ {
+ /* cannot just send a 8-bit version */
+ usrerr("%s does not support 8BITMIME", mci->mci_host);
+ mci->mci_status = "5.6.3";
+ return EX_DATAERR;
+ }
+
+ if (bitset(MCIF_DSN, mci->mci_flags))
+ {
+ if (e->e_envid != NULL)
+ {
+ strcat(optbuf, " ENVID=");
+ strcat(optbuf, e->e_envid);
+ }
+
+ /* RET= parameter */
+ if (bitset(EF_RET_PARAM, e->e_flags))
+ {
+ strcat(optbuf, " RET=");
+ if (bitset(EF_NO_BODY_RETN, e->e_flags))
+ strcat(optbuf, "HDRS");
+ else
+ strcat(optbuf, "FULL");
+ }
+ }
+
/*
** Send the MAIL command.
** Designates the sender.
@@ -349,7 +415,7 @@ smtpmailfrom(m, mci, e)
!bitnset(M_NO_NULL_FROM, m->m_flags))
(void) strcpy(buf, "");
else
- expand("\201g", buf, &buf[sizeof buf - 1], e);
+ expand("\201g", buf, sizeof buf, e);
if (buf[0] == '<')
{
/* strip off <angle brackets> (put back on below) */
@@ -360,7 +426,7 @@ smtpmailfrom(m, mci, e)
}
else
bufp = buf;
- if (e->e_from.q_mailer == LocalMailer ||
+ if (bitnset(M_LOCALMAILER, e->e_from.q_mailer->m_flags) ||
!bitnset(M_FROMPATH, m->m_flags))
{
smtpmessage("MAIL From:<%s>%s", m, mci, bufp, optbuf);
@@ -373,37 +439,57 @@ 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 || REPLYTYPE(r) == 4)
+ if (r < 0 || r == 421)
{
+ /* communications failure/service shutting down */
mci->mci_exitstat = EX_TEMPFAIL;
mci->mci_errno = errno;
smtpquit(m, mci, e);
return EX_TEMPFAIL;
}
- else if (r == 250)
+ else if (REPLYTYPE(r) == 4)
+ {
+ return EX_TEMPFAIL;
+ }
+ else if (REPLYTYPE(r) == 2)
{
- mci->mci_exitstat = EX_OK;
return EX_OK;
}
+ else if (r == 501)
+ {
+ /* syntax error in arguments */
+ mci->mci_status = "5.5.2";
+ return EX_DATAERR;
+ }
+ else if (r == 553)
+ {
+ /* mailbox name not allowed */
+ mci->mci_status = "5.1.3";
+ return EX_DATAERR;
+ }
else if (r == 552)
{
- /* signal service unavailable */
- mci->mci_exitstat = EX_UNAVAILABLE;
- smtpquit(m, mci, e);
+ /* exceeded storage allocation */
+ mci->mci_status = "5.2.2";
+ return EX_UNAVAILABLE;
+ }
+ else if (REPLYTYPE(r) == 5)
+ {
+ /* unknown error */
return EX_UNAVAILABLE;
}
#ifdef LOG
if (LogLevel > 1)
{
- syslog(LOG_CRIT, "%s: SMTP MAIL protocol error: %s",
- e->e_id, SmtpReplyBuffer);
+ syslog(LOG_CRIT, "%s: %.100s: SMTP MAIL protocol error: %s",
+ e->e_id, mci->mci_host,
+ shortenstring(SmtpReplyBuffer, 403));
}
#endif
/* protocol error -- close up */
smtpquit(m, mci, e);
- mci->mci_exitstat = EX_PROTOCOL;
return EX_PROTOCOL;
}
/*
@@ -422,6 +508,7 @@ smtpmailfrom(m, mci, e)
** Sends the mail via SMTP.
*/
+int
smtprcpt(to, m, mci, e)
ADDRESS *to;
register MAILER *m;
@@ -429,30 +516,77 @@ smtprcpt(to, m, mci, e)
ENVELOPE *e;
{
register int r;
+ char optbuf[MAXLINE];
+ extern char *smtptodsn();
+
+ strcpy(optbuf, "");
+ if (bitset(MCIF_DSN, mci->mci_flags))
+ {
+ /* NOTIFY= parameter */
+ if (bitset(QHASNOTIFY, to->q_flags) &&
+ bitset(QPRIMARY, to->q_flags))
+ {
+ bool firstone = TRUE;
- smtpmessage("RCPT To:<%s>", m, mci, to->q_user);
+ strcat(optbuf, " NOTIFY=");
+ if (bitset(QPINGONSUCCESS, to->q_flags))
+ {
+ strcat(optbuf, "SUCCESS");
+ firstone = FALSE;
+ }
+ if (bitset(QPINGONFAILURE, to->q_flags))
+ {
+ if (!firstone)
+ strcat(optbuf, ",");
+ strcat(optbuf, "FAILURE");
+ firstone = FALSE;
+ }
+ if (bitset(QPINGONDELAY, to->q_flags))
+ {
+ if (!firstone)
+ strcat(optbuf, ",");
+ strcat(optbuf, "DELAY");
+ firstone = FALSE;
+ }
+ if (firstone)
+ strcat(optbuf, "NEVER");
+ }
+
+ /* ORCPT= parameter */
+ if (to->q_orcpt != NULL)
+ {
+ strcat(optbuf, " ORCPT=");
+ strcat(optbuf, to->q_orcpt);
+ }
+ }
+
+ smtpmessage("RCPT To:<%s>%s", m, mci, to->q_user, optbuf);
SmtpPhase = mci->mci_phase = "client RCPT";
setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
r = reply(m, mci, e, TimeOuts.to_rcpt, NULL);
+ to->q_rstatus = newstr(SmtpReplyBuffer);
+ to->q_status = smtptodsn(r);
+ to->q_statmta = mci->mci_host;
if (r < 0 || REPLYTYPE(r) == 4)
- return (EX_TEMPFAIL);
+ return EX_TEMPFAIL;
else if (REPLYTYPE(r) == 2)
- return (EX_OK);
+ return EX_OK;
else if (r == 550 || r == 551 || r == 553)
- return (EX_NOUSER);
- else if (r == 552 || r == 554)
- return (EX_UNAVAILABLE);
+ return EX_NOUSER;
+ else if (REPLYTYPE(r) == 5)
+ return EX_UNAVAILABLE;
#ifdef LOG
if (LogLevel > 1)
{
- syslog(LOG_CRIT, "%s: SMTP RCPT protocol error: %s",
- e->e_id, SmtpReplyBuffer);
+ syslog(LOG_CRIT, "%s: %.100s: SMTP RCPT protocol error: %s",
+ e->e_id, mci->mci_host,
+ shortenstring(SmtpReplyBuffer, 403));
}
#endif
- return (EX_PROTOCOL);
+ return EX_PROTOCOL;
}
/*
** SMTPDATA -- send the data and clean up the transaction.
@@ -469,8 +603,9 @@ smtprcpt(to, m, mci, e)
*/
static jmp_buf CtxDataTimeout;
-static int datatimeout();
+static void datatimeout();
+int
smtpdata(m, mci, e)
struct mailer *m;
register MCI *mci;
@@ -496,20 +631,21 @@ smtpdata(m, mci, e)
if (r < 0 || REPLYTYPE(r) == 4)
{
smtpquit(m, mci, e);
- return (EX_TEMPFAIL);
+ return EX_TEMPFAIL;
}
- else if (r == 554)
+ else if (REPLYTYPE(r) == 5)
{
smtprset(m, mci, e);
- return (EX_UNAVAILABLE);
+ return EX_UNAVAILABLE;
}
else if (r != 354)
{
#ifdef LOG
if (LogLevel > 1)
{
- syslog(LOG_CRIT, "%s: SMTP DATA-1 protocol error: %s",
- e->e_id, SmtpReplyBuffer);
+ syslog(LOG_CRIT, "%s: %.100s: SMTP DATA-1 protocol error: %s",
+ e->e_id, mci->mci_host,
+ shortenstring(SmtpReplyBuffer, 403));
}
#endif
smtprset(m, mci, e);
@@ -533,16 +669,22 @@ smtpdata(m, mci, e)
}
timeout = e->e_msgsize / 16;
- if (timeout < (time_t) 60)
- timeout = (time_t) 60;
- timeout += e->e_nrcpts * 90;
+ if (timeout < (time_t) 600)
+ timeout = (time_t) 600;
+ timeout += e->e_nrcpts * 300;
ev = setevent(timeout, datatimeout, 0);
- /* now output the actual message */
- (*e->e_puthdr)(mci, e);
- putline("\n", mci);
+ /*
+ ** Output the actual message.
+ */
+
+ (*e->e_puthdr)(mci, e->e_header, e);
(*e->e_putbody)(mci, e, NULL);
+ /*
+ ** Cleanup after sending message.
+ */
+
clrevent(ev);
if (ferror(mci->mci_out))
@@ -569,28 +711,31 @@ smtpdata(m, mci, e)
if (r < 0)
{
smtpquit(m, mci, e);
- return (EX_TEMPFAIL);
+ return EX_TEMPFAIL;
}
mci->mci_state = MCIS_OPEN;
e->e_statmsg = newstr(&SmtpReplyBuffer[4]);
if (REPLYTYPE(r) == 4)
- return (EX_TEMPFAIL);
- else if (r == 250)
- return (EX_OK);
- else if (r == 552 || r == 554)
- return (EX_UNAVAILABLE);
+ return EX_TEMPFAIL;
+ else if (REPLYCLASS(r) != 5)
+ /* fall through */ ;
+ else if (REPLYTYPE(r) == 2)
+ return EX_OK;
+ else if (REPLYTYPE(r) == 5)
+ return EX_UNAVAILABLE;
#ifdef LOG
if (LogLevel > 1)
{
- syslog(LOG_CRIT, "%s: SMTP DATA-2 protocol error: %s",
- e->e_id, SmtpReplyBuffer);
+ syslog(LOG_CRIT, "%s: %.100s: SMTP DATA-2 protocol error: %s",
+ e->e_id, mci->mci_host,
+ shortenstring(SmtpReplyBuffer, 403));
}
#endif
- return (EX_PROTOCOL);
+ return EX_PROTOCOL;
}
-static int
+static void
datatimeout()
{
longjmp(CtxDataTimeout, 1);
@@ -608,6 +753,7 @@ datatimeout()
** sends the final protocol and closes the connection.
*/
+void
smtpquit(m, mci, e)
register MAILER *m;
register MCI *mci;
@@ -647,6 +793,7 @@ smtpquit(m, mci, e)
** SMTPRSET -- send a RSET (reset) command
*/
+void
smtprset(m, mci, e)
register MAILER *m;
register MCI *mci;
@@ -670,6 +817,7 @@ smtprset(m, mci, e)
** SMTPPROBE -- check the connection state
*/
+int
smtpprobe(mci)
register MCI *mci;
{
@@ -693,9 +841,8 @@ smtpprobe(mci)
** mci -- the mailer connection info structure.
** e -- the current envelope.
** timeout -- the timeout for reads.
-** pfunc -- processing function for second and subsequent
-** lines of response -- if null, no special
-** processing is done.
+** pfunc -- processing function called on each line of response.
+** If null, no special processing is done.
**
** Returns:
** reply code it reads.
@@ -704,6 +851,7 @@ smtpprobe(mci)
** flushes the mail file.
*/
+int
reply(m, mci, e, timeout, pfunc)
MAILER *m;
MCI *mci;
@@ -749,7 +897,6 @@ reply(m, mci, e, timeout, pfunc)
if (p == NULL)
{
bool oldholderrs;
- extern char MsgBuf[]; /* err.c */
/* if the remote end closed early, fake an error */
if (errno == 0)
@@ -770,16 +917,18 @@ reply(m, mci, e, timeout, pfunc)
pause();
mci->mci_state = MCIS_ERROR;
smtpquit(m, mci, e);
-#ifdef XDEBUG
+#if XDEBUG
{
char wbuf[MAXLINE];
char *p = wbuf;
+
if (e->e_to != NULL)
{
- sprintf(p, "%s... ", e->e_to);
+ sprintf(p, "%s... ",
+ shortenstring(e->e_to, 203));
p += strlen(p);
}
- sprintf(p, "reply(%s) during %s",
+ sprintf(p, "reply(%.100s) during %s",
mci->mci_host, SmtpPhase);
checkfd012(wbuf);
}
@@ -815,8 +964,8 @@ reply(m, mci, e, timeout, pfunc)
nmessage("050 %s", bufp);
/* process the line */
- if (pfunc != NULL && !firstline)
- (*pfunc)(bufp, m, mci, e);
+ if (pfunc != NULL)
+ (*pfunc)(bufp, firstline, m, mci, e);
firstline = FALSE;
@@ -871,6 +1020,7 @@ reply(m, mci, e, timeout, pfunc)
*/
/*VARARGS1*/
+void
#ifdef __STDC__
smtpmessage(char *f, MAILER *m, MCI *mci, ...)
#else
@@ -884,7 +1034,7 @@ smtpmessage(f, m, mci, va_alist)
VA_LOCAL_DECL
VA_START(mci);
- (void) vsprintf(SmtpMsgBuffer, f, ap);
+ (void) vsnprintf(SmtpMsgBuffer, sizeof SmtpMsgBuffer, f, ap);
VA_END;
if (tTd(18, 1) || Verbose)
diff --git a/usr.sbin/sendmail/src/util.c b/usr.sbin/sendmail/src/util.c
index b7e1d14..eac336e 100644
--- a/usr.sbin/sendmail/src/util.c
+++ b/usr.sbin/sendmail/src/util.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1983, 1995 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)util.c 8.39.1.5 (Berkeley) 3/5/95";
+static char sccsid[] = "@(#)util.c 8.84 (Berkeley) 11/18/95";
#endif /* not lint */
# include "sendmail.h"
@@ -57,6 +57,7 @@ static char sccsid[] = "@(#)util.c 8.39.1.5 (Berkeley) 3/5/95";
** deliver
*/
+void
stripquotes(s)
char *s;
{
@@ -107,8 +108,7 @@ xalloc(sz)
p = malloc((unsigned) sz);
if (p == NULL)
{
- syserr("Out of memory!!");
- abort();
+ syserr("!Out of memory!!");
/* exit(EX_UNAVAILABLE); */
}
return (p);
@@ -208,6 +208,7 @@ copyqueue(addr)
** prints av.
*/
+void
printav(av)
register char **av;
{
@@ -253,8 +254,9 @@ lower(c)
** output to stdout
*/
+void
xputs(s)
- register char *s;
+ register const char *s;
{
register int c;
register struct metamac *mp;
@@ -269,11 +271,20 @@ xputs(s)
{
if (!isascii(c))
{
- if (c == MATCHREPL || c == MACROEXPAND)
+ if (c == MATCHREPL)
{
putchar('$');
continue;
}
+ if (c == MACROEXPAND)
+ {
+ putchar('$');
+ if (strchr("=~&?", *s) != NULL)
+ putchar(*s++);
+ if (bitset(0200, *s))
+ printf("{%s}", macname(*s++ & 0377));
+ continue;
+ }
for (mp = MetaMacros; mp->metaname != '\0'; mp++)
{
if ((mp->metaval & 0377) == c)
@@ -282,6 +293,12 @@ xputs(s)
break;
}
}
+ if (c == MATCHCLASS || c == MATCHNCLASS)
+ {
+ if (!bitset(0200, *s))
+ continue;
+ printf("{%s}", macname(*s++ & 0377));
+ }
if (mp->metaname != '\0')
continue;
(void) putchar('\\');
@@ -296,9 +313,6 @@ xputs(s)
/* wasn't a meta-macro -- find another way to print it */
switch (c)
{
- case '\0':
- continue;
-
case '\n':
c = 'n';
break;
@@ -316,6 +330,8 @@ xputs(s)
(void) putchar(c ^ 0100);
continue;
}
+ (void) putchar('\\');
+ (void) putchar(c);
}
(void) fflush(stdout);
}
@@ -336,6 +352,7 @@ xputs(s)
** parse
*/
+void
makelower(p)
register char *p;
{
@@ -365,6 +382,7 @@ makelower(p)
** none.
*/
+void
buildfname(gecos, login, buf)
register char *gecos;
char *login;
@@ -415,6 +433,8 @@ buildfname(gecos, login, buf)
** SFF_MUSTOWN -- "uid" must own this file.
** SFF_NOSLINK -- file cannot be a symbolic link.
** mode -- mode bits that must match.
+** st -- if set, points to a stat structure that will
+** get the stat info for the file.
**
** Returns:
** 0 if fn exists, is owned by uid, and matches mode.
@@ -438,104 +458,195 @@ buildfname(gecos, login, buf)
# define S_IXUSR (S_IEXEC)
#endif
+#define ST_MODE_NOFILE 0171147 /* unlikely to occur */
+
int
-safefile(fn, uid, gid, uname, flags, mode)
+safefile(fn, uid, gid, uname, flags, mode, st)
char *fn;
uid_t uid;
gid_t gid;
char *uname;
int flags;
int mode;
+ struct stat *st;
{
register char *p;
register struct group *gr = NULL;
+ int file_errno = 0;
struct stat stbuf;
+ struct stat fstbuf;
- if (tTd(54, 4))
+ if (tTd(44, 4))
printf("safefile(%s, uid=%d, gid=%d, flags=%x, mode=%o):\n",
fn, uid, gid, flags, mode);
errno = 0;
+ if (st == NULL)
+ st = &fstbuf;
- for (p = fn; (p = strchr(++p, '/')) != NULL; *p = '/')
+ /* first check to see if the file exists at all */
+#ifdef HASLSTAT
+ if ((bitset(SFF_NOSLINK, flags) ? lstat(fn, st)
+ : stat(fn, st)) < 0)
+#else
+ if (stat(fn, st) < 0)
+#endif
{
- *p = '\0';
- if (stat(fn, &stbuf) < 0)
- break;
- if (uid == 0 && !bitset(SFF_ROOTOK, flags))
+ file_errno = errno;
+ }
+ else if (bitset(SFF_SETUIDOK, flags) &&
+ !bitset(S_IXUSR|S_IXGRP|S_IXOTH, st->st_mode) &&
+ S_ISREG(st->st_mode))
+ {
+ /*
+ ** If final file is setuid, run as the owner of that
+ ** file. Gotta be careful not to reveal anything too
+ ** soon here!
+ */
+
+#ifdef SUID_ROOT_FILES_OK
+ if (bitset(S_ISUID, st->st_mode))
+#else
+ if (bitset(S_ISUID, st->st_mode) && st->st_uid != 0)
+#endif
{
- if (bitset(S_IXOTH, stbuf.st_mode))
- continue;
- break;
+ uid = st->st_uid;
+ uname = NULL;
}
- if (stbuf.st_uid == uid && bitset(S_IXUSR, stbuf.st_mode))
- continue;
- if (stbuf.st_gid == gid && bitset(S_IXGRP, stbuf.st_mode))
- continue;
-#ifndef NO_GROUP_SET
- if (uname != NULL &&
- ((gr != NULL && gr->gr_gid == stbuf.st_gid) ||
- (gr = getgrgid(stbuf.st_gid)) != NULL))
- {
- register char **gp;
+#ifdef SUID_ROOT_FILES_OK
+ if (bitset(S_ISGID, st->st_mode))
+#else
+ if (bitset(S_ISGID, st->st_mode) && st->st_gid != 0)
+#endif
+ gid = st->st_gid;
+ }
- for (gp = gr->gr_mem; *gp != NULL; gp++)
- if (strcmp(*gp, uname) == 0)
- break;
- if (*gp != NULL && bitset(S_IXGRP, stbuf.st_mode))
+ if (!bitset(SFF_NOPATHCHECK, flags) ||
+ (uid == 0 && !bitset(SFF_ROOTOK, flags)))
+ {
+ /* check the path to the file for acceptability */
+ for (p = fn; (p = strchr(++p, '/')) != NULL; *p = '/')
+ {
+ *p = '\0';
+ if (stat(fn, &stbuf) < 0)
+ break;
+ if (uid == 0 && bitset(S_IWGRP|S_IWOTH, stbuf.st_mode))
+ message("051 WARNING: writable directory %s",
+ fn);
+ if (uid == 0 && !bitset(SFF_ROOTOK, flags))
+ {
+ if (bitset(S_IXOTH, stbuf.st_mode))
+ continue;
+ break;
+ }
+ if (stbuf.st_uid == uid &&
+ bitset(S_IXUSR, stbuf.st_mode))
continue;
- }
+ if (stbuf.st_gid == gid &&
+ bitset(S_IXGRP, stbuf.st_mode))
+ continue;
+#ifndef NO_GROUP_SET
+ if (uname != NULL &&
+ ((gr != NULL && gr->gr_gid == stbuf.st_gid) ||
+ (gr = getgrgid(stbuf.st_gid)) != NULL))
+ {
+ register char **gp;
+
+ for (gp = gr->gr_mem; gp != NULL && *gp != NULL; gp++)
+ if (strcmp(*gp, uname) == 0)
+ break;
+ if (gp != NULL && *gp != NULL &&
+ bitset(S_IXGRP, stbuf.st_mode))
+ continue;
+ }
#endif
- if (!bitset(S_IXOTH, stbuf.st_mode))
- break;
+ if (!bitset(S_IXOTH, stbuf.st_mode))
+ break;
+ }
+ if (p != NULL)
+ {
+ int ret = errno;
+
+ if (ret == 0)
+ ret = EACCES;
+ if (tTd(44, 4))
+ printf("\t[dir %s] %s\n", fn, errstring(ret));
+ *p = '/';
+ return ret;
+ }
}
- if (p != NULL)
- {
- int ret = errno;
- if (ret == 0)
- ret = EACCES;
- if (tTd(54, 4))
- printf("\t[dir %s] %s\n", fn, errstring(ret));
- *p = '/';
- return ret;
- }
+ /*
+ ** If the target file doesn't exist, check the directory to
+ ** ensure that it is writable by this user.
+ */
-#ifdef HASLSTAT
- if ((bitset(SFF_NOSLINK, flags) ? lstat(fn, &stbuf)
- : stat(fn, &stbuf)) < 0)
-#else
- if (stat(fn, &stbuf) < 0)
-#endif
+ if (file_errno != 0)
{
- int ret = errno;
+ int ret = file_errno;
- if (tTd(54, 4))
+ if (tTd(44, 4))
printf("\t%s\n", errstring(ret));
errno = 0;
+ if (!bitset(SFF_CREAT, flags))
+ return ret;
+
+ /* check to see if legal to create the file */
+ p = strrchr(fn, '/');
+ if (p == NULL)
+ return ENOTDIR;
+ *p = '\0';
+ if (stat(fn, &stbuf) >= 0)
+ {
+ int md = S_IWRITE|S_IEXEC;
+ if (stbuf.st_uid != uid)
+ md >>= 6;
+ if ((stbuf.st_mode & md) != md)
+ errno = EACCES;
+ }
+ ret = errno;
+ if (tTd(44, 4))
+ printf("\t[final dir %s uid %d mode %o] %s\n",
+ fn, stbuf.st_uid, stbuf.st_mode,
+ errstring(ret));
+ *p = '/';
+ st->st_mode = ST_MODE_NOFILE;
return ret;
}
#ifdef S_ISLNK
- if (bitset(SFF_NOSLINK, flags) && S_ISLNK(stbuf.st_mode))
+ if (bitset(SFF_NOSLINK, flags) && S_ISLNK(st->st_mode))
{
- if (tTd(54, 4))
- printf("\t[slink mode %o]\tEPERM\n", stbuf.st_mode);
+ if (tTd(44, 4))
+ printf("\t[slink mode %o]\tEPERM\n", st->st_mode);
return EPERM;
}
#endif
+ if (bitset(SFF_REGONLY, flags) && !S_ISREG(st->st_mode))
+ {
+ if (tTd(44, 4))
+ printf("\t[non-reg mode %o]\tEPERM\n", st->st_mode);
+ return EPERM;
+ }
+ if (bitset(S_IWUSR|S_IWGRP|S_IWOTH, mode) &&
+ bitset(S_IXUSR|S_IXGRP|S_IXOTH, st->st_mode))
+ {
+ if (tTd(44, 4))
+ printf("\t[exec bits %o]\tEPERM]\n", st->st_mode);
+ return EPERM;
+ }
if (uid == 0 && !bitset(SFF_ROOTOK, flags))
mode >>= 6;
- else if (stbuf.st_uid != uid)
+ else if (st->st_uid != uid)
{
mode >>= 3;
- if (stbuf.st_gid == gid)
+ if (st->st_gid == gid)
;
#ifndef NO_GROUP_SET
else if (uname != NULL &&
- ((gr != NULL && gr->gr_gid == stbuf.st_gid) ||
- (gr = getgrgid(stbuf.st_gid)) != NULL))
+ ((gr != NULL && gr->gr_gid == st->st_gid) ||
+ (gr = getgrgid(st->st_gid)) != NULL))
{
register char **gp;
@@ -549,22 +660,104 @@ safefile(fn, uid, gid, uname, flags, mode)
else
mode >>= 3;
}
- if (tTd(54, 4))
+ if (tTd(44, 4))
printf("\t[uid %d, stat %o, mode %o] ",
- stbuf.st_uid, stbuf.st_mode, mode);
- if ((stbuf.st_uid == uid || stbuf.st_uid == 0 ||
+ st->st_uid, st->st_mode, mode);
+ if ((st->st_uid == uid || st->st_uid == 0 ||
!bitset(SFF_MUSTOWN, flags)) &&
- (stbuf.st_mode & mode) == mode)
+ (st->st_mode & mode) == mode)
{
- if (tTd(54, 4))
+ if (tTd(44, 4))
printf("\tOK\n");
return 0;
}
- if (tTd(54, 4))
+ if (tTd(44, 4))
printf("\tEACCES\n");
return EACCES;
}
/*
+** SAFEFOPEN -- do a file open with extra checking
+**
+** Parameters:
+** fn -- the file name to open.
+** omode -- the open-style mode flags.
+** cmode -- the create-style mode flags.
+** sff -- safefile flags.
+**
+** Returns:
+** Same as fopen.
+*/
+
+#ifndef O_ACCMODE
+# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+#endif
+
+FILE *
+safefopen(fn, omode, cmode, sff)
+ char *fn;
+ int omode;
+ int cmode;
+ int sff;
+{
+ int rval;
+ FILE *fp;
+ int smode;
+ struct stat stb, sta;
+
+ if (bitset(O_CREAT, omode))
+ sff |= SFF_CREAT;
+ smode = 0;
+ switch (omode & O_ACCMODE)
+ {
+ case O_RDONLY:
+ smode = S_IREAD;
+ break;
+
+ case O_WRONLY:
+ smode = S_IWRITE;
+ break;
+
+ case O_RDWR:
+ smode = S_IREAD|S_IWRITE;
+ break;
+
+ default:
+ smode = 0;
+ break;
+ }
+ if (bitset(SFF_OPENASROOT, sff))
+ rval = safefile(fn, 0, 0, NULL, sff, smode, &stb);
+ else
+ rval = safefile(fn, RealUid, RealGid, RealUserName,
+ sff, smode, &stb);
+ if (rval != 0)
+ {
+ errno = rval;
+ return NULL;
+ }
+ if (stb.st_mode == ST_MODE_NOFILE)
+ omode |= O_EXCL;
+
+ fp = dfopen(fn, omode, cmode);
+ if (fp == NULL)
+ return NULL;
+ if (bitset(O_EXCL, omode))
+ return fp;
+ if (fstat(fileno(fp), &sta) < 0 ||
+ sta.st_nlink != stb.st_nlink ||
+ sta.st_dev != stb.st_dev ||
+ sta.st_ino != stb.st_ino ||
+ sta.st_uid != stb.st_uid ||
+ sta.st_gid != stb.st_gid)
+ {
+ syserr("554 cannot open: file %s changed after open", fn);
+ fclose(fp);
+ errno = EPERM;
+ return NULL;
+ }
+ return fp;
+}
+ /*
** FIXCRLF -- fix <CR><LF> in line.
**
** Looks for the <CR><LF> combination and turns it into the
@@ -583,6 +776,7 @@ safefile(fn, uid, gid, uname, flags, mode)
** line is changed in place.
*/
+void
fixcrlf(line, stripnl)
char *line;
bool stripnl;
@@ -607,10 +801,6 @@ fixcrlf(line, stripnl)
** whatever), so this tries to get around it.
*/
-#ifndef O_ACCMODE
-# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
-#endif
-
struct omodes
{
int mask;
@@ -693,16 +883,46 @@ dfopen(filename, omode, cmode)
** output of l to fp.
*/
+void
putline(l, mci)
register char *l;
register MCI *mci;
{
+ putxline(l, mci, PXLF_MAPFROM);
+}
+ /*
+** PUTXLINE -- putline with flags bits.
+**
+** This routine always guarantees outputing a newline (or CRLF,
+** as appropriate) at the end of the string.
+**
+** Parameters:
+** l -- line to put.
+** mci -- the mailer connection information.
+** pxflags -- flag bits:
+** PXLF_MAPFROM -- map From_ to >From_.
+** PXLF_STRIP8BIT -- strip 8th bit.
+**
+** Returns:
+** none
+**
+** Side Effects:
+** output of l to fp.
+*/
+
+void
+putxline(l, mci, pxflags)
+ register char *l;
+ register MCI *mci;
+ int pxflags;
+{
register char *p;
register char svchar;
int slop = 0;
/* strip out 0200 bits -- these can look like TELNET protocol */
- if (bitset(MCIF_7BIT, mci->mci_flags))
+ if (bitset(MCIF_7BIT, mci->mci_flags) ||
+ bitset(PXLF_STRIP8BIT, pxflags))
{
for (p = l; (svchar = *p) != '\0'; ++p)
if (bitset(0200, svchar))
@@ -734,6 +954,15 @@ putline(l, mci)
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);
+ }
fputs(l, mci->mci_out);
(void) putc('!', mci->mci_out);
fputs(mci->mci_mailer->m_eol, mci->mci_out);
@@ -776,6 +1005,7 @@ putline(l, mci)
** f is unlinked.
*/
+void
xunlink(f)
char *f;
{
@@ -806,13 +1036,14 @@ xunlink(f)
** fp is closed.
*/
+void
xfclose(fp, a, b)
FILE *fp;
char *a, *b;
{
if (tTd(53, 99))
printf("xfclose(%x) %s %s\n", fp, a, b);
-#ifdef XDEBUG
+#if XDEBUG
if (fileno(fp) == 1)
syserr("xfclose(%s %s): fd = 1", a, b);
#endif
@@ -839,10 +1070,7 @@ xfclose(fp, a, b)
*/
static jmp_buf CtxReadTimeout;
-static int readtimeout();
-static EVENT *GlobalTimeout = NULL;
-static bool EnableTimeout = FALSE;
-static int ReadProgress;
+static void readtimeout();
char *
sfgets(buf, siz, fp, timeout, during)
@@ -868,22 +1096,19 @@ sfgets(buf, siz, fp, timeout, during)
{
# ifdef LOG
syslog(LOG_NOTICE,
- "timeout waiting for input from %s during %s\n",
+ "timeout waiting for input from %.100s during %s",
CurHostName? CurHostName: "local", during);
# endif
errno = 0;
usrerr("451 timeout waiting for input during %s",
during);
buf[0] = '\0';
-#ifdef XDEBUG
+#if XDEBUG
checkfd012(during);
#endif
return (NULL);
}
- if (GlobalTimeout == NULL)
- ev = setevent(timeout, readtimeout, 0);
- else
- EnableTimeout = TRUE;
+ ev = setevent(timeout, readtimeout, 0);
}
/* try to read */
@@ -898,10 +1123,7 @@ sfgets(buf, siz, fp, timeout, during)
}
/* clear the event if it has not sprung */
- if (GlobalTimeout == NULL)
- clrevent(ev);
- else
- EnableTimeout = FALSE;
+ clrevent(ev);
/* clean up the books and exit */
LineNumber++;
@@ -914,50 +1136,30 @@ sfgets(buf, siz, fp, timeout, during)
}
if (TrafficLogFile != NULL)
fprintf(TrafficLogFile, "%05d <<< %s", getpid(), buf);
- if (SevenBit)
+ if (SevenBitInput)
+ {
for (p = buf; *p != '\0'; p++)
*p &= ~0200;
- return (buf);
-}
-
-void
-sfgetset(timeout)
- time_t timeout;
-{
- /* cancel pending timer */
- if (GlobalTimeout != NULL)
- {
- clrevent(GlobalTimeout);
- GlobalTimeout = NULL;
}
-
- /* schedule fresh one if so requested */
- if (timeout != 0)
+ else if (!HasEightBits)
{
- ReadProgress = LineNumber;
- GlobalTimeout = setevent(timeout, readtimeout, timeout);
+ for (p = buf; *p != '\0'; p++)
+ {
+ if (bitset(0200, *p))
+ {
+ HasEightBits = TRUE;
+ break;
+ }
+ }
}
+ return (buf);
}
-static
+static void
readtimeout(timeout)
time_t timeout;
{
- /* terminate if ordinary timeout */
- if (GlobalTimeout == NULL)
- longjmp(CtxReadTimeout, 1);
-
- /* terminate if no progress was made -- reset state */
- if (EnableTimeout && (LineNumber <= ReadProgress))
- {
- EnableTimeout = FALSE;
- GlobalTimeout = NULL;
- longjmp(CtxReadTimeout, 2);
- }
-
- /* schedule a new timeout */
- GlobalTimeout = NULL;
- sfgetset(timeout);
+ longjmp(CtxReadTimeout, 1);
}
/*
** FGETFOLDED -- like fgets, but know about folded lines.
@@ -1033,7 +1235,9 @@ fgetfolded(buf, n, f)
}
if (p == bp)
return (NULL);
- *--p = '\0';
+ if (p[-1] == '\n')
+ p--;
+ *p = '\0';
return (bp);
}
/*
@@ -1095,6 +1299,7 @@ atobool(s)
** none.
*/
+int
atooct(s)
register char *s;
{
@@ -1241,10 +1446,11 @@ strcontainedin(a, b)
** none
*/
+void
checkfd012(where)
char *where;
{
-#ifdef XDEBUG
+#if XDEBUG
register int i;
struct stat stbuf;
@@ -1277,9 +1483,9 @@ checkfd012(where)
** none.
*/
-#include <netdb.h>
#include <arpa/inet.h>
+void
printopenfds(logit)
bool logit;
{
@@ -1299,18 +1505,22 @@ printopenfds(logit)
** logit -- if set, send output to syslog instead of stdout.
*/
+void
dumpfd(fd, printclosed, logit)
int fd;
bool printclosed;
bool logit;
{
- register struct hostent *hp;
register char *p;
+ char *hp;
char *fmtstr;
- struct sockaddr_in sin;
+#ifdef S_IFSOCK
+ SOCKADDR sa;
+#endif
auto int slen;
struct stat st;
char buf[200];
+ extern char *hostnamebyanyaddr();
p = buf;
sprintf(p, "%3d: ", fd);
@@ -1341,26 +1551,30 @@ dumpfd(fd, printclosed, logit)
case S_IFSOCK:
sprintf(p, "SOCK ");
p += strlen(p);
- slen = sizeof sin;
- if (getsockname(fd, (struct sockaddr *) &sin, &slen) < 0)
- sprintf(p, "(badsock)");
+ slen = sizeof sa;
+ if (getsockname(fd, &sa.sa, &slen) < 0)
+ sprintf(p, "(%s)", errstring(errno));
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));
+ hp = hostnamebyanyaddr(&sa);
+ if (sa.sa.sa_family == AF_INET)
+ sprintf(p, "%s/%d", hp, ntohs(sa.sin.sin_port));
+ else
+ sprintf(p, "%s", hp);
}
p += strlen(p);
sprintf(p, "->");
p += strlen(p);
- slen = sizeof sin;
- if (getpeername(fd, (struct sockaddr *) &sin, &slen) < 0)
- sprintf(p, "(badsock)");
+ slen = sizeof sa;
+ if (getpeername(fd, &sa.sa, &slen) < 0)
+ sprintf(p, "(%s)", errstring(errno));
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));
+ hp = hostnamebyanyaddr(&sa);
+ if (sa.sa.sa_family == AF_INET)
+ sprintf(p, "%s/%d", hp, ntohs(sa.sin.sin_port));
+ else
+ sprintf(p, "%s", hp);
}
break;
#endif
@@ -1411,7 +1625,7 @@ defprint:
printit:
#ifdef LOG
if (logit)
- syslog(LOG_DEBUG, "%s", buf);
+ syslog(LOG_DEBUG, "%.800s", buf);
else
#endif
printf("%s\n", buf);
@@ -1436,7 +1650,7 @@ printit:
char *
shortenstring(s, m)
- register char *s;
+ register const char *s;
int m;
{
int l;
@@ -1444,7 +1658,7 @@ shortenstring(s, m)
l = strlen(s);
if (l < m)
- return s;
+ return (char *) s;
if (m > MAXSHORTSTR)
m = MAXSHORTSTR;
else if (m < 10)
@@ -1466,6 +1680,240 @@ shortenstring(s, m)
return buf;
}
/*
+** SHORTEN_HOSTNAME -- strip local domain information off of hostname.
+**
+** Parameters:
+** host -- the host to shorten (stripped in place).
+**
+** Returns:
+** none.
+*/
+
+void
+shorten_hostname(host)
+ char host[];
+{
+ register char *p;
+ char *mydom;
+ int i;
+ bool canon = FALSE;
+
+ /* strip off final dot */
+ p = &host[strlen(host) - 1];
+ if (*p == '.')
+ {
+ *p = '\0';
+ canon = TRUE;
+ }
+
+ /* see if there is any domain at all -- if not, we are done */
+ p = strchr(host, '.');
+ if (p == NULL)
+ return;
+
+ /* yes, we have a domain -- see if it looks like us */
+ mydom = macvalue('m', CurEnv);
+ if (mydom == NULL)
+ mydom = "";
+ i = strlen(++p);
+ if ((canon ? strcasecmp(p, mydom) : strncasecmp(p, mydom, i)) == 0 &&
+ (mydom[i] == '.' || mydom[i] == '\0'))
+ *--p = '\0';
+}
+ /*
+** PROG_OPEN -- open a program for reading
+**
+** Parameters:
+** argv -- the argument list.
+** pfd -- pointer to a place to store the file descriptor.
+** e -- the current envelope.
+**
+** Returns:
+** pid of the process -- -1 if it failed.
+*/
+
+int
+prog_open(argv, pfd, e)
+ char **argv;
+ int *pfd;
+ ENVELOPE *e;
+{
+ int pid;
+ int i;
+ int saveerrno;
+ int fdv[2];
+ char *p, *q;
+ char buf[MAXLINE + 1];
+ extern int DtableSize;
+
+ if (pipe(fdv) < 0)
+ {
+ syserr("%s: cannot create pipe for stdout", argv[0]);
+ return -1;
+ }
+ pid = fork();
+ if (pid < 0)
+ {
+ syserr("%s: cannot fork", argv[0]);
+ close(fdv[0]);
+ close(fdv[1]);
+ return -1;
+ }
+ if (pid > 0)
+ {
+ /* parent */
+ close(fdv[1]);
+ *pfd = fdv[0];
+ return pid;
+ }
+
+ /* child -- close stdin */
+ close(0);
+
+ /* stdout goes back to parent */
+ close(fdv[0]);
+ if (dup2(fdv[1], 1) < 0)
+ {
+ syserr("%s: cannot dup2 for stdout", argv[0]);
+ _exit(EX_OSERR);
+ }
+ close(fdv[1]);
+
+ /* stderr goes to transcript if available */
+ if (e->e_xfp != NULL)
+ {
+ if (dup2(fileno(e->e_xfp), 2) < 0)
+ {
+ syserr("%s: cannot dup2 for stderr", argv[0]);
+ _exit(EX_OSERR);
+ }
+ }
+
+ /* this process has no right to the queue file */
+ if (e->e_lockfp != NULL)
+ close(fileno(e->e_lockfp));
+
+ /* run as default user */
+ endpwent();
+ setgid(DefGid);
+ setuid(DefUid);
+
+ /* run in some directory */
+ if (ProgMailer != NULL)
+ p = ProgMailer->m_execdir;
+ else
+ p = NULL;
+ for (; p != NULL; p = q)
+ {
+ q = strchr(p, ':');
+ if (q != NULL)
+ *q = '\0';
+ expand(p, buf, sizeof buf, e);
+ if (q != NULL)
+ *q++ = ':';
+ if (buf[0] != '\0' && chdir(buf) >= 0)
+ break;
+ }
+ if (p == NULL)
+ {
+ /* backup directories */
+ if (chdir("/tmp") < 0)
+ (void) chdir("/");
+ }
+
+ /* arrange for all the files to be closed */
+ for (i = 3; i < DtableSize; i++)
+ {
+ register int j;
+
+ if ((j = fcntl(i, F_GETFD, 0)) != -1)
+ (void) fcntl(i, F_SETFD, j | 1);
+ }
+
+ /* now exec the process */
+ execve(argv[0], (ARGV_T) argv, (ARGV_T) UserEnviron);
+
+ /* woops! failed */
+ saveerrno = errno;
+ syserr("%s: cannot exec", argv[0]);
+ if (transienterror(saveerrno))
+ _exit(EX_OSERR);
+ _exit(EX_CONFIG);
+}
+ /*
+** GET_COLUMN -- look up a Column in a line buffer
+**
+** Parameters:
+** line -- the raw text line to search.
+** col -- the column number to fetch.
+** delim -- the delimiter between columns. If null,
+** use white space.
+** buf -- the output buffer.
+**
+** Returns:
+** buf if successful.
+** NULL otherwise.
+*/
+
+char *
+get_column(line, col, delim, buf)
+ char line[];
+ int col;
+ char delim;
+ char buf[];
+{
+ char *p;
+ char *begin, *end;
+ int i;
+ char delimbuf[3];
+
+ if (delim == '\0')
+ strcpy(delimbuf, "\n\t ");
+ else
+ {
+ delimbuf[0] = delim;
+ delimbuf[1] = '\0';
+ }
+
+ p = line;
+ if (*p == '\0')
+ return NULL; /* line empty */
+ if (*p == delim && col == 0)
+ return NULL; /* first column empty */
+
+ begin = line;
+
+ if (col == 0 && delim == '\0')
+ {
+ while (*begin && isspace(*begin))
+ begin++;
+ }
+
+ for (i = 0; i < col; i++)
+ {
+ if ((begin = strpbrk(begin, delimbuf)) == NULL)
+ return NULL; /* no such column */
+ begin++;
+ if (delim == '\0')
+ {
+ while (*begin && isspace(*begin))
+ begin++;
+ }
+ }
+
+ end = strpbrk(begin, delimbuf);
+ if (end == NULL)
+ {
+ strcpy(buf, begin);
+ }
+ else
+ {
+ strncpy(buf, begin, end - begin);
+ buf[end - begin] = '\0';
+ }
+ return buf;
+}
+ /*
** CLEANSTRCPY -- copy string keeping out bogus characters
**
** Parameters:
@@ -1517,8 +1965,8 @@ cleanstrcpy(t, f, l)
char *
denlstring(s, strict, logattacks)
char *s;
- int strict;
- int logattacks;
+ bool strict;
+ bool logattacks;
{
register char *p;
int l;
@@ -1545,14 +1993,16 @@ denlstring(s, strict, logattacks)
for (p = bp; (p = strchr(p, '\n')) != NULL; )
*p++ = ' ';
+/*
#ifdef LOG
if (logattacks)
{
- syslog(LOG_NOTICE, "POSSIBLE ATTACK from %s: newline in string \"%s\"",
+ syslog(LOG_NOTICE, "POSSIBLE ATTACK from %.100s: newline in string \"%s\"",
RealHostName == NULL ? "[UNKNOWN]" : RealHostName,
- shortenstring(bp, 80));
+ shortenstring(bp, 203));
}
#endif
+*/
return bp;
}
OpenPOWER on IntegriCloud