14091Seric # include <errno.h> 24091Seric # include "sendmail.h" 34091Seric 4*4211Seric static char SccsId[] = "@(#)headers.c 3.4 08/22/81"; 54091Seric 64091Seric /* 74091Seric ** CHOMPHEADER -- process and save a header line. 84091Seric ** 94091Seric ** Called by collect and by readcf to deal with header lines. 104091Seric ** 114091Seric ** Parameters: 124091Seric ** line -- header as a text line. 134091Seric ** def -- if set, this is a default value. 144091Seric ** 154091Seric ** Returns: 164091Seric ** flags for this header. 174091Seric ** 184091Seric ** Side Effects: 194091Seric ** The header is saved on the header list. 204091Seric */ 214091Seric 224091Seric chompheader(line, def) 234091Seric char *line; 244091Seric bool def; 254091Seric { 264091Seric register char *p; 274091Seric register HDR *h; 284091Seric HDR **hp; 294091Seric extern bool isheader(); 304091Seric char *fname; 314091Seric char *fvalue; 324091Seric struct hdrinfo *hi; 334091Seric 344091Seric /* strip off trailing newline */ 354091Seric p = rindex(line, '\n'); 364091Seric if (p != NULL) 374091Seric *p = '\0'; 384091Seric 394091Seric /* find canonical name */ 404091Seric fname = line; 414091Seric p = index(line, ':'); 424091Seric fvalue = &p[1]; 434091Seric while (isspace(*--p)) 444091Seric continue; 454091Seric *++p = '\0'; 464091Seric makelower(fname); 474091Seric 48*4211Seric /* hack, hack -- save the old From: address */ 49*4211Seric if (!def && strcmp(fname, "from") == 0) 50*4211Seric fname = "original-from"; 51*4211Seric 524091Seric /* strip field value on front */ 534091Seric if (*fvalue == ' ') 544091Seric fvalue++; 554091Seric 564091Seric /* search header list for this header */ 574091Seric for (hp = &Header, h = Header; h != NULL; hp = &h->h_link, h = h->h_link) 584091Seric { 594150Seric if (strcmp(fname, h->h_field) == 0 && bitset(H_DEFAULT, h->h_flags) && 604150Seric !bitset(H_FORCE, h->h_flags)) 614091Seric break; 624091Seric } 634091Seric 644091Seric /* see if it is a known type */ 654091Seric for (hi = HdrInfo; hi->hi_field != NULL; hi++) 664091Seric { 674091Seric if (strcmp(hi->hi_field, fname) == 0) 684091Seric break; 694091Seric } 704091Seric 714091Seric /* if this means "end of header" quit now */ 724091Seric if (bitset(H_EOH, hi->hi_flags)) 734091Seric return (hi->hi_flags); 744091Seric 754091Seric /* create/fill in a new node */ 764091Seric if (h == NULL) 774091Seric { 784091Seric /* create a new node */ 794091Seric *hp = h = (HDR *) xalloc(sizeof *h); 804091Seric h->h_field = newstr(fname); 814091Seric h->h_value = NULL; 824091Seric h->h_link = NULL; 834091Seric h->h_flags = hi->hi_flags; 844091Seric h->h_mflags = hi->hi_mflags; 854091Seric } 864091Seric if (def) 874091Seric h->h_flags |= H_DEFAULT; 884091Seric else 894091Seric h->h_flags &= ~H_CHECK; 904091Seric if (h->h_value != NULL) 914091Seric free(h->h_value); 924091Seric h->h_value = newstr(fvalue); 934091Seric 944091Seric return (h->h_flags); 954091Seric } 964091Seric /* 974091Seric ** HVALUE -- return value of a header. 984091Seric ** 994091Seric ** Only "real" fields (i.e., ones that have not been supplied 1004091Seric ** as a default) are used. 1014091Seric ** 1024091Seric ** Parameters: 1034091Seric ** field -- the field name. 1044091Seric ** 1054091Seric ** Returns: 1064091Seric ** pointer to the value part. 1074091Seric ** NULL if not found. 1084091Seric ** 1094091Seric ** Side Effects: 1104091Seric ** sets the H_USED bit in the header if found. 1114091Seric */ 1124091Seric 1134091Seric char * 1144091Seric hvalue(field) 1154091Seric char *field; 1164091Seric { 1174091Seric register HDR *h; 1184091Seric 1194091Seric for (h = Header; h != NULL; h = h->h_link) 1204091Seric { 1214091Seric if (!bitset(H_DEFAULT, h->h_flags) && strcmp(h->h_field, field) == 0) 1224091Seric { 1234091Seric h->h_flags |= H_USED; 1244091Seric return (h->h_value); 1254091Seric } 1264091Seric } 1274091Seric return (NULL); 1284091Seric } 1294091Seric /* 1304091Seric ** ISHEADER -- predicate telling if argument is a header. 1314091Seric ** 1324091Seric ** Parameters: 1334091Seric ** s -- string to check for possible headerness. 1344091Seric ** 1354091Seric ** Returns: 1364091Seric ** TRUE if s is a header. 1374091Seric ** FALSE otherwise. 1384091Seric ** 1394091Seric ** Side Effects: 1404091Seric ** none. 1414091Seric */ 1424091Seric 1434091Seric bool 1444091Seric isheader(s) 1454091Seric register char *s; 1464091Seric { 1474091Seric if (!isalnum(*s)) 1484091Seric return (FALSE); 1494091Seric while (!isspace(*s) && *s != ':') 1504091Seric s++; 1514091Seric while (isspace(*s)) 1524091Seric s++; 1534091Seric return (*s == ':'); 1544091Seric } 155