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