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