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