|
|
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.42 10/15/87"; ! 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: /* resize the bitmap array */ ! 190: (void) free (bitmap); ! 191: BITMAPSIZE = 8 * (((ngsize - minartno) + 7) / 8); ! 192: bitmap = malloc((unsigned)BITMAPSIZE/8); ! 193: if (bitmap == NULL) ! 194: xerror("Can't malloc bitmap"); ! 195: } ! 196: ! 197: cur = 0; ! 198: bzero(bitmap, (int) (ngsize-minartno)/8+1); /* 8 bits per character */ ! 199: ! 200: /* Decode the .newsrc line indicating what we have read. */ ! 201: for (ptr = rcbuf; *ptr && *ptr != ':'; ptr++) ! 202: ; ! 203: while (*ptr) { ! 204: while (!isdigit(*ptr) && *ptr) ! 205: ptr++; ! 206: if (!*ptr) ! 207: break; ! 208: (void) sscanf(ptr, "%ld", &next); ! 209: if (punct == ',') { ! 210: while (++cur < next) { ! 211: set(cur); ! 212: } ! 213: } ! 214: cur = next; ! 215: while (!ispunct(*ptr) && *ptr) ! 216: ptr++; ! 217: punct = *ptr; ! 218: } ! 219: if (rflag) ! 220: bit = ngsize+1; ! 221: else ! 222: bit = minartno -1; ! 223: nextbit(); ! 224: ngrp = 1; ! 225: return 0; ! 226: } ! 227: ! 228: #ifdef TMAIL ! 229: catchterm() ! 230: { ! 231: (void) unlink(infile); ! 232: (void) unlink(outfile); ! 233: xxit(0); ! 234: } ! 235: ! 236: ! 237: /* ! 238: * The -M (Mail) interface. This code is a reasonably simple model for ! 239: * writing other interfaces. We write out all relevant articles to ! 240: * a temp file, then invoke Mail with an option to have it tell us which ! 241: * articles it read. Finally we count those articles as really read. ! 242: */ ! 243: Mail() ! 244: { ! 245: register FILE *fp = NULL, *ofp; ! 246: struct hbuf h; ! 247: register char *ptr, *fname; ! 248: int isnews = FALSE; ! 249: register int i; ! 250: ! 251: for(i=0;i<NUNREC;i++) ! 252: h.unrec[i] = NULL; ! 253: ! 254: ofp = xfopen(mktemp(outfile), "w"); ! 255: if (aflag && *datebuf) ! 256: if ((atime = cgtdate(datebuf)) == -1) ! 257: xerror("Cannot parse date string"); ! 258: while (!nextng()) ! 259: while (bit <= ngsize) { ! 260: #ifdef SERVER ! 261: if ((fp = getarticle(groupdir,bit,"ARTICLE")) != NULL) { ! 262: strcpy(filename, article_name()); ! 263: (void) fclose(fp); ! 264: fp = NULL; ! 265: } else { ! 266: #ifdef DEBUG ! 267: fprintf(stderr, "Bad article '%s/%d'\n", groupdir, ! 268: bit); ! 269: #endif /* DEBUG */ ! 270: clear(bit); ! 271: nextbit(); ! 272: continue; ! 273: } ! 274: #else /* !SERVER */ ! 275: (void) sprintf(filename, "%s/%ld", dirname(groupdir), bit); ! 276: #endif /* !SERVER */ ! 277: if (access(filename, 4) ! 278: || ((fp = art_open (filename, "r")) == NULL) ! 279: || (hread(&h, fp, TRUE) == NULL) ! 280: || !aselect(&h, FALSE)) { ! 281: #ifdef DEBUG ! 282: fprintf(stderr, "Bad article '%s'\n", filename); ! 283: #endif ! 284: if (fp != NULL) { ! 285: (void) fclose(fp); ! 286: fp = NULL; ! 287: } ! 288: clear(bit); ! 289: nextbit(); ! 290: continue; ! 291: } ! 292: fname = ptr = index(h.from, '('); ! 293: if (fname) { ! 294: while (ptr && ptr[-1] == ' ') ! 295: ptr--; ! 296: if (ptr) ! 297: *ptr = 0; ! 298: fname++; ! 299: ptr = fname + strlen(fname) - 1; ! 300: if (*ptr == ')') ! 301: *ptr = 0; ! 302: } ! 303: h.subtime = cgtdate(h.subdate); ! 304: fprintf(ofp, "From %s %s", ! 305: #ifdef INTERNET ! 306: h.from[0] ? h.from : ! 307: #endif ! 308: h.path, ctime(&h.subtime)); ! 309: if (fname) ! 310: fprintf(ofp, "Full-Name: %s\n", fname); ! 311: fprintf(ofp, "Newsgroups: %s\n", h.nbuf); ! 312: fprintf(ofp, "Subject: %s\n", h.title); ! 313: fprintf(ofp, "Article-ID: %s/%ld\n\n", groupdir, bit); ! 314: tprint(fp, ofp, TRUE); ! 315: putc('\n', ofp); ! 316: isnews = TRUE; ! 317: (void) fclose(fp); ! 318: #ifdef SERVER ! 319: (void) unlink(filename); /* get rid of temp file */ ! 320: #endif /* SERVER */ ! 321: fp = NULL; ! 322: nextbit(); ! 323: } ! 324: updaterc(); ! 325: (void) fclose(ofp); ! 326: if (!isnews) { ! 327: fprintf(stderr, "No news.\n"); ! 328: (void) unlink(outfile); ! 329: return; ! 330: } ! 331: (void) signal(SIGHUP, catchterm); ! 332: (void) signal(SIGTERM, catchterm); ! 333: (void) sprintf(bfr, "%s -f %s -T %s", TMAIL, outfile, mktemp(infile)); ! 334: fwait(fsubr(ushell, bfr, (char *)NULL)); ! 335: ofp = xfopen(infile, "r"); ! 336: (void) fseek(actfp, 0L, 0); ! 337: while (fgets(afline, BUFLEN, actfp) != NULL) { ! 338: last = 0; ! 339: if (sscanf(afline, "%s %ld", bfr, &nngsize) < 2) { ! 340: bfr[0] = '\0'; ! 341: nngsize = 0; ! 342: } ! 343: if (!ngmatch(bfr, header.nbuf)) ! 344: continue; ! 345: *groupdir = 0; ! 346: if (selectng(bfr, TRUE, FALSE)) ! 347: continue; ! 348: (void) fseek(ofp, 0L, 0); ! 349: while (fgets(groupdir, BUFLEN, ofp) != NULL) { ! 350: (void) nstrip(groupdir); ! 351: ptr = index(groupdir, '/'); ! 352: *ptr = 0; ! 353: if (STRCMP(bfr, groupdir)) ! 354: continue; ! 355: (void) sscanf(++ptr, "%ld", &last); ! 356: clear(last); ! 357: } ! 358: if (last) { ! 359: (void) strcpy(groupdir, bfr); ! 360: updaterc(); ! 361: } ! 362: } ! 363: (void) unlink(infile); ! 364: (void) unlink(outfile); ! 365: } ! 366: #endif ! 367: ! 368: updaterc() ! 369: { ! 370: register long cur = 1, next = 1; ! 371: register int i; ! 372: register char *ptr; ! 373: char oldptr; ! 374: ! 375: sprintf(rcbuf, "%s%c ", groupdir, zapng ? '!' : ':'); ! 376: ! 377: zapng = FALSE; ! 378: again: ! 379: ptr = &rcbuf[strlen(rcbuf)]; ! 380: while (get(next) && next <= ngsize) ! 381: next++; ! 382: cur = next; ! 383: while (!(get(next)) && next <= ngsize) ! 384: next++; ! 385: if (cur == next) { ! 386: next = ngsize + 1; ! 387: goto skip; ! 388: } ! 389: if (ptr[-1] != ' ') ! 390: *ptr++ = ','; ! 391: if (cur + 1 == next) ! 392: (void) sprintf(ptr, "%ld", cur); ! 393: else ! 394: (void) sprintf(ptr, "%ld-%ld", cur, next - 1); ! 395: skip: ! 396: if ((long) next > ngsize) { ! 397: if (strpbrk(rcbuf, ":!") == NULL) /* bad line, huh?? */ ! 398: return; ! 399: ptr = index(rcbuf, ' '); ! 400: if (ptr == NULL) /* impossible */ ! 401: return; ! 402: ptr--; ! 403: oldptr = *ptr; ! 404: ptr[0] = ':'; ! 405: ptr[1] = '\0'; ! 406: i = findrcline(groupdir); ! 407: if (i >= 0) { ! 408: ptr[0] = oldptr; ! 409: ptr[1] = ' '; ! 410: rcline[i] = realloc(rcline[i], (unsigned)(strlen(rcbuf) + 1)); ! 411: if (rcline[i] == NULL) ! 412: xerror("Cannot realloc"); ! 413: (void) strcpy(rcline[i], rcbuf); ! 414: #ifdef DEBUG ! 415: fprintf(stderr," new rcline = %s\n", rcline[i]); ! 416: #endif /* DEBUG */ ! 417: return; ! 418: } ! 419: if (++line > LINES) ! 420: xerror("Too many newsgroups"); ! 421: ptr[0] = oldptr; ! 422: ptr[1] = ' '; ! 423: if ((rcline[line] = malloc((unsigned)(strlen(rcbuf) + 1))) == NULL) ! 424: xerror("Not enough memory"); ! 425: (void) strcpy(rcline[line], rcbuf); ! 426: #ifdef DEBUG ! 427: fprintf(stderr," new rcline2 = %s\n", rcline[line]); ! 428: #endif /* DEBUG */ ! 429: return; ! 430: } ! 431: cur = next; ! 432: goto again; ! 433: } ! 434: ! 435: newrc(rcname) ! 436: char *rcname; ! 437: { ! 438: register FILE *fp; ! 439: ! 440: if (close(creat(rcname, 0666))) { ! 441: (void) sprintf(bfr, "Cannot create %s", newsrc); ! 442: xerror(bfr); ! 443: } ! 444: ! 445: sprintf(bfr, "%s/users", LIB); ! 446: if ((fp = fopen(bfr, "a")) != NULL) { ! 447: fprintf(fp, "%s\n", username); ! 448: (void) fclose(fp); ! 449: (void) chmod(bfr, 0666); ! 450: } ! 451: } ! 452: ! 453: nextbit() ! 454: { ! 455: #ifdef DEBUG ! 456: fprintf(stderr,"nextbit() bit = %ld\n", bit); ! 457: #endif /* DEBUG */ ! 458: last = bit; ! 459: if (readmode == SPEC || xflag) { ! 460: if (rflag) ! 461: bit--; ! 462: else ! 463: bit++; ! 464: return; ! 465: } ! 466: if (rflag) ! 467: while (--bit, !get(bit) && bit > minartno) ! 468: ; ! 469: else ! 470: while (++bit, !get(bit) && bit <= ngsize) ! 471: ; ! 472: #ifdef DEBUG ! 473: fprintf(stderr,"nextng leaves bit as %ld\n", bit); ! 474: #endif /* DEBUG */ ! 475: } ! 476: ! 477: /* ! 478: * Return TRUE if the user has not ruled out this article. ! 479: */ ! 480: aselect(hp, insist) ! 481: register struct hbuf *hp; ! 482: int insist; ! 483: { ! 484: if (insist) ! 485: return TRUE; ! 486: if (tflag && !titmat(hp, header.title)) ! 487: return FALSE; ! 488: if (aflag && cgtdate(hp->subdate) < atime) ! 489: return FALSE; ! 490: if (index(hp->nbuf, ',') && !rightgroup(hp)) ! 491: return FALSE; ! 492: if (fflag && (hp->followid[0] || PREFIX(hp->title, "Re:"))) ! 493: return FALSE; ! 494: return TRUE; ! 495: } ! 496: ! 497: /* ! 498: * Code to avoid showing multiple articles for news. ! 499: * Works even if you exit news. ! 500: * Returns nonzero if we should show this article. ! 501: */ ! 502: rightgroup(hp) ! 503: struct hbuf *hp; ! 504: { ! 505: char ng[BUFLEN]; ! 506: register char *p, *g; ! 507: int i, flag; ! 508: ! 509: strcpy(ng, hp->nbuf); ! 510: g = ng; ! 511: flag = 1; ! 512: while (g != NULL) { ! 513: p = index(g, ','); ! 514: if (p != NULL) { ! 515: *p++ = '\0'; ! 516: while (*p == ' ') ! 517: p++; ! 518: } ! 519: if (STRCMP(g, groupdir) == 0) ! 520: return flag; ! 521: if (ngmatch(g, header.nbuf) ! 522: && ((i = findrcline(g)) >= 0 ! 523: && index(rcline[i], '!') == NULL)) ! 524: flag = 0; ! 525: g = p; ! 526: } ! 527: /* we must be in "junk" or "control" */ ! 528: return TRUE; ! 529: } ! 530: ! 531: back() ! 532: { ! 533: while (fseek(actfp, -2L, 1) != -1 && ftell(actfp) > 0L) { ! 534: if (getc(actfp) == '\n') ! 535: return 0; ! 536: } ! 537: if (ftell(actfp) == 0L) ! 538: return 0; ! 539: return 1; ! 540: } ! 541: ! 542: /* ! 543: * Trap interrupts. ! 544: */ ! 545: onsig(n) ! 546: int n; ! 547: { ! 548: (void) signal(n, onsig); ! 549: SigTrap = n; ! 550: if (rcreadok < 2) { ! 551: fprintf(stderr, "Aborted early\n"); ! 552: xxit(0); ! 553: } ! 554: } ! 555: ! 556: /* ! 557: * finds the line in your .newsrc file (actually the in-core "rcline" ! 558: * copy of it) and returns the index into the array where it was found. ! 559: * -1 means it didn't find it. ! 560: * ! 561: * We play clever games here to make this faster. It's inherently ! 562: * quadratic - we spend lots of CPU time here because we search through ! 563: * the whole .newsrc for each line. The "prev" variable remembers where ! 564: * the last match was found; we start the search there and loop around ! 565: * to the beginning, in the hopes that the calls will be roughly in order. ! 566: */ ! 567: int ! 568: findrcline(name) ! 569: register char *name; ! 570: { ! 571: register char * p; ! 572: register int i; ! 573: register int top; ! 574: register int len; ! 575: static int prev; ! 576: static int didthru; ! 577: ! 578: for ( ; didthru <= line; ++didthru) ! 579: if ((p = index(rcline[didthru], '!')) != 0 || ! 580: (p = index(rcline[didthru], ':')) != 0) { ! 581: lentab[didthru] = (int)(p - rcline[didthru]); ! 582: } ! 583: len = strlen(name); ! 584: top = line; ! 585: i = prev; ! 586: loop: ! 587: for ( ; i <= top; ++i) ! 588: if (lentab[i] == len && rcline[i] != NULL && ! 589: STRNCMP(name, rcline[i], len) == 0) ! 590: return prev = i; ! 591: if (i > line && line > prev - 1) { ! 592: i = 0; ! 593: top = prev - 1; ! 594: goto loop; ! 595: } ! 596: return -1; ! 597: } ! 598: ! 599: /* ! 600: * sortactive - make a local copy of the active file, sorted according ! 601: * to the user's preferences, according to his .newsrc file. ! 602: */ ! 603: ! 604: struct table_elt { ! 605: int rcindex; ! 606: long maxart, minart; ! 607: char yn; ! 608: }; ! 609: ! 610: #ifdef SORTACTIVE ! 611: static int ! 612: rcsort(a, b) ! 613: char *a, *b; ! 614: { ! 615: return(((struct table_elt *)a)->rcindex - ! 616: ((struct table_elt *)b)->rcindex); ! 617: } ! 618: ! 619: static char *newactivename = "/tmp/newsaXXXXXX"; ! 620: #endif /* SORTACTIVE */ ! 621: ! 622: sortactive() ! 623: { ! 624: register struct table_elt *tp; ! 625: register char *p; ! 626: register FILE *nfp, *afp; ! 627: char aline[BUFLEN], ngname[BUFLEN]; ! 628: struct table_elt table[LINES]; ! 629: int nlines = 0, i, delta, lastline; ! 630: ! 631: #ifdef SORTACTIVE ! 632: /* make a new sorted copy of ACTIVE */ ! 633: nfp = fopen(mktemp(newactivename), "w"); ! 634: (void) chmod(newactivename, 0600); ! 635: if (nfp == NULL) { ! 636: perror(newactivename); ! 637: return; ! 638: } ! 639: ! 640: /* look up all the lines in ACTIVE, finding their positions in .newsrc */ ! 641: p = ACTIVE; ! 642: ACTIVE = newactivename; ! 643: afp = xfopen(p, "r"); ! 644: ! 645: #else /* !SORTACTIVE */ ! 646: afp = xfopen(ACTIVE, "r"); ! 647: #endif /* !SORTACTIVE */ ! 648: tp = table; ! 649: while (fgets(aline, sizeof aline, afp) != NULL) { ! 650: if (sscanf(aline,"%s %ld %ld %c", ngname, &tp->maxart, ! 651: &tp->minart, &tp->yn) != 4) ! 652: xerror("Active file corrupt"); ! 653: delta = tp->maxart - tp->minart; ! 654: if (delta >= BITMAPSIZE) ! 655: BITMAPSIZE = delta + 1; ! 656: if (Kflag && tp->maxart > 0 && ngmatch(ngname, header.nbuf)) { ! 657: int j; ! 658: ! 659: j = findrcline(ngname); ! 660: if (j >= 0 && index(rcline[j], '!') == NULL) { ! 661: char rbuf[BUFLEN]; ! 662: if (tp->maxart == 1) ! 663: sprintf(rbuf, "%s: 1", ngname); ! 664: else ! 665: sprintf(rbuf, "%s: 1-%ld", ngname, tp->maxart); ! 666: rcline[j] = realloc(rcline[j], ! 667: (unsigned)(strlen(rbuf)+1)); ! 668: if (rcline[j] == NULL) ! 669: xerror("Not enough memory"); ! 670: strcpy(rcline[j], rbuf); ! 671: } ! 672: } ! 673: #ifdef SORTACTIVE ! 674: tp->rcindex = findrcline(ngname); ! 675: if (tp->rcindex < 0) { ! 676: if (++line > LINES) ! 677: xerror("Too many newsgroups"); ! 678: strcat(ngname, ":"); ! 679: rcline[line] = malloc((unsigned)(strlen(ngname) + 1)); ! 680: if (rcline[line] == NULL) ! 681: xerror("Not enough memory"); ! 682: strcpy(rcline[line], ngname); ! 683: tp->rcindex = line; ! 684: } ! 685: tp++; ! 686: #endif /* SORTACTIVE */ ! 687: } ! 688: (void) fclose(afp); ! 689: BITMAPSIZE = 8 * ((BITMAPSIZE+7) / 8); ! 690: bitmap = malloc((unsigned)BITMAPSIZE/8); ! 691: if (bitmap == NULL) ! 692: xerror("Can't malloc bitmap"); ! 693: ! 694: #ifdef SORTACTIVE ! 695: /* sort by position in user's .newsrc file (new groups come up last) */ ! 696: nlines = tp - table; ! 697: qsort((char *)table, nlines, sizeof table[0], rcsort); ! 698: ! 699: tp = table; ! 700: lastline = tp->rcindex - 1; ! 701: /* copy active to newactive, in the new order */ ! 702: for (i = 0; i < nlines; i++) { ! 703: while (++lastline < tp->rcindex) { ! 704: if (STRNCMP(rcline[lastline], "options ", 8) == 0) { ! 705: fprintf(nfp, "%s\n", rcline[lastline]); ! 706: } else { ! 707: fprintf(stderr, "Duplicate .newsrc line or bad group %s\n", ! 708: rcline[lastline]); ! 709: lentab[lastline] = 0; ! 710: free(rcline[lastline]); ! 711: rcline[lastline] = NULL; ! 712: } ! 713: } ! 714: if (rcline[tp->rcindex] == NULL) ! 715: continue; ! 716: p = rcline[tp->rcindex]; ! 717: while (*p != ':' && *p != '!') ! 718: fputc(*p++, nfp); ! 719: (void) fprintf(nfp, " %ld %ld %c\n", tp->maxart, tp->minart, ! 720: tp->yn); ! 721: tp++; ! 722: } ! 723: (void) fclose(nfp); ! 724: #endif /* SORTACTIVE */ ! 725: } ! 726: ! 727: #include <errno.h> ! 728: ! 729: #ifdef SMALL_ADDRESS_SPACE ! 730: list_group(lgroup, displines, flag, pngsize) ! 731: char *lgroup; ! 732: int displines, flag; ! 733: long pngsize; ! 734: { ! 735: printf("Not enough memory on your machine to include this function.\n");} ! 736: #else /* !SMALL_ADDRESS_SPACE */ ! 737: ! 738: /* ! 739: * Routine to display header lines for all articles in newsgroup. If the flag ! 740: * argument is FALSE then only articles which are not marked as read in the ! 741: * bitmap will be displayed. This routine makes no attempt to determine if ! 742: * the article is in multiple groups and therefore should not be displayed at ! 743: * this time. ! 744: */ ! 745: ! 746: static int *lg_array = NULL; ! 747: static int *lg_entry; ! 748: static int lg_max = 0; ! 749: static int int_sig; ! 750: extern int errno; ! 751: ! 752: lg_cmp(p1, p2) ! 753: int *p1, *p2; ! 754: { ! 755: return *p1 - *p2; ! 756: } ! 757: ! 758: list_group(lgroup, displines, flag, pngsize) ! 759: char *lgroup; ! 760: int displines, flag; ! 761: long pngsize; ! 762: { ! 763: char *briefdate(); ! 764: struct hbuf hh; ! 765: #ifndef SERVER ! 766: register DIR *dirp; ! 767: register struct direct *dir; ! 768: #endif /* !SERVER */ ! 769: register FILE *fp_art; ! 770: int i; ! 771: int entries; ! 772: unsigned int alloc_size; ! 773: int (*old_sig) (); ! 774: extern lg_trap(); ! 775: char *gets(); ! 776: #ifdef SERVER ! 777: int lowgp,highgp; ! 778: char workspace[256]; ! 779: if (*lgroup == ' ' || *lgroup == '\0') return; ! 780: strcpy(workspace, set_group(lgroup)); ! 781: if (*workspace != CHAR_OK) { ! 782: printf("Group %s is invalid: \n%s\n", lgroup, workspace); ! 783: return; ! 784: } ! 785: /* We assume that the server will return a line of this format */ ! 786: (void) sscanf(workspace, "%s %ld %ld %ld", bfr, &i, &lowgp, &highgp); ! 787: if (i == 0) { ! 788: printf("There are no articles in %s\n", lgroup); ! 789: return; ! 790: } ! 791: #else /* !SERVER */ ! 792: /* This should get the numbers from the active file XXX */ ! 793: if ((dirp = opendir(dirname(lgroup))) == NULL) { ! 794: printf("Can't open %s\r\n", dirname(lgroup)); ! 795: return; ! 796: } ! 797: #endif /* !SERVER */ ! 798: entries = 0; ! 799: if (lg_array == NULL) { ! 800: lg_max = 50; ! 801: alloc_size = lg_max * sizeof(int); ! 802: lg_array = (int *) malloc(alloc_size); ! 803: } ! 804: #ifdef SERVER ! 805: for(i = lowgp; i < highgp; i++){ ! 806: #else /* !SERVER */ ! 807: while ((dir = readdir(dirp)) != NULL) { ! 808: if (dir->d_ino == 0) ! 809: continue; ! 810: i = atoi(dir->d_name); ! 811: #endif /* !SERVER */ ! 812: if ((i < 1) || (i > pngsize)) ! 813: continue; ! 814: if (flag == FALSE) { ! 815: if (get((long)i) == 0) ! 816: continue; ! 817: } ! 818: if (++entries > lg_max) { ! 819: lg_max += 50; ! 820: alloc_size = lg_max * sizeof(int); ! 821: lg_array = (int *) realloc((char *) lg_array, alloc_size); ! 822: } ! 823: lg_array[entries - 1] = i; ! 824: } ! 825: if (entries == lg_max) { ! 826: lg_max++; ! 827: alloc_size = lg_max * sizeof(int); ! 828: lg_array = (int *) realloc((char *) lg_array, alloc_size); ! 829: } ! 830: qsort(lg_array, entries, sizeof *lg_array, lg_cmp); ! 831: lg_array[entries] = 0; ! 832: int_sig = 0; ! 833: old_sig = signal(SIGINT, lg_trap); ! 834: hh.unrec[0] = NULL; ! 835: for (lg_entry = lg_array; *lg_entry != 0 && int_sig == 0; lg_entry++) { ! 836: #ifdef SERVER ! 837: /* we'll see if just getting the header will work here */ ! 838: if ((fp_art = getarticle(lgroup, *lg_entry, "HEAD")) != NULL) { ! 839: strcpy(filename, article_name()); ! 840: (void) fclose(fp_art); ! 841: fp_art = NULL; ! 842: } ! 843: else ! 844: continue; ! 845: #else /* !SERVER */ ! 846: (void) sprintf(filename, "%s/%d", dirname(lgroup), *lg_entry); ! 847: #endif /* !SERVER */ ! 848: fp_art = fopen(filename, "r"); ! 849: if (fp_art == NULL) ! 850: continue; ! 851: if (hread(&hh, fp_art, TRUE) == NULL) { ! 852: (void) fclose(fp_art); ! 853: continue; ! 854: } ! 855: printf("%5d %-20.20s %-13s %s\r\n", ! 856: *lg_entry, hh.from, ! 857: briefdate(hh.subdate), hh.title); ! 858: for (i = 0; i < displines;) { ! 859: if (fgets(bfr, LBUFLEN, fp_art) == NULL) { ! 860: break; ! 861: } ! 862: if ((bfr[0] == '\n') || (bfr[0] == '>')) { ! 863: continue; ! 864: } ! 865: printf("%s", bfr); ! 866: i++; ! 867: } ! 868: (void) fclose(fp_art); ! 869: #ifdef SERVER ! 870: (void) unlink(filename); ! 871: #endif /* SERVER */ ! 872: } ! 873: (void) fflush(stdout); ! 874: #ifndef SERVER ! 875: closedir(dirp); ! 876: #endif /* !SERVER */ ! 877: (void) signal(SIGINT, old_sig); /* restore to old value */ ! 878: printf("[Press RETURN to continue]"); ! 879: (void) fflush(stdout); ! 880: ! 881: while (TRUE) { ! 882: errno = 0; ! 883: i = getchar(); ! 884: if (errno == EINTR) ! 885: continue; ! 886: if (i == '\n' || i == '\r') ! 887: break; ! 888: if (i == EOF) ! 889: break; ! 890: if (i == '\4') ! 891: break; ! 892: } ! 893: (void) free(lg_array); ! 894: lg_array = NULL; ! 895: ! 896: } ! 897: #endif /* !SMALL_ADDRESS_SPACE */ ! 898: ! 899: lg_trap(code) ! 900: int code; ! 901: { ! 902: ! 903: int_sig = 1; ! 904: (void) signal(code, lg_trap); /* reset signal */ ! 905: ! 906: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.