📄 head.c
字号:
/* $Id: head.c,v 3.0 1992/02/23 21:25:39 davison Trn $ *//* This software is Copyright 1991 by Stan Barber. * * Permission is hereby granted to copy, reproduce, redistribute or otherwise * use this software as long as: there is no monetary profit gained * specifically from the use or reproduction of this software, it is not * sold, rented, traded or otherwise marketed, and this copyright notice is * included prominently in any copy made. * * The author make no claims as to the fitness or correctness of this software * for any use whatsoever, and it is provided as is. Any use of this software * is at the user's own risk. */#include "EXTERN.h"#include "common.h"#include "artio.h"#include "cache.h"#include "ng.h"#include "ngdata.h"#include "util.h"#include "hash.h"#include "rthread.h"#include "rt-process.h"#include "rt-util.h"#include "final.h"#include "nntp.h"#include "INTERN.h"#include "head.h"bool first_one; /* is this the 1st occurance of this header line? */static char htypeix[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};voidhead_init(){ register int i; for (i=HEAD_FIRST+1; i<HEAD_LAST; i++) htypeix[*htype[i].ht_name - 'a'] = i; headbuf_size = LBUFLEN * 8; headbuf = safemalloc(headbuf_size);}#ifdef DEBUGvoiddumpheader(where)char *where;{ register int i; printf("header: %d %s", parsed_art, where); for (i=0; i<HEAD_LAST; i++) { printf("%15s %4d %4d %03o\n",htype[i].ht_name, htype[i].ht_minpos, htype[i].ht_maxpos, htype[i].ht_flags) FLUSH; }}#endifintset_line_type(bufptr,colon)char *bufptr;register char *colon;{ char lc[LONGKEY+3]; register char *t, *f; register int i, len; if (colon-bufptr > LONGKEY+2) return SOME_LINE; for (t=lc,f=bufptr; f<colon; f++, t++) { if (isspace(*f)) /* guard against space before : */ break; *t = isupper(*f) ? tolower(*f) : *f; } *t = '\0'; f = lc; /* get lc into register */ len = t - f; /* now scan the headtype table, backwards so we don't have to supply an * extra terminating value, using first letter as index, and length as * optimization to avoid calling subroutine strEQ unnecessarily. Hauls. */ if (islower(*f)) { for (i = htypeix[*f - 'a']; *htype[i].ht_name == *f; --i) { if (len == htype[i].ht_length && strEQ(f, htype[i].ht_name)) { return i; } } } return SOME_LINE;}voidstart_header(artnum)ART_NUM artnum;{ register int i;#ifdef DEBUG if (debug & DEB_HEADER) dumpheader("start_header\n");#endif for (i=0; i<HEAD_LAST; i++) { htype[i].ht_minpos = -1; htype[i].ht_maxpos = 0; } in_header = SOME_LINE; first_one = FALSE; parsed_art = artnum;}voidend_header_line(){ if (first_one) { /* did we just pass 1st occurance? */ first_one = FALSE; /* remember where line left off */ htype[in_header].ht_maxpos = artpos; if (htype[in_header].ht_flags & HT_CACHED) { ARTICLE *ap = article_ptr(parsed_art); if (!get_cached_line(ap, in_header, TRUE)) { int start = htype[in_header].ht_minpos + htype[in_header].ht_length + 1; MEM_SIZE size; char *s; while (headbuf[start] == ' ' || headbuf[start] == '\t') start++; size = artpos - start + 1 - 1; /* pre-strip newline */ if (in_header == SUBJ_LINE) set_subj_line(ap,headbuf+start,size-1); else { s = safemalloc(size); *s = '\0'; safecat(s,headbuf+start,size); set_cached_line(ap,in_header,s); } } } }}boolparseline(art_buf,newhide,oldhide)char *art_buf;int newhide, oldhide;{ if (*art_buf == ' ' || *art_buf == '\t') { /* header continuation line? */ return oldhide; } else { /* maybe another header line */ char *s; end_header_line(); s = index(art_buf,':'); if (s == Nullch) /* is it the end of the header? */ in_header = PAST_HEADER; else { /* it is a new header line */ in_header = set_line_type(art_buf,s); first_one = (htype[in_header].ht_minpos < 0); if (first_one) { htype[in_header].ht_minpos = artpos; if (in_header == DATE_LINE) { register ARTICLE *ap = article_ptr(parsed_art); if (!ap->date) ap->date = parsedate(art_buf+6); } }#ifdef DEBUG if (debug & DEB_HEADER) dumpheader(art_buf);#endif if (htype[in_header].ht_flags & HT_HIDE) return newhide; } } return FALSE; /* don't hide this line */}voidend_header(){ register ARTICLE *ap = article_ptr(parsed_art); end_header_line(); in_header = PAST_HEADER; /* just to be sure */ if (!ap->subj) { uncache_article(ap,FALSE); return; }#ifndef DBM_XREFS if (htype[XREF_LINE].ht_minpos < 0) article_ptr(parsed_art)->xrefs = nullstr;#endif#ifdef USE_NNTP htype[PAST_HEADER].ht_minpos = artpos; /* remember where body starts */#else htype[PAST_HEADER].ht_minpos = ftell(artfp);#endif if (ThreadedGroup && !(ap->flags & AF_THREADED)) { if (valid_article(ap)) { ARTICLE *artp_hold = artp; references = fetchlines(parsed_art, REFS_LINE); thread_article(ap); free(references); artp = artp_hold; } } else if (!(ap->flags & AF_CACHED)) cache_article(ap); check_poster(ap);}/* read the header into memory and parse it if we haven't already */boolparseheader(artnum)ART_NUM artnum;{ register char *bp; register int len; if (parsed_art == artnum) return TRUE; if (artnum > lastart) return FALSE; spin(20);#ifdef USE_NNTP if (!nntp_header(artnum)) { uncache_article(article_ptr(artnum),FALSE); return FALSE; }#else if (!artopen(artnum)) return FALSE;#endif start_header(artnum); artpos = 0; bp = headbuf; while (in_header) { if (headbuf_size < artpos + LBUFLEN) { headbuf_size += LBUFLEN * 4; headbuf = saferealloc(headbuf,headbuf_size); }#ifdef USE_NNTP nntp_gets(bp,LBUFLEN); if (*bp == '.') { if (!bp[1]) { *bp++ = '\n'; /* tag the end with an empty line */ artpos++; break; } strcpy(bp,bp+1); } len = strlen(bp); bp[len++] = '\n'; bp[len] = '\0';#else if (fgets(bp,LBUFLEN,artfp) == Nullch) break; len = strlen(bp);#endif parseline(bp,FALSE,FALSE); artpos += len; bp += len; } *bp = '\0'; /* this probably isn't needed */ end_header(); return TRUE;}/* get a header line from an article */char *fetchlines(artnum,which_line)ART_NUM artnum; /* article to get line from */int which_line; /* type of line desired */{ char *s, *t; register ART_POS firstpos; register ART_POS lastpos; int size; s = fetchcache(artnum,which_line); if (s) return savestr(s); if ((firstpos = htype[which_line].ht_minpos) < 0) return savestr(nullstr); firstpos += htype[which_line].ht_length + 1; lastpos = htype[which_line].ht_maxpos; size = lastpos - firstpos;#ifdef DEBUG if (debug && (size < 1 || size > 1000)) { printf("Firstpos = %ld, lastpos = %ld\n",(long)firstpos,(long)lastpos); gets(cmd_buf); }#endif s = safemalloc((MEM_SIZE)size); t = headbuf + firstpos; while (*t == ' ' || *t == '\t') t++; *s = '\0'; safecat(s,t,size); return s;}/* prefetch a header line from one or more articles */#ifdef USE_NNTPchar *prefetchlines(artnum,which_line,copy) /* NNTP version */ART_NUM artnum; /* article to get line from */int which_line; /* type of line desired */bool_int copy; /* do you want it savestr()ed? */{ register ARTICLE *ap; register char *s, *t; int size; register ART_NUM num, priornum, lastnum; bool cached = (htype[which_line].ht_flags & HT_CACHED); /* find_article() returns a Nullart if the artnum value is invalid */ if (!(ap = find_article(artnum)) || (ap->flags & AF_MISSING)) s = nullstr; else if (cached) s = get_cached_line(ap, which_line, untrim_cache); else s = Nullch; if (s) { if (copy) s = savestr(s); return s; } spin(20); if (copy) s = safemalloc((MEM_SIZE)(size = LBUFLEN)); else { s = cmd_buf; size = sizeof cmd_buf; } *s = '\0'; priornum = artnum-1; lastnum = artnum + PREFETCH_SIZE - 1; if (lastnum > lastart) lastnum = lastart; if (cached) sprintf(ser_line,"XHDR %s %ld-%ld",htype[which_line].ht_name, artnum,lastnum); else sprintf(ser_line,"XHDR %s %ld",htype[which_line].ht_name,artnum); nntp_command(ser_line); if (nntp_check(TRUE) == NNTP_CLASS_OK) { for (;;) { nntp_gets(ser_line, sizeof ser_line);# ifdef DEBUG if (debug & DEB_NNTP) printf("<%s\n", ser_line) FLUSH;# endif if (ser_line[0] == '.') break; if ((t = index(ser_line, '\r')) != Nullch) *t = '\0'; if (!(t = index(ser_line, ' '))) continue; t++; num = atol(ser_line); if (num < artnum || num > lastnum) continue; while (++priornum < num) uncache_article(ap++,FALSE); if (which_line == SUBJ_LINE) set_subj_line(ap++, t, strlen(t)); else if (cached) set_cached_line(ap++, which_line, savestr(t)); if (num == artnum) safecat(s,t,size); } } else { fprintf(stderr,"\nUnexpected close of server socket.\n"); finalize(1); } while (priornum++ < lastnum) uncache_article(ap++,FALSE); if (copy) s = saferealloc(s, (MEM_SIZE)strlen(s)+1); return s;}#else /* !USE_NNTP */char *prefetchlines(artnum,which_line,copy)ART_NUM artnum; /* article to get line from */int which_line; /* type of line desired */bool_int copy; /* do you want it savestr()ed? */{ char *s, *t; register ART_POS firstpos; register ART_POS lastpos; int size; if (copy) return fetchlines(artnum,which_line); s = fetchcache(artnum,which_line); if (s) return s; if ((firstpos = htype[which_line].ht_minpos) < 0) return nullstr; firstpos += htype[which_line].ht_length + 1; lastpos = htype[which_line].ht_maxpos; size = lastpos - firstpos; t = headbuf + firstpos; while (*t == ' ' || *t == '\t') t++; *cmd_buf = '\0'; safecat(cmd_buf,t,CBUFLEN); /* hope this is okay--we're */ return cmd_buf; /* really scraping for space here */}#endif /* !USE_NNTP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -