summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1995-12-02 18:17:40 +0000
committerpeter <peter@FreeBSD.org>1995-12-02 18:17:40 +0000
commita531c1a15720076e696b7ecb296c53191cf906c6 (patch)
treea0e24bbe1b4263b12bb5a33862e1d9f0272e8ef8 /usr.sbin
parent91b3d1fef5f70cc06d726f635e7a187744eb869d (diff)
downloadFreeBSD-src-a531c1a15720076e696b7ecb296c53191cf906c6.zip
FreeBSD-src-a531c1a15720076e696b7ecb296c53191cf906c6.tar.gz
Initial round of conflict resolutions.. I need to do another
pass over this and check it more closely, but my initial concern was to get it to all compile again. Some of the obsoleted files 'cvs rm'ed.
Diffstat (limited to 'usr.sbin')
-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