|
|
1.1 root 1: /* $Header: rcln.c,v 4.3 85/05/01 11:45:36 lwall Exp $
2: *
3: * $Log: rcln.c,v $
4: * Revision 4.3 85/05/01 11:45:36 lwall
5: * Baseline for release with 4.3bsd.
6: *
7: */
8:
9: #include "EXTERN.h"
10: #include "common.h"
11: #include "util.h"
12: #include "rcstuff.h"
13: #include "ngdata.h"
14: #include "INTERN.h"
15: #include "rcln.h"
16:
17: void
18: rcln_init()
19: {
20: ;
21: }
22:
23: #ifdef CATCHUP
24: void
25: catch_up(ngx)
26: NG_NUM ngx;
27: {
28: char tmpbuf[128];
29:
30: #ifdef VERBOSE
31: IF(verbose)
32: printf("\nMarking %s as all read.\n",rcline[ngx]) FLUSH;
33: ELSE
34: #endif
35: #ifdef TERSE
36: fputs("\nMarked read\n",stdout) FLUSH;
37: #endif
38: sprintf(tmpbuf,"%s: 1-%ld", rcline[ngx],(long)getngsize(ngx));
39: free(rcline[ngx]);
40: rcline[ngx] = savestr(tmpbuf);
41: *(rcline[ngx] + rcnums[ngx] - 1) = '\0';
42: write_rc();
43: }
44: #endif
45:
46: /* add an article number to a newsgroup, if it isn't already read */
47:
48: int
49: addartnum(artnum,ngnam)
50: ART_NUM artnum;
51: char *ngnam;
52: {
53: register NG_NUM ngnum = find_ng(ngnam);
54: register char *s, *t, *maxt = Nullch;
55: ART_NUM min = 0, max = -1, lastnum = 0;
56: char *mbuf;
57: bool morenum;
58:
59: if (!artnum)
60: return 0;
61: if (ngnum == nextrcline || !rcnums[ngnum])
62: /* not found in newsrc? */
63: return 0;
64: #ifdef CACHEFIRST
65: if (!abs1st[ngnum])
66: #else
67: if (!toread[ngnum])
68: #endif
69: /* now is a good time to trim down */
70: set_toread(ngnum); /* the list due to expires if we */
71: /* have not yet. */
72: #ifdef DEBUGGING
73: if (artnum > ngmax[ngnum] + 10 /* allow for incoming articles */
74: ) {
75: printf("\nCorrupt Xref line!!! %ld --> %s(1..%ld)\n",
76: artnum,ngnam,
77: ngmax[ngnum]) FLUSH;
78: paranoid = TRUE; /* paranoia reigns supreme */
79: return -1; /* hope this was the first newsgroup */
80: }
81: #endif
82:
83: if (toread[ngnum] == TR_BOGUS)
84: return 0;
85: #ifdef DEBUGGING
86: if (debug & DEB_XREF_MARKER) {
87: printf("%ld->\n%s%c%s\n",(long)artnum,rcline[ngnum],rcchar[ngnum],
88: rcline[ngnum] + rcnums[ngnum]) FLUSH;
89: }
90: #endif
91: s = rcline[ngnum] + rcnums[ngnum];
92: while (*s == ' ') s++; /* skip spaces */
93: t = s;
94: while (isdigit(*s) && artnum >= (min = atol(s))) {
95: /* while it might have been read */
96: for (t = s; isdigit(*t); t++) ; /* skip number */
97: if (*t == '-') { /* is it a range? */
98: t++; /* skip to next number */
99: if (artnum <= (max = atol(t)))
100: return 0; /* it is in range => already read */
101: lastnum = max; /* remember it */
102: maxt = t; /* remember position in case we */
103: /* want to overwrite the max */
104: while (isdigit(*t)) t++; /* skip second number */
105: }
106: else {
107: if (artnum == min) /* explicitly a read article? */
108: return 0;
109: lastnum = min; /* remember what the number was */
110: maxt = Nullch; /* last one was not a range */
111: }
112: while (*t && !isdigit(*t)) t++; /* skip comma and any spaces */
113: s = t;
114: }
115:
116: /* we have not read it, so insert the article number before s */
117:
118: morenum = isdigit(*s); /* will it need a comma after? */
119: *(rcline[ngnum] + rcnums[ngnum] - 1) = rcchar[ngnum];
120: mbuf = safemalloc((MEM_SIZE)(strlen(s) + (s-rcline[ngnum]) + 8));
121: strcpy(mbuf,rcline[ngnum]); /* make new rc line */
122: if (maxt && lastnum && artnum == lastnum+1)
123: /* can we just extend last range? */
124: t = mbuf + (maxt-rcline[ngnum]);/* then overwrite previous max */
125: else {
126: t = mbuf + (t-rcline[ngnum]); /* point t into new line instead */
127: if (lastnum) { /* have we parsed any line? */
128: if (!morenum) /* are we adding to the tail? */
129: *t++ = ','; /* supply comma before */
130: if (!maxt && artnum == lastnum+1 && *(t-1) == ',')
131: /* adjacent singletons? */
132: *(t-1) = '-'; /* turn them into a range */
133: }
134: }
135: if (morenum) { /* is there more to life? */
136: if (min == artnum+1) { /* can we consolidate further? */
137: bool range_before = (*(t-1) == '-');
138: bool range_after;
139: char *nextmax;
140:
141: for (nextmax = s; isdigit(*nextmax); nextmax++) ;
142: range_after = *nextmax++ == '-';
143:
144: if (range_before)
145: *t = '\0'; /* artnum is redundant */
146: else
147: sprintf(t,"%ld-",(long)artnum);/* artnum will be new min */
148:
149: if (range_after)
150: s = nextmax; /* *s is redundant */
151: /* else
152: s = s */ /* *s is new max */
153: }
154: else
155: sprintf(t,"%ld,",(long)artnum); /* put the number and comma */
156: }
157: else
158: sprintf(t,"%ld",(long)artnum); /* put the number there (wherever) */
159: strcat(t,s); /* copy remainder of line */
160: #ifdef DEBUGGING
161: if (debug & DEB_XREF_MARKER) {
162: printf("%s\n",mbuf) FLUSH;
163: }
164: #endif
165: free(rcline[ngnum]);
166: rcline[ngnum] = mbuf; /* pull the switcheroo */
167: *(rcline[ngnum] + rcnums[ngnum] - 1) = '\0';
168: /* wipe out : or ! */
169: if (toread[ngnum] > TR_NONE) /* lest we turn unsub into bogus */
170: --toread[ngnum];
171: return 0;
172: }
173:
174: #ifdef MCHASE
175: /* delete an article number from a newsgroup, if it is there */
176:
177: void
178: subartnum(artnum,ngnam)
179: register ART_NUM artnum;
180: char *ngnam;
181: {
182: register NG_NUM ngnum = find_ng(ngnam);
183: register char *s, *t;
184: register ART_NUM min, max;
185: char *mbuf;
186: int curlen;
187:
188: if (!artnum)
189: return;
190: if (ngnum == nextrcline || !rcnums[ngnum])
191: return; /* not found in newsrc? */
192: #ifdef DEBUGGING
193: if (debug & DEB_XREF_MARKER) {
194: printf("%ld<-\n%s%c%s\n",(long)artnum,rcline[ngnum],rcchar[ngnum],
195: rcline[ngnum] + rcnums[ngnum]) FLUSH;
196: }
197: #endif
198: s = rcline[ngnum] + rcnums[ngnum];
199: while (*s == ' ') s++; /* skip spaces */
200:
201: /* a little optimization, since it is almost always the last number */
202:
203: for (t=s; *t; t++) ; /* find end of string */
204: curlen = t-rcline[ngnum];
205: for (t--; isdigit(*t); t--) ; /* find previous delim */
206: if (*t == ',' && atol(t+1) == artnum) {
207: *t = '\0';
208: if (toread[ngnum] >= TR_NONE)
209: ++toread[ngnum];
210: #ifdef DEBUGGING
211: if (debug & DEB_XREF_MARKER)
212: printf("%s%c %s\n",rcline[ngnum],rcchar[ngnum],s) FLUSH;
213: #endif
214: return;
215: }
216:
217: /* not the last number, oh well, we may need the length anyway */
218:
219: while (isdigit(*s) && artnum >= (min = atol(s))) {
220: /* while it might have been read */
221: for (t = s; isdigit(*t); t++) ; /* skip number */
222: if (*t == '-') { /* is it a range? */
223: t++; /* skip to next number */
224: max = atol(t);
225: while (isdigit(*t)) t++; /* skip second number */
226: if (artnum <= max) {
227: /* it is in range => already read */
228: if (artnum == min) {
229: min++;
230: artnum = 0;
231: }
232: else if (artnum == max) {
233: max--;
234: artnum = 0;
235: }
236: *(rcline[ngnum] + rcnums[ngnum] - 1) = rcchar[ngnum];
237: mbuf = safemalloc((MEM_SIZE)(curlen + (artnum?15:2)));
238: *s = '\0';
239: strcpy(mbuf,rcline[ngnum]); /* make new rc line */
240: s = mbuf + (s-rcline[ngnum]);
241: /* point s into mbuf now */
242: if (artnum) { /* split into two ranges? */
243: prange(s,min,artnum-1);
244: s += strlen(s);
245: *s++ = ',';
246: prange(s,artnum+1,max);
247: }
248: else /* only one range */
249: prange(s,min,max);
250: s += strlen(s);
251: strcpy(s,t); /* copy remainder over */
252: #ifdef DEBUGGING
253: if (debug & DEB_XREF_MARKER) {
254: printf("%s\n",mbuf) FLUSH;
255: }
256: #endif
257: free(rcline[ngnum]);
258: rcline[ngnum] = mbuf; /* pull the switcheroo */
259: *(rcline[ngnum] + rcnums[ngnum] - 1) = '\0';
260: /* wipe out : or ! */
261: if (toread[ngnum] >= TR_NONE)
262: ++toread[ngnum];
263: return;
264: }
265: }
266: else {
267: if (artnum == min) { /* explicitly a read article? */
268: if (*t == ',') /* pick a comma, any comma */
269: t++;
270: else if (s[-1] == ',')
271: s--;
272: else if (s[-2] == ',') /* (in case of space) */
273: s -= 2;
274: strcpy(s,t); /* no need to realloc */
275: if (toread[ngnum] >= TR_NONE)
276: ++toread[ngnum];
277: #ifdef DEBUGGING
278: if (debug & DEB_XREF_MARKER) {
279: printf("%s%c%s\n",rcline[ngnum],rcchar[ngnum],
280: rcline[ngnum] + rcnums[ngnum]) FLUSH;
281: }
282: #endif
283: return;
284: }
285: }
286: while (*t && !isdigit(*t)) t++; /* skip comma and any spaces */
287: s = t;
288: }
289: }
290:
291: void
292: prange(where,min,max)
293: char *where;
294: ART_NUM min,max;
295: {
296: if (min == max)
297: sprintf(where,"%ld",(long)min);
298: else
299: sprintf(where,"%ld-%ld",(long)min,(long)max);
300: }
301: #endif
302:
303: /* calculate the number of unread articles for a newsgroup */
304:
305: void
306: set_toread(ngnum)
307: register NG_NUM ngnum;
308: {
309: register char *s, *c, *h;
310: char tmpbuf[64], *mybuf = tmpbuf;
311: char *nums;
312: int length;
313: #ifdef CACHEFIRST
314: bool virgin_ng = (!abs1st[ngnum]);
315: #endif
316: ART_NUM ngsize = getngsize(ngnum);
317: ART_NUM unread = ngsize;
318: ART_NUM newmax;
319:
320: #ifdef DEBUGGING
321: ngmax[ngnum] = ngsize; /* for checking out-of-range Xrefs */
322: #endif
323: if (ngsize == TR_BOGUS) {
324: printf("Warning! Bogus newsgroup: %s\n",rcline[ngnum]) FLUSH;
325: paranoid = TRUE;
326: toread[ngnum] = TR_BOGUS;
327: return;
328: }
329: #ifdef CACHEFIRST
330: if (virgin_ng)
331: #else
332: if (!toread[ngnum])
333: #endif
334: {
335: sprintf(tmpbuf," 1-%ld",(long)ngsize);
336: if (strNE(tmpbuf,rcline[ngnum]+rcnums[ngnum]))
337: checkexpired(ngnum,ngsize); /* this might realloc rcline */
338: }
339: nums = rcline[ngnum]+rcnums[ngnum];
340: length = strlen(nums);
341: if (length >= 60)
342: mybuf = safemalloc((MEM_SIZE)(length+5));
343: strcpy(mybuf,nums);
344: mybuf[length++] = ',';
345: mybuf[length] = '\0';
346: for (s = mybuf; isspace(*s); s++)
347: ;
348: for ( ; (c = index(s,',')) != Nullch ; s = ++c) {
349: /* for each range */
350: *c = '\0'; /* keep index from running off */
351: if ((h = index(s,'-')) != Nullch) /* find - in range, if any */
352: unread -= (newmax = atol(h+1)) - atol(s) + 1;
353: else if (newmax = atol(s))
354: unread--; /* recalculate length */
355: if (newmax > ngsize) { /* paranoia check */
356: unread = -1;
357: break;
358: }
359: }
360: if (unread >= 0) /* reasonable number? */
361: toread[ngnum] = (ART_UNREAD)unread;
362: /* remember how many are left */
363: else { /* SOMEONE RESET THE NEWSGROUP!!! */
364: toread[ngnum] = (ART_UNREAD)ngsize;
365: /* assume nothing carried over */
366: printf("Warning! Somebody reset %s--assuming nothing read.\n",
367: rcline[ngnum]) FLUSH;
368: *(rcline[ngnum] + rcnums[ngnum]) = '\0';
369: paranoid = TRUE; /* enough to make a guy paranoid */
370: }
371: if (mybuf != tmpbuf)
372: free(mybuf);
373: if (rcchar[ngnum] == NEGCHAR)
374: toread[ngnum] = TR_UNSUB;
375: }
376:
377: /* make sure expired articles are marked as read */
378:
379: void
380: checkexpired(ngnum,ngsize)
381: register NG_NUM ngnum;
382: ART_NUM ngsize;
383: {
384: register ART_NUM a1st = getabsfirst(ngnum,ngsize);
385: register char *s, *t;
386: register ART_NUM num, lastnum = 0;
387: char *mbuf, *newnum;
388:
389: if (a1st<=1)
390: return;
391: #ifdef DEBUGGING
392: if (debug & DEB_XREF_MARKER) {
393: printf("1-%ld->\n%s%c%s\n",(long)(a1st-1),rcline[ngnum],rcchar[ngnum],
394: rcline[ngnum] + rcnums[ngnum]) FLUSH;
395: }
396: #endif
397: for (s = rcline[ngnum] + rcnums[ngnum]; isspace(*s); s++);
398: while (*s && (num = atol(s)) <= a1st) {
399: while (isdigit(*s)) s++;
400: while (*s && !isdigit(*s)) s++;
401: lastnum = num;
402: }
403: if (*s) {
404: if (s[-1] == '-') { /* landed in a range? */
405: if (lastnum != 1)
406: sprintf(rcline[ngnum]+rcnums[ngnum]," 1-%s",s);
407: goto ret;
408: }
409: }
410: /* s now points to what should follow first range */
411: if (s - rcline[ngnum] > rcnums[ngnum] + 10)
412: mbuf = rcline[ngnum];
413: else {
414: mbuf = safemalloc((MEM_SIZE)(rcnums[ngnum] + strlen(s) + 10));
415: strcpy(mbuf,rcline[ngnum]);
416: }
417: newnum = t = mbuf+rcnums[ngnum];
418: sprintf(t," 1-%ld",(long)(a1st - (lastnum != a1st)));
419: if (*s) {
420: t += strlen(t);
421: *t++ = ',';
422: strcpy(t,s);
423: }
424: if (mbuf == rcline[ngnum]) {
425: rcline[ngnum] = saferealloc(rcline[ngnum],
426: (MEM_SIZE)(rcnums[ngnum] + strlen(newnum) + 1));
427: }
428: else {
429: free(rcline[ngnum]);
430: rcline[ngnum] = mbuf;
431: }
432:
433: ret:; /* semicolon in case DEBUGGING undefined */
434: #ifdef DEBUGGING
435: if (debug & DEB_XREF_MARKER) {
436: printf("%s%c%s\n",rcline[ngnum],rcchar[ngnum],
437: rcline[ngnum] + rcnums[ngnum]) FLUSH;
438: }
439: #endif
440: }
441:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.