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