⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 head.c

📁 早期freebsd实现
💻 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 + -