4.4BSD/usr/src/contrib/news/trn3/ngdata.c

Compare this file to the similar file:
Show the results in this format:

/* $Id: ngdata.c,v 3.0 1992/02/01 03:09:32 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 "rcstuff.h"
#include "trn.h"
#include "cache.h"
#include "bits.h"
#include "head.h"
#include "rthread.h"
#include "rt-select.h"
#include "ng.h"
#include "intrp.h"
#include "kfile.h"
#include "final.h"
#include "rcln.h"
#include "term.h"
#include "util.h"
#include "nntp.h"
#include "ndir.h"
#include "INTERN.h"
#include "ngdata.h"

/* open the active file */

void
ngdata_init()
{
#ifdef USE_NNTP
    char *cp;

    nntp_command("LIST");	/* tell server we want the active file */
    if (nntp_check(TRUE) != NNTP_CLASS_OK) { /* and then see if that's ok */
	printf("Can't get active file from server: \n%s\n", ser_line);
	finalize(1);
    }
    time(&lastactfetch);

    cp = filexp("%P/rrnact.%$");	/* make a temporary name */
    strcpy(active_name, cp);
    actfp = fopen(active_name, "w+");	/* and get ready */
    if (actfp == Nullfp) {
	printf(cantopen,active_name) FLUSH;
	finalize(1);
    }

    activeitems = 0;
    while (1) {
	nntp_gets(ser_line, sizeof ser_line);
	if (ser_line[0] == '.')		/* while there's another line */
	    break;			/* get it and write it to */
	activeitems++;
	fputs(ser_line, actfp);
	putc('\n', actfp);
    }

    if (ferror(actfp)) {
	printf("Error writing to active file %s.\n", active_name) FLUSH;
	finalize(1);
    }
#else /* !USE_NNTP */
    ngdatansrv_init();
#endif
    if (fseek(actfp,0L,0) == -1) {	/* just get to the beginning */
	printf("Error seeking in active file.\n") FLUSH;
	finalize(1);
    }
    return;
}

bool
access_ng()
{
#ifdef USE_NNTP
    long unread, first, last;

    if (!nntp_group(ngname)) {
	toread[ng] = TR_BOGUS;
	return FALSE;
    }
    if ((lastart = getngsize(ng)) < 0)	/* this cannot happen (laugh here) */
	return FALSE;
    (void) sscanf(ser_line,"%*d%ld%ld%ld",&unread,&first,&last);

    /* NNTP mangles the high/low values when no articles are present. */
    if (!unread)
	absfirst = lastart+1;
    else {
	absfirst = (ART_NUM)first;
	if (last > lastart)
	    lastart = (ART_NUM)last;
    }
    ngmax[ng] = lastart;	/* ensure getngsize() knows the new maximum */
    first = abs1st[ng];
    abs1st[ng] = absfirst;
    if (absfirst > first)
	checkexpired(ng);
#else /* !USE_NNTP */

    if (eaccess(ngdir,5)) {		/* directory read protected? */
	if (eaccess(ngdir,0)) {
# ifdef VERBOSE
	    IF(verbose)
		printf("\nNewsgroup %s does not have a spool directory!\n",
		    ngname) FLUSH;
	    ELSE
# endif
# ifdef TERSE
		printf("\nNo spool for %s!\n",ngname) FLUSH;
# endif
# ifdef CATCHUP
	    catch_up(ng);
# endif
	} else {
# ifdef VERBOSE
	    IF(verbose)
		printf("\nNewsgroup %s is not currently accessible.\n",
		    ngname) FLUSH;
	    ELSE
# endif
# ifdef TERSE
		printf("\n%s not readable.\n",ngname) FLUSH;
# endif
	}
	toread[ng] = TR_NONE; /* make this newsgroup temporarily invisible */
	return FALSE;
    }

    /* chdir to newsgroup subdirectory */

    if (chdir(ngdir)) {
	printf(nocd,ngdir) FLUSH;
	return FALSE;
    }
    if ((lastart = getngsize(ng)) < 0)	/* this cannot happen (laugh here) */
	return FALSE;
    absfirst = abs1st[ng];
    setfoundbits();			/* might reset absfirst */
#endif /* !USE_NNTP */

    dmcount = 0;

    build_cache();
    return TRUE;
}

