ftp.nice.ch/pub/next/unix/network/news/rn.5.4.s.tar.gz#/rn/ngdata.c

This is ngdata.c in view mode; [Download] [Up]

/* $Header: ngdata.c,v 4.3.2.11 90/11/22 16:14:34 sob Exp $
 *
 * $Log:	ngdata.c,v $
 * Revision 4.3.2.11  90/11/22  16:14:34  sob
 * Added changes to accomodate picky C preprocessors
 * 
 * Revision 4.3.2.10  90/04/14  22:05:15  sob
 * Removed redundant declaration of active_name
 * 
 * Revision 4.3.2.9  90/03/22  23:04:55  sob
 * Fixes provided by Wayne Davison <drivax!davison>
 * 
 * Revision 4.3.2.8  90/03/17  20:50:51  sob
 * Fixes provided by stewart@netxcom.iad-nxe.global-mis.dhl.com to handle
 * flaky transfers of the active file from the server.
 * 
 * Revision 4.3.2.7  90/03/17  17:11:08  sob
 * Added support for CNEWS active file flags.
 *
 * Revision 4.3.2.6  89/12/08  22:42:04  sob
 * Corrected typo in an #ifdef statement pointed out by
 * jik@pit-manager.mit.edu
 * 
 * Revision 4.3.2.5  89/11/28  01:51:14  sob
 * Removed redundant #include directive.
 * 
 * Revision 4.3.2.4  89/11/27  01:31:07  sob
 * Altered NNTP code per ideas suggested by Bela Lubkin
 * <filbo@gorn.santa-cruz.ca.us>
 * 
 * Revision 4.3.2.3  89/11/08  02:41:40  sob
 * Removed unneeded subroutine.
 * 
 * Revision 4.3.2.2  89/11/08  02:24:31  sob
 * Integrated modifications from other RRN patches colleceted from USENET
 * 
 * Revision 4.3.2.1  89/11/06  00:42:43  sob
 * Added RRN support from NNTP 1.5
 * 
 * Revision 4.3  85/05/01  11:44:38  lwall
 * Baseline for release with 4.3bsd.
 * 
 */

#include "EXTERN.h"
#include "common.h"
#include "ndir.h"
#include "rcstuff.h"
#include "rn.h"
#include "intrp.h"
#include "final.h"
#include "rcln.h"
#include "util.h"
#ifdef SERVER
#include "server.h"
#endif
#include "INTERN.h"
#include "ngdata.h"

void
ngdata_init()
{
#ifdef SERVER
    char ser_line[256];
    char *cp;
    int entries;
#endif
/* The following is only for systems that do not zero globals properly */
#ifdef ZEROGLOB
# ifdef CACHEFIRST
    for (i=0; i<MAXRCLINE; i++)
	abs1st[i] = 0;
# endif
#endif	/* ZEROGLOB */

    /* open the active file */

#ifdef SERVER

    put_server("LIST");		/* tell server we want the active file */
    get_server(ser_line, sizeof(ser_line));
    if (*ser_line != CHAR_OK) {		/* and then see if that's ok */
	fprintf(stdout, "Can't get active file from server: \n%s\n", ser_line);
	finalize(1);
    }

    cp = filexp("/tmp/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);
    }

    entries = 0;
    while (1) {
	if (get_server(ser_line, sizeof(ser_line)) < 0) {
	    printf("Can't get active file from server:\ntransfer failed after %d entries\n", entries);
	    finalize(1);
	}
	if (ser_line[0] == '.')		/* while there's another line */
		break;			/* get it and write it to */
	entries++;
	fputs(ser_line, actfp);
	putc('\n', actfp);
    }

    fseek(actfp,0L,0);		/* just get to the beginning */

#else /* not SERVER */

    actfp = fopen(filexp(ACTIVE),"r");
    if (actfp == Nullfp) {
	printf(cantopen,filexp(ACTIVE)) FLUSH;
	finalize(1);
    }
#endif
}

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

ART_NUM
getngsize(num)
register NG_NUM num;
{
    register int len;
    register char *nam;
    char tmpbuf[80];
    ART_POS oldsoft;

    nam = rcline[num];
    len = rcnums[num] - 1;
    softtries++;
#ifdef DEBUGGING
    if (debug & DEB_SOFT_POINTERS)
	printf("Softptr = %ld\n",(long)softptr[num]) FLUSH;
#endif
    oldsoft = softptr[num];
    if ((softptr[num] = findact(tmpbuf, nam, len, (long)oldsoft)) >= 0) {
	if (softptr[num] != oldsoft) {
	    softmisses++;
	    writesoft = TRUE;
	}
    }
    else {
	softptr[num] = 0;
	if (rcchar[num] == ':')		/* unsubscribe quietly */
	    rcchar[num] = NEGCHAR;
	return TR_BOGUS;		/* well, not so quietly, actually */
    }
	
#ifdef DEBUGGING
    if (debug & DEB_SOFT_POINTERS) {
	printf("Should be %ld\n",(long)softptr[num]) FLUSH;
    }
#endif
#ifdef MININACT
    {
	register char *s;
	ART_NUM tmp;

	for (s=tmpbuf+len+1; isdigit(*s); s++) ;
	if (tmp = atol(s))
#ifdef CACHEFIRST
	    abs1st[num] = tmp;
#else
	    abs1st = tmp;
#endif
	if (!in_ng) {
	    for (s++; isdigit(*s); s++) ;
	    while (isspace(*s)) s++;
	    switch (*s) {
	    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;
	    }
	}
    }
#endif
    return atol(tmpbuf+len+1);
}

