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