|
|
1.1 ! root 1: /* ! 2: * This software is Copyright (c) 1986 by Rick Adams. ! 3: * ! 4: * Permission is hereby granted to copy, reproduce, redistribute or ! 5: * otherwise use this software as long as: there is no monetary ! 6: * profit gained specifically from the use or reproduction or this ! 7: * software, it is not sold, rented, traded or otherwise marketed, and ! 8: * this copyright notice is included prominently in any copy ! 9: * made. ! 10: * ! 11: * The author make no claims as to the fitness or correctness of ! 12: * this software for any use whatsoever, and it is provided as is. ! 13: * Any use of this software is at the user's own risk. ! 14: * ! 15: * rfuncs - functions for readnews. ! 16: */ ! 17: ! 18: #ifdef SCCSID ! 19: static char *SccsId = "@(#)rfuncs.c 2.29 3/19/86"; ! 20: #endif /* SCCSID */ ! 21: ! 22: /*LINTLIBRARY*/ ! 23: ! 24: #include "rparams.h" ! 25: ! 26: char lentab[LINES]; /* length of newsgroupname for each rcline */ ! 27: long nngsize; /* The next upcoming value of ngsize. */ ! 28: long nminartno; /* Smallest article number in this group */ ! 29: int BITMAPSIZE = 0; ! 30: ! 31: nextng() ! 32: { ! 33: long curpos; ! 34: #ifdef DEBUG ! 35: fprintf(stderr, "nextng()\n"); ! 36: #endif ! 37: curpos = ftell(actfp); ! 38: ! 39: next: ! 40: #ifdef DEBUG ! 41: fprintf(stderr, "next:\n"); ! 42: #endif ! 43: if (actdirect == BACKWARD) { ! 44: if (back()) { ! 45: (void) fseek(actfp, curpos, 0); ! 46: return 1; ! 47: } ! 48: if (back()) { ! 49: (void) fseek(actfp, curpos, 0); ! 50: return 1; ! 51: } ! 52: } ! 53: if (fgets(afline, BUFLEN, actfp) == NULL) ! 54: return 1; ! 55: if (sscanf(afline, "%s %ld %ld", bfr, &nngsize, &nminartno) < 3) { ! 56: bfr[0] = '\0'; ! 57: nngsize = 0; ! 58: nminartno = 0; ! 59: } ! 60: #ifdef DEBUG ! 61: fprintf(stderr, "bfr = '%s'\n", bfr); ! 62: #endif ! 63: ! 64: if (!ngmatch(bfr, header.nbuf)) ! 65: goto next; ! 66: if (xflag) ! 67: readmode = SPEC; ! 68: else ! 69: readmode = NEXT; ! 70: if (selectng(bfr, TRUE, FALSE)) ! 71: goto next; ! 72: return 0; ! 73: } ! 74: ! 75: ! 76: selectng(name, fastcheck, resubscribe) ! 77: char *name; ! 78: { ! 79: register char *ptr, punct = ','; ! 80: register int i; ! 81: register char *p; ! 82: register long cur; ! 83: long next = 0; ! 84: FILE *af; ! 85: long s, sm; ! 86: char buf[100], n[100]; ! 87: ! 88: #ifdef DEBUG ! 89: fprintf(stderr,"selectng: groupdir = %s\n", groupdir); ! 90: #endif /* DEBUG */ ! 91: if (*groupdir) ! 92: updaterc(); ! 93: last = 1; ! 94: if (strcmp(name, bfr)) { ! 95: af = xfopen(ACTIVE, "r"); ! 96: while (fgets(buf, sizeof buf, af) != NULL) { ! 97: if (sscanf(buf, "%s %ld %ld", n, &s, &sm) == 3 && ! 98: strcmp(n, name) == 0) { ! 99: ngsize = s; ! 100: minartno = sm; ! 101: break; ! 102: } ! 103: } ! 104: (void) fclose(af); ! 105: } else { ! 106: ngsize = nngsize; ! 107: minartno = nminartno; ! 108: } ! 109: #ifdef DEBUG ! 110: fprintf(stderr, "selectng(%s) sets ngsize to %ld, minartno to %ld\n", ! 111: name, ngsize, minartno); ! 112: #endif ! 113: (void) strcpy(groupdir, name); ! 114: if (!xflag) { ! 115: i = findrcline(name); ! 116: if (i >= 0) { ! 117: if (p = index(rcline[i], '!')) { ! 118: switch (resubscribe) { ! 119: case FALSE: ! 120: groupdir[0] = 0; ! 121: return 1; ! 122: case TRUE: ! 123: *p = ':'; ! 124: break; ! 125: case PERHAPS: ! 126: zapng = TRUE; ! 127: break; ! 128: } ! 129: } else ! 130: p = index(rcline[i], ':'); ! 131: if (!p) /* shouldn't happen */ ! 132: p = rcline[i]; ! 133: while (*++p == ' ') ! 134: ; ! 135: (void) sprintf(rcbuf, "%s%s%ld", rcline[i], ! 136: *p == '\0' ? " " : ",", ngsize+1); ! 137: } ! 138: else ! 139: (void) sprintf(rcbuf, "ng: %ld", ngsize+1); ! 140: } else ! 141: (void) sprintf(rcbuf, "ng: %ld", ngsize+1); ! 142: #ifdef DEBUG ! 143: fprintf(stderr, "rcbuf set to %s\n", rcbuf); ! 144: #endif /* DEBUG */ ! 145: ! 146: /* ! 147: * Fast check for common case: 1-### ! 148: */ ! 149: if (fastcheck) { ! 150: p = rcbuf; ! 151: while (*p != ' ') ! 152: p++; ! 153: while (*p == ' ') ! 154: p++; ! 155: if (*p++ == '1' && *p++ == '-') { ! 156: cur = 0; ! 157: while (isdigit(*p)) ! 158: cur = 10 * cur + *p++ - '0'; ! 159: if (*p == ',' && cur == ngsize) { ! 160: #ifdef DEBUG ! 161: fprintf(stderr, "Group: %s, all read\n", groupdir); ! 162: #endif ! 163: groupdir[0] = 0; ! 164: return 1; ! 165: } ! 166: if (cur > ngsize) { ! 167: /* ! 168: * Claim to have read articles ! 169: * which "active" believes have ! 170: * never existed - we believe "active" ! 171: */ ! 172: fprintf(stderr, ! 173: "%s %s...\r\n\t%s %ld to %ld\r\n", ! 174: "Warning: newsgroup", groupdir, ! 175: "last article claimed read reset from", ! 176: cur, ngsize); ! 177: } ! 178: } ! 179: } ! 180: ! 181: /* ! 182: * The key to understanding this piece of code is that a bit is set iff ! 183: * that article has NOT been read. Thus, we fill in the holes when ! 184: * commas are found (e.g. 1-20,30-35 will result in filling in the 21-29 ! 185: * holes), and so we assume the newsrc file is properly ordered, the way ! 186: * we write it out. ! 187: */ ! 188: if ((ngsize-minartno) > BITMAPSIZE) { ! 189: /* This should never happen */ ! 190: (void) xerror("Bitmap not large enough for newsgroup %s", groupdir); ! 191: } ! 192: ! 193: cur = 0; ! 194: bzero(bitmap, (int) (ngsize-minartno)/8+1); /* 8 bits per character */ ! 195: ! 196: /* Decode the .newsrc line indicating what we have read. */ ! 197: for (ptr = rcbuf; *ptr && *ptr != ':'; ptr++) ! 198: ; ! 199: while (*ptr) { ! 200: while (!isdigit(*ptr) && *ptr) ! 201: ptr++; ! 202: if (!*ptr) ! 203: break; ! 204: (void) sscanf(ptr, "%ld", &next); ! 205: if (punct == ',') { ! 206: while (++cur < next) { ! 207: set(cur); ! 208: } ! 209: } ! 210: cur = next; ! 211: while (!ispunct(*ptr) && *ptr) ! 212: ptr++; ! 213: punct = *ptr; ! 214: } ! 215: if (rflag) ! 216: bit = ngsize+1; ! 217: else ! 218: bit = minartno -1; ! 219: nextbit(); ! 220: ngrp = 1; ! 221: return 0; ! 222: } ! 223: ! 224: #ifdef TMAIL ! 225: catchterm() ! 226: { ! 227: (void) unlink(infile); ! 228: (void) unlink(outfile); ! 229: xxit(0); ! 230: } ! 231: ! 232: ! 233: /* ! 234: * The -M (Mail) interface. This code is a reasonably simple model for ! 235: * writing other interfaces. We write out all relevant articles to ! 236: * a temp file, then invoke Mail with an option to have it tell us which ! 237: * articles it read. Finally we count those articles as really read. ! 238: */ ! 239: Mail() ! 240: { ! 241: register FILE *fp = NULL, *ofp; ! 242: struct hbuf h; ! 243: register char *ptr, *fname; ! 244: int news = 0; ! 245: register int i; ! 246: ! 247: for(i=0;i<NUNREC;i++) ! 248: h.unrec[i] = NULL; ! 249: ! 250: ofp = xfopen(mktemp(outfile), "w"); ! 251: if (aflag && *datebuf) ! 252: if ((atime = cgtdate(datebuf)) == -1) ! 253: xerror("Cannot parse date string"); ! 254: while (!nextng()) ! 255: while (bit <= ngsize) { ! 256: (void) sprintf(filename, "%s/%ld", dirname(groupdir), bit); ! 257: if (access(filename, 4) ! 258: || ((fp = fopen(filename, "r")) == NULL) ! 259: || (hread(&h, fp, TRUE) == NULL) ! 260: || !aselect(&h, FALSE)) { ! 261: #ifdef DEBUG ! 262: fprintf(stderr, "Bad article '%s'\n", filename); ! 263: #endif ! 264: if (fp != NULL) { ! 265: (void) fclose(fp); ! 266: fp = NULL; ! 267: } ! 268: clear(bit); ! 269: nextbit(); ! 270: continue; ! 271: } ! 272: fname = ptr = index(h.from, '('); ! 273: if (fname) { ! 274: while (ptr && ptr[-1] == ' ') ! 275: ptr--; ! 276: if (ptr) ! 277: *ptr = 0; ! 278: fname++; ! 279: ptr = fname + strlen(fname) - 1; ! 280: if (*ptr == ')') ! 281: *ptr = 0; ! 282: } ! 283: h.subtime = cgtdate(h.subdate); ! 284: fprintf(ofp, "From %s %s", ! 285: #ifdef INTERNET ! 286: h.from[0] ? h.from : ! 287: #endif ! 288: h.path, ctime(&h.subtime)); ! 289: if (fname) ! 290: fprintf(ofp, "Full-Name: %s\n", fname); ! 291: fprintf(ofp, "Newsgroups: %s\n", h.nbuf); ! 292: fprintf(ofp, "Subject: %s\n", h.title); ! 293: fprintf(ofp, "Article-ID: %s/%ld\n\n", groupdir, bit); ! 294: tprint(fp, ofp, TRUE); ! 295: putc('\n', ofp); ! 296: news = TRUE; ! 297: (void) fclose(fp); ! 298: fp = NULL; ! 299: nextbit(); ! 300: } ! 301: updaterc(); ! 302: (void) fclose(ofp); ! 303: if (!news) { ! 304: if (!checkngs()) ! 305: fprintf(stderr, "No news.\n"); ! 306: (void) unlink(outfile); ! 307: return; ! 308: } ! 309: (void) signal(SIGHUP, catchterm); ! 310: (void) signal(SIGTERM, catchterm); ! 311: (void) sprintf(bfr, "%s -f %s -T %s", TMAIL, outfile, mktemp(infile)); ! 312: fwait(fsubr(ushell, bfr, (char *)NULL)); ! 313: ofp = xfopen(infile, "r"); ! 314: (void) fseek(actfp, 0L, 0); ! 315: while (fgets(afline, BUFLEN, actfp) != NULL) { ! 316: last = 0; ! 317: if (sscanf(afline, "%s %ld", bfr, &nngsize) < 2) { ! 318: bfr[0] = '\0'; ! 319: nngsize = 0; ! 320: } ! 321: if (!ngmatch(bfr, header.nbuf)) ! 322: continue; ! 323: *groupdir = 0; ! 324: if (selectng(bfr, TRUE, FALSE)) ! 325: continue; ! 326: (void) fseek(ofp, 0L, 0); ! 327: while (fgets(groupdir, BUFLEN, ofp) != NULL) { ! 328: (void) nstrip(groupdir); ! 329: ptr = index(groupdir, '/'); ! 330: *ptr = 0; ! 331: if (strcmp(bfr, groupdir)) ! 332: continue; ! 333: (void) sscanf(++ptr, "%ld", &last); ! 334: clear(last); ! 335: } ! 336: if (last) { ! 337: (void) strcpy(groupdir, bfr); ! 338: updaterc(); ! 339: } ! 340: } ! 341: (void) unlink(infile); ! 342: (void) unlink(outfile); ! 343: } ! 344: #endif ! 345: ! 346: updaterc() ! 347: { ! 348: register long cur = 1, next = 1; ! 349: register int i; ! 350: register char *ptr; ! 351: char oldptr; ! 352: ! 353: sprintf(rcbuf, "%s%c ", groupdir, zapng ? '!' : ':'); ! 354: ! 355: zapng = FALSE; ! 356: again: ! 357: ptr = &rcbuf[strlen(rcbuf)]; ! 358: while (get(next) && next <= ngsize) ! 359: next++; ! 360: cur = next; ! 361: while (!(get(next)) && next <= ngsize) ! 362: next++; ! 363: if (cur == next) { ! 364: next = ngsize + 1; ! 365: goto skip; ! 366: } ! 367: if (ptr[-1] != ' ') ! 368: *ptr++ = ','; ! 369: if (cur + 1 == next) ! 370: (void) sprintf(ptr, "%ld", cur); ! 371: else ! 372: (void) sprintf(ptr, "%ld-%ld", cur, next - 1); ! 373: skip: ! 374: if ((long) next > ngsize) { ! 375: if (strpbrk(rcbuf, ":!") == NULL) /* bad line, huh?? */ ! 376: return; ! 377: ptr = index(rcbuf, ' '); ! 378: if (ptr == NULL) /* impossible */ ! 379: return; ! 380: ptr--; ! 381: oldptr = *ptr; ! 382: ptr[0] = ':'; ! 383: ptr[1] = '\0'; ! 384: i = findrcline(groupdir); ! 385: if (i >= 0) { ! 386: ptr[0] = oldptr; ! 387: ptr[1] = ' '; ! 388: rcline[i] = realloc(rcline[i], (unsigned)(strlen(rcbuf) + 1)); ! 389: if (rcline[i] == NULL) ! 390: xerror("Cannot realloc"); ! 391: (void) strcpy(rcline[i], rcbuf); ! 392: #ifdef DEBUG ! 393: fprintf(stderr," new rcline = %s\n", rcline[i]); ! 394: #endif /* DEBUG */ ! 395: return; ! 396: } ! 397: if (++line > LINES) ! 398: xerror("Too many newsgroups"); ! 399: ptr[0] = oldptr; ! 400: ptr[1] = ' '; ! 401: if ((rcline[line] = malloc((unsigned)(strlen(rcbuf) + 1))) == NULL) ! 402: xerror("Not enough memory"); ! 403: (void) strcpy(rcline[line], rcbuf); ! 404: #ifdef DEBUG ! 405: fprintf(stderr," new rcline2 = %s\n", rcline[line]); ! 406: #endif /* DEBUG */ ! 407: return; ! 408: } ! 409: cur = next; ! 410: goto again; ! 411: } ! 412: ! 413: newrc(rcname) ! 414: char *rcname; ! 415: { ! 416: register FILE *fp; ! 417: ! 418: if (close(creat(rcname, 0666))) { ! 419: (void) sprintf(bfr, "Cannot create %s", newsrc); ! 420: xerror(bfr); ! 421: } ! 422: ! 423: sprintf(bfr, "%s/users", LIB); ! 424: if ((fp = fopen(bfr, "a")) != NULL) { ! 425: fprintf(fp, "%s\n", username); ! 426: (void) fclose(fp); ! 427: (void) chmod(bfr, 0666); ! 428: } ! 429: } ! 430: ! 431: nextbit() ! 432: { ! 433: #ifdef DEBUG ! 434: fprintf(stderr,"nextbit() bit = %ld\n", bit); ! 435: #endif /* DEBUG */ ! 436: last = bit; ! 437: if (readmode == SPEC || xflag) { ! 438: if (rflag) ! 439: bit--; ! 440: else ! 441: bit++; ! 442: return; ! 443: } ! 444: if (rflag) ! 445: while (--bit, !get(bit) && bit > minartno) ! 446: ; ! 447: else ! 448: while (++bit, !get(bit) && bit <= ngsize) ! 449: ; ! 450: #ifdef DEBUG ! 451: fprintf(stderr,"nextng leaves bit as %ld\n", bit); ! 452: #endif /* DEBUG */ ! 453: } ! 454: ! 455: /* ! 456: * Return TRUE if the user has not ruled out this article. ! 457: */ ! 458: aselect(hp, insist) ! 459: register struct hbuf *hp; ! 460: int insist; ! 461: { ! 462: if (insist) ! 463: return TRUE; ! 464: if (tflag && !titmat(hp, header.title)) ! 465: return FALSE; ! 466: if (aflag && cgtdate(hp->subdate) < atime) ! 467: return FALSE; ! 468: if (index(hp->nbuf, ',') && !rightgroup(hp)) ! 469: return FALSE; ! 470: if (fflag && (hp->followid[0] || prefix(hp->title, "Re:"))) ! 471: return FALSE; ! 472: return TRUE; ! 473: } ! 474: ! 475: /* ! 476: * Code to avoid showing multiple articles for news. ! 477: * Works even if you exit news. ! 478: * Returns nonzero if we should show this article. ! 479: */ ! 480: rightgroup(hp) ! 481: struct hbuf *hp; ! 482: { ! 483: char ng[BUFLEN]; ! 484: register char *p, *g; ! 485: int i, flag; ! 486: ! 487: strcpy(ng, hp->nbuf); ! 488: g = ng; ! 489: flag = 1; ! 490: while (g != NULL) { ! 491: p = index(g, ','); ! 492: if (p != NULL) { ! 493: *p++ = '\0'; ! 494: while (*p == ' ') ! 495: p++; ! 496: } ! 497: if (strcmp(g, groupdir) == 0) ! 498: return flag; ! 499: if (ngmatch(g, header.nbuf) ! 500: && ((i = findrcline(g)) >= 0 ! 501: && index(rcline[i], '!') == NULL)) ! 502: flag = 0; ! 503: g = p; ! 504: } ! 505: /* we must be in "junk" or "control" */ ! 506: return TRUE; ! 507: } ! 508: ! 509: back() ! 510: { ! 511: while (fseek(actfp, -2L, 1) != -1 && ftell(actfp) > 0L) { ! 512: if (getc(actfp) == '\n') ! 513: return 0; ! 514: } ! 515: if (ftell(actfp) == 0L) ! 516: return 0; ! 517: return 1; ! 518: } ! 519: ! 520: /* ! 521: * Trap interrupts. ! 522: */ ! 523: onsig(n) ! 524: int n; ! 525: { ! 526: (void) signal(n, onsig); ! 527: SigTrap = n; ! 528: if (rcreadok < 2) { ! 529: fprintf(stderr, "Aborted early\n"); ! 530: xxit(0); ! 531: } ! 532: } ! 533: ! 534: /* ! 535: * finds the line in your .newsrc file (actually the in-core "rcline" ! 536: * copy of it) and returns the index into the array where it was found. ! 537: * -1 means it didn't find it. ! 538: * ! 539: * We play clever games here to make this faster. It's inherently ! 540: * quadratic - we spend lots of CPU time here because we search through ! 541: * the whole .newsrc for each line. The "prev" variable remembers where ! 542: * the last match was found; we start the search there and loop around ! 543: * to the beginning, in the hopes that the calls will be roughly in order. ! 544: */ ! 545: int ! 546: findrcline(name) ! 547: register char *name; ! 548: { ! 549: register char * p; ! 550: register int i; ! 551: register int top; ! 552: register int len; ! 553: static int prev; ! 554: static int didthru; ! 555: ! 556: for ( ; didthru <= line; ++didthru) ! 557: if ((p = index(rcline[didthru], '!')) != 0 || ! 558: (p = index(rcline[didthru], ':')) != 0) { ! 559: lentab[didthru] = (int)(p - rcline[didthru]); ! 560: } ! 561: len = strlen(name); ! 562: top = line; ! 563: i = prev; ! 564: loop: ! 565: for ( ; i <= top; ++i) ! 566: if (lentab[i] == len && rcline[i] != NULL && ! 567: strncmp(name, rcline[i], len) == 0) ! 568: return prev = i; ! 569: if (i > line && line > prev - 1) { ! 570: i = 0; ! 571: top = prev - 1; ! 572: goto loop; ! 573: } ! 574: return -1; ! 575: } ! 576: ! 577: /* ! 578: * sortactive - make a local copy of the active file, sorted according ! 579: * to the user's preferences, according to his .newsrc file. ! 580: */ ! 581: ! 582: struct table_elt { ! 583: int rcindex; ! 584: long maxart, minart; ! 585: char yn; ! 586: }; ! 587: ! 588: #ifdef SORTACTIVE ! 589: static int ! 590: rcsort(a, b) ! 591: char *a, *b; ! 592: { ! 593: return(((struct table_elt *)a)->rcindex - ! 594: ((struct table_elt *)b)->rcindex); ! 595: } ! 596: ! 597: static char *newactivename = "/tmp/newsaXXXXXX"; ! 598: #endif /* SORTACTIVE */ ! 599: ! 600: sortactive() ! 601: { ! 602: register struct table_elt *tp; ! 603: register char *p; ! 604: register FILE *nfp, *afp; ! 605: char aline[BUFLEN], ngname[BUFLEN]; ! 606: struct table_elt table[LINES]; ! 607: int nlines = 0, i, delta, lastline; ! 608: ! 609: #ifdef SORTACTIVE ! 610: /* make a new sorted copy of ACTIVE */ ! 611: nfp = fopen(mktemp(newactivename), "w"); ! 612: (void) chmod(newactivename, 0600); ! 613: if (nfp == NULL) { ! 614: perror(newactivename); ! 615: return; ! 616: } ! 617: ! 618: /* look up all the lines in ACTIVE, finding their positions in .newsrc */ ! 619: p = ACTIVE; ! 620: ACTIVE = newactivename; ! 621: afp = xfopen(p, "r"); ! 622: tp = table; ! 623: #else /* !SORTACTIVE */ ! 624: afp = xfopen(ACTIVE, "r"); ! 625: #endif /* !SORTACTIVE */ ! 626: while (fgets(aline, sizeof aline, afp) != NULL) { ! 627: if (sscanf(aline,"%s %ld %ld %c", ngname, &tp->maxart, &tp->minart, &tp->yn) != 4) ! 628: xerror("Active file corrupt"); ! 629: delta = tp->maxart - tp->minart; ! 630: if (delta >= BITMAPSIZE) ! 631: BITMAPSIZE = delta+ 1; ! 632: #ifdef SORTACTIVE ! 633: tp->rcindex = findrcline(ngname); ! 634: if (tp->rcindex < 0) { ! 635: register FILE *f; ! 636: /* it's not in his .newsrc, maybe it's aliased? */ ! 637: f = xfopen(ALIASES,"r"); ! 638: while (fscanf(f,"%s %s", afline, bfr) == 2 ! 639: && strcmp(ngname, bfr)) ! 640: ; ! 641: (void) fclose(f); ! 642: if (strcmp(ngname, bfr) == 0) { ! 643: int j; ! 644: j = findrcline(afline); ! 645: if (j >= 0) { ! 646: p = rcline[j]; ! 647: while (*p != ':' && *p != '!' && *p) ! 648: p++; ! 649: strcat(bfr, p); ! 650: rcline[j] = realloc(rcline[j], (unsigned)(strlen(bfr)+1)); ! 651: if (rcline[j] == NULL) ! 652: xerror("Not enough memory"); ! 653: strcpy(rcline[j], bfr); ! 654: tp++->rcindex = j; ! 655: continue; ! 656: } ! 657: } ! 658: if (++line > LINES) ! 659: xerror("Too many newsgroups"); ! 660: strcat(ngname, ":"); ! 661: rcline[line] = malloc((unsigned)(strlen(ngname) + 1)); ! 662: if (rcline[line] == NULL) ! 663: xerror("Not enough memory"); ! 664: strcpy(rcline[line], ngname); ! 665: tp->rcindex = line; ! 666: } ! 667: tp++; ! 668: #endif /* SORTACTIVE */ ! 669: } ! 670: (void) fclose(afp); ! 671: BITMAPSIZE = 8 * ((BITMAPSIZE+7) / 8); ! 672: bitmap = malloc((unsigned)BITMAPSIZE/8); ! 673: if (bitmap == NULL) ! 674: xerror("Can't malloc bitmap"); ! 675: ! 676: #ifdef SORTACTIVE ! 677: /* sort by position in user's .newsrc file (new groups come up last) */ ! 678: nlines = tp - table; ! 679: qsort((char *)table, nlines, sizeof table[0], rcsort); ! 680: ! 681: tp = table; ! 682: lastline = tp->rcindex - 1; ! 683: /* copy active to newactive, in the new order */ ! 684: for (i = 0; i < nlines; i++) { ! 685: while (++lastline < tp->rcindex) { ! 686: fprintf(stderr, "Duplicate .newsrc line or bad group %s\n", ! 687: rcline[lastline]); ! 688: lentab[lastline] = 0; ! 689: free(rcline[lastline]); ! 690: rcline[lastline] = NULL; ! 691: } ! 692: if (rcline[tp->rcindex] == NULL) ! 693: continue; ! 694: p = rcline[tp->rcindex]; ! 695: while (*p != ':' && *p != '!') ! 696: fputc(*p++, nfp); ! 697: (void) fprintf(nfp, " %ld %ld %c\n", tp->maxart, tp->minart, ! 698: tp->yn); ! 699: tp++; ! 700: } ! 701: (void) fclose(nfp); ! 702: #endif /* SORTACTIVE */ ! 703: } ! 704: ! 705: /* ARGSUSED */ ! 706: checkngs(nbuf, f) ! 707: char *nbuf; ! 708: FILE *f; ! 709: { ! 710: return 0; ! 711: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.