ACT_POS
findact(outbuf,nam,len,suggestion)
char *outbuf;
char *nam;
int len;
long suggestion;
{
    ACT_POS retval;

    fseek(actfp,100000L,1);	/* hopefully this forces a reread */
    if (suggestion == 0L || fseek(actfp,suggestion,0) < 0 ||
      fgets(outbuf,80,actfp) == Nullch ||
      outbuf[len] != ' ' ||
      strnNE(outbuf,nam,len)) {
#ifdef DEBUGGING
	if (debug & DEB_SOFT_POINTERS)
	    printf("Missed, looking for %s in %sLen = %d\n",nam,outbuf,len)
	      FLUSH;
#endif
	fseek(actfp,0L,0);
#ifndef lint
	retval = (ACT_POS)ftell(actfp);
#else
	retval = Null(ACT_POS);
#endif /* lint */
	while (fgets(outbuf,80,actfp) != Nullch) {
	    if (outbuf[len] == ' ' && strnEQ(outbuf,nam,len))
		return retval;
#ifndef lint
	    retval = (ACT_POS) ftell(actfp);
#endif /* lint */
	}
	return (ACT_POS) -1;		/* well, not so quietly, actually */
    }
    else
#ifndef lint
	return (ACT_POS) suggestion;
#else
	return retval;
#endif /* lint */
    /*NOTREACHED*/
}

/* determine the absolutely first existing article number */
#ifdef SERVER
ART_NUM
getabsfirst(ngnum,ngsize)
register NG_NUM ngnum;
ART_NUM ngsize;
{
    register ART_NUM a1st;
#ifndef MININACT
    char ser_line[256];
    ART_NUM x,y;
#endif

#ifdef CACHEFIRST
    if (a1st = abs1st[ngnum])
	return a1st;
#endif
#ifdef MININACT
    getngsize(ngnum);
# ifdef CACHEFIRST
    return abs1st[ngnum];
# else
    return abs1st;
# endif
#else
    sprintf(cp,"GROUP %s",rcline[ngnum]);
    put_server(cp);
    if (get_server(ser_line, sizeof(ser_line)) < 0) {
	fprintf(stderr, "rrn: Unexpected close of server socket.\n");
	finalize(1);
    }
    if (*ser_line != CHAR_OK) {		/* and then see if that's ok */
	a1st = ngsize+1;		/* nothing there */
    }
    (void) sscanf(ser_line,"%d%d%d",&x,&y,&a1st);
# ifdef CACHEFIRST
    abs1st[ngnum] = a1st;
# endif
    return a1st;
#endif
}
/* we already know the lowest article number with NNTP */
ART_NUM
getngmin(dirname,floor)
char *dirname;
ART_NUM floor;
{
    return(floor);
}
#else
ART_NUM
getabsfirst(ngnum,ngsize)
register NG_NUM ngnum;
ART_NUM ngsize;
{
    register ART_NUM a1st;
#ifndef MININACT
    char dirname[MAXFILENAME];
#endif

#ifdef CACHEFIRST
    if (a1st = abs1st[ngnum])
	return a1st;
#endif
#ifdef MININACT
    getngsize(ngnum);
# ifdef CACHEFIRST
    return abs1st[ngnum];
# else
    return abs1st;
# endif
#else /* not MININACT */
    sprintf(dirname,"%s/%s",spool,getngdir(rcline[ngnum]));
    a1st = getngmin(dirname,0L);
    if (!a1st)				/* nothing there at all? */
	a1st = ngsize+1;		/* aim them at end of newsgroup */
# ifdef CACHEFIRST
    abs1st[ngnum] = a1st;
# endif
    return a1st;
#endif /* MININACT */
}

/* scan a directory for minimum article number greater than floor */

ART_NUM
getngmin(dirname,floor)
char *dirname;
ART_NUM floor;
{
    register DIR *dirp;
    register struct DIRTYPE *dp;
    register ART_NUM min = 1000000;
    register ART_NUM maybe;
    register char *p;
    char tmpbuf[128];
    
    dirp = opendir(dirname);
    if (!dirp)
	return 0;
    while ((dp = readdir(dirp)) != Null(struct DIRTYPE *)) {
	if ((maybe = atol(dp->d_name)) < min && maybe > floor) {
	    for (p = dp->d_name; *p; p++)
		if (!isdigit(*p))
		    goto nope;
	    if (*dirname == '.' && !dirname[1])
		stat(dp->d_name, &filestat);
	    else {
		sprintf(tmpbuf,"%s/%s",dirname,dp->d_name);
		stat(tmpbuf, &filestat);
	    }
	    if (! (filestat.st_mode & S_IFDIR))
		min = maybe;
	}
      nope:
	;
    }
    closedir(dirp);
    return min==1000000 ? 0 : min;
}
#endif

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.