summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/src/headers.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/src/headers.c')
-rw-r--r--contrib/sendmail/src/headers.c206
1 files changed, 163 insertions, 43 deletions
diff --git a/contrib/sendmail/src/headers.c b/contrib/sendmail/src/headers.c
index b7c5ef9..59bbf56 100644
--- a/contrib/sendmail/src/headers.c
+++ b/contrib/sendmail/src/headers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -14,8 +14,9 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: headers.c,v 8.266.4.9 2003/10/30 00:17:22 gshapiro Exp $")
+SM_RCSID("@(#)$Id: headers.c,v 8.286 2004/07/08 17:57:32 ca Exp $")
+static HDR *allocheader __P((char *, char *, int, SM_RPOOL_T *));
static size_t fix_mime_header __P((HDR *, ENVELOPE *));
static int priencode __P((char *));
static void put_vanilla_header __P((HDR *, char *, MCI *));
@@ -88,7 +89,7 @@ chompheader(line, pflag, hdrp, e)
if (tTd(31, 6))
{
sm_dprintf("chompheader: ");
- xputs(line);
+ xputs(sm_debug_file(), line);
sm_dprintf("\n");
}
@@ -292,11 +293,12 @@ hse:
int rscheckflags;
char *rs;
- /* no ruleset? look for default */
- rs = hi->hi_ruleset;
rscheckflags = RSF_COUNT;
if (!bitset(hi->hi_flags, H_FROM|H_RCPT))
rscheckflags |= RSF_UNSTRUCTURED;
+
+ /* no ruleset? look for default */
+ rs = hi->hi_ruleset;
if (rs == NULL)
{
s = stab("*", ST_HEADER, ST_FIND);
@@ -358,17 +360,10 @@ hse:
(void) sm_snprintf(qval, sizeof qval, "%d", k);
macdefine(&e->e_macro, A_TEMP, macid("{hdrlen}"), qval);
#if _FFR_HDR_TYPE
- /*
- ** XXX: h isn't set yet
- ** If we really want to be precise then we have
- ** to lookup the header (see below).
- ** It's probably not worth the effort.
- */
-
- if (bitset(H_FROM, h->h_flags))
+ if (bitset(H_FROM, hi->hi_flags))
macdefine(&e->e_macro, A_PERM,
macid("{addr_type}"), "h s");
- else if (bitset(H_RCPT, h->h_flags))
+ else if (bitset(H_RCPT, hi->hi_flags))
macdefine(&e->e_macro, A_PERM,
macid("{addr_type}"), "h r");
else
@@ -467,6 +462,44 @@ hse:
return h->h_flags;
}
/*
+** ALLOCHEADER -- allocate a header entry
+**
+** Parameters:
+** field -- the name of the header field.
+** value -- the value of the field.
+** flags -- flags to add to h_flags.
+** rp -- resource pool for allocations
+**
+** Returns:
+** Pointer to a newly allocated and populated HDR.
+*/
+
+static HDR *
+allocheader(field, value, flags, rp)
+ char *field;
+ char *value;
+ int flags;
+ SM_RPOOL_T *rp;
+{
+ HDR *h;
+ STAB *s;
+
+ /* find info struct */
+ s = stab(field, ST_HEADER, ST_FIND);
+
+ /* allocate space for new header */
+ h = (HDR *) sm_rpool_malloc_x(rp, sizeof *h);
+ h->h_field = field;
+ h->h_value = sm_rpool_strdup_x(rp, value);
+ h->h_flags = flags;
+ if (s != NULL)
+ h->h_flags |= s->s_header.hi_flags;
+ clrbitmap(h->h_mflags);
+ h->h_macro = '\0';
+
+ return h;
+}
+/*
** ADDHEADER -- add a header entry to the end of the queue.
**
** This bypasses the special checking of chompheader.
@@ -492,13 +525,9 @@ addheader(field, value, flags, e)
ENVELOPE *e;
{
register HDR *h;
- STAB *s;
HDR **hp;
HDR **hdrlist = &e->e_header;
- /* find info struct */
- s = stab(field, ST_HEADER, ST_FIND);
-
/* find current place in list -- keep back pointer? */
for (hp = hdrlist; (h = *hp) != NULL; hp = &h->h_link)
{
@@ -507,18 +536,65 @@ addheader(field, value, flags, e)
}
/* allocate space for new header */
- h = (HDR *) sm_rpool_malloc_x(e->e_rpool, sizeof *h);
- h->h_field = field;
- h->h_value = sm_rpool_strdup_x(e->e_rpool, value);
+ h = allocheader(field, value, flags, e->e_rpool);
h->h_link = *hp;
- h->h_flags = flags;
- if (s != NULL)
- h->h_flags |= s->s_header.hi_flags;
- clrbitmap(h->h_mflags);
- h->h_macro = '\0';
*hp = h;
}
/*
+** INSHEADER -- insert a header entry at the specified index
+**
+** This bypasses the special checking of chompheader.
+**
+** Parameters:
+** idx -- index into the header list at which to insert
+** field -- the name of the header field.
+** value -- the value of the field.
+** flags -- flags to add to h_flags.
+** e -- envelope.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** inserts the field on the list of headers for this envelope.
+*/
+
+void
+insheader(idx, field, value, flags, e)
+ int idx;
+ char *field;
+ char *value;
+ int flags;
+ ENVELOPE *e;
+{
+ HDR *h, *srch, *last = NULL;
+
+ /* allocate space for new header */
+ h = allocheader(field, value, flags, e->e_rpool);
+
+ /* find insertion position */
+ for (srch = e->e_header; srch != NULL && idx > 0;
+ srch = srch->h_link, idx--)
+ last = srch;
+
+ if (e->e_header == NULL)
+ {
+ e->e_header = h;
+ h->h_link = NULL;
+ }
+ else if (srch == NULL)
+ {
+ SM_ASSERT(last != NULL);
+ last->h_link = h;
+ h->h_link = NULL;
+ }
+ else
+ {
+ h->h_link = srch->h_link;
+ srch->h_link = h;
+ }
+}
+/*
** HVALUE -- return value of a header.
**
** Only "real" fields (i.e., ones that have not been supplied
@@ -674,7 +750,7 @@ eatheader(e, full, log)
if (tTd(32, 1))
{
sm_dprintf("(");
- xputs(h->h_value);
+ xputs(sm_debug_file(), h->h_value);
sm_dprintf(") ");
}
expand(h->h_value, buf, sizeof buf, e);
@@ -689,7 +765,7 @@ eatheader(e, full, log)
}
if (tTd(32, 1))
{
- xputs(h->h_value);
+ xputs(sm_debug_file(), h->h_value);
sm_dprintf("\n");
}
@@ -731,10 +807,8 @@ eatheader(e, full, log)
e->e_msgid = h->h_value;
while (isascii(*e->e_msgid) && isspace(*e->e_msgid))
e->e_msgid++;
-#if _FFR_MESSAGEID_MACRO
macdefine(&e->e_macro, A_PERM, macid("{msg_id}"),
- e->e_msgid);
-#endif /* _FFR_MESSAGEID_MACRO */
+ e->e_msgid);
}
}
if (tTd(32, 1))
@@ -767,6 +841,60 @@ eatheader(e, full, log)
+ e->e_nrcpts * WkRecipFact;
}
+ /* check for DSN to properly set e_timeoutclass */
+ p = hvalue("content-type", e->e_header);
+ if (p != NULL)
+ {
+ bool oldsupr;
+ char **pvp;
+ char pvpbuf[MAXLINE];
+ extern unsigned char MimeTokenTab[256];
+
+ /* tokenize header */
+ oldsupr = SuprErrs;
+ SuprErrs = true;
+ pvp = prescan(p, '\0', pvpbuf, sizeof pvpbuf, NULL,
+ MimeTokenTab, false);
+ SuprErrs = oldsupr;
+
+ /* Check if multipart/report */
+ if (pvp != NULL && pvp[0] != NULL &&
+ pvp[1] != NULL && pvp[2] != NULL &&
+ sm_strcasecmp(*pvp++, "multipart") == 0 &&
+ strcmp(*pvp++, "/") == 0 &&
+ sm_strcasecmp(*pvp++, "report") == 0)
+ {
+ /* Look for report-type=delivery-status */
+ while (*pvp != NULL)
+ {
+ /* skip to semicolon separator */
+ while (*pvp != NULL && strcmp(*pvp, ";") != 0)
+ pvp++;
+
+ /* skip semicolon */
+ if (*pvp++ == NULL || *pvp == NULL)
+ break;
+
+ /* look for report-type */
+ if (sm_strcasecmp(*pvp++, "report-type") != 0)
+ continue;
+
+ /* skip equal */
+ if (*pvp == NULL || strcmp(*pvp, "=") != 0)
+ continue;
+
+ /* check value */
+ if (*++pvp != NULL &&
+ sm_strcasecmp(*pvp,
+ "delivery-status") == 0)
+ e->e_timeoutclass = TOC_DSN;
+
+ /* found report-type, no need to continue */
+ break;
+ }
+ }
+ }
+
/* message timeout priority */
p = hvalue("priority", e->e_header);
if (p != NULL)
@@ -778,15 +906,11 @@ eatheader(e, full, log)
e->e_timeoutclass = TOC_NORMAL;
else if (sm_strcasecmp(p, "non-urgent") == 0)
e->e_timeoutclass = TOC_NONURGENT;
-#if _FFR_QUEUERETURN_DSN
else if (bitset(EF_RESPONSE, e->e_flags))
e->e_timeoutclass = TOC_DSN;
-#endif /* _FFR_QUEUERETURN_DSN */
}
-#if _FFR_QUEUERETURN_DSN
else if (bitset(EF_RESPONSE, e->e_flags))
e->e_timeoutclass = TOC_DSN;
-#endif /* _FFR_QUEUERETURN_DSN */
/* date message originated */
p = hvalue("posted-date", e->e_header);
@@ -1240,12 +1364,8 @@ crackaddr(addr, e)
{
c = *q++;
if (quoteit && c == '"')
- {
SM_APPEND_CHAR('\\');
- SM_APPEND_CHAR(c);
- }
- else
- SM_APPEND_CHAR(c);
+ SM_APPEND_CHAR(c);
}
if (quoteit)
{
@@ -1407,7 +1527,7 @@ crackaddr(addr, e)
if (tTd(33, 1))
{
sm_dprintf("crackaddr=>`");
- xputs(buf);
+ xputs(sm_debug_file(), buf);
sm_dprintf("'\n");
}
return buf;
@@ -1460,7 +1580,7 @@ putheader(mci, hdr, e, flags)
if (tTd(34, 11))
{
sm_dprintf(" %s: ", h->h_field);
- xputs(p);
+ xputs(sm_debug_file(), p);
}
/* Skip empty headers */
@@ -1814,7 +1934,7 @@ commaize(h, p, oldstyle, mci, e)
char pvpbuf[PSBUFSIZE];
res = prescan(p, oldstyle ? ' ' : ',', pvpbuf,
- sizeof pvpbuf, &oldp, NULL);
+ sizeof pvpbuf, &oldp, NULL, false);
p = oldp;
#if _FFR_IGNORE_BOGUS_ADDR
/* ignore addresses that can't be parsed */
OpenPOWER on IntegriCloud