home *** CD-ROM | disk | FTP | other *** search
- /* $Header: E:\SRC\UUPC\RN\RCS/RCLN.C 1.1 1992/11/21 06:14:58 ahd Exp $
- *
- * $Log: RCLN.C $
- * Revision 1.1 1992/11/21 06:14:58 ahd
- * Initial
- *
- *
- * Rev 1.0 18 Nov 1990 0:21:52
- * Initial revision.
- * Revision 4.3.2.1 90/04/23 00:22:22 sob
- * Changed atoi to atol and fixed RCS information.
- *
- * Revision 4.3.1.2 85/07/23 17:39:08 lwall
- * Oops, was freeing a static buf on -c in checkexpired.
- *
- * Revision 4.3.1.1 85/05/10 11:37:08 lwall
- * Branch for patches.
- *
- * Revision 4.3 85/05/01 11:45:36 lwall
- * Baseline for release with 4.3bsd.
- *
- */
-
- #include <stdlib.h>
- #include <string.h>
-
- #include "EXTERN.h"
- #include "common.h"
- #include "util.h"
- #include "rcstuff.h"
- #include "ngdata.h"
- #include "INTERN.h"
- #include "rcln.h"
-
- void
- rcln_init()
- {
- ;
- }
-
- #ifdef CATCHUP
- void
- catch_up(ngx)
- NG_NUM ngx;
- {
- char tmpbuf[128];
- char *tmpp;
-
- #ifdef VERBOSE
- IF(verbose)
- printf("\nMarking %s as all read.\n", rcline[ngx]) FLUSH;
- ELSE
- #endif
-
- #ifdef TERSE
- fputs("\nMarked read\n", stdout) FLUSH;
- #endif
-
- sprintf(tmpbuf, "%s: 1-%ld", rcline[ngx], (long) getngsize(ngx));
- free(rcline[ngx]);
- rcline[ngx] = savestr(tmpbuf);
- tmpp = rcline[ngx] + rcnums[ngx] - 1;
- *tmpp = '\0';
- write_rc();
- }
-
- #endif
-
- /* add an article number to a newsgroup, if it isn't already read */
-
- int
- addartnum(artnum, ngnam)
- ART_NUM artnum;
- char *ngnam;
- {
- register NG_NUM ngnum = find_ng(ngnam);
- register char *s, *t, *maxt = Nullch;
- ART_NUM min = 0, max = -1, lastnum = 0;
- char *mbuf;
- bool morenum;
-
- if (!artnum)
- return 0;
- if (ngnum == nextrcline || !rcnums[ngnum])
- /* not found in newsrc? */
- return 0;
-
- #ifdef CACHEFIRST
- if (!abs1st[ngnum])
- #else
- if (!toread[ngnum])
- #endif
-
- /* now is a good time to trim down */
- set_toread(ngnum); /* the list due to
- * expires if we */
- /* have not yet. */
-
- #ifdef DEBUGGING
- if (artnum > ngmax[ngnum] + 10 /* allow for incoming
- * articles */
- )
- {
- printf("\nCorrupt Xref line!!! %ld --> %s(1..%ld)\n",
- artnum, ngnam,
- ngmax[ngnum]) FLUSH;
- paranoid = TRUE; /* paranoia reigns
- * supreme */
- return -1; /* hope this was the
- * first newsgroup */
- }
- #endif
-
- if (toread[ngnum] == TR_BOGUS)
- return 0;
-
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER)
- {
- printf("%ld->\n%s%c%s\n", (long) artnum, rcline[ngnum], rcchar[ngnum],
- rcline[ngnum] + rcnums[ngnum]) FLUSH;
- }
- #endif
-
- s = rcline[ngnum] + rcnums[ngnum];
- while (*s == ' ')
- s++; /* skip spaces */
- t = s;
- while (isdigit(*s) && artnum >= (min = atol(s)))
- {
- /* while it might have been read */
- for (t = s; isdigit(*t); t++); /* skip number */
- if (*t == '-')
- { /* is it a range? */
- t++; /* skip to next number */
- if (artnum <= (max = atol(t)))
- return 0; /* it is in range =>
- * already read */
- lastnum = max; /* remember it */
- maxt = t; /* remember position in
- * case we */
- /* want to overwrite the max */
- while (isdigit(*t))
- t++; /* skip second number */
- }
- else
- {
- if (artnum == min) /* explicitly a read
- * article? */
- return 0;
- lastnum = min; /* remember what the
- * number was */
- maxt = Nullch; /* last one was not a
- * range */
- }
- while (*t && !isdigit(*t))
- t++; /* skip comma and any
- * spaces */
- s = t;
- }
-
- /* we have not read it, so insert the article number before s */
-
- morenum = isdigit(*s); /* will it need a comma
- * after? */
- *(rcline[ngnum] + rcnums[ngnum] - 1) = rcchar[ngnum];
- mbuf = safemalloc((MEM_SIZE) (strlen(s) + (s - rcline[ngnum]) + 8));
- strcpy(mbuf, rcline[ngnum]); /* make new rc line */
- if (maxt && lastnum && artnum == lastnum + 1)
- /* can we just extend last range? */
- t = mbuf + (maxt - rcline[ngnum]); /* then overwrite
- * previous max */
- else
- {
- t = mbuf + (t - rcline[ngnum]); /* point t into new line
- * instead */
- if (lastnum)
- { /* have we parsed any
- * line? */
- if (!morenum) /* are we adding to the
- * tail? */
- *t++ = ','; /* supply comma before */
- if (!maxt && artnum == lastnum + 1 && *(t - 1) == ',')
- /* adjacent singletons? */
- *(t - 1) = '-'; /* turn them into a
- * range */
- }
- }
- if (morenum)
- { /* is there more to
- * life? */
- if (min == artnum + 1)
- { /* can we consolidate
- * further? */
- bool range_before = (*(t - 1) == '-');
- bool range_after;
- char *nextmax;
-
- for (nextmax = s; isdigit(*nextmax); nextmax++);
- range_after = *nextmax++ == '-';
-
- if (range_before)
- *t = '\0'; /* artnum is redundant */
- else
- sprintf(t, "%ld-", (long) artnum); /* artnum will be new
- * min */
-
- if (range_after)
- s = nextmax; /* *s is redundant */
- /* else s = s *//* *s is new max */
- }
- else
- sprintf(t, "%ld,", (long) artnum); /* put the number and
- * comma */
- }
- else
- sprintf(t, "%ld", (long) artnum); /* put the number there
- * (wherever) */
- strcat(t, s); /* copy remainder of
- * line */
-
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER)
- {
- printf("%s\n", mbuf) FLUSH;
- }
- #endif
-
- free(rcline[ngnum]);
- rcline[ngnum] = mbuf; /* pull the switcheroo */
- *(rcline[ngnum] + rcnums[ngnum] - 1) = '\0';
- /* wipe out : or ! */
- if (toread[ngnum] > TR_NONE) /* lest we turn unsub
- * into bogus */
- --toread[ngnum];
- return 0;
- }
-
- #ifdef MCHASE
- /* delete an article number from a newsgroup, if it is there */
-
- void
- subartnum(artnum, ngnam)
- register ART_NUM artnum;
- char *ngnam;
- {
- register NG_NUM ngnum = find_ng(ngnam);
- register char *s, *t;
- register ART_NUM min, max;
- char *mbuf;
- int curlen;
-
- if (!artnum)
- return;
- if (ngnum == nextrcline || !rcnums[ngnum])
- return; /* not found in newsrc? */
-
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER)
- {
- printf("%ld<-\n%s%c%s\n", (long) artnum, rcline[ngnum], rcchar[ngnum],
- rcline[ngnum] + rcnums[ngnum]) FLUSH;
- }
- #endif
-
- s = rcline[ngnum] + rcnums[ngnum];
- while (*s == ' ')
- s++; /* skip spaces */
-
- /* a little optimization, since it is almost always the last number */
-
- for (t = s; *t; t++); /* find end of string */
- curlen = t - rcline[ngnum];
- for (t--; isdigit(*t); t--); /* find previous delim */
- if (*t == ',' && atol(t + 1) == artnum)
- {
- *t = '\0';
- if (toread[ngnum] >= TR_NONE)
- ++toread[ngnum];
-
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER)
- printf("%s%c %s\n", rcline[ngnum], rcchar[ngnum], s) FLUSH;
- #endif
-
- return;
- }
-
- /* not the last number, oh well, we may need the length anyway */
-
- while (isdigit(*s) && artnum >= (min = atol(s)))
- {
- /* while it might have been read */
- for (t = s; isdigit(*t); t++); /* skip number */
- if (*t == '-')
- { /* is it a range? */
- t++; /* skip to next number */
- max = atol(t);
- while (isdigit(*t))
- t++; /* skip second number */
- if (artnum <= max)
- {
- /* it is in range => already read */
- if (artnum == min)
- {
- min++;
- artnum = 0;
- }
- else if (artnum == max)
- {
- max--;
- artnum = 0;
- }
- *(rcline[ngnum] + rcnums[ngnum] - 1) = rcchar[ngnum];
- mbuf = safemalloc((MEM_SIZE) (curlen + (artnum ? 15 : 2)));
- *s = '\0';
- strcpy(mbuf, rcline[ngnum]); /* make new rc line */
- s = mbuf + (s - rcline[ngnum]);
- /* point s into mbuf now */
- if (artnum)
- { /* split into two
- * ranges? */
- prange(s, min, artnum - 1);
- s += strlen(s);
- *s++ = ',';
- prange(s, artnum + 1, max);
- }
- else /* only one range */
- prange(s, min, max);
- s += strlen(s);
- strcpy(s, t); /* copy remainder over */
-
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER)
- {
- printf("%s\n", mbuf) FLUSH;
- }
- #endif
-
- free(rcline[ngnum]);
- rcline[ngnum] = mbuf; /* pull the switcheroo */
- *(rcline[ngnum] + rcnums[ngnum] - 1) = '\0';
- /* wipe out : or ! */
- if (toread[ngnum] >= TR_NONE)
- ++toread[ngnum];
- return;
- }
- }
- else
- {
- if (artnum == min)
- { /* explicitly a read
- * article? */
- if (*t == ',') /* pick a comma, any
- * comma */
- t++;
- else if (s[-1] == ',')
- s--;
- else if (s[-2] == ',') /* (in case of space) */
- s -= 2;
- strcpy(s, t); /* no need to realloc */
- if (toread[ngnum] >= TR_NONE)
- ++toread[ngnum];
-
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER)
- {
- printf("%s%c%s\n", rcline[ngnum], rcchar[ngnum],
- rcline[ngnum] + rcnums[ngnum]) FLUSH;
- }
- #endif
-
- return;
- }
- }
- while (*t && !isdigit(*t))
- t++; /* skip comma and any
- * spaces */
- s = t;
- }
- }
-
- void
- prange(where, min, max)
- char *where;
- ART_NUM min, max;
- {
- if (min == max)
- sprintf(where, "%ld", (long) min);
- else
- sprintf(where, "%ld-%ld", (long) min, (long) max);
- }
-
- #endif
-
- /* calculate the number of unread articles for a newsgroup */
-
- void
- set_toread(ngnum)
- register NG_NUM ngnum;
- {
- register char *s, *c, *h;
- char tmpbuf[64], *mybuf = tmpbuf;
- char *nums;
- int length;
-
- #ifdef CACHEFIRST
- bool virgin_ng = (!abs1st[ngnum]);
-
- #endif
- ART_NUM ngsize = getngsize(ngnum);
- ART_NUM unread = ngsize;
- ART_NUM newmax;
-
- #ifdef DEBUGGING
- ngmax[ngnum] = ngsize; /* for checking
- * out-of-range Xrefs */
- #endif
-
- if (ngsize == TR_BOGUS)
- {
- printf("Warning! Bogus newsgroup: %s\n", rcline[ngnum]) FLUSH;
- paranoid = TRUE;
- toread[ngnum] = TR_BOGUS;
- return;
- }
-
- #ifdef CACHEFIRST
- if (virgin_ng)
- #else
- if (!toread[ngnum])
- #endif
-
- {
- sprintf(tmpbuf, " 1-%ld", (long) ngsize);
- if (strNE(tmpbuf, rcline[ngnum] + rcnums[ngnum]))
- checkexpired(ngnum, ngsize); /* this might realloc
- * rcline */
- }
- nums = rcline[ngnum] + rcnums[ngnum];
- length = strlen(nums);
- if (length >= 60)
- mybuf = safemalloc((MEM_SIZE) (length + 5));
- strcpy(mybuf, nums);
- mybuf[length++] = ',';
- mybuf[length] = '\0';
- for (s = mybuf; isspace(*s); s++)
- ;
- for (; (c = index(s, ',')) != Nullch; s = ++c)
- {
- /* for each range */
- *c = '\0'; /* keep index from
- * running off */
- if ((h = index(s, '-')) != Nullch) /* find - in range, if
- * any */
- unread -= (newmax = atol(h + 1)) - atol(s) + 1;
- else if (newmax = atol(s))
- unread--; /* recalculate length */
- if (newmax > ngsize)
- { /* paranoia check */
- unread = -1;
- break;
- }
- }
- if (unread >= 0) /* reasonable number? */
- toread[ngnum] = (ART_UNREAD) unread;
- /* remember how many are left */
- else
- { /* SOMEONE RESET THE
- * NEWSGROUP!!! */
- toread[ngnum] = (ART_UNREAD) ngsize;
- /* assume nothing carried over */
- printf("Warning! Somebody reset %s--assuming nothing read.\n",
- rcline[ngnum]) FLUSH;
- *(rcline[ngnum] + rcnums[ngnum]) = '\0';
- paranoid = TRUE; /* enough to make a guy
- * paranoid */
- }
- if (mybuf != tmpbuf)
- free(mybuf);
- if (rcchar[ngnum] == NEGCHAR)
- toread[ngnum] = TR_UNSUB;
- }
-
- /* make sure expired articles are marked as read */
-
- void
- checkexpired(ngnum, ngsize)
- register NG_NUM ngnum;
- ART_NUM ngsize;
- {
- register ART_NUM a1st = getabsfirst(ngnum, ngsize);
- register char *s, *t;
- register ART_NUM num, lastnum = 0;
- char *mbuf, *newnum;
-
- if (a1st <= 1)
- return;
-
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER)
- {
- printf("1-%ld->\n%s%c%s\n", (long) (a1st - 1), rcline[ngnum], rcchar[ngnum],
- rcline[ngnum] + rcnums[ngnum]) FLUSH;
- }
- #endif
-
- for (s = rcline[ngnum] + rcnums[ngnum]; isspace(*s); s++);
- while (*s && (num = atol(s)) <= a1st)
- {
- while (isdigit(*s))
- s++;
- while (*s && !isdigit(*s))
- s++;
- lastnum = num;
- }
- if (*s)
- {
- if (s[-1] == '-')
- { /* landed in a range? */
- if (lastnum != 1)
- {
- if (3 + strlen(s) > strlen(rcline[ngnum] + rcnums[ngnum]))
- {
- mbuf = safemalloc((MEM_SIZE) (rcnums[ngnum] + 3 +
- strlen(s) + 1));
- strcpy(mbuf, rcline[ngnum]);
- sprintf(mbuf + rcnums[ngnum], " 1-%s", s);
- free(rcline[ngnum]);
- rcline[ngnum] = mbuf;
- }
- else
- {
- sprintf(rcline[ngnum] + rcnums[ngnum], " 1-%s", s);
- }
- }
- goto ret;
- }
- }
- /* s now points to what should follow first range */
- if (s - rcline[ngnum] > rcnums[ngnum] + 10)
- mbuf = rcline[ngnum];
- else
- {
- mbuf = safemalloc((MEM_SIZE) (rcnums[ngnum] + strlen(s) + 10));
- strcpy(mbuf, rcline[ngnum]);
- }
- newnum = t = mbuf + rcnums[ngnum];
- sprintf(t, " 1-%ld", (long) (a1st - (lastnum != a1st)));
- if (*s)
- {
- t += strlen(t);
- *t++ = ',';
- strcpy(t, s);
- }
- if (!checkflag && mbuf == rcline[ngnum])
- {
- rcline[ngnum] = saferealloc(rcline[ngnum],
- (MEM_SIZE) (rcnums[ngnum] + strlen(newnum) + 1));
- }
- else
- {
- if (!checkflag)
- free(rcline[ngnum]);
- rcline[ngnum] = mbuf;
- }
-
- ret:; /* semicolon in case
- * DEBUGGING undefined */
-
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER)
- {
- printf("%s%c%s\n", rcline[ngnum], rcchar[ngnum],
- rcline[ngnum] + rcnums[ngnum]) FLUSH;
- }
- #endif
- }
-