|
|
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.