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