void
grow_ng(newlast)
ART_NUM newlast;
{
    ART_NUM tmpfirst;

    forcegrow = FALSE;
    if (newlast > lastart) {
	ART_NUM tmpart = art;
	toread[ng] += (ART_UNREAD)(newlast-lastart);
	grow_cache(newlast);
	tmpfirst = lastart+1;
	lastart = newlast;
	thread_grow();
#ifdef KILLFILES
#ifdef VERBOSE
	IF(verbose)
	    sprintf(buf,
		"%ld more article%s arrived -- processing memorized commands...\n\n",
		(long)(lastart - tmpfirst + 1),
		(lastart > tmpfirst ? "s have" : " has" ) );
	ELSE			/* my, my, how clever we are */
#endif
#ifdef TERSE
	    strcpy(buf, "More news -- auto-processing...\n\n");
#endif
	if (has_normal_kills)
	    kill_unwanted(tmpfirst,buf,TRUE);
#endif
	art = tmpart;
    }
}

void
ng_skip()
{
#ifndef USE_NNTP			/* never read it & cannot find it? */
    if (errno != ENOENT) {	/* has it not been deleted? */
	clear();
# ifdef VERBOSE
	IF(verbose)
	    printf("\n(Article %ld exists but is unreadable.)\n",(long)art)
		FLUSH;
	ELSE
# endif
# ifdef TERSE
	    printf("\n(%ld unreadable.)\n",(long)art) FLUSH;
# endif
	if (novice_delays) {
	    pad(just_a_sec);
	    sleep(2);
	}
    }
    inc_art(selected_only,FALSE);	/* try next article */

#else /* USE_NNTP */
    ART_NUM artnum;

    clear();
# ifdef VERBOSE
    IF(verbose)
	fputs("Skipping unavailable article\n",stdout);
    ELSE
# endif /* VERBOSE */
# ifdef TERSE
	fputs("Skipping\n",stdout);
# endif /* TERSE */
    if (novice_delays) {
	pad(just_a_sec/3);
	sleep(1);
    }
    art++;
    artp++;
    do {
	/* tries to grab PREFETCH_SIZE XHDRS, flagging missing articles */
	(void) fetchsubj(art, FALSE);
	artnum = art+PREFETCH_SIZE-1;
	if (artnum > lastart)
	    artnum = lastart;
	while (art <= artnum) {
	    if (!(artp->flags & AF_MISSING))
		return;
	    art++;
	    artp++;
	}
    } while (art <= lastart);
#endif /* USE_NNTP */
}

/* find the maximum article number of a newsgroup */

ART_NUM
getngsize(num)
register NG_NUM num;
{
    register int len;
    register char *nam;
    char tmpbuf[LBUFLEN];
    ART_POS oldsoft;
    long last, first;
    char ch;

    nam = rcline[num];
    len = rcnums[num] - 1;
    softtries++;
#ifdef DEBUG
    if (debug & DEB_SOFT_POINTERS)
	printf("Softptr = %ld\n",(long)softptr[num]) FLUSH;
#endif
    oldsoft = softptr[num];
#ifndef USE_NNTP
    fseek(actfp,100000L,1);    /* hopefully this forces a reread */
#endif
    if ((softptr[num] = findact(tmpbuf, nam, len, (long)oldsoft)) >= 0) {
	if (softptr[num] != oldsoft) {
	    softmisses++;
	    writesoft = TRUE;
	}
    }
    else {
	softptr[num] = 0;
	if (RCCHAR(rcchar[num]) == ':')
	    rcchar[num] = NEGCHAR;
	return TR_BOGUS;		/* well, not so quietly, actually */
    }
	
#ifdef DEBUG
    if (debug & DEB_SOFT_POINTERS) {
	printf("Should be %ld\n",(long)softptr[num]) FLUSH;
    }
#endif
#ifndef ANCIENT_NEWS
    sscanf(tmpbuf+len+1, "%ld %ld %c", &last, &first, &ch);
#else
    sscanf(tmpbuf+len+1, "%ld %c", &last, &ch);
    first = 1;
#endif
    if (!abs1st[num])
	abs1st[num] = (ART_NUM)first;
    if (!in_ng) {
	switch (ch) {
	case 'n': moderated = getval("NOPOSTRING"," (no posting)"); break;
	case 'm': moderated = getval("MODSTRING", " (moderated)"); break;
	/* This shouldn't even occur.  What are we doing in a non-existent
	   group?  Disallow it. */
	case 'x': return TR_BOGUS;
	/* what should be done about refiled groups?  rn shouldn't even
	   be in them (ie, if sci.aquaria is refiled to rec.aquaria, then
	   get the news there) */
	case '=': return TR_BOGUS;
	default: moderated = nullstr;
	}
    }
    if (last < ngmax[num])
	return ngmax[num];
    return ngmax[num] = (ART_NUM)last;
}