|
|
1.1 root 1: /* $Header: rcstuff.c,v 4.3.1.5 86/07/24 14:09:10 lwall Exp $
2: *
3: * $Log: rcstuff.c,v $
4: * Revision 4.3.1.5 86/07/24 14:09:10 lwall
5: * Removed check for spool directory existence in get_ng.
6: *
7: * Revision 4.3.1.4 85/09/10 11:04:44 lwall
8: * Improved %m in in_char().
9: *
10: * Revision 4.3.1.3 85/05/29 09:13:25 lwall
11: * %d that should be %ld.
12: *
13: * Revision 4.3.1.2 85/05/17 11:40:08 lwall
14: * Sped up "rn -c" by not mallocing unnecessarily.
15: *
16: * Revision 4.3.1.1 85/05/10 11:37:18 lwall
17: * Branch for patches.
18: *
19: * Revision 4.3 85/05/01 11:45:56 lwall
20: * Baseline for release with 4.3bsd.
21: *
22: */
23:
24: #include "EXTERN.h"
25: #include "common.h"
26: #include "util.h"
27: #include "ngdata.h"
28: #include "term.h"
29: #include "final.h"
30: #include "rn.h"
31: #include "intrp.h"
32: #include "only.h"
33: #include "rcln.h"
34: #include "INTERN.h"
35: #include "rcstuff.h"
36:
37: char *rcname INIT(Nullch); /* path name of .newsrc file */
38: char *rctname INIT(Nullch); /* path name of temp .newsrc file */
39: char *rcbname INIT(Nullch); /* path name of backup .newsrc file */
40: char *softname INIT(Nullch); /* path name of .rnsoft file */
41: FILE *rcfp INIT(Nullfp); /* .newsrc file pointer */
42:
43: #ifdef HASHNG
44: short hashtbl[HASHSIZ];
45: #endif
46:
47: bool
48: rcstuff_init()
49: {
50: register NG_NUM newng;
51: register char *s;
52: register int i;
53: register bool foundany = FALSE;
54: char *some_buf;
55: long length;
56:
57: #ifdef HASHNG
58: for (i=0; i<HASHSIZ; i++)
59: hashtbl[i] = -1;
60: #endif
61:
62: /* make filenames */
63:
64: rcname = savestr(filexp(RCNAME));
65: rctname = savestr(filexp(RCTNAME));
66: rcbname = savestr(filexp(RCBNAME));
67: softname = savestr(filexp(SOFTNAME));
68:
69: /* make sure the .newsrc file exists */
70:
71: newsrc_check();
72:
73: /* open .rnsoft file containing soft ptrs to active file */
74:
75: tmpfp = fopen(softname,"r");
76: if (tmpfp == Nullfp)
77: writesoft = TRUE;
78:
79: /* read in the .newsrc file */
80:
81: for (nextrcline = 0;
82: (some_buf = get_a_line(buf,LBUFLEN,rcfp)) != Nullch;
83: nextrcline++) {
84: /* for each line in .newsrc */
85: char tmpbuf[10];
86:
87: newng = nextrcline; /* get it into a register */
88: length = len_last_line_got; /* side effect of get_a_line */
89: if (length <= 1) { /* only a newline??? */
90: nextrcline--; /* compensate for loop increment */
91: continue;
92: }
93: if (newng >= MAXRCLINE) { /* check for overflow */
94: fputs("Too many lines in .newsrc\n",stdout) FLUSH;
95: finalize(1);
96: }
97: if (tmpfp != Nullfp && fgets(tmpbuf,10,tmpfp) != Nullch)
98: softptr[newng] = atoi(tmpbuf);
99: else
100: softptr[newng] = 0;
101: some_buf[--length] = '\0'; /* wipe out newline */
102: if (checkflag) /* no extra mallocs for -c */
103: rcline[newng] = some_buf;
104: else if (some_buf == buf) {
105: rcline[newng] = savestr(some_buf);
106: /* make a semipermanent copy */
107: }
108: else {
109: /*NOSTRICT*/
110: #ifndef lint
111: some_buf = saferealloc(some_buf,(MEM_SIZE)(length+1));
112: #endif lint
113: rcline[newng] = some_buf;
114: }
115: #ifdef NOTDEF
116: if (strnEQ(some_buf,"to.",3)) { /* is this a non-newsgroup? */
117: nextrcline--; /* destroy this line */
118: continue;
119: }
120: #endif
121: if (*some_buf == ' ' ||
122: *some_buf == '\t' ||
123: strnEQ(some_buf,"options",7)) { /* non-useful line? */
124: toread[newng] = TR_JUNK;
125: rcchar[newng] = ' ';
126: rcnums[newng] = 0;
127: continue;
128: }
129: for (s = rcline[newng]; *s && *s != ':' && *s != NEGCHAR; s++) ;
130: if (!*s && !checkflag) {
131: #ifndef lint
132: rcline[newng] = saferealloc(rcline[newng],(MEM_SIZE)length+2);
133: #endif lint
134: s = rcline[newng] + length;
135: *s = ':';
136: *(s+1) = '\0';
137: }
138: rcchar[newng] = *s; /* salt away the : or ! */
139: rcnums[newng] = (char)(s - rcline[newng]);
140: rcnums[newng]++; /* remember where it was */
141: *s = '\0'; /* null terminate newsgroup name */
142: #ifdef HASHNG
143: if (!checkflag)
144: sethash(newng);
145: #endif
146: if (rcchar[newng] == NEGCHAR) {
147: toread[newng] = TR_UNSUB;
148: continue;
149: }
150:
151: /* now find out how much there is to read */
152:
153: if (!inlist(buf) || (suppress_cn && foundany && !paranoid))
154: toread[newng] = TR_NONE; /* no need to calculate now */
155: else
156: set_toread(newng);
157: #ifdef VERBOSE
158: if (!checkflag && softmisses == 1) {
159: softmisses++; /* lie a little */
160: fputs("(Revising soft pointers--be patient.)\n",stdout) FLUSH;
161: }
162: #endif
163: if (toread[newng] > TR_NONE) { /* anything unread? */
164: if (!foundany) {
165: starthere = newng;
166: foundany = TRUE; /* remember that fact*/
167: }
168: if (suppress_cn) { /* if no listing desired */
169: if (checkflag) { /* if that is all they wanted */
170: finalize(1); /* then bomb out */
171: }
172: }
173: else {
174: #ifdef VERBOSE
175: IF(verbose)
176: printf("Unread news in %-20s %5ld article%s\n",
177: rcline[newng],(long)toread[newng],
178: toread[newng]==TR_ONE ? nullstr : "s") FLUSH;
179: ELSE
180: #endif
181: #ifdef TERSE
182: printf("%s: %ld article%s\n",
183: rcline[newng],(long)toread[newng],
184: toread[newng]==TR_ONE ? nullstr : "s") FLUSH;
185: #endif
186: if (int_count) {
187: countdown = 1;
188: int_count = 0;
189: }
190: if (countdown) {
191: if (! --countdown) {
192: fputs("etc.\n",stdout) FLUSH;
193: if (checkflag)
194: finalize(1);
195: suppress_cn = TRUE;
196: }
197: }
198: }
199: }
200: }
201: fclose(rcfp); /* close .newsrc */
202: if (tmpfp != Nullfp)
203: fclose(tmpfp); /* close .rnsoft */
204: if (checkflag) { /* were we just checking? */
205: finalize(foundany); /* tell them what we found */
206: }
207: if (paranoid)
208: cleanup_rc();
209:
210: #ifdef DEBUGGING
211: if (debug & DEB_HASH) {
212: page_init();
213: for (i=0; i<HASHSIZ; i++) {
214: sprintf(buf,"%d %d",i,hashtbl[i]);
215: print_lines(buf,NOMARKING);
216: }
217: }
218: #endif
219:
220: return foundany;
221: }
222:
223: /* try to find or add an explicitly specified newsgroup */
224: /* returns TRUE if found or added, FALSE if not. */
225: /* assumes that we are chdir'ed to SPOOL */
226:
227: bool
228: get_ng(what,do_reloc)
229: char *what;
230: bool do_reloc;
231: {
232: char *ntoforget;
233: char promptbuf[128];
234:
235: #ifdef VERBOSE
236: IF(verbose)
237: ntoforget = "Type n to forget about this newsgroup.\n";
238: ELSE
239: #endif
240: #ifdef TERSE
241: ntoforget = "n to forget it.\n";
242: #endif
243: if (index(what,'/')) {
244: dingaling();
245: printf("\nBad newsgroup name.\n") FLUSH;
246: return FALSE;
247: }
248: set_ngname(what);
249: ng = find_ng(ngname);
250: if (ng == nextrcline) { /* not in .newsrc? */
251: if ((softptr[ng] = findact(buf,ngname,strlen(ngname),0L)) < 0 ) {
252: dingaling();
253: #ifdef VERBOSE
254: IF(verbose)
255: printf("\nNewsgroup %s does not exist!\n",ngname) FLUSH;
256: ELSE
257: #endif
258: #ifdef TERSE
259: printf("\nNo %s!\n",ngname) FLUSH;
260: #endif
261: sleep(2);
262: return FALSE;
263: }
264: #ifdef VERBOSE
265: IF(verbose)
266: sprintf(promptbuf,"\nNewsgroup %s not in .newsrc--add? [yn] ",ngname);
267: ELSE
268: #endif
269: #ifdef TERSE
270: sprintf(promptbuf,"\nAdd %s? [yn] ",ngname);
271: #endif
272: reask_add:
273: in_char(promptbuf,'A');
274: putchar('\n') FLUSH;
275: setdef(buf,"y");
276: #ifdef VERIFY
277: printcmd();
278: #endif
279: if (*buf == 'h') {
280: #ifdef VERBOSE
281: IF(verbose)
282: printf("Type y or SP to add %s to your .newsrc.\n", ngname)
283: FLUSH;
284: ELSE
285: #endif
286: #ifdef TERSE
287: fputs("y or SP to add\n",stdout) FLUSH;
288: #endif
289: fputs(ntoforget,stdout) FLUSH;
290: goto reask_add;
291: }
292: else if (*buf == 'n' || *buf == 'q') {
293: return FALSE;
294: }
295: else if (*buf == 'y') {
296: ng = add_newsgroup(ngname);
297: do_reloc = FALSE;
298: }
299: else {
300: fputs(hforhelp,stdout) FLUSH;
301: settle_down();
302: goto reask_add;
303: }
304: }
305: else if (rcchar[ng] == NEGCHAR) { /* unsubscribed? */
306: #ifdef VERBOSE
307: IF(verbose)
308: sprintf(promptbuf,
309: "\nNewsgroup %s is currently unsubscribed to--resubscribe? [yn] ",ngname)
310: FLUSH;
311: ELSE
312: #endif
313: #ifdef TERSE
314: sprintf(promptbuf,"\n%s unsubscribed--resubscribe? [yn] ",ngname)
315: FLUSH;
316: #endif
317: reask_unsub:
318: in_char(promptbuf,'R');
319: putchar('\n') FLUSH;
320: setdef(buf,"y");
321: #ifdef VERIFY
322: printcmd();
323: #endif
324: if (*buf == 'h') {
325: #ifdef VERBOSE
326: IF(verbose)
327: printf("Type y or SP to resubscribe to %s.\n", ngname) FLUSH;
328: ELSE
329: #endif
330: #ifdef TERSE
331: fputs("y or SP to resubscribe.\n",stdout) FLUSH;
332: #endif
333: fputs(ntoforget,stdout) FLUSH;
334: goto reask_unsub;
335: }
336: else if (*buf == 'n' || *buf == 'q') {
337: return FALSE;
338: }
339: else if (*buf == 'y') {
340: rcchar[ng] = ':';
341: }
342: else {
343: fputs(hforhelp,stdout) FLUSH;
344: settle_down();
345: goto reask_unsub;
346: }
347: }
348:
349: /* now calculate how many unread articles in newsgroup */
350:
351: set_toread(ng);
352: #ifdef RELOCATE
353: if (do_reloc)
354: ng = relocate_newsgroup(ng,-1);
355: #endif
356: return toread[ng] >= TR_NONE;
357: }
358:
359: /* add a newsgroup to the .newsrc file (eventually) */
360:
361: NG_NUM
362: add_newsgroup(ngn)
363: char *ngn;
364: {
365: register NG_NUM newng = nextrcline++;
366: /* increment max rcline index */
367:
368: rcnums[newng] = strlen(ngn) + 1;
369: rcline[newng] = safemalloc((MEM_SIZE)(rcnums[newng] + 1));
370: strcpy(rcline[newng],ngn); /* and copy over the name */
371: *(rcline[newng] + rcnums[newng]) = '\0';
372: rcchar[newng] = ':'; /* call it subscribed */
373: toread[newng] = TR_NONE; /* just for prettiness */
374: #ifdef HASHNG
375: sethash(newng); /* so we can find it again */
376: #endif
377: #ifdef RELOCATE
378: return relocate_newsgroup(newng,-1);
379: #else
380: return newng;
381: #endif
382: }
383:
384: #ifdef RELOCATE
385: NG_NUM
386: relocate_newsgroup(ngx,newng)
387: NG_NUM ngx;
388: NG_NUM newng;
389: {
390: char *dflt = (ngx!=current_ng ? "$^.L" : "$^L");
391: char *tmprcline;
392: ART_UNREAD tmptoread;
393: char tmprcchar;
394: char tmprcnums;
395: ACT_POS tmpsoftptr;
396: register NG_NUM i;
397: #ifdef DEBUGGING
398: ART_NUM tmpngmax;
399: #endif
400: #ifdef CACHEFIRST
401: ART_NUM tmpabs1st;
402: #endif
403:
404: starthere = 0; /* Disable this optimization */
405: writesoft = TRUE; /* Update soft pointer file */
406: if (ngx < nextrcline-1) {
407: #ifdef HASHNG
408: for (i=0; i<HASHSIZ; i++) {
409: if (hashtbl[i] > ngx)
410: --hashtbl[i];
411: else if (hashtbl[i] == ngx)
412: hashtbl[i] = nextrcline-1;
413: }
414: #endif
415: tmprcline = rcline[ngx];
416: tmptoread = toread[ngx];
417: tmprcchar = rcchar[ngx];
418: tmprcnums = rcnums[ngx];
419: tmpsoftptr = softptr[ngx];
420: #ifdef DEBUGGING
421: tmpngmax = ngmax[ngx];
422: #endif
423: #ifdef CACHEFIRST
424: tmpabs1st = abs1st[ngx];
425: #endif
426: for (i=ngx+1; i<nextrcline; i++) {
427: rcline[i-1] = rcline[i];
428: toread[i-1] = toread[i];
429: rcchar[i-1] = rcchar[i];
430: rcnums[i-1] = rcnums[i];
431: softptr[i-1] = softptr[i];
432: #ifdef DEBUGGING
433: ngmax[i-1] = ngmax[i];
434: #endif
435: #ifdef CACHEFIRST
436: abs1st[i-1] = abs1st[i];
437: #endif
438: }
439: rcline[nextrcline-1] = tmprcline;
440: toread[nextrcline-1] = tmptoread;
441: rcchar[nextrcline-1] = tmprcchar;
442: rcnums[nextrcline-1] = tmprcnums;
443: softptr[nextrcline-1] = tmpsoftptr;
444: #ifdef DEBUGGING
445: ngmax[nextrcline-1] = tmpngmax;
446: #endif
447: #ifdef CACHEFIRST
448: abs1st[nextrcline-1] = tmpabs1st;
449: #endif
450: }
451: if (current_ng > ngx)
452: current_ng--;
453: if (newng < 0) {
454: reask_reloc:
455: unflush_output(); /* disable any ^O in effect */
456: #ifdef VERBOSE
457: IF(verbose)
458: printf("\nPut newsgroup where? [%s] ", dflt);
459: ELSE
460: #endif
461: #ifdef TERSE
462: printf("\nPut where? [%s] ", dflt);
463: #endif
464: fflush(stdout);
465: reinp_reloc:
466: eat_typeahead();
467: getcmd(buf);
468: if (errno || *buf == '\f') {
469: /* if return from stop signal */
470: goto reask_reloc; /* give them a prompt again */
471: }
472: setdef(buf,dflt);
473: #ifdef VERIFY
474: printcmd();
475: #endif
476: if (*buf == 'h') {
477: #ifdef VERBOSE
478: IF(verbose) {
479: printf("\n\n\
480: Type ^ to put the newsgroup first (position 0).\n\
481: Type $ to put the newsgroup last (position %d).\n", nextrcline-1);
482: printf("\
483: Type . to put it before the current newsgroup (position %d).\n", current_ng);
484: printf("\
485: Type -newsgroup name to put it before that newsgroup.\n\
486: Type +newsgroup name to put it after that newsgroup.\n\
487: Type a number between 0 and %d to put it at that position.\n", nextrcline-1);
488: printf("\
489: Type L for a listing of newsgroups and their positions.\n") FLUSH;
490: }
491: ELSE
492: #endif
493: #ifdef TERSE
494: {
495: printf("\n\n\
496: ^ to put newsgroup first (pos 0).\n\
497: $ to put last (pos %d).\n", nextrcline-1);
498: printf("\
499: . to put before current newsgroup (pos %d).\n", current_ng);
500: printf("\
501: -newsgroup to put before newsgroup.\n\
502: +newsgroup to put after.\n\
503: number in 0-%d to put at that pos.\n", nextrcline-1);
504: printf("\
505: L for list of .newsrc.\n") FLUSH;
506: }
507: #endif
508: goto reask_reloc;
509: }
510: else if (*buf == 'L') {
511: putchar('\n') FLUSH;
512: list_newsgroups();
513: goto reask_reloc;
514: }
515: else if (isdigit(*buf)) {
516: if (!finish_command(TRUE)) /* get rest of command */
517: goto reinp_reloc;
518: newng = atoi(buf);
519: if (newng < 0)
520: newng = 0;
521: if (newng >= nextrcline)
522: return nextrcline-1;
523: }
524: else if (*buf == '^') {
525: putchar('\n') FLUSH;
526: newng = 0;
527: }
528: else if (*buf == '$') {
529: putchar('\n') FLUSH;
530: return nextrcline-1;
531: }
532: else if (*buf == '.') {
533: putchar('\n') FLUSH;
534: newng = current_ng;
535: }
536: else if (*buf == '-' || *buf == '+') {
537: if (!finish_command(TRUE)) /* get rest of command */
538: goto reinp_reloc;
539: newng = find_ng(buf+1);
540: if (newng == nextrcline) {
541: fputs("Not found.",stdout) FLUSH;
542: goto reask_reloc;
543: }
544: if (*buf == '+')
545: newng++;
546: }
547: else {
548: printf("\n%s",hforhelp) FLUSH;
549: settle_down();
550: goto reask_reloc;
551: }
552: }
553: if (newng < nextrcline-1) {
554: #ifdef HASHNG
555: for (i=0; i<HASHSIZ; i++) {
556: if (hashtbl[i] == nextrcline-1)
557: hashtbl[i] = newng;
558: else if (hashtbl[i] >= newng)
559: ++hashtbl[i];
560: }
561: #endif
562: tmprcline = rcline[nextrcline-1];
563: tmptoread = toread[nextrcline-1];
564: tmprcchar = rcchar[nextrcline-1];
565: tmprcnums = rcnums[nextrcline-1];
566: tmpsoftptr = softptr[nextrcline-1];
567: #ifdef DEBUGGING
568: tmpngmax = ngmax[nextrcline-1];
569: #endif
570: #ifdef CACHEFIRST
571: tmpabs1st = abs1st[nextrcline-1];
572: #endif
573: for (i=nextrcline-2; i>=newng; i--) {
574: rcline[i+1] = rcline[i];
575: toread[i+1] = toread[i];
576: rcchar[i+1] = rcchar[i];
577: rcnums[i+1] = rcnums[i];
578: softptr[i+1] = softptr[i];
579: #ifdef DEBUGGING
580: ngmax[i+1] = ngmax[i];
581: #endif
582: #ifdef CACHEFIRST
583: abs1st[i+1] = abs1st[i];
584: #endif
585: }
586: rcline[newng] = tmprcline;
587: toread[newng] = tmptoread;
588: rcchar[newng] = tmprcchar;
589: rcnums[newng] = tmprcnums;
590: softptr[newng] = tmpsoftptr;
591: #ifdef DEBUGGING
592: ngmax[newng] = tmpngmax;
593: #endif
594: #ifdef CACHEFIRST
595: abs1st[newng] = tmpabs1st;
596: #endif
597: }
598: if (current_ng >= newng)
599: current_ng++;
600: return newng;
601: }
602: #endif
603:
604: /* List out the newsrc with annotations */
605:
606: void
607: list_newsgroups()
608: {
609: register NG_NUM i;
610: char tmpbuf[2048];
611: static char *status[] = {"(READ)","(UNSUB)","(BOGUS)","(JUNK)"};
612: int cmd;
613:
614: page_init();
615: print_lines("\
616: # Status Newsgroup\n\
617: ",STANDOUT);
618: for (i=0; i<nextrcline && !int_count; i++) {
619: if (toread[i] >= 0)
620: set_toread(i);
621: *(rcline[i] + rcnums[i] - 1) = rcchar[i];
622: if (toread[i] > 0)
623: sprintf(tmpbuf,"%3d %6ld ",i,(long)toread[i]);
624: else
625: sprintf(tmpbuf,"%3d %7s ",i,status[-toread[i]]);
626: safecpy(tmpbuf+13,rcline[i],2034);
627: *(rcline[i] + rcnums[i] - 1) = '\0';
628: if (cmd = print_lines(tmpbuf,NOMARKING)) {
629: if (cmd > 0)
630: pushchar(cmd);
631: break;
632: }
633: }
634: int_count = 0;
635: }
636:
637: /* find a newsgroup in .newsrc */
638:
639: NG_NUM
640: find_ng(ngnam)
641: char *ngnam;
642: {
643: register NG_NUM ngnum;
644: #ifdef HASHNG
645: register int hashix = hash(ngnam);
646: register int incr = 1;
647:
648: while ((ngnum = hashtbl[hashix]) >= 0) {
649: if (strEQ(rcline[ngnum], ngnam) && toread[ngnum] >= TR_UNSUB)
650: return ngnum;
651: hashix = (hashix + incr) % HASHSIZ;
652: incr += 2; /* offsets from original are in n*2 */
653: }
654: return nextrcline; /* = notfound */
655:
656: #else /* just do linear search */
657:
658: for (ngnum = 0; ngnum < nextrcline; ngnum++) {
659: if (strEQ(rcline[ngnum],ngnam))
660: break;
661: }
662: return ngnum;
663: #endif
664: }
665:
666: void
667: cleanup_rc()
668: {
669: register NG_NUM ngx;
670: register NG_NUM bogosity = 0;
671:
672: #ifdef VERBOSE
673: IF(verbose)
674: fputs("Checking out your .newsrc--hang on a second...\n",stdout)
675: FLUSH;
676: ELSE
677: #endif
678: #ifdef TERSE
679: fputs("Checking .newsrc--hang on...\n",stdout) FLUSH;
680: #endif
681: for (ngx = 0; ngx < nextrcline; ngx++) {
682: if (toread[ngx] >= TR_UNSUB) {
683: set_toread(ngx); /* this may reset newsgroup */
684: /* or declare it bogus */
685: }
686: if (toread[ngx] == TR_BOGUS)
687: bogosity++;
688: }
689: for (ngx = nextrcline-1; ngx >= 0 && toread[ngx] == TR_BOGUS; ngx--)
690: bogosity--; /* discount already moved ones */
691: if (nextrcline > 5 && bogosity > nextrcline / 2) {
692: fputs(
693: "It looks like the active file is messed up. Contact your news administrator,\n\
694: ",stdout);
695: fputs(
696: "leave the \"bogus\" groups alone, and they may come back to normal. Maybe.\n\
697: ",stdout) FLUSH;
698: }
699: #ifdef RELOCATE
700: else if (bogosity) {
701: #ifdef VERBOSE
702: IF(verbose)
703: fputs("Moving bogus newsgroups to the end of your .newsrc.\n",
704: stdout) FLUSH;
705: ELSE
706: #endif
707: #ifdef TERSE
708: fputs("Moving boguses to the end.\n",stdout) FLUSH;
709: #endif
710: for (; ngx >= 0; ngx--) {
711: if (toread[ngx] == TR_BOGUS)
712: relocate_newsgroup(ngx,nextrcline-1);
713: }
714: #ifdef DELBOGUS
715: reask_bogus:
716: in_char("Delete bogus newsgroups? [ny] ", 'D');
717: putchar('\n') FLUSH;
718: setdef(buf,"n");
719: #ifdef VERIFY
720: printcmd();
721: #endif
722: if (*buf == 'h') {
723: #ifdef VERBOSE
724: IF(verbose)
725: fputs("\
726: Type y to delete bogus newsgroups.\n\
727: Type n or SP to leave them at the end in case they return.\n\
728: ",stdout) FLUSH;
729: ELSE
730: #endif
731: #ifdef TERSE
732: fputs("y to delete, n to keep\n",stdout) FLUSH;
733: #endif
734: goto reask_bogus;
735: }
736: else if (*buf == 'n' || *buf == 'q')
737: ;
738: else if (*buf == 'y') {
739: while (toread[nextrcline-1] == TR_BOGUS && nextrcline > 0)
740: --nextrcline; /* real tough, huh? */
741: }
742: else {
743: fputs(hforhelp,stdout) FLUSH;
744: settle_down();
745: goto reask_bogus;
746: }
747: #endif
748: }
749: #else
750: #ifdef VERBOSE
751: IF(verbose)
752: fputs("You should edit bogus newsgroups out of your .newsrc.\n",
753: stdout) FLUSH;
754: ELSE
755: #endif
756: #ifdef TERSE
757: fputs("Edit boguses from .newsrc.\n",stdout) FLUSH;
758: #endif
759: #endif
760: paranoid = FALSE;
761: }
762:
763: #ifdef HASHNG
764: /* make an entry in the hash table for the current newsgroup */
765:
766: void
767: sethash(thisng)
768: NG_NUM thisng;
769: {
770: register int hashix = hash(rcline[thisng]);
771: register int incr = 1;
772: #ifdef DEBUGGING
773: static int hashhits = 0, hashtries = 0;
774: #endif
775:
776: #ifdef DEBUGGING
777: hashtries++;
778: #endif
779: while (hashtbl[hashix] >= 0) {
780: #ifdef DEBUGGING
781: hashhits++;
782: if (debug & DEB_HASH) {
783: printf(" Hash hits: %d / %d\n",hashhits, hashtries) FLUSH;
784: }
785: hashtries++;
786: #endif
787: hashix = (hashix + incr) % HASHSIZ;
788: incr += 2; /* offsets from original are in n*2 */
789: }
790: hashtbl[hashix] = thisng;
791: }
792:
793: short prime[] = {1,2,-3,-5,7,11,-13,-17,19,23,-29,-31,37,41,-43,-47,53,57,-59,
794: -61,67,71,-73,-79,83,89,-97,-101,1,1,1,1,1,1,1,1,1,1,1,1};
795:
796: int
797: hash(ngnam)
798: register char *ngnam;
799: {
800: register int i = 0;
801: register int ch;
802: register int sum = 0;
803: #ifdef DEBUGGING
804: char *ngn = ngnam;
805: #endif
806:
807: while (ch = *ngnam++) {
808: sum += (ch + i) * prime[i]; /* gives ~ 10% hits at 25% full */
809: i++;
810: }
811: #ifdef DEBUGGING
812: if (debug & DEB_HASH)
813: printf("hash(%s) => %d => %d\n",ngn, sum, (sum<0?-sum:sum)%HASHSIZ)
814: FLUSH;
815: #endif
816: if (sum < 0)
817: sum = -sum;
818: return sum % HASHSIZ;
819: }
820:
821: #endif
822:
823: void
824: newsrc_check()
825: {
826: rcfp = fopen(rcname,"r"); /* open it */
827: if (rcfp == Nullfp) { /* not there? */
828: #ifdef VERBOSE
829: IF(verbose)
830: fputs("\
831: Trying to set up a .newsrc file--running newsetup...\n\n\
832: ",stdout) FLUSH;
833: ELSE
834: #endif
835: #ifdef TERSE
836: fputs("Setting up .newsrc...\n",stdout) FLUSH;
837: #endif
838: if (doshell(sh,filexp(NEWSETUP)) ||
839: (rcfp = fopen(rcname,"r")) == Nullfp) {
840: #ifdef VERBOSE
841: IF(verbose)
842: fputs("\
843: Can't create a .newsrc--you must do it yourself.\n\
844: ",stdout) FLUSH;
845: ELSE
846: #endif
847: #ifdef TERSE
848: fputs("(Fatal)\n",stdout) FLUSH;
849: #endif
850: finalize(1);
851: }
852: }
853: else {
854: UNLINK(rcbname); /* unlink backup file name */
855: link(rcname,rcbname); /* and backup current name */
856: }
857: }
858:
859: /* write out the (presumably) revised .newsrc */
860:
861: void
862: write_rc()
863: {
864: register NG_NUM tmpng;
865: register char *delim;
866:
867: rcfp = fopen(rctname, "w"); /* open .newsrc */
868: if (rcfp == Nullfp) {
869: printf("Can't recreate .newsrc\n") FLUSH;
870: finalize(1);
871: }
872:
873: /* write out each line*/
874:
875: for (tmpng = 0; tmpng < nextrcline; tmpng++) {
876: if (rcnums[tmpng]) {
877: delim = rcline[tmpng] + rcnums[tmpng] - 1;
878: *delim = rcchar[tmpng];
879: }
880: else
881: delim = Nullch;
882: #ifdef DEBUGGING
883: if (debug & DEB_NEWSRC_LINE)
884: printf("%s\n",rcline[tmpng]) FLUSH;
885: #endif
886: fprintf(rcfp,"%s\n",rcline[tmpng]);
887: if (delim)
888: *delim = '\0'; /* might still need this line */
889: }
890:
891: fclose(rcfp); /* close .newsrc */
892: UNLINK(rcname);
893: link(rctname,rcname);
894: UNLINK(rctname);
895:
896: if (writesoft) {
897: tmpfp = fopen(filexp(softname), "w"); /* open .rnsoft */
898: if (tmpfp == Nullfp) {
899: printf(cantcreate,filexp(softname)) FLUSH;
900: return;
901: }
902: for (tmpng = 0; tmpng < nextrcline; tmpng++) {
903: fprintf(tmpfp,"%ld\n",(long)softptr[tmpng]);
904: }
905: fclose(tmpfp);
906: }
907: }
908:
909: void
910: get_old_rc()
911: {
912: UNLINK(rctname);
913: link(rcname,rctname);
914: UNLINK(rcname);
915: link(rcbname,rcname);
916: UNLINK(rcbname);
917: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.