/* $Id: head.c,v 1.3 1993/08/02 23:52:34 nate Exp $ */ /* 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 authors 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}; void head_init() { register int i; for (i=HEAD_FIRST+1; i LONGKEY+2) return SOME_LINE; for (t=lc,f=bufptr; fdate) 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 */ } void end_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+1; /* 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 */ bool parseheader(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 */ 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; /* Only return a cached subject line if it isn't the current article */ if (which_line != SUBJ_LINE || parsed_art != artnum) { s = fetchcache(artnum,which_line,FILL_CACHE); 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 */ 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; #ifdef USE_NNTP if (parsed_art != artnum) { ARTICLE *ap; int size; register ART_NUM num, priornum, lastnum; bool cached; s = fetchcache(artnum,which_line,DONT_FILL_CACHE); 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 = (htype[which_line].ht_flags & HT_CACHED)) != 0) 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 (ap = find_article(artnum); ; ) { 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; } #endif /* Only return a cached subject line if it isn't the current article */ s = Nullch; if (which_line != SUBJ_LINE || parsed_art != artnum) s = fetchcache(artnum,which_line,FILL_CACHE); if ((firstpos = htype[which_line].ht_minpos) < 0) s = nullstr; if (s) { if (copy) s = savestr(s); return s; } firstpos += htype[which_line].ht_length + 1; lastpos = htype[which_line].ht_maxpos; size = lastpos - firstpos; if (copy) s = safemalloc((MEM_SIZE)size); else { /* hope this is okay--we're */ s = cmd_buf; /* really scraping for space here */ if (size > sizeof cmd_buf) size = sizeof cmd_buf; } t = headbuf + firstpos; while (*t == ' ' || *t == '\t') t++; *s = '\0'; safecat(s,t,size); return s; }