1:
2: /* @(#)header.c 1.5 92/02/17
3: *
4: * Copyright (c) Steve Holden and Rich Burridge.
5: * All rights reserved.
6: *
7: * Permission is given to distribute these sources, as long as the
8: * copyright messages are not removed, and no monies are exchanged.
9: *
10: * No responsibility is taken for any errors inherent either
11: * to the comments or the code of this program, but if reported
12: * to me then an attempt will be made to fix them.
13: */
14:
15: #include "mp.h"
16: #include "extern.h"
17:
18:
19: /* If input line is header of type 'hdr', get the contents of the header
20: * into 'dest' (dynamically allocated).
21: */
22:
23:
24: get_header(hdr, dest)
25: char *hdr ;
26: char **dest ;
27: {
28: if (hdr_equal(hdr))
29: {
30: *dest = malloc((unsigned) (strlen(nextline) - strlen(hdr) + 1)) ;
31: STRCPY(*dest, nextline + strlen(hdr)) ;
32: }
33: }
34:
35:
36: /* If input line is header of type 'hdr', get header into dest. The header
37: * may have multiple lines. This skips input to next line.
38: */
39:
40: void
41: get_mult_hdr(hdr, dest)
42: char *hdr ;
43: char *dest[] ;
44: {
45: int i = 0 ;
46:
47: if (hdr_equal(hdr))
48: {
49: get_header(hdr, dest) ;
50: i++ ;
51: readline() ;
52: while (i < MAXCONT && !emptyline(nextline) && isspace(nextline[0]))
53: {
54: dest[i] = malloc((unsigned) (strlen(nextline) + 1)) ;
55: STRCPY(dest[i], nextline) ;
56: i++ ;
57: readline() ;
58: }
59: dest[i] = NULL ;
60: }
61: }
62:
63:
64: /* Compare the first word of the current line (converted to lower-case,
65: * with the given header definition. Determine if they are equal.
66: */
67:
68: int
69: hdr_equal(val)
70: char val[MAXLINE] ;
71: {
72: register char *nptr = nextline ;
73: register char *wptr = val ;
74: register int n, w ;
75:
76: do
77: {
78: n = *nptr++ ;
79: w = *wptr++ ;
80: if (isupper(n)) n = tolower(n) ;
81: if (isupper(w)) w = tolower(w) ;
82: if (n != w && w != '\0') return(0) ;
83: }
84: while (n != '\0' && w != '\0') ;
85: return(1) ;
86: }
87:
88:
89: /* Parse_headers is a function which reads and parses the message headers,
90: * extracting the bits which are of interest.
91: *
92: * The document is on standard input; the document is read up to the end of
93: * the header; the next line is read ahead into 'nextline'.
94: *
95: * Parameter:
96: * digest indicates if parsing is of digest headers instead of message
97: * headers
98: *
99: * Implicit Input:
100: * nextline contains the next line from standard input
101: *
102: * Side-effects:
103: * The function fills in the global header variables with headers found.
104: * The global variable doc_type is set to the document type
105: * The global variable nextline is set
106: * The document is read up to the line following the headers
107: */
108:
109:
110:
111: parse_headers(digest)
112: int digest ; /* Parsing digest headers */
113: {
114: char *colon ; /* Pointer to colon in line */
115: char *c ; /* General character pointer */
116: char tmpstr[MAXLINE] ;
117:
118: /* If not processing digest headers, determine if this article is an
119: * ordinary text file.
120: */
121:
122: if (!digest)
123: {
124: if (!hdr_equal(FROM_HDR)) /* UNIX From_ header? */
125: {
126: colon = strchr(nextline, ':') ;
127: if (colon == NULL) /* No colon => not a header line */
128: {
129: doc_type = DO_TEXT ;
130: return ;
131: }
132: c = nextline ;
133: while (c < colon && (!isspace(*c))) c++ ;
134: if (c != colon) /* Whitespace in header name => not header */
135: {
136: doc_type = DO_TEXT ;
137: return ;
138: }
139: }
140: }
141:
142: doc_type = DO_MAIL ; /* Default to mail document */
143:
144: /* Parse headers */
145:
146: while (TRUE)
147: {
148: if (emptyline(nextline)) break ; /* End of headers */
149:
150: if (!digest)
151: {
152: get_header(FROM_HDR, &from_) ;
153: get_header(APP_FROMHDR, &apparently_from) ;
154: get_header(APP_TOHDR, &apparently_to) ;
155: get_header(NEWSGROUPSHDR, &newsgroups) ;
156: get_header(NEWSGROUPHDR, &newsgroups) ;
157: get_header(REPLYHDR, &reply_to) ;
158:
159: get_mult_hdr(TOHDR, to) ;
160: if (emptyline(nextline)) break ;
161:
162: get_mult_hdr(CCHDR, cc) ;
163: if (emptyline(nextline)) break ;
164:
165: if (doc_type != DO_NEWS && hdr_equal(NEWSGROUPSHDR))
166: doc_type = DO_NEWS ;
167: if (doc_type != DO_NEWS && hdr_equal(NEWSGROUPHDR))
168: doc_type = DO_NEWS ;
169: }
170: get_header(FROMHDR, &from) ;
171: get_header(SUBJECTHDR, &subject) ;
172: get_header(DATEHDR, &date) ;
173:
174: if (content)
175: {
176: get_header(CONTENT_LEN, &content_len) ;
177: if (hdr_equal(CONTENT_LEN))
178: {
179: SSCANF(nextline, "%s %d", tmpstr, &mlen) ;
180:
181: /* The Content-Length: doesn't seem to include the initial blank line
182: * between the mail header and the message body, or the blank line after
183: * the message body and before the start of the next "From " header, so add
184: * in two for those.
185: */
186: mlen += 2 ;
187: }
188: }
189:
190: if (!hdr_equal(TOHDR) && !hdr_equal(CCHDR))
191: {
192: while (!end_of_file && !end_of_line)
193: readline() ; /* Skip rest of long lines */
194: readline() ;
195: }
196: }
197: }
198:
199:
200:
201: reset_headers() /* Reset header values for next message. */
202: {
203: int i ;
204:
205: if (from != NULL) free(from) ;
206: if (from_ != NULL) free(from_) ;
207: if (apparently_from != NULL) free(apparently_from) ;
208: if (apparently_to != NULL) free(apparently_to) ;
209: if (content_len != NULL) free(content_len) ;
210: if (date != NULL) free(date) ;
211: if (newsgroups != NULL) free(newsgroups) ;
212: if (reply_to != NULL) free(reply_to) ;
213:
214: from = from_ = apparently_from = apparently_to = NULL ;
215: date = newsgroups = reply_to = subject = NULL ;
216:
217: for (i = 0; i < MAXCONT+1; i++)
218: {
219: if (to[i] != NULL) free(to[i]) ;
220: if (cc[i] != NULL) free(cc[i]) ;
221: to[i] = cc[i] = NULL ;
222: }
223: }
224:
225:
226: /* Show_headers outputs the headers in PostScript. Different headers are
227: * output depending 'digest'.
228: */
229:
230:
231: show_headers(digest)
232: int digest ;
233: {
234: if (digest)
235: {
236: if (from) mixedshow(FROMHDR, from) ;
237: if (subject) mixedshow(SUBJECTHDR, subject) ;
238: if (date) mixedshow(DATEHDR, date) ;
239: }
240: else
241: {
242: if (from_) boldshow(FROM_HDR, from_) ;
243: if (from) mixedshow(FROMHDR, from) ;
244: if (apparently_from) mixedshow(APP_FROMHDR, apparently_from) ;
245: if (to[0]) show_mult_hdr(TOHDR, to) ;
246: if (apparently_to) mixedshow(APP_TOHDR, apparently_to) ;
247: if (cc[0]) show_mult_hdr(CCHDR, cc) ;
248: if (reply_to) mixedshow(REPLYHDR, reply_to) ;
249: if (newsgroups) mixedshow(NEWSGROUPSHDR, newsgroups) ;
250: if (subject) mixedshow(SUBJECTHDR, subject) ;
251: if (date) mixedshow(DATEHDR, date) ;
252: }
253: FPUTS("sf ", stdout) ;
254: }
255:
256:
257: void
258: show_mult_hdr(hdr, val)
259: char *hdr ; /* Name of header */
260: char *val[] ; /* Value of header */
261: {
262: mixedshow(hdr, *val) ;
263: val++ ;
264: while (*val) romanshow(*val++) ;
265: }