home *** CD-ROM | disk | FTP | other *** search
- /* $Header: E:\SRC\UUPC\RN\RCS/NGDATA.C 1.1 1992/11/21 06:14:58 ahd Exp $
- *
- * $Log: NGDATA.C $
- * Revision 1.1 1992/11/21 06:14:58 ahd
- * Initial
- *
- *
- * Rev 1.0 18 Nov 1990 0:22:10
- * Initial revision.
- * 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 /* SERVER */
- }
-
- /* 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);
- }
-
- #ifndef msdos
- #endif
-
- 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 */
- }
-
- #if 0
- ACT_POS
- findact(outbuf, nam, len, suggestion)
- char *outbuf;
- char *nam;
- int len;
- long suggestion;
- {
- long minart;
- long maxart;
- char mode;
-
- if (!get_ng_info(nam, &minart, &maxart, &mode))
- return -1L;
- sprintf(outbuf, "%s %10.10ld %10.10ld %c\n",
- nam, maxart, minart, mode);
- return suggestion;
- }
-
- #endif /* msdos */
-
- /* 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 */
- strcpy(dirname, 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;
- {
-
- #ifndef msdos
- 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;
- #else
- return floor;
- #endif
- }
-
- #endif
-