home *** CD-ROM | disk | FTP | other *** search
- /* $Header: ngdata.c,v 4.3.3.2 91/01/16 03:18:21 davison Trn $
- *
- * $Log: ngdata.c,v $
- * Revision 4.3.3.2 91/01/16 03:18:21 davison
- * Integrated rn patches 48-54. Fixed bug in ZEROGLOB code.
- *
- * Revision 4.3.3.1 90/07/21 20:28:27 davison
- * Initial Trn Release
- *
- * 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];
- int entries;
- #endif
- char *cp;
-
- /* The following is only for systems that do not zero globals properly */
- #ifdef ZEROGLOB
- # ifdef CACHEFIRST
- {
- int i;
- for (i=0; i<MAXRCLINE; i++)
- abs1st[i] = 0;
- }
- # endif
- #endif /* ZEROGLOB */
-
- /* open the active file */
-
- #ifdef SERVER
-
- #ifdef USETHREADS
- if (use_threads) {
- cp = filexp(ACTIVE2);
- actfp = fopen(cp,"r");
- if (actfp == Nullfp) {
- printf(cantopen,cp) FLUSH;
- finalize(1);
- }
- return;
- }
- #endif
-
- 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 */
-
- #ifdef USETHREADS
- if (use_threads)
- cp = filexp(ACTIVE2);
- else
- #endif
- cp = filexp(ACTIVE);
- actfp = fopen(cp,"r");
- if (actfp == Nullfp) {
- printf(cantopen,cp) 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, ch;
- 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++;
- ch = *s;
- #ifdef USETHREADS
- if (isupper(ch)) {
- ch = tolower(ch);
- ThreadedGroup = FALSE;
- } else
- ThreadedGroup = use_threads;
- #endif
- 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;
- }
- }
- }
- #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
-