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