1*4091Seric # include <stdio.h> 2*4091Seric # include <ctype.h> 3*4091Seric # include <errno.h> 4*4091Seric # include "sendmail.h" 5*4091Seric 6*4091Seric static char SccsId[] = "@(#)headers.c 3.1 08/09/81"; 7*4091Seric 8*4091Seric /* 9*4091Seric ** CHOMPHEADER -- process and save a header line. 10*4091Seric ** 11*4091Seric ** Called by collect and by readcf to deal with header lines. 12*4091Seric ** 13*4091Seric ** Parameters: 14*4091Seric ** line -- header as a text line. 15*4091Seric ** def -- if set, this is a default value. 16*4091Seric ** 17*4091Seric ** Returns: 18*4091Seric ** flags for this header. 19*4091Seric ** 20*4091Seric ** Side Effects: 21*4091Seric ** The header is saved on the header list. 22*4091Seric */ 23*4091Seric 24*4091Seric chompheader(line, def) 25*4091Seric char *line; 26*4091Seric bool def; 27*4091Seric { 28*4091Seric register char *p; 29*4091Seric register HDR *h; 30*4091Seric HDR **hp; 31*4091Seric extern bool isheader(); 32*4091Seric char *fname; 33*4091Seric char *fvalue; 34*4091Seric struct hdrinfo *hi; 35*4091Seric 36*4091Seric /* strip off trailing newline */ 37*4091Seric p = rindex(line, '\n'); 38*4091Seric if (p != NULL) 39*4091Seric *p = '\0'; 40*4091Seric 41*4091Seric /* find canonical name */ 42*4091Seric fname = line; 43*4091Seric p = index(line, ':'); 44*4091Seric fvalue = &p[1]; 45*4091Seric while (isspace(*--p)) 46*4091Seric continue; 47*4091Seric *++p = '\0'; 48*4091Seric makelower(fname); 49*4091Seric 50*4091Seric /* strip field value on front */ 51*4091Seric if (*fvalue == ' ') 52*4091Seric fvalue++; 53*4091Seric 54*4091Seric /* search header list for this header */ 55*4091Seric for (hp = &Header, h = Header; h != NULL; hp = &h->h_link, h = h->h_link) 56*4091Seric { 57*4091Seric if (strcmp(fname, h->h_field) == 0 && bitset(H_DEFAULT, h->h_flags)) 58*4091Seric break; 59*4091Seric } 60*4091Seric 61*4091Seric /* see if it is a known type */ 62*4091Seric for (hi = HdrInfo; hi->hi_field != NULL; hi++) 63*4091Seric { 64*4091Seric if (strcmp(hi->hi_field, fname) == 0) 65*4091Seric break; 66*4091Seric } 67*4091Seric 68*4091Seric /* if this means "end of header" quit now */ 69*4091Seric if (bitset(H_EOH, hi->hi_flags)) 70*4091Seric return (hi->hi_flags); 71*4091Seric 72*4091Seric /* create/fill in a new node */ 73*4091Seric if (h == NULL) 74*4091Seric { 75*4091Seric /* create a new node */ 76*4091Seric *hp = h = (HDR *) xalloc(sizeof *h); 77*4091Seric h->h_field = newstr(fname); 78*4091Seric h->h_value = NULL; 79*4091Seric h->h_link = NULL; 80*4091Seric h->h_flags = hi->hi_flags; 81*4091Seric h->h_mflags = hi->hi_mflags; 82*4091Seric } 83*4091Seric if (def) 84*4091Seric h->h_flags |= H_DEFAULT; 85*4091Seric else 86*4091Seric h->h_flags &= ~H_CHECK; 87*4091Seric if (h->h_value != NULL) 88*4091Seric free(h->h_value); 89*4091Seric h->h_value = newstr(fvalue); 90*4091Seric 91*4091Seric return (h->h_flags); 92*4091Seric } 93*4091Seric /* 94*4091Seric ** HVALUE -- return value of a header. 95*4091Seric ** 96*4091Seric ** Only "real" fields (i.e., ones that have not been supplied 97*4091Seric ** as a default) are used. 98*4091Seric ** 99*4091Seric ** Parameters: 100*4091Seric ** field -- the field name. 101*4091Seric ** 102*4091Seric ** Returns: 103*4091Seric ** pointer to the value part. 104*4091Seric ** NULL if not found. 105*4091Seric ** 106*4091Seric ** Side Effects: 107*4091Seric ** sets the H_USED bit in the header if found. 108*4091Seric */ 109*4091Seric 110*4091Seric char * 111*4091Seric hvalue(field) 112*4091Seric char *field; 113*4091Seric { 114*4091Seric register HDR *h; 115*4091Seric 116*4091Seric for (h = Header; h != NULL; h = h->h_link) 117*4091Seric { 118*4091Seric if (!bitset(H_DEFAULT, h->h_flags) && strcmp(h->h_field, field) == 0) 119*4091Seric { 120*4091Seric h->h_flags |= H_USED; 121*4091Seric return (h->h_value); 122*4091Seric } 123*4091Seric } 124*4091Seric return (NULL); 125*4091Seric } 126*4091Seric /* 127*4091Seric ** ISHEADER -- predicate telling if argument is a header. 128*4091Seric ** 129*4091Seric ** Parameters: 130*4091Seric ** s -- string to check for possible headerness. 131*4091Seric ** 132*4091Seric ** Returns: 133*4091Seric ** TRUE if s is a header. 134*4091Seric ** FALSE otherwise. 135*4091Seric ** 136*4091Seric ** Side Effects: 137*4091Seric ** none. 138*4091Seric */ 139*4091Seric 140*4091Seric bool 141*4091Seric isheader(s) 142*4091Seric register char *s; 143*4091Seric { 144*4091Seric if (!isalnum(*s)) 145*4091Seric return (FALSE); 146*4091Seric while (!isspace(*s) && *s != ':') 147*4091Seric s++; 148*4091Seric while (isspace(*s)) 149*4091Seric s++; 150*4091Seric return (*s == ':'); 151*4091Seric } 152