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