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