1: /* $Header: head.c,v 4.3.1.2 85/05/10 13:47:25 lwall Exp $
2: *
3: * $Log: head.c,v $
4: * Revision 4.3.1.2 85/05/10 13:47:25 lwall
5: * Added debugging stuff.
6: *
7: * Revision 4.3.1.1 85/05/10 11:32:30 lwall
8: * Branch for patches.
9: *
10: * Revision 4.3 85/05/01 11:38:21 lwall
11: * Baseline for release with 4.3bsd.
12: *
13: */
14:
15: #include "EXTERN.h"
16: #include "common.h"
17: #include "artio.h"
18: #include "bits.h"
19: #include "util.h"
20: #include "INTERN.h"
21: #include "head.h"
22:
23: bool first_one; /* is this the 1st occurance of this header line? */
24:
25: static char htypeix[26] =
26: {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
27:
28: void
29: head_init()
30: {
31: register int i;
32:
33: for (i=HEAD_FIRST+1; i<HEAD_LAST; i++)
34: htypeix[*htype[i].ht_name - 'a'] = i;
35: }
36:
37: #ifdef DEBUGGING
38: (where)
39: char *where;
40: {
41: register int i;
42:
43: printf("header: %d %s", parsed_art, where);
44:
45: for (i=0; i<HEAD_LAST; i++) {
46: printf("%15s %4d %4d %03o\n",htype[i].ht_name,
47: htype[i].ht_minpos,
48: htype[i].ht_maxpos,
49: htype[i].ht_flags) FLUSH;
50: }
51: }
52: #endif
53:
54: int
55: set_line_type(bufptr,colon)
56: char *bufptr;
57: register char *colon;
58: {
59: char lc[LONGKEY+3];
60: register char *t, *f;
61: register int i, len;
62:
63: for (t=lc,f=bufptr; f<colon; f++, t++) {
64: if (isspace(*f))
65: /* guard against space before : */
66: break;
67: *t = isupper(*f) ? tolower(*f) : *f;
68: }
69: *t = '\0';
70: f = lc; /* get lc into register */
71: len = t - f;
72:
73: /* now scan the headtype table, backwards so we don't have to supply an
74: * extra terminating value, using first letter as index, and length as
75: * optimization to avoid calling subroutine strEQ unnecessarily. Hauls.
76: */
77:
78: if (islower(*f)) {
79: for (i = htypeix[*f - 'a']; *htype[i].ht_name == *f; --i) {
80: if (len == htype[i].ht_length && strEQ(f, htype[i].ht_name)) {
81: return i;
82: }
83: }
84: }
85: return SOME_LINE;
86: }
87:
88:
89: start_header(artnum)
90: ART_NUM artnum;
91: {
92: register int i;
93:
94: #ifdef DEBUGGING
95: if (debug & 4)
96: dumpheader("start_header\n");
97: #endif
98: for (i=0; i<HEAD_LAST; i++) {
99: htype[i].ht_minpos = -1;
100: htype[i].ht_maxpos = 0;
101: }
102: in_header = SOME_LINE;
103: first_one = FALSE;
104: #ifdef ASYNC_PARSE
105: parsed_art = artnum;
106: #endif
107: }
108:
109: bool
110: parseline(art_buf,newhide,oldhide)
111: char *art_buf;
112: int newhide, oldhide;
113: {
114: if (*art_buf == ' ' || *art_buf == '\t')
115: /* header continuation line? */
116: return oldhide;
117: else { /* maybe another header line */
118: char *s;
119:
120: if (first_one) { /* did we just pass 1st occurance? */
121: first_one = FALSE;
122: htype[in_header].ht_maxpos = artpos;
123: /* remember where line left off */
124: }
125: s = index(art_buf,':');
126: if (s == Nullch || s-art_buf > LONGKEY+2) {
127: /* is it the end of the header? */
128: htype[PAST_HEADER].ht_minpos =
129: (*art_buf == '\n') ? ftell(artfp) : artpos;
130: /* remember where body starts */
131: in_header = PAST_HEADER;
132: }
133: else { /* it is a new header line */
134: in_header = set_line_type(art_buf,s);
135: first_one = (htype[in_header].ht_minpos < 0);
136: if (first_one)
137: htype[in_header].ht_minpos = artpos;
138: #ifdef DEBUGGING
139: if (debug & 4)
140: dumpheader(art_buf);
141: #endif
142: if (htype[in_header].ht_flags & HT_HIDE)
143: return newhide;
144: }
145: }
146: return FALSE; /* don't hide this line */
147: }
148:
149: #ifdef ASYNC_PARSE
150: int
151: parse_maybe(artnum)
152: ART_NUM artnum;
153: {
154: char tmpbuf[LBUFLEN];
155:
156: if (parsed_art == artnum)
157: return 0;
158: /* no maybe about it now */
159: if (artopen(artnum) == Nullfp) {
160: return -1;
161: }
162: start_header(artnum);
163: while (in_header) {
164: artpos = ftell(artfp);
165: if (fgets(tmpbuf,LBUFLEN,artfp) == Nullch)
166: break;
167: parseline(tmpbuf,FALSE,FALSE);
168: }
169: in_header = PAST_HEADER;
170: return 0;
171: }
172: #endif
173:
174: /* get the subject line for an article */
175:
176: char *
177: fetchsubj(artnum,current_subject,copy)
178: ART_NUM artnum; /* article to get subject from */
179: bool current_subject; /* is it in a parsed header? */
180: bool copy; /* do you want it savestr()ed? */
181: {
182: char *s = Nullch, *t;
183:
184: #ifdef CACHESUBJ
185: if (!subj_list) {
186: register ART_NUM i;
187:
188:
189: #ifndef lint
190: subj_list =
191: (char**)safemalloc((MEM_SIZE)((OFFSET(lastart)+2)*sizeof(char *)));
192: #endif lint
193: for (i=0; i<=OFFSET(lastart); i++)
194: subj_list[i] = Nullch;
195: }
196: if (!artnum || artnum > lastart)
197: s = nullstr;
198: else
199: s = subj_list[OFFSET(artnum)];
200: #endif
201: if (s == Nullch) {
202: if (current_subject) {
203: s = fetchlines(artnum,SUBJ_LINE);
204: #ifdef CACHESUBJ
205: subj_list[OFFSET(artnum)] = s;
206: #endif
207: }
208: else {
209: s = safemalloc((MEM_SIZE)256);
210: *s = '\0';
211: if (artopen(artnum) != Nullfp) {
212: do {
213: if (fgets(s,256,artfp) == Nullch)
214: strcpy(s, "Title: \n");
215: } while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8));
216: s[strlen(s)-1] = '\0';
217: t = index(s,':')+1;
218: while (*t == ' ') t++;
219: strcpy(s, t);
220: }
221: s = saferealloc(s, (MEM_SIZE)strlen(s)+1);
222: #ifdef CACHESUBJ
223: subj_list[OFFSET(artnum)] = s;
224: #endif
225: }
226: }
227: #ifdef CACHESUBJ
228: if (copy) {
229: t = savestr(s);
230: return t;
231: }
232: else
233: return s;
234: #else
235: if (copy)
236: return s;
237: else {
238: safecpy(cmd_buf,s,CBUFLEN); /* hope this is okay--we're */
239: free(s);
240: return cmd_buf; /* really scraping for space here */
241: }
242: #endif
243: }
244:
245: /* get header lines from an article */
246:
247: char *
248: fetchlines(artnum,which_line)
249: ART_NUM artnum; /* article to get line from */
250: int which_line; /* type of line desired */
251: {
252: char *newbuf, *t, tmp_buf[LBUFLEN];
253: register ART_POS curpos;
254: int size;
255: register ART_POS firstpos;
256: register ART_POS lastpos;
257:
258: #ifdef ASYNC_PARSE
259: if (parse_maybe(artnum))
260: artnum = 0;
261: #endif
262: firstpos = htype[which_line].ht_minpos;
263: lastpos = htype[which_line].ht_maxpos;
264: if (!artnum || firstpos < 0 || artopen(artnum) == Nullfp) {
265: newbuf = safemalloc((unsigned int)1);
266: *newbuf = '\0';
267: return newbuf;
268: }
269: #ifndef lint
270: size = lastpos - firstpos + 1;
271: #else
272: size = Null(int);
273: #endif lint
274: #ifdef DEBUGGING
275: if (debug && (size < 1 || size > 1000)) {
276: printf("Firstpos = %ld, lastpos = %ld\n",(long)firstpos,(long)lastpos);
277: gets(tmp_buf);
278: }
279: #endif
280: newbuf = safemalloc((unsigned int)size);
281: *newbuf = '\0';
282: fseek(artfp,firstpos,0);
283: for (curpos = firstpos; curpos < lastpos; curpos = ftell(artfp)) {
284: if (fgets(tmp_buf,LBUFLEN,artfp) == Nullch)
285: break;
286: if (*tmp_buf == ' ' || *tmp_buf == '\t')
287: t = tmp_buf;
288: else
289: t = index(tmp_buf,':')+1;
290: if (t == Nullch)
291: break;
292: else {
293: while (*t == ' ' || *t == '\t') t++;
294: safecat(newbuf,t,size);
295: }
296: }
297: return newbuf;
298: }