summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/src
diff options
context:
space:
mode:
authorgshapiro <gshapiro@FreeBSD.org>2007-04-09 01:38:51 +0000
committergshapiro <gshapiro@FreeBSD.org>2007-04-09 01:38:51 +0000
commit97853bac963c5d3bed1b2cc8456b52dc100a3a16 (patch)
tree2164c380c4cbce635871c28ad6025cf3001cedaa /contrib/sendmail/src
parenta26ee9422b3dd49a0146ab2eec3f21acf30e399c (diff)
parent14e22b52d4375b164f9fa21c0ab3abd9837e823f (diff)
downloadFreeBSD-src-97853bac963c5d3bed1b2cc8456b52dc100a3a16.zip
FreeBSD-src-97853bac963c5d3bed1b2cc8456b52dc100a3a16.tar.gz
This commit was generated by cvs2svn to compensate for changes in r168515,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib/sendmail/src')
-rw-r--r--contrib/sendmail/src/Makefile4
-rw-r--r--contrib/sendmail/src/Makefile.m44
-rw-r--r--contrib/sendmail/src/README7
-rw-r--r--contrib/sendmail/src/TRACEFLAGS5
-rw-r--r--contrib/sendmail/src/TUNING22
-rw-r--r--contrib/sendmail/src/alias.c29
-rw-r--r--contrib/sendmail/src/arpadate.c4
-rw-r--r--contrib/sendmail/src/collect.c38
-rw-r--r--contrib/sendmail/src/control.c24
-rw-r--r--contrib/sendmail/src/daemon.c272
-rw-r--r--contrib/sendmail/src/daemon.h62
-rw-r--r--contrib/sendmail/src/deliver.c156
-rw-r--r--contrib/sendmail/src/domain.c23
-rw-r--r--contrib/sendmail/src/envelope.c53
-rw-r--r--contrib/sendmail/src/helpfile5
-rw-r--r--contrib/sendmail/src/macro.c158
-rw-r--r--contrib/sendmail/src/main.c218
-rw-r--r--contrib/sendmail/src/map.c554
-rw-r--r--contrib/sendmail/src/map.h86
-rw-r--r--contrib/sendmail/src/milter.c1115
-rw-r--r--contrib/sendmail/src/mime.c46
-rw-r--r--contrib/sendmail/src/parseaddr.c313
-rw-r--r--contrib/sendmail/src/queue.c257
-rw-r--r--contrib/sendmail/src/ratectrl.c6
-rw-r--r--contrib/sendmail/src/readcf.c205
-rw-r--r--contrib/sendmail/src/recipient.c76
-rw-r--r--contrib/sendmail/src/sasl.c6
-rw-r--r--contrib/sendmail/src/sendmail.h109
-rw-r--r--contrib/sendmail/src/sm_resolve.c14
-rw-r--r--contrib/sendmail/src/srvrsmtp.c663
-rw-r--r--contrib/sendmail/src/stab.c40
-rw-r--r--contrib/sendmail/src/stats.c14
-rw-r--r--contrib/sendmail/src/timers.c10
-rw-r--r--contrib/sendmail/src/tls.c24
-rw-r--r--contrib/sendmail/src/udb.c60
-rw-r--r--contrib/sendmail/src/usersmtp.c48
-rw-r--r--contrib/sendmail/src/util.c304
-rw-r--r--contrib/sendmail/src/version.c6
38 files changed, 3324 insertions, 1716 deletions
diff --git a/contrib/sendmail/src/Makefile b/contrib/sendmail/src/Makefile
index c86bbf5..a5633c7 100644
--- a/contrib/sendmail/src/Makefile
+++ b/contrib/sendmail/src/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 8.11 1999/09/23 22:36:42 ca Exp $
+# $Id: Makefile,v 8.12 2006/08/29 22:00:11 ca Exp $
SHELL= /bin/sh
BUILD= ./Build
@@ -6,6 +6,8 @@ OPTIONS= $(CONFIG) $(FLAGS)
all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
+check: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC
diff --git a/contrib/sendmail/src/Makefile.m4 b/contrib/sendmail/src/Makefile.m4
index 5cf0f78..10c1122 100644
--- a/contrib/sendmail/src/Makefile.m4
+++ b/contrib/sendmail/src/Makefile.m4
@@ -1,7 +1,8 @@
-dnl $Id: Makefile.m4,v 8.96 2003/08/08 20:31:17 ca Exp $
+dnl $Id: Makefile.m4,v 8.107 2007/01/09 00:04:09 ca Exp $
include(confBUILDTOOLSDIR`/M4/switch.m4')
define(`confREQUIRE_LIBSM', `true')
+define(`confREQUIRE_SM_OS_H', `true')
bldPRODUCT_START(`executable', `sendmail')
define(`bldBIN_TYPE', `G')
define(`bldINSTALL_DIR', `')
@@ -10,6 +11,7 @@ PREPENDDEF(`confENVDEF', `confMAPDEF')
bldPUSH_SMLIB(`sm')
bldPUSH_SMLIB(`smutil')
+
dnl hack: /etc/mail is not defined as "location of .cf" in the build system
define(`bldTARGET_INST_DEP', ifdef(`confINST_DEP', `confINST_DEP',
`${DESTDIR}/etc/mail/submit.cf ${DESTDIR}${MSPQ}'))dnl
diff --git a/contrib/sendmail/src/README b/contrib/sendmail/src/README
index 1ed29b1..2039674 100644
--- a/contrib/sendmail/src/README
+++ b/contrib/sendmail/src/README
@@ -9,7 +9,7 @@
# the sendmail distribution.
#
#
-# $Id: README,v 8.389 2006/05/02 16:58:50 ca Exp $
+# $Id: README,v 8.390 2006/11/13 22:27:27 ca Exp $
#
This directory contains the source files for sendmail(TM).
@@ -508,6 +508,9 @@ HASSNPRINTF Set this to 1 if your OS has a working snprintf(3), i.e.,
size were unlimited.
LDAP_REFERRALS Set this if you want to use the -R flag (do not auto chase
referrals) for LDAP maps (requires -DLDAPMAP).
+MILTER_NO_NAGLE Turn off Nagle algorithm for communication with libmilter
+ ("cork" on Linux). On some operating systems this may
+ improve the interprocess communication performance.
+-----------------------+
@@ -1844,4 +1847,4 @@ util.c Some general purpose routines used by sendmail.
version.c The version number and information about this
version of sendmail.
-(Version $Revision: 8.389 $, last update $Date: 2006/05/02 16:58:50 $ )
+(Version $Revision: 8.390 $, last update $Date: 2006/11/13 22:27:27 $ )
diff --git a/contrib/sendmail/src/TRACEFLAGS b/contrib/sendmail/src/TRACEFLAGS
index 820cf20..a6249fd 100644
--- a/contrib/sendmail/src/TRACEFLAGS
+++ b/contrib/sendmail/src/TRACEFLAGS
@@ -1,4 +1,4 @@
-# $Id: TRACEFLAGS,v 8.44 2006/02/27 18:52:41 ca Exp $
+# $Id: TRACEFLAGS,v 8.47 2006/09/11 22:36:32 ca Exp $
0, 4 main.c main canonical name, UUCP node name, a.k.a.s
0, 15 main.c main print configuration
0, 44 util.c printav print address of each string
@@ -27,6 +27,7 @@
20 parseaddr.c parseaddr
21 parseaddr.c rewrite
22 parseaddr.c prescan
+23 main.c testmodeline
24 parseaddr.c buildaddr, allocaddr
25 recipient.c sendtolist
26 recipient.c recipient
@@ -69,6 +70,7 @@
56 mci.c persistent host status
57 util.c snprintf
58 bf.c bf* routines
+59 parseaddr.c cataddr
60 map.c
61 conf.c sm_gethostbyname
62 multiple file descriptor checking
@@ -88,6 +90,7 @@
81 sun remote mode
83 collect.c timeout
84 deliver.c timeout
+85 map.c dprintf map
91 mci.c syslogging of MCI cache information
93,>99 * Prevent daemon connection fork for profiling/debugging
94,>99 srvrsmtp.c cause commands to fail (for protocol testing)
diff --git a/contrib/sendmail/src/TUNING b/contrib/sendmail/src/TUNING
index 6ccff9a..fe9e694 100644
--- a/contrib/sendmail/src/TUNING
+++ b/contrib/sendmail/src/TUNING
@@ -5,7 +5,7 @@
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
#
-# $Id: TUNING,v 1.19 2003/01/25 23:06:02 ca Exp $
+# $Id: TUNING,v 1.21 2006/09/25 16:45:05 ca Exp $
#
********************************************
@@ -39,7 +39,7 @@ Depending on your requirements, these may need different options
to optimize sendmail for the particular purpose. It is also possible
to configure sendmail to achieve good performance in all cases, but
it will not be optimal for any specific purpose. For example, it
-is non-trivival to combine low latency (fast delivery of incoming
+is non-trivial to combine low latency (fast delivery of incoming
mail) with high overall throughput.
Before we explore the different scenarios, a basic discussion about
@@ -49,7 +49,7 @@ disk I/O, delivery modes, and queue control is required.
* Disk I/O
-----------------------------------------------
-In general mail will be written to disk up before a delivery attempt
+In general mail will be written to disk before a delivery attempt
is made. This is required for reliability and should only be changed
in a few specific cases that are mentioned later on. To achieve
better disk I/O performance the queue directories can be spread
@@ -76,7 +76,7 @@ interactive: incoming mail will be immediately delivered by the same process
queue: incoming mail will be queued and delivered by a queue runner later on
The first offers the lowest latency without the disadvantage of the
-second, which keep the connection from the sender open until the
+second, which keeps the connection from the sender open until the
delivery to the next hop succeeded or failed. However, it does not
allow for a good control over the number of delivery processes other
than limiting the total number of direct children of the daemon
@@ -95,7 +95,7 @@ other two modes. However, this mode is probably also best for
concurrent delivery since the number of queue runners can be specified
on a queue group basis. Persistent queue runners (-qp) can be used
to minimize the overhead for creating processes because they just
-sleep for the specified interval (which shold be short) instead of
+sleep for the specified interval (which should be short) instead of
exiting after a queue run.
@@ -139,7 +139,7 @@ should be added to the .mc file.
* Mailing Lists and Large Aliases (1-n Mailing)
-----------------------------------------------
-Before 8.12 sendmail delivers an e-mail sequentially to all its
+Before 8.12 sendmail would deliver an e-mail sequentially to all its
recipients. For mailing lists or large aliases the overall delivery
time can be substantial, especially if some of the recipients are
located at hosts that are slow to accept e-mail. Some mailing list
@@ -148,9 +148,9 @@ fewer recipients. sendmail 8.12 can do this itself, either across
queue groups or within a queue directory. The latter is controlled
by the 'r=' field of a queue group declaration.
-Let's assume a simple example: a mailing lists where most of
-the recipients are at three domains: the local one (local.domain)
-and two remotes (one.domain, two.domain) and the rest is splittered
+Let's assume a simple example: a mailing list where most of the
+recipients are at three domains: the local one (local.domain) and
+two remotes (one.domain, two.domain) and the rest is splittered
over several other domains. For this case it is useful to specify
three queue groups:
@@ -209,10 +209,10 @@ For high volume mail it is necessary to be able to control the load
on the system. Therefore the 'queue' delivery mode should be used,
and all options related to number of processes and the load should
be set to reasonable values. It is important not to accept mail
-faster than it can be delivered otherwise the system will be
+faster than it can be delivered; otherwise the system will be
overwhelmed. Hence RefuseLA should be lower than QueueLA, the number
of daemon children should probably be lower than the number of queue
-runnners (MaxChildren vs. MaxQueueChildren). DelayLA is a new option
+runners (MaxChildren vs. MaxQueueChildren). DelayLA is a new option
in 8.12 which allows delaying connections instead of rejecting them.
This may result in a smoother load distribution depending on how
the mails are submitted to sendmail.
diff --git a/contrib/sendmail/src/alias.c b/contrib/sendmail/src/alias.c
index 3c05212..3eae4ba 100644
--- a/contrib/sendmail/src/alias.c
+++ b/contrib/sendmail/src/alias.c
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: alias.c,v 8.217 2003/07/28 17:47:18 ca Exp $")
+SM_RCSID("@(#)$Id: alias.c,v 8.219 2006/10/24 18:04:09 ca Exp $")
#define SEPARATOR ':'
# define ALIAS_SPEC_SEPARATORS " ,/:"
@@ -90,7 +90,7 @@ alias(a, sendq, aliaslevel, e)
if (e->e_sender != NULL && *e->e_sender == '\0')
{
/* Look for owner of alias */
- (void) sm_strlcpyn(obuf, sizeof obuf, 2, "owner-", a->q_user);
+ (void) sm_strlcpyn(obuf, sizeof(obuf), 2, "owner-", a->q_user);
if (aliaslookup(obuf, &status, a->q_host) != NULL)
{
if (LogLevel > 8)
@@ -107,7 +107,8 @@ alias(a, sendq, aliaslevel, e)
{
a->q_state = QS_QUEUEUP;
if (e->e_message == NULL)
- e->e_message = "alias database unavailable";
+ e->e_message = sm_rpool_strdup_x(e->e_rpool,
+ "alias database unavailable");
/* XXX msg only per recipient? */
if (a->q_message == NULL)
@@ -164,10 +165,10 @@ alias(a, sendq, aliaslevel, e)
*/
if (strncmp(a->q_user, "owner-", 6) == 0 ||
- strlen(a->q_user) > sizeof obuf - 7)
- (void) sm_strlcpy(obuf, "owner-owner", sizeof obuf);
+ strlen(a->q_user) > sizeof(obuf) - 7)
+ (void) sm_strlcpy(obuf, "owner-owner", sizeof(obuf));
else
- (void) sm_strlcpyn(obuf, sizeof obuf, 2, "owner-", a->q_user);
+ (void) sm_strlcpyn(obuf, sizeof(obuf), 2, "owner-", a->q_user);
owner = aliaslookup(obuf, &status, a->q_host);
if (owner == NULL)
return;
@@ -287,7 +288,7 @@ setalias(spec)
if (AliasFileMap == NULL)
{
(void) sm_strlcpy(buf, "aliases.files sequence",
- sizeof buf);
+ sizeof(buf));
AliasFileMap = makemapentry(buf);
if (AliasFileMap == NULL)
{
@@ -295,10 +296,10 @@ setalias(spec)
return;
}
}
- (void) sm_snprintf(buf, sizeof buf, "Alias%d", NAliasFileMaps);
+ (void) sm_snprintf(buf, sizeof(buf), "Alias%d", NAliasFileMaps);
s = stab(buf, ST_MAP, ST_ENTER);
map = &s->s_map;
- memset(map, '\0', sizeof *map);
+ memset(map, '\0', sizeof(*map));
map->map_mname = s->s_name;
p = strpbrk(p, ALIAS_SPEC_SEPARATORS);
if (p != NULL && *p == SEPARATOR)
@@ -458,8 +459,8 @@ aliaswait(map, ext, isopen)
return isopen;
}
mtime = stb.st_mtime;
- if (sm_strlcpyn(buf, sizeof buf, 2,
- map->map_file, ext == NULL ? "" : ext) >= sizeof buf)
+ if (sm_strlcpyn(buf, sizeof(buf), 2,
+ map->map_file, ext == NULL ? "" : ext) >= sizeof(buf))
{
if (LogLevel > 3)
sm_syslog(LOG_INFO, NOQID,
@@ -656,7 +657,7 @@ readaliases(map, af, announcestats, logstats)
LineNumber = 0;
naliases = bytes = longest = 0;
skipping = false;
- while (sm_io_fgets(af, SM_TIME_DEFAULT, line, sizeof line) != NULL)
+ while (sm_io_fgets(af, SM_TIME_DEFAULT, line, sizeof(line)) != NULL)
{
int lhssize, rhssize;
int c;
@@ -779,7 +780,7 @@ readaliases(map, af, announcestats, logstats)
/* read continuation line */
if (sm_io_fgets(af, SM_TIME_DEFAULT, p,
- sizeof line - (p-line)) == NULL)
+ sizeof(line) - (p-line)) == NULL)
break;
LineNumber++;
@@ -928,7 +929,7 @@ forward(user, sendq, aliaslevel, e)
ep = strchr(pp, SEPARATOR);
if (ep != NULL)
*ep = '\0';
- expand(pp, buf, sizeof buf, e);
+ expand(pp, buf, sizeof(buf), e);
if (ep != NULL)
*ep++ = SEPARATOR;
if (buf[0] == '\0')
diff --git a/contrib/sendmail/src/arpadate.c b/contrib/sendmail/src/arpadate.c
index 16082cd..5d3d7a6 100644
--- a/contrib/sendmail/src/arpadate.c
+++ b/contrib/sendmail/src/arpadate.c
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: arpadate.c,v 8.30 2001/09/11 04:05:12 gshapiro Exp $")
+SM_RCSID("@(#)$Id: arpadate.c,v 8.31 2006/08/15 23:24:55 ca Exp $")
/*
** ARPADATE -- Create date in ARPANET format
@@ -192,7 +192,7 @@ arpadate(ud)
{
*q++ = ' ';
*q++ = '(';
- while (*tz != '\0' && q < &b[sizeof b - 3])
+ while (*tz != '\0' && q < &b[sizeof(b) - 3])
*q++ = *tz++;
*q++ = ')';
}
diff --git a/contrib/sendmail/src/collect.c b/contrib/sendmail/src/collect.c
index 534ce9c..56fed0a 100644
--- a/contrib/sendmail/src/collect.c
+++ b/contrib/sendmail/src/collect.c
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: collect.c,v 8.273 2006/03/31 18:51:47 ca Exp $")
+SM_RCSID("@(#)$Id: collect.c,v 8.280 2006/11/29 00:20:40 ca Exp $")
static void eatfrom __P((char *volatile, ENVELOPE *));
static void collect_doheader __P((ENVELOPE *));
@@ -53,13 +53,13 @@ collect_eoh(e, numhdrs, hdrslen)
char hsize[16];
/* call the end-of-header check ruleset */
- (void) sm_snprintf(hnum, sizeof hnum, "%d", numhdrs);
- (void) sm_snprintf(hsize, sizeof hsize, "%d", hdrslen);
+ (void) sm_snprintf(hnum, sizeof(hnum), "%d", numhdrs);
+ (void) sm_snprintf(hsize, sizeof(hsize), "%d", hdrslen);
if (tTd(30, 10))
sm_dprintf("collect: rscheck(\"check_eoh\", \"%s $| %s\")\n",
hnum, hsize);
(void) rscheck("check_eoh", hnum, hsize, e, RSF_UNSTRUCTURED|RSF_COUNT,
- 3, NULL, e->e_id);
+ 3, NULL, e->e_id, NULL);
/*
** Process the header,
@@ -144,11 +144,11 @@ collect_doheader(e)
break;
case NRA_ADD_BCC:
- addheader("Bcc", " ", 0, e);
+ addheader("Bcc", " ", 0, e, true);
break;
case NRA_ADD_TO_UNDISCLOSED:
- addheader("To", "undisclosed-recipients:;", 0, e);
+ addheader("To", "undisclosed-recipients:;", 0, e, true);
break;
}
@@ -161,7 +161,7 @@ collect_doheader(e)
if (tTd(30, 3))
sm_dprintf("Adding %s: %s\n",
hdr, q->q_paddr);
- addheader(hdr, q->q_paddr, 0, e);
+ addheader(hdr, q->q_paddr, 0, e, true);
}
}
}
@@ -315,7 +315,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
numhdrs = 0;
HasEightBits = false;
buf = bp = bufbuf;
- buflen = sizeof bufbuf;
+ buflen = sizeof(bufbuf);
pbp = peekbuf;
istate = IS_BOL;
mstate = SaveFrom ? MS_HEADER : MS_UFROM;
@@ -552,25 +552,7 @@ bufferchar:
sm_free(obuf); /* XXX */
}
- /*
- ** XXX Notice: the logic here is broken.
- ** An input to sendmail that doesn't contain a
- ** header but starts immediately with the body whose
- ** first line contain characters which match the
- ** following "if" will cause problems: those
- ** characters will NOT appear in the output...
- ** Do we care?
- */
-
- if (c >= 0200 && c <= 0237)
- {
-#if 0 /* causes complaints -- figure out something for 8.n+1 */
- usrerr("Illegal character 0x%x in header", c);
-#else /* 0 */
- /* EMPTY */
-#endif /* 0 */
- }
- else if (c != '\0')
+ if (c != '\0')
{
*bp++ = c;
++hdrslen;
@@ -599,7 +581,7 @@ bufferchar:
nextstate:
if (tTd(30, 35))
- sm_dprintf("nextstate, istate=%d, mstate=%d, line = \"%s\"\n",
+ sm_dprintf("nextstate, istate=%d, mstate=%d, line=\"%s\"\n",
istate, mstate, buf);
switch (mstate)
{
diff --git a/contrib/sendmail/src/control.c b/contrib/sendmail/src/control.c
index 0d7ee0b..0b525f7 100644
--- a/contrib/sendmail/src/control.c
+++ b/contrib/sendmail/src/control.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2004, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -10,7 +10,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: control.c,v 8.126 2004/08/04 20:54:00 ca Exp $")
+SM_RCSID("@(#)$Id: control.c,v 8.128 2006/08/15 23:24:56 ca Exp $")
#include <sm/fdset.h>
@@ -21,9 +21,7 @@ SM_RCSID("@(#)$Id: control.c,v 8.126 2004/08/04 20:54:00 ca Exp $")
#define CMDHELP 3 /* help */
#define CMDSTATUS 4 /* daemon status */
#define CMDMEMDUMP 5 /* dump memory, to find memory leaks */
-#if _FFR_CONTROL_MSTAT
-# define CMDMSTAT 6 /* daemon status, more info, tagged data */
-#endif /* _FFR_CONTROL_MSTAT */
+#define CMDMSTAT 6 /* daemon status, more info, tagged data */
struct cmd
{
@@ -38,9 +36,7 @@ static struct cmd CmdTab[] =
{ "shutdown", CMDSHUTDOWN },
{ "status", CMDSTATUS },
{ "memdump", CMDMEMDUMP },
-#if _FFR_CONTROL_MSTAT
{ "mstat", CMDMSTAT },
-#endif /* _FFR_CONTROL_MSTAT */
{ NULL, CMDERROR }
};
@@ -74,7 +70,7 @@ opencontrolsocket()
if (ControlSocketName == NULL || *ControlSocketName == '\0')
return 0;
- if (strlen(ControlSocketName) >= sizeof controladdr.sun_path)
+ if (strlen(ControlSocketName) >= sizeof(controladdr.sun_path))
{
errno = ENAMETOOLONG;
return -1;
@@ -101,13 +97,13 @@ opencontrolsocket()
}
(void) unlink(ControlSocketName);
- memset(&controladdr, '\0', sizeof controladdr);
+ memset(&controladdr, '\0', sizeof(controladdr));
controladdr.sun_family = AF_UNIX;
(void) sm_strlcpy(controladdr.sun_path, ControlSocketName,
- sizeof controladdr.sun_path);
+ sizeof(controladdr.sun_path));
if (bind(ControlSocket, (struct sockaddr *) &controladdr,
- sizeof controladdr) < 0)
+ sizeof(controladdr)) < 0)
{
save_errno = errno;
clrcontrol();
@@ -305,7 +301,7 @@ control_command(sock, e)
(void) sm_io_setvbuf(s, SM_TIME_DEFAULT, NULL,
SM_IO_NBF, SM_IO_BUFSIZ);
- if (sm_io_fgets(s, SM_TIME_DEFAULT, inp, sizeof inp) == NULL)
+ if (sm_io_fgets(s, SM_TIME_DEFAULT, inp, sizeof(inp)) == NULL)
{
(void) sm_io_close(s, SM_TIME_DEFAULT);
exit(EX_IOERR);
@@ -323,7 +319,7 @@ control_command(sock, e)
cmd = cmdbuf;
while (*p != '\0' &&
!(isascii(*p) && isspace(*p)) &&
- cmd < &cmdbuf[sizeof cmdbuf - 2])
+ cmd < &cmdbuf[sizeof(cmdbuf) - 2])
*cmd++ = *p++;
*cmd = '\0';
@@ -390,7 +386,6 @@ control_command(sock, e)
proc_list_display(s, "");
break;
-# if _FFR_CONTROL_MSTAT
case CMDMSTAT: /* daemon status, extended, tagged format */
proc_list_probe();
(void) sm_io_fprintf(s, SM_TIME_DEFAULT,
@@ -401,7 +396,6 @@ control_command(sock, e)
disk_status(s, "D:");
proc_list_display(s, "P:");
break;
-# endif /* _FFR_CONTROL_MSTAT */
case CMDMEMDUMP: /* daemon memory dump, to find memory leaks */
# if SM_HEAP_CHECK
diff --git a/contrib/sendmail/src/daemon.c b/contrib/sendmail/src/daemon.c
index 6d366d9..76b5b58 100644
--- a/contrib/sendmail/src/daemon.c
+++ b/contrib/sendmail/src/daemon.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -12,8 +12,9 @@
*/
#include <sendmail.h>
+#include "map.h"
-SM_RCSID("@(#)$Id: daemon.c,v 8.666 2006/04/18 01:23:42 ca Exp $")
+SM_RCSID("@(#)$Id: daemon.c,v 8.678 2007/03/08 00:33:40 ca Exp $")
#if defined(SOCK_STREAM) || defined(__GNU_LIBRARY__)
# define USE_SOCK_STREAM 1
@@ -58,37 +59,8 @@ SM_RCSID("@(#)$Id: daemon.c,v 8.666 2006/04/18 01:23:42 ca Exp $")
#include <sm/fdset.h>
-/* structure to describe a daemon or a client */
-struct daemon
-{
- int d_socket; /* fd for socket */
- SOCKADDR d_addr; /* socket for incoming */
- unsigned short d_port; /* port number */
- int d_listenqueue; /* size of listen queue */
- int d_tcprcvbufsize; /* size of TCP receive buffer */
- int d_tcpsndbufsize; /* size of TCP send buffer */
- time_t d_refuse_connections_until;
- bool d_firsttime;
- int d_socksize;
- BITMAP256 d_flags; /* flags; see sendmail.h */
- char *d_mflags; /* flags for use in macro */
- char *d_name; /* user-supplied name */
-#if MILTER
- char *d_inputfilterlist;
- struct milter *d_inputfilters[MAXFILTERS];
-#endif /* MILTER */
-#if _FFR_SS_PER_DAEMON
- int d_supersafe;
-#endif /* _FFR_SS_PER_DAEMON */
-#if _FFR_DM_PER_DAEMON
- int d_dm; /* DeliveryMode */
-#endif /* _FFR_DM_PER_DAEMON */
-};
-
-typedef struct daemon DAEMON_T;
-
-#define SAFE_NOTSET (-1) /* SuperSafe (per daemon) option not set */
-/* see also sendmail.h: SuperSafe values */
+#define DAEMON_C 1
+#include <daemon.h>
static void connecttimeout __P((int));
static int opendaemonsocket __P((DAEMON_T *, bool));
@@ -128,7 +100,6 @@ static void authtimeout __P((int));
** Convert the entry in hbuf into a canonical form.
*/
-static DAEMON_T Daemons[MAXDAEMONS];
static int NDaemons = 0; /* actual number of daemons */
static time_t NextDiskSpaceCheck = 0;
@@ -165,7 +136,7 @@ getrequests(e)
#endif /* XDEBUG */
char status[MAXLINE];
SOCKADDR sa;
- SOCKADDR_LEN_T len = sizeof sa;
+ SOCKADDR_LEN_T len = sizeof(sa);
#if _FFR_QUEUE_RUN_PARANOIA
time_t lastrun;
#endif /* _FFR_QUEUE_RUN_PARANOIA */
@@ -173,7 +144,6 @@ getrequests(e)
extern int ControlSocket;
# endif /* NETUNIX */
extern ENVELOPE BlankEnvelope;
- extern bool refuseconnections __P((char *, ENVELOPE *, int, bool));
/* initialize data for function that generates queue ids */
@@ -218,7 +188,7 @@ getrequests(e)
{
char jbuf[MAXHOSTNAMELEN];
- expand("\201j", jbuf, sizeof jbuf, e);
+ expand("\201j", jbuf, sizeof(jbuf), e);
j_has_dot = strchr(jbuf, '.') != NULL;
}
#endif /* XDEBUG */
@@ -263,8 +233,7 @@ getrequests(e)
continue;
if (bitnset(D_DISABLE, Daemons[idx].d_flags))
continue;
- if (refuseconnections(Daemons[idx].d_name, e, idx,
- curdaemon == idx))
+ if (refuseconnections(e, idx, curdaemon == idx))
{
if (Daemons[idx].d_socket >= 0)
{
@@ -300,7 +269,7 @@ getrequests(e)
{
char jbuf[MAXHOSTNAMELEN];
- expand("\201j", jbuf, sizeof jbuf, e);
+ expand("\201j", jbuf, sizeof(jbuf), e);
if (!wordinclass(jbuf, 'w'))
{
dumpstate("daemon lost $j");
@@ -423,7 +392,7 @@ getrequests(e)
{
lotherend = Daemons[idx].d_socksize;
memset(&RealHostAddr, '\0',
- sizeof RealHostAddr);
+ sizeof(RealHostAddr));
t = accept(Daemons[idx].d_socket,
(struct sockaddr *)&RealHostAddr,
&lotherend);
@@ -457,8 +426,8 @@ getrequests(e)
{
struct sockaddr_un sa_un;
- lotherend = sizeof sa_un;
- memset(&sa_un, '\0', sizeof sa_un);
+ lotherend = sizeof(sa_un);
+ memset(&sa_un, '\0', sizeof(sa_un));
t = accept(ControlSocket,
(struct sockaddr *)&sa_un,
&lotherend);
@@ -627,9 +596,9 @@ getrequests(e)
/* XXX get some better "random" data? */
seed = get_random();
RAND_seed((void *) &NextDiskSpaceCheck,
- sizeof NextDiskSpaceCheck);
- RAND_seed((void *) &now, sizeof now);
- RAND_seed((void *) &seed, sizeof seed);
+ sizeof(NextDiskSpaceCheck));
+ RAND_seed((void *) &now, sizeof(now));
+ RAND_seed((void *) &seed, sizeof(seed));
#else /* STARTTLS */
(void) get_random();
#endif /* STARTTLS */
@@ -720,7 +689,7 @@ getrequests(e)
macdefine(&BlankEnvelope.e_macro, A_TEMP,
macid("{daemon_addr}"),
anynet_ntoa(&Daemons[curdaemon].d_addr));
- (void) sm_snprintf(status, sizeof status, "%d",
+ (void) sm_snprintf(status, sizeof(status), "%d",
ntohs(Daemons[curdaemon].d_port));
macdefine(&BlankEnvelope.e_macro, A_TEMP,
macid("{daemon_port}"), status);
@@ -752,19 +721,36 @@ getrequests(e)
/* Add parent process as first child item */
proc_list_add(CurrentPid, "daemon child",
PROC_DAEMON_CHILD, 0, -1, NULL);
-
/* don't schedule queue runs if ETRN */
QueueIntvl = 0;
+
+ /*
+ ** Hack: override global variables if
+ ** the corresponding DaemonPortOption
+ ** is set.
+ */
#if _FFR_SS_PER_DAEMON
if (Daemons[curdaemon].d_supersafe !=
- SAFE_NOTSET)
- SuperSafe = Daemons[curdaemon].d_supersafe;
+ DPO_NOTSET)
+ SuperSafe = Daemons[curdaemon].
+ d_supersafe;
#endif /* _FFR_SS_PER_DAEMON */
-#if _FFR_DM_PER_DAEMON
if (Daemons[curdaemon].d_dm != DM_NOTSET)
set_delivery_mode(
Daemons[curdaemon].d_dm, e);
-#endif /* _FFR_DM_PER_DAEMON */
+
+ if (Daemons[curdaemon].d_refuseLA !=
+ DPO_NOTSET)
+ RefuseLA = Daemons[curdaemon].
+ d_refuseLA;
+ if (Daemons[curdaemon].d_queueLA != DPO_NOTSET)
+ QueueLA = Daemons[curdaemon].d_queueLA;
+ if (Daemons[curdaemon].d_delayLA != DPO_NOTSET)
+ DelayLA = Daemons[curdaemon].d_delayLA;
+ if (Daemons[curdaemon].d_maxchildren !=
+ DPO_NOTSET)
+ MaxChildren = Daemons[curdaemon].
+ d_maxchildren;
sm_setproctitle(true, e, "startup with %s",
anynet_ntoa(&RealHostAddr));
@@ -909,13 +895,13 @@ getrequests(e)
/* parent -- keep track of children */
if (control)
{
- (void) sm_snprintf(status, sizeof status,
+ (void) sm_snprintf(status, sizeof(status),
"control socket server child");
proc_list_add(pid, status, PROC_CONTROL, 0, -1, NULL);
}
else
{
- (void) sm_snprintf(status, sizeof status,
+ (void) sm_snprintf(status, sizeof(status),
"SMTP server child for %s",
anynet_ntoa(&RealHostAddr));
proc_list_add(pid, status, PROC_DAEMON, 0, -1,
@@ -1138,12 +1124,12 @@ opendaemonsocket(d, firsttime)
if (tTd(15, 101))
(void) setsockopt(d->d_socket, SOL_SOCKET,
SO_DEBUG, (char *)&on,
- sizeof on);
+ sizeof(on));
(void) setsockopt(d->d_socket, SOL_SOCKET,
- SO_REUSEADDR, (char *)&on, sizeof on);
+ SO_REUSEADDR, (char *)&on, sizeof(on));
(void) setsockopt(d->d_socket, SOL_SOCKET,
- SO_KEEPALIVE, (char *)&on, sizeof on);
+ SO_KEEPALIVE, (char *)&on, sizeof(on));
#ifdef SO_RCVBUF
if (d->d_tcprcvbufsize > 0)
@@ -1184,30 +1170,30 @@ opendaemonsocket(d, firsttime)
#if _FFR_DAEMON_NETUNIX
# ifdef NETUNIX
case AF_UNIX:
- socksize = sizeof d->d_addr.sunix;
+ socksize = sizeof(d->d_addr.sunix);
break;
# endif /* NETUNIX */
#endif /* _FFR_DAEMON_NETUNIX */
#if NETINET
case AF_INET:
- socksize = sizeof d->d_addr.sin;
+ socksize = sizeof(d->d_addr.sin);
break;
#endif /* NETINET */
#if NETINET6
case AF_INET6:
- socksize = sizeof d->d_addr.sin6;
+ socksize = sizeof(d->d_addr.sin6);
break;
#endif /* NETINET6 */
#if NETISO
case AF_ISO:
- socksize = sizeof d->d_addr.siso;
+ socksize = sizeof(d->d_addr.siso);
break;
#endif /* NETISO */
default:
- socksize = sizeof d->d_addr;
+ socksize = sizeof(d->d_addr);
break;
}
@@ -1260,7 +1246,7 @@ setupdaemon(daemonaddr)
if (daemonaddr->sa.sa_family == AF_UNSPEC)
{
- memset(daemonaddr, '\0', sizeof *daemonaddr);
+ memset(daemonaddr, '\0', sizeof(*daemonaddr));
#if NETINET
daemonaddr->sa.sa_family = AF_INET;
#endif /* NETINET */
@@ -1456,11 +1442,13 @@ setsockaddroptions(p, d)
d->d_addr.sa.sa_family = AF_INET;
#endif /* NETINET */
#if _FFR_SS_PER_DAEMON
- d->d_supersafe = SAFE_NOTSET;
+ d->d_supersafe = DPO_NOTSET;
#endif /* _FFR_SS_PER_DAEMON */
-#if _FFR_DM_PER_DAEMON
d->d_dm = DM_NOTSET;
-#endif /* _FFR_DM_PER_DAEMON */
+ d->d_refuseLA = DPO_NOTSET;
+ d->d_queueLA = DPO_NOTSET;
+ d->d_delayLA = DPO_NOTSET;
+ d->d_maxchildren = DPO_NOTSET;
while (p != NULL)
{
@@ -1480,16 +1468,20 @@ setsockaddroptions(p, d)
continue;
while (isascii(*++v) && isspace(*v))
continue;
- if (isascii(*f) && islower(*f))
- *f = toupper(*f);
switch (*f)
{
case 'A': /* address */
+#if !_FFR_DPO_CS
+ case 'a':
+#endif /* !_FFR_DPO_CS */
addr = v;
break;
-#if _FFR_DM_PER_DAEMON
+ case 'c':
+ d->d_maxchildren = atoi(v);
+ break;
+
case 'D': /* DeliveryMode */
switch (*v)
{
@@ -1505,9 +1497,15 @@ setsockaddroptions(p, d)
break;
}
break;
-#endif /* _FFR_DM_PER_DAEMON */
+
+ case 'd': /* delayLA */
+ d->d_delayLA = atoi(v);
+ break;
case 'F': /* address family */
+#if !_FFR_DPO_CS
+ case 'f':
+#endif /* !_FFR_DPO_CS */
if (isascii(*v) && isdigit(*v))
d->d_addr.sa.sa_family = atoi(v);
#if _FFR_DAEMON_NETUNIX
@@ -1544,31 +1542,57 @@ setsockaddroptions(p, d)
#if MILTER
case 'I':
+# if !_FFR_DPO_CS
+ case 'i':
+# endif /* !_FFR_DPO_CS */
d->d_inputfilterlist = v;
break;
#endif /* MILTER */
case 'L': /* listen queue size */
+#if !_FFR_DPO_CS
+ case 'l':
+#endif /* !_FFR_DPO_CS */
d->d_listenqueue = atoi(v);
break;
case 'M': /* modifiers (flags) */
+#if !_FFR_DPO_CS
+ case 'm':
+#endif /* !_FFR_DPO_CS */
d->d_mflags = getmodifiers(v, d->d_flags);
break;
case 'N': /* name */
+#if !_FFR_DPO_CS
+ case 'n':
+#endif /* !_FFR_DPO_CS */
d->d_name = v;
break;
case 'P': /* port */
+#if !_FFR_DPO_CS
+ case 'p':
+#endif /* !_FFR_DPO_CS */
port = v;
break;
+ case 'q':
+ d->d_queueLA = atoi(v);
+ break;
+
case 'R': /* receive buffer size */
d->d_tcprcvbufsize = atoi(v);
break;
+ case 'r':
+ d->d_refuseLA = atoi(v);
+ break;
+
case 'S': /* send buffer size */
+#if !_FFR_DPO_CS
+ case 's':
+#endif /* !_FFR_DPO_CS */
d->d_tcpsndbufsize = atoi(v);
break;
@@ -1860,7 +1884,7 @@ setdaemonoptions(p)
{
char num[30];
- (void) sm_snprintf(num, sizeof num, "Daemon%d", NDaemons);
+ (void) sm_snprintf(num, sizeof(num), "Daemon%d", NDaemons);
Daemons[NDaemons].d_name = newstr(num);
}
@@ -1916,7 +1940,7 @@ setclientoptions(p)
int family;
DAEMON_T d;
- memset(&d, '\0', sizeof d);
+ memset(&d, '\0', sizeof(d));
setsockaddroptions(p, &d);
/* grab what we need */
@@ -1929,7 +1953,7 @@ setclientoptions(p)
{
char num[30];
- (void) sm_snprintf(num, sizeof num, "Client%d", family);
+ (void) sm_snprintf(num, sizeof(num), "Client%d", family);
ClientSettings[family].d_name = newstr(num);
}
}
@@ -2125,7 +2149,7 @@ makeconnection(host, port, mci, e, enough)
char p6[INET6_ADDRSTRLEN];
#endif /* NETINET6 */
- memset(&clt_addr, '\0', sizeof clt_addr);
+ memset(&clt_addr, '\0', sizeof(clt_addr));
/* infer the address family from the address itself */
clt_addr.sa.sa_family = addr_family(p);
@@ -2138,7 +2162,7 @@ makeconnection(host, port, mci, e, enough)
clt_addr.sin.sin_addr.s_addr != INADDR_LOOPBACK)
{
clt_bind = true;
- socksize = sizeof (struct sockaddr_in);
+ socksize = sizeof(struct sockaddr_in);
}
break;
#endif /* NETINET */
@@ -2146,16 +2170,16 @@ makeconnection(host, port, mci, e, enough)
#if NETINET6
case AF_INET6:
if (inet_addr(p) != INADDR_NONE)
- (void) sm_snprintf(p6, sizeof p6,
+ (void) sm_snprintf(p6, sizeof(p6),
"IPv6:::ffff:%s", p);
else
- (void) sm_strlcpy(p6, p, sizeof p6);
+ (void) sm_strlcpy(p6, p, sizeof(p6));
if (anynet_pton(AF_INET6, p6,
&clt_addr.sin6.sin6_addr) == 1 &&
!IN6_IS_ADDR_LOOPBACK(&clt_addr.sin6.sin6_addr))
{
clt_bind = true;
- socksize = sizeof (struct sockaddr_in6);
+ socksize = sizeof(struct sockaddr_in6);
}
break;
#endif /* NETINET6 */
@@ -2185,7 +2209,7 @@ makeconnection(host, port, mci, e, enough)
clt_bind = true;
if (clt_addr.sin.sin_port != 0)
clt_bind = true;
- socksize = sizeof (struct sockaddr_in);
+ socksize = sizeof(struct sockaddr_in);
break;
#endif /* NETINET */
#if NETINET6
@@ -2194,14 +2218,14 @@ makeconnection(host, port, mci, e, enough)
clt_addr.sin6.sin6_addr = in6addr_any;
else
clt_bind = true;
- socksize = sizeof (struct sockaddr_in6);
+ socksize = sizeof(struct sockaddr_in6);
if (clt_addr.sin6.sin6_port != 0)
clt_bind = true;
break;
#endif /* NETINET6 */
#if NETISO
case AF_ISO:
- socksize = sizeof clt_addr.siso;
+ socksize = sizeof(clt_addr.siso);
clt_bind = true;
break;
#endif /* NETISO */
@@ -2217,8 +2241,8 @@ makeconnection(host, port, mci, e, enough)
SM_SET_H_ERRNO(0);
errno = 0;
- memset(&CurHostAddr, '\0', sizeof CurHostAddr);
- memset(&addr, '\0', sizeof addr);
+ memset(&CurHostAddr, '\0', sizeof(CurHostAddr));
+ memset(&addr, '\0', sizeof(addr));
SmtpPhase = mci->mci_phase = "initial connection";
CurHostName = host;
@@ -2236,7 +2260,7 @@ makeconnection(host, port, mci, e, enough)
*p = '\0';
#if NETINET6
- memset(&hid6, '\0', sizeof hid6);
+ memset(&hid6, '\0', sizeof(hid6));
#endif /* NETINET6 */
#if NETINET
if (family == AF_INET &&
@@ -2336,6 +2360,14 @@ gothostent:
# endif /* NETINET6 */
{
if (errno == ETIMEDOUT ||
+# if _FFR_GETHBN_ExFILE
+# ifdef EMFILE
+ errno == EMFILE ||
+# endif /* EMFILE */
+# ifdef ENFILE
+ errno == ENFILE ||
+# endif /* ENFILE */
+# endif /* _FFR_GETHBN_ExFILE */
h_errno == TRY_AGAIN ||
(errno == ECONNREFUSED && UseNameServer))
{
@@ -2387,7 +2419,7 @@ gothostent:
#endif /* NETINET6 */
default:
- if (hp->h_length > sizeof addr.sa.sa_data)
+ if (hp->h_length > sizeof(addr.sa.sa_data))
{
syserr("makeconnection: long sa_data: family %d len %d",
hp->h_addrtype, hp->h_length);
@@ -2444,14 +2476,14 @@ gothostent:
#if NETINET
case AF_INET:
addr.sin.sin_port = port;
- addrlen = sizeof (struct sockaddr_in);
+ addrlen = sizeof(struct sockaddr_in);
break;
#endif /* NETINET */
#if NETINET6
case AF_INET6:
addr.sin6.sin6_port = port;
- addrlen = sizeof (struct sockaddr_in6);
+ addrlen = sizeof(struct sockaddr_in6);
break;
#endif /* NETINET6 */
@@ -2459,7 +2491,7 @@ gothostent:
case AF_ISO:
/* assume two byte transport selector */
memmove(TSEL((struct sockaddr_iso *) &addr), (char *) &port, 2);
- addrlen = sizeof (struct sockaddr_iso);
+ addrlen = sizeof(struct sockaddr_iso);
break;
#endif /* NETISO */
@@ -2556,7 +2588,7 @@ gothostent:
int on = 1;
(void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
- (char *)&on, sizeof on);
+ (char *)&on, sizeof(on));
}
if (e->e_xfp != NULL) /* for debugging */
(void) sm_io_flush(e->e_xfp, SM_TIME_DEFAULT);
@@ -2574,7 +2606,7 @@ gothostent:
(void) setsockopt(s, SOL_SOCKET,
SO_REUSEADDR,
(char *) &on,
- sizeof on);
+ sizeof(on));
break;
#endif /* NETINET */
@@ -2584,7 +2616,7 @@ gothostent:
(void) setsockopt(s, SOL_SOCKET,
SO_REUSEADDR,
(char *) &on,
- sizeof on);
+ sizeof(on));
break;
#endif /* NETINET6 */
}
@@ -2795,7 +2827,7 @@ nextaddr:
}
/* find out name for Interface through which we connect */
- len = sizeof addr;
+ len = sizeof(addr);
if (getsockname(s, &addr.sa, &len) == 0)
{
char *name;
@@ -2833,11 +2865,9 @@ nextaddr:
macid("{if_family_out}"), NULL);
}
-#if _FFR_HELONAME
/* Use the configured HeloName as appropriate */
if (HeloName != NULL && HeloName[0] != '\0')
mci->mci_heloname = newstr(HeloName);
-#endif /* _FFR_HELONAME */
mci_setstat(mci, EX_OK, NULL, NULL);
return EX_OK;
@@ -2897,10 +2927,10 @@ makeconnection_ds(mux_path, mci)
}
/* prepare address structure */
- memset(&unix_addr, '\0', sizeof unix_addr);
+ memset(&unix_addr, '\0', sizeof(unix_addr));
unix_addr.sun_family = AF_UNIX;
- if (strlen(mux_path) >= sizeof unix_addr.sun_path)
+ if (strlen(mux_path) >= sizeof(unix_addr.sun_path))
{
syserr("makeconnection_ds: domain socket name %s too long",
mux_path);
@@ -2911,7 +2941,7 @@ makeconnection_ds(mux_path, mci)
return EX_UNAVAILABLE;
}
(void) sm_strlcpy(unix_addr.sun_path, mux_path,
- sizeof unix_addr.sun_path);
+ sizeof(unix_addr.sun_path));
/* initialize domain socket */
sock = socket(AF_UNIX, SOCK_STREAM, 0);
@@ -3372,7 +3402,7 @@ getauthinfo(fd, may_be_forged)
static char hbuf[MAXNAME + MAXAUTHINFO + 11];
*may_be_forged = false;
- falen = sizeof RealHostAddr;
+ falen = sizeof(RealHostAddr);
if (isatty(fd) || (i = getpeername(fd, &RealHostAddr.sa, &falen)) < 0 ||
falen <= 0 || RealHostAddr.sa.sa_family == 0)
{
@@ -3388,7 +3418,7 @@ getauthinfo(fd, may_be_forged)
return NULL;
errno = 0;
}
- (void) sm_strlcpyn(hbuf, sizeof hbuf, 2, RealUserName,
+ (void) sm_strlcpyn(hbuf, sizeof(hbuf), 2, RealUserName,
"@localhost");
if (tTd(9, 1))
sm_dprintf("getauthinfo: %s\n", hbuf);
@@ -3454,7 +3484,7 @@ getauthinfo(fd, may_be_forged)
if (TimeOuts.to_ident == 0)
goto noident;
- lalen = sizeof la;
+ lalen = sizeof(la);
switch (RealHostAddr.sa.sa_family)
{
#if NETINET
@@ -3469,7 +3499,7 @@ getauthinfo(fd, may_be_forged)
port = RealHostAddr.sin.sin_port;
/* create ident query */
- (void) sm_snprintf(ibuf, sizeof ibuf, "%d,%d\r\n",
+ (void) sm_snprintf(ibuf, sizeof(ibuf), "%d,%d\r\n",
ntohs(RealHostAddr.sin.sin_port),
ntohs(la.sin.sin_port));
@@ -3517,7 +3547,7 @@ getauthinfo(fd, may_be_forged)
port = RealHostAddr.sin6.sin6_port;
/* create ident query */
- (void) sm_snprintf(ibuf, sizeof ibuf, "%d,%d\r\n",
+ (void) sm_snprintf(ibuf, sizeof(ibuf), "%d,%d\r\n",
ntohs(RealHostAddr.sin6.sin6_port),
ntohs(la.sin6.sin6_port));
@@ -3576,7 +3606,7 @@ getauthinfo(fd, may_be_forged)
/* get result */
p = &ibuf[0];
- nleft = sizeof ibuf - 1;
+ nleft = sizeof(ibuf) - 1;
while ((i = read(s, p, nleft)) > 0)
{
char *s;
@@ -3659,13 +3689,13 @@ getauthinfo(fd, may_be_forged)
if (sm_strncasecmp(ostype, "other", 5) == 0 &&
(ostype[5] == ' ' || ostype[5] == '\0'))
{
- (void) sm_strlcpy(hbuf, "IDENT:", sizeof hbuf);
+ (void) sm_strlcpy(hbuf, "IDENT:", sizeof(hbuf));
cleanstrcpy(&hbuf[6], p, MAXAUTHINFO);
}
else
cleanstrcpy(hbuf, p, MAXAUTHINFO);
len = strlen(hbuf);
- (void) sm_strlcpyn(&hbuf[len], sizeof hbuf - len, 2, "@",
+ (void) sm_strlcpyn(&hbuf[len], sizeof(hbuf) - len, 2, "@",
RealHostName == NULL ? "localhost" : RealHostName);
goto postident;
@@ -3698,7 +3728,7 @@ noident:
sm_dprintf("getauthinfo: NULL\n");
return NULL;
}
- (void) sm_strlcpy(hbuf, RealHostName, sizeof hbuf);
+ (void) sm_strlcpy(hbuf, RealHostName, sizeof(hbuf));
postident:
#if IP_SRCROUTE
@@ -3727,7 +3757,7 @@ postident:
int l;
struct IPOPTION ipopt;
- ipoptlen = sizeof ipopt;
+ ipoptlen = sizeof(ipopt);
if (getsockopt(fd, IPPROTO_IP, IP_OPTIONS,
(char *) &ipopt, &ipoptlen) < 0)
goto noipsr;
@@ -3760,7 +3790,7 @@ postident:
*/
p = &hbuf[strlen(hbuf)];
- l = sizeof hbuf - (hbuf - p) - 6;
+ l = sizeof(hbuf) - (hbuf - p) - 6;
(void) sm_snprintf(p, SPACELEFT(hbuf, p),
" [%s@%.*s",
*o == IPOPT_SSRR ? "!" : "",
@@ -3979,8 +4009,8 @@ host_map_lookup(map, name, av, statp)
{
int ttl;
- (void) sm_strlcpy(hbuf, name, sizeof hbuf);
- if (getcanonname(hbuf, sizeof hbuf - 1, !HasWildcardMX, &ttl))
+ (void) sm_strlcpy(hbuf, name, sizeof(hbuf));
+ if (getcanonname(hbuf, sizeof(hbuf) - 1, !HasWildcardMX, &ttl))
{
ans = hbuf;
if (ttl > 0)
@@ -4022,7 +4052,7 @@ host_map_lookup(map, name, av, statp)
static char n[MAXNAME + 1];
/* hp->h_name is about to disappear */
- (void) sm_strlcpy(n, ans, sizeof n);
+ (void) sm_strlcpy(n, ans, sizeof(n));
ans = n;
}
freehostent(hp);
@@ -4289,10 +4319,10 @@ anynet_ntoa(sap)
# if NETUNIX
case AF_UNIX:
if (sap->sunix.sun_path[0] != '\0')
- (void) sm_snprintf(buf, sizeof buf, "[UNIX: %.64s]",
+ (void) sm_snprintf(buf, sizeof(buf), "[UNIX: %.64s]",
sap->sunix.sun_path);
else
- (void) sm_strlcpy(buf, "[UNIX: localhost]", sizeof buf);
+ (void) sm_strlcpy(buf, "[UNIX: localhost]", sizeof(buf));
return buf;
# endif /* NETUNIX */
@@ -4303,7 +4333,7 @@ anynet_ntoa(sap)
# if NETINET6
case AF_INET6:
- ap = anynet_ntop(&sap->sin6.sin6_addr, buf, sizeof buf);
+ ap = anynet_ntop(&sap->sin6.sin6_addr, buf, sizeof(buf));
if (ap != NULL)
return ap;
break;
@@ -4311,7 +4341,7 @@ anynet_ntoa(sap)
# if NETLINK
case AF_LINK:
- (void) sm_snprintf(buf, sizeof buf, "[LINK: %s]",
+ (void) sm_snprintf(buf, sizeof(buf), "[LINK: %s]",
link_ntoa((struct sockaddr_dl *) &sap->sa));
return buf;
# endif /* NETLINK */
@@ -4322,10 +4352,10 @@ anynet_ntoa(sap)
}
/* unknown family -- just dump bytes */
- (void) sm_snprintf(buf, sizeof buf, "Family %d: ", sap->sa.sa_family);
+ (void) sm_snprintf(buf, sizeof(buf), "Family %d: ", sap->sa.sa_family);
bp = &buf[strlen(buf)];
ap = sap->sa.sa_data;
- for (l = sizeof sap->sa.sa_data; --l >= 0; )
+ for (l = sizeof(sap->sa.sa_data); --l >= 0; )
{
(void) sm_snprintf(bp, SPACELEFT(buf, bp), "%02x:",
*ap++ & 0377);
@@ -4385,7 +4415,7 @@ hostnamebyanyaddr(sap)
# if NETISO
case AF_ISO:
hp = sm_gethostbyaddr((char *) &sap->siso.siso_addr,
- sizeof sap->siso.siso_addr, AF_ISO);
+ sizeof(sap->siso.siso_addr), AF_ISO);
break;
# endif /* NETISO */
@@ -4396,7 +4426,7 @@ hostnamebyanyaddr(sap)
# endif /* NETUNIX */
default:
- hp = sm_gethostbyaddr(sap->sa.sa_data, sizeof sap->sa.sa_data,
+ hp = sm_gethostbyaddr(sap->sa.sa_data, sizeof(sap->sa.sa_data),
sap->sa.sa_family);
break;
}
@@ -4424,7 +4454,7 @@ hostnamebyanyaddr(sap)
static char n[MAXNAME + 1];
/* Copy the string, hp->h_name is about to disappear */
- (void) sm_strlcpy(n, name, sizeof n);
+ (void) sm_strlcpy(n, name, sizeof(n));
name = n;
}
freehostent(hp);
@@ -4448,7 +4478,7 @@ hostnamebyanyaddr(sap)
{
static char buf[203];
- (void) sm_snprintf(buf, sizeof buf, "[%.200s]",
+ (void) sm_snprintf(buf, sizeof(buf), "[%.200s]",
anynet_ntoa(sap));
return buf;
}
diff --git a/contrib/sendmail/src/daemon.h b/contrib/sendmail/src/daemon.h
new file mode 100644
index 0000000..d8fa291
--- /dev/null
+++ b/contrib/sendmail/src/daemon.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2006 Sendmail, Inc. and its suppliers.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ *
+ * $Id: daemon.h,v 8.3 2006/07/13 22:57:03 ca Exp $
+ */
+
+#ifndef DAEMON_H
+#define DAEMON_H 1
+
+#if DAEMON_C
+# define EXTERN
+#else
+# define EXTERN extern
+#endif
+
+/* structure to describe a daemon or a client */
+struct daemon
+{
+ int d_socket; /* fd for socket */
+ SOCKADDR d_addr; /* socket for incoming */
+ unsigned short d_port; /* port number */
+ int d_listenqueue; /* size of listen queue */
+ int d_tcprcvbufsize; /* size of TCP receive buffer */
+ int d_tcpsndbufsize; /* size of TCP send buffer */
+ time_t d_refuse_connections_until;
+ bool d_firsttime;
+ int d_socksize;
+ BITMAP256 d_flags; /* flags; see sendmail.h */
+ char *d_mflags; /* flags for use in macro */
+ char *d_name; /* user-supplied name */
+
+ int d_dm; /* DeliveryMode */
+ int d_refuseLA;
+ int d_queueLA;
+ int d_delayLA;
+ int d_maxchildren;
+
+#if MILTER
+ char *d_inputfilterlist;
+ struct milter *d_inputfilters[MAXFILTERS];
+#endif /* MILTER */
+#if _FFR_SS_PER_DAEMON
+ int d_supersafe;
+#endif /* _FFR_SS_PER_DAEMON */
+};
+
+typedef struct daemon DAEMON_T;
+
+EXTERN DAEMON_T Daemons[MAXDAEMONS];
+
+#define DPO_NOTSET (-1) /* daemon option (int) not set */
+/* see also sendmail.h: SuperSafe values */
+
+extern bool refuseconnections __P((ENVELOPE *, int, bool));
+
+#undef EXTERN
+#endif /* ! DAEMON_H */
diff --git a/contrib/sendmail/src/deliver.c b/contrib/sendmail/src/deliver.c
index 6454da7..01d5258 100644
--- a/contrib/sendmail/src/deliver.c
+++ b/contrib/sendmail/src/deliver.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -14,7 +14,7 @@
#include <sendmail.h>
#include <sm/time.h>
-SM_RCSID("@(#)$Id: deliver.c,v 8.1003.2.1 2006/05/23 01:32:08 ca Exp $")
+SM_RCSID("@(#)$Id: deliver.c,v 8.1012 2007/03/29 21:20:15 ca Exp $")
#if HASSETUSERCONTEXT
# include <login_cap.h>
@@ -34,7 +34,6 @@ static void mailfiletimeout __P((int));
static void endwaittimeout __P((int));
static int parse_hostsignature __P((char *, char **, MAILER *));
static void sendenvelope __P((ENVELOPE *, int));
-extern MCI *mci_new __P((SM_RPOOL_T *));
static int coloncmp __P((const char *, const char *));
#if STARTTLS
@@ -383,7 +382,7 @@ sendall(e, mode)
*/
ee = (ENVELOPE *) sm_rpool_malloc_x(e->e_rpool,
- sizeof *ee);
+ sizeof(*ee));
STRUCTCOPY(*e, *ee);
ee->e_message = NULL;
ee->e_id = NULL;
@@ -884,7 +883,7 @@ sendenvelope(e, mode)
#if XDEBUG
char wbuf[MAXNAME + 20];
- (void) sm_snprintf(wbuf, sizeof wbuf, "sendall(%.*s)",
+ (void) sm_snprintf(wbuf, sizeof(wbuf), "sendall(%.*s)",
MAXNAME, q->q_paddr);
checkfd012(wbuf);
#endif /* XDEBUG */
@@ -959,7 +958,7 @@ sync_dir(filename, panic)
dirp = strrchr(filename, '/');
if (dirp != NULL)
{
- if (sm_strlcpy(dir, filename, sizeof dir) >= sizeof dir)
+ if (sm_strlcpy(dir, filename, sizeof(dir)) >= sizeof(dir))
return;
dir[dirp - filename] = '\0';
dirp = dir;
@@ -1012,8 +1011,8 @@ dup_queue_file(e, ee, type)
** Make sure both are in the same directory.
*/
- (void) sm_strlcpy(f1buf, queuename(e, type), sizeof f1buf);
- (void) sm_strlcpy(f2buf, queuename(ee, type), sizeof f2buf);
+ (void) sm_strlcpy(f1buf, queuename(e, type), sizeof(f1buf));
+ (void) sm_strlcpy(f2buf, queuename(ee, type), sizeof(f2buf));
/* Force the df to disk if it's not there yet */
if (type == DATAFL_LETTER && e->e_dfp != NULL &&
@@ -1192,6 +1191,8 @@ coloncmp(a, b)
** true iff FallbackSmartHost should be tried.
*/
+static bool should_try_fbsh __P((ENVELOPE *, bool *, char *, size_t, int));
+
static bool
should_try_fbsh(e, tried_fallbacksmarthost, hostbuf, hbsz, status)
ENVELOPE *e;
@@ -1333,11 +1334,13 @@ deliver(e, firstto)
char cbuf[MAXPATHLEN];
errno = 0;
+ SM_REQUIRE(firstto != NULL); /* same as to */
if (!QS_IS_OK(to->q_state))
return 0;
suidwarn = geteuid() == 0;
+ SM_REQUIRE(e != NULL);
m = to->q_mailer;
host = to->q_host;
CurEnv = e; /* just in case */
@@ -1382,6 +1385,7 @@ deliver(e, firstto)
/* rewrite from address, using rewriting rules */
rcode = EX_OK;
+ SM_ASSERT(e->e_from.q_mailer != NULL);
if (bitnset(M_UDBENVELOPE, e->e_from.q_mailer->m_flags))
p = e->e_sender;
else
@@ -1441,7 +1445,7 @@ deliver(e, firstto)
break;
/* this entry is safe -- go ahead and process it */
- expand(*mvp, buf, sizeof buf, e);
+ expand(*mvp, buf, sizeof(buf), e);
*pvp++ = sm_rpool_strdup_x(e->e_rpool, buf);
if (pvp >= &pv[MAXPV - 3])
{
@@ -1595,7 +1599,7 @@ deliver(e, firstto)
quarantine = (e->e_quarmsg != NULL);
rcode = rscheck("check_compat", e->e_from.q_paddr, to->q_paddr,
e, RSF_RMCOMM|RSF_COUNT, 3, NULL,
- e->e_id);
+ e->e_id, NULL);
if (rcode == EX_OK)
{
/* do in-code checking if not discarding */
@@ -1698,7 +1702,7 @@ deliver(e, firstto)
if (p == NULL && ctladdr != NULL)
p = ctladdr->q_home;
macdefine(&e->e_macro, A_PERM, 'z', p);
- expand(m->m_argv[1], buf, sizeof buf, e);
+ expand(m->m_argv[1], buf, sizeof(buf), e);
if (strlen(buf) > 0)
rcode = mailfile(buf, m, ctladdr, SFF_CREAT, e);
else
@@ -1754,18 +1758,18 @@ deliver(e, firstto)
notify[0] = '\0';
if (bitset(QPINGONSUCCESS, to->q_flags))
(void) sm_strlcat(notify, "SUCCESS,",
- sizeof notify);
+ sizeof(notify));
if (bitset(QPINGONFAILURE, to->q_flags))
(void) sm_strlcat(notify, "FAILURE,",
- sizeof notify);
+ sizeof(notify));
if (bitset(QPINGONDELAY, to->q_flags))
(void) sm_strlcat(notify, "DELAY,",
- sizeof notify);
+ sizeof(notify));
/* Set to NEVER or drop trailing comma */
if (notify[0] == '\0')
(void) sm_strlcat(notify, "NEVER",
- sizeof notify);
+ sizeof(notify));
else
notify[strlen(notify) - 1] = '\0';
@@ -1782,7 +1786,7 @@ deliver(e, firstto)
if (!clever)
{
- expand(*mvp, buf, sizeof buf, e);
+ expand(*mvp, buf, sizeof(buf), e);
*pvp++ = sm_rpool_strdup_x(e->e_rpool, buf);
if (pvp >= &pv[MAXPV - 2])
{
@@ -1829,7 +1833,7 @@ deliver(e, firstto)
{
while (*++mvp != NULL)
{
- expand(*mvp, buf, sizeof buf, e);
+ expand(*mvp, buf, sizeof(buf), e);
*pvp++ = sm_rpool_strdup_x(e->e_rpool, buf);
if (pvp >= &pv[MAXPV])
syserr("554 5.3.0 deliver: pv overflow after $u for %s",
@@ -1883,7 +1887,7 @@ deliver(e, firstto)
char wbuf[MAXLINE];
/* make absolutely certain 0, 1, and 2 are in use */
- (void) sm_snprintf(wbuf, sizeof wbuf, "%s... openmailer(%s)",
+ (void) sm_snprintf(wbuf, sizeof(wbuf), "%s... openmailer(%s)",
shortenstring(e->e_to, MAXSHORTSTR),
m->m_name);
checkfd012(wbuf);
@@ -2060,7 +2064,7 @@ tryhost:
continue;
}
(void) sm_strlcpy(hostbuf, mxhosts[hostnum],
- sizeof hostbuf);
+ sizeof(hostbuf));
hostnum++;
if (endp != NULL)
*endp = sep;
@@ -2098,7 +2102,7 @@ tryhost:
/* Try FallbackSmartHost? */
if (should_try_fbsh(e, &tried_fallbacksmarthost,
- hostbuf, sizeof hostbuf,
+ hostbuf, sizeof(hostbuf),
mci->mci_exitstat))
goto one_last_try;
@@ -2190,7 +2194,7 @@ tryhost:
{
/* Try FallbackSmartHost? */
if (should_try_fbsh(e, &tried_fallbacksmarthost,
- hostbuf, sizeof hostbuf, i))
+ hostbuf, sizeof(hostbuf), i))
goto one_last_try;
if (tTd(11, 1))
@@ -2527,7 +2531,7 @@ tryhost:
/* change root to some "safe" directory */
if (m->m_rootdir != NULL)
{
- expand(m->m_rootdir, cbuf, sizeof cbuf, e);
+ expand(m->m_rootdir, cbuf, sizeof(cbuf), e);
if (tTd(11, 20))
sm_dprintf("openmailer: chroot %s\n",
cbuf);
@@ -2664,7 +2668,7 @@ tryhost:
q = strchr(p, ':');
if (q != NULL)
*q = '\0';
- expand(p, cbuf, sizeof cbuf, e);
+ expand(p, cbuf, sizeof(cbuf), e);
if (q != NULL)
*q++ = ':';
if (tTd(11, 20))
@@ -2945,16 +2949,19 @@ reconnect: /* after switching to an encrypted connection */
if (usetls)
usetls = !iscltflgset(e, D_NOTLS);
+ host = macvalue(macid("{server_name}"), e);
if (usetls)
{
- host = macvalue(macid("{server_name}"), e);
olderrors = Errors;
QuickAbort = false;
SuprErrs = true;
if (rscheck("try_tls", host, NULL, e,
- RSF_RMCOMM, 7, host, NOQID) != EX_OK
+ RSF_RMCOMM, 7, host, NOQID, NULL)
+ != EX_OK
|| Errors > olderrors)
+ {
usetls = false;
+ }
SuprErrs = saveSuprErrs;
QuickAbort = saveQuickAbort;
}
@@ -3024,7 +3031,7 @@ reconnect: /* after switching to an encrypted connection */
if (rscheck("tls_server",
macvalue(macid("{verify}"), e),
NULL, e, RSF_RMCOMM|RSF_COUNT, 5,
- host, NOQID) != EX_OK ||
+ host, NOQID, NULL) != EX_OK ||
Errors > olderrors ||
rcode == EX_SOFTWARE)
{
@@ -3041,7 +3048,7 @@ reconnect: /* after switching to an encrypted connection */
{
p = "403 4.7.0 server not authenticated.";
(void) sm_strlcpy(enhsc, "4.7.0",
- sizeof enhsc);
+ sizeof(enhsc));
}
SuprErrs = saveSuprErrs;
QuickAbort = saveQuickAbort;
@@ -3079,8 +3086,18 @@ reconnect: /* after switching to an encrypted connection */
*/
(void) sm_strlcpy(SmtpError, p,
- sizeof SmtpError);
+ sizeof(SmtpError));
+ }
+ else if (mci->mci_state == MCIS_CLOSED)
+ {
+ /* connection close caused by 421 */
+ mci->mci_errno = 0;
+ rcode = EX_TEMPFAIL;
+ mci_setstat(mci, rcode, NULL, "421");
}
+ else
+ rcode = 0;
+
QuickAbort = saveQuickAbort;
SuprErrs = saveSuprErrs;
if (DONE_STARTTLS(mci->mci_flags) &&
@@ -3171,7 +3188,7 @@ reconnect: /* after switching to an encrypted connection */
(void) sm_strlcpy(SmtpError,
"Temporary AUTH failure",
- sizeof SmtpError);
+ sizeof(SmtpError));
}
}
# endif /* SASL */
@@ -3233,7 +3250,7 @@ do_transfer:
rcode = EX_DATAERR;
/* Need an e_message for error */
- (void) sm_snprintf(SmtpError, sizeof SmtpError,
+ (void) sm_snprintf(SmtpError, sizeof(SmtpError),
"Message is too large; %ld bytes max",
mci->mci_maxsize);
goto give_up;
@@ -3297,7 +3314,7 @@ do_transfer:
** We set SmtpError as
*/
- (void) sm_snprintf(SmtpError, sizeof SmtpError,
+ (void) sm_snprintf(SmtpError, sizeof(SmtpError),
"%s mailer (%s) exited with EX_TEMPFAIL",
m->m_name, m->m_mailer);
}
@@ -3337,7 +3354,7 @@ do_transfer:
# if STARTTLS
i = rscheck("tls_rcpt", to->q_user, NULL, e,
RSF_RMCOMM|RSF_COUNT, 3,
- mci->mci_host, e->e_id);
+ mci->mci_host, e->e_id, NULL);
if (i != EX_OK)
{
markfailure(e, to, mci, i, false);
@@ -3612,7 +3629,7 @@ cleanup: ;
char wbuf[MAXLINE];
/* make absolutely certain 0, 1, and 2 are in use */
- (void) sm_snprintf(wbuf, sizeof wbuf,
+ (void) sm_snprintf(wbuf, sizeof(wbuf),
"%s... end of deliver(%s)",
e->e_to == NULL ? "NO-TO-LIST"
: shortenstring(e->e_to,
@@ -3756,7 +3773,7 @@ markfailure(e, q, mci, rcode, ovr)
{
char buf[16];
- (void) sm_snprintf(buf, sizeof buf, "%d", rcode);
+ (void) sm_snprintf(buf, sizeof(buf), "%d", rcode);
q->q_rstatus = sm_rpool_strdup_x(e->e_rpool, buf);
}
@@ -3830,7 +3847,7 @@ endmailer(mci, e, pv)
if (mci->mci_in != NULL && mci->mci_state != MCIS_ERROR &&
e->e_xfp != NULL)
{
- while (sfgets(buf, sizeof buf, mci->mci_in,
+ while (sfgets(buf, sizeof(buf), mci->mci_in,
TimeOuts.to_quit, "Draining Input") != NULL)
(void) sm_io_fputs(e->e_xfp, SM_TIME_DEFAULT, buf);
}
@@ -3980,7 +3997,7 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
statmsg = "250 2.0.0 Sent";
if (e->e_statmsg != NULL)
{
- (void) sm_snprintf(buf, sizeof buf, "%s (%s)",
+ (void) sm_snprintf(buf, sizeof(buf), "%s (%s)",
statmsg,
shortenstring(e->e_statmsg, 403));
statmsg = buf;
@@ -3988,7 +4005,7 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
}
else if (exmsg == NULL)
{
- (void) sm_snprintf(buf, sizeof buf,
+ (void) sm_snprintf(buf, sizeof(buf),
"554 5.3.0 unknown mailer error %d",
status);
status = EX_UNAVAILABLE;
@@ -4054,7 +4071,7 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
else if (status == EX_NOHOST && h_errno != 0)
{
statmsg = sm_errstring(h_errno + E_DNSBASE);
- (void) sm_snprintf(buf, sizeof buf, "%s (%s)", exmsg + 1,
+ (void) sm_snprintf(buf, sizeof(buf), "%s (%s)", exmsg + 1,
statmsg);
statmsg = buf;
usestat = true;
@@ -4065,14 +4082,14 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
statmsg = exmsg;
if (*statmsg++ == ':' && errnum != 0)
{
- (void) sm_snprintf(buf, sizeof buf, "%s: %s", statmsg,
+ (void) sm_snprintf(buf, sizeof(buf), "%s: %s", statmsg,
sm_errstring(errnum));
statmsg = buf;
usestat = true;
}
else if (bitnset(M_LMTP, m->m_flags) && e->e_statmsg != NULL)
{
- (void) sm_snprintf(buf, sizeof buf, "%s (%s)", statmsg,
+ (void) sm_snprintf(buf, sizeof(buf), "%s (%s)", statmsg,
shortenstring(e->e_statmsg, 403));
statmsg = buf;
usestat = true;
@@ -4091,7 +4108,7 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
{
if (dsn == NULL)
{
- (void) sm_snprintf(dsnbuf, sizeof dsnbuf,
+ (void) sm_snprintf(dsnbuf, sizeof(dsnbuf),
"%.*s", off, statmsg + 4);
dsn = dsnbuf;
}
@@ -4112,11 +4129,11 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
Errors++;
if ((off = isenhsc(statmsg + 4, ' ')) > 0 &&
- off < sizeof mbuf - 4)
+ off < sizeof(mbuf) - 4)
{
if (dsn == NULL)
{
- (void) sm_snprintf(dsnbuf, sizeof dsnbuf,
+ (void) sm_snprintf(dsnbuf, sizeof(dsnbuf),
"%.*s", off, statmsg + 4);
dsn = dsnbuf;
}
@@ -4124,12 +4141,12 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
/* copy only part of statmsg to mbuf */
(void) sm_strlcpy(mbuf, statmsg, off);
- (void) sm_strlcat(mbuf, " %s", sizeof mbuf);
+ (void) sm_strlcat(mbuf, " %s", sizeof(mbuf));
}
else
{
dsnbuf[0] = '\0';
- (void) sm_snprintf(mbuf, sizeof mbuf, "%.3s %%s",
+ (void) sm_snprintf(mbuf, sizeof(mbuf), "%.3s %%s",
statmsg);
off = 4;
}
@@ -4315,10 +4332,10 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e)
# endif /* (STATLEN) > 203 */
/* stat: max 210 bytes */
- if ((bp - buf) > (sizeof buf - ((STATLEN) + 20)))
+ if ((bp - buf) > (sizeof(buf) - ((STATLEN) + 20)))
{
/* desperation move -- truncate data */
- bp = buf + sizeof buf - ((STATLEN) + 17);
+ bp = buf + sizeof(buf) - ((STATLEN) + 17);
(void) sm_strlcpy(bp, "...", SPACELEFT(buf, bp));
bp += 3;
}
@@ -4434,7 +4451,7 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e)
{
p = macvalue('h', e);
if (p != NULL && p[0] != '\0')
- (void) sm_snprintf(buf, sizeof buf, "relay=%.100s", p);
+ (void) sm_snprintf(buf, sizeof(buf), "relay=%.100s", p);
}
if (buf[0] != '\0')
sm_syslog(LOG_INFO, e->e_id, "%.1000s", buf);
@@ -4481,7 +4498,7 @@ putfromline(mci, e)
{
char *bang;
- expand("\201g", buf, sizeof buf, e);
+ expand("\201g", buf, sizeof(buf), e);
bang = strchr(buf, '!');
if (bang == NULL)
{
@@ -4495,25 +4512,25 @@ putfromline(mci, e)
at = strrchr(buf, '@');
if (at == NULL)
{
- expand("\201k", hname, sizeof hname, e);
+ expand("\201k", hname, sizeof(hname), e);
at = hname;
}
else
*at++ = '\0';
- (void) sm_snprintf(xbuf, sizeof xbuf,
+ (void) sm_snprintf(xbuf, sizeof(xbuf),
"From %.800s \201d remote from %.100s\n",
buf, at);
}
else
{
*bang++ = '\0';
- (void) sm_snprintf(xbuf, sizeof xbuf,
+ (void) sm_snprintf(xbuf, sizeof(xbuf),
"From %.800s \201d remote from %.100s\n",
bang, buf);
template = xbuf;
}
}
- expand(template, buf, sizeof buf, e);
+ expand(template, buf, sizeof(buf), e);
return putxline(buf, strlen(buf), mci, PXLF_HEADER);
}
@@ -4620,7 +4637,7 @@ putbody(mci, e, separator)
if (hvalue("Content-Type", e->e_header) == NULL)
{
- (void) sm_snprintf(buf, sizeof buf,
+ (void) sm_snprintf(buf, sizeof(buf),
"Content-Type: text/plain; charset=%s",
defcharset(e));
if (!putline(buf, mci))
@@ -4688,9 +4705,9 @@ putbody(mci, e, separator)
}
/* determine end of buffer; allow for short mailer lines */
- buflim = &buf[sizeof buf - 1];
+ buflim = &buf[sizeof(buf) - 1];
if (mci->mci_mailer->m_linelimit > 0 &&
- mci->mci_mailer->m_linelimit < sizeof buf - 1)
+ mci->mci_mailer->m_linelimit < sizeof(buf) - 1)
buflim = &buf[mci->mci_mailer->m_linelimit - 1];
/* copy temp file to output with mapping */
@@ -4836,6 +4853,7 @@ putbody(mci, e, separator)
SM_TIME_DEFAULT,
mci->mci_mailer->m_eol);
}
+ pos = 0;
ostate = OSTATE_HEAD;
continue;
}
@@ -5135,13 +5153,13 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
if (strncmp(SafeFileEnv, filename, len) == 0)
filename += len;
- if (len + strlen(filename) + 1 >= sizeof targetfile)
+ if (len + strlen(filename) + 1 >= sizeof(targetfile))
{
syserr("mailfile: filename too long (%s/%s)",
SafeFileEnv, filename);
return EX_CANTCREAT;
}
- (void) sm_strlcpy(targetfile, SafeFileEnv, sizeof targetfile);
+ (void) sm_strlcpy(targetfile, SafeFileEnv, sizeof(targetfile));
realfile = targetfile + len;
if (*filename == '/')
filename++;
@@ -5150,20 +5168,20 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
/* paranoia: trailing / should be removed in readcf */
if (targetfile[len - 1] != '/')
(void) sm_strlcat(targetfile,
- "/", sizeof targetfile);
+ "/", sizeof(targetfile));
(void) sm_strlcat(targetfile, filename,
- sizeof targetfile);
+ sizeof(targetfile));
}
}
else if (mailer->m_rootdir != NULL)
{
- expand(mailer->m_rootdir, targetfile, sizeof targetfile, e);
+ expand(mailer->m_rootdir, targetfile, sizeof(targetfile), e);
len = strlen(targetfile);
if (strncmp(targetfile, filename, len) == 0)
filename += len;
- if (len + strlen(filename) + 1 >= sizeof targetfile)
+ if (len + strlen(filename) + 1 >= sizeof(targetfile))
{
syserr("mailfile: filename too long (%s/%s)",
targetfile, filename);
@@ -5171,18 +5189,18 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
}
realfile = targetfile + len;
if (targetfile[len - 1] != '/')
- (void) sm_strlcat(targetfile, "/", sizeof targetfile);
+ (void) sm_strlcat(targetfile, "/", sizeof(targetfile));
if (*filename == '/')
(void) sm_strlcat(targetfile, filename + 1,
- sizeof targetfile);
+ sizeof(targetfile));
else
(void) sm_strlcat(targetfile, filename,
- sizeof targetfile);
+ sizeof(targetfile));
}
else
{
- if (sm_strlcpy(targetfile, filename, sizeof targetfile) >=
- sizeof targetfile)
+ if (sm_strlcpy(targetfile, filename, sizeof(targetfile)) >=
+ sizeof(targetfile))
{
syserr("mailfile: filename too long (%s)", filename);
return EX_CANTCREAT;
@@ -5460,7 +5478,7 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
q = strchr(p, ':');
if (q != NULL)
*q = '\0';
- expand(p, buf, sizeof buf, e);
+ expand(p, buf, sizeof(buf), e);
if (q != NULL)
*q++ = ':';
if (tTd(11, 20))
@@ -5544,7 +5562,7 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
if (ev != NULL)
sm_clrevent(ev);
- memset(&mcibuf, '\0', sizeof mcibuf);
+ memset(&mcibuf, '\0', sizeof(mcibuf));
mcibuf.mci_mailer = mailer;
mcibuf.mci_out = f;
if (bitnset(M_7BITS, mailer->m_flags))
diff --git a/contrib/sendmail/src/domain.c b/contrib/sendmail/src/domain.c
index 81e64d1..394b0d3f 100644
--- a/contrib/sendmail/src/domain.c
+++ b/contrib/sendmail/src/domain.c
@@ -12,11 +12,12 @@
*/
#include <sendmail.h>
+#include "map.h"
#if NAMED_BIND
-SM_RCSID("@(#)$Id: domain.c,v 8.199 2006/04/18 00:00:34 ca Exp $ (with name server)")
+SM_RCSID("@(#)$Id: domain.c,v 8.202 2006/12/19 01:15:07 ca Exp $ (with name server)")
#else /* NAMED_BIND */
-SM_RCSID("@(#)$Id: domain.c,v 8.199 2006/04/18 00:00:34 ca Exp $ (without name server)")
+SM_RCSID("@(#)$Id: domain.c,v 8.202 2006/12/19 01:15:07 ca Exp $ (without name server)")
#endif /* NAMED_BIND */
#if NAMED_BIND
@@ -276,7 +277,7 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl)
{
if (tTd(8, 1))
sm_dprintf("getmxrr: res_search(%s) failed (errno=%d, h_errno=%d)\n",
- host == NULL ? "<NULL>" : host, errno, h_errno);
+ host, errno, h_errno);
switch (h_errno)
{
case NO_DATA:
@@ -524,14 +525,14 @@ punt:
h = NULL;
# endif /* NETINET6 */
}
- if (strlen(host) >= sizeof MXHostBuf)
+ if (strlen(host) >= sizeof(MXHostBuf))
{
*rcode = EX_CONFIG;
syserr("Host name %s too long",
shortenstring(host, MAXSHORTSTR));
return -1;
}
- (void) sm_strlcpy(MXHostBuf, host, sizeof MXHostBuf);
+ (void) sm_strlcpy(MXHostBuf, host, sizeof(MXHostBuf));
mxhosts[0] = MXHostBuf;
prefs[0] = 0;
if (host[0] == '[')
@@ -568,7 +569,7 @@ punt:
}
}
if (trycanon &&
- getcanonname(mxhosts[0], sizeof MXHostBuf - 2, false, pttl))
+ getcanonname(mxhosts[0], sizeof(MXHostBuf) - 2, false, pttl))
{
/* XXX MXHostBuf == "" ? is that possible? */
bp = &MXHostBuf[strlen(MXHostBuf)];
@@ -730,14 +731,14 @@ bestmx_map_lookup(map, name, av, statp)
return NULL;
}
slen = strlen(mxhosts[i]);
- if (len + slen + 2 > sizeof buf)
+ if (len + slen + 2 > sizeof(buf))
break;
if (i > 0)
{
*p++ = map->map_coldelim;
len++;
}
- (void) sm_strlcpy(p, mxhosts[i], sizeof buf - len);
+ (void) sm_strlcpy(p, mxhosts[i], sizeof(buf) - len);
p += slen;
len += slen;
}
@@ -1005,7 +1006,7 @@ nexttype:
ap += n)
{
n = dn_expand((unsigned char *) &answer, eom, ap,
- (RES_UNC_T) nbuf, sizeof nbuf);
+ (RES_UNC_T) nbuf, sizeof(nbuf));
if (n < 0)
break;
ap += n;
@@ -1070,7 +1071,7 @@ nexttype:
char ebuf[MAXLINE];
(void) sm_snprintf(ebuf,
- sizeof ebuf,
+ sizeof(ebuf),
"Deferred: DNS failure: CNAME loop for %.100s",
host);
CurEnv->e_message =
@@ -1149,7 +1150,7 @@ nexttype:
** Otherwise append the saved domain name.
*/
- (void) sm_snprintf(nbuf, sizeof nbuf, "%.*s%s%.*s", MAXDNAME, host,
+ (void) sm_snprintf(nbuf, sizeof(nbuf), "%.*s%s%.*s", MAXDNAME, host,
*mxmatch == '\0' ? "" : ".",
MAXDNAME, mxmatch);
(void) sm_strlcpy(host, nbuf, hbsize);
diff --git a/contrib/sendmail/src/envelope.c b/contrib/sendmail/src/envelope.c
index 50009a4..a607a15 100644
--- a/contrib/sendmail/src/envelope.c
+++ b/contrib/sendmail/src/envelope.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2003, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: envelope.c,v 8.296 2006/03/31 18:53:50 ca Exp $")
+SM_RCSID("@(#)$Id: envelope.c,v 8.302 2006/11/10 23:12:52 ca Exp $")
/*
** CLRSESSENVELOPE -- clear session oriented data in an envelope
@@ -75,9 +75,7 @@ newenvelope(e, parent, rpool)
register ENVELOPE *parent;
SM_RPOOL_T *rpool;
{
-#if _FFR_DM_PER_DAEMON
- int sendmode;
-#endif /* _FFR_DM_PER_DAEMON */
+ int sendmode;
/*
** This code used to read:
@@ -88,12 +86,10 @@ newenvelope(e, parent, rpool)
** This meant macvalue() could go into an infinite loop.
*/
-#if _FFR_DM_PER_DAEMON
if (parent != NULL)
sendmode = parent->e_sendmode;
else
sendmode = DM_NOTSET;
-#endif /* _FFR_DM_PER_DAEMON */
if (e == parent)
parent = e->e_parent;
@@ -101,11 +97,11 @@ newenvelope(e, parent, rpool)
if (e == CurEnv)
memmove((char *) &e->e_from,
(char *) &NullAddress,
- sizeof e->e_from);
+ sizeof(e->e_from));
else
memmove((char *) &e->e_from,
(char *) &CurEnv->e_from,
- sizeof e->e_from);
+ sizeof(e->e_from));
e->e_parent = parent;
assign_queueid(e);
e->e_ctime = curtime();
@@ -130,10 +126,8 @@ newenvelope(e, parent, rpool)
e->e_putbody = putbody;
if (CurEnv->e_xfp != NULL)
(void) sm_io_flush(CurEnv->e_xfp, SM_TIME_DEFAULT);
-#if _FFR_DM_PER_DAEMON
if (sendmode != DM_NOTSET)
e->e_sendmode = sendmode;
-#endif /* _FFR_DM_PER_DAEMON */
return e;
}
@@ -289,13 +283,13 @@ dropenvelope(e, fulldrop, split)
{
if (msg_timeout == MSG_NOT_BY)
{
- (void) sm_snprintf(buf, sizeof buf,
+ (void) sm_snprintf(buf, sizeof(buf),
"delivery time expired %lds",
e->e_deliver_by);
}
else
{
- (void) sm_snprintf(buf, sizeof buf,
+ (void) sm_snprintf(buf, sizeof(buf),
"Cannot send message for %s",
pintvl(TimeOuts.to_q_return[e->e_timeoutclass],
false));
@@ -387,12 +381,12 @@ dropenvelope(e, fulldrop, split)
{
if (msg_timeout == MSG_WARN_BY)
{
- (void) sm_snprintf(buf, sizeof buf,
+ (void) sm_snprintf(buf, sizeof(buf),
"Warning: Delivery time (%lds) exceeded",
e->e_deliver_by);
}
else
- (void) sm_snprintf(buf, sizeof buf,
+ (void) sm_snprintf(buf, sizeof(buf),
"Warning: could not send message for past %s",
pintvl(TimeOuts.to_q_warning[e->e_timeoutclass],
false));
@@ -488,7 +482,7 @@ dropenvelope(e, fulldrop, split)
if (failure_return)
{
- expand(PostMasterCopy, pcopy, sizeof pcopy, e);
+ expand(PostMasterCopy, pcopy, sizeof(pcopy), e);
if (tTd(50, 8))
sm_dprintf("dropenvelope(%s): sending postmaster copy to %s\n",
@@ -706,8 +700,8 @@ clearenvelope(e, fullclear, rpool)
nhp = &e->e_header;
while (bh != NULL)
{
- *nhp = (HDR *) sm_rpool_malloc_x(rpool, sizeof *bh);
- memmove((char *) *nhp, (char *) bh, sizeof *bh);
+ *nhp = (HDR *) sm_rpool_malloc_x(rpool, sizeof(*bh));
+ memmove((char *) *nhp, (char *) bh, sizeof(*bh));
bh = bh->h_link;
nhp = &(*nhp)->h_link;
}
@@ -766,11 +760,11 @@ initsys(e)
*/
/* process id */
- (void) sm_snprintf(buf, sizeof buf, "%d", (int) CurrentPid);
+ (void) sm_snprintf(buf, sizeof(buf), "%d", (int) CurrentPid);
macdefine(&e->e_macro, A_TEMP, 'p', buf);
/* hop count */
- (void) sm_snprintf(buf, sizeof buf, "%d", e->e_hopcount);
+ (void) sm_snprintf(buf, sizeof(buf), "%d", e->e_hopcount);
macdefine(&e->e_macro, A_TEMP, 'c', buf);
/* time as integer, unix time, arpa time */
@@ -788,7 +782,7 @@ initsys(e)
{
if (strrchr(p, '/') != NULL)
p = strrchr(p, '/') + 1;
- (void) sm_strlcpy(ybuf, sizeof ybuf, p);
+ (void) sm_strlcpy(ybuf, sizeof(ybuf), p);
macdefine(&e->e_macro, A_PERM, 'y', ybuf);
}
}
@@ -817,14 +811,14 @@ settime(e)
register struct tm *tm;
now = curtime();
- (void) sm_snprintf(buf, sizeof buf, "%ld", (long) now);
+ (void) sm_snprintf(buf, sizeof(buf), "%ld", (long) now);
macdefine(&e->e_macro, A_TEMP, macid("{time}"), buf);
tm = gmtime(&now);
- (void) sm_snprintf(buf, sizeof buf, "%04d%02d%02d%02d%02d",
+ (void) sm_snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min);
macdefine(&e->e_macro, A_TEMP, 't', buf);
- (void) sm_strlcpy(buf, ctime(&now), sizeof buf);
+ (void) sm_strlcpy(buf, ctime(&now), sizeof(buf));
p = strchr(buf, '\n');
if (p != NULL)
*p = '\0';
@@ -1013,7 +1007,7 @@ setsender(from, e, delimptr, delimchar, internal)
if (host == NULL)
host = MyHostName;
- (void) sm_snprintf(ebuf, sizeof ebuf,
+ (void) sm_snprintf(ebuf, sizeof(ebuf),
"%.*s@%.*s", MAXNAME,
realname, MAXNAME, host);
p = ebuf;
@@ -1041,7 +1035,7 @@ setsender(from, e, delimptr, delimchar, internal)
char nbuf[100];
SuprErrs = true;
- expand("\201n", nbuf, sizeof nbuf, e);
+ expand("\201n", nbuf, sizeof(nbuf), e);
from = sm_rpool_strdup_x(e->e_rpool, nbuf);
if (parseaddr(from, &e->e_from, RF_COPYALL, ' ',
NULL, e, false) == NULL &&
@@ -1152,7 +1146,8 @@ setsender(from, e, delimptr, delimchar, internal)
** links in the net.
*/
- pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL, NULL, false);
+ pvp = prescan(from, delimchar, pvpbuf, sizeof(pvpbuf), NULL,
+ IntTokenTab, false);
if (pvp == NULL)
{
/* don't need to give error -- prescan did that already */
@@ -1167,11 +1162,11 @@ setsender(from, e, delimptr, delimchar, internal)
(void) REWRITE(pvp, 4, e);
macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), NULL);
bp = buf + 1;
- cataddr(pvp, NULL, bp, sizeof buf - 2, '\0');
+ cataddr(pvp, NULL, bp, sizeof(buf) - 2, '\0', false);
if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags))
{
/* heuristic: route-addr: add angle brackets */
- (void) sm_strlcat(bp, ">", sizeof buf - 1);
+ (void) sm_strlcat(bp, ">", sizeof(buf) - 1);
*--bp = '<';
}
e->e_sender = sm_rpool_strdup_x(e->e_rpool, bp);
diff --git a/contrib/sendmail/src/helpfile b/contrib/sendmail/src/helpfile
index d5d55e8..941dc2a 100644
--- a/contrib/sendmail/src/helpfile
+++ b/contrib/sendmail/src/helpfile
@@ -1,6 +1,6 @@
#vers 2
cpyr
-cpyr Copyright (c) 1998-2000, 2002, 2004-2006 Sendmail, Inc. and its suppliers.
+cpyr Copyright (c) 1998-2000, 2002, 2004-2007 Sendmail, Inc. and its suppliers.
cpyr All rights reserved.
cpyr Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
cpyr Copyright (c) 1988, 1993
@@ -11,7 +11,7 @@ cpyr By using this file, you agree to the terms and conditions set
cpyr forth in the LICENSE file which can be found at the top level of
cpyr the sendmail distribution.
cpyr
-cpyr $$Id: helpfile,v 8.47 2006/04/26 18:22:54 ca Exp $$
+cpyr $$Id: helpfile,v 8.48 2007/02/01 18:29:44 ca Exp $$
cpyr
smtp This is sendmail version $v
smtp Topics:
@@ -133,4 +133,5 @@ control help This message.
control restart Restart sendmail.
control shutdown Shutdown sendmail.
control status Show sendmail status.
+control mstat Show sendmail status (machine readable format).
control memdump Dump allocated memory list (for debugging only).
diff --git a/contrib/sendmail/src/macro.c b/contrib/sendmail/src/macro.c
index af8f6d5..8f0642f 100644
--- a/contrib/sendmail/src/macro.c
+++ b/contrib/sendmail/src/macro.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2001, 2003 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2001, 2003, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,14 +13,17 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: macro.c,v 8.88 2003/09/05 23:11:18 ca Exp $")
+SM_RCSID("@(#)$Id: macro.c,v 8.102 2006/12/21 23:06:10 ca Exp $")
+#include <sm/sendmail.h>
#if MAXMACROID != (BITMAPBITS - 1)
ERROR Read the comment in conf.h
#endif /* MAXMACROID != (BITMAPBITS - 1) */
static char *MacroName[MAXMACROID + 1]; /* macro id to name table */
int NextMacroId = 0240; /* codes for long named macros */
+/* see sendmail.h: Special characters in rewriting rules. */
+
/*
** INITMACROS -- initialize the macro system
@@ -67,10 +70,10 @@ struct metamac MetaMacros[] =
void
initmacros(e)
- register ENVELOPE *e;
+ ENVELOPE *e;
{
- register struct metamac *m;
- register int c;
+ struct metamac *m;
+ int c;
char buf[5];
for (m = MetaMacros; m->metaname != '\0'; m++)
@@ -94,13 +97,19 @@ initmacros(e)
MACBINDING("opMode", MID_OPMODE);
/*XXX should probably add equivalents for all short macros here XXX*/
}
+
/*
-** EXPAND -- macro expand a string using $x escapes.
+** EXPAND/DOEXPAND -- macro expand a string using $x escapes.
+**
+** After expansion, the expansion will be in external form (that is,
+** there will be no sendmail metacharacters and METAQUOTEs will have
+** been stripped out).
**
** Parameters:
** s -- the string to expand.
** buf -- the place to put the expansion.
** bufsize -- the size of the buffer.
+** explevel -- the depth of expansion (doexpand only)
** e -- envelope in which to work.
**
** Returns:
@@ -110,22 +119,25 @@ initmacros(e)
** none.
*/
-void
-expand(s, buf, bufsize, e)
- register char *s;
- register char *buf;
+static void doexpand __P(( char *, char *, size_t, int, ENVELOPE *));
+
+static void
+doexpand(s, buf, bufsize, explevel, e)
+ char *s;
+ char *buf;
size_t bufsize;
- register ENVELOPE *e;
+ int explevel;
+ ENVELOPE *e;
{
- register char *xp;
- register char *q;
+ char *xp;
+ char *q;
bool skipping; /* set if conditionally skipping output */
bool recurse; /* set if recursion required */
size_t i;
int skiplev; /* skipping nesting level */
int iflev; /* if nesting level */
+ bool quotenext; /* quote the following character */
char xbuf[MACBUFSIZE];
- static int explevel = 0;
if (tTd(35, 24))
{
@@ -138,6 +150,7 @@ expand(s, buf, bufsize, e)
skipping = false;
skiplev = 0;
iflev = 0;
+ quotenext = false;
if (s == NULL)
s = "";
for (xp = xbuf; *s != '\0'; s++)
@@ -150,12 +163,19 @@ expand(s, buf, bufsize, e)
*/
q = NULL;
- c = *s;
- switch (c & 0377)
+ c = *s & 0377;
+
+ if (quotenext)
+ {
+ quotenext = false;
+ goto simpleinterpolate;
+ }
+
+ switch (c)
{
case CONDIF: /* see if var set */
iflev++;
- c = *++s;
+ c = *++s & 0377;
if (skipping)
skiplev++;
else
@@ -196,33 +216,45 @@ expand(s, buf, bufsize, e)
if (q == NULL)
continue;
break;
+
+ case METAQUOTE:
+ /* next octet completely quoted */
+ quotenext = true;
+ break;
}
/*
** Interpolate q or output one character
*/
- if (skipping || xp >= &xbuf[sizeof xbuf - 1])
+ simpleinterpolate:
+ if (skipping || xp >= &xbuf[sizeof(xbuf) - 1])
continue;
if (q == NULL)
*xp++ = c;
else
{
/* copy to end of q or max space remaining in buf */
- while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1])
+ bool hiderecurse = false;
+
+ while ((c = *q++) != '\0' &&
+ xp < &xbuf[sizeof(xbuf) - 1])
{
/* check for any sendmail metacharacters */
- if ((c & 0340) == 0200)
+ if (!hiderecurse && (c & 0340) == 0200)
recurse = true;
*xp++ = c;
+
+ /* give quoted characters a free ride */
+ hiderecurse = (c & 0377) == METAQUOTE;
}
}
}
*xp = '\0';
- if (tTd(35, 24))
+ if (tTd(35, 28))
{
- sm_dprintf("expand ==> ");
+ sm_dprintf("expand(%d) ==> ", explevel);
xputs(sm_debug_file(), xbuf);
sm_dprintf("\n");
}
@@ -232,9 +264,7 @@ expand(s, buf, bufsize, e)
{
if (explevel < MaxMacroRecursion)
{
- explevel++;
- expand(xbuf, buf, bufsize, e);
- explevel--;
+ doexpand(xbuf, buf, bufsize, explevel + 1, e);
return;
}
syserr("expand: recursion too deep (%d max)",
@@ -242,11 +272,34 @@ expand(s, buf, bufsize, e)
}
/* copy results out */
- i = xp - xbuf;
- if (i >= bufsize)
- i = bufsize - 1;
- memmove(buf, xbuf, i);
- buf[i] = '\0';
+ if (explevel == 0)
+ (void) sm_strlcpy(buf, xbuf, bufsize);
+ else
+ {
+ /* leave in internal form */
+ i = xp - xbuf;
+ if (i >= bufsize)
+ i = bufsize - 1;
+ memmove(buf, xbuf, i);
+ buf[i] = '\0';
+ }
+
+ if (tTd(35, 24))
+ {
+ sm_dprintf("expand ==> ");
+ xputs(sm_debug_file(), buf);
+ sm_dprintf("\n");
+ }
+}
+
+void
+expand(s, buf, bufsize, e)
+ char *s;
+ char *buf;
+ size_t bufsize;
+ ENVELOPE *e;
+{
+ doexpand(s, buf, bufsize, 0, e);
}
/*
@@ -407,19 +460,19 @@ macset(mac, i, value)
char *
macvalue(n, e)
int n;
- register ENVELOPE *e;
+ ENVELOPE *e;
{
n = bitidx(n);
if (e != NULL && e->e_mci != NULL)
{
- register char *p = e->e_mci->mci_macro.mac_table[n];
+ char *p = e->e_mci->mci_macro.mac_table[n];
if (p != NULL)
return p;
}
while (e != NULL)
{
- register char *p = e->e_macro.mac_table[n];
+ char *p = e->e_macro.mac_table[n];
if (p != NULL)
return p;
@@ -429,6 +482,7 @@ macvalue(n, e)
}
return GlobalMacros.mac_table[n];
}
+
/*
** MACNAME -- return the name of a macro given its internal id
**
@@ -440,6 +494,9 @@ macvalue(n, e)
**
** Side Effects:
** none.
+**
+** WARNING:
+** Not thread-safe.
*/
char *
@@ -448,8 +505,12 @@ macname(n)
{
static char mbuf[2];
- n = bitidx(n);
- if (bitset(0200, n))
+ n = (int)(unsigned char)n;
+ if (n > MAXMACROID)
+ return "***OUT OF RANGE MACRO***";
+
+ /* if not ASCII printable, look up the name */
+ if (n <= 0x20 || n > 0x7f)
{
char *p = MacroName[n];
@@ -457,10 +518,13 @@ macname(n)
return p;
return "***UNDEFINED MACRO***";
}
+
+ /* if in the ASCII graphic range, just return the id directly */
mbuf[0] = n;
mbuf[1] = '\0';
return mbuf;
}
+
/*
** MACID_PARSE -- return id of macro identified by its name
**
@@ -472,7 +536,7 @@ macname(n)
**
** Returns:
** 0 -- An error was detected.
-** 1..255 -- The internal id code for this macro.
+** 1..MAXMACROID -- The internal id code for this macro.
**
** Side Effects:
** If this is a new macro name, a new id is allocated.
@@ -481,11 +545,11 @@ macname(n)
int
macid_parse(p, ep)
- register char *p;
+ char *p;
char **ep;
{
int mid;
- register char *bp;
+ char *bp;
char mbuf[MAXMACNAMELEN + 1];
if (tTd(35, 14))
@@ -510,11 +574,18 @@ macid_parse(p, ep)
if (ep != NULL)
*ep = p + 1;
if (tTd(35, 14))
- sm_dprintf("%c\n", bitidx(*p));
+ {
+ char buf[2];
+
+ buf[0] = *p;
+ buf[1] = '\0';
+ xputs(sm_debug_file(), buf);
+ sm_dprintf("\n");
+ }
return bitidx(*p);
}
bp = mbuf;
- while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof mbuf - 1])
+ while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof(mbuf) - 1])
{
if (isascii(*p) && (isalnum(*p) || *p == '_'))
*bp++ = *p;
@@ -530,7 +601,7 @@ macid_parse(p, ep)
else if (*p != '}')
{
syserr("Macro/class name ({%s}) too long (%d chars max)",
- mbuf, (int) (sizeof mbuf - 1));
+ mbuf, (int) (sizeof(mbuf) - 1));
}
else if (mbuf[1] == '\0')
{
@@ -540,7 +611,7 @@ macid_parse(p, ep)
}
else
{
- register STAB *s;
+ STAB *s;
s = stab(mbuf, ST_MACRO, ST_ENTER);
if (s->s_macro != 0)
@@ -574,6 +645,7 @@ macid_parse(p, ep)
sm_dprintf("0x%x\n", mid);
return mid;
}
+
/*
** WORDINCLASS -- tell if a word is in a specific class
**
@@ -591,7 +663,7 @@ wordinclass(str, cl)
char *str;
int cl;
{
- register STAB *s;
+ STAB *s;
s = stab(str, ST_CLASS, ST_FIND);
return s != NULL && bitnset(bitidx(cl), s->s_class);
diff --git a/contrib/sendmail/src/main.c b/contrib/sendmail/src/main.c
index 0d6928d..c11de46 100644
--- a/contrib/sendmail/src/main.c
+++ b/contrib/sendmail/src/main.c
@@ -13,6 +13,7 @@
#define _DEFINE
#include <sendmail.h>
+#include <sm/sendmail.h>
#include <sm/xtrap.h>
#include <sm/signal.h>
@@ -25,7 +26,7 @@ SM_UNUSED(static char copyright[]) =
The Regents of the University of California. All rights reserved.\n";
#endif /* ! lint */
-SM_RCSID("@(#)$Id: main.c,v 8.944.2.2 2006/08/03 22:05:03 ca Exp $")
+SM_RCSID("@(#)$Id: main.c,v 8.962 2006/12/19 19:47:37 ca Exp $")
#if NETINET || NETINET6
@@ -231,7 +232,7 @@ main(argc, argv, envp)
starttime = curtime();
/* avoid null pointer dereferences */
- TermEscape.te_rv_on = TermEscape.te_rv_off = "";
+ TermEscape.te_rv_on = TermEscape.te_under_on = TermEscape.te_normal = "";
RealUid = getuid();
RealGid = getgid();
@@ -305,7 +306,7 @@ main(argc, argv, envp)
checkfd012("after openlog");
#endif /* XDEBUG */
- tTsetup(tTdvect, sizeof tTdvect, "0-99.1,*_trace_*.1");
+ tTsetup(tTdvect, sizeof(tTdvect), "0-99.1,*_trace_*.1");
#ifdef NGROUPS_MAX
/* save initial group set for future checks */
@@ -477,7 +478,7 @@ main(argc, argv, envp)
"WARNING: Can not use -d with -q. Disabling debugging.\n");
sm_debug_close();
sm_debug_setfile(NULL);
- (void) memset(tTdvect, '\0', sizeof tTdvect);
+ (void) memset(tTdvect, '\0', sizeof(tTdvect));
}
#if LOG
@@ -521,9 +522,9 @@ main(argc, argv, envp)
pw = sm_getpwuid(RealUid);
if (pw != NULL)
- (void) sm_strlcpy(rnamebuf, pw->pw_name, sizeof rnamebuf);
+ (void) sm_strlcpy(rnamebuf, pw->pw_name, sizeof(rnamebuf));
else
- (void) sm_snprintf(rnamebuf, sizeof rnamebuf, "Unknown UID %d",
+ (void) sm_snprintf(rnamebuf, sizeof(rnamebuf), "Unknown UID %d",
(int) RealUid);
RealUserName = rnamebuf;
@@ -567,7 +568,7 @@ main(argc, argv, envp)
j = 0;
for (av = argv; *av != NULL; )
j += strlen(*av++) + 1;
- SaveArgv = (char **) xalloc(sizeof (char *) * (argc + 1));
+ SaveArgv = (char **) xalloc(sizeof(char *) * (argc + 1));
CommandLineArgs = xalloc(j);
p = CommandLineArgs;
for (av = argv, i = 0; *av != NULL; )
@@ -691,7 +692,7 @@ main(argc, argv, envp)
macdefine(&BlankEnvelope.e_macro, A_PERM, 'v', Version);
/* hostname */
- hp = myhostname(jbuf, sizeof jbuf);
+ hp = myhostname(jbuf, sizeof(jbuf));
if (jbuf[0] != '\0')
{
struct utsname utsname;
@@ -752,7 +753,7 @@ main(argc, argv, envp)
break;
memmove(&ia, hp->h_addr_list[i], INADDRSZ);
- (void) sm_snprintf(ipbuf, sizeof ipbuf,
+ (void) sm_snprintf(ipbuf, sizeof(ipbuf),
"[%.100s]", inet_ntoa(ia));
break;
# endif /* NETINET */
@@ -763,9 +764,9 @@ main(argc, argv, envp)
break;
memmove(&ia6, hp->h_addr_list[i], IN6ADDRSZ);
- addr = anynet_ntop(&ia6, buf6, sizeof buf6);
+ addr = anynet_ntop(&ia6, buf6, sizeof(buf6));
if (addr != NULL)
- (void) sm_snprintf(ipbuf, sizeof ipbuf,
+ (void) sm_snprintf(ipbuf, sizeof(ipbuf),
"[%.100s]", addr);
break;
# endif /* NETINET6 */
@@ -863,7 +864,7 @@ main(argc, argv, envp)
CHECK_AGAINST_OPMODE(j);
BlankEnvelope.e_hopcount = (short) strtol(optarg, &ep,
10);
- (void) sm_snprintf(buf, sizeof buf, "%d",
+ (void) sm_snprintf(buf, sizeof(buf), "%d",
BlankEnvelope.e_hopcount);
macdefine(&BlankEnvelope.e_macro, A_TEMP, 'c', buf);
@@ -1006,7 +1007,7 @@ main(argc, argv, envp)
break;
case 'I': /* Limit by ID */
- new = (QUEUE_CHAR *) xalloc(sizeof *new);
+ new = (QUEUE_CHAR *) xalloc(sizeof(*new));
new->queue_match = newstr(&optarg[1]);
new->queue_negate = negate;
new->queue_next = QueueLimitId;
@@ -1014,7 +1015,7 @@ main(argc, argv, envp)
break;
case 'R': /* Limit by recipient */
- new = (QUEUE_CHAR *) xalloc(sizeof *new);
+ new = (QUEUE_CHAR *) xalloc(sizeof(*new));
new->queue_match = newstr(&optarg[1]);
new->queue_negate = negate;
new->queue_next = QueueLimitRecipient;
@@ -1022,7 +1023,7 @@ main(argc, argv, envp)
break;
case 'S': /* Limit by sender */
- new = (QUEUE_CHAR *) xalloc(sizeof *new);
+ new = (QUEUE_CHAR *) xalloc(sizeof(*new));
new->queue_match = newstr(&optarg[1]);
new->queue_negate = negate;
new->queue_next = QueueLimitSender;
@@ -1036,7 +1037,7 @@ main(argc, argv, envp)
case 'Q': /* Limit by quarantine message */
if (optarg[1] != '\0')
{
- new = (QUEUE_CHAR *) xalloc(sizeof *new);
+ new = (QUEUE_CHAR *) xalloc(sizeof(*new));
new->queue_match = newstr(&optarg[1]);
new->queue_negate = negate;
new->queue_next = QueueLimitQuarantine;
@@ -1230,11 +1231,11 @@ main(argc, argv, envp)
mbuf[0] = '\0';
if (bitset(1 << STDIN_FILENO, MissingFds))
- (void) sm_strlcat(mbuf, ", stdin", sizeof mbuf);
+ (void) sm_strlcat(mbuf, ", stdin", sizeof(mbuf));
if (bitset(1 << STDOUT_FILENO, MissingFds))
- (void) sm_strlcat(mbuf, ", stdout", sizeof mbuf);
+ (void) sm_strlcat(mbuf, ", stdout", sizeof(mbuf));
if (bitset(1 << STDERR_FILENO, MissingFds))
- (void) sm_strlcat(mbuf, ", stderr", sizeof mbuf);
+ (void) sm_strlcat(mbuf, ", stderr", sizeof(mbuf));
/* Notice: fill_errno is from high above: fill_fd() */
sm_syslog(LOG_WARNING, NOQID,
@@ -1377,7 +1378,7 @@ main(argc, argv, envp)
HoldErrs = true;
/* set up the $=m class now, after .cf has a chance to redefine $m */
- expand("\201m", jbuf, sizeof jbuf, &BlankEnvelope);
+ expand("\201m", jbuf, sizeof(jbuf), &BlankEnvelope);
if (jbuf[0] != '\0')
setclass('m', jbuf);
@@ -1392,7 +1393,7 @@ main(argc, argv, envp)
/* Now we know which .cf file we use */
sm_dprintf(" Conf file:\t%s (selected)\n",
getcfname(OpMode, SubmitMode, cftype, conffile));
- expand(PidFile, pidpath, sizeof pidpath, &BlankEnvelope);
+ expand(PidFile, pidpath, sizeof(pidpath), &BlankEnvelope);
sm_dprintf(" Pid file:\t%s (selected)\n", pidpath);
}
@@ -1739,7 +1740,7 @@ main(argc, argv, envp)
SmtpError[0] = '\0';
/* our name for SMTP codes */
- expand("\201j", jbuf, sizeof jbuf, &BlankEnvelope);
+ expand("\201j", jbuf, sizeof(jbuf), &BlankEnvelope);
if (jbuf[0] == '\0')
PSTRSET(MyHostName, "localhost");
else
@@ -2082,7 +2083,7 @@ main(argc, argv, envp)
"> ");
(void) sm_io_flush(smioout, SM_TIME_DEFAULT);
if (sm_io_fgets(smioin, SM_TIME_DEFAULT, buf,
- sizeof buf) == NULL)
+ sizeof(buf)) == NULL)
testmodeline("/quit", &MainEnvelope);
p = strchr(buf, '\n');
if (p != NULL)
@@ -2112,7 +2113,8 @@ main(argc, argv, envp)
#if STARTTLS
tls_ok = true;
- if (OpMode == MD_QUEUERUN || OpMode == MD_DELIVER)
+ if (OpMode == MD_QUEUERUN || OpMode == MD_DELIVER ||
+ OpMode == MD_ARPAFTP)
{
/* check whether STARTTLS is turned off for the client */
if (chkclientmodifiers(D_NOTLS))
@@ -2324,7 +2326,7 @@ main(argc, argv, envp)
dtype[0] = '\0';
if (OpMode == MD_DAEMON)
{
- (void) sm_strlcat(dtype, "+SMTP", sizeof dtype);
+ (void) sm_strlcat(dtype, "+SMTP", sizeof(dtype));
DaemonPid = CurrentPid;
}
if (QueueIntvl > 0)
@@ -2334,10 +2336,10 @@ main(argc, argv, envp)
? "+persistent-queueing@"
: "+queueing@",
pintvl(QueueIntvl, true),
- sizeof dtype);
+ sizeof(dtype));
}
if (tTd(0, 1))
- (void) sm_strlcat(dtype, "+debugging", sizeof dtype);
+ (void) sm_strlcat(dtype, "+debugging", sizeof(dtype));
sm_syslog(LOG_INFO, NOQID,
"starting daemon (%s): %s", Version, dtype + 1);
@@ -2435,8 +2437,9 @@ main(argc, argv, envp)
}
sm_syslog(LOG_ERR, NOQID,
- "persistent queue runner=%d died, signal=%d",
- group, WTERMSIG(status));
+ "persistent queue runner=%d died, pid=%ld, signal=%d",
+ group, (long) ret,
+ WTERMSIG(status));
}
/*
@@ -2454,6 +2457,7 @@ main(argc, argv, envp)
mark_work_group_restart(group,
-1);
}
+ CHECK_RESTART;
}
finis(true, true, ExitStat);
/* NOTREACHED */
@@ -2472,7 +2476,7 @@ main(argc, argv, envp)
/* set the title to make it easier to find */
qtype[0] = '\0';
- (void) sm_strlcpyn(qtype, sizeof qtype, 4,
+ (void) sm_strlcpyn(qtype, sizeof(qtype), 4,
"Queue runner@",
pintvl(QueueIntvl, true),
" for ",
@@ -2541,7 +2545,7 @@ main(argc, argv, envp)
{
char ipbuf[103];
- (void) sm_snprintf(ipbuf, sizeof ipbuf, "[%.100s]",
+ (void) sm_snprintf(ipbuf, sizeof(ipbuf), "[%.100s]",
anynet_ntoa(&RealHostAddr));
macdefine(&BlankEnvelope.e_macro, A_TEMP,
macid("{client_name}"), ipbuf);
@@ -2559,18 +2563,18 @@ main(argc, argv, envp)
{
#if NETINET
case AF_INET:
- (void) sm_snprintf(pbuf, sizeof pbuf, "%d",
+ (void) sm_snprintf(pbuf, sizeof(pbuf), "%d",
RealHostAddr.sin.sin_port);
break;
#endif /* NETINET */
#if NETINET6
case AF_INET6:
- (void) sm_snprintf(pbuf, sizeof pbuf, "%d",
+ (void) sm_snprintf(pbuf, sizeof(pbuf), "%d",
RealHostAddr.sin6.sin6_port);
break;
#endif /* NETINET6 */
default:
- (void) sm_snprintf(pbuf, sizeof pbuf, "0");
+ (void) sm_snprintf(pbuf, sizeof(pbuf), "0");
break;
}
macdefine(&BlankEnvelope.e_macro, A_TEMP,
@@ -2578,17 +2582,24 @@ main(argc, argv, envp)
if (OpMode == MD_DAEMON)
{
+ ENVELOPE *saved_env;
+
/* validate the connection */
HoldErrs = true;
+ saved_env = CurEnv;
+ CurEnv = &BlankEnvelope;
nullserver = validate_connection(&RealHostAddr,
macvalue(macid("{client_name}"),
- &MainEnvelope),
- &MainEnvelope);
+ &BlankEnvelope),
+ &BlankEnvelope);
+ if (bitset(EF_DISCARD, BlankEnvelope.e_flags))
+ MainEnvelope.e_flags |= EF_DISCARD;
+ CurEnv = saved_env;
HoldErrs = false;
}
else if (p_flags == NULL)
{
- p_flags = (BITMAP256 *) xalloc(sizeof *p_flags);
+ p_flags = (BITMAP256 *) xalloc(sizeof(*p_flags));
clrbitmap(p_flags);
}
#if STARTTLS
@@ -2769,7 +2780,7 @@ main(argc, argv, envp)
}
/* set message size */
- (void) sm_snprintf(buf, sizeof buf, "%ld",
+ (void) sm_snprintf(buf, sizeof(buf), "%ld",
MainEnvelope.e_msgsize);
macdefine(&MainEnvelope.e_macro, A_TEMP,
macid("{msg_size}"), buf);
@@ -2909,8 +2920,15 @@ finis(drop, cleanup, exitstat)
sm_rpool_free(CurEnv->e_rpool);
CurEnv->e_rpool = NULL;
- /* this may have pointed to the rpool */
+ /* these may have pointed to the rpool */
CurEnv->e_to = NULL;
+ CurEnv->e_message = NULL;
+ CurEnv->e_statmsg = NULL;
+ CurEnv->e_quarmsg = NULL;
+ CurEnv->e_bodytype = NULL;
+ CurEnv->e_id = NULL;
+ CurEnv->e_envid = NULL;
+ CurEnv->e_auth_param = NULL;
}
else
poststats(StatFile);
@@ -2961,7 +2979,7 @@ finis(drop, cleanup, exitstat)
if (DaemonPid == pid || PidFilePid == pid)
{
/* blow away the pid file */
- expand(PidFile, pidpath, sizeof pidpath, CurEnv);
+ expand(PidFile, pidpath, sizeof(pidpath), CurEnv);
(void) unlink(pidpath);
}
@@ -3418,7 +3436,7 @@ auth_warning(e, msg, va_alist)
{
struct hostent *hp;
- hp = myhostname(hostbuf, sizeof hostbuf);
+ hp = myhostname(hostbuf, sizeof(hostbuf));
#if NETINET6
if (hp != NULL)
{
@@ -3428,12 +3446,12 @@ auth_warning(e, msg, va_alist)
#endif /* NETINET6 */
}
- (void) sm_strlcpyn(buf, sizeof buf, 2, hostbuf, ": ");
+ (void) sm_strlcpyn(buf, sizeof(buf), 2, hostbuf, ": ");
p = &buf[strlen(buf)];
SM_VA_START(ap, msg);
(void) sm_vsnprintf(p, SPACELEFT(buf, p), msg, ap);
SM_VA_END(ap);
- addheader("X-Authentication-Warning", buf, 0, e);
+ addheader("X-Authentication-Warning", buf, 0, e, true);
if (LogLevel > 3)
sm_syslog(LOG_INFO, e->e_id,
"Authentication-Warning: %.400s",
@@ -3589,9 +3607,6 @@ sigusr1(sig)
int sig;
{
int save_errno = errno;
-# if SM_HEAP_CHECK
- extern void dumpstab __P((void));
-# endif /* SM_HEAP_CHECK */
FIX_SYSV_SIGNAL(sig, sigusr1);
errno = save_errno;
@@ -3896,6 +3911,69 @@ sm_printoptions(options)
}
sm_dprintf("\n");
}
+
+/*
+** TO8BIT -- convert \octal sequences in a test mode input line
+**
+** Parameters:
+** str -- the input line.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** replaces \0octal in str with octal value.
+*/
+
+static bool to8bit __P((char *));
+
+static bool
+to8bit(str)
+ char *str;
+{
+ int c, len;
+ char *out, *in;
+ bool changed;
+
+ if (str == NULL)
+ return false;
+ in = out = str;
+ changed = false;
+ len = 0;
+ while ((c = (*str++ & 0377)) != '\0')
+ {
+ int oct, nxtc;
+
+ ++len;
+ if (c == '\\' &&
+ (nxtc = (*str & 0377)) == '0')
+ {
+ oct = 0;
+ while ((nxtc = (*str & 0377)) != '\0' &&
+ isascii(nxtc) && isdigit(nxtc))
+ {
+ oct <<= 3;
+ oct += nxtc - '0';
+ ++str;
+ ++len;
+ }
+ changed = true;
+ c = oct;
+ }
+ *out++ = c;
+ }
+ *out++ = c;
+ if (changed)
+ {
+ char *q;
+
+ q = quote_internal_chars(in, in, &len);
+ if (q != in)
+ sm_strlcpy(in, q, len);
+ }
+ return changed;
+}
+
/*
** TESTMODELINE -- process a test mode input line
**
@@ -3925,14 +4003,20 @@ testmodeline(line, e)
char **s;
struct rewrite *rw;
ADDRESS a;
+ char *lbp;
+ auto int lbs;
static int tryflags = RF_COPYNONE;
char exbuf[MAXLINE];
+ char lbuf[MAXLINE];
extern unsigned char TokTypeNoC[];
+ bool eightbit;
/* skip leading spaces */
while (*line == ' ')
line++;
+ lbp = NULL;
+ eightbit = false;
switch (line[0])
{
case '#':
@@ -3950,8 +4034,11 @@ testmodeline(line, e)
mid = macid_parse(&line[2], &delimptr);
if (mid == 0)
return;
- translate_dollars(delimptr);
- macdefine(&e->e_macro, A_TEMP, mid, delimptr);
+ lbs = sizeof(lbuf);
+ lbp = translate_dollars(delimptr, lbuf, &lbs);
+ macdefine(&e->e_macro, A_TEMP, mid, lbp);
+ if (lbp != lbuf)
+ SM_FREE(lbp);
break;
case 'C':
@@ -3961,8 +4048,11 @@ testmodeline(line, e)
mid = macid_parse(&line[2], &delimptr);
if (mid == 0)
return;
- translate_dollars(delimptr);
- expand(delimptr, exbuf, sizeof exbuf, e);
+ lbs = sizeof(lbuf);
+ lbp = translate_dollars(delimptr, lbuf, &lbs);
+ expand(lbp, exbuf, sizeof(exbuf), e);
+ if (lbp != lbuf)
+ SM_FREE(lbp);
p = exbuf;
while (*p != '\0')
{
@@ -4158,13 +4248,13 @@ testmodeline(line, e)
"Usage: /canon address\n");
return;
}
- else if (sm_strlcpy(host, p, sizeof host) >= sizeof host)
+ else if (sm_strlcpy(host, p, sizeof(host)) >= sizeof(host))
{
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
"Name too long\n");
return;
}
- (void) getcanonname(host, sizeof host, !HasWildcardMX,
+ (void) getcanonname(host, sizeof(host), !HasWildcardMX,
NULL);
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
"getcanonname(%s) returns %s\n",
@@ -4332,12 +4422,21 @@ testmodeline(line, e)
a.q_user);
e->e_to = NULL;
}
+ else if (sm_strcasecmp(&line[1], "header") == 0)
+ {
+ unsigned long ul;
+
+ ul = chompheader(p, CHHDR_CHECK|CHHDR_USER, NULL, e);
+ (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
+ "ul = %lu\n", ul);
+ }
else
{
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
"Unknown \"/\" command %s\n",
line);
}
+ (void) sm_io_flush(smioout, SM_TIME_DEFAULT);
return;
}
@@ -4353,6 +4452,8 @@ testmodeline(line, e)
return;
}
*p = '\0';
+ if (tTd(23, 101))
+ eightbit = to8bit(p + 1);
if (invalidaddr(p + 1, NULL, true))
return;
do
@@ -4360,8 +4461,8 @@ testmodeline(line, e)
register char **pvp;
char pvpbuf[PSBUFSIZE];
- pvp = prescan(++p, ',', pvpbuf, sizeof pvpbuf, &delimptr,
- ConfigLevel >= 9 ? TokTypeNoC : NULL, false);
+ pvp = prescan(++p, ',', pvpbuf, sizeof(pvpbuf), &delimptr,
+ ConfigLevel >= 9 ? TokTypeNoC : ExtTokenTab, false);
if (pvp == NULL)
continue;
p = q;
@@ -4382,10 +4483,19 @@ testmodeline(line, e)
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
"== Ruleset %s (%d) status %d\n",
p, rs, status);
+ else if (eightbit)
+ {
+ cataddr(pvp, NULL, exbuf, sizeof(exbuf), '\0',
+ true);
+ (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
+ "cataddr: %s\n",
+ str2prt(exbuf));
+ }
while (*p != '\0' && *p++ != ',')
continue;
}
} while (*(p = delimptr) != '\0');
+ (void) sm_io_flush(smioout, SM_TIME_DEFAULT);
}
static void
diff --git a/contrib/sendmail/src/map.c b/contrib/sendmail/src/map.c
index 9a7bf7a..510b7c9 100644
--- a/contrib/sendmail/src/map.c
+++ b/contrib/sendmail/src/map.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2005 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1992, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1992, 1993
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: map.c,v 8.672 2006/04/18 01:26:41 ca Exp $")
+SM_RCSID("@(#)$Id: map.c,v 8.696 2007/04/03 21:33:14 ca Exp $")
#if LDAPMAP
# include <sm/ldap.h>
@@ -39,6 +39,8 @@ SM_RCSID("@(#)$Id: map.c,v 8.672 2006/04/18 01:26:41 ca Exp $")
# endif /* NDBM */
#endif /* NIS */
+#include "map.h"
+
#if NEWDB
# if DB_VERSION_MAJOR < 2
static bool db_map_open __P((MAP *, int, char *, DBTYPE, const void *));
@@ -659,6 +661,50 @@ map_close(s, bogus)
}
map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_OPENBOGUS|MF_CLOSING);
}
+
+#if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
+extern int getdomainname();
+
+/* this is mainly for backward compatibility in Sun environment */
+static char *
+sun_init_domain()
+{
+ /*
+ ** Get the domain name from the kernel.
+ ** If it does not start with a leading dot, then remove
+ ** the first component. Since leading dots are funny Unix
+ ** files, we treat a leading "+" the same as a leading dot.
+ ** Finally, force there to be at least one dot in the domain name
+ ** (i.e. top-level domains are not allowed, like "com", must be
+ ** something like "sun.com").
+ */
+
+ char buf[MAXNAME];
+ char *period, *autodomain;
+
+ if (getdomainname(buf, sizeof buf) < 0)
+ return NULL;
+
+ if (buf[0] == '\0')
+ return NULL;
+
+ if (tTd(0, 20))
+ printf("domainname = %s\n", buf);
+
+ if (buf[0] == '+')
+ buf[0] = '.';
+ period = strchr(buf, '.');
+ if (period == NULL)
+ autodomain = buf;
+ else
+ autodomain = period + 1;
+ if (strchr(autodomain, '.') == NULL)
+ return newstr(buf);
+ else
+ return newstr(autodomain);
+}
+#endif /* SUN_EXTENSIONS && SUN_INIT_DOMAIN */
+
/*
** GETCANONNAME -- look up name using service switch
**
@@ -687,6 +733,10 @@ getcanonname(host, hbsize, trymx, pttl)
auto int status;
char *maptype[MAXMAPSTACK];
short mapreturn[MAXMAPACTIONS];
+#if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
+ bool should_try_nis_domain = false;
+ static char *nis_domain = NULL;
+#endif
nmaps = switch_map_find("hosts", maptype, mapreturn);
if (pttl != 0)
@@ -706,12 +756,20 @@ getcanonname(host, hbsize, trymx, pttl)
else if (strcmp("nis", maptype[mapno]) == 0)
{
found = nis_getcanonname(host, hbsize, &status);
+# if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
+ if (nis_domain == NULL)
+ nis_domain = sun_init_domain();
+# endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
}
#endif /* NIS */
#if NISPLUS
else if (strcmp("nisplus", maptype[mapno]) == 0)
{
found = nisplus_getcanonname(host, hbsize, &status);
+# if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
+ if (nis_domain == NULL)
+ nis_domain = sun_init_domain();
+# endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
}
#endif /* NISPLUS */
#if NAMED_BIND
@@ -744,6 +802,12 @@ getcanonname(host, hbsize, trymx, pttl)
(macvalue('m', CurEnv) != NULL || strchr(host, '.') != NULL))
break;
+#if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
+ if (found)
+ should_try_nis_domain = true;
+ /* but don't break, as we need to try all methods first */
+#endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
+
/* see if we should continue */
if (status == EX_TEMPFAIL)
{
@@ -784,11 +848,33 @@ getcanonname(host, hbsize, trymx, pttl)
(void) sm_strlcat(host, d, hbsize);
}
else
+ {
+#if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
+ if (VendorCode == VENDOR_SUN &&
+ should_try_nis_domain)
+ {
+ goto try_nis_domain;
+ }
+#endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
return false;
+ }
}
return true;
}
+#if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
+ if (VendorCode == VENDOR_SUN && should_try_nis_domain)
+ {
+ try_nis_domain:
+ if (nis_domain != NULL &&
+ strlen(nis_domain) + strlen(host) + 1 < hbsize)
+ {
+ (void) sm_strlcat2(host, ".", nis_domain, hbsize);
+ return true;
+ }
+ }
+#endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
+
if (tTd(38, 20))
sm_dprintf("getcanonname(%s), failed, status=%d\n", host,
status);
@@ -835,7 +921,7 @@ extract_canonname(name, dot, line, cbuf, cbuflen)
{
char nbuf[MAXNAME + 1];
- p = get_column(line, i, '\0', nbuf, sizeof nbuf);
+ p = get_column(line, i, '\0', nbuf, sizeof(nbuf));
if (p == NULL)
break;
if (*p == '\0')
@@ -918,17 +1004,7 @@ dns_map_open(map, mode)
** false -- otherwise.
*/
-# if _FFR_DNSMAP_MULTILIMIT
-# if !_FFR_DNSMAP_MULTI
- ERROR README: You must define _FFR_DNSMAP_MULTI to use _FFR_DNSMAP_MULTILIMIT
-# endif /* ! _FFR_DNSMAP_MULTI */
-# endif /* _FFR_DNSMAP_MULTILIMIT */
-
-# if _FFR_DNSMAP_MULTI
-# if _FFR_DNSMAP_MULTILIMIT
-# define map_sizelimit map_lockfd /* overload field */
-# endif /* _FFR_DNSMAP_MULTILIMIT */
-# endif /* _FFR_DNSMAP_MULTI */
+#define map_sizelimit map_lockfd /* overload field */
struct dns_map
{
@@ -943,7 +1019,7 @@ dns_map_parseargs(map,args)
register char *p = args;
struct dns_map *map_p;
- map_p = (struct dns_map *) xalloc(sizeof *map_p);
+ map_p = (struct dns_map *) xalloc(sizeof(*map_p));
map_p->dns_m_type = -1;
map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL;
@@ -1016,7 +1092,6 @@ dns_map_parseargs(map,args)
map->map_retry = atoi(p);
break;
-# if _FFR_DNSMAP_MULTI
case 'z':
if (*++p != '\\')
map->map_coldelim = *p;
@@ -1038,14 +1113,11 @@ dns_map_parseargs(map,args)
}
break;
-# if _FFR_DNSMAP_MULTILIMIT
case 'Z':
while (isascii(*++p) && isspace(*p))
continue;
map->map_sizelimit = atoi(p);
break;
-# endif /* _FFR_DNSMAP_MULTILIMIT */
-# endif /* _FFR_DNSMAP_MULTI */
/* Start of dns_map specific args */
case 'R': /* search field */
@@ -1066,7 +1138,6 @@ dns_map_parseargs(map,args)
}
break;
-# if _FFR_DNSMAP_BASE
case 'B': /* base domain */
{
char *h;
@@ -1087,8 +1158,6 @@ dns_map_parseargs(map,args)
*h = ' ';
}
break;
-# endif /* _FFR_DNSMAP_BASE */
-
}
while (*p != '\0' && !(isascii(*p) && isspace(*p)))
p++;
@@ -1103,7 +1172,7 @@ dns_map_parseargs(map,args)
map->map_tapp = newstr(map->map_tapp);
/*
- ** Assumption: assert(sizeof int <= sizeof(ARBPTR_T));
+ ** Assumption: assert(sizeof(int) <= sizeof(ARBPTR_T));
** Even if this assumption is wrong, we use only one byte,
** so it doesn't really matter.
*/
@@ -1133,11 +1202,7 @@ dns_map_lookup(map, name, av, statp)
char **av;
int *statp;
{
-# if _FFR_DNSMAP_MULTI
-# if _FFR_DNSMAP_MULTILIMIT
int resnum = 0;
-# endif /* _FFR_DNSMAP_MULTILIMIT */
-# endif /* _FFR_DNSMAP_MULTI */
char *vp = NULL, *result = NULL;
size_t vsize;
struct dns_map *map_p;
@@ -1152,7 +1217,6 @@ dns_map_lookup(map, name, av, statp)
map->map_mname, name);
map_p = (struct dns_map *)(map->map_db1);
-# if _FFR_DNSMAP_BASE
if (map->map_file != NULL && *map->map_file != '\0')
{
size_t len;
@@ -1171,7 +1235,6 @@ dns_map_lookup(map, name, av, statp)
sm_free(appdomain);
}
else
-# endif /* _FFR_DNSMAP_BASE */
{
r = dns_lookup_int(name, C_IN, map_p->dns_m_type,
map->map_timeout, map->map_retry);
@@ -1232,7 +1295,7 @@ dns_map_lookup(map, name, av, statp)
case T_AAAA:
type = "T_AAAA";
value = anynet_ntop(rr->rr_u.rr_aaaa, buf6,
- sizeof buf6);
+ sizeof(buf6));
break;
# endif /* NETINET6 */
}
@@ -1263,12 +1326,9 @@ dns_map_lookup(map, name, av, statp)
type != NULL ? type : "<UNKNOWN>",
rr->rr_type,
value != NULL ? value : "<NO VALUE>");
-# if _FFR_DNSMAP_MULTI
if (value != NULL &&
(map->map_coldelim == '\0' ||
-# if _FFR_DNSMAP_MULTILIMIT
map->map_sizelimit == 1 ||
-# endif /* _FFR_DNSMAP_MULTILIMIT */
bitset(MF_MATCHONLY, map->map_mflags)))
{
/* Only care about the first match */
@@ -1292,16 +1352,10 @@ dns_map_lookup(map, name, av, statp)
vp, map->map_coldelim, value);
sm_free(vp);
vp = new;
-# if _FFR_DNSMAP_MULTILIMIT
if (map->map_sizelimit > 0 &&
++resnum >= map->map_sizelimit)
break;
-# endif /* _FFR_DNSMAP_MULTILIMIT */
}
-# else /* _FFR_DNSMAP_MULTI */
- vp = value;
- break;
-# endif /* _FFR_DNSMAP_MULTI */
}
if (vp == NULL)
{
@@ -1312,10 +1366,8 @@ dns_map_lookup(map, name, av, statp)
goto cleanup;
}
-# if _FFR_DNSMAP_MULTI
/* Cleanly truncate for rulesets */
truncate_at_delim(vp, PSBUFSIZE / 2, map->map_coldelim);
-# endif /* _FFR_DNSMAP_MULTI */
vsize = strlen(vp);
@@ -1328,10 +1380,8 @@ dns_map_lookup(map, name, av, statp)
result = map_rewrite(map, vp, vsize, av);
cleanup:
-# if _FFR_DNSMAP_MULTI
if (vp != NULL)
sm_free(vp);
-# endif /* _FFR_DNSMAP_MULTI */
if (r != NULL)
dns_free_data(r);
return result;
@@ -1373,10 +1423,10 @@ ndbm_map_open(map, mode)
mode &= O_ACCMODE;
/* do initial file and directory checks */
- if (sm_strlcpyn(dirfile, sizeof dirfile, 2,
- map->map_file, ".dir") >= sizeof dirfile ||
- sm_strlcpyn(pagfile, sizeof pagfile, 2,
- map->map_file, ".pag") >= sizeof pagfile)
+ if (sm_strlcpyn(dirfile, sizeof(dirfile), 2,
+ map->map_file, ".dir") >= sizeof(dirfile) ||
+ sm_strlcpyn(pagfile, sizeof(pagfile), 2,
+ map->map_file, ".pag") >= sizeof(pagfile))
{
errno = 0;
if (!bitset(MF_OPTIONAL, map->map_mflags))
@@ -1632,8 +1682,8 @@ ndbm_map_lookup(map, name, av, statp)
key.dsize = strlen(name);
if (!bitset(MF_NOFOLDCASE, map->map_mflags))
{
- if (key.dsize > sizeof keybuf - 1)
- key.dsize = sizeof keybuf - 1;
+ if (key.dsize > sizeof(keybuf) - 1)
+ key.dsize = sizeof(keybuf) - 1;
memmove(keybuf, key.dptr, key.dsize);
keybuf[key.dsize] = '\0';
makelower(keybuf);
@@ -1729,8 +1779,8 @@ ndbm_map_store(map, lhs, rhs)
key.dptr = lhs;
if (!bitset(MF_NOFOLDCASE, map->map_mflags))
{
- if (key.dsize > sizeof keybuf - 1)
- key.dsize = sizeof keybuf - 1;
+ if (key.dsize > sizeof(keybuf) - 1)
+ key.dsize = sizeof(keybuf) - 1;
memmove(keybuf, key.dptr, key.dsize);
keybuf[key.dsize] = '\0';
makelower(keybuf);
@@ -1814,10 +1864,10 @@ ndbm_map_close(map)
map->map_mflags |= MF_NOFOLDCASE;
- (void) sm_snprintf(buf, sizeof buf, "%010ld", curtime());
+ (void) sm_snprintf(buf, sizeof(buf), "%010ld", curtime());
ndbm_map_store(map, "YP_LAST_MODIFIED", buf);
- (void) gethostname(buf, sizeof buf);
+ (void) gethostname(buf, sizeof(buf));
ndbm_map_store(map, "YP_MASTER_NAME", buf);
map->map_mflags = save_mflags;
@@ -1890,7 +1940,7 @@ bt_map_open(map, mode)
map->map_mname, map->map_file, mode);
# if DB_VERSION_MAJOR < 3
- memset(&btinfo, '\0', sizeof btinfo);
+ memset(&btinfo, '\0', sizeof(btinfo));
# ifdef DB_CACHE_SIZE
btinfo.db_cachesize = DB_CACHE_SIZE;
# endif /* DB_CACHE_SIZE */
@@ -1919,7 +1969,7 @@ hash_map_open(map, mode)
map->map_mname, map->map_file, mode);
# if DB_VERSION_MAJOR < 3
- memset(&hinfo, '\0', sizeof hinfo);
+ memset(&hinfo, '\0', sizeof(hinfo));
# ifdef DB_HASH_NELEM
hinfo.h_nelem = DB_HASH_NELEM;
# endif /* DB_HASH_NELEM */
@@ -1958,7 +2008,7 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
char buf[MAXPATHLEN];
/* do initial file and directory checks */
- if (sm_strlcpy(buf, map->map_file, sizeof buf) >= sizeof buf)
+ if (sm_strlcpy(buf, map->map_file, sizeof(buf)) >= sizeof(buf))
{
errno = 0;
if (!bitset(MF_OPTIONAL, map->map_mflags))
@@ -1969,7 +2019,7 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
i = strlen(buf);
if (i < 3 || strcmp(&buf[i - 3], ".db") != 0)
{
- if (sm_strlcat(buf, ".db", sizeof buf) >= sizeof buf)
+ if (sm_strlcat(buf, ".db", sizeof(buf)) >= sizeof(buf))
{
errno = 0;
if (!bitset(MF_OPTIONAL, map->map_mflags))
@@ -2258,14 +2308,14 @@ db_map_lookup(map, name, av, statp)
char keybuf[MAXNAME + 1];
char buf[MAXPATHLEN];
- memset(&key, '\0', sizeof key);
- memset(&val, '\0', sizeof val);
+ memset(&key, '\0', sizeof(key));
+ memset(&val, '\0', sizeof(val));
if (tTd(38, 20))
sm_dprintf("db_map_lookup(%s, %s)\n",
map->map_mname, name);
- if (sm_strlcpy(buf, map->map_file, sizeof buf) >= sizeof buf)
+ if (sm_strlcpy(buf, map->map_file, sizeof(buf)) >= sizeof(buf))
{
errno = 0;
if (!bitset(MF_OPTIONAL, map->map_mflags))
@@ -2278,8 +2328,8 @@ db_map_lookup(map, name, av, statp)
buf[i - 3] = '\0';
key.size = strlen(name);
- if (key.size > sizeof keybuf - 1)
- key.size = sizeof keybuf - 1;
+ if (key.size > sizeof(keybuf) - 1)
+ key.size = sizeof(keybuf) - 1;
key.data = keybuf;
memmove(keybuf, name, key.size);
keybuf[key.size] = '\0';
@@ -2417,8 +2467,8 @@ db_map_store(map, lhs, rhs)
register DB *db = map->map_db2;
char keybuf[MAXNAME + 1];
- memset(&key, '\0', sizeof key);
- memset(&data, '\0', sizeof data);
+ memset(&key, '\0', sizeof(key));
+ memset(&data, '\0', sizeof(data));
if (tTd(38, 12))
sm_dprintf("db_map_store(%s, %s, %s)\n",
@@ -2428,8 +2478,8 @@ db_map_store(map, lhs, rhs)
key.data = lhs;
if (!bitset(MF_NOFOLDCASE, map->map_mflags))
{
- if (key.size > sizeof keybuf - 1)
- key.size = sizeof keybuf - 1;
+ if (key.size > sizeof(keybuf) - 1)
+ key.size = sizeof(keybuf) - 1;
memmove(keybuf, key.data, key.size);
keybuf[key.size] = '\0';
makelower(keybuf);
@@ -2474,7 +2524,7 @@ db_map_store(map, lhs, rhs)
static int bufsiz = 0;
DBT old;
- memset(&old, '\0', sizeof old);
+ memset(&old, '\0', sizeof(old));
old.data = db_map_lookup(map, key.data,
(char **) NULL, &status);
@@ -2688,8 +2738,8 @@ nis_map_lookup(map, name, av, statp)
map->map_mname, name);
buflen = strlen(name);
- if (buflen > sizeof keybuf - 1)
- buflen = sizeof keybuf - 1;
+ if (buflen > sizeof(keybuf) - 1)
+ buflen = sizeof(keybuf) - 1;
memmove(keybuf, name, buflen);
keybuf[buflen] = '\0';
if (!bitset(MF_NOFOLDCASE, map->map_mflags))
@@ -2757,7 +2807,7 @@ nis_getcanonname(name, hbsize, statp)
if (tTd(38, 20))
sm_dprintf("nis_getcanonname(%s)\n", name);
- if (sm_strlcpy(nbuf, name, sizeof nbuf) >= sizeof nbuf)
+ if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf))
{
*statp = EX_UNAVAILABLE;
return false;
@@ -2798,14 +2848,14 @@ nis_getcanonname(name, hbsize, statp)
sm_free(vp);
return false;
}
- (void) sm_strlcpy(host_record, vp, sizeof host_record);
+ (void) sm_strlcpy(host_record, vp, sizeof(host_record));
sm_free(vp);
if (tTd(38, 44))
sm_dprintf("got record `%s'\n", host_record);
vp = strpbrk(host_record, "#\n");
if (vp != NULL)
*vp = '\0';
- if (!extract_canonname(nbuf, NULL, host_record, cbuf, sizeof cbuf))
+ if (!extract_canonname(nbuf, NULL, host_record, cbuf, sizeof(cbuf)))
{
/* this should not happen, but.... */
*statp = EX_NOHOST;
@@ -2877,12 +2927,12 @@ nisplus_map_open(map, mode)
if (!PARTIAL_NAME(map->map_file))
{
map->map_domain = newstr("");
- (void) sm_strlcpy(qbuf, map->map_file, sizeof qbuf);
+ (void) sm_strlcpy(qbuf, map->map_file, sizeof(qbuf));
}
else
{
/* check to see if this map actually exists */
- (void) sm_strlcpyn(qbuf, sizeof qbuf, 3,
+ (void) sm_strlcpyn(qbuf, sizeof(qbuf), 3,
map->map_file, ".", map->map_domain);
}
@@ -3021,7 +3071,7 @@ nisplus_map_lookup(map, name, av, statp)
** NIS+ parser choke on them.
*/
- skleft = sizeof search_key - 4;
+ skleft = sizeof(search_key) - 4;
skp = search_key;
for (p = name; *p != '\0' && skleft > 0; p++)
{
@@ -3054,11 +3104,11 @@ nisplus_map_lookup(map, name, av, statp)
/* construct the query */
if (PARTIAL_NAME(map->map_file))
- (void) sm_snprintf(qbuf, sizeof qbuf, "[%s=%s],%s.%s",
+ (void) sm_snprintf(qbuf, sizeof(qbuf), "[%s=%s],%s.%s",
map->map_keycolnm, search_key, map->map_file,
map->map_domain);
else
- (void) sm_snprintf(qbuf, sizeof qbuf, "[%s=%s],%s",
+ (void) sm_snprintf(qbuf, sizeof(qbuf), "[%s=%s],%s",
map->map_keycolnm, search_key, map->map_file);
if (tTd(38, 20))
@@ -3135,7 +3185,7 @@ nisplus_getcanonname(name, hbsize, statp)
char nbuf[MAXNAME + 1];
char qbuf[MAXLINE + NIS_MAXNAMELEN];
- if (sm_strlcpy(nbuf, name, sizeof nbuf) >= sizeof nbuf)
+ if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf))
{
*statp = EX_UNAVAILABLE;
return false;
@@ -3146,14 +3196,14 @@ nisplus_getcanonname(name, hbsize, statp)
if (p == NULL)
{
/* single token */
- (void) sm_snprintf(qbuf, sizeof qbuf,
+ (void) sm_snprintf(qbuf, sizeof(qbuf),
"[name=%s],hosts.org_dir", nbuf);
}
else if (p[1] != '\0')
{
/* multi token -- take only first token in nbuf */
*p = '\0';
- (void) sm_snprintf(qbuf, sizeof qbuf,
+ (void) sm_snprintf(qbuf, sizeof(qbuf),
"[name=%s],hosts.org_dir.%s", nbuf, &p[1]);
}
else
@@ -3247,7 +3297,7 @@ nisplus_default_domain()
return default_domain;
p = nis_local_directory();
- (void) sm_strlcpy(default_domain, p, sizeof default_domain);
+ (void) sm_strlcpy(default_domain, p, sizeof(default_domain));
return default_domain;
}
@@ -3318,6 +3368,15 @@ ldapmap_open(map, mode)
if (tTd(38, 2))
sm_dprintf("ldapmap_open(%s, %d): ", map->map_mname, mode);
+#if defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && \
+ HASLDAPGETALIASBYNAME
+ if (VendorCode == VENDOR_SUN &&
+ strcmp(map->map_mname, "aliases.ldap") == 0)
+ {
+ return true;
+ }
+#endif /* defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && ... */
+
mode &= O_ACCMODE;
/* sendmail doesn't have the ability to write to LDAP (yet) */
@@ -3471,6 +3530,9 @@ sunet_id_hash(str)
*p_last = '\0';
return str;
}
+# define SM_CONVERT_ID(str) sunet_id_hash(str)
+# else /* SUNET_ID */
+# define SM_CONVERT_ID(str) makelower(str)
# endif /* SUNET_ID */
/*
@@ -3485,6 +3547,7 @@ ldapmap_lookup(map, name, av, statp)
int *statp;
{
int flags;
+ int i;
int plen = 0;
int psize = 0;
int msgid;
@@ -3493,39 +3556,122 @@ ldapmap_lookup(map, name, av, statp)
char *result = NULL;
SM_RPOOL_T *rpool;
SM_LDAP_STRUCT *lmap = NULL;
+ char *argv[SM_LDAP_ARGS];
char keybuf[MAXKEY];
+#if SM_LDAP_ARGS != MAX_MAP_ARGS
+# ERROR _SM_LDAP_ARGS must be the same as _MAX_MAP_ARGS
+#endif /* SM_LDAP_ARGS != MAX_MAP_ARGS */
- if (tTd(38, 20))
- sm_dprintf("ldapmap_lookup(%s, %s)\n", map->map_mname, name);
+#if defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && \
+ HASLDAPGETALIASBYNAME
+ if (VendorCode == VENDOR_SUN &&
+ strcmp(map->map_mname, "aliases.ldap") == 0)
+ {
+ char answer[MAXNAME + 1];
+ int rc;
+
+ rc = __getldapaliasbyname(name, answer, sizeof(answer));
+ if (rc != 0)
+ {
+ if (tTd(38, 20))
+ sm_dprintf("getldapaliasbyname(%.100s) failed, errno=%d\n",
+ name, errno);
+ *statp = EX_NOTFOUND;
+ return NULL;
+ }
+ *statp = EX_OK;
+ if (tTd(38, 20))
+ sm_dprintf("getldapaliasbyname(%.100s) => %s\n", name,
+ answer);
+ if (bitset(MF_MATCHONLY, map->map_mflags))
+ result = map_rewrite(map, name, strlen(name), NULL);
+ else
+ result = map_rewrite(map, answer, strlen(answer), av);
+ return result;
+ }
+#endif /* defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && ... */
/* Get ldap struct pointer from map */
lmap = (SM_LDAP_STRUCT *) map->map_db1;
sm_ldap_setopts(lmap->ldap_ld, lmap);
- (void) sm_strlcpy(keybuf, name, sizeof keybuf);
+ if (lmap->ldap_multi_args)
+ {
+ SM_REQUIRE(av != NULL);
+ memset(argv, '\0', sizeof(argv));
+ for (i = 0; i < SM_LDAP_ARGS && av[i] != NULL; i++)
+ {
+ argv[i] = sm_strdup(av[i]);
+ if (argv[i] == NULL)
+ {
+ int save_errno, j;
+
+ save_errno = errno;
+ for (j = 0; j < i && argv[j] != NULL; j++)
+ SM_FREE(argv[j]);
+ *statp = EX_TEMPFAIL;
+ errno = save_errno;
+ return NULL;
+ }
- if (!bitset(MF_NOFOLDCASE, map->map_mflags))
+ if (!bitset(MF_NOFOLDCASE, map->map_mflags))
+ SM_CONVERT_ID(av[i]);
+ }
+ }
+ else
{
-# ifdef SUNET_ID
- sunet_id_hash(keybuf);
-# else /* SUNET_ID */
- makelower(keybuf);
-# endif /* SUNET_ID */
+ (void) sm_strlcpy(keybuf, name, sizeof(keybuf));
+
+ if (!bitset(MF_NOFOLDCASE, map->map_mflags))
+ SM_CONVERT_ID(keybuf);
+ }
+
+ if (tTd(38, 20))
+ {
+ if (lmap->ldap_multi_args)
+ {
+ sm_dprintf("ldapmap_lookup(%s, argv)\n",
+ map->map_mname);
+ for (i = 0; i < SM_LDAP_ARGS; i++)
+ {
+ sm_dprintf(" argv[%d] = %s\n", i,
+ argv[i] == NULL ? "NULL" : argv[i]);
+ }
+ }
+ else
+ {
+ sm_dprintf("ldapmap_lookup(%s, %s)\n",
+ map->map_mname, name);
+ }
}
- msgid = sm_ldap_search(lmap, keybuf);
- if (msgid == -1)
+ if (lmap->ldap_multi_args)
+ {
+ msgid = sm_ldap_search_m(lmap, argv);
+
+ /* free the argv array and its content, no longer needed */
+ for (i = 0; i < SM_LDAP_ARGS && argv[i] != NULL; i++)
+ SM_FREE(argv[i]);
+ }
+ else
+ msgid = sm_ldap_search(lmap, keybuf);
+ if (msgid == SM_LDAP_ERR)
{
errno = sm_ldap_geterrno(lmap->ldap_ld) + E_LDAPBASE;
save_errno = errno;
if (!bitset(MF_OPTIONAL, map->map_mflags))
{
+ /*
+ ** Do not include keybuf as this error may be shown
+ ** to outsiders.
+ */
+
if (bitset(MF_NODEFER, map->map_mflags))
- syserr("Error in ldap_search using %s in map %s",
- keybuf, map->map_mname);
+ syserr("Error in ldap_search in map %s",
+ map->map_mname);
else
- syserr("451 4.3.5 Error in ldap_search using %s in map %s",
- keybuf, map->map_mname);
+ syserr("451 4.3.5 Error in ldap_search in map %s",
+ map->map_mname);
}
*statp = EX_TEMPFAIL;
switch (save_errno - E_LDAPBASE)
@@ -3542,6 +3688,19 @@ ldapmap_lookup(map, name, av, statp)
errno = save_errno;
return NULL;
}
+#if SM_LDAP_ERROR_ON_MISSING_ARGS
+ else if (msgid == SM_LDAP_ERR_ARG_MISS)
+ {
+ if (bitset(MF_NODEFER, map->map_mflags))
+ syserr("Error in ldap_search in map %s, too few arguments",
+ map->map_mname);
+ else
+ syserr("554 5.3.5 Error in ldap_search in map %s, too few arguments",
+ map->map_mname);
+ *statp = EX_CONFIG;
+ return NULL;
+ }
+#endif /* SM_LDAP_ERROR_ON_MISSING_ARGS */
*statp = EX_NOTFOUND;
vp = NULL;
@@ -3722,7 +3881,7 @@ ldapmap_parseargs(map, args)
if (lmap == NULL || lmap != LDAPDefaults)
{
/* We need to alloc an SM_LDAP_STRUCT struct */
- lmap = (SM_LDAP_STRUCT *) xalloc(sizeof *lmap);
+ lmap = (SM_LDAP_STRUCT *) xalloc(sizeof(*lmap));
if (LDAPDefaults == NULL)
sm_ldap_clear(lmap);
else
@@ -3746,11 +3905,11 @@ ldapmap_parseargs(map, args)
char lcbuf[MAXLINE];
/* Get $j */
- expand("\201j", jbuf, sizeof jbuf, &BlankEnvelope);
+ expand("\201j", jbuf, sizeof(jbuf), &BlankEnvelope);
if (jbuf[0] == '\0')
{
(void) sm_strlcpy(jbuf, "localhost",
- sizeof jbuf);
+ sizeof(jbuf));
}
lc = macvalue(macid("{sendmailMTACluster}"), CurEnv);
@@ -3758,14 +3917,14 @@ ldapmap_parseargs(map, args)
lc = "";
else
{
- expand(lc, lcbuf, sizeof lcbuf, CurEnv);
+ expand(lc, lcbuf, sizeof(lcbuf), CurEnv);
lc = lcbuf;
}
- n = sm_snprintf(ldapfilt, sizeof ldapfilt,
+ n = sm_snprintf(ldapfilt, sizeof(ldapfilt),
"(&(objectClass=sendmailMTAAliasObject)(sendmailMTAAliasGrouping=aliases)(|(sendmailMTACluster=%s)(sendmailMTAHost=%s))(sendmailMTAKey=%%0))",
lc, jbuf);
- if (n >= sizeof ldapfilt)
+ if (n >= sizeof(ldapfilt))
{
syserr("%s: Default LDAP string too long",
map->map_mname);
@@ -4138,6 +4297,10 @@ ldapmap_parseargs(map, args)
# endif /* LDAP_VERSION_MIN */
break;
+ case 'K':
+ lmap->ldap_multi_args = true;
+ break;
+
default:
syserr("Illegal option %c map %s", *p, map->map_mname);
break;
@@ -4228,7 +4391,7 @@ ldapmap_parseargs(map, args)
ldapmap_dequote(lmap->ldap_secret));
return false;
}
- lmap->ldap_secret = sfgets(m_tmp, sizeof m_tmp,
+ lmap->ldap_secret = sfgets(m_tmp, sizeof(m_tmp),
sfd, TimeOuts.to_fileopen,
"ldapmap_parseargs");
(void) sm_io_close(sfd, SM_TIME_DEFAULT);
@@ -4257,7 +4420,7 @@ ldapmap_parseargs(map, args)
** stashed
*/
- (void) sm_snprintf(m_tmp, sizeof m_tmp,
+ (void) sm_snprintf(m_tmp, sizeof(m_tmp),
"KRBTKFILE=%s",
ldapmap_dequote(lmap->ldap_secret));
lmap->ldap_secret = m_tmp;
@@ -4481,10 +4644,10 @@ ldapmap_set_defaults(spec)
/* Allocate and set the default values */
if (LDAPDefaults == NULL)
- LDAPDefaults = (SM_LDAP_STRUCT *) xalloc(sizeof *LDAPDefaults);
+ LDAPDefaults = (SM_LDAP_STRUCT *) xalloc(sizeof(*LDAPDefaults));
sm_ldap_clear(LDAPDefaults);
- memset(&map, '\0', sizeof map);
+ memset(&map, '\0', sizeof(map));
/* look up the class */
class = stab("ldap", ST_MAPCLASS, ST_FIND);
@@ -4535,7 +4698,7 @@ ldapmap_set_defaults(spec)
/*
** Support for the CCSO Nameserver (ph/qi).
** This code is intended to replace the so-called "ph mailer".
-** Contributed by Mark D. Roth <roth@uiuc.edu>. Contact him for support.
+** Contributed by Mark D. Roth. Contact him for support.
*/
/* what version of the ph map code we're running */
@@ -4572,11 +4735,11 @@ ph_map_parseargs(map, args)
PH_MAP_STRUCT *pmap = NULL;
/* initialize version string */
- (void) sm_snprintf(phmap_id, sizeof phmap_id,
+ (void) sm_snprintf(phmap_id, sizeof(phmap_id),
"sendmail-%s phmap-20010529 libphclient-%s",
Version, libphclient_version);
- pmap = (PH_MAP_STRUCT *) xalloc(sizeof *pmap);
+ pmap = (PH_MAP_STRUCT *) xalloc(sizeof(*pmap));
/* defaults */
pmap->ph_servers = NULL;
@@ -4961,6 +5124,7 @@ ph_map_lookup(map, key, args, pstat)
return NULL;
}
#endif /* PH_MAP */
+
/*
** syslog map
*/
@@ -5099,6 +5263,99 @@ syslog_map_lookup(map, string, args, statp)
return "";
}
+#if _FFR_DPRINTF_MAP
+/*
+** dprintf map
+*/
+
+#define map_dbg_level map_lockfd /* overload field */
+
+/*
+** DPRINTF_MAP_PARSEARGS -- check for priority level to dprintf messages.
+*/
+
+bool
+dprintf_map_parseargs(map, args)
+ MAP *map;
+ char *args;
+{
+ char *p = args;
+ char *dbg_level = NULL;
+
+ /* there is no check whether there is really an argument */
+ while (*p != '\0')
+ {
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (*p != '-')
+ break;
+ ++p;
+ if (*p == 'D')
+ {
+ map->map_mflags |= MF_DEFER;
+ ++p;
+ }
+ else if (*p == 'S')
+ {
+ map->map_spacesub = *++p;
+ if (*p != '\0')
+ p++;
+ }
+ else if (*p == 'd')
+ {
+ while (*++p != '\0' && isascii(*p) && isspace(*p))
+ continue;
+ if (*p == '\0')
+ break;
+ dbg_level = p;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ if (*p != '\0')
+ *p++ = '\0';
+ }
+ else
+ {
+ syserr("Illegal option %c map dprintf", *p);
+ ++p;
+ }
+ }
+
+ if (dbg_level == NULL)
+ map->map_dbg_level = 0;
+ else
+ {
+ if (!(isascii(*dbg_level) && isdigit(*dbg_level)))
+ {
+ syserr("dprintf map \"%s\", file %s: -d should specify a number, not %s",
+ map->map_mname, map->map_file,
+ dbg_level);
+ return false;
+ }
+ map->map_dbg_level = atoi(dbg_level);
+ }
+ return true;
+}
+
+/*
+** DPRINTF_MAP_LOOKUP -- rewrite and print message. Always return empty string
+*/
+
+char *
+dprintf_map_lookup(map, string, args, statp)
+ MAP *map;
+ char *string;
+ char **args;
+ int *statp;
+{
+ char *ptr = map_rewrite(map, string, strlen(string), args);
+
+ if (ptr != NULL && tTd(85, map->map_dbg_level))
+ sm_dprintf("%s\n", ptr);
+ *statp = EX_OK;
+ return "";
+}
+#endif /* _FFR_DPRINTF_MAP */
+
/*
** HESIOD Modules
*/
@@ -5166,12 +5423,12 @@ hes_map_lookup(map, name, av, statp)
char nbuf[MAXNAME];
nl = strlen(name);
- if (nl < sizeof nbuf - 1)
+ if (nl < sizeof(nbuf) - 1)
np = nbuf;
else
np = xalloc(strlen(name) + 2);
np[0] = '\\';
- (void) sm_strlcpy(&np[1], name, (sizeof nbuf) - 1);
+ (void) sm_strlcpy(&np[1], name, (sizeof(nbuf)) - 1);
# ifdef HESIOD_INIT
hp = hesiod_resolve(HesiodContext, np, map->map_file);
# else /* HESIOD_INIT */
@@ -5352,7 +5609,7 @@ ni_getcanonname(name, hbsize, statp)
if (tTd(38, 20))
sm_dprintf("ni_getcanonname(%s)\n", name);
- if (sm_strlcpy(nbuf, name, sizeof nbuf) >= sizeof nbuf)
+ if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf))
{
*statp = EX_UNAVAILABLE;
return false;
@@ -5527,8 +5784,8 @@ text_map_lookup(map, name, av, statp)
sm_dprintf("text_map_lookup(%s, %s)\n", map->map_mname, name);
buflen = strlen(name);
- if (buflen > sizeof search_key - 1)
- buflen = sizeof search_key - 1; /* XXX just cut if off? */
+ if (buflen > sizeof(search_key) - 1)
+ buflen = sizeof(search_key) - 1; /* XXX just cut if off? */
memmove(search_key, name, buflen);
search_key[buflen] = '\0';
if (!bitset(MF_NOFOLDCASE, map->map_mflags))
@@ -5544,7 +5801,7 @@ text_map_lookup(map, name, av, statp)
key_idx = map->map_keycolno;
delim = map->map_coldelim;
while (sm_io_fgets(f, SM_TIME_DEFAULT,
- linebuf, sizeof linebuf) != NULL)
+ linebuf, sizeof(linebuf)) != NULL)
{
char *p;
@@ -5554,7 +5811,7 @@ text_map_lookup(map, name, av, statp)
p = strchr(linebuf, '\n');
if (p != NULL)
*p = '\0';
- p = get_column(linebuf, key_idx, delim, buf, sizeof buf);
+ p = get_column(linebuf, key_idx, delim, buf, sizeof(buf));
if (p != NULL && sm_strcasecmp(search_key, p) == 0)
{
found_it = true;
@@ -5567,7 +5824,7 @@ text_map_lookup(map, name, av, statp)
*statp = EX_NOTFOUND;
return NULL;
}
- vp = get_column(linebuf, map->map_valcolno, delim, buf, sizeof buf);
+ vp = get_column(linebuf, map->map_valcolno, delim, buf, sizeof(buf));
if (vp == NULL)
{
*statp = EX_NOTFOUND;
@@ -5601,7 +5858,7 @@ text_getcanonname(name, hbsize, statp)
if (tTd(38, 20))
sm_dprintf("text_getcanonname(%s)\n", name);
- if (sm_strlcpy(nbuf, name, sizeof nbuf) >= sizeof nbuf)
+ if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf))
{
*statp = EX_UNAVAILABLE;
return false;
@@ -5618,7 +5875,7 @@ text_getcanonname(name, hbsize, statp)
found = false;
while (!found &&
sm_io_fgets(f, SM_TIME_DEFAULT,
- linebuf, sizeof linebuf) != NULL)
+ linebuf, sizeof(linebuf)) != NULL)
{
char *p = strpbrk(linebuf, "#\n");
@@ -5626,7 +5883,7 @@ text_getcanonname(name, hbsize, statp)
*p = '\0';
if (linebuf[0] != '\0')
found = extract_canonname(nbuf, dot, linebuf,
- cbuf, sizeof cbuf);
+ cbuf, sizeof(cbuf));
}
(void) sm_io_close(f, SM_TIME_DEFAULT);
if (!found)
@@ -5970,13 +6227,13 @@ user_map_lookup(map, key, av, statp)
break;
case 3:
- (void) sm_snprintf(buf, sizeof buf, "%d",
+ (void) sm_snprintf(buf, sizeof(buf), "%d",
(int) user.mbdb_uid);
rwval = buf;
break;
case 4:
- (void) sm_snprintf(buf, sizeof buf, "%d",
+ (void) sm_snprintf(buf, sizeof(buf), "%d",
(int) user.mbdb_gid);
rwval = buf;
break;
@@ -6033,7 +6290,7 @@ prog_map_lookup(map, name, av, statp)
argv[i++] = map->map_file;
if (map->map_rebuild != NULL)
{
- (void) sm_strlcpy(buf, map->map_rebuild, sizeof buf);
+ (void) sm_strlcpy(buf, map->map_rebuild, sizeof(buf));
for (p = strtok(buf, " \t"); p != NULL; p = strtok(NULL, " \t"))
{
if (i >= MAXPV - 1)
@@ -6064,7 +6321,7 @@ prog_map_lookup(map, name, av, statp)
*statp = EX_OSFILE;
return NULL;
}
- i = read(fd, buf, sizeof buf - 1);
+ i = read(fd, buf, sizeof(buf) - 1);
if (i < 0)
{
syserr("prog_map_lookup(%s): read error %s",
@@ -6092,7 +6349,7 @@ prog_map_lookup(map, name, av, statp)
rval = map_rewrite(map, buf, strlen(buf), av);
/* now flush any additional output */
- while ((i = read(fd, buf, sizeof buf)) > 0)
+ while ((i = read(fd, buf, sizeof(buf))) > 0)
continue;
}
@@ -6239,7 +6496,7 @@ switch_map_open(map, mode)
if (maptype[mapno] == NULL)
continue;
- (void) sm_strlcpyn(nbuf, sizeof nbuf, 3,
+ (void) sm_strlcpyn(nbuf, sizeof(nbuf), 3,
map->map_mname, ".", maptype[mapno]);
s = stab(nbuf, ST_MAP, ST_FIND);
if (s == NULL)
@@ -6561,7 +6818,7 @@ regex_map_init(map, ap)
pflags = REG_ICASE | REG_EXTENDED | REG_NOSUB;
p = ap;
- map_p = (struct regex_map *) xnalloc(sizeof *map_p);
+ map_p = (struct regex_map *) xnalloc(sizeof(*map_p));
map_p->regex_pattern_buf = (regex_t *)xnalloc(sizeof(regex_t));
for (;;)
@@ -6629,7 +6886,7 @@ regex_map_init(map, ap)
char errbuf[ERRBUF_SIZE];
(void) regerror(regerr, map_p->regex_pattern_buf,
- errbuf, sizeof errbuf);
+ errbuf, sizeof(errbuf));
syserr("pattern-compile-error: %s", errbuf);
sm_free(map_p->regex_pattern_buf); /* XXX */
sm_free(map_p); /* XXX */
@@ -6884,10 +7141,10 @@ ns_map_t_find(mapname)
/* if we are looking at a NULL ns_map_list_t, then create a new one */
if (ns_map == NULL)
{
- ns_map = (ns_map_list_t *) xalloc(sizeof *ns_map);
+ ns_map = (ns_map_list_t *) xalloc(sizeof(*ns_map));
ns_map->mapname = newstr(mapname);
- ns_map->map = (ns_map_t *) xalloc(sizeof *ns_map->map);
- memset(ns_map->map, '\0', sizeof *ns_map->map);
+ ns_map->map = (ns_map_t *) xalloc(sizeof(*ns_map->map));
+ memset(ns_map->map, '\0', sizeof(*ns_map->map));
ns_map->next = ns_maps;
ns_maps = ns_map;
}
@@ -6911,8 +7168,8 @@ nsd_map_lookup(map, name, av, statp)
sm_dprintf("nsd_map_lookup(%s, %s)\n", map->map_mname, name);
buflen = strlen(name);
- if (buflen > sizeof keybuf - 1)
- buflen = sizeof keybuf - 1; /* XXX simply cut off? */
+ if (buflen > sizeof(keybuf) - 1)
+ buflen = sizeof(keybuf) - 1; /* XXX simply cut off? */
memmove(keybuf, name, buflen);
keybuf[buflen] = '\0';
if (!bitset(MF_NOFOLDCASE, map->map_mflags))
@@ -6927,7 +7184,7 @@ nsd_map_lookup(map, name, av, statp)
return NULL;
}
r = ns_lookup(ns_map, NULL, map->map_file, keybuf, NULL,
- buf, sizeof buf);
+ buf, sizeof(buf));
if (r == NS_UNAVAIL || r == NS_TRYAGAIN)
{
*statp = EX_TEMPFAIL;
@@ -7038,6 +7295,13 @@ arith_map_lookup(map, name, av, statp)
boolres = true;
break;
+ case 'r':
+ r = v[1] - v[0] + 1;
+ if (r <= 0)
+ return NULL;
+ r = get_random() % r + v[0];
+ break;
+
default:
/* XXX */
*statp = EX_CONFIG;
@@ -7048,10 +7312,10 @@ arith_map_lookup(map, name, av, statp)
return NULL;
}
if (boolres)
- (void) sm_snprintf(result, sizeof result,
+ (void) sm_snprintf(result, sizeof(result),
res ? "TRUE" : "FALSE");
else
- (void) sm_snprintf(result, sizeof result, "%ld", r);
+ (void) sm_snprintf(result, sizeof(result), "%ld", r);
return result;
}
*statp = EX_CONFIG;
@@ -7129,7 +7393,7 @@ socket_map_open(map, mode)
/* XXX It should be put in a library... */
/* protocol:filename or protocol:port@host */
- memset(&addr, '\0', sizeof addr);
+ memset(&addr, '\0', sizeof(addr));
p = map->map_file;
colon = strchr(p, ':');
if (colon != NULL)
@@ -7213,7 +7477,7 @@ socket_map_open(map, mode)
long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK;
at = colon;
- if (strlen(colon) >= sizeof addr.sunix.sun_path)
+ if (strlen(colon) >= sizeof(addr.sunix.sun_path))
{
syserr("socket map \"%s\": local socket name %s too long",
map->map_mname, colon);
@@ -7231,8 +7495,8 @@ socket_map_open(map, mode)
}
(void) sm_strlcpy(addr.sunix.sun_path, colon,
- sizeof addr.sunix.sun_path);
- addrlen = sizeof (struct sockaddr_un);
+ sizeof(addr.sunix.sun_path));
+ addrlen = sizeof(struct sockaddr_un);
}
else
# endif /* NETUNIX */
@@ -7305,7 +7569,7 @@ socket_map_open(map, mode)
}
# endif /* NETINET */
# if NETINET6
- (void) memset(&hid6, '\0', sizeof hid6);
+ (void) memset(&hid6, '\0', sizeof(hid6));
if (addr.sa.sa_family == AF_INET6 &&
anynet_pton(AF_INET6, &at[1],
&hid6.sin6_addr) == 1)
@@ -7347,7 +7611,7 @@ socket_map_open(map, mode)
memmove(&addr.sin.sin_addr,
hp->h_addr, INADDRSZ);
addr.sin.sin_port = port;
- addrlen = sizeof (struct sockaddr_in);
+ addrlen = sizeof(struct sockaddr_in);
addrno = 1;
break;
# endif /* NETINET */
@@ -7357,7 +7621,7 @@ socket_map_open(map, mode)
memmove(&addr.sin6.sin6_addr,
hp->h_addr, IN6ADDRSZ);
addr.sin6.sin6_port = port;
- addrlen = sizeof (struct sockaddr_in6);
+ addrlen = sizeof(struct sockaddr_in6);
addrno = 1;
break;
# endif /* NETINET6 */
@@ -7584,8 +7848,8 @@ socket_map_lookup(map, name, av, statp)
if (!bitset(MF_NOFOLDCASE, map->map_mflags))
{
nettolen = strlen(name);
- if (nettolen > sizeof keybuf - 1)
- nettolen = sizeof keybuf - 1;
+ if (nettolen > sizeof(keybuf) - 1)
+ nettolen = sizeof(keybuf) - 1;
memmove(keybuf, name, nettolen);
keybuf[nettolen] = '\0';
makelower(keybuf);
diff --git a/contrib/sendmail/src/map.h b/contrib/sendmail/src/map.h
new file mode 100644
index 0000000..dda9999
--- /dev/null
+++ b/contrib/sendmail/src/map.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2006 Sendmail, Inc. and its suppliers.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ *
+ * $Id: map.h,v 8.3 2006/12/19 19:49:51 ca Exp $
+ */
+
+#ifndef _MAP_H
+# define _MAP_H 1
+
+extern char *arith_map_lookup __P((MAP *, char *, char **, int *));
+
+extern char *bestmx_map_lookup __P((MAP *, char *, char **, int *));
+
+extern char *bogus_map_lookup __P((MAP *, char *, char **, int *));
+
+extern bool bt_map_open __P((MAP *, int));
+
+extern char *db_map_lookup __P((MAP *, char *, char **, int *));
+
+extern void db_map_store __P((MAP *, char *, char *));
+extern void db_map_close __P((MAP *));
+
+extern bool dequote_init __P((MAP *, char *));
+extern char *dequote_map __P((MAP *, char *, char **, int *));
+
+extern bool dns_map_open __P((MAP *, int));
+extern bool dns_map_parseargs __P((MAP *, char *));
+extern char *dns_map_lookup __P((MAP *, char *, char **, int *));
+
+extern bool dprintf_map_parseargs __P((MAP *, char *));
+extern char *dprintf_map_lookup __P((MAP *, char *, char **, int *));
+
+extern bool hash_map_open __P((MAP *, int));
+
+extern bool host_map_init __P((MAP *, char *));
+extern char *host_map_lookup __P((MAP *, char *, char **, int *));
+
+extern char *impl_map_lookup __P((MAP *, char *, char **, int *));
+extern void impl_map_store __P((MAP *, char *, char *));
+extern bool impl_map_open __P((MAP *, int));
+extern void impl_map_close __P((MAP *));
+
+extern char *macro_map_lookup __P((MAP *, char *, char **, int *));
+
+extern bool map_parseargs __P((MAP *, char *));
+
+extern bool nis_map_open __P((MAP *, int));
+extern char *nis_map_lookup __P((MAP *, char *, char **, int *));
+
+extern bool null_map_open __P((MAP *, int));
+extern void null_map_close __P((MAP *));
+extern char *null_map_lookup __P((MAP *, char *, char **, int *));
+extern void null_map_store __P((MAP *, char *, char *));
+
+extern char *prog_map_lookup __P((MAP *, char *, char **, int *));
+
+extern bool regex_map_init __P((MAP *, char *));
+extern char *regex_map_lookup __P((MAP *, char *, char **, int *));
+
+extern char *seq_map_lookup __P((MAP *, char *, char **, int *));
+extern void seq_map_store __P((MAP *, char *, char *));
+extern bool seq_map_parse __P((MAP *, char *));
+
+extern char *stab_map_lookup __P((MAP *, char *, char **, int *));
+extern void stab_map_store __P((MAP *, char *, char *));
+extern bool stab_map_open __P((MAP *, int));
+
+extern bool switch_map_open __P((MAP *, int));
+
+extern bool syslog_map_parseargs __P((MAP *, char *));
+extern char *syslog_map_lookup __P((MAP *, char *, char **, int *));
+
+extern bool text_map_open __P((MAP *, int));
+extern char *text_map_lookup __P((MAP *, char *, char **, int *));
+
+extern char *udb_map_lookup __P((MAP *, char *, char **, int *));
+
+extern bool user_map_open __P((MAP *, int));
+extern char *user_map_lookup __P((MAP *, char *, char **, int *));
+
+#endif /* ! _MAP_H */
diff --git a/contrib/sendmail/src/milter.c b/contrib/sendmail/src/milter.c
index 19fd59d..67d5eae 100644
--- a/contrib/sendmail/src/milter.c
+++ b/contrib/sendmail/src/milter.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2005 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1999-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -10,9 +10,10 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: milter.c,v 8.232 2005/08/05 21:49:04 ca Exp $")
+SM_RCSID("@(#)$Id: milter.c,v 8.267 2007/02/27 22:21:12 ca Exp $")
#if MILTER
+# include <sm/sendmail.h>
# include <libmilter/mfapi.h>
# include <libmilter/mfdef.h>
@@ -22,9 +23,9 @@ SM_RCSID("@(#)$Id: milter.c,v 8.232 2005/08/05 21:49:04 ca Exp $")
# if NETINET || NETINET6
# include <arpa/inet.h>
-# if _FFR_MILTER_NAGLE
+# if MILTER_NO_NAGLE
# include <netinet/tcp.h>
-# endif /* _FFR_MILTER_NAGLE */
+# endif /* MILTER_NO_NAGLE */
# endif /* NETINET || NETINET6 */
# include <sm/fdset.h>
@@ -33,6 +34,49 @@ static void milter_connect_timeout __P((int));
static void milter_error __P((struct milter *, ENVELOPE *));
static int milter_open __P((struct milter *, bool, ENVELOPE *));
static void milter_parse_timeouts __P((char *, struct milter *));
+static char *milter_sysread __P((struct milter *, char *, ssize_t, time_t,
+ ENVELOPE *, const char *));
+static char *milter_read __P((struct milter *, char *, ssize_t *, time_t,
+ ENVELOPE *, const char *));
+static char *milter_write __P((struct milter *, int, char *, ssize_t,
+ time_t, ENVELOPE *, const char *));
+static char *milter_send_command __P((struct milter *, int, void *,
+ ssize_t, ENVELOPE *, char *, const char *));
+static char *milter_command __P((int, void *, ssize_t, char **,
+ ENVELOPE *, char *, const char *, bool));
+static char *milter_body __P((struct milter *, ENVELOPE *, char *));
+static int milter_reopen_df __P((ENVELOPE *));
+static int milter_reset_df __P((ENVELOPE *));
+static void milter_quit_filter __P((struct milter *, ENVELOPE *));
+static void milter_abort_filter __P((struct milter *, ENVELOPE *));
+static void milter_send_macros __P((struct milter *, char **, int,
+ ENVELOPE *));
+static int milter_negotiate __P((struct milter *, ENVELOPE *));
+static void milter_per_connection_check __P((ENVELOPE *));
+static char *milter_headers __P((struct milter *, ENVELOPE *, char *));
+static void milter_addheader __P((struct milter *, char *, ssize_t,
+ ENVELOPE *));
+static void milter_insheader __P((struct milter *, char *, ssize_t,
+ ENVELOPE *));
+static void milter_changeheader __P((struct milter *, char *, ssize_t,
+ ENVELOPE *));
+static void milter_chgfrom __P((char *, ssize_t, ENVELOPE *));
+static void milter_addrcpt __P((char *, ssize_t, ENVELOPE *));
+static void milter_addrcpt_par __P((char *, ssize_t, ENVELOPE *));
+static void milter_delrcpt __P((char *, ssize_t, ENVELOPE *));
+static int milter_replbody __P((char *, ssize_t, bool, ENVELOPE *));
+static int milter_set_macros __P((char *, char **, char *, int));
+
+
+/* milter states */
+# define SMFS_CLOSED 'C' /* closed for all further actions */
+# define SMFS_OPEN 'O' /* connected to remote milter filter */
+# define SMFS_INMSG 'M' /* currently servicing a message */
+# define SMFS_DONE 'D' /* done with current message */
+# define SMFS_CLOSABLE 'Q' /* done with current connection */
+# define SMFS_ERROR 'E' /* error state */
+# define SMFS_READY 'R' /* ready for action */
+# define SMFS_SKIP 'S' /* skip body */
static char *MilterConnectMacros[MAXFILTERMACROS + 1];
static char *MilterHeloMacros[MAXFILTERMACROS + 1];
@@ -40,6 +84,7 @@ static char *MilterEnvFromMacros[MAXFILTERMACROS + 1];
static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1];
static char *MilterDataMacros[MAXFILTERMACROS + 1];
static char *MilterEOMMacros[MAXFILTERMACROS + 1];
+static char *MilterEOHMacros[MAXFILTERMACROS + 1];
static size_t MilterMaxDataSize = MILTER_MAX_DATA_SIZE;
# define MILTER_CHECK_DONE_MSG() \
@@ -146,7 +191,7 @@ static size_t MilterMaxDataSize = MILTER_MAX_DATA_SIZE;
** Assumes 'm' is a milter structure for the current socket.
*/
-# define MILTER_TIMEOUT(routine, secs, write, started) \
+# define MILTER_TIMEOUT(routine, secs, write, started, function) \
{ \
int ret; \
int save_errno; \
@@ -184,14 +229,14 @@ static size_t MilterMaxDataSize = MILTER_MAX_DATA_SIZE;
{ \
case 0: \
if (tTd(64, 5)) \
- sm_dprintf("milter_%s(%s): timeout\n", (routine), \
- m->mf_name); \
+ sm_dprintf("milter_%s(%s): timeout, where=%s\n", \
+ (routine), m->mf_name, (function)); \
if (MilterLogLevel > 0) \
sm_syslog(LOG_ERR, e->e_id, \
- "Milter (%s): %s %s %s %s", \
- m->mf_name, "timeout", \
+ "Milter (%s): timeout %s data %s, where=%s", \
+ m->mf_name, \
started ? "during" : "before", \
- "data", (routine)); \
+ (routine), (function)); \
milter_error(m, e); \
return NULL; \
\
@@ -246,12 +291,13 @@ static size_t MilterMaxDataSize = MILTER_MAX_DATA_SIZE;
*/
static char *
-milter_sysread(m, buf, sz, to, e)
+milter_sysread(m, buf, sz, to, e, where)
struct milter *m;
char *buf;
ssize_t sz;
time_t to;
ENVELOPE *e;
+ const char *where;
{
time_t readstart = 0;
ssize_t len, curl;
@@ -272,22 +318,22 @@ milter_sysread(m, buf, sz, to, e)
if (now - readstart >= to)
{
if (tTd(64, 5))
- sm_dprintf("milter_read (%s): %s %s %s",
- m->mf_name, "timeout",
+ sm_dprintf("milter_sys_read (%s): timeout %s data read in %s",
+ m->mf_name,
started ? "during" : "before",
- "data read");
+ where);
if (MilterLogLevel > 0)
sm_syslog(LOG_ERR, e->e_id,
- "Milter (%s): %s %s %s",
- m->mf_name, "timeout",
+ "Milter (%s): timeout %s data read in %s",
+ m->mf_name,
started ? "during" : "before",
- "data read");
+ where);
milter_error(m, e);
return NULL;
}
to -= now - readstart;
readstart = now;
- MILTER_TIMEOUT("read", to, false, started);
+ MILTER_TIMEOUT("read", to, false, started, where);
}
len = read(m->mf_sock, buf + curl, sz - curl);
@@ -297,7 +343,7 @@ milter_sysread(m, buf, sz, to, e)
int save_errno = errno;
if (tTd(64, 5))
- sm_dprintf("milter_read(%s): read returned %ld: %s\n",
+ sm_dprintf("milter_sys_read(%s): read returned %ld: %s\n",
m->mf_name, (long) len,
sm_errstring(save_errno));
if (MilterLogLevel > 0)
@@ -319,11 +365,11 @@ milter_sysread(m, buf, sz, to, e)
if (curl != sz)
{
if (tTd(64, 5))
- sm_dprintf("milter_read(%s): cmd read returned %ld, expecting %ld\n",
+ sm_dprintf("milter_sys_read(%s): cmd read returned %ld, expecting %ld\n",
m->mf_name, (long) curl, (long) sz);
if (MilterLogLevel > 0)
sm_syslog(LOG_ERR, e->e_id,
- "milter_read(%s): cmd read returned %ld, expecting %ld",
+ "milter_sys_read(%s): cmd read returned %ld, expecting %ld",
m->mf_name, (long) curl, (long) sz);
milter_error(m, e);
return NULL;
@@ -332,21 +378,20 @@ milter_sysread(m, buf, sz, to, e)
}
static char *
-milter_read(m, cmd, rlen, to, e)
+milter_read(m, cmd, rlen, to, e, where)
struct milter *m;
char *cmd;
ssize_t *rlen;
time_t to;
ENVELOPE *e;
+ const char *where;
{
time_t readstart = 0;
ssize_t expl;
mi_int32 i;
-# if _FFR_MILTER_NAGLE
-# ifdef TCP_CORK
+# if MILTER_NO_NAGLE && defined(TCP_CORK)
int cork = 0;
-# endif
-# endif /* _FFR_MILTER_NAGLE */
+# endif /* MILTER_NO_NAGLE && defined(TCP_CORK) */
char *buf;
char data[MILTER_LEN_BYTES + 1];
@@ -354,8 +399,8 @@ milter_read(m, cmd, rlen, to, e)
{
if (MilterLogLevel > 0)
sm_syslog(LOG_ERR, e->e_id,
- "milter_read(%s): socket closed",
- m->mf_name);
+ "milter_read(%s): socket closed, where=%s",
+ m->mf_name, where);
milter_error(m, e);
return NULL;
}
@@ -366,23 +411,19 @@ milter_read(m, cmd, rlen, to, e)
if (to > 0)
readstart = curtime();
-# if _FFR_MILTER_NAGLE
-# ifdef TCP_CORK
+# if MILTER_NO_NAGLE && defined(TCP_CORK)
setsockopt(m->mf_sock, IPPROTO_TCP, TCP_CORK, (char *)&cork,
sizeof(cork));
-# endif
-# endif /* _FFR_MILTER_NAGLE */
+# endif /* MILTER_NO_NAGLE && defined(TCP_CORK) */
- if (milter_sysread(m, data, sizeof data, to, e) == NULL)
+ if (milter_sysread(m, data, sizeof(data), to, e, where) == NULL)
return NULL;
-# if _FFR_MILTER_NAGLE
-# ifdef TCP_CORK
+# if MILTER_NO_NAGLE && defined(TCP_CORK)
cork = 1;
setsockopt(m->mf_sock, IPPROTO_TCP, TCP_CORK, (char *)&cork,
sizeof(cork));
-# endif
-# endif /* _FFR_MILTER_NAGLE */
+# endif /* MILTER_NO_NAGLE && defined(TCP_CORK) */
/* reset timeout */
if (to > 0)
@@ -393,12 +434,12 @@ milter_read(m, cmd, rlen, to, e)
if (now - readstart >= to)
{
if (tTd(64, 5))
- sm_dprintf("milter_read(%s): timeout before data read\n",
- m->mf_name);
+ sm_dprintf("milter_read(%s): timeout before data read, where=%s\n",
+ m->mf_name, where);
if (MilterLogLevel > 0)
sm_syslog(LOG_ERR, e->e_id,
- "Milter read(%s): timeout before data read",
- m->mf_name);
+ "Milter read(%s): timeout before data read, where=%s",
+ m->mf_name, where);
milter_error(m, e);
return NULL;
}
@@ -417,12 +458,12 @@ milter_read(m, cmd, rlen, to, e)
if (expl < 0)
{
if (tTd(64, 5))
- sm_dprintf("milter_read(%s): read size %ld out of range\n",
- m->mf_name, (long) expl);
+ sm_dprintf("milter_read(%s): read size %ld out of range, where=%s\n",
+ m->mf_name, (long) expl, where);
if (MilterLogLevel > 0)
sm_syslog(LOG_ERR, e->e_id,
- "milter_read(%s): read size %ld out of range",
- m->mf_name, (long) expl);
+ "milter_read(%s): read size %ld out of range, where=%s",
+ m->mf_name, (long) expl, where);
milter_error(m, e);
return NULL;
}
@@ -432,7 +473,7 @@ milter_read(m, cmd, rlen, to, e)
buf = (char *) xalloc(expl);
- if (milter_sysread(m, buf, expl, to, e) == NULL)
+ if (milter_sysread(m, buf, expl, to, e, where) == NULL)
{
sm_free(buf); /* XXX */
return NULL;
@@ -463,18 +504,20 @@ milter_read(m, cmd, rlen, to, e)
*/
static char *
-milter_write(m, cmd, buf, len, to, e)
+milter_write(m, cmd, buf, len, to, e, where)
struct milter *m;
- char cmd;
+ int cmd;
char *buf;
ssize_t len;
time_t to;
ENVELOPE *e;
+ const char *where;
{
time_t writestart = (time_t) 0;
ssize_t sl, i;
int num_vectors;
mi_int32 nl;
+ char command = (char) cmd;
char data[MILTER_LEN_BYTES + 1];
bool started = false;
struct iovec vector[2];
@@ -509,11 +552,11 @@ milter_write(m, cmd, buf, len, to, e)
if (tTd(64, 20))
sm_dprintf("milter_write(%s): cmd %c, len %ld\n",
- m->mf_name, cmd, (long) len);
+ m->mf_name, command, (long) len);
- nl = htonl(len + 1); /* add 1 for the cmd char */
+ nl = htonl(len + 1); /* add 1 for the command char */
(void) memcpy(data, (char *) &nl, MILTER_LEN_BYTES);
- data[MILTER_LEN_BYTES] = cmd;
+ data[MILTER_LEN_BYTES] = command;
sl = MILTER_LEN_BYTES + 1;
/* set up the vector for the size / command */
@@ -552,7 +595,7 @@ milter_write(m, cmd, buf, len, to, e)
if (to > 0)
{
writestart = curtime();
- MILTER_TIMEOUT("write", to, true, started);
+ MILTER_TIMEOUT("write", to, true, started, where);
}
/* write the vector(s) */
@@ -563,12 +606,12 @@ milter_write(m, cmd, buf, len, to, e)
if (tTd(64, 5))
sm_dprintf("milter_write(%s): write(%c) returned %ld, expected %ld: %s\n",
- m->mf_name, cmd, (long) i, (long) sl,
+ m->mf_name, command, (long) i, (long) sl,
sm_errstring(save_errno));
if (MilterLogLevel > 0)
sm_syslog(LOG_ERR, e->e_id,
"Milter (%s): write(%c) returned %ld, expected %ld: %s",
- m->mf_name, cmd, (long) i, (long) sl,
+ m->mf_name, command, (long) i, (long) sl,
sm_errstring(save_errno));
milter_error(m, e);
return NULL;
@@ -629,7 +672,7 @@ milter_open(m, parseonly, e)
}
/* protocol:filename or protocol:port@host */
- memset(&addr, '\0', sizeof addr);
+ memset(&addr, '\0', sizeof(addr));
p = m->mf_conn;
colon = strchr(p, ':');
if (colon != NULL)
@@ -709,7 +752,7 @@ milter_open(m, parseonly, e)
long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK;
at = colon;
- if (strlen(colon) >= sizeof addr.sunix.sun_path)
+ if (strlen(colon) >= sizeof(addr.sunix.sun_path))
{
if (tTd(64, 5))
sm_dprintf("X%s: local socket name %s too long\n",
@@ -762,8 +805,8 @@ milter_open(m, parseonly, e)
}
(void) sm_strlcpy(addr.sunix.sun_path, colon,
- sizeof addr.sunix.sun_path);
- addrlen = sizeof (struct sockaddr_un);
+ sizeof(addr.sunix.sun_path));
+ addrlen = sizeof(struct sockaddr_un);
}
else
# endif /* NETUNIX */
@@ -815,7 +858,7 @@ milter_open(m, parseonly, e)
milter_error(m, e);
return -1;
# else /* NO_GETSERVBYNAME */
- register struct servent *sp;
+ struct servent *sp;
sp = getservbyname(colon, "tcp");
if (sp == NULL)
@@ -865,7 +908,7 @@ milter_open(m, parseonly, e)
}
# endif /* NETINET */
# if NETINET6
- (void) memset(&hid6, '\0', sizeof hid6);
+ (void) memset(&hid6, '\0', sizeof(hid6));
if (addr.sa.sa_family == AF_INET6 &&
anynet_pton(AF_INET6, &at[1],
&hid6.sin6_addr) == 1)
@@ -936,7 +979,7 @@ milter_open(m, parseonly, e)
memmove(&addr.sin.sin_addr,
hp->h_addr, INADDRSZ);
addr.sin.sin_port = port;
- addrlen = sizeof (struct sockaddr_in);
+ addrlen = sizeof(struct sockaddr_in);
addrno = 1;
break;
# endif /* NETINET */
@@ -946,7 +989,7 @@ milter_open(m, parseonly, e)
memmove(&addr.sin6.sin6_addr,
hp->h_addr, IN6ADDRSZ);
addr.sin6.sin6_port = port;
- addrlen = sizeof (struct sockaddr_in6);
+ addrlen = sizeof(struct sockaddr_in6);
addrno = 1;
break;
# endif /* NETINET6 */
@@ -1134,16 +1177,14 @@ milter_open(m, parseonly, e)
hp = NULL;
}
# endif /* NETINET6 */
-# if _FFR_MILTER_NAGLE
-# ifndef TCP_CORK
+# if MILTER_NO_NAGLE && !defined(TCP_CORK)
{
int nodelay = 1;
setsockopt(m->mf_sock, IPPROTO_TCP, TCP_NODELAY,
(char *)&nodelay, sizeof(nodelay));
}
-# endif /* TCP_CORK */
-# endif /* _FFR_MILTER_NAGLE */
+# endif /* MILTER_NO_NAGLE && !defined(TCP_CORK) */
return sock;
}
@@ -1160,6 +1201,7 @@ milter_connect_timeout(ignore)
errno = ETIMEDOUT;
longjmp(MilterConnectTimeout, 1);
}
+
/*
** MILTER_SETUP -- setup structure for a mail filter
**
@@ -1175,8 +1217,8 @@ milter_setup(line)
char *line;
{
char fcode;
- register char *p;
- register struct milter *m;
+ char *p;
+ struct milter *m;
STAB *s;
/* collect the filter name */
@@ -1191,8 +1233,8 @@ milter_setup(line)
syserr("name required for mail filter");
return;
}
- m = (struct milter *) xalloc(sizeof *m);
- memset((char *) m, '\0', sizeof *m);
+ m = (struct milter *) xalloc(sizeof(*m));
+ memset((char *) m, '\0', sizeof(*m));
m->mf_name = newstr(line);
m->mf_state = SMFS_READY;
m->mf_sock = -1;
@@ -1200,6 +1242,11 @@ milter_setup(line)
m->mf_timeout[SMFTO_WRITE] = (time_t) 10;
m->mf_timeout[SMFTO_READ] = (time_t) 10;
m->mf_timeout[SMFTO_EOM] = (time_t) 300;
+#if _FFR_MILTER_CHECK
+ m->mf_mta_prot_version = SMFI_PROT_VERSION;
+ m->mf_mta_prot_flags = SMFI_CURR_PROT;
+ m->mf_mta_actions = SMFI_CURR_ACTS;
+#endif /* _FFR_MILTER_CHECK */
/* now scan through and assign info from the fields */
while (*p != '\0')
@@ -1247,6 +1294,18 @@ milter_setup(line)
milter_parse_timeouts(p, m);
break;
+#if _FFR_MILTER_CHECK
+ case 'a':
+ m->mf_mta_actions = strtoul(p, NULL, 0);
+ break;
+ case 'f':
+ m->mf_mta_prot_flags = strtoul(p, NULL, 0);
+ break;
+ case 'v':
+ m->mf_mta_prot_version = strtoul(p, NULL, 0);
+ break;
+#endif /* _FFR_MILTER_CHECK */
+
default:
syserr("X%s: unknown filter equate %c=",
m->mf_name, fcode);
@@ -1265,6 +1324,7 @@ milter_setup(line)
else
s->s_milter = m;
}
+
/*
** MILTER_CONFIG -- parse option list into an array and check config
**
@@ -1286,7 +1346,7 @@ milter_config(spec, list, max)
int max;
{
int numitems = 0;
- register char *p;
+ char *p;
/* leave one for the NULL signifying the end of the list */
max--;
@@ -1327,6 +1387,7 @@ milter_config(spec, list, max)
if (MilterLogLevel == -1)
MilterLogLevel = LogLevel;
}
+
/*
** MILTER_PARSE_TIMEOUTS -- parse timeout list
**
@@ -1347,7 +1408,7 @@ milter_parse_timeouts(spec, m)
{
char fcode;
int tcode;
- register char *p;
+ char *p;
p = spec;
@@ -1414,6 +1475,63 @@ milter_parse_timeouts(spec, m)
p = delimptr;
}
}
+
+/*
+** MILTER_SET_MACROS -- set milter macros
+**
+** Parameters:
+** name -- name of milter.
+** macros -- where to store macros.
+** val -- the value of the option.
+** nummac -- current number of macros
+**
+** Returns:
+** new number of macros
+*/
+
+static int
+milter_set_macros(name, macros, val, nummac)
+ char *name;
+ char **macros;
+ char *val;
+ int nummac;
+{
+ char *p;
+
+ p = newstr(val);
+ while (*p != '\0')
+ {
+ char *macro;
+
+ /* Skip leading commas, spaces */
+ while (*p != '\0' &&
+ (*p == ',' || (isascii(*p) && isspace(*p))))
+ p++;
+
+ if (*p == '\0')
+ break;
+
+ /* Find end of macro */
+ macro = p;
+ while (*p != '\0' && *p != ',' &&
+ isascii(*p) && !isspace(*p))
+ p++;
+ if (*p != '\0')
+ *p++ = '\0';
+
+ if (nummac >= MAXFILTERMACROS)
+ {
+ syserr("milter_set_option: too many macros in Milter.%s (max %d)",
+ name, MAXFILTERMACROS);
+ macros[nummac] = NULL;
+ return -1;
+ }
+ macros[nummac++] = macro;
+ }
+ macros[nummac] = NULL;
+ return nummac;
+}
+
/*
** MILTER_SET_OPTION -- set an individual milter option
**
@@ -1436,25 +1554,28 @@ static struct milteropt
unsigned char mo_code; /* code for option */
} MilterOptTab[] =
{
-# define MO_MACROS_CONNECT 0x01
+# define MO_MACROS_CONNECT SMFIM_CONNECT
{ "macros.connect", MO_MACROS_CONNECT },
-# define MO_MACROS_HELO 0x02
+# define MO_MACROS_HELO SMFIM_HELO
{ "macros.helo", MO_MACROS_HELO },
-# define MO_MACROS_ENVFROM 0x03
+# define MO_MACROS_ENVFROM SMFIM_ENVFROM
{ "macros.envfrom", MO_MACROS_ENVFROM },
-# define MO_MACROS_ENVRCPT 0x04
+# define MO_MACROS_ENVRCPT SMFIM_ENVRCPT
{ "macros.envrcpt", MO_MACROS_ENVRCPT },
-# define MO_MACROS_DATA 0x05
+# define MO_MACROS_DATA SMFIM_DATA
{ "macros.data", MO_MACROS_DATA },
-# define MO_MACROS_EOM 0x06
+# define MO_MACROS_EOM SMFIM_EOM
{ "macros.eom", MO_MACROS_EOM },
+# define MO_MACROS_EOH SMFIM_EOH
+ { "macros.eoh", MO_MACROS_EOH },
+
# define MO_LOGLEVEL 0x07
{ "loglevel", MO_LOGLEVEL },
# if _FFR_MAXDATASIZE
-# define MO_MAXDATASIZE 0x08
+# define MO_MAXDATASIZE 0x08
{ "maxdatasize", MO_MAXDATASIZE },
# endif /* _FFR_MAXDATASIZE */
- { NULL, 0 },
+ { NULL, (unsigned char)-1 },
};
void
@@ -1463,11 +1584,11 @@ milter_set_option(name, val, sticky)
char *val;
bool sticky;
{
- int nummac = 0;
- register struct milteropt *mo;
- char *p;
+ int nummac, r;
+ struct milteropt *mo;
char **macros = NULL;
+ nummac = 0;
if (tTd(37, 2) || tTd(64, 5))
sm_dprintf("milter_set_option(%s = %s)", name, val);
@@ -1535,6 +1656,11 @@ milter_set_option(name, val, sticky)
macros = MilterEnvRcptMacros;
/* FALLTHROUGH */
+ case MO_MACROS_EOH:
+ if (macros == NULL)
+ macros = MilterEOHMacros;
+ /* FALLTHROUGH */
+
case MO_MACROS_EOM:
if (macros == NULL)
macros = MilterEOMMacros;
@@ -1544,37 +1670,9 @@ milter_set_option(name, val, sticky)
if (macros == NULL)
macros = MilterDataMacros;
- p = newstr(val);
- while (*p != '\0')
- {
- char *macro;
-
- /* Skip leading commas, spaces */
- while (*p != '\0' &&
- (*p == ',' || (isascii(*p) && isspace(*p))))
- p++;
-
- if (*p == '\0')
- break;
-
- /* Find end of macro */
- macro = p;
- while (*p != '\0' && *p != ',' &&
- isascii(*p) && !isspace(*p))
- p++;
- if (*p != '\0')
- *p++ = '\0';
-
- if (nummac >= MAXFILTERMACROS)
- {
- syserr("milter_set_option: too many macros in Milter.%s (max %d)",
- name, MAXFILTERMACROS);
- macros[nummac] = NULL;
- break;
- }
- macros[nummac++] = macro;
- }
- macros[nummac] = NULL;
+ r = milter_set_macros(name, macros, val, nummac);
+ if (r >= 0)
+ nummac = r;
break;
default:
@@ -1584,6 +1682,7 @@ milter_set_option(name, val, sticky)
if (sticky)
setbitn(mo->mo_code, StickyMilterOpt);
}
+
/*
** MILTER_REOPEN_DF -- open & truncate the data file (for replbody)
**
@@ -1600,7 +1699,7 @@ milter_reopen_df(e)
{
char dfname[MAXPATHLEN];
- (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof dfname);
+ (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof(dfname));
/*
** In SuperSafe == SAFE_REALLY mode, e->e_dfp is a read-only FP so
@@ -1638,6 +1737,7 @@ milter_reopen_df(e)
}
return 0;
}
+
/*
** MILTER_RESET_DF -- re-open read-only the data file (for replbody)
**
@@ -1655,7 +1755,7 @@ milter_reset_df(e)
int afd;
char dfname[MAXPATHLEN];
- (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof dfname);
+ (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof(dfname));
if (sm_io_flush(e->e_dfp, SM_TIME_DEFAULT) != 0 ||
sm_io_error(e->e_dfp))
@@ -1689,6 +1789,7 @@ milter_reset_df(e)
e->e_flags |= EF_HAS_DF;
return 0;
}
+
/*
** MILTER_CAN_DELRCPTS -- can any milter filters delete recipients?
**
@@ -1723,6 +1824,7 @@ milter_can_delrcpts()
return can;
}
+
/*
** MILTER_QUIT_FILTER -- close down a single filter
**
@@ -1759,7 +1861,7 @@ milter_quit_filter(m, e)
}
(void) milter_write(m, SMFIC_QUIT, (char *) NULL, 0,
- m->mf_timeout[SMFTO_WRITE], e);
+ m->mf_timeout[SMFTO_WRITE], e, "quit_filter");
if (m->mf_sock >= 0)
{
(void) close(m->mf_sock);
@@ -1768,6 +1870,7 @@ milter_quit_filter(m, e)
if (m->mf_state != SMFS_ERROR)
m->mf_state = SMFS_CLOSED;
}
+
/*
** MILTER_ABORT_FILTER -- tell filter to abort current message
**
@@ -1795,10 +1898,11 @@ milter_abort_filter(m, e)
return;
(void) milter_write(m, SMFIC_ABORT, (char *) NULL, 0,
- m->mf_timeout[SMFTO_WRITE], e);
+ m->mf_timeout[SMFTO_WRITE], e, "abort_filter");
if (m->mf_state != SMFS_ERROR)
m->mf_state = SMFS_DONE;
}
+
/*
** MILTER_SEND_MACROS -- provide macros to the filters
**
@@ -1816,11 +1920,12 @@ static void
milter_send_macros(m, macros, cmd, e)
struct milter *m;
char **macros;
- char cmd;
+ int cmd;
ENVELOPE *e;
{
int i;
int mid;
+ char command = (char) cmd;
char *v;
char *buf, *bp;
char exp[MAXLINE];
@@ -1849,7 +1954,7 @@ milter_send_macros(m, macros, cmd, e)
buf = (char *) xalloc(s);
bp = buf;
- *bp++ = cmd;
+ *bp++ = command;
for (i = 0; macros[i] != NULL; i++)
{
mid = macid(macros[i]);
@@ -1862,7 +1967,7 @@ milter_send_macros(m, macros, cmd, e)
if (tTd(64, 10))
sm_dprintf("milter_send_macros(%s, %c): %s=%s\n",
- m->mf_name, cmd, macros[i], exp);
+ m->mf_name, command, macros[i], exp);
(void) sm_strlcpy(bp, macros[i], s - (bp - buf));
bp += strlen(bp) + 1;
@@ -1870,7 +1975,7 @@ milter_send_macros(m, macros, cmd, e)
bp += strlen(bp) + 1;
}
(void) milter_write(m, SMFIC_MACRO, buf, s,
- m->mf_timeout[SMFTO_WRITE], e);
+ m->mf_timeout[SMFTO_WRITE], e, "send_macros");
sm_free(buf);
}
@@ -1879,7 +1984,7 @@ milter_send_macros(m, macros, cmd, e)
**
** Parameters:
** m -- current milter filter
-** command -- command to send.
+** cmd -- command to send.
** data -- optional command data.
** sz -- length of buf.
** e -- current envelope (for e->e_id).
@@ -1890,20 +1995,20 @@ milter_send_macros(m, macros, cmd, e)
*/
static char *
-milter_send_command(m, command, data, sz, e, state)
+milter_send_command(m, cmd, data, sz, e, state, where)
struct milter *m;
- char command;
+ int cmd;
void *data;
ssize_t sz;
ENVELOPE *e;
char *state;
+ const char *where;
{
char rcmd;
ssize_t rlen;
unsigned long skipflag;
-#if _FFR_MILTER_NOHDR_RESP
unsigned long norespflag = 0;
-#endif /* _FFR_MILTER_NOHDR_RESP */
+ char command = (char) cmd;
char *action;
char *defresponse;
char *response;
@@ -1917,64 +2022,66 @@ milter_send_command(m, command, data, sz, e, state)
{
case SMFIC_CONNECT:
skipflag = SMFIP_NOCONNECT;
+ norespflag = SMFIP_NR_CONN;
action = "connect";
defresponse = "554 Command rejected";
break;
case SMFIC_HELO:
skipflag = SMFIP_NOHELO;
+ norespflag = SMFIP_NR_HELO;
action = "helo";
defresponse = "550 Command rejected";
break;
case SMFIC_MAIL:
skipflag = SMFIP_NOMAIL;
+ norespflag = SMFIP_NR_MAIL;
action = "mail";
defresponse = "550 5.7.1 Command rejected";
break;
case SMFIC_RCPT:
skipflag = SMFIP_NORCPT;
+ norespflag = SMFIP_NR_RCPT;
action = "rcpt";
defresponse = "550 5.7.1 Command rejected";
break;
case SMFIC_HEADER:
skipflag = SMFIP_NOHDRS;
-#if _FFR_MILTER_NOHDR_RESP
- norespflag = SMFIP_NOHREPL;
-#endif /* _FFR_MILTER_NOHDR_RESP */
+ norespflag = SMFIP_NR_HDR;
action = "header";
defresponse = "550 5.7.1 Command rejected";
break;
case SMFIC_BODY:
skipflag = SMFIP_NOBODY;
+ norespflag = SMFIP_NR_BODY;
action = "body";
defresponse = "554 5.7.1 Command rejected";
break;
case SMFIC_EOH:
skipflag = SMFIP_NOEOH;
+ norespflag = SMFIP_NR_EOH;
action = "eoh";
defresponse = "550 5.7.1 Command rejected";
break;
-#if SMFI_VERSION > 2
case SMFIC_UNKNOWN:
skipflag = SMFIP_NOUNKNOWN;
+ norespflag = SMFIP_NR_UNKN;
action = "unknown";
defresponse = "550 5.7.1 Command rejected";
break;
-#endif /* SMFI_VERSION > 2 */
-#if SMFI_VERSION > 3
case SMFIC_DATA:
skipflag = SMFIP_NODATA;
+ norespflag = SMFIP_NR_DATA;
action = "data";
defresponse = "550 5.7.1 Command rejected";
break;
-#endif /* SMFI_VERSION > 3 */
case SMFIC_BODYEOB:
case SMFIC_OPTNEG:
@@ -1991,29 +2098,30 @@ milter_send_command(m, command, data, sz, e, state)
break;
}
+ if (tTd(64, 10))
+ sm_dprintf("milter_send_command(%s): skip=%lx, pflags=%x\n",
+ m->mf_name, skipflag, m->mf_pflags);
+
/* check if filter wants this command */
- if (skipflag != 0 &&
- bitset(skipflag, m->mf_pflags))
+ if (skipflag != 0 && bitset(skipflag, m->mf_pflags))
return NULL;
/* send the command to the filter */
(void) milter_write(m, command, data, sz,
- m->mf_timeout[SMFTO_WRITE], e);
+ m->mf_timeout[SMFTO_WRITE], e, where);
if (m->mf_state == SMFS_ERROR)
{
MILTER_CHECK_ERROR(false, return NULL);
return NULL;
}
-#if _FFR_MILTER_NOHDR_RESP
/* check if filter sends response to this command */
if (norespflag != 0 && bitset(norespflag, m->mf_pflags))
return NULL;
-#endif /* _FFR_MILTER_NOHDR_RESP */
/* get the response from the filter */
response = milter_read(m, &rcmd, &rlen,
- m->mf_timeout[SMFTO_READ], e);
+ m->mf_timeout[SMFTO_READ], e, where);
if (m->mf_state == SMFS_ERROR)
{
MILTER_CHECK_ERROR(false, return NULL);
@@ -2029,28 +2137,32 @@ milter_send_command(m, command, data, sz, e, state)
case SMFIR_REPLYCODE:
MILTER_CHECK_REPLYCODE(defresponse);
if (MilterLogLevel > 10)
- sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, reject=%s",
+ sm_syslog(LOG_INFO, e->e_id,
+ "milter=%s, action=%s, reject=%s",
m->mf_name, action, response);
*state = rcmd;
break;
case SMFIR_REJECT:
if (MilterLogLevel > 10)
- sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, reject",
+ sm_syslog(LOG_INFO, e->e_id,
+ "milter=%s, action=%s, reject",
m->mf_name, action);
*state = rcmd;
break;
case SMFIR_DISCARD:
if (MilterLogLevel > 10)
- sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, discard",
+ sm_syslog(LOG_INFO, e->e_id,
+ "milter=%s, action=%s, discard",
m->mf_name, action);
*state = rcmd;
break;
case SMFIR_TEMPFAIL:
if (MilterLogLevel > 10)
- sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, tempfail",
+ sm_syslog(LOG_INFO, e->e_id,
+ "milter=%s, action=%s, tempfail",
m->mf_name, action);
*state = rcmd;
break;
@@ -2063,7 +2175,8 @@ milter_send_command(m, command, data, sz, e, state)
else
m->mf_state = SMFS_DONE;
if (MilterLogLevel > 10)
- sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, accepted",
+ sm_syslog(LOG_INFO, e->e_id,
+ "milter=%s, action=%s, accepted",
m->mf_name, action);
break;
@@ -2072,8 +2185,17 @@ milter_send_command(m, command, data, sz, e, state)
if (command == SMFIC_MAIL)
m->mf_state = SMFS_INMSG;
if (MilterLogLevel > 12)
- sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, continue",
+ sm_syslog(LOG_INFO, e->e_id,
+ "milter=%s, action=%s, continue",
+ m->mf_name, action);
+ break;
+
+ case SMFIR_SKIP:
+ if (MilterLogLevel > 12)
+ sm_syslog(LOG_INFO, e->e_id,
+ "milter=%s, action=%s, skip",
m->mf_name, action);
+ m->mf_state = SMFS_SKIP;
break;
default:
@@ -2086,8 +2208,7 @@ milter_send_command(m, command, data, sz, e, state)
break;
}
- if (*state != SMFIR_REPLYCODE &&
- response != NULL)
+ if (*state != SMFIR_REPLYCODE && response != NULL)
{
sm_free(response); /* XXX */
response = NULL;
@@ -2099,33 +2220,38 @@ milter_send_command(m, command, data, sz, e, state)
** MILTER_COMMAND -- send a command and return the response for each filter
**
** Parameters:
-** command -- command to send.
+** cmd -- command to send.
** data -- optional command data.
** sz -- length of buf.
** macros -- macros to send for filter smfi_getsymval().
** e -- current envelope (for macro access).
** state -- return state word.
+** where -- description of calling function (logging).
+** cmd_error -- did the SMTP command cause an error?
**
** Returns:
** response string (may be NULL)
*/
static char *
-milter_command(command, data, sz, macros, e, state)
- char command;
+milter_command(cmd, data, sz, macros, e, state, where, cmd_error)
+ int cmd;
void *data;
ssize_t sz;
char **macros;
ENVELOPE *e;
char *state;
+ const char *where;
+ bool cmd_error;
{
int i;
+ char command = (char) cmd;
char *response = NULL;
time_t tn = 0;
if (tTd(64, 10))
sm_dprintf("milter_command: cmd %c len %ld\n",
- (char) command, (long) sz);
+ command, (long) sz);
*state = SMFIR_CONTINUE;
for (i = 0; InputFilters[i] != NULL; i++)
@@ -2158,7 +2284,22 @@ milter_command(command, data, sz, macros, e, state)
if (MilterLogLevel > 21)
tn = curtime();
- response = milter_send_command(m, command, data, sz, e, state);
+ /*
+ ** send the command if
+ ** there is no error
+ ** or it's RCPT and the client asked for it:
+ ** !cmd_error ||
+ ** where == "rcpt" && m->mf_pflags & SMFIP_RCPT_REJ != 0
+ ** negate that condition and use continue
+ */
+
+ if (cmd_error &&
+ (strcmp(where, "rcpt") != 0 ||
+ (m->mf_pflags & SMFIP_RCPT_REJ) == 0))
+ continue;
+
+ response = milter_send_command(m, command, data, sz, e, state,
+ where);
if (MilterLogLevel > 21)
{
@@ -2173,6 +2314,92 @@ milter_command(command, data, sz, macros, e, state)
}
return response;
}
+
+static int milter_getsymlist __P((struct milter *, char *, int, int));
+
+static int
+milter_getsymlist(m, buf, rlen, offset)
+ struct milter *m;
+ char *buf;
+ int rlen;
+ int offset;
+{
+ int i, r, nummac;
+ mi_int32 v;
+
+ SM_ASSERT(m != NULL);
+ SM_ASSERT(buf != NULL);
+
+ while (offset + MILTER_LEN_BYTES < rlen)
+ {
+ size_t len;
+ char **macros;
+
+ nummac = 0;
+ (void) memcpy((char *) &v, buf + offset, MILTER_LEN_BYTES);
+ i = ntohl(v);
+ if (i < SMFIM_FIRST || i > SMFIM_LAST)
+ return -1;
+ offset += MILTER_LEN_BYTES;
+ macros = NULL;
+
+ switch (i)
+ {
+ case MO_MACROS_CONNECT:
+ if (macros == NULL)
+ macros = MilterConnectMacros;
+ /* FALLTHROUGH */
+
+ case MO_MACROS_HELO:
+ if (macros == NULL)
+ macros = MilterHeloMacros;
+ /* FALLTHROUGH */
+
+ case MO_MACROS_ENVFROM:
+ if (macros == NULL)
+ macros = MilterEnvFromMacros;
+ /* FALLTHROUGH */
+
+ case MO_MACROS_ENVRCPT:
+ if (macros == NULL)
+ macros = MilterEnvRcptMacros;
+ /* FALLTHROUGH */
+
+ case MO_MACROS_EOM:
+ if (macros == NULL)
+ macros = MilterEOMMacros;
+ /* FALLTHROUGH */
+
+ case MO_MACROS_EOH:
+ if (macros == NULL)
+ macros = MilterEOHMacros;
+ /* FALLTHROUGH */
+
+ case MO_MACROS_DATA:
+ if (macros == NULL)
+ macros = MilterDataMacros;
+
+ len = strlen(buf + offset);
+ if (len > 0)
+ {
+ r = milter_set_macros(m->mf_name, macros,
+ buf + offset, nummac);
+ if (r >= 0)
+ nummac = r;
+ }
+ break;
+
+ default:
+ return -1;
+ }
+ if (len == 0)
+ return -1;
+ offset += len + 1;
+ }
+
+ return 0;
+}
+
/*
** MILTER_NEGOTIATE -- get version and flags from filter
**
@@ -2190,10 +2417,8 @@ milter_negotiate(m, e)
ENVELOPE *e;
{
char rcmd;
- mi_int32 fvers;
- mi_int32 fflags;
- mi_int32 pflags;
- mi_int32 curr_prot;
+ mi_int32 fvers, fflags, pflags;
+ mi_int32 mta_prot_vers, mta_prot_flags, mta_actions;
ssize_t rlen;
char *response;
char data[MILTER_OPTLEN];
@@ -2209,32 +2434,36 @@ milter_negotiate(m, e)
return -1;
}
- fvers = htonl(SMFI_VERSION);
- fflags = htonl(SMFI_CURR_ACTS);
- curr_prot = SMFI_V2_PROT
-#if _FFR_MILTER_NOHDR_RESP
- | SMFIP_NOHREPL
-#endif /* _FFR_MILTER_NOHDR_RESP */
-#if SMFI_VERSION >= 3
- | SMFIP_NOUNKNOWN
-# if SMFI_VERSION >= 4
- | SMFIP_NODATA
-# endif /* SMFI_VERSION >= 4 */
-#endif /* SMFI_VERSION >= 3 */
- ;
- pflags = htonl(curr_prot);
+#if _FFR_MILTER_CHECK
+ mta_prot_vers = m->mf_mta_prot_version;
+ mta_prot_flags = m->mf_mta_prot_flags;
+ mta_actions = m->mf_mta_actions;
+#else /* _FFR_MILTER_CHECK */
+ mta_prot_vers = SMFI_PROT_VERSION;
+ mta_prot_flags = SMFI_CURR_PROT;
+ mta_actions = SMFI_CURR_ACTS;
+#endif /* _FFR_MILTER_CHECK */
+
+ fvers = htonl(mta_prot_vers);
+ pflags = htonl(mta_prot_flags);
+ fflags = htonl(mta_actions);
(void) memcpy(data, (char *) &fvers, MILTER_LEN_BYTES);
(void) memcpy(data + MILTER_LEN_BYTES,
(char *) &fflags, MILTER_LEN_BYTES);
(void) memcpy(data + (MILTER_LEN_BYTES * 2),
(char *) &pflags, MILTER_LEN_BYTES);
- (void) milter_write(m, SMFIC_OPTNEG, data, sizeof data,
- m->mf_timeout[SMFTO_WRITE], e);
+ (void) milter_write(m, SMFIC_OPTNEG, data, sizeof(data),
+ m->mf_timeout[SMFTO_WRITE], e, "negotiate");
if (m->mf_state == SMFS_ERROR)
return -1;
- response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e);
+ if (tTd(64, 5))
+ sm_dprintf("milter_negotiate(%s): send: version %lu, fflags 0x%lx, pflags 0x%lx\n",
+ m->mf_name, ntohl(fvers), ntohl(fflags), ntohl(pflags));
+
+ response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e,
+ "negotiate");
if (m->mf_state == SMFS_ERROR)
return -1;
@@ -2273,7 +2502,7 @@ milter_negotiate(m, e)
(void) memcpy((char *) &fvers, response, MILTER_LEN_BYTES);
/* Now make sure we have enough for the feature bitmap */
- if (rlen != MILTER_OPTLEN)
+ if (rlen < MILTER_OPTLEN)
{
if (tTd(64, 5))
sm_dprintf("milter_negotiate(%s): did not return enough info\n",
@@ -2292,8 +2521,6 @@ milter_negotiate(m, e)
MILTER_LEN_BYTES);
(void) memcpy((char *) &pflags, response + (MILTER_LEN_BYTES * 2),
MILTER_LEN_BYTES);
- sm_free(response); /* XXX */
- response = NULL;
m->mf_fvers = ntohl(fvers);
m->mf_fflags = ntohl(fflags);
@@ -2311,39 +2538,39 @@ milter_negotiate(m, e)
"Milter (%s): negotiate: version %d != MTA milter version %d",
m->mf_name, m->mf_fvers, SMFI_VERSION);
milter_error(m, e);
- return -1;
+ goto error;
}
/* check for filter feature mismatch */
- if ((m->mf_fflags & SMFI_CURR_ACTS) != m->mf_fflags)
+ if ((m->mf_fflags & mta_actions) != m->mf_fflags)
{
if (tTd(64, 5))
sm_dprintf("milter_negotiate(%s): filter abilities 0x%x != MTA milter abilities 0x%lx\n",
m->mf_name, m->mf_fflags,
- SMFI_CURR_ACTS);
+ (unsigned long) mta_actions);
if (MilterLogLevel > 0)
sm_syslog(LOG_ERR, e->e_id,
"Milter (%s): negotiate: filter abilities 0x%x != MTA milter abilities 0x%lx",
m->mf_name, m->mf_fflags,
- (unsigned long) SMFI_CURR_ACTS);
+ (unsigned long) mta_actions);
milter_error(m, e);
- return -1;
+ goto error;
}
/* check for protocol feature mismatch */
- if ((m->mf_pflags & curr_prot) != m->mf_pflags)
+ if ((m->mf_pflags & mta_prot_flags) != m->mf_pflags)
{
if (tTd(64, 5))
sm_dprintf("milter_negotiate(%s): protocol abilities 0x%x != MTA milter abilities 0x%lx\n",
m->mf_name, m->mf_pflags,
- (unsigned long) curr_prot);
+ (unsigned long) mta_prot_flags);
if (MilterLogLevel > 0)
sm_syslog(LOG_ERR, e->e_id,
"Milter (%s): negotiate: protocol abilities 0x%x != MTA milter abilities 0x%lx",
m->mf_name, m->mf_pflags,
- (unsigned long) curr_prot);
+ (unsigned long) mta_prot_flags);
milter_error(m, e);
- return -1;
+ goto error;
}
if (m->mf_fvers <= 2)
@@ -2351,11 +2578,22 @@ milter_negotiate(m, e)
if (m->mf_fvers <= 3)
m->mf_pflags |= SMFIP_NODATA;
+ if (rlen > MILTER_OPTLEN)
+ {
+ milter_getsymlist(m, response, rlen, MILTER_OPTLEN);
+ }
+
if (tTd(64, 5))
- sm_dprintf("milter_negotiate(%s): version %u, fflags 0x%x, pflags 0x%x\n",
+ sm_dprintf("milter_negotiate(%s): received: version %u, fflags 0x%x, pflags 0x%x\n",
m->mf_name, m->mf_fvers, m->mf_fflags, m->mf_pflags);
return 0;
+
+ error:
+ if (response != NULL)
+ sm_free(response); /* XXX */
+ return -1;
}
+
/*
** MILTER_PER_CONNECTION_CHECK -- checks on per-connection commands
**
@@ -2383,6 +2621,7 @@ milter_per_connection_check(e)
milter_quit_filter(m, e);
}
}
+
/*
** MILTER_ERROR -- Put a milter filter into error state
**
@@ -2415,6 +2654,7 @@ milter_error(m, e)
sm_syslog(LOG_INFO, e->e_id, "Milter (%s): to error state",
m->mf_name);
}
+
/*
** MILTER_HEADERS -- send headers to a single milter filter
**
@@ -2442,8 +2682,8 @@ milter_headers(m, e, state)
for (h = e->e_header; h != NULL; h = h->h_link)
{
- char *buf;
- ssize_t s;
+ int len_n, len_v, len_t, len_f;
+ char *buf, *hv;
/* don't send over deleted headers */
if (h->h_value == NULL)
@@ -2458,23 +2698,39 @@ milter_headers(m, e, state)
continue;
if (tTd(64, 10))
- sm_dprintf("milter_headers: %s: %s\n",
+ sm_dprintf("milter_headers: %s:%s\n",
h->h_field, h->h_value);
if (MilterLogLevel > 21)
sm_syslog(LOG_INFO, e->e_id, "Milter (%s): header, %s",
m->mf_name, h->h_field);
- s = strlen(h->h_field) + 1 + strlen(h->h_value) + 1;
- if (s < 0)
+ if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags)
+ || *(h->h_value) != ' ')
+ hv = h->h_value;
+ else
+ hv = h->h_value + 1;
+ len_f = strlen(h->h_field) + 1;
+ len_t = len_f + strlen(hv) + 1;
+ if (len_t < 0)
continue;
- buf = (char *) xalloc(s);
- (void) sm_snprintf(buf, s, "%s%c%s",
- h->h_field, '\0', h->h_value);
+ buf = (char *) xalloc(len_t);
+
+ /*
+ ** Note: currently the call to dequote_internal_chars()
+ ** is not required as h_field is supposed to be 7-bit US-ASCII.
+ */
+
+ len_n = dequote_internal_chars(h->h_field, buf, len_f);
+ SM_ASSERT(len_n < len_f);
+ len_v = dequote_internal_chars(hv, buf + len_n + 1,
+ len_t - len_n - 1);
+ SM_ASSERT(len_t >= len_n + 1 + len_v + 1);
+ len_t = len_n + 1 + len_v + 1;
/* send it over */
response = milter_send_command(m, SMFIC_HEADER, buf,
- s, e, state);
- sm_free(buf); /* XXX */
+ len_t, e, state, "header");
+ sm_free(buf);
if (m->mf_state == SMFS_ERROR ||
m->mf_state == SMFS_DONE ||
*state != SMFIR_CONTINUE)
@@ -2485,6 +2741,7 @@ milter_headers(m, e, state)
m->mf_name);
return response;
}
+
/*
** MILTER_BODY -- send the body to a filter
**
@@ -2532,11 +2789,13 @@ milter_body(m, e, state)
/* Change LF to CRLF */
if (c == '\n')
{
+#if !_FFR_MILTER_CONVERT_ALL_LF_TO_CRLF
/* Not a CRLF already? */
if (prevchar != '\r')
+#endif /* !_FFR_MILTER_CONVERT_ALL_LF_TO_CRLF */
{
/* Room for CR now? */
- if (bp + 2 > &buf[sizeof buf])
+ if (bp + 2 > &buf[sizeof(buf)])
{
/* No room, buffer LF */
bufchar = c;
@@ -2554,11 +2813,12 @@ milter_body(m, e, state)
}
*bp++ = (char) c;
prevchar = c;
- if (bp >= &buf[sizeof buf])
+ if (bp >= &buf[sizeof(buf)])
{
/* send chunk */
response = milter_send_command(m, SMFIC_BODY, buf,
- bp - buf, e, state);
+ bp - buf, e, state,
+ "body chunk");
bp = buf;
if (bufchar != '\0')
{
@@ -2569,6 +2829,7 @@ milter_body(m, e, state)
}
if (m->mf_state == SMFS_ERROR ||
m->mf_state == SMFS_DONE ||
+ m->mf_state == SMFS_SKIP ||
*state != SMFIR_CONTINUE)
break;
}
@@ -2578,7 +2839,8 @@ milter_body(m, e, state)
{
ExitStat = EX_IOERR;
if (*state == SMFIR_CONTINUE ||
- *state == SMFIR_ACCEPT)
+ *state == SMFIR_ACCEPT ||
+ m->mf_state == SMFS_SKIP)
{
*state = SMFIR_TEMPFAIL;
if (response != NULL)
@@ -2597,16 +2859,23 @@ milter_body(m, e, state)
if (bp > buf &&
m->mf_state != SMFS_ERROR &&
m->mf_state != SMFS_DONE &&
+ m->mf_state != SMFS_SKIP &&
*state == SMFIR_CONTINUE)
{
/* send chunk */
response = milter_send_command(m, SMFIC_BODY, buf, bp - buf,
- e, state);
+ e, state, "last body chunk");
bp = buf;
}
if (MilterLogLevel > 17)
sm_syslog(LOG_INFO, e->e_id, "Milter (%s): body, sent",
m->mf_name);
+ if (m->mf_state == SMFS_SKIP)
+ {
+ *state = SMFIR_CONTINUE;
+ m->mf_state = SMFS_READY;
+ }
+
return response;
}
@@ -2615,9 +2884,41 @@ milter_body(m, e, state)
*/
/*
+** ADDLEADINGSPACE -- Add a leading space to a string
+**
+** Parameters:
+** str -- string
+** rp -- resource pool for allocations
+**
+** Returns:
+** pointer to new string
+*/
+
+static char *addleadingspace __P((char *, SM_RPOOL_T *));
+
+static char *
+addleadingspace(str, rp)
+ char *str;
+ SM_RPOOL_T *rp;
+{
+ size_t l;
+ char *new;
+
+ SM_ASSERT(str != NULL);
+ l = strlen(str);
+ SM_ASSERT(l + 2 > l);
+ new = sm_rpool_malloc_x(rp, l + 2);
+ new[0] = ' ';
+ new[1] = '\0';
+ sm_strlcpy(new + 1, str, l + 1);
+ return new;
+}
+
+/*
** MILTER_ADDHEADER -- Add the supplied header to the message
**
** Parameters:
+** m -- current filter.
** response -- encoded form of header/value.
** rlen -- length of response.
** e -- current envelope.
@@ -2627,12 +2928,14 @@ milter_body(m, e, state)
*/
static void
-milter_addheader(response, rlen, e)
+milter_addheader(m, response, rlen, e)
+ struct milter *m;
char *response;
ssize_t rlen;
ENVELOPE *e;
{
- char *val;
+ int mh_v_len;
+ char *val, *mh_value;
HDR *h;
if (tTd(64, 10))
@@ -2649,7 +2952,8 @@ milter_addheader(response, rlen, e)
if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen)
{
if (tTd(64, 10))
- sm_dprintf("didn't follow protocol (total len)\n");
+ sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
+ (int) strlen(response), (int) (rlen - 1));
return;
}
@@ -2679,6 +2983,9 @@ milter_addheader(response, rlen, e)
break;
}
+ mh_v_len = 0;
+ mh_value = quote_internal_chars(val, NULL, &mh_v_len);
+
/* add to e_msgsize */
e->e_msgsize += strlen(response) + 2 + strlen(val);
@@ -2686,28 +2993,39 @@ milter_addheader(response, rlen, e)
{
if (tTd(64, 10))
sm_dprintf("Replace default header %s value with %s\n",
- h->h_field, val);
+ h->h_field, mh_value);
if (MilterLogLevel > 8)
sm_syslog(LOG_INFO, e->e_id,
"Milter change: default header %s value with %s",
- h->h_field, val);
- h->h_value = newstr(val);
+ h->h_field, mh_value);
+ if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags))
+ h->h_value = mh_value;
+ else
+ {
+ h->h_value = addleadingspace (mh_value, e->e_rpool);
+ SM_FREE(mh_value);
+ }
h->h_flags |= H_USER;
}
else
{
if (tTd(64, 10))
- sm_dprintf("Add %s: %s\n", response, val);
+ sm_dprintf("Add %s: %s\n", response, mh_value);
if (MilterLogLevel > 8)
- sm_syslog(LOG_INFO, e->e_id, "Milter add: header: %s: %s",
- response, val);
- addheader(newstr(response), val, H_USER, e);
+ sm_syslog(LOG_INFO, e->e_id,
+ "Milter add: header: %s: %s",
+ response, mh_value);
+ addheader(newstr(response), mh_value, H_USER, e,
+ !bitset(SMFIP_HDR_LEADSPC, m->mf_pflags));
+ SM_FREE(mh_value);
}
}
+
/*
** MILTER_INSHEADER -- Insert the supplied header
**
** Parameters:
+** m -- current filter.
** response -- encoded form of header/value.
** rlen -- length of response.
** e -- current envelope.
@@ -2722,14 +3040,15 @@ milter_addheader(response, rlen, e)
*/
static void
-milter_insheader(response, rlen, e)
+milter_insheader(m, response, rlen, e)
+ struct milter *m;
char *response;
ssize_t rlen;
ENVELOPE *e;
{
mi_int32 idx, i;
- char *field;
- char *val;
+ int mh_v_len;
+ char *field, *val, *mh_value;
if (tTd(64, 10))
sm_dprintf("milter_insheader: ");
@@ -2775,17 +3094,23 @@ milter_insheader(response, rlen, e)
e->e_msgsize += strlen(response) + 2 + strlen(val);
if (tTd(64, 10))
- sm_dprintf("Insert (%d) %s: %s\n", idx, response, val);
+ sm_dprintf("Insert (%d) %s: %s\n", idx, field, val);
if (MilterLogLevel > 8)
sm_syslog(LOG_INFO, e->e_id,
"Milter insert (%d): header: %s: %s",
idx, field, val);
- insheader(idx, newstr(field), val, H_USER, e);
+ mh_v_len = 0;
+ mh_value = quote_internal_chars(val, NULL, &mh_v_len);
+ insheader(idx, newstr(field), mh_value, H_USER, e,
+ !bitset(SMFIP_HDR_LEADSPC, m->mf_pflags));
+ SM_FREE(mh_value);
}
+
/*
** MILTER_CHANGEHEADER -- Change the supplied header in the message
**
** Parameters:
+** m -- current filter.
** response -- encoded form of header/index/value.
** rlen -- length of response.
** e -- current envelope.
@@ -2795,13 +3120,15 @@ milter_insheader(response, rlen, e)
*/
static void
-milter_changeheader(response, rlen, e)
+milter_changeheader(m, response, rlen, e)
+ struct milter *m;
char *response;
ssize_t rlen;
ENVELOPE *e;
{
mi_int32 i, index;
- char *field, *val;
+ int mh_v_len;
+ char *field, *val, *mh_value;
HDR *h, *sysheader;
if (tTd(64, 10))
@@ -2844,13 +3171,15 @@ milter_changeheader(response, rlen, e)
return;
}
+ mh_v_len = 0;
+ mh_value = quote_internal_chars(val, NULL, &mh_v_len);
+
sysheader = NULL;
for (h = e->e_header; h != NULL; h = h->h_link)
{
if (sm_strcasecmp(h->h_field, field) == 0)
{
- if (bitset(H_USER, h->h_flags) &&
- --index <= 0)
+ if (bitset(H_USER, h->h_flags) && --index <= 0)
{
sysheader = NULL;
break;
@@ -2889,12 +3218,13 @@ milter_changeheader(response, rlen, e)
{
/* treat modify value with no existing header as add */
if (tTd(64, 10))
- sm_dprintf("Add %s: %s\n", field, val);
+ sm_dprintf("Add %s: %s\n", field, mh_value);
if (MilterLogLevel > 8)
sm_syslog(LOG_INFO, e->e_id,
"Milter change (add): header: %s: %s"
- , field, val);
- addheader(newstr(field), val, H_USER, e);
+ , field, mh_value);
+ addheader(newstr(field), mh_value, H_USER, e,
+ !bitset(SMFIP_HDR_LEADSPC, m->mf_pflags));
}
return;
}
@@ -2903,7 +3233,7 @@ milter_changeheader(response, rlen, e)
{
if (*val == '\0')
{
- sm_dprintf("Delete%s %s: %s\n",
+ sm_dprintf("Delete%s %s:%s\n",
h == sysheader ? " (default header)" : "",
field,
h->h_value == NULL ? "<NULL>" : h->h_value);
@@ -2914,7 +3244,7 @@ milter_changeheader(response, rlen, e)
h == sysheader ? " (default header)" : "",
field,
h->h_value == NULL ? "<NULL>" : h->h_value,
- val);
+ mh_value);
}
}
@@ -2923,7 +3253,7 @@ milter_changeheader(response, rlen, e)
if (*val == '\0')
{
sm_syslog(LOG_INFO, e->e_id,
- "Milter delete: header%s %s: %s",
+ "Milter delete: header%s %s:%s",
h == sysheader ? " (default header)" : "",
field,
h->h_value == NULL ? "<NULL>" : h->h_value);
@@ -2935,7 +3265,7 @@ milter_changeheader(response, rlen, e)
h == sysheader ? " (default header)" : "",
field,
h->h_value == NULL ? "<NULL>" : h->h_value,
- val);
+ mh_value);
}
}
@@ -2965,14 +3295,237 @@ milter_changeheader(response, rlen, e)
e->e_msgsize -= l;
}
h->h_value = NULL;
+ SM_FREE(mh_value);
}
else
{
- h->h_value = newstr(val);
+ if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags))
+ h->h_value = mh_value;
+ else
+ {
+ h->h_value = addleadingspace (mh_value, e->e_rpool);
+ SM_FREE(mh_value);
+ }
h->h_flags |= H_USER;
e->e_msgsize += strlen(h->h_value);
}
}
+
+/*
+** MILTER_SPLIT_RESPONSE -- Split response into fields.
+**
+** Parameters:
+** response -- encoded repsonse.
+** rlen -- length of response.
+** pargc -- number of arguments (ouput)
+**
+** Returns:
+** array of pointers to the individual strings
+*/
+
+static char **milter_split_response __P((char *, ssize_t, int *));
+
+static char **
+milter_split_response(response, rlen, pargc)
+ char *response;
+ ssize_t rlen;
+ int *pargc;
+{
+ char **s;
+ size_t i;
+ int elem, nelem;
+
+ SM_ASSERT(response != NULL);
+ SM_ASSERT(pargc != NULL);
+ *pargc = 0;
+ if (rlen < 2 || strlen(response) >= (size_t) rlen)
+ {
+ if (tTd(64, 10))
+ sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
+ (int) strlen(response), (int) (rlen - 1));
+ return NULL;
+ }
+
+ nelem = 0;
+ for (i = 0; i < rlen; i++)
+ {
+ if (response[i] == '\0')
+ ++nelem;
+ }
+ if (nelem == 0)
+ return NULL;
+
+ /* last entry is only for the name */
+ s = (char **)malloc(nelem * (sizeof(*s)));
+ if (s == NULL)
+ return NULL;
+ s[0] = response;
+ for (i = 0, elem = 0; i < rlen && elem < nelem; i++)
+ {
+ if (response[i] == '\0')
+ {
+ ++elem;
+ if (i + 1 >= rlen)
+ s[elem] = NULL;
+ else
+ s[elem] = &(response[i + 1]);
+ }
+ }
+ *pargc = nelem;
+
+ if (tTd(64, 10))
+ {
+ for (elem = 0; elem < nelem; elem++)
+ sm_dprintf("argv[%d]=\"%s\"\n", elem, s[elem]);
+ }
+
+ /* overwrite last entry (already done above, just paranoia) */
+ s[elem] = NULL;
+ return s;
+}
+
+/*
+** MILTER_CHGFROM -- Change the envelope sender address
+**
+** Parameters:
+** response -- encoded form of recipient address.
+** rlen -- length of response.
+** e -- current envelope.
+**
+** Returns:
+** none
+*/
+
+static void
+milter_chgfrom(response, rlen, e)
+ char *response;
+ ssize_t rlen;
+ ENVELOPE *e;
+{
+ int olderrors, argc;
+ char **argv;
+
+ if (tTd(64, 10))
+ sm_dprintf("milter_chgfrom: ");
+
+ /* sanity checks */
+ if (response == NULL)
+ {
+ if (tTd(64, 10))
+ sm_dprintf("NULL response\n");
+ return;
+ }
+
+ if (*response == '\0' ||
+ strlen(response) + 1 > (size_t) rlen)
+ {
+ if (tTd(64, 10))
+ sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
+ (int) strlen(response), (int) (rlen - 1));
+ return;
+ }
+
+ if (tTd(64, 10))
+ sm_dprintf("%s\n", response);
+ if (MilterLogLevel > 8)
+ sm_syslog(LOG_INFO, e->e_id, "Milter chgfrom: %s", response);
+ argv = milter_split_response(response, rlen, &argc);
+ if (argc < 1 || argc > 2)
+ {
+ if (tTd(64, 10))
+ sm_dprintf("didn't follow protocol argc=%d\n", argc);
+ return;
+ }
+
+ olderrors = Errors;
+ setsender(argv[0], e, NULL, '\0', false);
+ if (argc == 2)
+ {
+ reset_mail_esmtp_args(e);
+
+ /*
+ ** need "features" here: how to get those? via e?
+ ** "fake" it for now: allow everything.
+ */
+
+ parse_esmtp_args(e, NULL, argv[0], argv[1], "MAIL", NULL,
+ mail_esmtp_args);
+ }
+ Errors = olderrors;
+ return;
+}
+
+/*
+** MILTER_ADDRCPT_PAR -- Add the supplied recipient to the message
+**
+** Parameters:
+** response -- encoded form of recipient address.
+** rlen -- length of response.
+** e -- current envelope.
+**
+** Returns:
+** none
+*/
+
+static void
+milter_addrcpt_par(response, rlen, e)
+ char *response;
+ ssize_t rlen;
+ ENVELOPE *e;
+{
+ int olderrors, argc;
+ char *delimptr;
+ char **argv;
+ ADDRESS *a;
+
+ if (tTd(64, 10))
+ sm_dprintf("milter_addrcpt_par: ");
+
+ /* sanity checks */
+ if (response == NULL)
+ {
+ if (tTd(64, 10))
+ sm_dprintf("NULL response\n");
+ return;
+ }
+
+ if (tTd(64, 10))
+ sm_dprintf("%s\n", response);
+ if (MilterLogLevel > 8)
+ sm_syslog(LOG_INFO, e->e_id, "Milter add: rcpt: %s", response);
+
+ argv = milter_split_response(response, rlen, &argc);
+ if (argc < 1 || argc > 2)
+ {
+ if (tTd(64, 10))
+ sm_dprintf("didn't follow protocol argc=%d\n", argc);
+ return;
+ }
+ olderrors = Errors;
+
+ /* how to set ESMTP arguments? */
+ a = parseaddr(argv[0], NULLADDR, RF_COPYALL, ' ', &delimptr, e, true);
+
+ if (a != NULL && olderrors == Errors)
+ {
+ parse_esmtp_args(e, a, argv[0], argv[1], "RCPT", NULL,
+ rcpt_esmtp_args);
+ if (olderrors == Errors)
+ a = recipient(a, &e->e_sendqueue, 0, e);
+ else
+ sm_dprintf("olderrors=%d, Errors=%d\n",
+ olderrors, Errors);
+ }
+ else
+ {
+ sm_dprintf("a=%p, olderrors=%d, Errors=%d\n",
+ a, olderrors, Errors);
+ }
+
+ Errors = olderrors;
+ return;
+}
+
/*
** MILTER_ADDRCPT -- Add the supplied recipient to the message
**
@@ -3022,6 +3575,7 @@ milter_addrcpt(response, rlen, e)
Errors = olderrors;
return;
}
+
/*
** MILTER_DELRCPT -- Delete the supplied recipient from the message
**
@@ -3055,7 +3609,8 @@ milter_delrcpt(response, rlen, e)
strlen(response) + 1 != (size_t) rlen)
{
if (tTd(64, 10))
- sm_dprintf("didn't follow protocol (total len)\n");
+ sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
+ (int) strlen(response), (int) (rlen - 1));
return;
}
@@ -3067,6 +3622,7 @@ milter_delrcpt(response, rlen, e)
(void) removefromlist(response, &e->e_sendqueue, e);
return;
}
+
/*
** MILTER_REPLBODY -- Replace the current data file with new body
**
@@ -3100,7 +3656,7 @@ milter_replbody(response, rlen, newfilter, e)
char dfname[MAXPATHLEN];
(void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER),
- sizeof dfname);
+ sizeof(dfname));
/* Reset prevchar */
prevchar = '\0';
@@ -3303,6 +3859,7 @@ milter_init(e, state)
return true;
}
+
/*
** MILTER_CONNECT -- send connection info to milter filters
**
@@ -3365,7 +3922,7 @@ milter_connect(hostname, addr, e, state)
family = SMFIA_INET6;
port = addr.sin6.sin6_port;
sockinfo = anynet_ntop(&addr.sin6.sin6_addr, buf6,
- sizeof buf6);
+ sizeof(buf6));
if (sockinfo == NULL)
sockinfo = "";
break;
@@ -3387,19 +3944,19 @@ milter_connect(hostname, addr, e, state)
(void) memcpy(bp, hostname, strlen(hostname));
bp += strlen(hostname);
*bp++ = '\0';
- (void) memcpy(bp, &family, sizeof family);
- bp += sizeof family;
+ (void) memcpy(bp, &family, sizeof(family));
+ bp += sizeof(family);
if (family != SMFIA_UNKNOWN)
{
- (void) memcpy(bp, &port, sizeof port);
- bp += sizeof port;
+ (void) memcpy(bp, &port, sizeof(port));
+ bp += sizeof(port);
/* include trailing '\0' */
(void) memcpy(bp, sockinfo, strlen(sockinfo) + 1);
}
- response = milter_command(SMFIC_CONNECT, buf, s,
- MilterConnectMacros, e, state);
+ response = milter_command(SMFIC_CONNECT, buf, s, MilterConnectMacros,
+ e, state, "connect", false);
sm_free(buf); /* XXX */
/*
@@ -3442,6 +3999,7 @@ milter_connect(hostname, addr, e, state)
}
return response;
}
+
/*
** MILTER_HELO -- send SMTP HELO/EHLO command info to milter filters
**
@@ -3486,10 +4044,11 @@ milter_helo(helo, e, state)
}
response = milter_command(SMFIC_HELO, helo, strlen(helo) + 1,
- MilterHeloMacros, e, state);
+ MilterHeloMacros, e, state, "helo", false);
milter_per_connection_check(e);
return response;
}
+
/*
** MILTER_ENVFROM -- send SMTP MAIL command info to milter filters
**
@@ -3570,11 +4129,11 @@ milter_envfrom(args, e, state)
}
if (MilterLogLevel > 14)
- sm_syslog(LOG_INFO, e->e_id, "Milter: senders: %s", buf);
+ sm_syslog(LOG_INFO, e->e_id, "Milter: sender: %s", buf);
/* send it over */
- response = milter_command(SMFIC_MAIL, buf, s,
- MilterEnvFromMacros, e, state);
+ response = milter_command(SMFIC_MAIL, buf, s, MilterEnvFromMacros,
+ e, state, "mail", false);
sm_free(buf); /* XXX */
/*
@@ -3585,7 +4144,7 @@ milter_envfrom(args, e, state)
MILTER_CHECK_DONE_MSG();
if (MilterLogLevel > 10 && *state == SMFIR_REJECT)
- sm_syslog(LOG_INFO, e->e_id, "Milter: reject, senders");
+ sm_syslog(LOG_INFO, e->e_id, "Milter: reject, sender");
return response;
}
@@ -3596,16 +4155,18 @@ milter_envfrom(args, e, state)
** args -- SMTP MAIL command args (args[0] == recipient).
** e -- current envelope.
** state -- return state from response.
+** rcpt_error -- does RCPT have an error?
**
** Returns:
** response string (may be NULL)
*/
char *
-milter_envrcpt(args, e, state)
+milter_envrcpt(args, e, state, rcpt_error)
char **args;
ENVELOPE *e;
char *state;
+ bool rcpt_error;
{
int i;
char *buf, *bp;
@@ -3652,13 +4213,12 @@ milter_envrcpt(args, e, state)
sm_syslog(LOG_INFO, e->e_id, "Milter: rcpts: %s", buf);
/* send it over */
- response = milter_command(SMFIC_RCPT, buf, s,
- MilterEnvRcptMacros, e, state);
+ response = milter_command(SMFIC_RCPT, buf, s, MilterEnvRcptMacros,
+ e, state, "rcpt", rcpt_error);
sm_free(buf); /* XXX */
return response;
}
-#if SMFI_VERSION > 3
/*
** MILTER_DATA_CMD -- send SMTP DATA command info to milter filters
**
@@ -3679,9 +4239,9 @@ milter_data_cmd(e, state)
sm_dprintf("milter_data_cmd\n");
/* send it over */
- return milter_command(SMFIC_DATA, NULL, 0, MilterDataMacros, e, state);
+ return milter_command(SMFIC_DATA, NULL, 0, MilterDataMacros, e, state,
+ "data", false);
}
-#endif /* SMFI_VERSION > 3 */
/*
** MILTER_DATA -- send message headers/body and gather final message results
@@ -3789,9 +4349,16 @@ milter_data(e, state)
if (tTd(64, 10))
sm_dprintf("milter_data: eoh\n");
+ if (MilterEOHMacros[0] != NULL)
+ {
+ milter_send_macros(m, MilterEOHMacros,
+ SMFIC_EOH, e);
+ MILTER_CHECK_RESULTS();
+ }
+
/* send it over */
response = milter_send_command(m, SMFIC_EOH, NULL, 0,
- e, state);
+ e, state, "eoh");
MILTER_CHECK_RESULTS();
}
@@ -3813,7 +4380,7 @@ milter_data(e, state)
/* send the final body chunk */
(void) milter_write(m, SMFIC_BODYEOB, NULL, 0,
- m->mf_timeout[SMFTO_WRITE], e);
+ m->mf_timeout[SMFTO_WRITE], e, "eom");
/* Get time EOM sent for timeout */
eomsent = curtime();
@@ -3838,7 +4405,8 @@ milter_data(e, state)
}
response = milter_read(m, &rcmd, &rlen,
- m->mf_timeout[SMFTO_READ], e);
+ m->mf_timeout[SMFTO_READ], e,
+ "body");
if (m->mf_state == SMFS_ERROR)
break;
@@ -3922,7 +4490,7 @@ milter_data(e, state)
"milter_data(%s): lied about adding headers, honoring request anyway",
m->mf_name);
}
- milter_addheader(response, rlen, e);
+ milter_addheader(m, response, rlen, e);
break;
case SMFIR_INSHEADER:
@@ -3933,7 +4501,7 @@ milter_data(e, state)
"milter_data(%s): lied about adding headers, honoring request anyway",
m->mf_name);
}
- milter_insheader(response, rlen, e);
+ milter_insheader(m, response, rlen, e);
break;
case SMFIR_CHGHEADER:
@@ -3944,7 +4512,18 @@ milter_data(e, state)
"milter_data(%s): lied about changing headers, honoring request anyway",
m->mf_name);
}
- milter_changeheader(response, rlen, e);
+ milter_changeheader(m, response, rlen, e);
+ break;
+
+ case SMFIR_CHGFROM:
+ if (!bitset(SMFIF_CHGFROM, m->mf_fflags))
+ {
+ if (MilterLogLevel > 9)
+ sm_syslog(LOG_WARNING, e->e_id,
+ "milter_data(%s) lied about changing sender, honoring request anyway",
+ m->mf_name);
+ }
+ milter_chgfrom(response, rlen, e);
break;
case SMFIR_ADDRCPT:
@@ -3958,6 +4537,17 @@ milter_data(e, state)
milter_addrcpt(response, rlen, e);
break;
+ case SMFIR_ADDRCPT_PAR:
+ if (!bitset(SMFIF_ADDRCPT_PAR, m->mf_fflags))
+ {
+ if (MilterLogLevel > 9)
+ sm_syslog(LOG_WARNING, e->e_id,
+ "milter_data(%s) lied about adding recipients with parameters, honoring request anyway",
+ m->mf_name);
+ }
+ milter_addrcpt_par(response, rlen, e);
+ break;
+
case SMFIR_DELRCPT:
if (!bitset(SMFIF_DELRCPT, m->mf_fflags))
{
@@ -4086,13 +4676,12 @@ finishup:
return response;
}
-#if SMFI_VERSION > 2
/*
** MILTER_UNKNOWN -- send any unrecognized or unimplemented command
** string to milter filters
**
** Parameters:
-** cmd -- the string itself.
+** smtpcmd -- the string itself.
** e -- current envelope.
** state -- return state from response.
**
@@ -4102,18 +4691,17 @@ finishup:
*/
char *
-milter_unknown(cmd, e, state)
- char *cmd;
+milter_unknown(smtpcmd, e, state)
+ char *smtpcmd;
ENVELOPE *e;
char *state;
{
if (tTd(64, 10))
- sm_dprintf("milter_unknown(%s)\n", cmd);
+ sm_dprintf("milter_unknown(%s)\n", smtpcmd);
- return milter_command(SMFIC_UNKNOWN, cmd, strlen(cmd) + 1,
- NULL, e, state);
+ return milter_command(SMFIC_UNKNOWN, smtpcmd, strlen(smtpcmd) + 1,
+ NULL, e, state, "unknown", false);
}
-#endif /* SMFI_VERSION > 2 */
/*
** MILTER_QUIT -- informs the filter(s) we are done and closes connection(s)
@@ -4137,6 +4725,7 @@ milter_quit(e)
for (i = 0; InputFilters[i] != NULL; i++)
milter_quit_filter(InputFilters[i], e);
}
+
/*
** MILTER_ABORT -- informs the filter(s) that we are aborting current message
**
diff --git a/contrib/sendmail/src/mime.c b/contrib/sendmail/src/mime.c
index c73fbf2..48540a0 100644
--- a/contrib/sendmail/src/mime.c
+++ b/contrib/sendmail/src/mime.c
@@ -14,7 +14,7 @@
#include <sendmail.h>
#include <string.h>
-SM_RCSID("@(#)$Id: mime.c,v 8.142.2.1 2006/05/23 01:32:08 ca Exp $")
+SM_RCSID("@(#)$Id: mime.c,v 8.146 2006/08/16 16:52:11 ca Exp $")
/*
** MIME support.
@@ -151,7 +151,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
MapNLtoCRLF = true;
p = hvalue("Content-Transfer-Encoding", header);
if (p == NULL ||
- (pvp = prescan(p, '\0', pvpbuf, sizeof pvpbuf, NULL,
+ (pvp = prescan(p, '\0', pvpbuf, sizeof(pvpbuf), NULL,
MimeTokenTab, false)) == NULL ||
pvp[0] == NULL)
{
@@ -159,7 +159,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
}
else
{
- cataddr(pvp, NULL, buf, sizeof buf, '\0');
+ cataddr(pvp, NULL, buf, sizeof(buf), '\0', false);
cte = sm_rpool_strdup_x(e->e_rpool, buf);
}
@@ -173,7 +173,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
p = "text/plain";
}
if (p != NULL &&
- (pvp = prescan(p, '\0', pvpbuf, sizeof pvpbuf, NULL,
+ (pvp = prescan(p, '\0', pvpbuf, sizeof(pvpbuf), NULL,
MimeTokenTab, false)) != NULL &&
pvp[0] != NULL)
{
@@ -238,7 +238,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
** just copy it through.
*/
- (void) sm_snprintf(buf, sizeof buf, "%.100s/%.100s", type, subtype);
+ (void) sm_snprintf(buf, sizeof(buf), "%.100s/%.100s", type, subtype);
if (wordinclass(buf, 'n') || (cte != NULL && !wordinclass(cte, 'e')))
flags |= M87F_NO8BIT;
@@ -283,7 +283,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
p = argv[i].a_value;
stripquotes(p);
}
- if (sm_strlcpy(bbuf, p, sizeof bbuf) >= sizeof bbuf)
+ if (sm_strlcpy(bbuf, p, sizeof(bbuf)) >= sizeof(bbuf))
{
usrerr("mime8to7: multipart boundary \"%s\" too long",
p);
@@ -322,7 +322,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
goto writeerr;
mci->mci_flags &= ~MCIF_INHEADER;
bt = MBT_FINAL;
- while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
+ while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof(buf))
!= NULL)
{
bt = mimeboundary(buf, boundaries);
@@ -340,7 +340,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
{
auto HDR *hdr = NULL;
- (void) sm_strlcpyn(buf, sizeof buf, 2, "--", bbuf);
+ (void) sm_strlcpyn(buf, sizeof(buf), 2, "--", bbuf);
if (!putline(buf, mci))
goto writeerr;
if (tTd(43, 35))
@@ -357,7 +357,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
if (bt == SM_IO_EOF)
goto writeerr;
}
- (void) sm_strlcpyn(buf, sizeof buf, 3, "--", bbuf, "--");
+ (void) sm_strlcpyn(buf, sizeof(buf), 3, "--", bbuf, "--");
if (!putline(buf, mci))
goto writeerr;
if (tTd(43, 35))
@@ -366,7 +366,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
mci->mci_flags &= ~MCIF_INMIME;
/* skip the late "comment" epilogue */
- while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
+ while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof(buf))
!= NULL)
{
bt = mimeboundary(buf, boundaries);
@@ -443,7 +443,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
DATAFL_LETTER, e->e_id);
/* do a scan of this body type to count character types */
- while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
+ while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof(buf))
!= NULL)
{
if (mimeboundary(buf, boundaries) != MBT_NOTSEP)
@@ -512,7 +512,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
** situation.
*/
- (void) sm_snprintf(buf, sizeof buf,
+ (void) sm_snprintf(buf, sizeof(buf),
"Content-Transfer-Encoding: %.200s", cte);
if (!putline(buf, mci))
goto writeerr;
@@ -522,7 +522,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
if (!putline("", mci))
goto writeerr;
mci->mci_flags &= ~MCIF_INHEADER;
- while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
+ while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof(buf))
!= NULL)
{
bt = mimeboundary(buf, boundaries);
@@ -544,7 +544,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
sm_dprintf(" ...Content-Transfer-Encoding: base64\n");
if (!putline("Content-Transfer-Encoding: base64", mci))
goto writeerr;
- (void) sm_snprintf(buf, sizeof buf,
+ (void) sm_snprintf(buf, sizeof(buf),
"X-MIME-Autoconverted: from 8bit to base64 by %s id %s",
MyHostName, e->e_id);
if (!putline(buf, mci) || !putline("", mci))
@@ -614,7 +614,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
if (!putline("Content-Transfer-Encoding: quoted-printable",
mci))
goto writeerr;
- (void) sm_snprintf(buf, sizeof buf,
+ (void) sm_snprintf(buf, sizeof(buf),
"X-MIME-Autoconverted: from 8bit to quoted-printable by %s id %s",
MyHostName, e->e_id);
if (!putline(buf, mci) || !putline("", mci))
@@ -798,7 +798,7 @@ mime_getchar(fp, boundaries, btp)
/* got "--", now check for rest of separator */
*bp++ = '-';
- while (bp < &buf[sizeof buf - 2] &&
+ while (bp < &buf[sizeof(buf) - 2] &&
(c = sm_io_getc(fp, SM_TIME_DEFAULT)) != SM_IO_EOF &&
c != '\n')
{
@@ -816,7 +816,7 @@ mime_getchar(fp, boundaries, btp)
return SM_IO_EOF;
}
- if (bp < &buf[sizeof buf - 2] && c != SM_IO_EOF)
+ if (bp < &buf[sizeof(buf) - 2] && c != SM_IO_EOF)
*bp++ = c;
}
@@ -1041,7 +1041,7 @@ mime7to8(mci, header, e)
p = hvalue("Content-Transfer-Encoding", header);
if (p == NULL ||
- (pvp = prescan(p, '\0', pvpbuf, sizeof pvpbuf, NULL,
+ (pvp = prescan(p, '\0', pvpbuf, sizeof(pvpbuf), NULL,
MimeTokenTab, false)) == NULL ||
pvp[0] == NULL)
{
@@ -1054,7 +1054,7 @@ mime7to8(mci, header, e)
/* cheap failsafe algorithm -- should work on text/plain */
if (p != NULL)
{
- (void) sm_snprintf(buf, sizeof buf,
+ (void) sm_snprintf(buf, sizeof(buf),
"Content-Transfer-Encoding: %s", p);
if (!putline(buf, mci))
goto writeerr;
@@ -1062,7 +1062,7 @@ mime7to8(mci, header, e)
if (!putline("", mci))
goto writeerr;
mci->mci_flags &= ~MCIF_INHEADER;
- while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf)
+ while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof(buf))
!= NULL)
{
if (!putline(buf, mci))
@@ -1070,13 +1070,13 @@ mime7to8(mci, header, e)
}
return true;
}
- cataddr(pvp, NULL, buf, sizeof buf, '\0');
+ cataddr(pvp, NULL, buf, sizeof(buf), '\0', false);
cte = sm_rpool_strdup_x(e->e_rpool, buf);
mci->mci_flags |= MCIF_INHEADER;
if (!putline("Content-Transfer-Encoding: 8bit", mci))
goto writeerr;
- (void) sm_snprintf(buf, sizeof buf,
+ (void) sm_snprintf(buf, sizeof(buf),
"X-MIME-Autoconverted: from %.200s to 8bit by %s id %s",
cte, MyHostName, e->e_id);
if (!putline(buf, mci) || !putline("", mci))
@@ -1173,7 +1173,7 @@ mime7to8(mci, header, e)
pxflags |= PXLF_NOADDEOL;
fbufp = fbuf;
while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf,
- sizeof buf) != NULL)
+ sizeof(buf)) != NULL)
{
off = mime_fromqp((unsigned char *) buf, &fbufp,
&fbuf[MAXLINE] - fbufp);
diff --git a/contrib/sendmail/src/parseaddr.c b/contrib/sendmail/src/parseaddr.c
index dea3e1f..9a14ec9 100644
--- a/contrib/sendmail/src/parseaddr.c
+++ b/contrib/sendmail/src/parseaddr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2005 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,7 +13,10 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: parseaddr.c,v 8.384 2006/04/18 01:28:47 ca Exp $")
+SM_RCSID("@(#)$Id: parseaddr.c,v 8.400 2006/12/21 00:24:06 ca Exp $")
+
+#include <sm/sendmail.h>
+#include "map.h"
static void allocaddr __P((ADDRESS *, int, char *, ENVELOPE *));
static int callsubr __P((char**, int, ENVELOPE *));
@@ -90,7 +93,8 @@ parseaddr(addr, a, flags, delim, delimptr, e, isrcpt)
if (delimptr == NULL)
delimptr = &delimptrbuf;
- pvp = prescan(addr, delim, pvpbuf, sizeof pvpbuf, delimptr, NULL, false);
+ pvp = prescan(addr, delim, pvpbuf, sizeof(pvpbuf), delimptr,
+ ExtTokenTab, false);
if (pvp == NULL)
{
if (tTd(20, 1))
@@ -176,7 +180,7 @@ parseaddr(addr, a, flags, delim, delimptr, e, isrcpt)
*/
if ((a->q_qgrp == NOAQGRP || a->q_qgrp == ENVQGRP) &&
- !bitset(RF_SENDERADDR|RF_HEADERADDR, flags) &&
+ !bitset(RF_SENDERADDR|RF_HEADERADDR|RF_RM_ADDR, flags) &&
OpMode != MD_INITALIAS)
{
int r;
@@ -268,7 +272,7 @@ invalidaddr(addr, delimptr, isrcpt)
}
for (; *addr != '\0'; addr++)
{
- if ((*addr & 0340) == 0200)
+ if (!EightBitAddrOK && (*addr & 0340) == 0200)
{
setstat(EX_USAGE);
result = true;
@@ -345,7 +349,7 @@ hasctrlchar(addr, isrcpt, complain)
}
result = "too long";
}
- if (!quoted && (*addr < 32 || *addr == 127))
+ if (!EightBitAddrOK && !quoted && (*addr < 32 || *addr == 127))
{
result = "non-printable character";
*addr = BAD_CHAR_REPLACEMENT;
@@ -363,7 +367,7 @@ hasctrlchar(addr, isrcpt, complain)
break;
}
}
- if ((*addr & 0340) == 0200)
+ if (!EightBitAddrOK && (*addr & 0340) == 0200)
{
setstat(EX_USAGE);
result = "8-bit character";
@@ -431,6 +435,7 @@ allocaddr(a, flags, paddr, e)
a->q_paddr = sm_rpool_strdup_x(e->e_rpool, a->q_user);
a->q_qgrp = NOAQGRP;
}
+
/*
** PRESCAN -- Prescan name and make it canonical
**
@@ -491,11 +496,51 @@ static short StateTab[NSTATES][NSTATES] =
/*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 },
+ /*ILL*/ { OPR|B, ATM|B, QST|B, SPC|MB, ONE|B, ILL|M }
+};
+
+/* these all get modified with the OperatorChars */
+
+/* token type table for external strings */
+unsigned char ExtTokenTab[256] =
+{
+ /* 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, SPC,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 */
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,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 ! " # $ % & ' ( ) * + , - . / */
+ 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
};
-/* token type table -- it gets modified with $o characters */
-static unsigned char TokTypeTab[256] =
+/* token type table for internal strings */
+unsigned char IntTokenTab[256] =
{
/* 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,
@@ -529,7 +574,7 @@ static unsigned char TokTypeTab[256] =
/* ` 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,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ONE
};
/* token type table for MIME parsing */
@@ -567,7 +612,7 @@ unsigned char MimeTokenTab[256] =
/* ` 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,
+ ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ONE
};
/* token type table: don't strip comments */
@@ -605,7 +650,7 @@ unsigned char TokTypeNoC[256] =
/* ` 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,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ONE
};
@@ -649,19 +694,21 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab, ignore)
if (OperatorChars == NULL)
OperatorChars = ".:@[]";
}
- expand(OperatorChars, obuf, sizeof obuf - sizeof DELIMCHARS,
+ expand(OperatorChars, obuf, sizeof(obuf) - sizeof(DELIMCHARS),
CurEnv);
- (void) sm_strlcat(obuf, DELIMCHARS, sizeof obuf);
+ (void) sm_strlcat(obuf, DELIMCHARS, sizeof(obuf));
for (p = obuf; *p != '\0'; p++)
{
- if (TokTypeTab[*p & 0xff] == ATM)
- TokTypeTab[*p & 0xff] = OPR;
+ if (IntTokenTab[*p & 0xff] == ATM)
+ IntTokenTab[*p & 0xff] = OPR;
+ if (ExtTokenTab[*p & 0xff] == ATM)
+ ExtTokenTab[*p & 0xff] = OPR;
if (TokTypeNoC[*p & 0xff] == ATM)
TokTypeNoC[*p & 0xff] = OPR;
}
}
if (toktab == NULL)
- toktab = TokTypeTab;
+ toktab = ExtTokenTab;
/* make sure error messages don't have garbage on them */
errno = 0;
@@ -712,7 +759,8 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab, ignore)
/* squirrel it away */
#if !ALLOW_255
- if ((char) c == (char) -1 && !tTd(82, 101))
+ if ((char) c == (char) -1 && !tTd(82, 101) &&
+ !EightBitAddrOK)
c &= 0x7f;
#endif /* !ALLOW_255 */
*q++ = c;
@@ -995,7 +1043,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
rulename = RuleSetNames[ruleset];
if (rulename == NULL)
{
- (void) sm_snprintf(name, sizeof name, "%d", ruleset);
+ (void) sm_snprintf(name, sizeof(name), "%d", ruleset);
rulename = name;
}
if (OpMode == MD_TEST)
@@ -1081,14 +1129,15 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
/* end-of-pattern before end-of-address */
goto backup;
}
- if (ap == NULL && (*rp & 0377) != MATCHZANY &&
- (*rp & 0377) != MATCHZERO)
+ if (ap == NULL &&
+ (rp[0] & 0377) != MATCHZANY &&
+ (rp[0] & 0377) != MATCHZERO)
{
/* end-of-input with patterns left */
goto backup;
}
- switch (*rp & 0377)
+ switch (rp[0] & 0377)
{
case MATCHCLASS:
/* match any phrase in a class */
@@ -1100,7 +1149,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
goto backup;
mlp->match_last = avp++;
cataddr(mlp->match_first, mlp->match_last,
- buf, sizeof buf, '\0');
+ buf, sizeof(buf), '\0', true);
if (!wordinclass(buf, rp[1]))
{
if (tTd(21, 36))
@@ -1215,8 +1264,9 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
/* run off the end -- back up again */
continue;
}
- if ((*rp & 0377) == MATCHANY ||
- (*rp & 0377) == MATCHZANY)
+
+ if ((rp[0] & 0377) == MATCHANY ||
+ (rp[0] & 0377) == MATCHZANY)
{
/* extend binding and continue */
mlp->match_last = avp++;
@@ -1224,7 +1274,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
mlp++;
break;
}
- if ((*rp & 0377) == MATCHCLASS)
+ if ((rp[0] & 0377) == MATCHCLASS)
{
/* extend binding and try again */
mlp->match_last = avp;
@@ -1263,14 +1313,14 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
rp = *rvp;
if (rp != NULL)
{
- if ((*rp & 0377) == CANONUSER)
+ if ((rp[0] & 0377) == CANONUSER)
{
rvp++;
rwr = rwr->r_next;
ruleno++;
loopcount = 0;
}
- else if ((*rp & 0377) == CANONHOST)
+ else if ((rp[0] & 0377) == CANONHOST)
{
rvp++;
rwr = NULL;
@@ -1284,7 +1334,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
register char **pp;
rp = *rvp;
- if ((*rp & 0377) == MATCHREPL)
+ if ((rp[0] & 0377) == MATCHREPL)
{
/* substitute from LHS */
m = &mlist[rp[1] - '1'];
@@ -1327,9 +1377,9 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
rulename, ruleno);
return EX_DATAERR;
}
- if ((*rp & 0377) != MACRODEXPAND)
+ if ((rp[0] & 0377) != MACRODEXPAND)
{
- /* vanilla replacement */
+ /* vanilla replacement from RHS */
*avp++ = rp;
}
else
@@ -1351,7 +1401,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
/* save the remainder of the input */
for (xpvp = pvp; *xpvp != NULL; xpvp++)
- trsize += sizeof *xpvp;
+ trsize += sizeof(*xpvp);
if (trsize > pvpb1_size)
{
if (pvpb1 != NULL)
@@ -1367,7 +1417,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
/* scan the new replacement */
xpvp = prescan(mval, '\0', pvpbuf,
- sizeof pvpbuf, NULL,
+ sizeof(pvpbuf), NULL,
NULL, false);
if (xpvp == NULL)
{
@@ -1421,23 +1471,13 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
char pvpbuf[PSBUFSIZE];
char *nullpvp[1];
- if ((**rvp & 0377) != HOSTBEGIN &&
- (**rvp & 0377) != LOOKUPBEGIN)
- continue;
-
- /*
- ** Got a hostname/keyword lookup.
- **
- ** This could be optimized fairly easily.
- */
-
hbrvp = rvp;
- if ((**rvp & 0377) == HOSTBEGIN)
+ if ((rvp[0][0] & 0377) == HOSTBEGIN)
{
endtoken = HOSTEND;
mapname = "host";
}
- else
+ else if ((rvp[0][0] & 0377) == LOOKUPBEGIN)
{
endtoken = LOOKUPEND;
mapname = *++rvp;
@@ -1448,6 +1488,15 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
SM_ASSERT(0);
}
}
+ else
+ continue;
+
+ /*
+ ** Got a hostname/keyword lookup.
+ **
+ ** This could be optimized fairly easily.
+ */
+
map = stab(mapname, ST_MAP, ST_FIND);
if (map == NULL)
syserr("554 5.3.0 rewrite: map %s not found",
@@ -1466,9 +1515,9 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
arg_rvp = argvect;
xpvp = NULL;
replac = pvpbuf;
- while (*rvp != NULL && (**rvp & 0377) != endtoken)
+ while (*rvp != NULL && ((rvp[0][0] & 0377) != endtoken))
{
- int nodetype = **rvp & 0377;
+ int nodetype = rvp[0][0] & 0377;
if (nodetype != CANONHOST &&
nodetype != CANONUSER)
@@ -1482,8 +1531,8 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
if (xpvp != NULL)
{
cataddr(xpvp, NULL, replac,
- &pvpbuf[sizeof pvpbuf] - replac,
- '\0');
+ &pvpbuf[sizeof(pvpbuf)] - replac,
+ '\0', false);
if (arg_rvp <
&argvect[MAX_MAP_ARGS - 1])
*++arg_rvp = replac;
@@ -1506,8 +1555,8 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
if (xpvp != NULL)
{
cataddr(xpvp, NULL, replac,
- &pvpbuf[sizeof pvpbuf] - replac,
- '\0');
+ &pvpbuf[sizeof(pvpbuf)] - replac,
+ '\0', false);
if (arg_rvp < &argvect[MAX_MAP_ARGS - 1])
*++arg_rvp = replac;
}
@@ -1517,12 +1566,13 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
*++arg_rvp = NULL;
/* save the remainder of the input string */
- trsize = (avp - rvp + 1) * sizeof *rvp;
+ trsize = (avp - rvp + 1) * sizeof(*rvp);
memmove((char *) pvpb1, (char *) rvp, trsize);
/* look it up */
- cataddr(key_rvp, NULL, cbuf, sizeof cbuf,
- map == NULL ? '\0' : map->s_map.map_spacesub);
+ cataddr(key_rvp, NULL, cbuf, sizeof(cbuf),
+ map == NULL ? '\0' : map->s_map.map_spacesub,
+ true);
argvect[0] = cbuf;
replac = map_lookup(map, cbuf, argvect, &rstat, e);
@@ -1530,8 +1580,8 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
if (replac == NULL && default_rvp != NULL)
{
/* create the default */
- cataddr(default_rvp, NULL, cbuf, sizeof cbuf,
- '\0');
+ cataddr(default_rvp, NULL, cbuf, sizeof(cbuf),
+ '\0', false);
replac = cbuf;
}
@@ -1549,7 +1599,8 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
{
/* scan the new replacement */
xpvp = prescan(replac, '\0', pvpbuf,
- sizeof pvpbuf, NULL, NULL, false);
+ sizeof(pvpbuf), NULL, NULL,
+ false);
if (xpvp == NULL)
{
/* prescan already printed error */
@@ -1584,7 +1635,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
for (avp = npvp; *avp++ != NULL;)
continue;
memmove((char *) pvp, (char *) npvp,
- (int) (avp - npvp) * sizeof *avp);
+ (int) (avp - npvp) * sizeof(*avp));
if (tTd(21, 4))
{
@@ -1648,7 +1699,7 @@ callsubr(pvp, reclevel, e)
for (avp = pvp, j = 0; *avp != NULL; avp++, j++)
{
- if ((**avp & 0377) == CALLSUBR && avp[1] != NULL)
+ if ((avp[0][0] & 0377) == CALLSUBR && avp[1] != NULL)
{
stripquotes(avp[1]);
subr = strtorwset(avp[1], NULL, ST_FIND);
@@ -1767,7 +1818,8 @@ map_lookup(smap, key, argvect, pstat, e)
if (tTd(60, 1))
{
- sm_dprintf("map_lookup(%s, %s", smap->s_name, key);
+ sm_dprintf("map_lookup(%s, ", smap->s_name);
+ xputs(sm_debug_file(), key);
if (tTd(60, 5))
{
int i;
@@ -1794,7 +1846,7 @@ map_lookup(smap, key, argvect, pstat, e)
{
char mbuf[320];
- (void) sm_snprintf(mbuf, sizeof mbuf,
+ (void) sm_snprintf(mbuf, sizeof(mbuf),
"%.80s map: lookup (%s): deferred",
smap->s_name,
shortenstring(key, MAXSHORTSTR));
@@ -1919,8 +1971,8 @@ buildaddr(tv, a, flags, e)
maxatom = MAXATOM;
if (a == NULL)
- a = (ADDRESS *) sm_rpool_malloc_x(e->e_rpool, sizeof *a);
- memset((char *) a, '\0', sizeof *a);
+ a = (ADDRESS *) sm_rpool_malloc_x(e->e_rpool, sizeof(*a));
+ memset((char *) a, '\0', sizeof(*a));
hbuf[0] = '\0';
/* set up default error return flags */
@@ -1976,8 +2028,8 @@ badaddr:
if (tv == hostp)
hostp = NULL;
else if (hostp != NULL)
- cataddr(hostp, tv - 1, hbuf, sizeof hbuf, '\0');
- cataddr(++tv, NULL, ubuf, sizeof ubuf, ' ');
+ cataddr(hostp, tv - 1, hbuf, sizeof(hbuf), '\0', false);
+ cataddr(++tv, NULL, ubuf, sizeof(ubuf), ' ', false);
--maxatom;
/* save away the host name */
@@ -2032,7 +2084,7 @@ badaddr:
off = 4;
ubuf[3] = '\0';
}
- (void) sm_strlcpyn(fmt, sizeof fmt, 2, ubuf, " %s");
+ (void) sm_strlcpyn(fmt, sizeof(fmt), 2, ubuf, " %s");
if (off > 4)
usrerr(fmt, ubuf + off);
else if (isenhsc(hbuf, '\0') > 0)
@@ -2119,7 +2171,7 @@ badaddr:
(void) rewrite(tv, 4, 0, e, maxatom);
/* save the result for the command line/RCPT argument */
- cataddr(tv, NULL, ubuf, sizeof ubuf, '\0');
+ cataddr(tv, NULL, ubuf, sizeof(ubuf), '\0', true);
a->q_user = sm_rpool_strdup_x(e->e_rpool, ubuf);
/*
@@ -2150,26 +2202,49 @@ badaddr:
** sz -- size of buf.
** spacesub -- the space separator character; if '\0',
** use SpaceSub.
+** external -- convert to external form?
+** (no metacharacters; METAQUOTEs removed, see below)
**
** Returns:
** none.
**
** Side Effects:
** Destroys buf.
+**
+** Notes:
+** There are two formats for strings: internal and external.
+** The external format is just an eight-bit clean string (no
+** null bytes, everything else OK). The internal format can
+** include sendmail metacharacters. The special character
+** METAQUOTE essentially quotes the character following, stripping
+** it of all special semantics.
+**
+** The cataddr routine needs to be aware of whether it is producing
+** an internal or external form as output (it only takes internal
+** form as input).
+**
+** The parseaddr routine has a similar issue on input, but that
+** is flagged on the basis of which token table is passed in.
*/
void
-cataddr(pvp, evp, buf, sz, spacesub)
+cataddr(pvp, evp, buf, sz, spacesub, external)
char **pvp;
char **evp;
char *buf;
register int sz;
int spacesub;
+ bool external;
{
- bool oatomtok = false;
- bool natomtok = false;
- register int i;
- register char *p;
+ bool oatomtok, natomtok;
+ char *p;
+
+ oatomtok = natomtok = false;
+ if (tTd(59, 14))
+ {
+ sm_dprintf("cataddr(%d) <==", external);
+ printav(sm_debug_file(), pvp);
+ }
if (sz <= 0)
return;
@@ -2186,19 +2261,37 @@ cataddr(pvp, evp, buf, sz, spacesub)
sz -= 2;
while (*pvp != NULL && sz > 0)
{
- natomtok = (TokTypeTab[**pvp & 0xff] == ATM);
+ char *q;
+
+ natomtok = (ExtTokenTab[**pvp & 0xff] == ATM);
if (oatomtok && natomtok)
{
*p++ = spacesub;
if (--sz <= 0)
break;
}
- i = sm_strlcpy(p, *pvp, sz);
- sz -= i;
+ for (q = *pvp; *q != '\0'; )
+ {
+ int c;
+
+ if (--sz <= 0)
+ break;
+ *p++ = c = *q++;
+
+ /*
+ ** If the current character (c) is METAQUOTE and we
+ ** want the "external" form and the next character
+ ** is not NUL, then overwrite METAQUOTE with that
+ ** character (i.e., METAQUOTE ch is changed to
+ ** ch). p[-1] is used because p is advanced (above).
+ */
+
+ if ((c & 0377) == METAQUOTE && external && *q != '\0')
+ p[-1] = *q++;
+ }
if (sz <= 0)
break;
oatomtok = natomtok;
- p += i;
if (pvp++ == evp)
break;
}
@@ -2220,7 +2313,11 @@ cataddr(pvp, evp, buf, sz, spacesub)
usrerr("cataddr: string too long");
#endif
*p = '\0';
+
+ if (tTd(59, 14))
+ sm_dprintf(" cataddr => %s\n", str2prt(buf));
}
+
/*
** SAMEADDR -- Determine if two addresses are the same
**
@@ -2544,7 +2641,11 @@ remotename(name, m, flags, pstat, e)
char addrtype[4];
if (tTd(12, 1))
- sm_dprintf("remotename(%s)\n", name);
+ {
+ sm_dprintf("remotename(");
+ xputs(sm_debug_file(), name);
+ sm_dprintf(")\n");
+ }
/* don't do anything if we are tagging it as special */
if (bitset(RF_SENDERADDR, flags))
@@ -2584,7 +2685,7 @@ remotename(name, m, flags, pstat, e)
** domain will be appended.
*/
- pvp = prescan(name, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL, false);
+ pvp = prescan(name, '\0', pvpbuf, sizeof(pvpbuf), NULL, NULL, false);
if (pvp == NULL)
return name;
if (REWRITE(pvp, 3, e) == EX_TEMPFAIL)
@@ -2658,22 +2759,26 @@ remotename(name, m, flags, pstat, e)
** Now restore the comment information we had at the beginning.
*/
- cataddr(pvp, NULL, lbuf, sizeof lbuf, '\0');
+ cataddr(pvp, NULL, lbuf, sizeof(lbuf), '\0', false);
oldg = macget(&e->e_macro, 'g');
macset(&e->e_macro, 'g', lbuf);
SM_TRY
/* need to make sure route-addrs have <angle brackets> */
if (bitset(RF_CANONICAL, flags) && lbuf[0] == '@')
- expand("<\201g>", buf, sizeof buf, e);
+ expand("<\201g>", buf, sizeof(buf), e);
else
- expand(fancy, buf, sizeof buf, e);
+ expand(fancy, buf, sizeof(buf), e);
SM_FINALLY
macset(&e->e_macro, 'g', oldg);
SM_END_TRY
if (tTd(12, 1))
- sm_dprintf("remotename => `%s'\n", buf);
+ {
+ sm_dprintf("remotename => `");
+ xputs(sm_debug_file(), buf);
+ sm_dprintf("'\n");
+ }
return buf;
}
/*
@@ -2711,7 +2816,8 @@ maplocaluser(a, sendq, aliaslevel, e)
sm_dprintf("maplocaluser: ");
printaddr(sm_debug_file(), a, false);
}
- pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL, false);
+ pvp = prescan(a->q_user, '\0', pvpbuf, sizeof(pvpbuf), NULL, NULL,
+ false);
if (pvp == NULL)
{
if (tTd(29, 9))
@@ -2940,6 +3046,8 @@ dequote_map(map, name, av, statp)
** logl -- logging level.
** host -- NULL or relay host.
** logid -- id for sm_syslog.
+** addr -- if not NULL and ruleset returns $#error:
+** store mailer triple here.
**
** Returns:
** EX_OK -- if the rwset doesn't resolve to $#error
@@ -2947,7 +3055,7 @@ dequote_map(map, name, av, statp)
*/
int
-rscheck(rwset, p1, p2, e, flags, logl, host, logid)
+rscheck(rwset, p1, p2, e, flags, logl, host, logid, addr)
char *rwset;
char *p1;
char *p2;
@@ -2956,6 +3064,7 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid)
int logl;
char *host;
char *logid;
+ ADDRESS *addr;
{
char *volatile buf;
size_t bufsize;
@@ -2964,7 +3073,6 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid)
char **pvp;
int rsno;
bool volatile discard = false;
- auto ADDRESS a1;
bool saveQuickAbort = QuickAbort;
bool saveSuprErrs = SuprErrs;
bool quarantine = false;
@@ -2984,24 +3092,24 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid)
if (p2 != NULL)
{
bufsize = strlen(p1) + strlen(p2) + 2;
- if (bufsize > sizeof buf0)
+ if (bufsize > sizeof(buf0))
buf = sm_malloc_x(bufsize);
else
{
buf = buf0;
- bufsize = sizeof buf0;
+ bufsize = sizeof(buf0);
}
(void) sm_snprintf(buf, bufsize, "%s%c%s", p1, CONDELSE, p2);
}
else
{
bufsize = strlen(p1) + 1;
- if (bufsize > sizeof buf0)
+ if (bufsize > sizeof(buf0))
buf = sm_malloc_x(bufsize);
else
{
buf = buf0;
- bufsize = sizeof buf0;
+ bufsize = sizeof(buf0);
}
(void) sm_strlcpy(buf, p1, bufsize);
}
@@ -3009,8 +3117,9 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid)
{
SuprErrs = true;
QuickAbort = false;
- pvp = prescan(buf, '\0', pvpbuf, sizeof pvpbuf, NULL,
- bitset(RSF_RMCOMM, flags) ? NULL : TokTypeNoC,
+ pvp = prescan(buf, '\0', pvpbuf, sizeof(pvpbuf), NULL,
+ bitset(RSF_RMCOMM, flags) ?
+ IntTokenTab : TokTypeNoC,
bitset(RSF_RMCOMM, flags) ? false : true);
SuprErrs = saveSuprErrs;
if (pvp == NULL)
@@ -3055,7 +3164,7 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid)
else
{
cataddr(&(pvp[5]), NULL, ubuf,
- sizeof ubuf, ' ');
+ sizeof(ubuf), ' ', true);
e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool,
ubuf);
}
@@ -3065,6 +3174,7 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid)
}
else
{
+ auto ADDRESS a1;
int savelogusrerrs = LogUsrErrs;
static bool logged = false;
@@ -3072,6 +3182,12 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid)
saveexitstat = ExitStat;
LogUsrErrs = false;
(void) buildaddr(pvp, &a1, 0, e);
+ if (addr != NULL)
+ {
+ addr->q_mailer = a1.q_mailer;
+ addr->q_user = a1.q_user;
+ addr->q_host = a1.q_host;
+ }
LogUsrErrs = savelogusrerrs;
rstat = ExitStat;
ExitStat = saveexitstat;
@@ -3192,24 +3308,24 @@ rscap(rwset, p1, p2, e, pvp, pvpbuf, size)
if (p2 != NULL)
{
bufsize = strlen(p1) + strlen(p2) + 2;
- if (bufsize > sizeof buf0)
+ if (bufsize > sizeof(buf0))
buf = sm_malloc_x(bufsize);
else
{
buf = buf0;
- bufsize = sizeof buf0;
+ bufsize = sizeof(buf0);
}
(void) sm_snprintf(buf, bufsize, "%s%c%s", p1, CONDELSE, p2);
}
else
{
bufsize = strlen(p1) + 1;
- if (bufsize > sizeof buf0)
+ if (bufsize > sizeof(buf0))
buf = sm_malloc_x(bufsize);
else
{
buf = buf0;
- bufsize = sizeof buf0;
+ bufsize = sizeof(buf0);
}
(void) sm_strlcpy(buf, p1, bufsize);
}
@@ -3217,7 +3333,8 @@ rscap(rwset, p1, p2, e, pvp, pvpbuf, size)
{
SuprErrs = true;
QuickAbort = false;
- *pvp = prescan(buf, '\0', pvpbuf, size, NULL, NULL, false);
+ *pvp = prescan(buf, '\0', pvpbuf, size, NULL, IntTokenTab,
+ false);
if (*pvp != NULL)
rstat = rewrite(*pvp, rsno, 0, e, size);
else
diff --git a/contrib/sendmail/src/queue.c b/contrib/sendmail/src/queue.c
index 6fd2315..e0919d5 100644
--- a/contrib/sendmail/src/queue.c
+++ b/contrib/sendmail/src/queue.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -14,7 +14,7 @@
#include <sendmail.h>
#include <sm/sem.h>
-SM_RCSID("@(#)$Id: queue.c,v 8.954.2.5 2006/07/31 21:44:18 ca Exp $")
+SM_RCSID("@(#)$Id: queue.c,v 8.972 2007/03/29 22:55:17 ca Exp $")
#include <dirent.h>
@@ -147,6 +147,13 @@ static ADDRESS *setctluser __P((char *, int, ENVELOPE *));
static int sm_strshufflecmp __P((char *, char *));
static void init_shuffle_alphabet __P(());
#endif /* _FFR_RHS */
+
+/*
+** Note: workcmpf?() don't use a prototype because it will cause a conflict
+** with the qsort() call (which expects something like
+** int (*compar)(const void *, const void *), not (WORK *, WORK *))
+*/
+
static int workcmpf0();
static int workcmpf1();
static int workcmpf2();
@@ -182,7 +189,7 @@ struct filesys_shared
/* probably kept in shared memory */
static FILESYS FileSys[MAXFILESYS]; /* queue file systems */
-static char *FSPath[MAXFILESYS]; /* pathnames for file systems */
+static const char *FSPath[MAXFILESYS]; /* pathnames for file systems */
#if SM_CONF_SHM
@@ -373,7 +380,7 @@ queueup(e, announce, msync)
newid = (e->e_id == NULL) || !bitset(EF_INQUEUE, e->e_flags);
- (void) sm_strlcpy(tf, queuename(e, NEWQFL_LETTER), sizeof tf);
+ (void) sm_strlcpy(tf, queuename(e, NEWQFL_LETTER), sizeof(tf));
tfp = e->e_lockfp;
if (tfp == NULL && newid)
{
@@ -383,7 +390,7 @@ queueup(e, announce, msync)
** is reused (e.g., because the clock is set back).
*/
- (void) sm_strlcpy(tf, queuename(e, ANYQFL_LETTER), sizeof tf);
+ (void) sm_strlcpy(tf, queuename(e, ANYQFL_LETTER), sizeof(tf));
OPEN_TF;
if (tfd < 0 ||
#if !SM_OPEN_EXLOCK
@@ -502,7 +509,7 @@ queueup(e, announce, msync)
** If there is no data file yet, create one.
*/
- (void) sm_strlcpy(df, queuename(e, DATAFL_LETTER), sizeof df);
+ (void) sm_strlcpy(df, queuename(e, DATAFL_LETTER), sizeof(df));
if (bitset(EF_HAS_DF, e->e_flags))
{
if (e->e_dfp != NULL &&
@@ -563,7 +570,7 @@ queueup(e, announce, msync)
e->e_dfino = ST_INODE(stbuf);
}
e->e_flags |= EF_HAS_DF;
- memset(&mcibuf, '\0', sizeof mcibuf);
+ memset(&mcibuf, '\0', sizeof(mcibuf));
mcibuf.mci_out = dfp;
mcibuf.mci_mailer = FileMailer;
(*e->e_putbody)(&mcibuf, e, NULL);
@@ -764,11 +771,11 @@ queueup(e, announce, msync)
** no effect on the addresses as they are output.
*/
- memset((char *) &nullmailer, '\0', sizeof nullmailer);
+ memset((char *) &nullmailer, '\0', sizeof(nullmailer));
nullmailer.m_re_rwset = nullmailer.m_rh_rwset =
nullmailer.m_se_rwset = nullmailer.m_sh_rwset = -1;
nullmailer.m_eol = "\n";
- memset(&mcibuf, '\0', sizeof mcibuf);
+ memset(&mcibuf, '\0', sizeof(mcibuf));
mcibuf.mci_mailer = &nullmailer;
mcibuf.mci_out = tfp;
@@ -786,9 +793,11 @@ queueup(e, announce, msync)
/* expand macros; if null, don't output header at all */
if (bitset(H_DEFAULT, h->h_flags))
{
- (void) expand(h->h_value, buf, sizeof buf, e);
+ (void) expand(h->h_value, buf, sizeof(buf), e);
if (buf[0] == '\0')
continue;
+ if (buf[0] == ' ' && buf[1] == '\0')
+ continue;
}
/* output this header */
@@ -822,7 +831,7 @@ queueup(e, announce, msync)
if (bitset(H_DEFAULT, h->h_flags) &&
!bitset(H_BINDLATE, h->h_flags))
{
- (void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "%s: %s\n",
+ (void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "%s:%s\n",
h->h_field,
denlstring(buf, false, true));
}
@@ -843,7 +852,7 @@ queueup(e, announce, msync)
}
else
{
- (void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "%s: %s\n",
+ (void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "%s:%s\n",
h->h_field,
denlstring(h->h_value, false,
true));
@@ -878,7 +887,7 @@ queueup(e, announce, msync)
/* rename (locked) tf to be (locked) [qh]f */
(void) sm_strlcpy(qf, queuename(e, ANYQFL_LETTER),
- sizeof qf);
+ sizeof(qf));
if (rename(tf, qf) < 0)
syserr("cannot rename(%s, %s), uid=%d",
tf, qf, (int) geteuid());
@@ -1870,7 +1879,6 @@ run_work_group(wgrp, flags)
time_t now;
bool full, more;
SM_RPOOL_T *rpool;
- extern void rmexpstab __P((void));
extern ENVELOPE BlankEnvelope;
extern SIGFUNC_DECL reapchild __P((int));
@@ -2476,9 +2484,9 @@ gatherq(qgrp, qdir, doall, full, more)
wn = WorkListCount - 1;
num_ent = 0;
if (qdir == NOQDIR)
- (void) sm_strlcpy(qd, ".", sizeof qd);
+ (void) sm_strlcpy(qd, ".", sizeof(qd));
else
- (void) sm_strlcpyn(qd, sizeof qd, 2,
+ (void) sm_strlcpyn(qd, sizeof(qd), 2,
Queue[qgrp]->qg_qpaths[qdir].qp_name,
(bitset(QP_SUBQF,
Queue[qgrp]->qg_qpaths[qdir].qp_subdirs)
@@ -2617,7 +2625,7 @@ gatherq(qgrp, qdir, doall, full, more)
SM_ASSERT(wn >= 0);
w = &WorkList[wn];
- (void) sm_strlcpyn(qf, sizeof qf, 3, qd, "/", d->d_name);
+ (void) sm_strlcpyn(qf, sizeof(qf), 3, qd, "/", d->d_name);
if (stat(qf, &sbuf) < 0)
{
if (errno != ENOENT)
@@ -2714,7 +2722,7 @@ gatherq(qgrp, qdir, doall, full, more)
i |= NEED_QUARANTINE;
while (cf != NULL && i != 0 &&
sm_io_fgets(cf, SM_TIME_DEFAULT, lbuf,
- sizeof lbuf) != NULL)
+ sizeof(lbuf)) != NULL)
{
int c;
time_t age;
@@ -2947,7 +2955,7 @@ sortq(max)
** based on host name, lock status, and priority.
*/
- qsort((char *) WorkList, wc, sizeof *WorkList, workcmpf1);
+ qsort((char *) WorkList, wc, sizeof(*WorkList), workcmpf1);
/*
** If one message to host is locked, "lock" all messages
@@ -2983,7 +2991,7 @@ sortq(max)
** based on lock status, host name, and priority.
*/
- qsort((char *) WorkList, wc, sizeof *WorkList, workcmpf2);
+ qsort((char *) WorkList, wc, sizeof(*WorkList), workcmpf2);
}
else if (QueueSortOrder == QSO_BYTIME)
{
@@ -2991,7 +2999,7 @@ sortq(max)
** Simple sort based on submission time only.
*/
- qsort((char *) WorkList, wc, sizeof *WorkList, workcmpf3);
+ qsort((char *) WorkList, wc, sizeof(*WorkList), workcmpf3);
}
else if (QueueSortOrder == QSO_BYFILENAME)
{
@@ -2999,7 +3007,7 @@ sortq(max)
** Sort based on queue filename.
*/
- qsort((char *) WorkList, wc, sizeof *WorkList, workcmpf4);
+ qsort((char *) WorkList, wc, sizeof(*WorkList), workcmpf4);
}
else if (QueueSortOrder == QSO_RANDOM)
{
@@ -3012,7 +3020,7 @@ sortq(max)
randi = get_rand_mod(MAXQFNAME);
if (randi < 2)
randi = 3;
- qsort((char *) WorkList, wc, sizeof *WorkList, workcmpf5);
+ qsort((char *) WorkList, wc, sizeof(*WorkList), workcmpf5);
}
else if (QueueSortOrder == QSO_BYMODTIME)
{
@@ -3021,7 +3029,7 @@ sortq(max)
** This puts the oldest items first.
*/
- qsort((char *) WorkList, wc, sizeof *WorkList, workcmpf6);
+ qsort((char *) WorkList, wc, sizeof(*WorkList), workcmpf6);
}
#if _FFR_RHS
else if (QueueSortOrder == QSO_BYSHUFFLE)
@@ -3031,7 +3039,7 @@ sortq(max)
*/
init_shuffle_alphabet();
- qsort((char *) WorkList, wc, sizeof *WorkList, workcmpf7);
+ qsort((char *) WorkList, wc, sizeof(*WorkList), workcmpf7);
}
#endif /* _FFR_RHS */
else if (QueueSortOrder == QSO_BYPRIORITY)
@@ -3040,7 +3048,7 @@ sortq(max)
** Simple sort based on queue priority only.
*/
- qsort((char *) WorkList, wc, sizeof *WorkList, workcmpf0);
+ qsort((char *) WorkList, wc, sizeof(*WorkList), workcmpf0);
}
/* else don't sort at all */
@@ -3057,7 +3065,7 @@ sortq(max)
for (i = wc; --i >= 0; )
{
- w = (WORK *) xalloc(sizeof *w);
+ w = (WORK *) xalloc(sizeof(*w));
w->w_qgrp = WorkList[i].w_qgrp;
w->w_qdir = WorkList[i].w_qdir;
w->w_name = WorkList[i].w_name;
@@ -3125,7 +3133,7 @@ grow_wlist(qgrp, qdir)
sm_dprintf("grow_wlist: WorkListSize=%d\n", WorkListSize);
if (WorkList == NULL)
{
- WorkList = (WORK *) xalloc((sizeof *WorkList) *
+ WorkList = (WORK *) xalloc((sizeof(*WorkList)) *
(QUEUESEGSIZE + 1));
WorkListSize = QUEUESEGSIZE;
}
@@ -3898,13 +3906,15 @@ readqf(e, openonly)
char *err;
char qf[MAXPATHLEN];
char buf[MAXLINE];
+ int bufsize;
/*
** Read and process the file.
*/
+ SM_REQUIRE(e != NULL);
bp = NULL;
- (void) sm_strlcpy(qf, queuename(e, ANYQFL_LETTER), sizeof qf);
+ (void) sm_strlcpy(qf, queuename(e, ANYQFL_LETTER), sizeof(qf));
qfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, qf, SM_IO_RDWR_B, NULL);
if (qfp == NULL)
{
@@ -4118,7 +4128,8 @@ readqf(e, openonly)
#endif /* _FFR_QUEUE_MACRO */
e->e_dfino = -1;
e->e_msgsize = -1;
- while ((bp = fgetfolded(buf, sizeof buf, qfp)) != NULL)
+ while (bufsize = sizeof(buf),
+ (bp = fgetfolded(buf, &bufsize, qfp)) != NULL)
{
unsigned long qflags;
ADDRESS *q;
@@ -4296,6 +4307,8 @@ readqf(e, openonly)
howlong);
e->e_id = NULL;
unlockqueue(e);
+ if (bp != buf)
+ sm_free(bp);
return false;
}
macdefine(&e->e_macro, A_TEMP,
@@ -4471,10 +4484,7 @@ readqf(e, openonly)
}
if (bp != buf)
- {
- sm_free(bp); /* XXX */
- bp = NULL;
- }
+ SM_FREE(bp);
}
/*
@@ -4496,6 +4506,17 @@ readqf(e, openonly)
(void) sm_io_close(qfp, SM_TIME_DEFAULT);
return false;
}
+
+#if _FFR_QF_PARANOIA
+ /* Check to make sure key fields were read */
+ if (e->e_from.q_mailer == NULL)
+ {
+ syserr("readqf: %s: sender not specified in queue file", qf);
+ (void) sm_io_close(qfp, SM_TIME_DEFAULT);
+ return false;
+ }
+ /* other checks? */
+#endif /* _FFR_QF_PARANOIA */
/* possibly set ${dsn_ret} macro */
if (bitset(EF_RET_PARAM, e->e_flags))
@@ -4528,7 +4549,7 @@ readqf(e, openonly)
e->e_msgsize = st.st_size + hdrsize;
e->e_dfdev = st.st_dev;
e->e_dfino = ST_INODE(st);
- (void) sm_snprintf(buf, sizeof buf, "%ld",
+ (void) sm_snprintf(buf, sizeof(buf), "%ld",
e->e_msgsize);
macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"),
buf);
@@ -4547,11 +4568,8 @@ readqf(e, openonly)
** queueup() with bogus data.
*/
- if (bp != NULL && bp != buf)
- {
- sm_free(bp); /* XXX */
- bp = NULL;
- }
+ if (bp != buf)
+ SM_FREE(bp);
if (qfp != NULL)
(void) sm_io_close(qfp, SM_TIME_DEFAULT);
e->e_lockfp = NULL;
@@ -4573,6 +4591,8 @@ readqf(e, openonly)
** Prints a string on stdout.
*/
+static void prtstr __P((char *, int));
+
static void
prtstr(s, ml)
char *s;
@@ -4749,17 +4769,17 @@ print_single_queue(qgrp, qdir)
if (qdir == NOQDIR)
{
- (void) sm_strlcpy(qd, ".", sizeof qd);
- (void) sm_strlcpy(qddf, ".", sizeof qddf);
+ (void) sm_strlcpy(qd, ".", sizeof(qd));
+ (void) sm_strlcpy(qddf, ".", sizeof(qddf));
}
else
{
- (void) sm_strlcpyn(qd, sizeof qd, 2,
+ (void) sm_strlcpyn(qd, sizeof(qd), 2,
Queue[qgrp]->qg_qpaths[qdir].qp_name,
(bitset(QP_SUBQF,
Queue[qgrp]->qg_qpaths[qdir].qp_subdirs)
? "/qf" : ""));
- (void) sm_strlcpyn(qddf, sizeof qddf, 2,
+ (void) sm_strlcpyn(qddf, sizeof(qddf), 2,
Queue[qgrp]->qg_qpaths[qdir].qp_name,
(bitset(QP_SUBDF,
Queue[qgrp]->qg_qpaths[qdir].qp_subdirs)
@@ -4852,7 +4872,7 @@ print_single_queue(qgrp, qdir)
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%13s",
w->w_name + 2);
- (void) sm_strlcpyn(qf, sizeof qf, 3, qd, "/", w->w_name);
+ (void) sm_strlcpyn(qf, sizeof(qf), 3, qd, "/", w->w_name);
f = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, qf, SM_IO_RDONLY_B,
NULL);
if (f == NULL)
@@ -4871,7 +4891,7 @@ print_single_queue(qgrp, qdir)
continue;
}
w->w_name[0] = DATAFL_LETTER;
- (void) sm_strlcpyn(qf, sizeof qf, 3, qddf, "/", w->w_name);
+ (void) sm_strlcpyn(qf, sizeof(qf), 3, qddf, "/", w->w_name);
if (stat(qf, &st) >= 0)
dfsize = st.st_size;
else
@@ -4919,7 +4939,7 @@ print_single_queue(qgrp, qdir)
quarmsg[0] = '\0';
statmsg[0] = bodytype[0] = '\0';
qfver = 0;
- while (sm_io_fgets(f, SM_TIME_DEFAULT, buf, sizeof buf) != NULL)
+ while (sm_io_fgets(f, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL)
{
register int i;
register char *p;
@@ -4935,22 +4955,22 @@ print_single_queue(qgrp, qdir)
break;
case 'M': /* error message */
- if ((i = strlen(&buf[1])) >= sizeof statmsg)
- i = sizeof statmsg - 1;
+ if ((i = strlen(&buf[1])) >= sizeof(statmsg))
+ i = sizeof(statmsg) - 1;
memmove(statmsg, &buf[1], i);
statmsg[i] = '\0';
break;
case 'q': /* quarantine reason */
- if ((i = strlen(&buf[1])) >= sizeof quarmsg)
- i = sizeof quarmsg - 1;
+ if ((i = strlen(&buf[1])) >= sizeof(quarmsg))
+ i = sizeof(quarmsg) - 1;
memmove(quarmsg, &buf[1], i);
quarmsg[i] = '\0';
break;
case 'B': /* body type */
- if ((i = strlen(&buf[1])) >= sizeof bodytype)
- i = sizeof bodytype - 1;
+ if ((i = strlen(&buf[1])) >= sizeof(bodytype))
+ i = sizeof(bodytype) - 1;
memmove(bodytype, &buf[1], i);
bodytype[i] = '\0';
break;
@@ -5206,7 +5226,7 @@ queuename(e, type)
/* xf files always have a valid qd and qg picked above */
if ((qd == NOQDIR || qg == NOQGRP) && type != XSCRPT_LETTER)
- (void) sm_strlcpyn(buf, sizeof buf, 2, pref, e->e_id);
+ (void) sm_strlcpyn(buf, sizeof(buf), 2, pref, e->e_id);
else
{
switch (type)
@@ -5234,7 +5254,7 @@ queuename(e, type)
sm_abort("queuename: bad queue file type %d", type);
}
- (void) sm_strlcpyn(buf, sizeof buf, 4,
+ (void) sm_strlcpyn(buf, sizeof(buf), 4,
Queue[qg]->qg_qpaths[qd].qp_name,
sub, pref, e->e_id);
}
@@ -5361,7 +5381,7 @@ assign_queueid(e)
idbuf[5] = QueueIdChars[tm->tm_sec % QIC_LEN_R];
idbuf[6] = QueueIdChars[seq / QIC_LEN];
idbuf[7] = QueueIdChars[seq % QIC_LEN];
- (void) sm_snprintf(&idbuf[8], sizeof idbuf - 8, "%06d",
+ (void) sm_snprintf(&idbuf[8], sizeof(idbuf) - 8, "%06d",
(int) LastQueuePid);
e->e_id = sm_rpool_strdup_x(e->e_rpool, idbuf);
macdefine(&e->e_macro, A_PERM, 'i', e->e_id);
@@ -5484,8 +5504,8 @@ setctluser(user, qfver, e)
** Set up addr fields for controlling user.
*/
- a = (ADDRESS *) sm_rpool_malloc_x(e->e_rpool, sizeof *a);
- memset((char *) a, '\0', sizeof *a);
+ a = (ADDRESS *) sm_rpool_malloc_x(e->e_rpool, sizeof(*a));
+ memset((char *) a, '\0', sizeof(*a));
if (*user == ':')
{
@@ -5558,7 +5578,7 @@ loseqfile(e, why)
if (e == NULL || e->e_id == NULL)
return;
p = queuename(e, ANYQFL_LETTER);
- if (sm_strlcpy(buf, p, sizeof buf) >= sizeof buf)
+ if (sm_strlcpy(buf, p, sizeof(buf)) >= sizeof(buf))
return;
if (!bitset(EF_INQUEUE, e->e_flags))
queueup(e, false, true);
@@ -5633,7 +5653,7 @@ qid_printname(e)
if (e->e_qdir == NOQDIR)
return id;
- (void) sm_snprintf(idbuf, sizeof idbuf, "%.32s/%s",
+ (void) sm_snprintf(idbuf, sizeof(idbuf), "%.32s/%s",
Queue[e->e_qgrp]->qg_qpaths[e->e_qdir].qp_name,
id);
return idbuf;
@@ -5665,7 +5685,7 @@ qid_printqueue(qgrp, qdir)
else
subdir = Queue[qgrp]->qg_qpaths[qdir].qp_name;
- (void) sm_strlcpyn(dir, sizeof dir, 4,
+ (void) sm_strlcpyn(dir, sizeof(dir), 4,
Queue[qgrp]->qg_qdir,
subdir == NULL ? "" : "/",
subdir == NULL ? "" : subdir,
@@ -5871,6 +5891,8 @@ setnewqueue(e)
** is it a queue directory?
*/
+static bool chkqdir __P((char *, long));
+
static bool
chkqdir(name, sff)
char *name;
@@ -6018,11 +6040,11 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
}
/* qpath: directory of current workgroup */
- len = sm_strlcpy(qpath, qg->qg_qdir, sizeof qpath);
- if (len >= sizeof qpath)
+ len = sm_strlcpy(qpath, qg->qg_qdir, sizeof(qpath));
+ if (len >= sizeof(qpath))
{
syserr("QueuePath %.256s too long (%d max)",
- qg->qg_qdir, (int) sizeof qpath);
+ qg->qg_qdir, (int) sizeof(qpath));
ExitStat = EX_CONFIG;
return qn;
}
@@ -6042,11 +6064,11 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
{
/* Copy subdirectory into prefix for later use */
- if (sm_strlcpy(prefix, qg->qg_qdir + blen, sizeof prefix) >=
- sizeof prefix)
+ if (sm_strlcpy(prefix, qg->qg_qdir + blen, sizeof(prefix)) >=
+ sizeof(prefix))
{
syserr("QueuePath %.256s too long (%d max)",
- qg->qg_qdir, (int) sizeof qpath);
+ qg->qg_qdir, (int) sizeof(qpath));
ExitStat = EX_CONFIG;
return qn;
}
@@ -6083,7 +6105,7 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
** Change to //foo*
*/
- (void) sm_strlcpy(qpath + 1, qpath, sizeof qpath - 1);
+ (void) sm_strlcpy(qpath + 1, qpath, sizeof(qpath) - 1);
++cp;
}
delim = cp;
@@ -6096,8 +6118,8 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
** so they can be opened without chdir().
*/
- off = sm_strlcpyn(relpath, sizeof relpath, 2, prefix, "/");
- SM_ASSERT(off < sizeof relpath);
+ off = sm_strlcpyn(relpath, sizeof(relpath), 2, prefix, "/");
+ SM_ASSERT(off < sizeof(relpath));
if (tTd(41, 2))
sm_dprintf("multiqueue_cache: prefix=\"%s%s\"\n",
@@ -6136,6 +6158,11 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
}
while ((d = readdir(dp)) != NULL)
{
+ /* Skip . and .. directories */
+ if (strcmp(d->d_name, ".") == 0 ||
+ strcmp(d->d_name, "..") == 0)
+ continue;
+
i = strlen(d->d_name);
if (i < len || strncmp(d->d_name, cp, len) != 0)
{
@@ -6156,14 +6183,14 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
if (qg->qg_qpaths == NULL)
{
slotsleft = INITIAL_SLOTS;
- qg->qg_qpaths = (QPATHS *)xalloc((sizeof *qg->qg_qpaths) *
+ qg->qg_qpaths = (QPATHS *)xalloc((sizeof(*qg->qg_qpaths)) *
slotsleft);
qg->qg_numqueues = 0;
}
else if (slotsleft < 1)
{
qg->qg_qpaths = (QPATHS *)sm_realloc((char *)qg->qg_qpaths,
- (sizeof *qg->qg_qpaths) *
+ (sizeof(*qg->qg_qpaths)) *
(qg->qg_numqueues +
ADD_SLOTS));
if (qg->qg_qpaths == NULL)
@@ -6178,7 +6205,7 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
qg->qg_qpaths[qg->qg_numqueues].qp_subdirs = QP_NOSUB;
#define CHKRSUBDIR(name, flag) \
- (void) sm_strlcpyn(subdir, sizeof subdir, 3, relpath, "/", name); \
+ (void) sm_strlcpyn(subdir, sizeof(subdir), 3, relpath, "/", name); \
if (chkqdir(subdir, sff)) \
qg->qg_qpaths[qg->qg_numqueues].qp_subdirs |= flag; \
else
@@ -6217,7 +6244,7 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
}
if (qg->qg_numqueues == 0)
{
- qg->qg_qpaths = (QPATHS *) xalloc(sizeof *qg->qg_qpaths);
+ qg->qg_qpaths = (QPATHS *) xalloc(sizeof(*qg->qg_qpaths));
/* test path to get warning messages */
i = safedirpath(qpath, RunAsUid, RunAsGid, NULL, sff, 0, 0);
@@ -6236,7 +6263,7 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
/* check subdirs */
#define CHKSUBDIR(name, flag) \
- (void) sm_strlcpyn(subdir, sizeof subdir, 3, qg->qg_qdir, "/", name); \
+ (void) sm_strlcpyn(subdir, sizeof(subdir), 3, qg->qg_qdir, "/", name); \
if (chkqdir(subdir, sff)) \
qg->qg_qpaths[0].qp_subdirs |= flag; \
else
@@ -6290,7 +6317,7 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
** FSF_NOT_FOUND: not in list
*/
-static short filesys_find __P((char *, char *, bool));
+static short filesys_find __P((const char *, const char *, bool));
#define FSF_NOT_FOUND (-1)
#define FSF_STAT_FAIL (-2)
@@ -6298,8 +6325,8 @@ static short filesys_find __P((char *, char *, bool));
static short
filesys_find(name, path, add)
- char *name;
- char *path;
+ const char *name;
+ const char *path;
bool add;
{
struct stat st;
@@ -6378,7 +6405,7 @@ filesys_setup(add)
QPATHS *qp = &Queue[i]->qg_qpaths[j];
char qddf[MAXPATHLEN];
- (void) sm_strlcpyn(qddf, sizeof qddf, 2, qp->qp_name,
+ (void) sm_strlcpyn(qddf, sizeof(qddf), 2, qp->qp_name,
(bitset(QP_SUBDF, qp->qp_subdirs)
? "/df" : ""));
fs = filesys_find(qp->qp_name, qddf, add);
@@ -6419,6 +6446,12 @@ filesys_update()
static time_t nextupdate = 0;
#if SM_CONF_SHM
+ /*
+ ** Only the daemon updates the shared memory, i.e.,
+ ** if shared memory is available but the pid is not the
+ ** one of the daemon, then don't do anything.
+ */
+
if (ShmId != SM_SHM_NO_ID && DaemonPid != CurrentPid)
return;
#endif /* SM_CONF_SHM */
@@ -6486,7 +6519,6 @@ filesys_free(fsize)
}
#endif /* _FFR_ANY_FREE_FS */
-#if _FFR_CONTROL_MSTAT
/*
** DISK_STATUS -- show amount of free space in queue directories
**
@@ -6524,7 +6556,6 @@ disk_status(out, prefix)
free);
}
}
-#endif /* _FFR_CONTROL_MSTAT */
#if SM_CONF_SHM
@@ -6666,8 +6697,6 @@ upd_qs(e, count, space, where)
}
-#if _FFR_SELECT_SHM
-
static bool write_key_file __P((char *, long));
static long read_key_file __P((char *, long));
@@ -6771,7 +6800,6 @@ read_key_file(keypath, key)
}
return key;
}
-#endif /* _FFR_SELECT_SHM */
/*
** INIT_SHM -- initialize shared memory structure
@@ -6802,17 +6830,13 @@ init_shm(qn, owner, hash)
int i;
int count;
int save_errno;
-#if _FFR_SELECT_SHM
bool keyselect;
-#endif /* _FFR_SELECT_SHM */
PtrFileSys = &FileSys[0];
PNumFileSys = &Numfilesys;
-#if _FFR_SELECT_SHM
/* if this "key" is specified: select one yourself */
-# define SEL_SHM_KEY ((key_t) -1)
-# define FIRST_SHM_KEY 25
-#endif /* _FFR_SELECT_SHM */
+#define SEL_SHM_KEY ((key_t) -1)
+#define FIRST_SHM_KEY 25
/* This allows us to disable shared memory at runtime. */
if (ShmKey == 0)
@@ -6820,7 +6844,6 @@ init_shm(qn, owner, hash)
count = 0;
shms = SM_T_SIZE + qn * sizeof(QUEUE_SHM_T);
-#if _FFR_SELECT_SHM
keyselect = ShmKey == SEL_SHM_KEY;
if (keyselect)
{
@@ -6828,13 +6851,16 @@ init_shm(qn, owner, hash)
ShmKey = FIRST_SHM_KEY;
else
{
+ errno = 0;
ShmKey = read_key_file(ShmKeyFile, ShmKey);
keyselect = false;
if (ShmKey == SEL_SHM_KEY)
+ {
+ save_errno = (errno != 0) ? errno : EINVAL;
goto error;
+ }
}
}
-#endif /* _FFR_SELECT_SHM */
for (;;)
{
/* allow read/write access for group? */
@@ -6846,7 +6872,6 @@ init_shm(qn, owner, hash)
break;
if (++count >= 3)
{
-#if _FFR_SELECT_SHM
if (keyselect)
{
++ShmKey;
@@ -6856,23 +6881,19 @@ init_shm(qn, owner, hash)
break;
continue;
}
-#endif /* _FFR_SELECT_SHM */
break;
}
-#if _FFR_SELECT_SHM
+
/* only sleep if we are at the first key */
if (!keyselect || ShmKey == SEL_SHM_KEY)
-#endif /* _FFR_SELECT_SHM */
- sleep(count);
+ sleep(count);
}
if (Pshm != NULL)
{
int *p;
-#if _FFR_SELECT_SHM
if (keyselect)
(void) write_key_file(ShmKeyFile, (long) ShmKey);
-#endif /* _FFR_SELECT_SHM */
if (owner && RunAsUid != 0)
{
i = sm_shmsetowner(ShmId, RunAsUid, RunAsGid, 0660);
@@ -6942,10 +6963,10 @@ init_shm(qn, owner, hash)
/*
-** SETUP_QUEUES -- setup all queue groups
+** SETUP_QUEUES -- set up all queue groups
**
** Parameters:
-** owner -- owner of shared memory.
+** owner -- owner of shared memory?
**
** Returns:
** none.
@@ -6975,13 +6996,13 @@ setup_queues(owner)
hashval = 0;
errno = 0;
- len = sm_strlcpy(basedir, QueueDir, sizeof basedir);
+ len = sm_strlcpy(basedir, QueueDir, sizeof(basedir));
/* Provide space for trailing '/' */
- if (len >= sizeof basedir - 1)
+ if (len >= sizeof(basedir) - 1)
{
syserr("QueueDirectory: path too long: %d, max %d",
- len, (int) sizeof basedir - 1);
+ len, (int) sizeof(basedir) - 1);
ExitStat = EX_CONFIG;
return;
}
@@ -7232,8 +7253,8 @@ makequeue(line, qdef)
char fcode;
/* allocate a queue and set up defaults */
- qg = (QUEUEGRP *) xalloc(sizeof *qg);
- memset((char *) qg, '\0', sizeof *qg);
+ qg = (QUEUEGRP *) xalloc(sizeof(*qg));
+ memset((char *) qg, '\0', sizeof(*qg));
if (line[0] == '\0')
{
@@ -7743,8 +7764,8 @@ dup_df(old, new)
SM_REQUIRE(ISVALIDQGRP(old->e_qgrp) && ISVALIDQDIR(old->e_qdir));
SM_REQUIRE(ISVALIDQGRP(new->e_qgrp) && ISVALIDQDIR(new->e_qdir));
- (void) sm_strlcpy(opath, queuename(old, DATAFL_LETTER), sizeof opath);
- (void) sm_strlcpy(npath, queuename(new, DATAFL_LETTER), sizeof npath);
+ (void) sm_strlcpy(opath, queuename(old, DATAFL_LETTER), sizeof(opath));
+ (void) sm_strlcpy(npath, queuename(new, DATAFL_LETTER), sizeof(npath));
if (old->e_dfp != NULL)
{
@@ -7789,7 +7810,7 @@ dup_df(old, new)
new->e_dfqgrp = old->e_dfqgrp;
new->e_dfqdir = old->e_dfqdir;
- (void) sm_strlcpy(npath, queuename(new, DATAFL_LETTER), sizeof npath);
+ (void) sm_strlcpy(npath, queuename(new, DATAFL_LETTER), sizeof(npath));
if (link(opath, npath) == 0)
{
new->e_flags |= EF_HAS_DF;
@@ -7830,7 +7851,7 @@ split_env(e, sendqueue, qgrp, qdir)
{
ENVELOPE *ee;
- ee = (ENVELOPE *) sm_rpool_malloc_x(e->e_rpool, sizeof *ee);
+ ee = (ENVELOPE *) sm_rpool_malloc_x(e->e_rpool, sizeof(*ee));
STRUCTCOPY(*e, *ee);
ee->e_message = NULL; /* XXX use original message? */
ee->e_id = NULL;
@@ -7933,6 +7954,7 @@ e_filesys_compare(p1, p2)
return 0;
}
+static int split_across_queue_groups __P((ENVELOPE *));
static int
split_across_queue_groups(e)
ENVELOPE *e;
@@ -8423,14 +8445,15 @@ quarantine_queue_item(qgrp, qdir, e, reason)
MODE_T oldumask = 0;
SM_FILE_T *oldqfp, *tempqfp;
char *bp;
+ int bufsize;
char oldqf[MAXPATHLEN];
char tempqf[MAXPATHLEN];
char newqf[MAXPATHLEN];
char buf[MAXLINE];
oldtype = queue_letter(e, ANYQFL_LETTER);
- (void) sm_strlcpy(oldqf, queuename(e, ANYQFL_LETTER), sizeof oldqf);
- (void) sm_strlcpy(tempqf, queuename(e, NEWQFL_LETTER), sizeof tempqf);
+ (void) sm_strlcpy(oldqf, queuename(e, ANYQFL_LETTER), sizeof(oldqf));
+ (void) sm_strlcpy(tempqf, queuename(e, NEWQFL_LETTER), sizeof(tempqf));
/*
** Instead of duplicating all the open
@@ -8491,7 +8514,8 @@ quarantine_queue_item(qgrp, qdir, e, reason)
}
/* Copy the data over, changing the quarantine reason */
- while ((bp = fgetfolded(buf, sizeof buf, oldqfp)) != NULL)
+ while (bufsize = sizeof(buf),
+ (bp = fgetfolded(buf, &bufsize, oldqfp)) != NULL)
{
if (tTd(40, 4))
sm_dprintf("+++++ %s\n", bp);
@@ -8510,7 +8534,6 @@ quarantine_queue_item(qgrp, qdir, e, reason)
}
sm_syslog(LOG_INFO, e->e_id, "unquarantine");
dirty = true;
- continue;
}
else if (strcmp(reason, &bp[1]) == 0)
{
@@ -8581,6 +8604,8 @@ quarantine_queue_item(qgrp, qdir, e, reason)
"%s\n", bp);
break;
}
+ if (bp != buf)
+ sm_free(bp);
}
/* Make sure we read the whole old file */
@@ -8633,12 +8658,12 @@ quarantine_queue_item(qgrp, qdir, e, reason)
if (oldtype == newtype)
{
/* going to rename tempqf to oldqf */
- (void) sm_strlcpy(newqf, oldqf, sizeof newqf);
+ (void) sm_strlcpy(newqf, oldqf, sizeof(newqf));
}
else
{
/* going to rename tempqf to new name based on newtype */
- (void) sm_strlcpy(newqf, queuename(e, newtype), sizeof newqf);
+ (void) sm_strlcpy(newqf, queuename(e, newtype), sizeof(newqf));
}
save_errno = 0;
diff --git a/contrib/sendmail/src/ratectrl.c b/contrib/sendmail/src/ratectrl.c
index 3185eae..22f9803 100644
--- a/contrib/sendmail/src/ratectrl.c
+++ b/contrib/sendmail/src/ratectrl.c
@@ -45,7 +45,7 @@
*/
#include <sendmail.h>
-SM_RCSID("@(#)$Id: ratectrl.c,v 8.10 2005/06/14 23:07:23 ca Exp $")
+SM_RCSID("@(#)$Id: ratectrl.c,v 8.11 2006/08/15 23:24:57 ca Exp $")
/*
** stuff included - given some warnings (inet_ntoa)
@@ -245,7 +245,7 @@ client_rate(now, saddr, update)
if (!CHashAryOK)
{
- memset(CHashAry, 0, sizeof (CHashAry));
+ memset(CHashAry, 0, sizeof(CHashAry));
CHashAryOK = true;
}
@@ -386,7 +386,7 @@ client_rate(now, saddr, update)
#endif /* NETINET6 */
#if 1
memset(chBest->ch_Times, '\0',
- sizeof (chBest->ch_Times));
+ sizeof(chBest->ch_Times));
#endif /* 1 */
}
diff --git a/contrib/sendmail/src/readcf.c b/contrib/sendmail/src/readcf.c
index f4a3759..bd57d80 100644
--- a/contrib/sendmail/src/readcf.c
+++ b/contrib/sendmail/src/readcf.c
@@ -12,8 +12,9 @@
*/
#include <sendmail.h>
+#include <sm/sendmail.h>
-SM_RCSID("@(#)$Id: readcf.c,v 8.651 2006/03/02 19:17:09 ca Exp $")
+SM_RCSID("@(#)$Id: readcf.c,v 8.663 2006/10/05 20:58:59 ca Exp $")
#if NETINET || NETINET6
# include <arpa/inet.h>
@@ -103,6 +104,7 @@ readcf(cfname, safe, e)
long sff = SFF_OPENASROOT;
struct stat statb;
char buf[MAXLINE];
+ int bufsize;
char exbuf[MAXLINE];
char pvpbuf[MAXLINE + MAXATOM];
static char *null_list[1] = { NULL };
@@ -148,8 +150,11 @@ readcf(cfname, safe, e)
xla_zero();
#endif /* XLA */
- while ((bp = fgetfolded(buf, sizeof buf, cf)) != NULL)
+ while (bufsize = sizeof(buf),
+ (bp = fgetfolded(buf, &bufsize, cf)) != NULL)
{
+ char *nbp;
+
if (bp[0] == '#')
{
if (bp != buf)
@@ -158,7 +163,10 @@ readcf(cfname, safe, e)
}
/* do macro expansion mappings */
- translate_dollars(bp);
+ nbp = translate_dollars(bp, bp, &bufsize);
+ if (nbp != bp && bp != buf)
+ sm_free(bp);
+ bp = nbp;
/* interpret this line */
errno = 0;
@@ -187,21 +195,21 @@ readcf(cfname, safe, e)
if (rwp == NULL)
{
RewriteRules[ruleset] = rwp =
- (struct rewrite *) xalloc(sizeof *rwp);
+ (struct rewrite *) xalloc(sizeof(*rwp));
}
else
{
- rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp);
+ rwp->r_next = (struct rewrite *) xalloc(sizeof(*rwp));
rwp = rwp->r_next;
}
rwp->r_next = NULL;
/* expand and save the LHS */
*p = '\0';
- expand(&bp[1], exbuf, sizeof exbuf, e);
+ expand(&bp[1], exbuf, sizeof(exbuf), e);
rwp->r_lhs = prescan(exbuf, '\t', pvpbuf,
- sizeof pvpbuf, NULL,
- ConfigLevel >= 9 ? TokTypeNoC : NULL,
+ sizeof(pvpbuf), NULL,
+ ConfigLevel >= 9 ? TokTypeNoC : IntTokenTab,
true);
nfuzzy = 0;
if (rwp->r_lhs != NULL)
@@ -216,7 +224,7 @@ readcf(cfname, safe, e)
char *botch;
botch = NULL;
- switch (**ap & 0377)
+ switch (ap[0][0] & 0377)
{
case MATCHZANY:
case MATCHANY:
@@ -227,7 +235,7 @@ readcf(cfname, safe, e)
break;
case MATCHREPL:
- botch = "$0-$9";
+ botch = "$1-$9";
break;
case CANONUSER:
@@ -286,10 +294,10 @@ readcf(cfname, safe, e)
while (*p != '\0' && *p != '\t')
p++;
*p = '\0';
- expand(q, exbuf, sizeof exbuf, e);
+ expand(q, exbuf, sizeof(exbuf), e);
rwp->r_rhs = prescan(exbuf, '\t', pvpbuf,
- sizeof pvpbuf, NULL,
- ConfigLevel >= 9 ? TokTypeNoC : NULL,
+ sizeof(pvpbuf), NULL,
+ ConfigLevel >= 9 ? TokTypeNoC : IntTokenTab,
true);
if (rwp->r_rhs != NULL)
{
@@ -312,13 +320,14 @@ readcf(cfname, safe, e)
char *botch;
botch = NULL;
- switch (**ap & 0377)
+ switch (ap[0][0] & 0377)
{
case MATCHREPL:
- if ((*ap)[1] <= '0' || (*ap)[1] > nfuzzy)
+ if (ap[0][1] <= '0' ||
+ ap[0][1] > nfuzzy)
{
syserr("replacement $%c out of bounds",
- (*ap)[1]);
+ ap[0][1]);
}
break;
@@ -354,34 +363,34 @@ readcf(cfname, safe, e)
/* FALLTHROUGH */
case LOOKUPBEGIN:
/* see above... */
- if ((**ap & 0377) == LOOKUPBEGIN)
+ if ((ap[0][0] & 0377) == LOOKUPBEGIN)
endtoken = LOOKUPEND;
if (inmap)
syserr("cannot nest map lookups");
inmap = true;
args = 0;
#if _FFR_EXTRA_MAP_CHECK
- if (*(ap + 1) == NULL)
+ if (ap[1] == NULL)
{
syserr("syntax error in map lookup");
break;
}
- nexttoken = **(ap + 1) & 0377;
+ nexttoken = ap[1][0] & 0377;
if (nexttoken == CANONHOST ||
nexttoken == CANONUSER ||
- nexttoken == endtoken)
+ nexttoken == endtoken))
{
syserr("missing map name for lookup");
break;
}
- if (*(ap + 2) == NULL)
+ if (ap[2] == NULL)
{
syserr("syntax error in map lookup");
break;
}
- if ((**ap & 0377) == HOSTBEGIN)
+ if (ap[0][0] == HOSTBEGIN)
break;
- nexttoken = **(ap + 2) & 0377;
+ nexttoken = ap[2][0] & 0377;
if (nexttoken == CANONHOST ||
nexttoken == CANONUSER ||
nexttoken == endtoken)
@@ -394,7 +403,7 @@ readcf(cfname, safe, e)
case HOSTEND:
case LOOKUPEND:
- if ((**ap & 0377) != endtoken)
+ if ((ap[0][0] & 0377) != endtoken)
break;
inmap = false;
endtoken = 0;
@@ -416,10 +425,9 @@ readcf(cfname, safe, e)
** check if map is defined.
*/
- ep = *(ap + 1);
- if ((*ep & 0377) != MACRODEXPAND &&
- stab(ep, ST_MAP,
- ST_FIND) == NULL)
+ ep = ap[1];
+ if ((ep[0] & 0377) != MACRODEXPAND &&
+ stab(ep, ST_MAP, ST_FIND) == NULL)
{
(void) sm_io_fprintf(smioout,
SM_TIME_DEFAULT,
@@ -446,7 +454,7 @@ readcf(cfname, safe, e)
break;
case 'S': /* select rewriting set */
- expand(&bp[1], exbuf, sizeof exbuf, e);
+ expand(&bp[1], exbuf, sizeof(exbuf), e);
ruleset = strtorwset(exbuf, NULL, ST_ENTER);
if (ruleset < 0)
break;
@@ -486,7 +494,7 @@ readcf(cfname, safe, e)
mid = macid_parse(&bp[1], &ep);
if (mid == 0)
break;
- expand(ep, exbuf, sizeof exbuf, e);
+ expand(ep, exbuf, sizeof(exbuf), e);
p = exbuf;
}
else
@@ -671,7 +679,7 @@ readcf(cfname, safe, e)
break;
case 'K':
- expand(&bp[1], exbuf, sizeof exbuf, e);
+ expand(&bp[1], exbuf, sizeof(exbuf), e);
(void) makemapentry(exbuf);
break;
@@ -733,6 +741,7 @@ readcf(cfname, safe, e)
}
}
}
+
/*
** TRANSLATE_DOLLARS -- convert $x into internal form
**
@@ -740,20 +749,35 @@ readcf(cfname, safe, e)
** to turn it into internal form.
**
** Parameters:
-** bp -- the buffer to translate.
+** ibp -- the buffer to translate.
+** obp -- where to put the translation; may be the same as obp
+** bsp -- a pointer to the size of obp; will be updated if
+** the buffer needs to be replaced.
**
** Returns:
-** None. The buffer is translated in place. Since the
-** translations always make the buffer shorter, this is
-** safe without a size parameter.
+** The buffer pointer; may differ from obp if the expansion
+** is larger then *bsp, in which case this will point to
+** malloc()ed memory which must be free()d by the caller.
*/
-void
-translate_dollars(bp)
- char *bp;
+char *
+translate_dollars(ibp, obp, bsp)
+ char *ibp;
+ char *obp;
+ int *bsp;
{
register char *p;
auto char *ep;
+ char *bp;
+
+ if (tTd(37, 53))
+ {
+ sm_dprintf("translate_dollars(");
+ xputs(sm_debug_file(), ibp);
+ sm_dprintf(")\n");
+ }
+
+ bp = quote_internal_chars(ibp, obp, bsp);
for (p = bp; *p != '\0'; p++)
{
@@ -777,7 +801,9 @@ translate_dollars(bp)
/* delete leading white space */
while (isascii(*p) && isspace(*p) &&
*p != '\n' && p > bp)
+ {
p--;
+ }
if ((e = strchr(++p, '\n')) != NULL)
(void) sm_strlcpy(p, e, strlen(p));
else
@@ -813,6 +839,15 @@ translate_dollars(bp)
/* strip trailing white space from the line */
while (--p > bp && isascii(*p) && isspace(*p))
*p = '\0';
+
+ if (tTd(37, 53))
+ {
+ sm_dprintf(" translate_dollars => ");
+ xputs(sm_debug_file(), bp);
+ sm_dprintf("\n");
+ }
+
+ return bp;
}
/*
** TOOMANY -- signal too many of some option
@@ -944,11 +979,11 @@ fileclass(class, filename, fmt, ismap, safe, optional)
char lcbuf[MAXLINE];
/* Get $j */
- expand("\201j", jbuf, sizeof jbuf, &BlankEnvelope);
+ expand("\201j", jbuf, sizeof(jbuf), &BlankEnvelope);
if (jbuf[0] == '\0')
{
(void) sm_strlcpy(jbuf, "localhost",
- sizeof jbuf);
+ sizeof(jbuf));
}
/* impose the default schema */
@@ -957,15 +992,15 @@ fileclass(class, filename, fmt, ismap, safe, optional)
lc = "";
else
{
- expand(lc, lcbuf, sizeof lcbuf, CurEnv);
+ expand(lc, lcbuf, sizeof(lcbuf), CurEnv);
lc = lcbuf;
}
cl = "ldap";
- n = sm_snprintf(buf, sizeof buf,
+ n = sm_snprintf(buf, sizeof(buf),
"-k (&(objectClass=sendmailMTAClass)(sendmailMTAClassName=%s)(|(sendmailMTACluster=%s)(sendmailMTAHost=%s))) -v sendmailMTAClassValue,sendmailMTAClassSearch:FILTER:sendmailMTAClass,sendmailMTAClassURL:URL:sendmailMTAClass",
mn, lc, jbuf);
- if (n >= sizeof buf)
+ if (n >= sizeof(buf))
{
syserr("fileclass: F{%s}: Default LDAP string too long",
mn);
@@ -996,7 +1031,7 @@ fileclass(class, filename, fmt, ismap, safe, optional)
sm_free(mn);
return;
}
- memset(&map, '\0', sizeof map);
+ memset(&map, '\0', sizeof(map));
map.map_class = &mapclass->s_mapclass;
map.map_mname = mn;
map.map_mflags |= MF_FILECLASS;
@@ -1095,7 +1130,7 @@ fileclass(class, filename, fmt, ismap, safe, optional)
return;
}
- while (sm_io_fgets(f, SM_TIME_DEFAULT, buf, sizeof buf) != NULL)
+ while (sm_io_fgets(f, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL)
{
#if SCANF
char wordbuf[MAXLINE + 1];
@@ -1170,8 +1205,8 @@ makemailer(line)
static int nextmailer = 0; /* "free" index into Mailer struct */
/* allocate a mailer and set up defaults */
- m = (struct mailer *) xalloc(sizeof *m);
- memset((char *) m, '\0', sizeof *m);
+ m = (struct mailer *) xalloc(sizeof(*m));
+ memset((char *) m, '\0', sizeof(*m));
errno = 0; /* avoid bogus error text */
/* collect the mailer name */
@@ -1630,7 +1665,7 @@ munchstring(p, delimptr, delim)
bool quotemode = false;
static char buf[MAXLINE];
- for (q = buf; *p != '\0' && q < &buf[sizeof buf - 1]; p++)
+ for (q = buf; *p != '\0' && q < &buf[sizeof(buf) - 1]; p++)
{
if (backslash)
{
@@ -1708,7 +1743,7 @@ extrquotstr(p, delimptr, delimbuf, st)
bool quotemode = false;
static char buf[MAXLINE];
- for (q = buf; *p != '\0' && q < &buf[sizeof buf - 1]; p++)
+ for (q = buf; *p != '\0' && q < &buf[sizeof(buf) - 1]; p++)
{
if (backslash)
{
@@ -1770,8 +1805,8 @@ makeargv(p)
argv[i++] = NULL;
/* now make a copy of the argv */
- avp = (char **) xalloc(sizeof *avp * i);
- memmove((char *) avp, (char *) argv, sizeof *avp * i);
+ avp = (char **) xalloc(sizeof(*avp) * i);
+ memmove((char *) avp, (char *) argv, sizeof(*avp) * i);
return avp;
}
@@ -2163,14 +2198,10 @@ static struct optioninfo
{ "DelayLA", O_DELAY_LA, OI_NONE },
#define O_FASTSPLIT 0xce
{ "FastSplit", O_FASTSPLIT, OI_NONE },
-#if _FFR_SOFT_BOUNCE
-# define O_SOFTBOUNCE 0xcf
+#define O_SOFTBOUNCE 0xcf
{ "SoftBounce", O_SOFTBOUNCE, OI_NONE },
-#endif /* _FFR_SOFT_BOUNCE */
-#if _FFR_SELECT_SHM
-# define O_SHMKEYFILE 0xd0
+#define O_SHMKEYFILE 0xd0
{ "SharedMemoryKeyFile", O_SHMKEYFILE, OI_NONE },
-#endif /* _FFR_SELECT_SHM */
#define O_REJECTLOGINTERVAL 0xd1
{ "RejectLogInterval", O_REJECTLOGINTERVAL, OI_NONE },
#define O_REQUIRES_DIR_FSYNC 0xd2
@@ -2187,10 +2218,8 @@ static struct optioninfo
# define O_CRLPATH 0xd7
{ "CRLPath", O_CRLPATH, OI_NONE },
#endif /* _FFR_CRLPATH */
-#if _FFR_HELONAME
-# define O_HELONAME 0xd8
+#define O_HELONAME 0xd8
{ "HeloName", O_HELONAME, OI_NONE },
-#endif /* _FFR_HELONAME */
#if _FFR_MEMSTAT
# define O_REFUSELOWMEM 0xd9
{ "RefuseLowMem", O_REFUSELOWMEM, OI_NONE },
@@ -2199,10 +2228,8 @@ static struct optioninfo
# define O_MEMRESOURCE 0xdb
{ "MemoryResource", O_MEMRESOURCE, OI_NONE },
#endif /* _FFR_MEMSTAT */
-#if _FFR_MAXNOOPCOMMANDS
-# define O_MAXNOOPCOMMANDS 0xdc
+#define O_MAXNOOPCOMMANDS 0xdc
{ "MaxNOOPCommands", O_MAXNOOPCOMMANDS, OI_NONE },
-#endif /* _FFR_MAXNOOPCOMMANDS */
#if _FFR_MSG_ACCEPT
# define O_MSG_ACCEPT 0xdd
{ "MessageAccept", O_MSG_ACCEPT, OI_NONE },
@@ -2211,6 +2238,13 @@ static struct optioninfo
# define O_CHK_Q_RUNNERS 0xde
{ "CheckQueueRunners", O_CHK_Q_RUNNERS, OI_NONE },
#endif /* _FFR_QUEUE_RUN_PARANOIA */
+#if _FFR_EIGHT_BIT_ADDR_OK
+# if !ALLOW_255
+# ERROR FFR_EIGHT_BIT_ADDR_OK requires _ALLOW_255
+# endif /* !ALLOW_255 */
+# define O_EIGHT_BIT_ADDR_OK 0xdf
+ { "EightBitAddrOK", O_EIGHT_BIT_ADDR_OK, OI_NONE },
+#endif /* _FFR_EIGHT_BIT_ADDR_OK */
{ NULL, '\0', OI_NONE }
};
@@ -2222,7 +2256,7 @@ static struct optioninfo
/* set a string option by expanding the value and assigning it */
/* WARNING this belongs ONLY into a case statement! */
#define SET_STRING_EXP(str) \
- expand(val, exbuf, sizeof exbuf, e); \
+ expand(val, exbuf, sizeof(exbuf), e); \
newval = sm_pstrdup_x(exbuf); \
if (str != NULL) \
sm_free(str); \
@@ -2251,10 +2285,10 @@ setoption(opt, val, safe, sticky, e)
#if _FFR_ALLOW_SASLINFO
extern unsigned int SubmitMode;
#endif /* _FFR_ALLOW_SASLINFO */
-#if STARTTLS || (_FFR_SELECT_SHM && SM_CONF_SHM)
+#if STARTTLS || SM_CONF_SHM
char *newval;
char exbuf[MAXLINE];
-#endif /* STARTTLS || (_FFR_SELECT_SHM && SM_CONF_SHM) */
+#endif /* STARTTLS || SM_CONF_SHM */
errno = 0;
if (opt == ' ')
@@ -3038,17 +3072,15 @@ setoption(opt, val, safe, sticky, e)
#endif /* SM_CONF_SHM */
break;
-#if _FFR_SELECT_SHM
case O_SHMKEYFILE: /* shared memory key file */
-# if SM_CONF_SHM
+#if SM_CONF_SHM
SET_STRING_EXP(ShmKeyFile);
-# else /* SM_CONF_SHM */
+#else /* SM_CONF_SHM */
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
"Warning: Option: %s requires shared memory support (-DSM_CONF_SHM)\n",
OPTNAME);
break;
-# endif /* SM_CONF_SHM */
-#endif /* _FFR_SELECT_SHM */
+#endif /* SM_CONF_SHM */
#if _FFR_MAX_FORWARD_ENTRIES
case O_MAXFORWARD: /* max # of forward entries */
@@ -3061,9 +3093,9 @@ setoption(opt, val, safe, sticky, e)
break;
case O_MUSTQUOTE: /* must quote these characters in phrases */
- (void) sm_strlcpy(buf, "@,;:\\()[]", sizeof buf);
- if (strlen(val) < sizeof buf - 10)
- (void) sm_strlcat(buf, val, sizeof buf);
+ (void) sm_strlcpy(buf, "@,;:\\()[]", sizeof(buf));
+ if (strlen(val) < sizeof(buf) - 10)
+ (void) sm_strlcat(buf, val, sizeof(buf));
else
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
"Warning: MustQuoteChars too long, ignored.\n");
@@ -3371,6 +3403,16 @@ setoption(opt, val, safe, sticky, e)
else if (MaxMimeFieldLength < 40)
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
"Warning: MaxMimeHeaderLength: field length limit set lower than 40\n");
+
+ /*
+ ** Headers field values now include leading space, so let's
+ ** adjust the values to be "backward compatible".
+ */
+
+ if (MaxMimeHeaderLength > 0)
+ MaxMimeHeaderLength++;
+ if (MaxMimeFieldLength > 0)
+ MaxMimeFieldLength++;
break;
case O_CONTROLSOCKET:
@@ -3702,11 +3744,9 @@ setoption(opt, val, safe, sticky, e)
UseMSP = atobool(val);
break;
-#if _FFR_SOFT_BOUNCE
case O_SOFTBOUNCE:
SoftBounce = atobool(val);
break;
-#endif /* _FFR_SOFT_BOUNCE */
case O_REJECTLOGINTERVAL: /* time btwn log msgs while refusing */
RejectLogInterval = convtime(val, 'h');
@@ -3729,11 +3769,10 @@ setoption(opt, val, safe, sticky, e)
FallbackSmartHost = newstr(val);
break;
-#if _FFR_HELONAME
case O_HELONAME:
HeloName = newstr(val);
break;
-#endif /* _FFR_HELONAME */
+
#if _FFR_MEMSTAT
case O_REFUSELOWMEM:
RefuseLowMem = atoi(val);
@@ -3746,11 +3785,9 @@ setoption(opt, val, safe, sticky, e)
break;
#endif /* _FFR_MEMSTAT */
-#if _FFR_MAXNOOPCOMMANDS
case O_MAXNOOPCOMMANDS:
MaxNOOPCommands = atoi(val);
break;
-#endif /* _FFR_MAXNOOPCOMMANDS */
#if _FFR_MSG_ACCEPT
case O_MSG_ACCEPT:
@@ -3764,6 +3801,12 @@ setoption(opt, val, safe, sticky, e)
break;
#endif /* _FFR_QUEUE_RUN_PARANOIA */
+#if _FFR_EIGHT_BIT_ADDR_OK
+ case O_EIGHT_BIT_ADDR_OK:
+ EightBitAddrOK = atobool(val);
+ break;
+#endif /* _FFR_EIGHT_BIT_ADDR_OK */
+
default:
if (tTd(37, 1))
{
@@ -3807,7 +3850,7 @@ setclass(class, str)
{
register STAB *s;
- if ((*str & 0377) == MATCHCLASS)
+ if ((str[0] & 0377) == MATCHCLASS)
{
int mid;
diff --git a/contrib/sendmail/src/recipient.c b/contrib/sendmail/src/recipient.c
index d952a8b..ea30adc 100644
--- a/contrib/sendmail/src/recipient.c
+++ b/contrib/sendmail/src/recipient.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2003, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: recipient.c,v 8.337 2004/08/03 19:57:23 ca Exp $")
+SM_RCSID("@(#)$Id: recipient.c,v 8.348 2007/03/19 21:33:09 ca Exp $")
static void includetimeout __P((int));
static ADDRESS *self_reference __P((ADDRESS *));
@@ -200,10 +200,10 @@ sendtolist(list, ctladdr, sendq, aliaslevel, e)
/* make sure we have enough space to copy the string */
i = strlen(list) + 1;
- if (i <= sizeof buf)
+ if (i <= sizeof(buf))
{
bufp = buf;
- i = sizeof buf;
+ i = sizeof(buf);
}
else
bufp = sm_malloc_x(i);
@@ -309,6 +309,7 @@ sendtolist(list, ctladdr, sendq, aliaslevel, e)
SM_END_TRY
return naddrs;
}
+
#if MILTER
/*
** REMOVEFROMLIST -- Remove addresses from a send list.
@@ -364,10 +365,10 @@ removefromlist(list, sendq, e)
/* make sure we have enough space to copy the string */
i = strlen(list) + 1;
- if (i <= sizeof buf)
+ if (i <= sizeof(buf))
{
bufp = buf;
- i = sizeof buf;
+ i = sizeof(buf);
}
else
bufp = sm_malloc_x(i);
@@ -387,7 +388,7 @@ removefromlist(list, sendq, e)
/* parse the address */
while ((isascii(*p) && isspace(*p)) || *p == ',')
p++;
- if (parseaddr(p, &a, RF_COPYALL,
+ if (parseaddr(p, &a, RF_COPYALL|RF_RM_ADDR,
delimiter, &delimptr, e, true) == NULL)
{
p = delimptr;
@@ -423,10 +424,10 @@ removefromlist(list, sendq, e)
return naddrs;
}
#endif /* MILTER */
+
/*
** RECIPIENT -- Designate a message recipient
-**
-** Saves the named person for future mailing.
+** Saves the named person for future mailing (after some checks).
**
** Parameters:
** new -- the (preparsed) address header for the recipient.
@@ -503,13 +504,13 @@ recipient(new, sendq, aliaslevel, e)
p = "rfc822";
if (sm_strcasecmp(p, "rfc822") != 0)
{
- (void) sm_snprintf(frbuf, sizeof frbuf, "%s; %.800s",
+ (void) sm_snprintf(frbuf, sizeof(frbuf), "%s; %.800s",
q->q_mailer->m_addrtype,
q->q_user);
}
else if (strchr(q->q_user, '@') != NULL)
{
- (void) sm_snprintf(frbuf, sizeof frbuf, "%s; %.800s",
+ (void) sm_snprintf(frbuf, sizeof(frbuf), "%s; %.800s",
p, q->q_user);
}
else if (strchr(q->q_paddr, '@') != NULL)
@@ -528,7 +529,7 @@ recipient(new, sendq, aliaslevel, e)
qp[strlen(qp) - 1] = '\0';
qp++;
}
- (void) sm_snprintf(frbuf, sizeof frbuf, "%s; %.800s",
+ (void) sm_snprintf(frbuf, sizeof(frbuf), "%s; %.800s",
p, qp);
/* undo damage */
@@ -537,7 +538,7 @@ recipient(new, sendq, aliaslevel, e)
}
else
{
- (void) sm_snprintf(frbuf, sizeof frbuf,
+ (void) sm_snprintf(frbuf, sizeof(frbuf),
"%s; %.700s@%.100s",
p, q->q_user, MyHostName);
}
@@ -562,7 +563,7 @@ recipient(new, sendq, aliaslevel, e)
p = e->e_from.q_mailer->m_addrtype;
if (p == NULL)
p = "rfc822";
- (void) sm_strlcpyn(obuf, sizeof obuf, 2, p, ";");
+ (void) sm_strlcpyn(obuf, sizeof(obuf), 2, p, ";");
qp = q->q_paddr;
@@ -577,9 +578,9 @@ recipient(new, sendq, aliaslevel, e)
qp++;
}
- p = xtextify(denlstring(qp, true, false), NULL);
+ p = xtextify(denlstring(qp, true, false), "=");
- if (sm_strlcat(obuf, p, sizeof obuf) >= sizeof obuf)
+ if (sm_strlcat(obuf, p, sizeof(obuf)) >= sizeof(obuf))
{
/* if too big, don't use it */
obuf[0] = '\0';
@@ -601,6 +602,18 @@ recipient(new, sendq, aliaslevel, e)
{
new->q_state = QS_BADADDR;
new->q_status = "5.4.6";
+ if (new->q_alias != NULL)
+ {
+ new->q_alias->q_state = QS_BADADDR;
+ new->q_alias->q_status = "5.4.6";
+ }
+ if ((SuprErrs || !LogUsrErrs) && LogLevel > 0)
+ {
+ sm_syslog(LOG_ERR, e->e_id,
+ "aliasing/forwarding loop broken: %s (%d aliases deep; %d max)",
+ FileName != NULL ? FileName : "", aliaslevel,
+ MaxAliasRecursion);
+ }
usrerrenh(new->q_status,
"554 aliasing/forwarding loop broken (%d aliases deep; %d max)",
aliaslevel, MaxAliasRecursion);
@@ -613,7 +626,7 @@ recipient(new, sendq, aliaslevel, e)
/* get unquoted user for file, program or user.name check */
i = strlen(new->q_user);
- if (i >= sizeof buf0)
+ if (i >= sizeof(buf0))
{
buflen = i + 1;
buf = xalloc(buflen);
@@ -621,7 +634,7 @@ recipient(new, sendq, aliaslevel, e)
else
{
buf = buf0;
- buflen = sizeof buf0;
+ buflen = sizeof(buf0);
}
(void) sm_strlcpy(buf, new->q_user, buflen);
for (p = buf; *p != '\0' && !quoted; p++)
@@ -904,7 +917,8 @@ recipient(new, sendq, aliaslevel, e)
{
new->q_state = QS_QUEUEUP;
if (e->e_message == NULL)
- e->e_message = "Deferred: user database error";
+ e->e_message = sm_rpool_strdup_x(e->e_rpool,
+ "Deferred: user database error");
if (new->q_message == NULL)
new->q_message = "Deferred: user database error";
if (LogLevel > 8)
@@ -1106,10 +1120,11 @@ recipient(new, sendq, aliaslevel, e)
}
}
new->q_flags |= QRCPTOK;
- (void) sm_snprintf(buf0, sizeof buf0, "%d", e->e_nrcpts);
+ (void) sm_snprintf(buf0, sizeof(buf0), "%d", e->e_nrcpts);
macdefine(&e->e_macro, A_TEMP, macid("{nrcpts}"), buf0);
return new;
}
+
/*
** FINDUSER -- find the password entry for a user.
**
@@ -1222,7 +1237,7 @@ finduser(name, fuzzyp, user)
}
# endif /* 0 */
- sm_pwfullname(pw->pw_gecos, pw->pw_name, buf, sizeof buf);
+ sm_pwfullname(pw->pw_gecos, pw->pw_name, buf, sizeof(buf));
if (strchr(buf, ' ') != NULL && sm_strcasecmp(buf, name) == 0)
{
if (tTd(29, 4))
@@ -1248,6 +1263,7 @@ finduser(name, fuzzyp, user)
return EX_NOUSER;
#endif /* MATCHGECOS */
}
+
/*
** WRITABLE -- predicate returning if the file is writable.
**
@@ -1351,6 +1367,7 @@ writable(filename, ctladdr, flags)
errno = safefile(filename, euid, egid, user, flags, S_IWRITE, NULL);
return errno == 0;
}
+
/*
** INCLUDE -- handle :include: specification.
**
@@ -1801,7 +1818,7 @@ resetuid:
LineNumber = 0;
ctladdr->q_flags &= ~QSELFREF;
nincludes = 0;
- while (sm_io_fgets(fp, SM_TIME_DEFAULT, buf, sizeof buf) != NULL &&
+ while (sm_io_fgets(fp, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL &&
!maxreached)
{
fixcrlf(buf, true);
@@ -1858,12 +1875,16 @@ resetuid:
sm_dprintf("include: read error: %s\n", sm_errstring(errno));
if (nincludes > 0 && !bitset(QSELFREF, ctladdr->q_flags))
{
- if (tTd(27, 5))
+ if (aliaslevel <= MaxAliasRecursion ||
+ ctladdr->q_state != QS_BADADDR)
{
- sm_dprintf("include: QS_DONTSEND ");
- printaddr(sm_debug_file(), ctladdr, false);
+ ctladdr->q_state = QS_DONTSEND;
+ if (tTd(27, 5))
+ {
+ sm_dprintf("include: QS_DONTSEND ");
+ printaddr(sm_debug_file(), ctladdr, false);
+ }
}
- ctladdr->q_state = QS_DONTSEND;
}
(void) sm_io_close(fp, SM_TIME_DEFAULT);
@@ -1886,6 +1907,7 @@ includetimeout(ignore)
errno = ETIMEDOUT;
longjmp(CtxIncludeTimeout, 1);
}
+
/*
** SENDTOARGV -- send to an argument vector.
**
@@ -1911,6 +1933,7 @@ sendtoargv(argv, e)
while ((p = *argv++) != NULL)
(void) sendtolist(p, NULLADDR, &e->e_sendqueue, 0, e);
}
+
/*
** GETCTLADDR -- get controlling address from an address header.
**
@@ -1931,6 +1954,7 @@ getctladdr(a)
a = a->q_alias;
return a;
}
+
/*
** SELF_REFERENCE -- check to see if an address references itself
**
diff --git a/contrib/sendmail/src/sasl.c b/contrib/sendmail/src/sasl.c
index 9e368ff..6f9e4a5 100644
--- a/contrib/sendmail/src/sasl.c
+++ b/contrib/sendmail/src/sasl.c
@@ -9,7 +9,7 @@
*/
#include <sm/gen.h>
-SM_RCSID("@(#)$Id: sasl.c,v 8.21 2004/11/22 23:09:00 gshapiro Exp $")
+SM_RCSID("@(#)$Id: sasl.c,v 8.22 2006/08/15 23:24:57 ca Exp $")
#if SASL
# include <stdlib.h>
@@ -258,7 +258,7 @@ iptostring(addr, addrlen, out, outlen)
niflags |= NI_WITHSCOPEID;
# endif /* NI_WITHSCOPEID */
if (getnameinfo((struct sockaddr *) addr, addrlen,
- hbuf, sizeof hbuf, pbuf, sizeof pbuf, niflags) != 0)
+ hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), niflags) != 0)
return false;
# else /* NETINET6 */
if (addr->sa.sa_family != AF_INET)
@@ -272,7 +272,7 @@ iptostring(addr, addrlen, out, outlen)
errno = ENOMEM;
return false;
}
- sm_snprintf(pbuf, sizeof pbuf, "%d", ntohs(addr->sin.sin_port));
+ sm_snprintf(pbuf, sizeof(pbuf), "%d", ntohs(addr->sin.sin_port));
# endif /* NETINET6 */
if (outlen < strlen(hbuf) + strlen(pbuf) + 2)
diff --git a/contrib/sendmail/src/sendmail.h b/contrib/sendmail/src/sendmail.h
index c1c9d84..51f2426 100644
--- a/contrib/sendmail/src/sendmail.h
+++ b/contrib/sendmail/src/sendmail.h
@@ -52,7 +52,7 @@
#ifdef _DEFINE
# ifndef lint
-SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1008.2.1 2006/05/23 01:32:07 ca Exp $";
+SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1042 2007/02/27 22:21:13 ca Exp $";
# endif /* ! lint */
#endif /* _DEFINE */
@@ -70,6 +70,7 @@ SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1008.2.1 2006/05/23
#include <sm/errstring.h>
#include <sm/sysexits.h>
#include <sm/shm.h>
+#include <sm/misc.h>
#ifdef LOG
# include <syslog.h>
@@ -332,7 +333,7 @@ typedef struct address ADDRESS;
extern ADDRESS NullAddress; /* a null (template) address [main.c] */
/* functions */
-extern void cataddr __P((char **, char **, char *, int, int));
+extern void cataddr __P((char **, char **, char *, int, int, bool));
extern char *crackaddr __P((char *, ENVELOPE *));
extern bool emptyaddr __P((ADDRESS *));
extern ADDRESS *getctladdr __P((ADDRESS *));
@@ -351,11 +352,25 @@ extern int sendtolist __P((char *, ADDRESS *, ADDRESS **, int, ENVELOPE *));
extern int removefromlist __P((char *, ADDRESS **, ENVELOPE *));
#endif /* MILTER */
extern void setsender __P((char *, ENVELOPE *, char **, int, bool));
+typedef void esmtp_args_F __P((ADDRESS *, char *, char *, ENVELOPE *));
+extern void parse_esmtp_args __P((ENVELOPE *, ADDRESS *, char *, char *,
+ char *, char *args[], esmtp_args_F));
+extern esmtp_args_F mail_esmtp_args;
+extern esmtp_args_F rcpt_esmtp_args;
+extern void reset_mail_esmtp_args __P((ENVELOPE *));
/* macro to simplify the common call to rewrite() */
#define REWRITE(pvp, rs, env) rewrite(pvp, rs, 0, env, MAXATOM)
/*
+** Token Tables for prescan
+*/
+
+extern unsigned char ExtTokenTab[256]; /* external strings */
+extern unsigned char IntTokenTab[256]; /* internal strings */
+
+
+/*
** Mailer definition structure.
** Every mailer known to the system is declared in this
** structure. It defines the pathname of the mailer, some
@@ -740,7 +755,7 @@ extern int mci_purge_persistent __P((char *, char *));
extern MCI **mci_scan __P((MCI *));
extern void mci_setstat __P((MCI *, int, char *, char *));
extern void mci_store_persistent __P((MCI *));
-extern int mci_traverse_persistent __P((int (*)(), char *));
+extern int mci_traverse_persistent __P((int (*)(char *, char *), char *));
extern void mci_unlock_host __P((MCI *));
EXTERN int MaxMciCache; /* maximum entries in MCI cache */
@@ -807,13 +822,13 @@ extern struct hdrinfo HdrInfo[];
#define CHHDR_QUEUE 0x0008 /* header from queue file */
/* functions */
-extern void addheader __P((char *, char *, int, ENVELOPE *));
+extern void addheader __P((char *, char *, int, ENVELOPE *, bool));
extern unsigned long chompheader __P((char *, int, HDR **, ENVELOPE *));
extern bool commaize __P((HDR *, char *, bool, MCI *, ENVELOPE *));
extern HDR *copyheader __P((HDR *, SM_RPOOL_T *));
extern void eatheader __P((ENVELOPE *, bool, bool));
extern char *hvalue __P((char *, HDR *));
-extern void insheader __P((int, char *, char *, int, ENVELOPE *));
+extern void insheader __P((int, char *, char *, int, ENVELOPE *, bool));
extern bool isheader __P((char *));
extern bool putfromline __P((MCI *, ENVELOPE *));
extern void setupheaders __P((void));
@@ -887,9 +902,8 @@ struct envelope
int e_xfqdir; /* index into queue directories (xf) */
SM_FILE_T *e_xfp; /* transcript file */
SM_FILE_T *e_lockfp; /* the lock file for this message */
- char *e_message; /* error message; readonly; NULL, or
- * static storage, or allocated from
- * e_rpool */
+ char *e_message; /* error message; readonly; NULL,
+ * or allocated from e_rpool */
char *e_statmsg; /* stat msg (changes per delivery).
* readonly. NULL or allocated from
* e_rpool. */
@@ -911,6 +925,7 @@ struct envelope
long e_deliver_by; /* deliver by */
int e_dlvr_flag; /* deliver by flag */
SM_RPOOL_T *e_rpool; /* resource pool for this envelope */
+ unsigned int e_features; /* server features */
};
/* values for e_flags */
@@ -1022,34 +1037,37 @@ struct rewrite
** cannot conflict.
*/
+/* "out of band" indicator */
+/* sm/sendmail.h #define METAQUOTE ((unsigned char)0377) quotes the next octet */
+
/* left hand side items */
#define MATCHZANY ((unsigned char)0220) /* match zero or more tokens */
#define MATCHANY ((unsigned char)0221) /* match one or more tokens */
#define MATCHONE ((unsigned char)0222) /* match exactly one token */
#define MATCHCLASS ((unsigned char)0223) /* match one token in a class */
-#define MATCHNCLASS ((unsigned char)0224) /* match anything not in class */
-#define MATCHREPL ((unsigned char)0225) /* replacement on RHS for above */
+#define MATCHNCLASS ((unsigned char)0224) /* match tokens not in class */
/* right hand side items */
+#define MATCHREPL ((unsigned char)0225) /* RHS replacement for above */
#define CANONNET ((unsigned char)0226) /* canonical net, next token */
#define CANONHOST ((unsigned char)0227) /* canonical host, next token */
#define CANONUSER ((unsigned char)0230) /* canonical user, next N tokens */
#define CALLSUBR ((unsigned char)0231) /* call another rewriting set */
-/* conditionals in macros */
+/* conditionals in macros (anywhere) */
#define CONDIF ((unsigned char)0232) /* conditional if-then */
#define CONDELSE ((unsigned char)0233) /* conditional else */
#define CONDFI ((unsigned char)0234) /* conditional fi */
-/* bracket characters for host name lookup */
+/* bracket characters for RHS host name lookup */
#define HOSTBEGIN ((unsigned char)0235) /* hostname lookup begin */
-#define HOSTEND ((unsigned char)0236) /* hostname lookup end */
+#define HOSTEND ((unsigned char)0236) /* hostname lookup end */
-/* bracket characters for generalized lookup */
+/* bracket characters for RHS generalized lookup */
#define LOOKUPBEGIN ((unsigned char)0205) /* generalized lookup begin */
#define LOOKUPEND ((unsigned char)0206) /* generalized lookup end */
-/* macro substitution character */
+/* macro substitution characters (anywhere) */
#define MACROEXPAND ((unsigned char)0201) /* macro expansion */
#define MACRODEXPAND ((unsigned char)0202) /* deferred macro expansion */
@@ -1098,11 +1116,11 @@ extern int macid_parse __P((char *, char **));
#define macid(name) macid_parse(name, NULL)
extern char *macname __P((int));
extern char *macvalue __P((int, ENVELOPE *));
-extern int rscheck __P((char *, char *, char *, ENVELOPE *, int, int, char *, char *));
+extern int rscheck __P((char *, char *, char *, ENVELOPE *, int, int, char *, char *, ADDRESS *));
extern int rscap __P((char *, char *, char *, ENVELOPE *, char ***, char *, int));
extern void setclass __P((int, char *));
extern int strtorwset __P((char *, char **, int));
-extern void translate_dollars __P((char *));
+extern char *translate_dollars __P((char *, char *, int *));
extern bool wordinclass __P((char *, int));
/*
@@ -1279,9 +1297,9 @@ extern char *map_rewrite __P((MAP *, const char *, size_t, char **));
extern char *ni_propval __P((char *, char *, char *, char *, int));
#endif /* NETINFO */
extern bool openmap __P((MAP *));
+extern int udbexpand __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
#if USERDB
extern void _udbx_close __P((void));
-extern int udbexpand __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
extern char *udbsender __P((char *, SM_RPOOL_T *));
#endif /* USERDB */
@@ -1587,6 +1605,7 @@ extern void set_delivery_mode __P((int, ENVELOPE *));
#define PXLF_STRIP8BIT 0x0002 /* strip 8th bit */
#define PXLF_HEADER 0x0004 /* map newlines in headers */
#define PXLF_NOADDEOL 0x0008 /* if EOL not present, don't add one */
+#define PXLF_STRIPMQUOTE 0x0010 /* strip METAQUOTEs */
/*
** Privacy flags
@@ -1607,11 +1626,9 @@ extern void set_delivery_mode __P((int, ENVELOPE *));
#define PRIV_NOETRN 0x00080000 /* disallow ETRN command */
#define PRIV_NOBODYRETN 0x00100000 /* do not return bodies on bounces */
#define PRIV_NORECEIPTS 0x00200000 /* disallow return receipts */
-#if _FFR_PRIV_NOACTUALRECIPIENT
-# define PRIV_NOACTUALRECIPIENT 0x00400000 /* no X-Actual-Recipient in DSNs */
-#endif /* _FFR_PRIV_NOACTUALRECIPIENT */
+#define PRIV_NOACTUALRECIPIENT 0x00400000 /* no X-Actual-Recipient in DSNs */
-/* don't give no info, anyway, anyhow */
+/* don't give no info, anyway, anyhow (in the main SMTP transaction) */
#define PRIV_GOAWAY 0x0000ffff
/* struct defining such things */
@@ -1636,6 +1653,7 @@ EXTERN unsigned long PrivacyFlags; /* privacy flags */
#define RF_COPYPADDR 0x020 /* copy print address */
#define RF_COPYALL (RF_COPYPARSE|RF_COPYPADDR)
#define RF_COPYNONE 0
+#define RF_RM_ADDR 0x040 /* address to be removed */
/*
** Flags passed to rscheck
@@ -1699,6 +1717,12 @@ struct milter
int mf_sock; /* connected socket */
char mf_state; /* state of filter */
time_t mf_timeout[SMFTO_NUM_TO]; /* timeouts */
+#if _FFR_MILTER_CHECK
+ /* for testing only */
+ mi_int32 mf_mta_prot_version;
+ mi_int32 mf_mta_prot_flags;
+ mi_int32 mf_mta_actions;
+#endif /* _FFR_MILTER_CHECK */
};
/* MTA flags */
@@ -1706,15 +1730,6 @@ struct milter
# define SMF_TEMPFAIL 'T' /* tempfail connection on failure */
# define SMF_TEMPDROP '4' /* 421 connection on failure */
-/* states */
-# define SMFS_CLOSED 'C' /* closed for all further actions */
-# define SMFS_OPEN 'O' /* connected to remote milter filter */
-# define SMFS_INMSG 'M' /* currently servicing a message */
-# define SMFS_DONE 'D' /* done with current message */
-# define SMFS_CLOSABLE 'Q' /* done with current connection */
-# define SMFS_ERROR 'E' /* error state */
-# define SMFS_READY 'R' /* ready for action */
-
EXTERN struct milter *InputFilters[MAXFILTERS];
EXTERN char *InputFilterList;
EXTERN int MilterLogLevel;
@@ -1759,7 +1774,8 @@ extern void vendor_set_uid __P((UID_T));
struct termescape
{
char *te_rv_on; /* turn reverse-video on */
- char *te_rv_off; /* turn reverse-video off */
+ char *te_under_on; /* turn underlining on */
+ char *te_normal; /* revert to normal output */
};
/*
@@ -2162,6 +2178,7 @@ EXTERN bool DontPruneRoutes; /* don't prune source routes */
EXTERN bool ForkQueueRuns; /* fork for each job when running the queue */
EXTERN bool FromFlag; /* if set, "From" person is explicit */
EXTERN bool GrabTo; /* if set, get recipients from msg */
+EXTERN bool EightBitAddrOK; /* we'll let 8-bit addresses through */
EXTERN bool HasEightBits; /* has at least one eight bit input byte */
EXTERN bool HasWildcardMX; /* don't use MX records when canonifying */
EXTERN bool HoldErrs; /* only output errors to transcript */
@@ -2184,9 +2201,7 @@ EXTERN bool SendMIMEErrors; /* send error messages in MIME format */
EXTERN bool SevenBitInput; /* force 7-bit data on input */
EXTERN bool SingleLineFromHeader; /* force From: header to be one line */
EXTERN bool SingleThreadDelivery; /* single thread hosts on delivery */
-#if _FFR_SOFT_BOUNCE
EXTERN bool SoftBounce; /* replace 5xy by 4xy (for testing) */
-#endif /* _FFR_SOFT_BOUNCE */
EXTERN bool volatile StopRequest; /* stop sending output */
EXTERN bool SuprErrs; /* set if we are suppressing errors */
EXTERN bool TryNullMXList; /* if we are the best MX, try host directly */
@@ -2256,9 +2271,7 @@ EXTERN gid_t RunAsGid; /* GID to become for bulk of run */
EXTERN gid_t EffGid; /* effective gid */
#if SM_CONF_SHM
EXTERN key_t ShmKey; /* shared memory key */
-# if _FFR_SELECT_SHM
EXTERN char *ShmKeyFile; /* shared memory key file */
-# endif /* _FFR_SELECT_SHM */
#endif /* SM_CONF_SHM */
EXTERN pid_t CurrentPid; /* current process id */
EXTERN pid_t DaemonPid; /* process id of daemon */
@@ -2291,9 +2304,7 @@ EXTERN char *FallbackMX; /* fall back MX host */
EXTERN char *FallbackSmartHost; /* fall back smart host */
EXTERN char *FileName; /* name to print on error messages */
EXTERN char *ForwardPath; /* path to search for .forward files */
-#if _FFR_HELONAME
EXTERN char *HeloName; /* hostname to announce in HELO */
-#endif /* _FFR_HELONAME */
EXTERN char *HelpFile; /* location of SMTP help file */
EXTERN char *HostStatDir; /* location of host status information */
EXTERN char *HostsFile; /* path to /etc/hosts file */
@@ -2432,7 +2443,7 @@ extern char *milter_connect __P((char *, SOCKADDR, ENVELOPE *, char *));
extern char *milter_helo __P((char *, ENVELOPE *, char *));
extern char *milter_envfrom __P((char **, ENVELOPE *, char *));
extern char *milter_data_cmd __P((ENVELOPE *, char *));
-extern char *milter_envrcpt __P((char **, ENVELOPE *, char *));
+extern char *milter_envrcpt __P((char **, ENVELOPE *, char *, bool));
extern char *milter_data __P((ENVELOPE *, char *));
extern char *milter_unknown __P((char *, ENVELOPE *, char *));
#endif /* MILTER */
@@ -2473,25 +2484,26 @@ extern char *defcharset __P((ENVELOPE *));
extern char *denlstring __P((char *, bool, bool));
extern void dferror __P((SM_FILE_T *volatile, char *, ENVELOPE *));
extern void disconnect __P((int, ENVELOPE *));
-#if _FFR_CONTROL_MSTAT
extern void disk_status __P((SM_FILE_T *, char *));
-#endif /* _FFR_CONTROL_MSTAT */
extern bool dns_getcanonname __P((char *, int, bool, int *, int *));
extern pid_t dofork __P((void));
extern int drop_privileges __P((bool));
extern int dsntoexitstat __P((char *));
extern void dumpfd __P((int, bool, bool));
+#if SM_HEAP_CHECK
+extern void dumpstab __P((void));
+#endif /* SM_HEAP_CHECK */
extern void dumpstate __P((char *));
extern bool enoughdiskspace __P((long, ENVELOPE *));
extern char *exitstat __P((char *));
extern void fatal_error __P((SM_EXC_T *));
-extern char *fgetfolded __P((char *, int, SM_FILE_T *));
+extern char *fgetfolded __P((char *, int *, SM_FILE_T *));
extern void fill_fd __P((int, char *));
extern char *find_character __P((char *, int));
extern int finduser __P((char *, bool *, SM_MBDB_T *));
extern void finis __P((bool, bool, volatile int));
extern void fixcrlf __P((char *, bool));
-extern long freediskspace __P((char *, long *));
+extern long freediskspace __P((const char *, long *));
#if NETINET6 && NEEDSGETIPNODE
extern void freehostent __P((struct hostent *));
#endif /* NETINET6 && NEEDSGETIPNODE */
@@ -2522,7 +2534,8 @@ extern int makeconnection __P((char *, volatile unsigned int, MCI *, ENVELOPE *,
extern void makeworkgroups __P((void));
extern void markfailure __P((ENVELOPE *, ADDRESS *, MCI *, int, bool));
extern void mark_work_group_restart __P((int, int));
-extern char * munchstring __P((char *, char **, int));
+extern MCI *mci_new __P((SM_RPOOL_T *));
+extern char *munchstring __P((char *, char **, int));
extern struct hostent *myhostname __P((char *, int));
extern char *newstr __P((const char *));
#if NISPLUS
@@ -2548,6 +2561,7 @@ extern void resetlimits __P((void));
extern void restart_daemon __P((void));
extern void restart_marked_work_groups __P((void));
extern bool rfc822_string __P((char *));
+extern void rmexpstab __P((void));
extern bool savemail __P((ENVELOPE *, bool));
extern void seed_random __P((void));
extern void sendtoargv __P((char **, ENVELOPE *));
@@ -2577,15 +2591,15 @@ extern void sm_setproctitle __P((bool, ENVELOPE *, const char *, ...));
extern pid_t sm_wait __P((int *));
extern bool split_by_recipient __P((ENVELOPE *e));
extern void stop_sendmail __P((void));
-extern char *str2prt __P((char *));
extern void stripbackslash __P((char *));
extern bool strreplnonprt __P((char *, int));
extern bool strcontainedin __P((bool, char *, char *));
extern int switch_map_find __P((char *, char *[], short []));
+#if STARTTLS
+extern void tls_set_verify __P((SSL_CTX *, SSL *, bool));
+#endif /* STARTTLS */
extern bool transienterror __P((int));
-#if _FFR_BESTMX_BETTER_TRUNCATION || _FFR_DNSMAP_MULTI
extern void truncate_at_delim __P((char *, size_t, int));
-#endif /* _FFR_BESTMX_BETTER_TRUNCATION || _FFR_DNSMAP_MULTI */
extern void tTflag __P((char *));
extern void tTsetup __P((unsigned char *, unsigned int, char *));
extern SIGFUNC_DECL tick __P((int));
@@ -2623,4 +2637,5 @@ extern int xunlink __P((char *));
extern char *xuntextify __P((char *));
+#undef EXTERN
#endif /* ! _SENDMAIL_H */
diff --git a/contrib/sendmail/src/sm_resolve.c b/contrib/sendmail/src/sm_resolve.c
index affd3e5..d2cf96d 100644
--- a/contrib/sendmail/src/sm_resolve.c
+++ b/contrib/sendmail/src/sm_resolve.c
@@ -46,7 +46,7 @@
# if NAMED_BIND
# include "sm_resolve.h"
-SM_RCSID("$Id: sm_resolve.c,v 8.33 2004/08/04 21:17:57 ca Exp $")
+SM_RCSID("$Id: sm_resolve.c,v 8.34 2006/08/15 23:24:58 ca Exp $")
static struct stot
{
@@ -184,7 +184,7 @@ parse_dns_reply(data, len)
/* doesn't work on Crays? */
memcpy(&r->dns_r_h, p, sizeof(r->dns_r_h));
p += sizeof(r->dns_r_h);
- status = dn_expand(data, data + len, p, host, sizeof host);
+ status = dn_expand(data, data + len, p, host, sizeof(host));
if (status < 0)
{
dns_free_data(r);
@@ -204,7 +204,7 @@ parse_dns_reply(data, len)
{
int type, class, ttl, size, txtlen;
- status = dn_expand(data, data + len, p, host, sizeof host);
+ status = dn_expand(data, data + len, p, host, sizeof(host));
if (status < 0)
{
dns_free_data(r);
@@ -252,7 +252,7 @@ parse_dns_reply(data, len)
case T_CNAME:
case T_PTR:
status = dn_expand(data, data + len, p, host,
- sizeof host);
+ sizeof(host));
if (status < 0)
{
dns_free_data(r);
@@ -269,7 +269,7 @@ parse_dns_reply(data, len)
case T_MX:
case T_AFSDB:
status = dn_expand(data, data + len, p + 2, host,
- sizeof host);
+ sizeof(host));
if (status < 0)
{
dns_free_data(r);
@@ -290,7 +290,7 @@ parse_dns_reply(data, len)
case T_SRV:
status = dn_expand(data, data + len, p + 6, host,
- sizeof host);
+ sizeof(host));
if (status < 0)
{
dns_free_data(r);
@@ -409,7 +409,7 @@ dns_lookup_int(domain, rr_class, rr_type, retrans, retry)
}
errno = 0;
SM_SET_H_ERRNO(0);
- len = res_search(domain, rr_class, rr_type, reply, sizeof reply);
+ len = res_search(domain, rr_class, rr_type, reply, sizeof(reply));
if (tTd(8, 16))
{
_res.options = old_options;
diff --git a/contrib/sendmail/src/srvrsmtp.c b/contrib/sendmail/src/srvrsmtp.c
index d95b5a5..1f067b1 100644
--- a/contrib/sendmail/src/srvrsmtp.c
+++ b/contrib/sendmail/src/srvrsmtp.c
@@ -17,7 +17,7 @@
# include <libmilter/mfdef.h>
#endif /* MILTER */
-SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.924.2.5 2006/07/07 16:29:39 ca Exp $")
+SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.960 2007/02/07 20:18:47 ca Exp $")
#include <sm/time.h>
#include <sm/fdset.h>
@@ -36,15 +36,15 @@ static SSL_CTX *srv_ctx = NULL; /* TLS server context */
static SSL *srv_ssl = NULL; /* per connection context */
static bool tls_ok_srv = false;
-#if _FFR_DM_ONE
-static bool NotFirstDelivery = false;
-#endif /* _FFR_DM_ONE */
-extern void tls_set_verify __P((SSL_CTX *, SSL *, bool));
# define TLS_VERIFY_CLIENT() tls_set_verify(srv_ctx, srv_ssl, \
bitset(SRV_VRFY_CLT, features))
#endif /* STARTTLS */
+#if _FFR_DM_ONE
+static bool NotFirstDelivery = false;
+#endif /* _FFR_DM_ONE */
+
/* server features */
#define SRV_NONE 0x0000 /* none... */
#define SRV_OFFER_TLS 0x0001 /* offer STARTTLS */
@@ -70,10 +70,7 @@ static unsigned int srvfeatures __P((ENVELOPE *, char *, unsigned int));
#define STOP_ATTACK ((time_t) -1)
static time_t checksmtpattack __P((volatile unsigned int *, unsigned int,
bool, char *, ENVELOPE *));
-static void mail_esmtp_args __P((char *, char *, ENVELOPE *, unsigned int));
static void printvrfyaddr __P((ADDRESS *, bool, bool));
-static void rcpt_esmtp_args __P((ADDRESS *, char *, char *, ENVELOPE *,
- unsigned int));
static char *skipword __P((char *volatile, char *));
static void setup_smtpd_io __P((void));
@@ -115,7 +112,7 @@ extern ENVELOPE BlankEnvelope;
do \
{ \
char buf[16]; \
- (void) sm_snprintf(buf, sizeof buf, "%d", \
+ (void) sm_snprintf(buf, sizeof(buf), "%d", \
BadRcptThrottle > 0 && n_badrcpts > BadRcptThrottle \
? n_badrcpts - 1 : n_badrcpts); \
macdefine(&e->e_macro, A_TEMP, macid("{nbadrcpts}"), buf); \
@@ -125,6 +122,88 @@ extern ENVELOPE BlankEnvelope;
(s)++
/*
+** PARSE_ESMTP_ARGS -- parse EMSTP arguments (for MAIL, RCPT)
+**
+** Parameters:
+** e -- the envelope
+** addr_st -- address (RCPT only)
+** p -- read buffer
+** delimptr -- current position in read buffer
+** which -- MAIL/RCPT
+** args -- arguments (output)
+** esmtp_args -- function to process a single ESMTP argument
+**
+** Returns:
+** none
+*/
+
+void
+parse_esmtp_args(e, addr_st, p, delimptr, which, args, esmtp_args)
+ ENVELOPE *e;
+ ADDRESS *addr_st;
+ char *p;
+ char *delimptr;
+ char *which;
+ char *args[];
+ esmtp_args_F esmtp_args;
+{
+ int argno;
+
+ argno = 0;
+ if (args != NULL)
+ args[argno++] = p;
+ p = delimptr;
+ while (p != NULL && *p != '\0')
+ {
+ char *kp;
+ char *vp = NULL;
+ char *equal = NULL;
+
+ /* locate the beginning of the keyword */
+ SKIP_SPACE(p);
+ if (*p == '\0')
+ break;
+ kp = p;
+
+ /* skip to the value portion */
+ while ((isascii(*p) && isalnum(*p)) || *p == '-')
+ p++;
+ if (*p == '=')
+ {
+ equal = 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))
+ sm_dprintf("%s: got arg %s=\"%s\"\n", which, kp,
+ vp == NULL ? "<null>" : vp);
+
+ esmtp_args(addr_st, kp, vp, e);
+ if (equal != NULL)
+ *equal = '=';
+ if (args != NULL)
+ args[argno] = kp;
+ argno++;
+ if (argno >= MAXSMTPARGS - 1)
+ usrerr("501 5.5.4 Too many parameters");
+ if (Errors > 0)
+ break;
+ }
+ if (args != NULL)
+ args[argno] = NULL;
+}
+
+/*
** SMTP -- run the SMTP protocol.
**
** Parameters:
@@ -291,6 +370,7 @@ static bool smtp_data __P((SMTP_T *, ENVELOPE *));
{ \
int savelogusrerrs = LogUsrErrs; \
\
+ milter_cmd_fail = true; \
switch (state) \
{ \
case SMFIR_SHUTDOWN: \
@@ -351,6 +431,7 @@ static bool smtp_data __P((SMTP_T *, ENVELOPE *));
"Milter: %s=%s, discard", \
str, addr); \
e->e_flags |= EF_DISCARD; \
+ milter_cmd_fail = false; \
break; \
\
case SMFIR_TEMPFAIL: \
@@ -363,6 +444,9 @@ static bool smtp_data __P((SMTP_T *, ENVELOPE *));
} \
usrerr(MSG_TEMPFAIL); \
break; \
+ default: \
+ milter_cmd_fail = false; \
+ break; \
} \
LogUsrErrs = savelogusrerrs; \
if (response != NULL) \
@@ -402,6 +486,7 @@ do \
sm_rpool_free(e->e_rpool); \
e = newenvelope(e, CurEnv, sm_rpool_new_x(NULL)); \
CurEnv = e; \
+ e->e_features = features; \
\
/* put back discard bit */ \
if (smtp.sm_discard) \
@@ -448,6 +533,7 @@ do \
qid_printname(e), CurSmtpClient, inp); \
}
+static bool SevenBitInput_Saved; /* saved version of SevenBitInput */
void
smtp(nullserver, d_flags, e)
@@ -473,11 +559,8 @@ smtp(nullserver, d_flags, e)
volatile unsigned int n_etrn = 0; /* count of ETRN */
volatile unsigned int n_noop = 0; /* count of NOOP/VERB/etc */
volatile unsigned int n_helo = 0; /* count of HELO/EHLO */
- volatile int save_sevenbitinput;
bool ok;
-#if _FFR_BLOCK_PROXIES
volatile bool first;
-#endif /* _FFR_BLOCK_PROXIES */
volatile bool tempfail = false;
volatile time_t wt; /* timeout after too many commands */
volatile time_t previous; /* time after checksmtpattack() */
@@ -488,9 +571,11 @@ smtp(nullserver, d_flags, e)
char *greetcode = "220";
char *hostname; /* my hostname ($j) */
QUEUE_CHAR *new;
- int argno;
char *args[MAXSMTPARGS];
- char inp[MAXLINE];
+ char inp[MAXINPLINE];
+#if MAXINPLINE < MAXLINE
+ ERROR _MAXINPLINE must NOT be less than _MAXLINE: MAXINPLINE < MAXLINE
+#endif /* MAXINPLINE < MAXLINE */
char cmdbuf[MAXLINE];
#if SASL
sasl_conn_t *conn;
@@ -502,7 +587,7 @@ smtp(nullserver, d_flags, e)
char *user;
char *in, *out2;
# if SASL >= 20000
- char *auth_id;
+ char *auth_id = NULL;
const char *out;
sasl_ssf_t ext_ssf;
char localip[60], remoteip[60];
@@ -521,6 +606,7 @@ smtp(nullserver, d_flags, e)
char *mechlist;
volatile unsigned int n_mechs;
unsigned int len;
+#else /* SASL */
#endif /* SASL */
int r;
#if STARTTLS
@@ -538,12 +624,22 @@ smtp(nullserver, d_flags, e)
# endif /* _FFR_NO_PIPE */
#endif /* PIPELINING */
volatile time_t log_delay = (time_t) 0;
+#if MILTER
+ volatile bool milter_cmd_done, milter_cmd_safe;
+ volatile bool milter_rcpt_added, milter_cmd_fail;
+ ADDRESS addr_st;
+# define p_addr_st &addr_st
+#else /* MILTER */
+# define p_addr_st NULL
+#endif /* MILTER */
+ size_t inplen;
- save_sevenbitinput = SevenBitInput;
+ SevenBitInput_Saved = SevenBitInput;
smtp.sm_nrcpts = 0;
#if MILTER
smtp.sm_milterize = (nullserver == NULL);
smtp.sm_milterlist = false;
+ addr = NULL;
#endif /* MILTER */
/* setup I/O fd correctly for the SMTP server */
@@ -641,6 +737,7 @@ smtp(nullserver, d_flags, e)
goto doquit;
}
+ e->e_features = features;
hostname = macvalue('j', e);
#if SASL
if (AuthRealm == NULL)
@@ -704,7 +801,7 @@ smtp(nullserver, d_flags, e)
&addrsize) == 0)
{
if (iptostring(&saddr_r, addrsize,
- remoteip, sizeof remoteip))
+ remoteip, sizeof(remoteip)))
{
sasl_setprop(conn, SASL_IPREMOTEPORT,
remoteip);
@@ -718,7 +815,7 @@ smtp(nullserver, d_flags, e)
{
if (iptostring(&saddr_l, addrsize,
localip,
- sizeof localip))
+ sizeof(localip)))
{
sasl_setprop(conn,
SASL_IPLOCALPORT,
@@ -764,7 +861,7 @@ smtp(nullserver, d_flags, e)
# endif /* 0 */
/* set properties */
- (void) memset(&ssp, '\0', sizeof ssp);
+ (void) memset(&ssp, '\0', sizeof(ssp));
/* XXX should these be options settable via .cf ? */
/* ssp.min_ssf = 0; is default due to memset() */
@@ -852,7 +949,9 @@ smtp(nullserver, d_flags, e)
char *response;
q = macvalue(macid("{client_name}"), e);
- SM_ASSERT(q != NULL);
+ SM_ASSERT(q != NULL || OpMode == MD_SMTP);
+ if (q == NULL)
+ q = "localhost";
response = milter_connect(q, RealHostAddr, e, &state);
switch (state)
{
@@ -907,7 +1006,7 @@ smtp(nullserver, d_flags, e)
#if STARTTLS
!smtps &&
#endif /* STARTTLS */
- *greetcode == '2')
+ *greetcode == '2' && nullserver == NULL)
{
time_t msecs = 0;
char **pvp;
@@ -929,9 +1028,8 @@ smtp(nullserver, d_flags, e)
int fd;
fd_set readfds;
struct timeval timeout;
-#if _FFR_LOG_GREET_PAUSE
struct timeval bp, ep, tp; /* {begin,end,total}pause */
-#endif /* _FFR_LOG_GREET_PAUSE */
+ int eoftest;
/* pause for a moment */
timeout.tv_sec = msecs / 1000;
@@ -948,31 +1046,25 @@ smtp(nullserver, d_flags, e)
fd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL);
FD_ZERO(&readfds);
SM_FD_SET(fd, &readfds);
-#if _FFR_LOG_GREET_PAUSE
gettimeofday(&bp, NULL);
-#endif /* _FFR_LOG_GREET_PAUSE */
if (select(fd + 1, FDSET_CAST &readfds,
NULL, NULL, &timeout) > 0 &&
- FD_ISSET(fd, &readfds))
+ FD_ISSET(fd, &readfds) &&
+ (eoftest = sm_io_getc(InChannel, SM_TIME_DEFAULT))
+ != SM_IO_EOF)
{
-#if _FFR_LOG_GREET_PAUSE
+ sm_io_ungetc(InChannel, SM_TIME_DEFAULT,
+ eoftest);
gettimeofday(&ep, NULL);
timersub(&ep, &bp, &tp);
-#endif /* _FFR_LOG_GREET_PAUSE */
greetcode = "554";
nullserver = "Command rejected";
sm_syslog(LOG_INFO, e->e_id,
-#if _FFR_LOG_GREET_PAUSE
- "rejecting commands from %s [%s] after %d seconds due to pre-greeting traffic",
-#else /* _FFR_LOG_GREET_PAUSE */
- "rejecting commands from %s [%s] due to pre-greeting traffic",
-#endif /* _FFR_LOG_GREET_PAUSE */
+ "rejecting commands from %s [%s] due to pre-greeting traffic after %d seconds",
peerhostname,
- anynet_ntoa(&RealHostAddr)
-#if _FFR_LOG_GREET_PAUSE
- , (int) tp.tv_sec +
+ anynet_ntoa(&RealHostAddr),
+ (int) tp.tv_sec +
(tp.tv_usec >= 500000 ? 1 : 0)
-#endif /* _FFR_LOG_GREET_PAUSE */
);
}
}
@@ -992,10 +1084,10 @@ smtp(nullserver, d_flags, e)
/* output the first line, inserting "ESMTP" as second word */
if (*greetcode == '5')
- (void) sm_snprintf(inp, sizeof inp, "%s not accepting messages",
- hostname);
+ (void) sm_snprintf(inp, sizeof(inp),
+ "%s not accepting messages", hostname);
else
- expand(SmtpGreeting, inp, sizeof inp, e);
+ expand(SmtpGreeting, inp, sizeof(inp), e);
p = strchr(inp, '\n');
if (p != NULL)
@@ -1004,10 +1096,10 @@ smtp(nullserver, d_flags, e)
if (id == NULL)
id = &inp[strlen(inp)];
if (p == NULL)
- (void) sm_snprintf(cmdbuf, sizeof cmdbuf,
+ (void) sm_snprintf(cmdbuf, sizeof(cmdbuf),
"%s %%.*s ESMTP%%s", greetcode);
else
- (void) sm_snprintf(cmdbuf, sizeof cmdbuf,
+ (void) sm_snprintf(cmdbuf, sizeof(cmdbuf),
"%s-%%.*s ESMTP%%s", greetcode);
message(cmdbuf, (int) (id - inp), inp, id);
@@ -1017,14 +1109,14 @@ smtp(nullserver, d_flags, e)
*p++ = '\0';
if (isascii(*id) && isspace(*id))
id++;
- (void) sm_strlcpyn(cmdbuf, sizeof cmdbuf, 2, greetcode, "-%s");
+ (void) sm_strlcpyn(cmdbuf, sizeof(cmdbuf), 2, greetcode, "-%s");
message(cmdbuf, id);
}
if (id != NULL)
{
if (isascii(*id) && isspace(*id))
id++;
- (void) sm_strlcpyn(cmdbuf, sizeof cmdbuf, 2, greetcode, " %s");
+ (void) sm_strlcpyn(cmdbuf, sizeof(cmdbuf), 2, greetcode, " %s");
message(cmdbuf, id);
}
@@ -1040,9 +1132,7 @@ smtp(nullserver, d_flags, e)
/* sendinghost's storage must outlive the current envelope */
if (sendinghost != NULL)
sendinghost = sm_strdup_x(sendinghost);
-#if _FFR_BLOCK_PROXIES
first = true;
-#endif /* _FFR_BLOCK_PROXIES */
gothello = false;
smtp.sm_gotmail = false;
for (;;)
@@ -1055,6 +1145,9 @@ smtp(nullserver, d_flags, e)
LogUsrErrs = false;
OnlyOneError = true;
e->e_flags &= ~(EF_VRFYONLY|EF_GLOBALERRS);
+#if MILTER
+ milter_cmd_fail = false;
+#endif /* MILTER */
/* setup for the read */
e->e_to = NULL;
@@ -1065,16 +1158,10 @@ smtp(nullserver, d_flags, e)
/* read the input line */
SmtpPhase = "server cmd read";
sm_setproctitle(true, e, "server %s cmd read", CurSmtpClient);
-#if SASL
- /*
- ** XXX SMTP AUTH requires accepting any length,
- ** at least for challenge/response
- */
-#endif /* SASL */
/* handle errors */
if (sm_io_error(OutChannel) ||
- (p = sfgets(inp, sizeof inp, InChannel,
+ (p = sfgets(inp, sizeof(inp), InChannel,
TimeOuts.to_nextcommand, SmtpPhase)) == NULL)
{
char *d;
@@ -1107,16 +1194,36 @@ smtp(nullserver, d_flags, e)
goto doquit;
}
-#if _FFR_BLOCK_PROXIES
+ /* also used by "proxy" check below */
+ inplen = strlen(inp);
+#if SASL
+ /*
+ ** SMTP AUTH requires accepting any length,
+ ** at least for challenge/response. However, not imposing
+ ** a limit is a bad idea (denial of service).
+ */
+
+ if (authenticating != SASL_PROC_AUTH
+ && sm_strncasecmp(inp, "AUTH ", 5) != 0
+ && inplen > MAXLINE)
+ {
+ message("421 4.7.0 %s Command too long, possible attack %s",
+ MyHostName, CurSmtpClient);
+ sm_syslog(LOG_INFO, e->e_id,
+ "%s: SMTP violation, input too long: %lu",
+ CurSmtpClient, (unsigned long) inplen);
+ goto doquit;
+ }
+#endif /* SASL */
+
if (first)
{
- size_t inplen, cmdlen;
+ size_t cmdlen;
int idx;
char *http_cmd;
static char *http_cmds[] = { "GET", "POST",
"CONNECT", "USER", NULL };
- inplen = strlen(inp);
for (idx = 0; (http_cmd = http_cmds[idx]) != NULL;
idx++)
{
@@ -1136,7 +1243,6 @@ smtp(nullserver, d_flags, e)
}
first = false;
}
-#endif /* _FFR_BLOCK_PROXIES */
/* clean up end of line */
fixcrlf(inp, true);
@@ -1270,7 +1376,7 @@ smtp(nullserver, d_flags, e)
{
char pbuf[8];
- (void) sm_snprintf(pbuf, sizeof pbuf,
+ (void) sm_snprintf(pbuf, sizeof(pbuf),
"%u", *ssf);
macdefine(&BlankEnvelope.e_macro,
A_TEMP,
@@ -1386,7 +1492,7 @@ smtp(nullserver, d_flags, e)
cmd = cmdbuf;
while (*p != '\0' &&
!(isascii(*p) && isspace(*p)) &&
- cmd < &cmdbuf[sizeof cmdbuf - 2])
+ cmd < &cmdbuf[sizeof(cmdbuf) - 2])
*cmd++ = *p++;
*cmd = '\0';
@@ -1801,7 +1907,7 @@ smtp(nullserver, d_flags, e)
macvalue(macid("{verify}"), e),
"STARTTLS", e,
RSF_RMCOMM|RSF_COUNT,
- 5, NULL, NOQID) != EX_OK ||
+ 5, NULL, NOQID, NULL) != EX_OK ||
Errors > 0)
{
extern char MsgBuf[];
@@ -1992,15 +2098,6 @@ smtp(nullserver, d_flags, e)
response = milter_helo(p, e, &state);
switch (state)
{
- case SMFIR_REPLYCODE:
- if (MilterLogLevel > 3)
- sm_syslog(LOG_INFO, e->e_id,
- "Milter: helo=%s, reject=%s",
- p, response);
- nullserver = newstr(response);
- smtp.sm_milterize = false;
- break;
-
case SMFIR_REJECT:
if (MilterLogLevel > 3)
sm_syslog(LOG_INFO, e->e_id,
@@ -2019,17 +2116,36 @@ smtp(nullserver, d_flags, e)
smtp.sm_milterize = false;
break;
- case SMFIR_SHUTDOWN:
+ case SMFIR_REPLYCODE:
if (MilterLogLevel > 3)
sm_syslog(LOG_INFO, e->e_id,
+ "Milter: helo=%s, reject=%s",
+ p, response);
+ if (strncmp(response, "421 ", 4) != 0
+ && strncmp(response, "421-", 4) != 0)
+ {
+ nullserver = newstr(response);
+ smtp.sm_milterize = false;
+ break;
+ }
+ /* FALLTHROUGH */
+
+ case SMFIR_SHUTDOWN:
+ if (MilterLogLevel > 3 &&
+ response == NULL)
+ sm_syslog(LOG_INFO, e->e_id,
"Milter: helo=%s, reject=421 4.7.0 %s closing connection",
p, MyHostName);
tempfail = true;
smtp.sm_milterize = false;
- message("421 4.7.0 %s closing connection",
- MyHostName);
+ if (response != NULL)
+ usrerr(response);
+ else
+ message("421 4.7.0 %s closing connection",
+ MyHostName);
/* arrange to ignore send list */
e->e_sendqueue = NULL;
+ lognullconnection = false;
goto doquit;
}
if (response != NULL)
@@ -2258,59 +2374,13 @@ smtp(nullserver, d_flags, e)
}
/* reset to default value */
- SevenBitInput = save_sevenbitinput;
+ SevenBitInput = SevenBitInput_Saved;
/* now parse ESMTP arguments */
e->e_msgsize = 0;
addr = p;
- argno = 0;
- args[argno++] = p;
- p = delimptr;
- while (p != NULL && *p != '\0')
- {
- char *kp;
- char *vp = NULL;
- char *equal = NULL;
-
- /* locate the beginning of the keyword */
- SKIP_SPACE(p);
- if (*p == '\0')
- break;
- kp = p;
-
- /* skip to the value portion */
- while ((isascii(*p) && isalnum(*p)) || *p == '-')
- p++;
- if (*p == '=')
- {
- equal = 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))
- sm_dprintf("MAIL: got arg %s=\"%s\"\n", kp,
- vp == NULL ? "<null>" : vp);
-
- mail_esmtp_args(kp, vp, e, features);
- if (equal != NULL)
- *equal = '=';
- args[argno++] = kp;
- if (argno >= MAXSMTPARGS - 1)
- usrerr("501 5.5.4 Too many parameters");
- if (Errors > 0)
- sm_exc_raisenew_x(&EtypeQuickAbort, 1);
- }
- args[argno] = NULL;
+ parse_esmtp_args(e, NULL, p, delimptr, "MAIL", args,
+ mail_esmtp_args);
if (Errors > 0)
sm_exc_raisenew_x(&EtypeQuickAbort, 1);
@@ -2344,7 +2414,7 @@ smtp(nullserver, d_flags, e)
#endif /* _FFR_MAIL_MACRO */
if (rscheck("check_mail", addr,
NULL, e, RSF_RMCOMM|RSF_COUNT, 3,
- NULL, e->e_id) != EX_OK ||
+ NULL, e->e_id, NULL) != EX_OK ||
Errors > 0)
sm_exc_raisenew_x(&EtypeQuickAbort, 1);
macdefine(&e->e_macro, A_PERM,
@@ -2423,6 +2493,17 @@ smtp(nullserver, d_flags, e)
case CMDRCPT: /* rcpt -- designate recipient */
DELAY_CONN("RCPT");
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_mailer}"), NULL);
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_host}"), NULL);
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_addr}"), NULL);
+#if MILTER
+ (void) memset(&addr_st, '\0', sizeof(addr_st));
+ a = NULL;
+ milter_rcpt_added = false;
+#endif
if (BadRcptThrottle > 0 &&
n_badrcpts >= BadRcptThrottle)
{
@@ -2476,16 +2557,16 @@ smtp(nullserver, d_flags, e)
#if MILTER
/*
- ** If the filter will be deleting recipients,
- ** don't expand them at RCPT time (in the call
+ ** Do not expand recipients at RCPT time (in the call
** to recipient()). If they are expanded, it
** is impossible for removefromlist() to figure
** out the expanded members of the original
** recipient and mark them as QS_DONTSEND.
*/
- if (milter_can_delrcpts())
- e->e_flags |= EF_VRFYONLY;
+ e->e_flags |= EF_VRFYONLY;
+ milter_cmd_done = false;
+ milter_cmd_safe = false;
#endif /* MILTER */
p = skipword(p, "to");
@@ -2533,63 +2614,34 @@ smtp(nullserver, d_flags, e)
/* now parse ESMTP arguments */
addr = p;
- argno = 0;
- args[argno++] = p;
- p = delimptr;
- while (p != NULL && *p != '\0')
- {
- char *kp;
- char *vp = NULL;
- char *equal = NULL;
-
- /* locate the beginning of the keyword */
- SKIP_SPACE(p);
- if (*p == '\0')
- break;
- kp = p;
-
- /* skip to the value portion */
- while ((isascii(*p) && isalnum(*p)) || *p == '-')
- p++;
- if (*p == '=')
- {
- equal = 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))
- sm_dprintf("RCPT: got arg %s=\"%s\"\n", kp,
- vp == NULL ? "<null>" : vp);
-
- rcpt_esmtp_args(a, kp, vp, e, features);
- if (equal != NULL)
- *equal = '=';
- args[argno++] = kp;
- if (argno >= MAXSMTPARGS - 1)
- usrerr("501 5.5.4 Too many parameters");
- if (Errors > 0)
- break;
- }
- args[argno] = NULL;
+ parse_esmtp_args(e, a, p, delimptr, "RCPT", args,
+ rcpt_esmtp_args);
if (Errors > 0)
goto rcpt_done;
+#if MILTER
+ /*
+ ** rscheck() can trigger an "exception"
+ ** in which case the execution continues at
+ ** SM_EXCEPT(exc, "[!F]*")
+ ** This means milter_cmd_safe is not set
+ ** and hence milter is not invoked.
+ ** Would it be "safe" to change that, i.e., use
+ ** milter_cmd_safe = true;
+ ** here so a milter is informed (if requested)
+ ** about RCPTs that are rejected by check_rcpt?
+ */
+# if _FFR_MILTER_CHECK_REJECTIONS_TOO
+ milter_cmd_safe = true;
+# endif
+#endif
+
/* do config file checking of the recipient */
macdefine(&e->e_macro, A_PERM,
macid("{addr_type}"), "e r");
if (rscheck("check_rcpt", addr,
NULL, e, RSF_RMCOMM|RSF_COUNT, 3,
- NULL, e->e_id) != EX_OK ||
+ NULL, e->e_id, p_addr_st) != EX_OK ||
Errors > 0)
goto rcpt_done;
macdefine(&e->e_macro, A_PERM,
@@ -2598,38 +2650,74 @@ smtp(nullserver, d_flags, e)
/* If discarding, don't bother to verify user */
if (bitset(EF_DISCARD, e->e_flags))
a->q_state = QS_VERIFIED;
+#if MILTER
+ milter_cmd_safe = true;
+#endif
+
+ /* save in recipient list after ESMTP mods */
+ a = recipient(a, &e->e_sendqueue, 0, e);
+ /* may trigger exception... */
+
+#if MILTER
+ milter_rcpt_added = true;
+#endif
+
+ if(!(Errors > 0) && QS_IS_BADADDR(a->q_state))
+ {
+ /* punt -- should keep message in ADDRESS.... */
+ usrerr("550 5.1.1 Addressee unknown");
+ }
#if MILTER
+ rcpt_done:
if (smtp.sm_milterlist && smtp.sm_milterize &&
!bitset(EF_DISCARD, e->e_flags))
{
char state;
char *response;
- response = milter_envrcpt(args, e, &state);
+ /* how to get the error codes? */
+ if (Errors > 0)
+ {
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_mailer}"),
+ "error");
+ if (a != NULL &&
+ a->q_status != NULL &&
+ a->q_rstatus != NULL)
+ {
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_host}"),
+ a->q_status);
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_addr}"),
+ a->q_rstatus);
+ }
+ else
+ {
+ if (addr_st.q_host != NULL)
+ macdefine(&e->e_macro,
+ A_PERM,
+ macid("{rcpt_host}"),
+ addr_st.q_host);
+ if (addr_st.q_user != NULL)
+ macdefine(&e->e_macro,
+ A_PERM,
+ macid("{rcpt_addr}"),
+ addr_st.q_user);
+ }
+ }
+
+ response = milter_envrcpt(args, e, &state,
+ Errors > 0);
+ milter_cmd_done = true;
MILTER_REPLY("to");
}
#endif /* MILTER */
- macdefine(&e->e_macro, A_PERM,
- macid("{rcpt_mailer}"), NULL);
- macdefine(&e->e_macro, A_PERM,
- macid("{rcpt_host}"), NULL);
- macdefine(&e->e_macro, A_PERM,
- macid("{rcpt_addr}"), NULL);
- macdefine(&e->e_macro, A_PERM,
- macid("{dsn_notify}"), NULL);
- if (Errors > 0)
- goto rcpt_done;
-
- /* save in recipient list after ESMTP mods */
- a = recipient(a, &e->e_sendqueue, 0, e);
- if (Errors > 0)
- goto rcpt_done;
-
/* no errors during parsing, but might be a duplicate */
e->e_to = a->q_paddr;
- if (!QS_IS_BADADDR(a->q_state))
+ if (!(Errors > 0) && !QS_IS_BADADDR(a->q_state))
{
if (smtp.sm_nrcpts == 0)
initsys(e);
@@ -2638,12 +2726,20 @@ smtp(nullserver, d_flags, e)
" (will queue)" : "");
smtp.sm_nrcpts++;
}
- else
- {
- /* punt -- should keep message in ADDRESS.... */
- usrerr("550 5.1.1 Addressee unknown");
- }
- rcpt_done:
+
+ /* Is this needed? */
+#if !MILTER
+ rcpt_done:
+#endif /* !MILTER */
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_mailer}"), NULL);
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_host}"), NULL);
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_addr}"), NULL);
+ macdefine(&e->e_macro, A_PERM,
+ macid("{dsn_notify}"), NULL);
+
if (Errors > 0)
{
++n_badrcpts;
@@ -2656,6 +2752,55 @@ smtp(nullserver, d_flags, e)
e->e_flags &= ~(EF_FATALERRS|EF_PM_NOTIFY);
++n_badrcpts;
NBADRCPTS;
+#if MILTER
+ if (smtp.sm_milterlist && smtp.sm_milterize &&
+ !bitset(EF_DISCARD, e->e_flags) &&
+ !milter_cmd_done && milter_cmd_safe)
+ {
+ char state;
+ char *response;
+
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_mailer}"), "error");
+
+ /* how to get the error codes? */
+ if (addr_st.q_host != NULL)
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_host}"),
+ addr_st.q_host);
+ else if (a != NULL && a->q_status != NULL)
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_host}"),
+ a->q_status);
+
+ if (addr_st.q_user != NULL)
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_addr}"),
+ addr_st.q_user);
+ else if (a != NULL && a->q_rstatus != NULL)
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_addr}"),
+ a->q_rstatus);
+
+ response = milter_envrcpt(args, e, &state,
+ true);
+ milter_cmd_done = true;
+ MILTER_REPLY("to");
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_mailer}"), NULL);
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_host}"), NULL);
+ macdefine(&e->e_macro, A_PERM,
+ macid("{rcpt_addr}"), NULL);
+ }
+ if (smtp.sm_milterlist && smtp.sm_milterize &&
+ milter_rcpt_added && milter_cmd_done &&
+ milter_cmd_fail)
+ {
+ (void) removefromlist(addr, &e->e_sendqueue, e);
+ milter_cmd_fail = false;
+ }
+#endif /* MILTER */
}
SM_END_TRY
break;
@@ -2738,7 +2883,7 @@ smtp(nullserver, d_flags, e)
/* do config file checking of the address */
if (rscheck(vrfy ? "check_vrfy" : "check_expn",
p, NULL, e, RSF_RMCOMM,
- 3, NULL, NOQID) != EX_OK ||
+ 3, NULL, NOQID, NULL) != EX_OK ||
Errors > 0)
sm_exc_raisenew_x(&EtypeQuickAbort, 1);
(void) sendtolist(p, NULLADDR, &vrfyqueue, 0, e);
@@ -2834,7 +2979,8 @@ smtp(nullserver, d_flags, e)
*/
if (rscheck("check_etrn", p, NULL, e,
- RSF_RMCOMM, 3, NULL, NOQID) != EX_OK ||
+ RSF_RMCOMM, 3, NULL, NOQID, NULL)
+ != EX_OK ||
Errors > 0)
break;
@@ -2997,7 +3143,7 @@ doquit:
break;
case CMDDBGDEBUG: /* set debug mode */
- tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
+ tTsetup(tTdvect, sizeof(tTdvect), "0-99.1");
tTflag(p);
message("200 2.0.0 Debug set");
break;
@@ -3106,12 +3252,13 @@ smtp_data(smtp, e)
#endif /* MILTER */
bool aborting;
bool doublequeue;
+ bool rv = true;
ADDRESS *a;
ENVELOPE *ee;
char *id;
char *oldid;
+ unsigned int features;
char buf[32];
- bool rv = true;
SmtpPhase = "server DATA";
if (!smtp->sm_gotmail)
@@ -3124,10 +3271,10 @@ smtp_data(smtp, e)
usrerr("503 5.0.0 Need RCPT (recipient)");
return true;
}
- (void) sm_snprintf(buf, sizeof buf, "%u", smtp->sm_nrcpts);
+ (void) sm_snprintf(buf, sizeof(buf), "%u", smtp->sm_nrcpts);
if (rscheck("check_data", buf, NULL, e,
RSF_RMCOMM|RSF_UNSTRUCTURED|RSF_COUNT, 3, NULL,
- e->e_id) != EX_OK)
+ e->e_id, NULL) != EX_OK)
return true;
#if MILTER && SMFI_VERSION > 3
@@ -3233,14 +3380,12 @@ smtp_data(smtp, e)
collect(InChannel, true, NULL, e, true);
/* redefine message size */
- (void) sm_snprintf(buf, sizeof buf, "%ld", e->e_msgsize);
+ (void) sm_snprintf(buf, sizeof(buf), "%ld", e->e_msgsize);
macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), buf);
-#if _FFR_CHECK_EOM
/* rscheck() will set Errors or EF_DISCARD if it trips */
(void) rscheck("check_eom", buf, NULL, e, RSF_UNSTRUCTURED|RSF_COUNT,
- 3, NULL, e->e_id);
-#endif /* _FFR_CHECK_EOM */
+ 3, NULL, e->e_id, NULL);
#if MILTER
milteraccept = true;
@@ -3303,7 +3448,7 @@ smtp_data(smtp, e)
}
/* Milter may have changed message size */
- (void) sm_snprintf(buf, sizeof buf, "%ld", e->e_msgsize);
+ (void) sm_snprintf(buf, sizeof(buf), "%ld", e->e_msgsize);
macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), buf);
/* abort message filters that didn't get the body & log msg is OK */
@@ -3509,7 +3654,7 @@ smtp_data(smtp, e)
{
char msg[MAXLINE];
- expand(MessageAccept, msg, sizeof msg, e);
+ expand(MessageAccept, msg, sizeof(msg), e);
message("250 2.0.0 %s", msg);
}
else
@@ -3603,8 +3748,10 @@ smtp_data(smtp, e)
*/
CurEnv = e;
+ features = e->e_features;
newenvelope(e, e, sm_rpool_new_x(NULL));
e->e_flags = BlankEnvelope.e_flags;
+ e->e_features = features;
/* restore connection quarantining */
if (smtp->sm_quarmsg == NULL)
@@ -3855,24 +4002,68 @@ skipword(p, w)
}
/*
+** RESET_MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line
+**
+** Parameters:
+** e -- the envelope.
+**
+** Returns:
+** none.
+*/
+
+void
+reset_mail_esmtp_args(e)
+ ENVELOPE *e;
+{
+ /* "size": no reset */
+
+ /* "body" */
+ SevenBitInput = SevenBitInput_Saved;
+ e->e_bodytype = NULL;
+
+ /* "envid" */
+ e->e_envid = NULL;
+ macdefine(&e->e_macro, A_PERM, macid("{dsn_envid}"), NULL);
+
+ /* "ret" */
+ e->e_flags &= EF_RET_PARAM;
+ e->e_flags &= EF_NO_BODY_RETN;
+ macdefine(&e->e_macro, A_TEMP, macid("{dsn_ret}"), NULL);
+
+#if SASL
+ /* "auth" */
+ macdefine(&e->e_macro, A_TEMP, macid("{auth_author}"), NULL);
+ e->e_auth_param = "";
+# if _FFR_AUTH_PASSING
+ macdefine(&BlankEnvelope.e_macro, A_PERM,
+ macid("{auth_author}"), NULL);
+# endif /* _FFR_AUTH_PASSING */
+#endif /* SASL */
+
+ /* "by" */
+ e->e_deliver_by = 0;
+ e->e_dlvr_flag = 0;
+}
+
+/*
** MAIL_ESMTP_ARGS -- process ESMTP arguments from MAIL line
**
** Parameters:
+** a -- address (unused, for compatibility with rcpt_esmtp_args)
** kp -- the parameter key.
** vp -- the value of that parameter.
** e -- the envelope.
-** features -- current server features
**
** Returns:
** none.
*/
-static void
-mail_esmtp_args(kp, vp, e, features)
+void
+mail_esmtp_args(a, kp, vp, e)
+ ADDRESS *a;
char *kp;
char *vp;
ENVELOPE *e;
- unsigned int features;
{
if (sm_strcasecmp(kp, "size") == 0)
{
@@ -3919,7 +4110,7 @@ mail_esmtp_args(kp, vp, e, features)
}
else if (sm_strcasecmp(kp, "envid") == 0)
{
- if (!bitset(SRV_OFFER_DSN, features))
+ if (!bitset(SRV_OFFER_DSN, e->e_features))
{
usrerr("504 5.7.0 Sorry, ENVID not supported, we do not allow DSN");
/* NOTREACHED */
@@ -3945,7 +4136,7 @@ mail_esmtp_args(kp, vp, e, features)
}
else if (sm_strcasecmp(kp, "ret") == 0)
{
- if (!bitset(SRV_OFFER_DSN, features))
+ if (!bitset(SRV_OFFER_DSN, e->e_features))
{
usrerr("504 5.7.0 Sorry, RET not supported, we do not allow DSN");
/* NOTREACHED */
@@ -4018,7 +4209,7 @@ mail_esmtp_args(kp, vp, e, features)
QuickAbort = false;
if (strcmp(auth_param, "<>") != 0 &&
(rscheck("trust_auth", auth_param, NULL, e, RSF_RMCOMM,
- 9, NULL, NOQID) != EX_OK || Errors > 0))
+ 9, NULL, NOQID, NULL) != EX_OK || Errors > 0))
{
if (tTd(95, 8))
{
@@ -4130,6 +4321,7 @@ mail_esmtp_args(kp, vp, e, features)
/* NOTREACHED */
}
}
+
/*
** RCPT_ESMTP_ARGS -- process ESMTP arguments from RCPT line
**
@@ -4138,25 +4330,23 @@ mail_esmtp_args(kp, vp, e, features)
** kp -- the parameter key.
** vp -- the value of that parameter.
** e -- the envelope.
-** features -- current server features
**
** Returns:
** none.
*/
-static void
-rcpt_esmtp_args(a, kp, vp, e, features)
+void
+rcpt_esmtp_args(a, kp, vp, e)
ADDRESS *a;
char *kp;
char *vp;
ENVELOPE *e;
- unsigned int features;
{
if (sm_strcasecmp(kp, "notify") == 0)
{
char *p;
- if (!bitset(SRV_OFFER_DSN, features))
+ if (!bitset(SRV_OFFER_DSN, e->e_features))
{
usrerr("504 5.7.0 Sorry, NOTIFY not supported, we do not allow DSN");
/* NOTREACHED */
@@ -4197,7 +4387,7 @@ rcpt_esmtp_args(a, kp, vp, e, features)
}
else if (sm_strcasecmp(kp, "orcpt") == 0)
{
- if (!bitset(SRV_OFFER_DSN, features))
+ if (!bitset(SRV_OFFER_DSN, e->e_features))
{
usrerr("504 5.7.0 Sorry, ORCPT not supported, we do not allow DSN");
/* NOTREACHED */
@@ -4251,11 +4441,11 @@ printvrfyaddr(a, last, vrfy)
if (vrfy && a->q_mailer != NULL &&
!bitnset(M_VRFY250, a->q_mailer->m_flags))
- (void) sm_strlcpy(fmtbuf, "252", sizeof fmtbuf);
+ (void) sm_strlcpy(fmtbuf, "252", sizeof(fmtbuf));
else
- (void) sm_strlcpy(fmtbuf, "250", sizeof fmtbuf);
+ (void) sm_strlcpy(fmtbuf, "250", sizeof(fmtbuf));
fmtbuf[3] = last ? ' ' : '-';
- (void) sm_strlcpy(&fmtbuf[4], "2.1.5 ", sizeof fmtbuf - 4);
+ (void) sm_strlcpy(&fmtbuf[4], "2.1.5 ", sizeof(fmtbuf) - 4);
if (a->q_fullname == NULL)
{
if ((a->q_mailer == NULL ||
@@ -4263,10 +4453,10 @@ printvrfyaddr(a, last, vrfy)
sm_strcasecmp(a->q_mailer->m_addrtype, "rfc822") == 0) &&
strchr(a->q_user, '@') == NULL)
(void) sm_strlcpy(&fmtbuf[OFFF], "<%s@%s>",
- sizeof fmtbuf - OFFF);
+ sizeof(fmtbuf) - OFFF);
else
(void) sm_strlcpy(&fmtbuf[OFFF], "<%s>",
- sizeof fmtbuf - OFFF);
+ sizeof(fmtbuf) - OFFF);
message(fmtbuf, a->q_user, MyHostName);
}
else
@@ -4276,10 +4466,10 @@ printvrfyaddr(a, last, vrfy)
sm_strcasecmp(a->q_mailer->m_addrtype, "rfc822") == 0) &&
strchr(a->q_user, '@') == NULL)
(void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s@%s>",
- sizeof fmtbuf - OFFF);
+ sizeof(fmtbuf) - OFFF);
else
(void) sm_strlcpy(&fmtbuf[OFFF], "%s <%s>",
- sizeof fmtbuf - OFFF);
+ sizeof(fmtbuf) - OFFF);
message(fmtbuf, a->q_fullname, a->q_user, MyHostName);
}
}
@@ -4600,7 +4790,7 @@ help(topic, e)
len = strlen(topic);
- while (sm_io_fgets(hf, SM_TIME_DEFAULT, buf, sizeof buf) != NULL)
+ while (sm_io_fgets(hf, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL)
{
if (buf[0] == '#')
{
@@ -4633,8 +4823,13 @@ help(topic, e)
fixcrlf(p, true);
if (foundvers >= 2)
{
- translate_dollars(p);
- expand(p, inp, sizeof inp, e);
+ char *lbp;
+ int lbs = sizeof(buf) - (p - buf);
+
+ lbp = translate_dollars(p, p, &lbs);
+ expand(lbp, inp, sizeof(inp), e);
+ if (p != lbp)
+ sm_free(lbp);
p = inp;
}
message("214-2.0.0 %s", p);
diff --git a/contrib/sendmail/src/stab.c b/contrib/sendmail/src/stab.c
index 2a71514..6dacdfa 100644
--- a/contrib/sendmail/src/stab.c
+++ b/contrib/sendmail/src/stab.c
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: stab.c,v 8.88 2003/05/21 15:36:30 ca Exp $")
+SM_RCSID("@(#)$Id: stab.c,v 8.89 2006/08/15 23:24:58 ca Exp $")
/*
** STAB -- manage the symbol table
@@ -110,72 +110,72 @@ stab(name, type, op)
switch (type)
{
case ST_CLASS:
- len = sizeof s->s_class;
+ len = sizeof(s->s_class);
break;
case ST_ADDRESS:
- len = sizeof s->s_address;
+ len = sizeof(s->s_address);
break;
case ST_MAILER:
- len = sizeof s->s_mailer;
+ len = sizeof(s->s_mailer);
break;
case ST_ALIAS:
- len = sizeof s->s_alias;
+ len = sizeof(s->s_alias);
break;
case ST_MAPCLASS:
- len = sizeof s->s_mapclass;
+ len = sizeof(s->s_mapclass);
break;
case ST_MAP:
- len = sizeof s->s_map;
+ len = sizeof(s->s_map);
break;
case ST_HOSTSIG:
- len = sizeof s->s_hostsig;
+ len = sizeof(s->s_hostsig);
break;
case ST_NAMECANON:
- len = sizeof s->s_namecanon;
+ len = sizeof(s->s_namecanon);
break;
case ST_MACRO:
- len = sizeof s->s_macro;
+ len = sizeof(s->s_macro);
break;
case ST_RULESET:
- len = sizeof s->s_ruleset;
+ len = sizeof(s->s_ruleset);
break;
case ST_HEADER:
- len = sizeof s->s_header;
+ len = sizeof(s->s_header);
break;
case ST_SERVICE:
- len = sizeof s->s_service;
+ len = sizeof(s->s_service);
break;
#if LDAPMAP
case ST_LMAP:
- len = sizeof s->s_lmap;
+ len = sizeof(s->s_lmap);
break;
#endif /* LDAPMAP */
#if MILTER
case ST_MILTER:
- len = sizeof s->s_milter;
+ len = sizeof(s->s_milter);
break;
#endif /* MILTER */
case ST_QUEUE:
- len = sizeof s->s_quegrp;
+ len = sizeof(s->s_quegrp);
break;
#if SOCKETMAP
case ST_SOCKETMAP:
- len = sizeof s->s_socketmap;
+ len = sizeof(s->s_socketmap);
break;
#endif /* SOCKETMAP */
@@ -189,15 +189,15 @@ stab(name, type, op)
*/
if (type >= ST_MCI)
- len = sizeof s->s_mci;
+ len = sizeof(s->s_mci);
else
{
syserr("stab: unknown symbol type %d", type);
- len = sizeof s->s_value;
+ len = sizeof(s->s_value);
}
break;
}
- len += sizeof *s - sizeof s->s_value;
+ len += sizeof(*s) - sizeof(s->s_value);
if (tTd(36, 15))
sm_dprintf("size of stab entry: %d\n", len);
diff --git a/contrib/sendmail/src/stats.c b/contrib/sendmail/src/stats.c
index 5725219..16a9c6d 100644
--- a/contrib/sendmail/src/stats.c
+++ b/contrib/sendmail/src/stats.c
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: stats.c,v 8.56 2002/06/27 22:47:37 gshapiro Exp $")
+SM_RCSID("@(#)$Id: stats.c,v 8.57 2006/08/15 23:24:58 ca Exp $")
#include <sendmail/mailstats.h>
@@ -112,7 +112,7 @@ void
clearstats()
{
/* clear the structure to avoid future disappointment */
- memset(&Stat, '\0', sizeof Stat);
+ memset(&Stat, '\0', sizeof(Stat));
GotStats = false;
}
/*
@@ -143,7 +143,7 @@ poststats(sfile)
entered = true;
(void) time(&Stat.stat_itime);
- Stat.stat_size = sizeof Stat;
+ Stat.stat_size = sizeof(Stat);
Stat.stat_magic = STAT_MAGIC;
Stat.stat_version = STAT_VERSION;
@@ -162,8 +162,8 @@ poststats(sfile)
entered = false;
return;
}
- if (read(fd, (char *) &stats, sizeof stats) == sizeof stats &&
- stats.stat_size == sizeof stats &&
+ if (read(fd, (char *) &stats, sizeof(stats)) == sizeof(stats) &&
+ stats.stat_size == sizeof(stats) &&
stats.stat_magic == Stat.stat_magic &&
stats.stat_version == Stat.stat_version)
{
@@ -185,11 +185,11 @@ poststats(sfile)
stats.stat_cf += Stat.stat_cf;
}
else
- memmove((char *) &stats, (char *) &Stat, sizeof stats);
+ memmove((char *) &stats, (char *) &Stat, sizeof(stats));
/* write out results */
(void) lseek(fd, (off_t) 0, 0);
- (void) write(fd, (char *) &stats, sizeof stats);
+ (void) write(fd, (char *) &stats, sizeof(stats));
(void) close(fd);
/* clear the structure to avoid future disappointment */
diff --git a/contrib/sendmail/src/timers.c b/contrib/sendmail/src/timers.c
index fdace01..43dc07d 100644
--- a/contrib/sendmail/src/timers.c
+++ b/contrib/sendmail/src/timers.c
@@ -11,7 +11,7 @@
*/
#include <sm/gen.h>
-SM_RCSID("@(#)$Id: timers.c,v 8.25 2005/06/14 23:07:23 ca Exp $")
+SM_RCSID("@(#)$Id: timers.c,v 8.26 2006/08/15 23:24:58 ca Exp $")
#if _FFR_TIMERS
# include <sys/types.h>
@@ -40,7 +40,7 @@ warntimer(msg, va_alist)
return;
# endif /* 0 */
SM_VA_START(ap, msg);
- (void) sm_vsnprintf(buf, sizeof buf, msg, ap);
+ (void) sm_vsnprintf(buf, sizeof(buf), msg, ap);
SM_VA_END(ap);
sm_syslog(LOG_NOTICE, CurEnv->e_id, "%s; e_timers=0x%lx",
buf, (unsigned long) &CurEnv->e_timers);
@@ -50,7 +50,7 @@ static void
zerotimer(ptimer)
TIMER *ptimer;
{
- memset(ptimer, '\0', sizeof *ptimer);
+ memset(ptimer, '\0', sizeof(*ptimer));
}
static void
@@ -130,7 +130,7 @@ getinctimer(ptimer)
if (BaseTimer.ti_wall_sec == 0)
{
/* first call */
- memset(ptimer, '\0', sizeof *ptimer);
+ memset(ptimer, '\0', sizeof(*ptimer));
}
else
{
@@ -223,7 +223,7 @@ strtimer(ptimer)
{
static char buf[40];
- (void) sm_snprintf(buf, sizeof buf, "%ld.%06ldr/%ld.%06ldc",
+ (void) sm_snprintf(buf, sizeof(buf), "%ld.%06ldr/%ld.%06ldc",
ptimer->ti_wall_sec, ptimer->ti_wall_usec,
ptimer->ti_cpu_sec, ptimer->ti_cpu_usec);
return buf;
diff --git a/contrib/sendmail/src/tls.c b/contrib/sendmail/src/tls.c
index 71fcdc3..1a213ca 100644
--- a/contrib/sendmail/src/tls.c
+++ b/contrib/sendmail/src/tls.c
@@ -10,7 +10,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: tls.c,v 8.105 2006/05/11 22:59:31 ca Exp $")
+SM_RCSID("@(#)$Id: tls.c,v 8.107 2006/10/12 21:35:11 ca Exp $")
#if STARTTLS
# include <openssl/err.h>
@@ -213,7 +213,7 @@ tls_rand_init(randfile, logl)
DontBlameSendmail))
{
/* add this even if fstat() failed */
- RAND_seed((void *) &st, sizeof st);
+ RAND_seed((void *) &st, sizeof(st));
}
(void) close(fd);
}
@@ -251,7 +251,7 @@ tls_rand_init(randfile, logl)
r = get_random();
(void) memcpy(buf + i, (void *) &r, sizeof(long));
}
- RAND_seed(buf, sizeof buf);
+ RAND_seed(buf, sizeof(buf));
if (LogLevel > logl)
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS: Warning: random number generator not properly seeded");
@@ -747,8 +747,10 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam)
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=%s, error: BIO_new=failed", who);
}
+ else
+ store = NULL;
# if _FFR_CRLPATH
- if (CRLPath != NULL)
+ if (CRLPath != NULL && store != NULL)
{
X509_LOOKUP *lookup;
@@ -1175,9 +1177,9 @@ tls_get_info(ssl, srv, host, mac, certreq)
macdefine(mac, A_TEMP, macid("{cipher}"),
(char *) SSL_CIPHER_get_name(c));
b = SSL_CIPHER_get_bits(c, &r);
- (void) sm_snprintf(bitstr, sizeof bitstr, "%d", b);
+ (void) sm_snprintf(bitstr, sizeof(bitstr), "%d", b);
macdefine(mac, A_TEMP, macid("{cipher_bits}"), bitstr);
- (void) sm_snprintf(bitstr, sizeof bitstr, "%d", r);
+ (void) sm_snprintf(bitstr, sizeof(bitstr), "%d", r);
macdefine(mac, A_TEMP, macid("{alg_bits}"), bitstr);
s = SSL_CIPHER_get_version(c);
if (s == NULL)
@@ -1198,19 +1200,19 @@ tls_get_info(ssl, srv, host, mac, certreq)
char buf[MAXNAME];
X509_NAME_oneline(X509_get_subject_name(cert),
- buf, sizeof buf);
+ buf, sizeof(buf));
macdefine(mac, A_TEMP, macid("{cert_subject}"),
xtextify(buf, "<>\")"));
X509_NAME_oneline(X509_get_issuer_name(cert),
- buf, sizeof buf);
+ buf, sizeof(buf));
macdefine(mac, A_TEMP, macid("{cert_issuer}"),
xtextify(buf, "<>\")"));
X509_NAME_get_text_by_NID(X509_get_subject_name(cert),
- NID_commonName, buf, sizeof buf);
+ NID_commonName, buf, sizeof(buf));
macdefine(mac, A_TEMP, macid("{cn_subject}"),
xtextify(buf, "<>\")"));
X509_NAME_get_text_by_NID(X509_get_issuer_name(cert),
- NID_commonName, buf, sizeof buf);
+ NID_commonName, buf, sizeof(buf));
macdefine(mac, A_TEMP, macid("{cn_issuer}"),
xtextify(buf, "<>\")"));
n = 0;
@@ -1564,7 +1566,7 @@ tls_verify_log(ok, ctx, name)
return 0;
}
- X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof buf);
+ X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
sm_syslog(LOG_INFO, NOQID,
"STARTTLS: %s cert verify: depth=%d %s, state=%d, reason=%s",
name, depth, buf, ok, X509_verify_cert_error_string(reason));
diff --git a/contrib/sendmail/src/udb.c b/contrib/sendmail/src/udb.c
index 8331230..29470e7 100644
--- a/contrib/sendmail/src/udb.c
+++ b/contrib/sendmail/src/udb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2003, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -12,15 +12,17 @@
*/
#include <sendmail.h>
+#include "map.h"
#if USERDB
-SM_RCSID("@(#)$Id: udb.c,v 8.161 2005/08/31 21:34:20 ca Exp $ (with USERDB)")
+SM_RCSID("@(#)$Id: udb.c,v 8.164 2006/12/19 19:49:51 ca Exp $ (with USERDB)")
#else /* USERDB */
-SM_RCSID("@(#)$Id: udb.c,v 8.161 2005/08/31 21:34:20 ca Exp $ (without USERDB)")
+SM_RCSID("@(#)$Id: udb.c,v 8.164 2006/12/19 19:49:51 ca Exp $ (without USERDB)")
#endif /* USERDB */
#if USERDB
+#include <sm/sendmail.h>
# if NEWDB
# include "sm/bdb.h"
# else /* NEWDB */
@@ -139,8 +141,8 @@ udbexpand(a, sendq, aliaslevel, e)
char *user;
char keybuf[MAXUDBKEY];
- memset(&key, '\0', sizeof key);
- memset(&info, '\0', sizeof info);
+ memset(&key, '\0', sizeof(key));
+ memset(&info, '\0', sizeof(info));
if (tTd(28, 1))
sm_dprintf("udbexpand(%s)\n", a->q_paddr);
@@ -173,10 +175,10 @@ udbexpand(a, sendq, aliaslevel, e)
if (user[0] == ':')
return EX_OK;
- keylen = sm_strlcpyn(keybuf, sizeof keybuf, 2, user, ":maildrop");
+ keylen = sm_strlcpyn(keybuf, sizeof(keybuf), 2, user, ":maildrop");
/* if name is too long, assume it won't match */
- if (keylen >= sizeof keybuf)
+ if (keylen >= sizeof(keybuf))
return EX_OK;
/* build actual database key */
@@ -196,8 +198,8 @@ udbexpand(a, sendq, aliaslevel, e)
user = userbuf;
userbuf[0] = '\0';
- usersize = sizeof userbuf;
- userleft = sizeof userbuf - 1;
+ usersize = sizeof(userbuf);
+ userleft = sizeof(userbuf) - 1;
/*
** Select action based on entry type.
@@ -350,9 +352,9 @@ udbexpand(a, sendq, aliaslevel, e)
** it into the envelope.
*/
- memset(&key, '\0', sizeof key);
- memset(&info, '\0', sizeof info);
- (void) sm_strlcpyn(keybuf, sizeof keybuf, 2, a->q_user,
+ memset(&key, '\0', sizeof(key));
+ memset(&info, '\0', sizeof(info));
+ (void) sm_strlcpyn(keybuf, sizeof(keybuf), 2, a->q_user,
":mailsender");
keylen = strlen(keybuf);
key.data = keybuf;
@@ -426,7 +428,7 @@ udbexpand(a, sendq, aliaslevel, e)
break;
}
if (strlen(hp->po_name) + strlen(hp->po_host) >
- sizeof pobuf - 2)
+ sizeof(pobuf) - 2)
{
if (tTd(28, 2))
sm_dprintf("hes_getmailhost(%s): expansion too long: %.30s@%.30s\n",
@@ -436,7 +438,7 @@ udbexpand(a, sendq, aliaslevel, e)
break;
}
info.data = pobuf;
- (void) sm_snprintf(pobuf, sizeof pobuf,
+ (void) sm_snprintf(pobuf, sizeof(pobuf),
"%s@%s", hp->po_name, hp->po_host);
info.size = strlen(info.data);
# else /* HES_GETMAILHOST */
@@ -484,7 +486,7 @@ udbexpand(a, sendq, aliaslevel, e)
** it into the envelope.
*/
- (void) sm_strlcpyn(keybuf, sizeof keybuf, 2, a->q_user,
+ (void) sm_strlcpyn(keybuf, sizeof(keybuf), 2, a->q_user,
":mailsender");
keylen = strlen(keybuf);
key.data = keybuf;
@@ -618,9 +620,9 @@ udbmatch(user, field, rpool)
/* long names can never match and are a pain to deal with */
i = strlen(field);
- if (i < sizeof "maildrop")
- i = sizeof "maildrop";
- if ((strlen(user) + i) > sizeof keybuf - 4)
+ if (i < sizeof("maildrop"))
+ i = sizeof("maildrop");
+ if ((strlen(user) + i) > sizeof(keybuf) - 4)
return NULL;
/* names beginning with colons indicate metadata */
@@ -628,7 +630,7 @@ udbmatch(user, field, rpool)
return NULL;
/* build database key */
- (void) sm_strlcpyn(keybuf, sizeof keybuf, 3, user, ":", field);
+ (void) sm_strlcpyn(keybuf, sizeof(keybuf), 3, user, ":", field);
keylen = strlen(keybuf);
for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++)
@@ -641,8 +643,8 @@ udbmatch(user, field, rpool)
{
# if NEWDB
case UDB_DBFETCH:
- memset(&key, '\0', sizeof key);
- memset(&info, '\0', sizeof info);
+ memset(&key, '\0', sizeof(key));
+ memset(&info, '\0', sizeof(info));
key.data = keybuf;
key.size = keylen;
# if DB_VERSION_MAJOR < 2
@@ -700,7 +702,7 @@ udbmatch(user, field, rpool)
*/
/* build database key */
- (void) sm_strlcpyn(keybuf, sizeof keybuf, 2, user, ":maildrop");
+ (void) sm_strlcpyn(keybuf, sizeof(keybuf), 2, user, ":maildrop");
keylen = strlen(keybuf);
for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++)
@@ -712,8 +714,8 @@ udbmatch(user, field, rpool)
/* get the default case for this database */
if (up->udb_default == NULL)
{
- memset(&key, '\0', sizeof key);
- memset(&info, '\0', sizeof info);
+ memset(&key, '\0', sizeof(key));
+ memset(&info, '\0', sizeof(info));
key.data = ":default:mailname";
key.size = strlen(key.data);
# if DB_VERSION_MAJOR < 2
@@ -740,8 +742,8 @@ udbmatch(user, field, rpool)
continue;
/* we have a default case -- verify user:maildrop */
- memset(&key, '\0', sizeof key);
- memset(&info, '\0', sizeof info);
+ memset(&key, '\0', sizeof(key));
+ memset(&info, '\0', sizeof(info));
key.data = keybuf;
key.size = keylen;
# if DB_VERSION_MAJOR < 2
@@ -852,8 +854,8 @@ udb_map_lookup(map, name, av, statp)
{
int keysize = strlen(name);
- if (keysize > sizeof keybuf - 1)
- keysize = sizeof keybuf - 1;
+ if (keysize > sizeof(keybuf) - 1)
+ keysize = sizeof(keybuf) - 1;
memmove(keybuf, name, keysize);
keybuf[keysize] = '\0';
makelower(keybuf);
@@ -1234,7 +1236,7 @@ hes_udb_get(key, info)
char **hp;
char kbuf[MAXUDBKEY + 1];
- if (sm_strlcpy(kbuf, key->data, sizeof kbuf) >= sizeof kbuf)
+ if (sm_strlcpy(kbuf, key->data, sizeof(kbuf)) >= sizeof(kbuf))
return 0;
name = kbuf;
type = strrchr(name, ':');
diff --git a/contrib/sendmail/src/usersmtp.c b/contrib/sendmail/src/usersmtp.c
index 0c5195e..622bbb8 100644
--- a/contrib/sendmail/src/usersmtp.c
+++ b/contrib/sendmail/src/usersmtp.c
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: usersmtp.c,v 8.467 2006/03/19 06:07:56 ca Exp $")
+SM_RCSID("@(#)$Id: usersmtp.c,v 8.469 2006/12/13 20:11:15 ca Exp $")
#include <sysexits.h>
@@ -541,6 +541,10 @@ static sasl_callback_t callbacks[] =
**
** Side Effects:
** checks/sets sasl_clt_init.
+**
+** Note:
+** Callbacks are ignored if sasl_client_init() has
+** been called before (by a library such as libnss_ldap)
*/
static bool sasl_clt_init = false;
@@ -789,7 +793,7 @@ readauth(filename, safe, sai, rpool)
lc = 0;
while (lc <= SASL_MECHLIST &&
- sm_io_fgets(f, SM_TIME_DEFAULT, buf, sizeof buf) != NULL)
+ sm_io_fgets(f, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL)
{
if (buf[0] != '#')
{
@@ -1578,9 +1582,15 @@ attemptauth(m, mci, e, sai)
/* make a new client sasl connection */
# if SASL >= 20000
+ /*
+ ** We provide the callbacks again because global callbacks in
+ ** sasl_client_init() are ignored if SASL has been initialized
+ ** before, for example, by a library such as libnss-ldap.
+ */
+
saslresult = sasl_client_new(bitnset(M_LMTP, m->m_flags) ? "lmtp"
: "smtp",
- CurHostName, NULL, NULL, NULL, 0,
+ CurHostName, NULL, NULL, callbacks, 0,
&mci->mci_conn);
# else /* SASL >= 20000 */
saslresult = sasl_client_new(bitnset(M_LMTP, m->m_flags) ? "lmtp"
@@ -1591,7 +1601,7 @@ attemptauth(m, mci, e, sai)
return EX_TEMPFAIL;
/* set properties */
- (void) memset(&ssp, '\0', sizeof ssp);
+ (void) memset(&ssp, '\0', sizeof(ssp));
/* XXX should these be options settable via .cf ? */
{
@@ -1650,7 +1660,7 @@ attemptauth(m, mci, e, sai)
break;
}
if (iptostring(&CurHostAddr, addrsize,
- remoteip, sizeof remoteip))
+ remoteip, sizeof(remoteip)))
{
if (sasl_setprop(mci->mci_conn, SASL_IPREMOTEPORT,
remoteip) != SASL_OK)
@@ -1662,7 +1672,7 @@ attemptauth(m, mci, e, sai)
(struct sockaddr *) &saddr_l, &addrsize) == 0)
{
if (iptostring(&saddr_l, addrsize,
- localip, sizeof localip))
+ localip, sizeof(localip)))
{
if (sasl_setprop(mci->mci_conn,
SASL_IPLOCALPORT,
@@ -2011,7 +2021,7 @@ smtpmailfrom(m, mci, e)
/* set up appropriate options to include */
if (bitset(MCIF_SIZE, mci->mci_flags) && e->e_msgsize > 0)
{
- (void) sm_snprintf(optbuf, sizeof optbuf, " SIZE=%ld",
+ (void) sm_snprintf(optbuf, sizeof(optbuf), " SIZE=%ld",
e->e_msgsize);
bufp = &optbuf[strlen(optbuf)];
}
@@ -2138,7 +2148,7 @@ smtpmailfrom(m, mci, e)
!bitnset(M_NO_NULL_FROM, m->m_flags))
buf[0] = '\0';
else
- expand("\201g", buf, sizeof buf, e);
+ expand("\201g", buf, sizeof(buf), e);
if (buf[0] == '<')
{
/* strip off <angle brackets> (put back on below) */
@@ -2296,7 +2306,7 @@ smtprcpt(to, m, mci, e, ctladdr, xstart)
/*
** Warning: in the following it is assumed that the free space
- ** in bufp is sizeof optbuf
+ ** in bufp is sizeof(optbuf)
*/
if (bitset(MCIF_DSN, mci->mci_flags))
@@ -2320,30 +2330,30 @@ smtprcpt(to, m, mci, e, ctladdr, xstart)
{
bool firstone = true;
- (void) sm_strlcat(bufp, " NOTIFY=", sizeof optbuf);
+ (void) sm_strlcat(bufp, " NOTIFY=", sizeof(optbuf));
if (bitset(QPINGONSUCCESS, to->q_flags))
{
- (void) sm_strlcat(bufp, "SUCCESS", sizeof optbuf);
+ (void) sm_strlcat(bufp, "SUCCESS", sizeof(optbuf));
firstone = false;
}
if (bitset(QPINGONFAILURE, to->q_flags))
{
if (!firstone)
(void) sm_strlcat(bufp, ",",
- sizeof optbuf);
- (void) sm_strlcat(bufp, "FAILURE", sizeof optbuf);
+ sizeof(optbuf));
+ (void) sm_strlcat(bufp, "FAILURE", sizeof(optbuf));
firstone = false;
}
if (bitset(QPINGONDELAY, to->q_flags))
{
if (!firstone)
(void) sm_strlcat(bufp, ",",
- sizeof optbuf);
- (void) sm_strlcat(bufp, "DELAY", sizeof optbuf);
+ sizeof(optbuf));
+ (void) sm_strlcat(bufp, "DELAY", sizeof(optbuf));
firstone = false;
}
if (firstone)
- (void) sm_strlcat(bufp, "NEVER", sizeof optbuf);
+ (void) sm_strlcat(bufp, "NEVER", sizeof(optbuf));
bufp += strlen(bufp);
}
@@ -3122,7 +3132,7 @@ reply(m, mci, e, timeout, pfunc, enhstat, rtype)
if (errno == 0)
{
(void) sm_snprintf(SmtpReplyBuffer,
- sizeof SmtpReplyBuffer,
+ sizeof(SmtpReplyBuffer),
"421 4.4.1 Connection reset by %s",
CURHOSTNAME);
#ifdef ECONNRESET
@@ -3242,7 +3252,7 @@ reply(m, mci, e, timeout, pfunc, enhstat, rtype)
/* save temporary failure messages for posterity */
if (SmtpReplyBuffer[0] == '4')
- (void) sm_strlcpy(SmtpError, SmtpReplyBuffer, sizeof SmtpError);
+ (void) sm_strlcpy(SmtpError, SmtpReplyBuffer, sizeof(SmtpError));
/* reply code 421 is "Service Shutting Down" */
if (r == SMTPCLOSING && mci->mci_state != MCIS_SSD &&
@@ -3285,7 +3295,7 @@ smtpmessage(f, m, mci, va_alist)
SM_VA_LOCAL_DECL
SM_VA_START(ap, mci);
- (void) sm_vsnprintf(SmtpMsgBuffer, sizeof SmtpMsgBuffer, f, ap);
+ (void) sm_vsnprintf(SmtpMsgBuffer, sizeof(SmtpMsgBuffer), f, ap);
SM_VA_END(ap);
if (tTd(18, 1) || Verbose)
diff --git a/contrib/sendmail/src/util.c b/contrib/sendmail/src/util.c
index c27cd90..af781ef 100644
--- a/contrib/sendmail/src/util.c
+++ b/contrib/sendmail/src/util.c
@@ -13,8 +13,9 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: util.c,v 8.394 2006/05/03 23:55:29 ca Exp $")
+SM_RCSID("@(#)$Id: util.c,v 8.410 2006/12/18 18:36:44 ca Exp $")
+#include <sm/sendmail.h>
#include <sysexits.h>
#include <sm/xtrap.h>
@@ -180,6 +181,7 @@ rfc822_string(s)
/* unbalanced '"' or '(' */
return !quoted && commentlev == 0;
}
+
/*
** SHORTEN_RFC822_STRING -- Truncate and rebalance an RFC822 string
**
@@ -288,6 +290,7 @@ increment:
}
return modified;
}
+
/*
** FIND_CHARACTER -- find an unquoted character in an RFC822 string
**
@@ -383,7 +386,6 @@ check_bodytype(bodytype)
return BODYTYPE_ILLEGAL;
}
-#if _FFR_BESTMX_BETTER_TRUNCATION || _FFR_DNSMAP_MULTI
/*
** TRUNCATE_AT_DELIM -- truncate string at a delimiter and append "..."
**
@@ -426,7 +428,7 @@ truncate_at_delim(str, len, delim)
else
str[0] = '\0';
}
-#endif /* _FFR_BESTMX_BETTER_TRUNCATION || _FFR_DNSMAP_MULTI */
+
/*
** XALLOC -- Allocate memory, raise an exception on error
**
@@ -472,6 +474,7 @@ xalloc(sz)
}
return p;
}
+
/*
** COPYPLIST -- copy list of pointers.
**
@@ -504,8 +507,8 @@ copyplist(list, copycont, rpool)
vp++;
- newvp = (char **) sm_rpool_malloc_x(rpool, (vp - list) * sizeof *vp);
- memmove((char *) newvp, (char *) list, (int) (vp - list) * sizeof *vp);
+ newvp = (char **) sm_rpool_malloc_x(rpool, (vp - list) * sizeof(*vp));
+ memmove((char *) newvp, (char *) list, (int) (vp - list) * sizeof(*vp));
if (copycont)
{
@@ -515,6 +518,7 @@ copyplist(list, copycont, rpool)
return newvp;
}
+
/*
** COPYQUEUE -- copy address queue.
**
@@ -543,7 +547,7 @@ copyqueue(addr, rpool)
if (!QS_IS_DEAD(addr->q_state))
{
newaddr = (ADDRESS *) sm_rpool_malloc_x(rpool,
- sizeof *newaddr);
+ sizeof(*newaddr));
STRUCTCOPY(*addr, *newaddr);
*tail = newaddr;
tail = &newaddr->q_next;
@@ -554,6 +558,7 @@ copyqueue(addr, rpool)
return ret;
}
+
/*
** LOG_SENDMAIL_PID -- record sendmail pid and command line.
**
@@ -582,7 +587,7 @@ log_sendmail_pid(e)
sff = SFF_NOLINK|SFF_ROOTOK|SFF_REGONLY|SFF_CREAT|SFF_NBLOCK;
if (TrustedUid != 0 && RealUid == TrustedUid)
sff |= SFF_OPENASROOT;
- expand(PidFile, pidpath, sizeof pidpath, e);
+ expand(PidFile, pidpath, sizeof(pidpath), e);
Pidf = safefopen(pidpath, O_WRONLY|O_TRUNC, FileMode, sff);
if (Pidf == NULL)
{
@@ -666,6 +671,7 @@ set_delivery_mode(mode, e)
buf[1] = '\0';
macdefine(&e->e_macro, A_TEMP, macid("{deliveryMode}"), buf);
}
+
/*
** SET_OP_MODE -- set and record the op mode
**
@@ -692,6 +698,7 @@ set_op_mode(mode)
buf[1] = '\0';
macdefine(&BlankEnvelope.e_macro, A_TEMP, MID_OPMODE, buf);
}
+
/*
** PRINTAV -- print argument vector.
**
@@ -709,7 +716,7 @@ set_op_mode(mode)
void
printav(fp, av)
SM_FILE_T *fp;
- register char **av;
+ char **av;
{
while (*av != NULL)
{
@@ -717,10 +724,14 @@ printav(fp, av)
sm_dprintf("\n\t%08lx=", (unsigned long) *av);
else
(void) sm_io_putc(fp, SM_TIME_DEFAULT, ' ');
- xputs(fp, *av++);
+ if (tTd(0, 99))
+ sm_dprintf("%s", str2prt(*av++));
+ else
+ xputs(fp, *av++);
}
(void) sm_io_putc(fp, SM_TIME_DEFAULT, '\n');
}
+
/*
** XPUTS -- put string doing control escapes.
**
@@ -738,10 +749,10 @@ printav(fp, av)
void
xputs(fp, s)
SM_FILE_T *fp;
- register const char *s;
+ const char *s;
{
- register int c;
- register struct metamac *mp;
+ int c;
+ struct metamac *mp;
bool shiftout = false;
extern struct metamac MetaMacros[];
static SM_DEBUG_T DebugANSI = SM_DEBUG_INITIALIZER("ANSI",
@@ -758,19 +769,19 @@ xputs(fp, s)
if (sm_debug_active(&DebugANSI, 1))
{
TermEscape.te_rv_on = "\033[7m";
- TermEscape.te_rv_off = "\033[0m";
+ TermEscape.te_normal = "\033[0m";
}
else
{
TermEscape.te_rv_on = "";
- TermEscape.te_rv_off = "";
+ TermEscape.te_normal = "";
}
}
if (s == NULL)
{
(void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s<null>%s",
- TermEscape.te_rv_on, TermEscape.te_rv_off);
+ TermEscape.te_rv_on, TermEscape.te_normal);
return;
}
while ((c = (*s++ & 0377)) != '\0')
@@ -778,10 +789,10 @@ xputs(fp, s)
if (shiftout)
{
(void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s",
- TermEscape.te_rv_off);
+ TermEscape.te_normal);
shiftout = false;
}
- if (!isascii(c))
+ if (!isascii(c) && !tTd(84, 1))
{
if (c == MATCHREPL)
{
@@ -889,7 +900,11 @@ xputs(fp, s)
(void) sm_io_putc(fp, SM_TIME_DEFAULT, '\\');
(void) sm_io_putc(fp, SM_TIME_DEFAULT, c);
}
- else
+ else if (tTd(84, 2))
+ (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " %o ", c);
+ else if (tTd(84, 1))
+ (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " %#x ", c);
+ else if (!isascii(c) && !tTd(84, 1))
{
(void) sm_io_putc(fp, SM_TIME_DEFAULT, '^');
(void) sm_io_putc(fp, SM_TIME_DEFAULT, c ^ 0100);
@@ -897,9 +912,10 @@ xputs(fp, s)
}
if (shiftout)
(void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s",
- TermEscape.te_rv_off);
+ TermEscape.te_normal);
(void) sm_io_flush(fp, SM_TIME_DEFAULT);
}
+
/*
** MAKELOWER -- Translate a line into lower case
**
@@ -926,6 +942,7 @@ makelower(p)
if (isascii(c) && isupper(c))
*p = tolower(c);
}
+
/*
** FIXCRLF -- fix <CR><LF> in line.
**
@@ -961,6 +978,7 @@ fixcrlf(line, stripnl)
*p++ = '\n';
*p = '\0';
}
+
/*
** PUTLINE -- put a line like fputs obeying SMTP conventions
**
@@ -985,6 +1003,7 @@ putline(l, mci)
{
return putxline(l, strlen(l), mci, PXLF_MAPFROM);
}
+
/*
** PUTXLINE -- putline with flags bits.
**
@@ -1000,6 +1019,7 @@ putline(l, mci)
** PXLF_STRIP8BIT -- strip 8th bit.
** PXLF_HEADER -- map bare newline in header to newline space.
** PXLF_NOADDEOL -- don't add an EOL if one wasn't present.
+** PXLF_STRIPMQUOTE -- strip METAQUOTE bytes.
**
** Returns:
** true iff line was written successfully
@@ -1008,6 +1028,37 @@ putline(l, mci)
** output of l to mci->mci_out.
*/
+
+#define PUTX(limit) \
+ do \
+ { \
+ quotenext = false; \
+ while (l < limit) \
+ { \
+ unsigned char c = (unsigned char) *l++; \
+ \
+ if (bitset(PXLF_STRIPMQUOTE, pxflags) && \
+ !quotenext && c == METAQUOTE) \
+ { \
+ quotenext = true; \
+ continue; \
+ } \
+ quotenext = false; \
+ if (strip8bit) \
+ c &= 0177; \
+ if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT, \
+ c) == SM_IO_EOF) \
+ { \
+ dead = true; \
+ break; \
+ } \
+ if (TrafficLogFile != NULL) \
+ (void) sm_io_putc(TrafficLogFile, \
+ SM_TIME_DEFAULT, \
+ c); \
+ } \
+ } while (0)
+
bool
putxline(l, len, mci, pxflags)
register char *l;
@@ -1015,20 +1066,15 @@ putxline(l, len, mci, pxflags)
register MCI *mci;
int pxflags;
{
- bool dead = false;
register char *p, *end;
- int slop = 0;
+ int slop;
+ bool dead, quotenext, strip8bit;
/* strip out 0200 bits -- these can look like TELNET protocol */
- if (bitset(MCIF_7BIT, mci->mci_flags) ||
- bitset(PXLF_STRIP8BIT, pxflags))
- {
- register char svchar;
-
- for (p = l; (svchar = *p) != '\0'; ++p)
- if (bitset(0200, svchar))
- *p = svchar &~ 0200;
- }
+ strip8bit = bitset(MCIF_7BIT, mci->mci_flags) ||
+ bitset(PXLF_STRIP8BIT, pxflags);
+ dead = false;
+ slop = 0;
end = l + len;
do
@@ -1051,7 +1097,6 @@ putxline(l, len, mci, pxflags)
while (mci->mci_mailer->m_linelimit > 0 &&
(p - l + slop) > mci->mci_mailer->m_linelimit)
{
- char *l_base = l;
register char *q = &l[mci->mci_mailer->m_linelimit - slop - 1];
if (l[0] == '.' && slop == 0 &&
@@ -1080,35 +1125,22 @@ putxline(l, len, mci, pxflags)
if (dead)
break;
- while (l < q)
- {
- if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
- (unsigned char) *l++) == SM_IO_EOF)
- {
- dead = true;
- break;
- }
- }
+ PUTX(q);
if (dead)
break;
- if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT, '!') ==
- SM_IO_EOF ||
+ if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
+ '!') == SM_IO_EOF ||
sm_io_fputs(mci->mci_out, SM_TIME_DEFAULT,
- mci->mci_mailer->m_eol) ==
- SM_IO_EOF ||
- sm_io_putc(mci->mci_out, SM_TIME_DEFAULT, ' ') ==
- SM_IO_EOF)
+ mci->mci_mailer->m_eol) == SM_IO_EOF ||
+ sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
+ ' ') == SM_IO_EOF)
{
dead = true;
break;
}
if (TrafficLogFile != NULL)
{
- for (l = l_base; l < q; l++)
- (void) sm_io_putc(TrafficLogFile,
- SM_TIME_DEFAULT,
- (unsigned char)*l);
(void) sm_io_fprintf(TrafficLogFile,
SM_TIME_DEFAULT,
"!\n%05d >>> ",
@@ -1149,19 +1181,7 @@ putxline(l, len, mci, pxflags)
(void) sm_io_putc(TrafficLogFile,
SM_TIME_DEFAULT, '>');
}
- for ( ; l < p; ++l)
- {
- if (TrafficLogFile != NULL)
- (void) sm_io_putc(TrafficLogFile,
- SM_TIME_DEFAULT,
- (unsigned char)*l);
- if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
- (unsigned char) *l) == SM_IO_EOF)
- {
- dead = true;
- break;
- }
- }
+ PUTX(p);
if (dead)
break;
@@ -1230,6 +1250,7 @@ xunlink(f)
errno = save_errno;
return i;
}
+
/*
** SFGETS -- "safe" fgets -- times out and ignores random interrupts.
**
@@ -1338,12 +1359,15 @@ sfgets(buf, siz, fp, timeout, during)
}
return buf;
}
+
/*
** FGETFOLDED -- like fgets, but knows about folded lines.
**
** Parameters:
** buf -- place to put result.
-** n -- bytes available.
+** np -- pointer to bytes available; will be updated with
+** the actual buffer size (not number of bytes filled)
+** on return.
** f -- file to read from.
**
** Returns:
@@ -1358,15 +1382,18 @@ sfgets(buf, siz, fp, timeout, during)
*/
char *
-fgetfolded(buf, n, f)
+fgetfolded(buf, np, f)
char *buf;
- register int n;
+ int *np;
SM_FILE_T *f;
{
register char *p = buf;
char *bp = buf;
register int i;
+ int n;
+ SM_REQUIRE(np != NULL);
+ n = *np;
SM_REQUIRE(n > 0);
SM_REQUIRE(buf != NULL);
if (f == NULL)
@@ -1408,6 +1435,7 @@ fgetfolded(buf, n, f)
sm_free(bp);
bp = nbp;
n = nn - (p - bp);
+ *np = nn;
}
*p++ = i;
if (i == '\n')
@@ -1427,6 +1455,7 @@ fgetfolded(buf, n, f)
*p = '\0';
return bp;
}
+
/*
** CURTIME -- return current time.
**
@@ -1445,6 +1474,7 @@ curtime()
(void) time(&t);
return t;
}
+
/*
** ATOBOOL -- convert a string representation to boolean.
**
@@ -1466,6 +1496,7 @@ atobool(s)
return true;
return false;
}
+
/*
** ATOOCT -- convert a string representation to octal.
**
@@ -1487,6 +1518,7 @@ atooct(s)
i = (i << 3) | (*s++ - '0');
return i;
}
+
/*
** BITINTERSECT -- tell if two bitmaps intersect
**
@@ -1505,13 +1537,14 @@ bitintersect(a, b)
{
int i;
- for (i = BITMAPBYTES / sizeof (int); --i >= 0; )
+ for (i = BITMAPBYTES / sizeof(int); --i >= 0; )
{
if ((a[i] & b[i]) != 0)
return true;
}
return false;
}
+
/*
** BITZEROP -- tell if a bitmap is all zero
**
@@ -1529,13 +1562,14 @@ bitzerop(map)
{
int i;
- for (i = BITMAPBYTES / sizeof (int); --i >= 0; )
+ for (i = BITMAPBYTES / sizeof(int); --i >= 0; )
{
if (map[i] != 0)
return false;
}
return true;
}
+
/*
** STRCONTAINEDIN -- tell if one string is contained in another
**
@@ -1584,6 +1618,7 @@ strcontainedin(icase, a, b)
}
return false;
}
+
/*
** CHECKFD012 -- check low numbered file descriptors
**
@@ -1608,6 +1643,7 @@ checkfd012(where)
fill_fd(i, where);
#endif /* XDEBUG */
}
+
/*
** CHECKFDOPEN -- make sure file descriptor is open -- for extended debugging
**
@@ -1634,6 +1670,7 @@ checkfdopen(fd, where)
}
#endif /* XDEBUG */
}
+
/*
** CHECKFDS -- check for new or missing file descriptors
**
@@ -1694,6 +1731,7 @@ checkfds(where)
}
errno = save_errno;
}
+
/*
** PRINTOPENFDS -- print the open file descriptors (for debugging)
**
@@ -1719,6 +1757,7 @@ printopenfds(logit)
for (fd = 0; fd < DtableSize; fd++)
dumpfd(fd, false, logit);
}
+
/*
** DUMPFD -- dump a file descriptor
**
@@ -1795,8 +1834,8 @@ dumpfd(fd, printclosed, logit)
case S_IFSOCK:
(void) sm_snprintf(p, SPACELEFT(buf, p), "SOCK ");
p += strlen(p);
- memset(&sa, '\0', sizeof sa);
- slen = sizeof sa;
+ memset(&sa, '\0', sizeof(sa));
+ slen = sizeof(sa);
if (getsockname(fd, &sa.sa, &slen) < 0)
(void) sm_snprintf(p, SPACELEFT(buf, p), "(%s)",
sm_errstring(errno));
@@ -1825,7 +1864,7 @@ dumpfd(fd, printclosed, logit)
p += strlen(p);
(void) sm_snprintf(p, SPACELEFT(buf, p), "->");
p += strlen(p);
- slen = sizeof sa;
+ slen = sizeof(sa);
if (getpeername(fd, &sa.sa, &slen) < 0)
(void) sm_snprintf(p, SPACELEFT(buf, p), "(%s)",
sm_errstring(errno));
@@ -1908,6 +1947,7 @@ printit:
else
sm_dprintf("%s\n", buf);
}
+
/*
** SHORTEN_HOSTNAME -- strip local domain information off of hostname.
**
@@ -1955,6 +1995,7 @@ shorten_hostname(host)
}
return NULL;
}
+
/*
** PROG_OPEN -- open a program for reading
**
@@ -2057,7 +2098,7 @@ prog_open(argv, pfd, e)
/* chroot to the program mailer directory, if defined */
if (ProgMailer != NULL && ProgMailer->m_rootdir != NULL)
{
- expand(ProgMailer->m_rootdir, buf, sizeof buf, e);
+ expand(ProgMailer->m_rootdir, buf, sizeof(buf), e);
if (chroot(buf) < 0)
{
syserr("prog_open: cannot chroot(%s)", buf);
@@ -2097,7 +2138,7 @@ prog_open(argv, pfd, e)
q = strchr(p, ':');
if (q != NULL)
*q = '\0';
- expand(p, buf, sizeof buf, e);
+ expand(p, buf, sizeof(buf), e);
if (q != NULL)
*q++ = ':';
if (buf[0] != '\0' && chdir(buf) >= 0)
@@ -2138,6 +2179,7 @@ prog_open(argv, pfd, e)
_exit(EX_CONFIG);
return -1; /* avoid compiler warning on IRIX */
}
+
/*
** GET_COLUMN -- look up a Column in a line buffer
**
@@ -2168,7 +2210,7 @@ get_column(line, col, delim, buf, buflen)
char delimbuf[4];
if ((char) delim == '\0')
- (void) sm_strlcpy(delimbuf, "\n\t ", sizeof delimbuf);
+ (void) sm_strlcpy(delimbuf, "\n\t ", sizeof(delimbuf));
else
{
delimbuf[0] = (char) delim;
@@ -2211,6 +2253,7 @@ get_column(line, col, delim, buf, buflen)
(void) sm_strlcpy(buf, begin, i + 1);
return buf;
}
+
/*
** CLEANSTRCPY -- copy string keeping out bogus characters
**
@@ -2248,6 +2291,7 @@ cleanstrcpy(t, f, l)
}
*t = '\0';
}
+
/*
** DENLSTRING -- convert newlines in a string to spaces
**
@@ -2296,7 +2340,7 @@ denlstring(s, strict, logattacks)
if (logattacks)
{
- sm_syslog(LOG_NOTICE, CurEnv->e_id,
+ sm_syslog(LOG_NOTICE, CurEnv ? CurEnv->e_id : NULL,
"POSSIBLE ATTACK from %.100s: newline in string \"%s\"",
RealHostName == NULL ? "[UNKNOWN]" : RealHostName,
shortenstring(bp, MAXSHORTSTR));
@@ -2339,101 +2383,6 @@ strreplnonprt(s, c)
}
/*
-** STR2PRT -- convert "unprintable" characters in a string to \oct
-**
-** Parameters:
-** s -- string to convert
-**
-** Returns:
-** converted string.
-** This is a static local buffer, string must be copied
-** before this function is called again!
-*/
-
-char *
-str2prt(s)
- char *s;
-{
- int l;
- char c, *h;
- bool ok;
- static int len = 0;
- static char *buf = NULL;
-
- if (s == NULL)
- return NULL;
- ok = true;
- for (h = s, l = 1; *h != '\0'; h++, l++)
- {
- if (*h == '\\')
- {
- ++l;
- ok = false;
- }
- else if (!(isascii(*h) && isprint(*h)))
- {
- l += 3;
- ok = false;
- }
- }
- if (ok)
- return s;
- if (l > len)
- {
- char *nbuf = sm_pmalloc_x(l);
-
- if (buf != NULL)
- sm_free(buf);
- len = l;
- buf = nbuf;
- }
- for (h = buf; *s != '\0' && l > 0; s++, l--)
- {
- c = *s;
- if (isascii(c) && isprint(c) && c != '\\')
- {
- *h++ = c;
- }
- else
- {
- *h++ = '\\';
- --l;
- switch (c)
- {
- case '\\':
- *h++ = '\\';
- break;
- case '\t':
- *h++ = 't';
- break;
- case '\n':
- *h++ = 'n';
- break;
- case '\r':
- *h++ = 'r';
- break;
- default:
- SM_ASSERT(l >= 2);
- (void) sm_snprintf(h, l, "%03o",
- (unsigned int)((unsigned char) c));
-
- /*
- ** XXX since l is unsigned this may
- ** wrap around if the calculation is screwed
- ** up...
- */
-
- l -= 2;
- h += 3;
- break;
- }
- }
- }
- *h = '\0';
- buf[len - 1] = '\0';
- return buf;
-}
-/*
** PATH_IS_DIR -- check to see if file exists and is a directory.
**
** There are some additional checks for security violations in
@@ -2482,6 +2431,7 @@ path_is_dir(pathname, createflag)
}
return true;
}
+
/*
** PROC_LIST_ADD -- add process id to list of our children
**
@@ -2545,15 +2495,19 @@ proc_list_add(pid, task, type, count, other, hostaddr)
if (i >= ProcListSize)
{
/* grow process list */
+ int chldwasblocked;
PROCS_T *npv;
SM_ASSERT(ProcListSize < INT_MAX - PROC_LIST_SEG);
- npv = (PROCS_T *) sm_pmalloc_x((sizeof *npv) *
+ npv = (PROCS_T *) sm_pmalloc_x((sizeof(*npv)) *
(ProcListSize + PROC_LIST_SEG));
+
+ /* Block SIGCHLD so reapchild() doesn't mess with us */
+ chldwasblocked = sm_blocksignal(SIGCHLD);
if (ProcListSize > 0)
{
memmove(npv, ProcListVec,
- ProcListSize * sizeof (PROCS_T));
+ ProcListSize * sizeof(PROCS_T));
sm_free(ProcListVec);
}
@@ -2567,6 +2521,8 @@ proc_list_add(pid, task, type, count, other, hostaddr)
i = ProcListSize;
ProcListSize += PROC_LIST_SEG;
ProcListVec = npv;
+ if (chldwasblocked == 0)
+ (void) sm_releasesignal(SIGCHLD);
}
ProcListVec[i].proc_pid = pid;
PSTRSET(ProcListVec[i].proc_task, task);
@@ -2586,6 +2542,7 @@ proc_list_add(pid, task, type, count, other, hostaddr)
CurChildren++;
}
}
+
/*
** PROC_LIST_SET -- set pid task in process list
**
@@ -2613,6 +2570,7 @@ proc_list_set(pid, task)
}
}
}
+
/*
** PROC_LIST_DROP -- drop pid from process list
**
@@ -2674,6 +2632,7 @@ proc_list_drop(pid, st, other)
else if (type == PROC_QUEUE)
CurRunners -= ProcListVec[i].proc_count;
}
+
/*
** PROC_LIST_CLEAR -- clear the process list
**
@@ -2697,6 +2656,7 @@ proc_list_clear()
ProcListVec[i].proc_pid = NO_PID;
CurChildren = 0;
}
+
/*
** PROC_LIST_PROBE -- probe processes in the list to see if they still exist
**
diff --git a/contrib/sendmail/src/version.c b/contrib/sendmail/src/version.c
index f577728..6bdfd11 100644
--- a/contrib/sendmail/src/version.c
+++ b/contrib/sendmail/src/version.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,6 +13,6 @@
#include <sm/gen.h>
-SM_RCSID("@(#)$Id: version.c,v 8.163.2.8 2006/07/26 17:24:02 ca Exp $")
+SM_RCSID("@(#)$Id: version.c,v 8.191 2007/04/03 21:21:18 ca Exp $")
-char Version[] = "8.13.8";
+char Version[] = "8.14.1";
OpenPOWER on IntegriCloud