|
|
1.1 ! root 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: dumpheader(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: void ! 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: } ! 299:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.