1 # include <errno.h> 2 # include "sendmail.h" 3 4 static char SccsId[] = "@(#)headers.c 3.5 08/24/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 if (!def && GrabTo && bitset(H_ADDR, h->h_flags)) 94 sendto(h->h_value, 0); 95 96 return (h->h_flags); 97 } 98 /* 99 ** HVALUE -- return value of a header. 100 ** 101 ** Only "real" fields (i.e., ones that have not been supplied 102 ** as a default) are used. 103 ** 104 ** Parameters: 105 ** field -- the field name. 106 ** 107 ** Returns: 108 ** pointer to the value part. 109 ** NULL if not found. 110 ** 111 ** Side Effects: 112 ** sets the H_USED bit in the header if found. 113 */ 114 115 char * 116 hvalue(field) 117 char *field; 118 { 119 register HDR *h; 120 121 for (h = Header; h != NULL; h = h->h_link) 122 { 123 if (!bitset(H_DEFAULT, h->h_flags) && strcmp(h->h_field, field) == 0) 124 { 125 h->h_flags |= H_USED; 126 return (h->h_value); 127 } 128 } 129 return (NULL); 130 } 131 /* 132 ** ISHEADER -- predicate telling if argument is a header. 133 ** 134 ** Parameters: 135 ** s -- string to check for possible headerness. 136 ** 137 ** Returns: 138 ** TRUE if s is a header. 139 ** FALSE otherwise. 140 ** 141 ** Side Effects: 142 ** none. 143 */ 144 145 bool 146 isheader(s) 147 register char *s; 148 { 149 if (!isalnum(*s)) 150 return (FALSE); 151 while (!isspace(*s) && *s != ':') 152 s++; 153 while (isspace(*s)) 154 s++; 155 return (*s == ':'); 156 } 157