58d3462d97d59aa391bdc7c47ae1c27be2b5def4
SCCSID(@
(#)headers.c 3.19 %G%);
** CHOMPHEADER -- process and save a header line.
** Called by collect and by readcf to deal with header lines.
** line -- header as a text line.
** def -- if set, this is a default value.
** flags for this header.
** The header is saved on the header list.
** Contents of 'line' are destroyed.
extern u_long
mfencode();
extern ADDRESS
*sendto();
/* strip off trailing newline */
register char *q
= index(p
+ 1, *p
);
syserr("chompheader: syntax error, line \"%s\"", line
);
/* find canonical name */
/* strip field value on front */
/* hack, hack -- save From: line specially */
if (!def
&& !QueueRun
&& strcmp(fname
, "from") == 0)
CurEnv
->e_origfrom
= newstr(fvalue
);
/* search header list for this header */
for (hp
= &CurEnv
->e_header
, h
= CurEnv
->e_header
; h
!= NULL
; hp
= &h
->h_link
, h
= h
->h_link
)
if (strcmp(fname
, h
->h_field
) == 0 && bitset(H_DEFAULT
, h
->h_flags
))
/* see if it is a known type */
for (hi
= HdrInfo
; hi
->hi_field
!= NULL
; hi
++)
if (strcmp(hi
->hi_field
, fname
) == 0)
/* if this means "end of header" quit now */
if (bitset(H_EOH
, hi
->hi_flags
))
/* don't put timestamps in every queue run */
if (QueueRun
&& h
!= NULL
&& bitset(H_FORCE
, h
->h_flags
))
/* create/fill in a new node */
if (h
== NULL
|| bitset(H_FORCE
, h
->h_flags
))
h
= (HDR
*) xalloc(sizeof *h
);
h
->h_field
= newstr(fname
);
h
->h_flags
= hi
->hi_flags
;
h
->h_mflags
= mopts
| hi
->hi_mflags
;
h
->h_value
= newstr(fvalue
);
(void) sendto(h
->h_value
, 0, (ADDRESS
*) NULL
, 0);
/* hack to see if this is a new format message */
if (bitset(H_RCPT
, h
->h_flags
) &&
(index(fvalue
, ',') != NULL
|| index(fvalue
, '(') != NULL
||
index(fvalue
, '<') != NULL
))
CurEnv
->e_oldstyle
= FALSE
;
** ADDHEADER -- add a header entry to the end of the queue.
** This bypasses the special checking of chompheader.
** field -- the name of the header field.
** value -- the value of the field. It must be lower-cased.
** e -- the envelope to add them to.
** adds the field on the list of headers for this envelope.
addheader(field
, value
, e
)
register struct hdrinfo
*hi
;
for (hi
= HdrInfo
; hi
->hi_field
!= NULL
; hi
++)
if (strcmp(field
, hi
->hi_field
) == 0)
/* find current place in list -- keep back pointer? */
for (hp
= &e
->e_header
; (h
= *hp
) != NULL
; hp
= &h
->h_link
)
if (strcmp(field
, h
->h_field
) == 0)
/* allocate space for new header */
h
= (HDR
*) xalloc(sizeof *h
);
h
->h_value
= newstr(value
);
h
->h_flags
= hi
->hi_flags
| H_DEFAULT
;
h
->h_mflags
= hi
->hi_mflags
;
** HVALUE -- return value of a header.
** Only "real" fields (i.e., ones that have not been supplied
** as a default) are used.
** field -- the field name.
** pointer to the value part.
** sets the H_USED bit in the header if found.
for (h
= CurEnv
->e_header
; h
!= NULL
; h
= h
->h_link
)
if (!bitset(H_DEFAULT
, h
->h_flags
) && strcmp(h
->h_field
, field
) == 0)
** ISHEADER -- predicate telling if argument is a header.
** A line is a header if it has a single word followed by
** optional white space followed by a colon.
** s -- string to check for possible headerness.
** TRUE if s is a header.
** According to RFC733, there should be a newline
** permitted after the word but before the colon.
** We don't seem to support that.....
while (!isspace(*s
) && *s
!= ':')
** GETXPART -- extract the "signature" part of an address line.
** Try to extract the full name from a general address
** field. We take anything which is a comment as a
** first choice. Failing in that, we see if there is
** a "machine readable" name (in <angle brackets>); if
** so we take anything preceeding that clause.
** If we blow it here it's not all that serious.
** NULL if no signature part.
register char *rval
= NULL
;
for (p
= q
; *p
!= '\0'; p
++)
else if (*p
== ')' && --parenlev
<= 0)
else if ((q
= index(p
, '<')) != NULL
)