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