📄 rcstuff.c
字号:
/* $Id: rcstuff.c,v 3.0 1992/02/01 03:09:32 davison Trn $ *//* This software is Copyright 1991 by Stan Barber. * * Permission is hereby granted to copy, reproduce, redistribute or otherwise * use this software as long as: there is no monetary profit gained * specifically from the use or reproduction of this software, it is not * sold, rented, traded or otherwise marketed, and this copyright notice is * included prominently in any copy made. * * The author make no claims as to the fitness or correctness of this software * for any use whatsoever, and it is provided as is. Any use of this software * is at the user's own risk. */#include "EXTERN.h"#include "common.h"#include "util.h"#include "cache.h"#include "bits.h"#include "ngdata.h"#include "term.h"#include "final.h"#include "trn.h"#include "intrp.h"#include "only.h"#include "rcln.h"#include "nntp.h"#include "autosub.h"#include "hash.h"#include "INTERN.h"#include "rcstuff.h"char *rcname INIT(Nullch); /* path name of .newsrc file */char *rctname INIT(Nullch); /* path name of temp .newsrc file */char *rcbname INIT(Nullch); /* path name of backup .newsrc file */char *softname INIT(Nullch); /* path name of .rnsoft file */FILE *rcfp INIT(Nullfp); /* .newsrc file pointer */static void grow_rc_arrays _((int));static void parse_rcline _((NG_NUM));#ifdef HASHNGstatic HASHTABLE *rc_hash;static int rcline_cmp _((char*,int,HASHDATUM));static void del_rc_line _((HASHDATUM*,int));static void ins_rc_line _((HASHDATUM*,int));#endifboolrcstuff_init(){ register NG_NUM newng; register int i; register bool foundany = FALSE; char *some_buf; long length;#ifdef USE_NNTP char *cp;#endif /* make filenames */#ifdef USE_NNTP if (cp = getenv("NEWSRC")) rcname = savestr(filexp(cp)); else rcname = savestr(filexp(RCNAME));#else rcname = savestr(filexp(RCNAME));#endif rctname = savestr(filexp(RCTNAME)); rcbname = savestr(filexp(RCBNAME)); softname = savestr(filexp(SOFTNAME)); /* make sure the .newsrc file exists */ newsrc_check(); /* open .rnsoft file containing soft ptrs to active file */ tmpfp = fopen(softname,"r"); if (tmpfp == Nullfp) writesoft = TRUE; /* allocate memory for rc file globals */ grow_rc_arrays(1500); /* read in the .newsrc file */ for (nextrcline = 0; (some_buf = get_a_line(buf,LBUFLEN,rcfp)) != Nullch; nextrcline++) /* for each line in .newsrc */ { char tmpbuf[10]; newng = nextrcline; /* get it into a register */ length = len_last_line_got; /* side effect of get_a_line */ if (length <= 1) { /* only a newline??? */ nextrcline--; /* compensate for loop increment */ continue; } if (newng >= maxrcline) /* check for overflow */ grow_rc_arrays(maxrcline + 500); if (tmpfp != Nullfp && fgets(tmpbuf,10,tmpfp) != Nullch) softptr[newng] = atol(tmpbuf); else softptr[newng] = 0; some_buf[--length] = '\0'; /* wipe out newline */ if (checkflag) /* no extra mallocs for -c */ rcline[newng] = some_buf; else if (some_buf == buf) rcline[newng] = savestr(some_buf); /* make semipermanent copy */ else { /*NOSTRICT*/#ifndef lint some_buf = saferealloc(some_buf,(MEM_SIZE)(length+1));#endif rcline[newng] = some_buf; } if (*some_buf == ' ' || *some_buf == '\t' || strnEQ(some_buf,"options",7)) { /* non-useful line? */ toread[newng] = TR_JUNK; rcchar[newng] = ' '; rcnums[newng] = 0; continue; } parse_rcline(newng); if (rcchar[newng] == NEGCHAR) { toread[newng] = TR_UNSUB; continue; } /* now find out how much there is to read */ if (!inlist(buf) || (suppress_cn && foundany && !paranoid)) toread[newng] = TR_NONE; /* no need to calculate now */ else set_toread(newng);#ifdef VERBOSE if (!checkflag && softmisses == 1) { softmisses++; /* lie a little */ fputs("(Revising soft pointers -- be patient.)\n",stdout) FLUSH; }#endif if (toread[newng] > TR_NONE) { /* anything unread? */ if (!foundany) { starthere = newng; foundany = TRUE; /* remember that fact*/ } if (suppress_cn) { /* if no listing desired */ if (checkflag) { /* if that is all they wanted */ finalize(1); /* then bomb out */ } } else {#ifdef VERBOSE IF(verbose) printf("Unread news in %-40s %5ld article%s\n", rcline[newng],(long)toread[newng], toread[newng]==TR_ONE ? nullstr : "s") FLUSH; ELSE#endif#ifdef TERSE printf("%s: %ld article%s\n", rcline[newng],(long)toread[newng], toread[newng]==TR_ONE ? nullstr : "s") FLUSH;#endif if (int_count) { countdown = 1; int_count = 0; } if (countdown) { if (!--countdown) { fputs("etc.\n",stdout) FLUSH; if (checkflag) finalize(1); suppress_cn = TRUE; } } } } } fclose(rcfp); /* close .newsrc */ if (tmpfp != Nullfp) fclose(tmpfp); /* close .rnsoft */ if (checkflag) /* were we just checking? */ finalize(foundany); /* tell them what we found */ if (paranoid) cleanup_rc();#ifdef HASHNG rc_hash = hashcreate((int)nextrcline, rcline_cmp); for (i = 0; i < nextrcline; i++) if (toread[i] >= TR_UNSUB) sethash(i);#endif return foundany;}static voidparse_rcline(ngnum)NG_NUM ngnum;{ char *s; for (s = rcline[ngnum]; *s && *s != ':' && *s != NEGCHAR; s++) ; if (!*s && !checkflag) {#ifndef lint rcline[ngnum] = saferealloc(rcline[ngnum], (MEM_SIZE)(s - rcline[ngnum]) + 3);#endif /* lint */ strcpy(s, ": "); } if (*s == ':' && s[1] && s[2] == '0') { rcchar[ngnum] = '0'; s[2] = '1'; } else rcchar[ngnum] = *s; /* salt away the : or ! */ rcnums[ngnum] = (char)(s - rcline[ngnum]) + 1; /* remember where the numbers are */ *s = '\0'; /* null terminate newsgroup name */}voidabandon_ng(ngnum)NG_NUM ngnum;{ char *some_buf = Nullch; /* open .oldnewsrc and try to find the prior value for the group. */ if ((rcfp = fopen(rcbname, "r")) != Nullfp) { int length = rcnums[ngnum] - 1; while ((some_buf = get_a_line(buf,LBUFLEN,rcfp)) != Nullch) { if (len_last_line_got <= 0) continue; some_buf[len_last_line_got-1] = '\0'; /* wipe out newline */ if ((some_buf[length] == ':' || some_buf[length] == NEGCHAR) && strnEQ(rcline[ngnum], some_buf, length)) { break; } if (some_buf != buf) free(some_buf); } fclose(rcfp); } else if (errno != ENOENT) { printf("Unable to open %s.\n", rcbname) FLUSH; return; } if (some_buf == Nullch) { some_buf = rcline[ngnum] + rcnums[ngnum]; if (*some_buf == ' ') some_buf++; *some_buf = '\0'; abs1st[ngnum] = 0; /* force group to be re-calculated */ } else { free(rcline[ngnum]); if (some_buf == buf) { rcline[ngnum] = savestr(some_buf); } else { /*NOSTRICT*/#ifndef lint some_buf = saferealloc(some_buf, (MEM_SIZE)(len_last_line_got));#endif /* lint */ rcline[ngnum] = some_buf; } } parse_rcline(ngnum); if (rcchar[ngnum] == NEGCHAR) rcchar[ngnum] = ':'; set_toread(ngnum);}/* try to find or add an explicitly specified newsgroup *//* returns TRUE if found or added, FALSE if not. *//* assumes that we are chdir'ed to NEWSSPOOL */boolget_ng(what,flags)char *what;int flags;{ char *ntoforget; char promptbuf[128]; int autosub;#ifdef VERBOSE IF(verbose) ntoforget = "Type n to forget about this newsgroup.\n"; ELSE#endif#ifdef TERSE ntoforget = "n to forget it.\n";#endif if (index(what,'/')) { dingaling(); printf("\nBad newsgroup name.\n") FLUSH; check_fuzzy_match: if (fuzzyGet && (flags & GNG_FUZZY)) { if (find_close_match()) what = ngname; else return FALSE; } else return FALSE; } set_ngname(what); ng = find_ng(ngname); if (ng == nextrcline) { /* not in .newsrc? */ if (ng >= maxrcline) /* check for overflow */ grow_rc_arrays(maxrcline + 25);#ifdef USE_NNTP softptr[ng] = 0; if (!nntp_group(ngname))#else /* !USE_NNTP */ if ((softptr[ng] = findact(buf,ngname,strlen(ngname),0L)) < 0)#endif /* !USE_NNTP */ { dingaling();#ifdef VERBOSE IF(verbose) printf("\nNewsgroup %s does not exist!\n",ngname) FLUSH; ELSE#endif#ifdef TERSE printf("\nNo %s!\n",ngname) FLUSH;#endif if (novice_delays) sleep(2); goto check_fuzzy_match; } autosub = auto_subscribe(ngname); if (!autosub) autosub = addnewbydefault; if (autosub) { if (append_unsub) { printf("(Adding %s to end of your .newsrc %ssubscribed)\n", ngname, (autosub == ADDNEW_SUB) ? "" : "un") FLUSH; ng = add_newsgroup(ngname, autosub); } else { if (autosub == ADDNEW_SUB) { printf("(Subscribing to %s)\n", ngname) FLUSH; ng = add_newsgroup(ngname, autosub); } else { printf("(Ignoring %s)\n", ngname) FLUSH; return FALSE; } } flags &= ~GNG_RELOC; } else {#ifdef VERBOSE IF(verbose) sprintf(promptbuf,"\nNewsgroup %s not in .newsrc -- subscribe? [ynYN] ",ngname); ELSE#endif#ifdef TERSE sprintf(promptbuf,"\nSubscribe %s? [ynYN] ",ngname);#endifreask_add: in_char(promptbuf,'A'); setdef(buf,"y");#ifdef VERIFY printcmd();#endif putchar('\n') FLUSH; if (*buf == 'h') {#ifdef VERBOSE IF(verbose) printf("Type y or SP to subscribe to %s.\n\Type Y to subscribe to this and all remaining new groups.\n\Type N to leave all remaining new groups unsubscribed.\n", ngname) FLUSH; ELSE#endif#ifdef TERSE fputs("y or SP to subscribe, Y to subscribe all new groups, N to unsubscribe all\n",stdout) FLUSH;#endif fputs(ntoforget,stdout) FLUSH; goto reask_add; } else if (*buf == 'n' || *buf == 'q') { if (append_unsub) { ng = add_newsgroup(ngname, NEGCHAR); } return FALSE; } else if (*buf == 'y') { ng = add_newsgroup(ngname, ':'); flags |= GNG_RELOC; } else if (*buf == 'Y') { addnewbydefault = ADDNEW_SUB; if (append_unsub) printf("(Adding %s to end of your .newsrc subscribed)\n", ngname) FLUSH; else printf("(Subscribing to %s)\n", ngname) FLUSH; ng = add_newsgroup(ngname, ':'); flags &= ~GNG_RELOC; } else if (*buf == 'N') { addnewbydefault = ADDNEW_UNSUB; if (append_unsub) { printf("(Adding %s to end of your .newsrc unsubscribed)\n", ngname) FLUSH; ng = add_newsgroup(ngname, NEGCHAR); flags &= ~GNG_RELOC; } else { printf("(Ignoring %s)\n", ngname) FLUSH; return FALSE; } } else { fputs(hforhelp,stdout) FLUSH; settle_down(); goto reask_add; } } } else if (mode == 'i') /* adding new groups during init? */ return FALSE; else if (rcchar[ng] == NEGCHAR) { /* unsubscribed? */#ifdef VERBOSE IF(verbose) sprintf(promptbuf,"\nNewsgroup %s is unsubscribed -- resubscribe? [yn] ",ngname) FLUSH; ELSE#endif#ifdef TERSE sprintf(promptbuf,"\nResubscribe %s? [yn] ",ngname) FLUSH;#endifreask_unsub: in_char(promptbuf,'R'); setdef(buf,"y");#ifdef VERIFY printcmd();#endif putchar('\n') FLUSH; if (*buf == 'h') {#ifdef VERBOSE IF(verbose) printf("Type y or SP to resubscribe to %s.\n", ngname) FLUSH; ELSE#endif#ifdef TERSE fputs("y or SP to resubscribe.\n",stdout) FLUSH;#endif fputs(ntoforget,stdout) FLUSH; goto reask_unsub; } else if (*buf == 'n' || *buf == 'q') { return FALSE; } else if (*buf == 'y') { register char *cp = rcline[ng] + rcnums[ng]; rcchar[ng] = (*cp && cp[1] == '0' ? '0' : ':'); flags &= ~GNG_RELOC; } else { fputs(hforhelp,stdout) FLUSH; settle_down(); goto reask_unsub; } } /* now calculate how many unread articles in newsgroup */ set_toread(ng);#ifdef RELOCATE if (flags & GNG_RELOC) { ng = relocate_newsgroup(ng,-1); if (ng < 0) return FALSE; }#endif return toread[ng] >= TR_NONE;}/* add a newsgroup to the .newsrc file (eventually) */NG_NUMadd_newsgroup(ngn, c)char *ngn;char_int c;{ register NG_NUM newng = nextrcline++; /* increment max rcline index */ if (newng >= maxrcline) /* check for overflow */ grow_rc_arrays(maxrcline + 25); rcnums[newng] = strlen(ngn) + 1; rcline[newng] = safemalloc((MEM_SIZE)(rcnums[newng] + 2)); strcpy(rcline[newng],ngn); /* and copy over the name */ strcpy(rcline[newng]+rcnums[newng], " "); rcchar[newng] = c; /* subscribe or unsubscribe */ toread[newng] = TR_NONE; /* just for prettiness */#ifdef HASHNG sethash(newng); /* so we can find it again */#endif return newng;}#ifdef RELOCATENG_NUMrelocate_newsgroup(ngx,newng)NG_NUM ngx;NG_NUM newng;{ char *dflt = (ngx!=current_ng ? "$^.Lq" : "$^Lq"); char *tmprcline; ART_UNREAD tmptoread; char tmprcchar; char tmprcnums; ACT_POS tmpsoftptr; register NG_NUM i; ART_NUM tmpngmax; ART_NUM tmpabs1st; starthere = 0; /* Disable this optimization */ writesoft = TRUE; /* Update soft pointer file */ if (ngx < nextrcline-1) {#ifdef HASHNG if (rc_hash) hashwalk(rc_hash, del_rc_line, ngx);#endif tmprcline = rcline[ngx]; tmptoread = toread[ngx]; tmprcchar = rcchar[ngx];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -