home *** CD-ROM | disk | FTP | other *** search
- From: sob@lib.tmc.edu (Stan Barber)
- Newsgroups: alt.sources
- Subject: rn/rrn combo kit part 5 of 9
- Message-ID: <431@lib.tmc.edu>
- Date: 14 Jun 90 03:28:04 GMT
-
- #! /bin/sh
-
- # Make a new directory for the rn sources, cd to it, and run kits 1 thru 9
- # through sh. When all 9 kits have been run, read README.
-
- echo "This is rn kit 5 (of 9). If kit 5 is complete, the line"
- echo '"'"End of kit 5 (of 9)"'" will echo at the end.'
- echo ""
- export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
- echo Extracting art.c
- cat >art.c <<'!STUFFY!FUNK!'
- /* $Header: art.c,v 4.3.2.3 90/04/21 14:43:27 sob Exp $
- *
- * $Log: art.c,v $
- * Revision 4.3.2.3 90/04/21 14:43:27 sob
- * Revised previous patch insure that it does not decrement below zero.
- *
- * Revision 4.3.2.2 90/03/22 23:03:25 sob
- * Fixes provided by Wayne Davison <drivax!davison>
- *
- * Revision 4.3.2.1 89/11/07 23:20:57 sob
- * Bug fixes for NNTP
- *
- * Revision 4.3.1.5 85/09/10 11:07:18 lwall
- * %m not restored on some returns.
- *
- * Revision 4.3.1.4 85/05/23 12:13:31 lwall
- * shouldn't display article that's really a subdirectory.
- *
- * Revision 4.3.1.3 85/05/13 09:29:55 lwall
- * Added CUSTOMLINES option.
- *
- * Revision 4.3.1.2 85/05/10 13:46:07 lwall
- * Fixed header reparse bug on backpage.
- *
- * Revision 4.3.1.1 85/05/10 11:30:56 lwall
- * Branch for patches.
- *
- * Revision 4.3 85/05/01 11:34:51 lwall
- * Baseline for release with 4.3bsd.
- *
- */
-
- #include "EXTERN.h"
- #include "common.h"
- #include "rn.h"
- #include "ngstuff.h"
- #include "ngdata.h"
- #include "head.h"
- #include "cheat.h"
- #include "help.h"
- #include "search.h"
- #include "artio.h"
- #include "ng.h"
- #include "bits.h"
- #include "final.h"
- #include "artstate.h"
- #include "rcstuff.h"
- #include "term.h"
- #include "sw.h"
- #include "util.h"
- #include "backpage.h"
- #include "intrp.h"
- #include "INTERN.h"
- #include "art.h"
-
- /* page_switch() return values */
-
- #define PS_NORM 0
- #define PS_ASK 1
- #define PS_RAISE 2
- #define PS_TOEND 3
-
- bool special = FALSE; /* is next page special length? */
- int slines = 0; /* how long to make page when special */
- ART_LINE highlight = -1; /* next line to be highlighted */
- char *restart = Nullch; /* if nonzero, the place where last */
- /* line left off on line split */
- char *blinebeg; /* where in buffer current line began */
- ART_POS alinebeg; /* where in file current line began */
-
- #ifdef INNERSEARCH
- ART_POS innersearch = 0; /* artpos of end of line we found */
- /* for 'g' command */
- ART_LINE isrchline = 0; /* last line to display */
- bool hide_everything = FALSE;
- /* if set, do not write page now, */
- /* but refresh when done with page */
- COMPEX gcompex; /* in article search pattern */
- #endif
-
- bool firstpage; /* is this the 1st page of article? */
-
- char art_buf[LBUFLEN]; /* place for article lines */
-
- void
- art_init()
- {
- ;
- }
-
- int
- do_article()
- {
- register char *s;
- ART_POS artsize; /* size in bytes of article */
- bool hide_this_line = FALSE; /* hidden header line? */
- ART_LINE linenum; /* line # on page, 1 origin */
- #ifdef ULSMARTS
- bool under_lining = FALSE;
- /* are we underlining a word? */
- #endif
- register char *bufptr = art_buf;
- /* pointer to input buffer */
- register int outpos; /* column position of output */
- static char prompt_buf[64]; /* place to hold prompt */
- bool notesfiles = FALSE; /* might there be notesfiles junk? */
- char oldmode = mode;
-
- #ifdef INNERSEARCH
- register int outputok;
- #endif
-
- if (fstat(artfp->_file,&filestat))
- /* get article file stats */
- return DA_CLEAN;
- if ((filestat.st_mode & S_IFMT) != S_IFREG)
- return DA_NORM;
- artsize = filestat.st_size;
- /* from that get article size */
- sprintf(prompt_buf,
- "%%sEnd of article %ld (of %ld)--what next? [%%s]",
- (long)art,(long)lastart); /* format prompt string */
- prompt = prompt_buf;
- int_count = 0; /* interrupt count is 0 */
- firstpage = (topline < 0);
- for (;;) { /* for each page */
- assert(art == openart);
- if (do_fseek) {
- #ifdef ASYNC_PARSE
- parse_maybe(art); /* make sure header is ours */
- #endif
- artpos = vrdary(artline);
- if (artpos < 0)
- artpos = -artpos; /* labs(), anyone? */
- if (firstpage)
- artpos = (ART_POS)0;
- fseek(artfp,artpos,0);
- if (artpos < htype[PAST_HEADER].ht_minpos)
- in_header = SOME_LINE;
- do_fseek = FALSE;
- restart = Nullch;
- }
- if (firstpage) {
- if (firstline) {
- interp(art_buf, (sizeof art_buf), firstline);
- #ifdef CLEAREOL
- maybe_eol();
- #endif CLEAREOL
- fputs(art_buf,stdout) FLUSH;
- artopen(art); /* rewind article in case interp */
- /* forced a header parse */
- }
- else {
- ART_NUM i;
-
- #ifdef CLEAREOL
- maybe_eol();
- #endif CLEAREOL
- printf("Article %ld",(long)art);
- i = (((ART_NUM)toread[ng]) - 1 + was_read(art));
- #ifdef DELAYMARK
- if (i || dmcount) {
- printf(" (%ld more",(long)i);
- if (dmcount)
- printf(" + %ld Marked to return)",(long)dmcount);
- putchar(')');
- }
- #else
- if (i)
- printf(" (%ld more)",(long)i);
- #endif
- if (htype[NGS_LINE].ht_flags & HT_HIDE)
- printf(" in %s", ngname);
- fputs(moderated,stdout);
- fputs(":\n",stdout) FLUSH;
- }
- start_header(art);
- forcelast = FALSE; /* we will have our day in court */
- restart = Nullch;
- artline = 0; /* start counting lines */
- artpos = 0;
- vwtary(artline,artpos); /* remember pos in file */
- }
- for (linenum=(firstpage?2:1);
- in_header || (
- #ifdef INNERSEARCH
- innersearch ? innermore() :
- #endif
- linenum<(firstpage?initlines:(special?slines:LINES)) );
- linenum++) { /* for each line on page */
- if (int_count) { /* exit via interrupt? */
- putchar('\n') FLUSH; /* get to left margin */
- int_count = 0; /* reset interrupt count */
- mode = oldmode;
- return DA_NORM; /* skip out of loops */
- }
- if (restart) { /* did not finish last line? */
- bufptr = restart; /* then start again here */
- restart = Nullch; /* and reset the flag */
- }
- else { /* not a restart */
- if (fgets(art_buf,LBUFLEN,artfp)==Nullch) {
- /* if all done */
- mode = oldmode;
- return DA_NORM; /* skip out of loops */
- }
- bufptr = art_buf; /* so start at beginning */
- art_buf[LBUFLEN-1] = '\0';
- /* make sure string ends */
- }
- blinebeg = bufptr; /* remember where we began */
- alinebeg = artpos; /* both in buffer and file */
- if (in_header && bufptr == art_buf)
- hide_this_line =
- parseline(art_buf,do_hiding,hide_this_line);
- else if (notesfiles && do_hiding &&
- bufptr == art_buf && *art_buf == '#' &&
- isupper(art_buf[1]) && art_buf[2] == ':' ) {
- fgets(art_buf,sizeof(art_buf),artfp);
- if (index(art_buf,'!') != Nullch)
- fgets(art_buf,sizeof(art_buf),artfp);
- htype[PAST_HEADER].ht_minpos = ftell(artfp);
- /* exclude notesfiles droppings */
- hide_this_line = TRUE; /* and do not print either */
- notesfiles = FALSE;
- }
- #ifdef CUSTOMLINES
- if (hideline && bufptr == art_buf &&
- execute(&hide_compex,art_buf) )
- hide_this_line = TRUE;
- #endif
- if (in_header && htype[in_header].ht_flags & HT_MAGIC) {
- if (in_header == NGS_LINE) {
- hide_this_line = (index(art_buf,',') == Nullch);
- }
- else if (in_header == EXPIR_LINE) {
- if (!(htype[EXPIR_LINE].ht_flags & HT_HIDE))
- hide_this_line = (strlen(art_buf) < 10);
- }
- }
- if (in_header == SUBJ_LINE &&
- htype[SUBJ_LINE].ht_flags & HT_MAGIC) {
- /* is this the subject? */
- int length;
-
- length = strlen(art_buf)-1;
- artline++;
- art_buf[length] = '\0'; /* wipe out newline */
- #ifdef NOFIREWORKS
- no_ulfire();
- #endif
- notesfiles =
- (instr(&art_buf[length-10]," - (nf") != Nullch);
- if (oldsubject) {
- length += 7;
- fputs("(SAME) ",stdout);
- oldsubject = FALSE;
- }
- if (length+UG > COLS) { /* rarely true */
- linenum++;
- vwtary(artline,vrdary(artline-1)+COLS);
- artline++;
- }
- s = art_buf + 8;
- *s++ = '\0'; /* make into 2 strings */
- #ifdef CLEAREOL
- maybe_eol();
- #endif CLEAREOL
- fputs(art_buf,stdout) FLUSH;
- /* print up through : */
- if (!UG)
- putchar(' ');
- underprint(s); /* print subject underlined */
- putchar('\n') FLUSH; /* and finish the line */
- }
- else if (hide_this_line && do_hiding) {
- /* do not print line? */
- linenum--; /* compensate for linenum++ */
- if (!in_header)
- hide_this_line = FALSE;
- }
- else { /* just a normal line */
- if (highlight==artline) { /* this line to be highlit? */
- if (marking == STANDOUT) {
- #ifdef NOFIREWORKS
- if (erase_screen)
- no_sofire();
- #endif
- standout();
- }
- else {
- #ifdef NOFIREWORKS
- if (erase_screen)
- no_ulfire();
- #endif
- underline();
- }
- if (*bufptr == '\n')
- putchar(' ');
- }
- #ifdef INNERSEARCH
- outputok = !hide_everything;
- /* get it into register, hopefully */
- #endif
- #ifdef CLEAREOL
- #ifdef INNERSEARCH
- if (outputok)
- #endif
- maybe_eol();
- #endif CLEAREOL
- #ifdef CUSTOMLINES
- if (pagestop && bufptr == art_buf &&
- execute(&page_compex,art_buf) )
- linenum = 32700;
- #endif
- for (outpos = 0; outpos < COLS; ) {
- /* while line has room */
- if (*bufptr >= ' ') { /* normal char? */
- #ifdef ULSMARTS
- if (*bufptr == '_') {
- if (bufptr[1] == '\b') {
- if (!under_lining && highlight!=artline
- #ifdef INNERSEARCH
- && outputok
- #endif
- ) {
- under_lining++;
- if (UG) {
- if (bufptr != buf &&
- bufptr[-1] == ' ') {
- outpos--;
- backspace();
- }
- }
- underline();
- }
- bufptr += 2;
- }
- }
- else {
- if (under_lining) {
- under_lining = 0;
- un_underline();
- if (UG) {
- if (*bufptr == ' ')
- goto skip_put;
- outpos++;
- }
- }
- }
- #endif
- #ifdef INNERSEARCH
- if (outputok)
- #endif
- {
- #ifdef ROTATION
- if (rotate && !in_header
- && isalpha(*bufptr)) {
- if ((*bufptr & 31) <= 13)
- putchar(*bufptr+13);
- else
- putchar(*bufptr-13);
- }
- else
- #endif
- putchar(*bufptr);
- }
- if (*UC && ((highlight==artline && marking == 1)
- #ifdef ULSMARTS
- || under_lining
- #endif
- )) {
- backspace();
- underchar();
- }
- skip_put:
- bufptr++;
- outpos++;
- }
- else if (*bufptr == '\n' || !*bufptr) {
- /* newline? */
- #ifdef ULSMARTS
- if (under_lining) {
- under_lining = 0;
- un_underline();
- }
- #endif
- #ifdef DEBUGGING
- if (debug & DEB_INNERSRCH && outpos < COLS - 6) {
- standout();
- printf("%4d",artline);
- un_standout();
- }
- #endif
- #ifdef INNERSEARCH
- if (outputok)
- #endif
- putchar('\n') FLUSH;
- restart = 0;
- outpos = 1000; /* signal normal \n */
- }
- else if (*bufptr == '\t') { /* tab? */
- #ifdef INNERSEARCH
- if (outputok)
- #endif
- putchar(*bufptr);
- bufptr++;
- outpos += 8 - outpos % 8;
- }
- else if (*bufptr == '\f') { /* form feed? */
- #ifdef INNERSEARCH
- if (outputok)
- #endif
- fputs("^L",stdout);
- if (bufptr == blinebeg && highlight != artline)
- linenum = 32700;
- /* how is that for a magic number? */
- bufptr++;
- outpos += 2;
- }
- else { /* other control char */
- #ifdef INNERSEARCH
- if (outputok)
- #endif
- {
- putchar('^');
- if (highlight == artline && *UC && marking == 1) {
- backspace();
- underchar();
- putchar(*bufptr+64);
- backspace();
- underchar();
- }
- else
- putchar(*bufptr+64);
- }
- bufptr++;
- outpos += 2;
- }
-
- } /* end of column loop */
-
- if (outpos < 1000) {/* did line overflow? */
- restart = bufptr;
- /* restart here next time */
- if (AM) { /* automatic margins on tty? */
- if (!XN && *bufptr == '\n')
- /* need we simulate XN? */
- restart = 0;
- /* skip the newline */
- }
- else { /* cursor just hangs there */
- #ifdef INNERSEARCH
- if (outputok)
- #endif
- putchar('\n') FLUSH;
- /* so move it down ourselves */
- if (*bufptr == '\n')
- restart = 0;
- /* simulate XN if need be */
- }
- #ifdef CLEAREOL
- /* #ifdef INNERSEARCH
- if (outputok)
- #endif
- maybe_eol(); */ /* comment this out for now
- until I am sure it is
- needed*/
-
- #endif CLEAREOL
- }
-
- /* handle normal end of output line formalities */
-
- if (highlight == artline) {
- /* were we highlighting line? */
- if (marking == STANDOUT)
- un_standout();
- else
- un_underline();
- highlight = -1; /* no more we are */
- }
- artline++; /* count the line just printed */
- if (artline - LINES + 1 > topline)
- /* did we just scroll top line off? */
- topline = artline - LINES + 1;
- /* then recompute top line # */
- }
-
- /* determine actual position in file */
-
- if (restart) /* stranded somewhere in the buffer? */
- artpos += restart - blinebeg;
- /* just calculate position */
- else /* no, ftell will do */
- artpos = ftell(artfp);
- /* so do ftell */
- vwtary(artline,artpos); /* remember pos in file */
- } /* end of line loop */
-
- #ifdef INNERSEARCH
- innersearch = 0;
- if (hide_everything) {
- hide_everything = FALSE;
- *buf = Ctl('l');
- goto fake_command;
- }
- #endif
- if (linenum >= 32700)/* did last line have formfeed? */
- vwtary(artline-1,-vrdary(artline-1));
- /* remember by negating pos in file */
-
- special = FALSE; /* end of page, so reset page length */
- firstpage = FALSE; /* and say it is not 1st time thru */
-
- /* extra loop bombout */
-
- if (artpos == artsize) {/* did we just now reach EOF? */
- mode = oldmode;
- return DA_NORM; /* avoid --MORE--(100%) */
- }
-
- /* not done with this article, so pretend we are a pager */
-
- reask_pager:
- unflush_output(); /* disable any ^O in effect */
- standout(); /* enter standout mode */
- printf("--MORE--(%ld%%)",(long)(artpos*100/artsize));
- un_standout(); /* leave standout mode */
- fflush(stdout);
- /* reinp_pager: /* unused, commented for lint */
- eat_typeahead();
- #ifdef DEBUGGING
- if (debug & DEB_CHECKPOINTING) {
- printf("(%d %d %d)",checkcount,linenum,artline);
- fflush(stdout);
- }
- #endif
- if (checkcount >= docheckwhen &&
- linenum == LINES &&
- (artline > 40 || checkcount >= docheckwhen+10) ) {
- /* while he is reading a whole page */
- /* in an article he is interested in */
- checkcount = 0;
- checkpoint_rc(); /* update .newsrc */
- }
- collect_subjects(); /* loads subject cache until */
- /* input is pending */
- mode = 'p';
- getcmd(buf);
- if (errno) {
- if (LINES < 100 && !int_count)
- *buf = '\f';/* on CONT fake up refresh */
- else {
- *buf = 'q'; /* on INTR or paper just quit */
- }
- }
- carriage_return();
- #ifndef CLEAREOL
- erase_eol(); /* and erase the prompt */
- #else
- if (erase_screen && can_home_clear)
- clear_rest();
- else
- erase_eol(); /* and erase the prompt */
- #endif CLEAREOL
- carriage_return(); /* Resets kernels tab coloumn counter to 0 */ fflush(stdout);
-
- fake_command: /* used by innersearch */
-
- /* parse and process pager command */
-
- switch (page_switch()) {
- case PS_ASK: /* reprompt "--MORE--..." */
- goto reask_pager;
- case PS_RAISE: /* reparse on article level */
- mode = oldmode;
- return DA_RAISE;
- case PS_TOEND: /* fast pager loop exit */
- mode = oldmode;
- return DA_TOEND;
- case PS_NORM: /* display more article */
- break;
- }
- } /* end of page loop */
- }
-
- /* process pager commands */
-
- int
- page_switch()
- {
- register char *s;
-
- switch (*buf) {
- case 'd':
- case Ctl('d'): /* half page */
- special = TRUE;
- slines = LINES / 2 + 1;
- if (marking && *blinebeg != '\f'
- #ifdef CUSTOMLINES
- && (!pagestop || blinebeg != art_buf ||
- !execute(&page_compex,blinebeg))
- #endif
- ) {
- up_line();
- highlight = --artline;
- restart = blinebeg;
- artpos = alinebeg;
- }
- return PS_NORM;
- case '!': /* shell escape */
- escapade();
- return PS_ASK;
- #ifdef INNERSEARCH
- case Ctl('i'):
- gline = 3;
- sprintf(cmd_buf,"^[^%c]",*blinebeg);
- compile(&gcompex,cmd_buf,TRUE,TRUE);
- goto caseG;
- case Ctl('g'):
- gline = 3;
- compile(&gcompex,"^Subject:",TRUE,TRUE);
- goto caseG;
- case 'g': /* in-article search */
- if (!finish_command(FALSE))/* get rest of command */
- return PS_ASK;
- s = buf+1;
- if (isspace(*s))
- s++;
- if ((s = compile(&gcompex,s,TRUE,TRUE)) != Nullch) {
- /* compile regular expression */
- printf("\n%s\n",s) FLUSH;
- return PS_ASK;
- }
- carriage_return();
- erase_eol(); /* erase the prompt */
- carriage_return(); /* Resets kernels tab coloumn counter to 0 */
- /* FALL THROUGH */
- caseG:
- case 'G': {
- /* ART_LINE lines_to_skip = 0; */
- ART_POS start_where;
-
- if (gline < 0 || gline > LINES-2)
- gline = LINES-2;
- #ifdef DEBUGGING
- if (debug & DEB_INNERSRCH)
- printf("Start here? %d >=? %d\n",topline + gline + 1,artline)
- FLUSH;
- #endif
- if (*buf == Ctl('i') || topline+gline+1 >= artline)
- start_where = artpos;
- /* in case we had a line wrap */
- else {
- start_where = vrdary(topline+gline+1);
- if (start_where < 0)
- start_where = -start_where;
- }
- if (start_where < htype[PAST_HEADER].ht_minpos)
- start_where = htype[PAST_HEADER].ht_minpos;
- fseek(artfp,(long)start_where,0);
- innersearch = 0; /* assume not found */
- while (fgets(buf, sizeof buf, artfp) != Nullch) {
- /* lines_to_skip++; NOT USED NOW */
- #ifdef DEBUGGING
- if (debug & DEB_INNERSRCH)
- printf("Test %s",buf) FLUSH;
- #endif
- if (execute(&gcompex,buf) != Nullch) {
- innersearch = ftell(artfp);
- break;
- }
- }
- if (!innersearch) {
- fseek(artfp,artpos,0);
- fputs("(Not found)",stdout) FLUSH;
- return PS_ASK;
- }
- #ifdef DEBUGGING
- if (debug & DEB_INNERSRCH)
- printf("On page? %ld <=? %ld\n",(long)innersearch,(long)artpos)
- FLUSH;
- #endif
- if (innersearch <= artpos) { /* already on page? */
- if (innersearch < artpos) {
- artline = topline+1;
- while (vrdary(artline) < innersearch)
- artline++;
- }
- highlight = artline - 1;
- #ifdef DEBUGGING
- if (debug & DEB_INNERSRCH)
- printf("@ %d\n",highlight) FLUSH;
- #endif
- topline = highlight - gline;
- if (topline < -1)
- topline = -1;
- *buf = '\f'; /* fake up a refresh */
- innersearch = 0;
- return page_switch();
- }
- else { /* who knows how many lines it is? */
- do_fseek = TRUE;
- hide_everything = TRUE;
- }
- return PS_NORM;
- }
- #else
- case 'g': case 'G': case Ctl('g'):
- notincl("g");
- return PS_ASK;
- #endif
- case '\n': /* one line */
- special = TRUE;
- slines = 2;
- return PS_NORM;
- #ifdef ROTATION
- case 'X':
- rotate = !rotate;
- /* FALL THROUGH */
- #endif
- case 'l':
- case '\f': /* refresh screen */
- #ifdef DEBUGGING
- if (debug & DEB_INNERSRCH) {
- printf("Topline = %d",topline) FLUSH;
- gets(buf);
- }
- #endif
- clear();
- carriage_return(); /* Resets kernels tab coloumn counter to 0 */
- do_fseek = TRUE;
- artline = topline;
- if (artline < 0)
- artline = 0;
- firstpage = (topline < 0);
- return PS_NORM;
- case 'b':
- case '\b':
- case Ctl('b'): { /* back up a page */
- ART_LINE target;
-
- #ifndef CLEAREOL
- clear();
- #else
- if (can_home_clear) /* if we can home do it */
- home_cursor();
- else
- clear();
-
- #endif CLEAREOL
- carriage_return(); /* Resets kernels tab coloumn counter to 0 */
- do_fseek = TRUE; /* reposition article file */
- target = topline - (LINES - 2);
- artline = topline;
- if (artline > 0) do {
- artline--;
- } while (artline >= 0 && artline > target &&
- vrdary(artline-1) >= 0);
- topline = artline;
- /* remember top line of screen */
- /* (line # within article file) */
- if (artline < 0)
- artline = 0;
- firstpage = (topline < 0);
- return PS_NORM;
- }
- case 'h': { /* help */
- int cmd;
-
- if ((cmd = help_page()) > 0)
- pushchar(cmd);
- return PS_ASK;
- }
- case '\177':
- case '\0': /* treat del,break as 'n' */
- *buf = 'n';
- /* FALL THROUGH */
- case 'k': case 'K':
- case 'n': case 'N': case Ctl('n'):
- case 's': case 'S':
- case 'u':
- case 'w': case 'W':
- case '|':
- mark_as_read(art); /* mark article as read */
- /* FALL THROUGH */
- case '#':
- case '$':
- case '&':
- case '-':
- case '.':
- case '/':
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- case '=':
- case '?':
- case 'c': case 'C':
- case 'f': case 'F':
- case 'j':
- case Ctl('k'):
- case 'm': case 'M':
- case 'p': case 'P': case Ctl('p'):
- case 'Q':
- case 'r': case 'R': case Ctl('r'):
- case 'v':
- case 'Y':
- #ifndef ROTATION
- case 'x': case 'X':
- #endif
- case Ctl('x'):
- case '^':
-
- #ifdef ROTATION
- rotate = FALSE;
- #endif
- reread = FALSE;
- do_hiding = TRUE;
- if (index("nNpP",*buf) == Nullch &&
- index("wWsS!&|/?123456789.",*buf) != Nullch) {
- setdfltcmd();
- standout(); /* enter standout mode */
- printf(prompt,mailcall,dfltcmd);
- /* print prompt, whatever it is */
- un_standout(); /* leave standout mode */
- putchar(' ');
- fflush(stdout);
- }
- return PS_RAISE; /* and pretend we were at end */
- #ifdef ROTATION
- case 'x':
- rotate = TRUE;
- /* FALL THROUGH */
- #endif
- case 'y':
- case Ctl('v'):
- /* Leaving it undocumented in case */
- /* I want to steal the key--LAW */
- case ' ': /* continue current article */
- if (erase_screen) { /* -e? */
- #ifndef CLEAREOL
- clear(); /* clear screen */
- #else
- if (can_home_clear) /* if we can home do it */
- home_cursor();
- else
- clear(); /* else clear screen */
-
- #endif CLEAREOL
- if (*blinebeg != '\f'
- #ifdef CUSTOMLINES
- && (!pagestop || blinebeg != art_buf ||
- !execute(&page_compex,blinebeg))
- #endif
- ) {
- restart = blinebeg;
- artline--; /* restart this line */
- artpos = alinebeg;
- if (marking) /* and mark repeated line */
- highlight = artline;
- }
- topline = artline;
- /* and remember top line of screen */
- /* (line # within article file) */
- }
- else if (marking && *blinebeg != '\f'
- #ifdef CUSTOMLINES
- && (!pagestop || blinebeg != art_buf ||
- !execute(&page_compex,blinebeg))
- #endif
- ) {
- /* are we marking repeats? */
- up_line(); /* go up one line */
- highlight = --artline;/* and get ready to highlight */
- restart = blinebeg; /* the old line */
- artpos = alinebeg;
- }
- return PS_NORM;
- case 'q': /* quit this article? */
- do_hiding = TRUE;
- return PS_TOEND;
- default:
- fputs(hforhelp,stdout) FLUSH;
- settle_down();
- return PS_ASK;
- }
- }
-
- #ifdef INNERSEARCH
- bool
- innermore()
- {
- if (artpos < innersearch) { /* not even on page yet? */
- #ifdef DEBUGGING
- if (debug & DEB_INNERSRCH)
- printf("Not on page %ld < %ld\n",(long)artpos,(long)innersearch)
- FLUSH;
- #endif
- return TRUE;
- }
- if (artpos == innersearch) { /* just got onto page? */
- isrchline = artline; /* remember first line after */
- highlight = artline - 1;
- #ifdef DEBUGGING
- if (debug & DEB_INNERSRCH)
- printf("There it is %ld = %ld, %d @ %d\n",(long)artpos,
- (long)innersearch,hide_everything,highlight) FLUSH;
- #endif
- if (hide_everything) { /* forced refresh? */
- topline = highlight - gline;
- if (topline < -1)
- topline = -1;
- return FALSE; /* let refresh do it all */
- }
- }
- #ifdef DEBUGGING
- if (debug & DEB_INNERSRCH)
- printf("Not far enough? %d <? %d + %d\n",artline,isrchline,gline)
- FLUSH;
- #endif
- if (artline < isrchline + gline) {
- return TRUE;
- }
- return FALSE;
- }
- #endif
- !STUFFY!FUNK!
- echo Extracting rcstuff.c
- cat >rcstuff.c <<'!STUFFY!FUNK!'
- /* $Header: rcstuff.c,v 4.3.2.5 90/05/04 00:44:07 sob Exp $
- *
- * $Log: rcstuff.c,v $
- * Revision 4.3.2.5 90/05/04 00:44:07 sob
- * Fixes to add_newsgroup() from lar@usl.edu.
- *
- * Revision 4.3.2.4 90/04/23 00:25:45 sob
- * Changed atoi to atol.
- *
- * Revision 4.3.2.3 89/12/20 23:25:04 sob
- * Changed the maximum lenght of a newsgroup name from 20 to 40 characters.
- *
- * Revision 4.3.2.2 89/11/26 18:22:26 sob
- * Added changes to addnewgroup() to cause rn to ask once and only once
- * to add a new group to .newsrc.
- * Fix provided by Fletcher Mattox <fletcher@cs.utexas.edu>
- *
- * Revision 4.3.2.1 89/11/06 00:58:29 sob
- * Added RRN support from NNTP 1.5
- *
- * Revision 4.3.1.5 86/07/24 14:09:10 lwall
- * Removed check for spool directory existence in get_ng.
- *
- * Revision 4.3.1.4 85/09/10 11:04:44 lwall
- * Improved %m in in_char().
- *
- * Revision 4.3.1.3 85/05/29 09:13:25 lwall
- * %d that should be %ld.
- *
- * Revision 4.3.1.2 85/05/17 11:40:08 lwall
- * Sped up "rn -c" by not mallocing unnecessarily.
- *
- * Revision 4.3.1.1 85/05/10 11:37:18 lwall
- * Branch for patches.
- *
- * Revision 4.3 85/05/01 11:45:56 lwall
- * Baseline for release with 4.3bsd.
- *
- */
-
- #include "EXTERN.h"
- #include "common.h"
- #include "util.h"
- #include "ngdata.h"
- #include "term.h"
- #include "final.h"
- #include "rn.h"
- #include "intrp.h"
- #include "only.h"
- #include "rcln.h"
- #ifdef SERVER
- #include "server.h"
- #endif
- #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 */
-
- #ifdef HASHNG
- short hashtbl[HASHSIZ];
- #endif
-
- bool
- rcstuff_init()
- {
- register NG_NUM newng;
- register char *s;
- register int i;
- register bool foundany = FALSE;
- char *some_buf;
- long length;
- #ifdef SERVER
- char *cp;
- #endif SERVER
-
- #ifdef HASHNG
- for (i=0; i<HASHSIZ; i++)
- hashtbl[i] = -1;
- #endif
-
- /* make filenames */
-
- #ifdef SERVER
-
- if (cp = getenv("NEWSRC"))
- rcname = savestr(filexp(cp));
- else
- rcname = savestr(filexp(RCNAME));
-
- #else not SERVER
-
- rcname = savestr(filexp(RCNAME));
-
- #endif SERVER
-
- 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;
-
- /* 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 */
- fputs("Too many lines in .newsrc\n",stdout) FLUSH;
- finalize(1);
- }
- 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 a semipermanent copy */
- }
- else {
- /*NOSTRICT*/
- #ifndef lint
- some_buf = saferealloc(some_buf,(MEM_SIZE)(length+1));
- #endif lint
- rcline[newng] = some_buf;
- }
- #ifdef NOTDEF
- if (strnEQ(some_buf,"to.",3)) { /* is this a non-newsgroup? */
- nextrcline--; /* destroy this line */
- continue;
- }
- #endif
- if (*some_buf == ' ' ||
- *some_buf == '\t' ||
- strnEQ(some_buf,"options",7)) { /* non-useful line? */
- toread[newng] = TR_JUNK;
- rcchar[newng] = ' ';
- rcnums[newng] = 0;
- continue;
- }
- for (s = rcline[newng]; *s && *s != ':' && *s != NEGCHAR; s++) ;
- if (!*s && !checkflag) {
- #ifndef lint
- rcline[newng] = saferealloc(rcline[newng],(MEM_SIZE)length+2);
- #endif lint
- s = rcline[newng] + length;
- *s = ':';
- *(s+1) = '\0';
- }
- rcchar[newng] = *s; /* salt away the : or ! */
- rcnums[newng] = (char)(s - rcline[newng]);
- rcnums[newng]++; /* remember where it was */
- *s = '\0'; /* null terminate newsgroup name */
- #ifdef HASHNG
- if (!checkflag)
- sethash(newng);
- #endif
- 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 DEBUGGING
- if (debug & DEB_HASH) {
- page_init();
- for (i=0; i<HASHSIZ; i++) {
- sprintf(buf,"%d %d",i,hashtbl[i]);
- print_lines(buf,NOMARKING);
- }
- }
- #endif
-
- return foundany;
- }
-
- /* 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 SPOOL */
-
- #ifdef SERVER
- static int addnewbydefault = 0;
- #endif SERVER
-
- bool
- get_ng(what,do_reloc)
- char *what;
- bool do_reloc;
- {
- char *ntoforget;
- char promptbuf[128];
- #ifdef SERVER
- char ser_line[256];
- #endif SERVER
-
- #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;
- return FALSE;
- }
- set_ngname(what);
- ng = find_ng(ngname);
- if (ng == nextrcline) { /* not in .newsrc? */
-
- #ifdef SERVER
- sprintf(ser_line, "GROUP %s", ngname);
- put_server(ser_line);
- if (get_server(ser_line, sizeof(ser_line)) < 0) {
- fprintf(stderr, "rrn: Unexpected close of server socket.\n");
- finalize(1);
- }
- if (*ser_line != CHAR_OK) {
- if (atoi(ser_line) != ERR_NOGROUP) {
- fprintf(stderr, "Server response to GROUP %s:\n%s\n",
- ngname, ser_line);
- }
- #else not SERVER
-
- if ((softptr[ng] = findact(buf,ngname,strlen(ngname),0L)) < 0 ) {
-
- #endif SERVER
-
- 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
- sleep(2);
- return FALSE;
- }
- #ifdef SERVER
- if (addnewbydefault) {
- printf("(Adding %s to end of your .newsrc)\n", ngname);
- ng = add_newsgroup(ngname, ':');
- do_reloc = FALSE;
- } else {
- #endif SERVER
- #ifdef VERBOSE
- IF(verbose)
- sprintf(promptbuf,"\nNewsgroup %s not in .newsrc--add? [yn] ",ngname);
- ELSE
- #endif
- #ifdef TERSE
- sprintf(promptbuf,"\nAdd %s? [yn] ",ngname);
- #endif
- reask_add:
- in_char(promptbuf,'A');
- putchar('\n') FLUSH;
- setdef(buf,"y");
- #ifdef VERIFY
- printcmd();
- #endif
- if (*buf == 'h') {
- #ifdef VERBOSE
- IF(verbose)
- printf("Type y or SP to add %s to your .newsrc.\n", ngname)
- FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- fputs("y or SP to add\n",stdout) FLUSH;
- #endif
- fputs(ntoforget,stdout) FLUSH;
- goto reask_add;
- }
- else if (*buf == 'n' || *buf == 'q') {
- ng = add_newsgroup(ngname, '!');
- return FALSE;
- }
- else if (*buf == 'y') {
- ng = add_newsgroup(ngname, ':');
- do_reloc = FALSE;
- }
- #ifdef SERVER
- else if (*buf == 'Y') {
- fputs(
- "(I'll add all new newsgroups to the end of your .newsrc.)\n", stdout);
- addnewbydefault = 1;
- printf("(Adding %s to end of your .newsrc)\n", ngname);
- ng = add_newsgroup(ngname, ':');
- do_reloc = FALSE;
- }
- #endif SERVER
- else {
- fputs(hforhelp,stdout) FLUSH;
- settle_down();
- goto reask_add;
- }
- #ifdef SERVER
- }
- #endif SERVER
- }
- else if (rcchar[ng] == NEGCHAR) { /* unsubscribed? */
- #ifdef VERBOSE
- IF(verbose)
- sprintf(promptbuf,
- "\nNewsgroup %s is currently unsubscribed to--resubscribe? [yn] ",ngname)
- FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- sprintf(promptbuf,"\n%s unsubscribed--resubscribe? [yn] ",ngname)
- FLUSH;
- #endif
- reask_unsub:
- in_char(promptbuf,'R');
- putchar('\n') FLUSH;
- setdef(buf,"y");
- #ifdef VERIFY
- printcmd();
- #endif
- 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') {
- rcchar[ng] = ':';
- }
- else {
- fputs(hforhelp,stdout) FLUSH;
- settle_down();
- goto reask_unsub;
- }
- }
-
- /* now calculate how many unread articles in newsgroup */
-
- set_toread(ng);
- #ifdef RELOCATE
- if (do_reloc)
- ng = relocate_newsgroup(ng,-1);
- #endif
- return toread[ng] >= TR_NONE;
- }
-
- /* add a newsgroup to the .newsrc file (eventually) */
-
- NG_NUM
- add_newsgroup(ngn, c)
- char *ngn, c;
- {
- register NG_NUM newng = nextrcline++;
- /* increment max rcline index */
-
- rcnums[newng] = strlen(ngn) + 1;
- rcline[newng] = safemalloc((MEM_SIZE)(rcnums[newng] + 1));
- strcpy(rcline[newng],ngn); /* and copy over the name */
- *(rcline[newng] + rcnums[newng]) = '\0';
- rcchar[newng] = c; /* subscribe or unsubscribe */
- toread[newng] = TR_NONE; /* just for prettiness */
- #ifdef HASHNG
- sethash(newng); /* so we can find it again */
- #endif
- #ifdef RELOCATE
- return c=='!' ? newng : relocate_newsgroup(newng,-1);
- #else
- return newng;
- #endif
- }
-
- #ifdef RELOCATE
- NG_NUM
- relocate_newsgroup(ngx,newng)
- NG_NUM ngx;
- NG_NUM newng;
- {
- char *dflt = (ngx!=current_ng ? "$^.L" : "$^L");
- char *tmprcline;
- ART_UNREAD tmptoread;
- char tmprcchar;
- char tmprcnums;
- ACT_POS tmpsoftptr;
- register NG_NUM i;
- #ifdef DEBUGGING
- ART_NUM tmpngmax;
- #endif
- #ifdef CACHEFIRST
- ART_NUM tmpabs1st;
- #endif
-
- starthere = 0; /* Disable this optimization */
- writesoft = TRUE; /* Update soft pointer file */
- if (ngx < nextrcline-1) {
- #ifdef HASHNG
- for (i=0; i<HASHSIZ; i++) {
- if (hashtbl[i] > ngx)
- --hashtbl[i];
- else if (hashtbl[i] == ngx)
- hashtbl[i] = nextrcline-1;
- }
- #endif
- tmprcline = rcline[ngx];
- tmptoread = toread[ngx];
- tmprcchar = rcchar[ngx];
- tmprcnums = rcnums[ngx];
- tmpsoftptr = softptr[ngx];
- #ifdef DEBUGGING
- tmpngmax = ngmax[ngx];
- #endif
- #ifdef CACHEFIRST
- tmpabs1st = abs1st[ngx];
- #endif
- for (i=ngx+1; i<nextrcline; i++) {
- rcline[i-1] = rcline[i];
- toread[i-1] = toread[i];
- rcchar[i-1] = rcchar[i];
- rcnums[i-1] = rcnums[i];
- softptr[i-1] = softptr[i];
- #ifdef DEBUGGING
- ngmax[i-1] = ngmax[i];
- #endif
- #ifdef CACHEFIRST
- abs1st[i-1] = abs1st[i];
- #endif
- }
- rcline[nextrcline-1] = tmprcline;
- toread[nextrcline-1] = tmptoread;
- rcchar[nextrcline-1] = tmprcchar;
- rcnums[nextrcline-1] = tmprcnums;
- softptr[nextrcline-1] = tmpsoftptr;
- #ifdef DEBUGGING
- ngmax[nextrcline-1] = tmpngmax;
- #endif
- #ifdef CACHEFIRST
- abs1st[nextrcline-1] = tmpabs1st;
- #endif
- }
- if (current_ng > ngx)
- current_ng--;
- if (newng < 0) {
- reask_reloc:
- unflush_output(); /* disable any ^O in effect */
- #ifdef SERVER
- if (addnewbydefault) {
- buf[0] = '$';
- buf[1] = '\0';
- } else {
- #endif SERVER
- #ifdef VERBOSE
- IF(verbose)
- printf("\nPut newsgroup where? [%s] ", dflt);
- ELSE
- #endif
- #ifdef TERSE
- printf("\nPut where? [%s] ", dflt);
- #endif
- fflush(stdout);
- reinp_reloc:
- eat_typeahead();
- getcmd(buf);
- #ifdef SERVER
- }
- #endif SERVER
- if (errno || *buf == '\f') {
- /* if return from stop signal */
- goto reask_reloc; /* give them a prompt again */
- }
- setdef(buf,dflt);
- #ifdef VERIFY
- printcmd();
- #endif
- if (*buf == 'h') {
- #ifdef VERBOSE
- IF(verbose) {
- printf("\n\n\
- Type ^ to put the newsgroup first (position 0).\n\
- Type $ to put the newsgroup last (position %d).\n", nextrcline-1);
- printf("\
- Type . to put it before the current newsgroup (position %d).\n", current_ng);
- printf("\
- Type -newsgroup name to put it before that newsgroup.\n\
- Type +newsgroup name to put it after that newsgroup.\n\
- Type a number between 0 and %d to put it at that position.\n", nextrcline-1);
- printf("\
- Type L for a listing of newsgroups and their positions.\n") FLUSH;
- }
- ELSE
- #endif
- #ifdef TERSE
- {
- printf("\n\n\
- ^ to put newsgroup first (pos 0).\n\
- $ to put last (pos %d).\n", nextrcline-1);
- printf("\
- . to put before current newsgroup (pos %d).\n", current_ng);
- printf("\
- -newsgroup to put before newsgroup.\n\
- +newsgroup to put after.\n\
- number in 0-%d to put at that pos.\n", nextrcline-1);
- printf("\
- L for list of .newsrc.\n") FLUSH;
- }
- #endif
- goto reask_reloc;
- }
- else if (*buf == 'L') {
- putchar('\n') FLUSH;
- list_newsgroups();
- goto reask_reloc;
- }
- else if (isdigit(*buf)) {
- if (!finish_command(TRUE)) /* get rest of command */
- goto reinp_reloc;
- newng = atol(buf);
- if (newng < 0)
- newng = 0;
- if (newng >= nextrcline)
- return nextrcline-1;
- }
- else if (*buf == '^') {
- putchar('\n') FLUSH;
- newng = 0;
- }
- else if (*buf == '$') {
- putchar('\n') FLUSH;
- return nextrcline-1;
- }
- else if (*buf == '.') {
- putchar('\n') FLUSH;
- newng = current_ng;
- }
- else if (*buf == '-' || *buf == '+') {
- if (!finish_command(TRUE)) /* get rest of command */
- goto reinp_reloc;
- newng = find_ng(buf+1);
- if (newng == nextrcline) {
- fputs("Not found.",stdout) FLUSH;
- goto reask_reloc;
- }
- if (*buf == '+')
- newng++;
- }
- else {
- printf("\n%s",hforhelp) FLUSH;
- settle_down();
- goto reask_reloc;
- }
- }
- if (newng < nextrcline-1) {
- #ifdef HASHNG
- for (i=0; i<HASHSIZ; i++) {
- if (hashtbl[i] == nextrcline-1)
- hashtbl[i] = newng;
- else if (hashtbl[i] >= newng)
- ++hashtbl[i];
- }
- #endif
- tmprcline = rcline[nextrcline-1];
- tmptoread = toread[nextrcline-1];
- tmprcchar = rcchar[nextrcline-1];
- tmprcnums = rcnums[nextrcline-1];
- tmpsoftptr = softptr[nextrcline-1];
- #ifdef DEBUGGING
- tmpngmax = ngmax[nextrcline-1];
- #endif
- #ifdef CACHEFIRST
- tmpabs1st = abs1st[nextrcline-1];
- #endif
- for (i=nextrcline-2; i>=newng; i--) {
- rcline[i+1] = rcline[i];
- toread[i+1] = toread[i];
- rcchar[i+1] = rcchar[i];
- rcnums[i+1] = rcnums[i];
- softptr[i+1] = softptr[i];
- #ifdef DEBUGGING
- ngmax[i+1] = ngmax[i];
- #endif
- #ifdef CACHEFIRST
- abs1st[i+1] = abs1st[i];
- #endif
- }
- rcline[newng] = tmprcline;
- toread[newng] = tmptoread;
- rcchar[newng] = tmprcchar;
- rcnums[newng] = tmprcnums;
- softptr[newng] = tmpsoftptr;
- #ifdef DEBUGGING
- ngmax[newng] = tmpngmax;
- #endif
- #ifdef CACHEFIRST
- abs1st[newng] = tmpabs1st;
- #endif
- }
- if (current_ng >= newng)
- current_ng++;
- return newng;
- }
- #endif
-
- /* List out the newsrc with annotations */
-
- void
- list_newsgroups()
- {
- register NG_NUM i;
- char tmpbuf[2048];
- static char *status[] = {"(READ)","(UNSUB)","(BOGUS)","(JUNK)"};
- int cmd;
-
- page_init();
- print_lines("\
- # Status Newsgroup\n\
- ",STANDOUT);
- for (i=0; i<nextrcline && !int_count; i++) {
- if (toread[i] >= 0)
- set_toread(i);
- *(rcline[i] + rcnums[i] - 1) = rcchar[i];
- if (toread[i] > 0)
- sprintf(tmpbuf,"%3d %6ld ",i,(long)toread[i]);
- else
- sprintf(tmpbuf,"%3d %7s ",i,status[-toread[i]]);
- safecpy(tmpbuf+13,rcline[i],2034);
- *(rcline[i] + rcnums[i] - 1) = '\0';
- if (cmd = print_lines(tmpbuf,NOMARKING)) {
- if (cmd > 0)
- pushchar(cmd);
- break;
- }
- }
- int_count = 0;
- }
-
- /* find a newsgroup in .newsrc */
-
- NG_NUM
- find_ng(ngnam)
- char *ngnam;
- {
- register NG_NUM ngnum;
- #ifdef HASHNG
- register int hashix = hash(ngnam);
- register int incr = 1;
-
- while ((ngnum = hashtbl[hashix]) >= 0) {
- if (strEQ(rcline[ngnum], ngnam) && toread[ngnum] >= TR_UNSUB)
- return ngnum;
- hashix = (hashix + incr) % HASHSIZ;
- incr += 2; /* offsets from original are in n*2 */
- }
- return nextrcline; /* = notfound */
-
- #else /* just do linear search */
-
- for (ngnum = 0; ngnum < nextrcline; ngnum++) {
- if (strEQ(rcline[ngnum],ngnam))
- break;
- }
- return ngnum;
- #endif
- }
-
- void
- cleanup_rc()
- {
- register NG_NUM ngx;
- register NG_NUM bogosity = 0;
-
- #ifdef VERBOSE
- IF(verbose)
- fputs("Checking out your .newsrc--hang on a second...\n",stdout)
- FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- fputs("Checking .newsrc--hang on...\n",stdout) FLUSH;
- #endif
- for (ngx = 0; ngx < nextrcline; ngx++) {
- if (toread[ngx] >= TR_UNSUB) {
- set_toread(ngx); /* this may reset newsgroup */
- /* or declare it bogus */
- }
- if (toread[ngx] == TR_BOGUS)
- bogosity++;
- }
- for (ngx = nextrcline-1; ngx >= 0 && toread[ngx] == TR_BOGUS; ngx--)
- bogosity--; /* discount already moved ones */
- if (nextrcline > 5 && bogosity > nextrcline / 2) {
- fputs(
- "It looks like the active file is messed up. Contact your news administrator,\n\
- ",stdout);
- fputs(
- "leave the \"bogus\" groups alone, and they may come back to normal. Maybe.\n\
- ",stdout) FLUSH;
- }
- #ifdef RELOCATE
- else if (bogosity) {
- #ifdef VERBOSE
- IF(verbose)
- fputs("Moving bogus newsgroups to the end of your .newsrc.\n",
- stdout) FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- fputs("Moving boguses to the end.\n",stdout) FLUSH;
- #endif
- for (; ngx >= 0; ngx--) {
- if (toread[ngx] == TR_BOGUS)
- relocate_newsgroup(ngx,nextrcline-1);
- }
- #ifdef DELBOGUS
- reask_bogus:
- in_char("Delete bogus newsgroups? [ny] ", 'D');
- putchar('\n') FLUSH;
- setdef(buf,"n");
- #ifdef VERIFY
- printcmd();
- #endif
- if (*buf == 'h') {
- #ifdef VERBOSE
- IF(verbose)
- fputs("\
- Type y to delete bogus newsgroups.\n\
- Type n or SP to leave them at the end in case they return.\n\
- ",stdout) FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- fputs("y to delete, n to keep\n",stdout) FLUSH;
- #endif
- goto reask_bogus;
- }
- else if (*buf == 'n' || *buf == 'q')
- ;
- else if (*buf == 'y') {
- while (toread[nextrcline-1] == TR_BOGUS && nextrcline > 0)
- --nextrcline; /* real tough, huh? */
- }
- else {
- fputs(hforhelp,stdout) FLUSH;
- settle_down();
- goto reask_bogus;
- }
- #endif
- }
- #else
- #ifdef VERBOSE
- IF(verbose)
- fputs("You should edit bogus newsgroups out of your .newsrc.\n",
- stdout) FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- fputs("Edit boguses from .newsrc.\n",stdout) FLUSH;
- #endif
- #endif
- paranoid = FALSE;
- }
-
- #ifdef HASHNG
- /* make an entry in the hash table for the current newsgroup */
-
- void
- sethash(thisng)
- NG_NUM thisng;
- {
- register int hashix = hash(rcline[thisng]);
- register int incr = 1;
- #ifdef DEBUGGING
- static int hashhits = 0, hashtries = 0;
- #endif
-
- #ifdef DEBUGGING
- hashtries++;
- #endif
- while (hashtbl[hashix] >= 0) {
- #ifdef DEBUGGING
- hashhits++;
- if (debug & DEB_HASH) {
- printf(" Hash hits: %d / %d\n",hashhits, hashtries) FLUSH;
- }
- hashtries++;
- #endif
- hashix = (hashix + incr) % HASHSIZ;
- incr += 2; /* offsets from original are in n*2 */
- }
- hashtbl[hashix] = thisng;
- }
-
- short prime[] = {1,2,-3,-5,7,11,-13,-17,19,23,-29,-31,37,41,-43,-47,53,57,-59,
- -61,67,71,-73,-79,83,89,-97,-101,1,1,1,1,1,1,1,1,1,1,1,1};
-
- int
- hash(ngnam)
- register char *ngnam;
- {
- register int i = 0;
- register int ch;
- register int sum = 0;
- #ifdef DEBUGGING
- char *ngn = ngnam;
- #endif
-
- while (ch = *ngnam++) {
- sum += (ch + i) * prime[i]; /* gives ~ 10% hits at 25% full */
- i++;
- }
- #ifdef DEBUGGING
- if (debug & DEB_HASH)
- printf("hash(%s) => %d => %d\n",ngn, sum, (sum<0?-sum:sum)%HASHSIZ)
- FLUSH;
- #endif
- if (sum < 0)
- sum = -sum;
- return sum % HASHSIZ;
- }
-
- #endif
-
- void
- newsrc_check()
- {
- rcfp = fopen(rcname,"r"); /* open it */
- if (rcfp == Nullfp) { /* not there? */
- #ifdef VERBOSE
- IF(verbose)
- fputs("\
- Trying to set up a .newsrc file--running newsetup...\n\n\
- ",stdout) FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- fputs("Setting up .newsrc...\n",stdout) FLUSH;
- #endif
- if (doshell(sh,filexp(NEWSETUP)) ||
- (rcfp = fopen(rcname,"r")) == Nullfp) {
- #ifdef VERBOSE
- IF(verbose)
- fputs("\
- Can't create a .newsrc--you must do it yourself.\n\
- ",stdout) FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- fputs("(Fatal)\n",stdout) FLUSH;
- #endif
- finalize(1);
- }
- }
- else {
- UNLINK(rcbname); /* unlink backup file name */
- link(rcname,rcbname); /* and backup current name */
- }
- }
-
- /* write out the (presumably) revised .newsrc */
-
- void
- write_rc()
- {
- register NG_NUM tmpng;
- register char *delim;
-
- rcfp = fopen(rctname, "w"); /* open .newsrc */
- if (rcfp == Nullfp) {
- printf("Can't recreate .newsrc\n") FLUSH;
- finalize(1);
- }
-
- /* write out each line*/
-
- for (tmpng = 0; tmpng < nextrcline; tmpng++) {
- if (rcnums[tmpng]) {
- delim = rcline[tmpng] + rcnums[tmpng] - 1;
- *delim = rcchar[tmpng];
- }
- else
- delim = Nullch;
- #ifdef DEBUGGING
- if (debug & DEB_NEWSRC_LINE)
- printf("%s\n",rcline[tmpng]) FLUSH;
- #endif
- fprintf(rcfp,"%s\n",rcline[tmpng]);
- if (delim)
- *delim = '\0'; /* might still need this line */
- }
-
- fclose(rcfp); /* close .newsrc */
- UNLINK(rcname);
- link(rctname,rcname);
- UNLINK(rctname);
-
- if (writesoft) {
- tmpfp = fopen(filexp(softname), "w"); /* open .rnsoft */
- if (tmpfp == Nullfp) {
- printf(cantcreate,filexp(softname)) FLUSH;
- return;
- }
- for (tmpng = 0; tmpng < nextrcline; tmpng++) {
- fprintf(tmpfp,"%ld\n",(long)softptr[tmpng]);
- }
- fclose(tmpfp);
- }
- }
-
- void
- get_old_rc()
- {
- UNLINK(rctname);
- link(rcname,rctname);
- UNLINK(rcname);
- link(rcbname,rcname);
- UNLINK(rcbname);
- }
- !STUFFY!FUNK!
- echo Extracting bits.c
- cat >bits.c <<'!STUFFY!FUNK!'
- /* $Header: bits.c,v 4.3.2.3 89/11/28 01:52:02 sob Locked $
- *
- * $Log: bits.c,v $
- * Revision 4.3.2.3 89/11/28 01:52:02 sob
- * Removed some lint.
- *
- * Revision 4.3.2.2 89/11/27 01:30:04 sob
- * Altered NNTP code per ideas suggested by Bela Lubkin
- * <filbo@gorn.santa-cruz.ca.us>
- *
- * Revision 4.3.1.4 86/10/31 15:23:53 lwall
- * Separated firstart into two variables so KILL on new articles won't
- * accidentally mark articles read.
- *
- * Revision 4.3.1.3 86/09/09 16:01:43 lwall
- * Fixed 'n more articles' bug.
- *
- * Revision 4.3.1.2 86/07/24 14:40:23 lwall
- * Gets host name from path instead of relay-version for news 2.10.3.
- *
- * Revision 4.3.1.1 85/05/10 11:31:41 lwall
- * Branch for patches.
- *
- * Revision 4.3 85/05/01 11:36:15 lwall
- * Baseline for release with 4.3bsd.
- *
- */
-
- #include "EXTERN.h"
- #include "common.h"
- #include "rcstuff.h"
- #include "head.h"
- #include "util.h"
- #include "final.h"
- #include "rn.h"
- #include "cheat.h"
- #include "ng.h"
- #include "artio.h"
- #include "intrp.h"
- #include "ngdata.h"
- #include "rcln.h"
- #include "kfile.h"
- #include "INTERN.h"
- #include "bits.h"
-
- #ifdef DBM
- # ifdef NULL
- # undef NULL
- # endif NULL
- # include <dbm.h>
- #endif DBM
- MEM_SIZE ctlsize; /* size of bitmap in bytes */
-
- void
- bits_init()
- {
- #ifdef DELAYMARK
- dmname = savestr(filexp(RNDELNAME));
- #else
- ;
- #endif
- }
-
- /* checkpoint the .newsrc */
-
- void
- checkpoint_rc()
- {
- #ifdef DEBUGGING
- if (debug & DEB_CHECKPOINTING) {
- fputs("(ckpt)",stdout);
- fflush(stdout);
- }
- #endif
- if (doing_ng)
- restore_ng(); /* do not restore M articles */
- if (rc_changed)
- write_rc();
- #ifdef DEBUGGING
- if (debug & DEB_CHECKPOINTING) {
- fputs("(done)",stdout);
- fflush(stdout);
- }
- #endif
- }
-
- /* reconstruct the .newsrc line in a human readable form */
-
- void
- restore_ng()
- {
- register char *s, *mybuf = buf;
- register ART_NUM i;
- ART_NUM count=0;
- int safelen = LBUFLEN - 16;
-
- strcpy(buf,rcline[ng]); /* start with the newsgroup name */
- s = buf + rcnums[ng] - 1; /* use s for buffer pointer */
- *s++ = rcchar[ng]; /* put the requisite : or !*/
- *s++ = ' '; /* put the not-so-requisite space */
- for (i=1; i<=lastart; i++) { /* for each article in newsgroup */
- if (s-mybuf > safelen) { /* running out of room? */
- safelen *= 2;
- if (mybuf == buf) { /* currently static? */
- *s = '\0';
- mybuf = safemalloc((MEM_SIZE)safelen + 16);
- strcpy(mybuf,buf); /* so we must copy it */
- s = mybuf + (s-buf);
- /* fix the pointer, too */
- }
- else { /* just grow in place, if possible */
- char *newbuf;
-
- newbuf = saferealloc(mybuf,(MEM_SIZE)safelen + 16);
- s = newbuf + (s-mybuf);
- mybuf = newbuf;
- }
- }
- if (!was_read(i)) /* still unread? */
- count++; /* then count it */
- else { /* article was read */
- ART_NUM oldi;
-
- sprintf(s,"%ld",(long)i); /* put out the min of the range */
- s += strlen(s); /* keeping house */
- oldi = i; /* remember this spot */
- do i++; while (i <= lastart && was_read(i));
- /* find 1st unread article or end */
- i--; /* backup to last read article */
- if (i > oldi) { /* range of more than 1? */
- sprintf(s,"-%ld,",(long)i);
- /* then it out as a range */
- s += strlen(s); /* and housekeep */
- }
- else
- *s++ = ','; /* otherwise, just a comma will do */
- }
- }
- if (*(s-1) == ',') /* is there a final ','? */
- s--; /* take it back */
- *s++ = '\0'; /* and terminate string */
- #ifdef DEBUGGING
- if (debug & DEB_NEWSRC_LINE && !panic) {
- printf("%s: %s\n",rcline[ng],rcline[ng]+rcnums[ng]) FLUSH;
- printf("%s\n",mybuf) FLUSH;
- }
- #endif
- free(rcline[ng]); /* return old rc line */
- if (mybuf == buf) {
- rcline[ng] = safemalloc((MEM_SIZE)(s-buf)+1);
- /* grab a new rc line */
- strcpy(rcline[ng], buf); /* and load it */
- }
- else {
- mybuf = saferealloc(mybuf,(MEM_SIZE)(s-mybuf)+1);
- /* be nice to the heap */
- rcline[ng] = mybuf;
- }
- *(rcline[ng] + rcnums[ng] - 1) = '\0';
- if (rcchar[ng] == NEGCHAR) { /* did they unsubscribe? */
- printf(unsubto,ngname) FLUSH;
- toread[ng] = TR_UNSUB; /* make line invisible */
- }
- else
- /*NOSTRICT*/
- toread[ng] = (ART_UNREAD)count; /* remember how many unread there are */
- }
-
- /* mark an article unread, keeping track of toread[] */
-
- void
- onemore(artnum)
- ART_NUM artnum;
- {
- #ifdef DEBUGGING
- if (debug && artnum < firstbit) {
- printf("onemore: %d < %d\n",artnum,firstbit) FLUSH;
- return;
- }
- #endif
- if (ctl_read(artnum)) {
- ctl_clear(artnum);
- ++toread[ng];
- }
- }
-
- /* mark an article read, keeping track of toread[] */
-
- void
- oneless(artnum)
- ART_NUM artnum;
- {
- #ifdef DEBUGGING
- if (debug && artnum < firstbit) {
- printf("oneless: %d < %d\n",artnum,firstbit) FLUSH;
- return;
- }
- #endif
- if (!ctl_read(artnum)) {
- ctl_set(artnum);
- if (toread[ng] > TR_NONE)
- --toread[ng];
- }
- }
-
- /* mark an article as unread, making sure that firstbit is properly handled */
- /* cross-references are left as read in the other newsgroups */
-
- void
- unmark_as_read(artnum)
- ART_NUM artnum;
- {
- check_first(artnum);
- onemore(artnum);
- #ifdef MCHASE
- if (!parse_maybe(artnum))
- chase_xrefs(artnum,FALSE);
- #endif
- }
-
- #ifdef DELAYMARK
- /* temporarily mark article as read. When newsgroup is exited, articles */
- /* will be marked as unread. Called via M command */
-
- void
- delay_unmark(artnum)
- ART_NUM artnum;
- {
- if (dmfp == Nullfp) {
- dmfp = fopen(dmname,"w");
- if (dmfp == Nullfp) {
- printf(cantcreate,dmname) FLUSH;
- sig_catcher(0);
- }
- }
- oneless(artnum); /* set the correct bit */
- dmcount++;
- fprintf(dmfp,"%ld\n",(long)artnum);
- }
- #endif
-
- /* mark article as read. If article is cross referenced to other */
- /* newsgroups, mark them read there also. */
-
- void
- mark_as_read(artnum)
- ART_NUM artnum;
- {
- oneless(artnum); /* set the correct bit */
- checkcount++; /* get more worried about crashes */
- chase_xrefs(artnum,TRUE);
- }
-
- /* make sure we have bits set correctly down to firstbit */
-
- void
- check_first(min)
- ART_NUM min;
- {
- register ART_NUM i = firstbit;
-
- if (min < absfirst)
- min = absfirst;
- if (min < i) {
- for (i--; i>=min; i--)
- ctl_set(i); /* mark as read */
- firstart = firstbit = min;
- }
- }
-
- /* bring back articles marked with M */
-
- #ifdef DELAYMARK
- void
- yankback()
- {
- register ART_NUM anum;
-
- if (dmfp) { /* delayed unmarks pending? */
- #ifdef VERBOSE
- printf("\nReturning %ld Marked article%s...\n",(long)dmcount,
- dmcount == 1 ? nullstr : "s") FLUSH;
- #endif
- fclose(dmfp);
- if (dmfp = fopen(dmname,"r")) {
- while (fgets(buf,sizeof buf,dmfp) != Nullch) {
- anum = (ART_NUM)atol(buf);
- /*NOSTRICT*/
- onemore(anum); /* then unmark them */
- #ifdef MCHASE
- chase_xrefs(anum,FALSE);
- #endif
- }
- fclose(dmfp);
- dmfp = Nullfp;
- UNLINK(dmname); /* and be tidy */
- }
- else {
- printf(cantopen,dmname) FLUSH;
- sig_catcher(0);
- }
- }
- dmcount = 0;
- }
- #endif
-
- /* run down xref list and mark as read or unread */
-
- int
- chase_xrefs(artnum,markread)
- ART_NUM artnum;
- int markread;
- {
- #ifdef ASYNC_PARSE
- if (parse_maybe(artnum)) /* make sure we have right header */
- return -1;
- #endif
- #ifdef DBM
- {
- datum lhs, rhs;
- datum fetch();
- register char *idp;
- char *ident_buf;
- static FILE * hist_file = Nullfp;
- #else
- if (
- #ifdef DEBUGGING
- debug & DEB_FEED_XREF ||
- #endif
- htype[XREF_LINE].ht_minpos >= 0) {
- /* are there article# xrefs? */
- #endif DBM
- char *xref_buf, *curxref;
- register char *xartnum;
- char *rver_buf = Nullch;
- static char *inews_site = Nullch;
- register ART_NUM x;
- char tmpbuf[128];
-
- #ifdef DBM
- rver_buf = fetchlines(artnum,NGS_LINE);
- /* get Newsgroups */
- if (!index(rver_buf,',')) /* if no comma, no Xref! */
- return 0;
- if (hist_file == Nullfp) { /* Init. file accesses */
- #ifdef DEBUGGING
- if (debug)
- printf ("chase_xref: opening files\n");
- #endif
- dbminit(filexp(ARTFILE));
- if ((hist_file = fopen (filexp(ARTFILE), "r")) == Nullfp)
- return 0;
- }
- xref_buf = safemalloc((MEM_SIZE)BUFSIZ);
- ident_buf = fetchlines(artnum,MESSID_LINE);
- /* get Message-ID */
- #ifdef DEBUGGING
- if (debug)
- printf ("chase_xref: Message-ID: %s\n", ident_buf);
- #endif
- idp = ident_buf;
- while (*++idp) /* make message-id case insensitive */
- if (isupper(*idp))
- *idp = tolower (*idp);
- lhs.dptr = ident_buf; /* look up article by id */
- lhs.dsize = strlen(lhs.dptr) + 1;
- rhs = fetch(lhs); /* fetch the record */
- if (rhs.dptr == NULL) /* if null, nothing there */
- goto wild_goose;
- fseek (hist_file, *((long *)rhs.dptr), 0);
- /* datum returned is position in hist file */
- fgets (xref_buf, BUFSIZ, hist_file);
- #ifdef DEBUGGING
- if (debug)
- printf ("Xref from history: %s\n", xref_buf);
- #endif
- curxref = cpytill(tmpbuf, xref_buf, '\t') + 1;
- curxref = cpytill(tmpbuf, curxref, '\t') + 1;
- #ifdef DEBUGGING
- if (debug)
- printf ("chase_xref: curxref: %s\n", curxref);
- #endif
- #else !DBM
- #ifdef DEBUGGING
- if (htype[XREF_LINE].ht_minpos >= 0)
- #endif
- xref_buf = fetchlines(artnum,XREF_LINE);
- /* get xrefs list */
- #ifdef DEBUGGING
- else {
- xref_buf = safemalloc((MEM_SIZE)100);
- printf("Give Xref: ") FLUSH;
- gets(xref_buf);
- }
- #endif
- #ifdef DEBUGGING
- if (debug & DEB_XREF_MARKER)
- printf("Xref: %s\n",xref_buf) FLUSH;
- #endif
- curxref = cpytill(tmpbuf,xref_buf,' ') + 1;
-
- /* Make sure site name on Xref matches what inews thinks site is.
- * Check first against last inews_site. If it matches, fine.
- * If not, fetch inews_site from current Relay-Version line and
- * check again. This is so that if the new administrator decides
- * to change the system name as known to inews, rn will still do
- * Xrefs correctly--each article need only match itself to be valid.
- */
- if (inews_site == Nullch || strNE(tmpbuf,inews_site)) {
- #ifndef NORELAY
- char *t;
- #endif
- if (inews_site != Nullch)
- free(inews_site);
- #ifndef NORELAY
- rver_buf = fetchlines(artnum,RVER_LINE);
- if ((t = instr(rver_buf,"; site ")) == Nullch)
- #else NORELAY
- /* In version 2.10.3 of news or afterwards, the Relay-Version
- * and Posting-Version header lines have been removed. For
- * the code below to work as intended, I have modified it to
- * extract the first component of the Path header line. This
- * should give the same effect as did the old code with respect
- * to the use of the Relay-Version site name.
- */
- rver_buf = fetchlines(artnum,PATH_LINE);
- if (instr(rver_buf,"!") == Nullch)
- #endif NORELAY
- inews_site = savestr(nullstr);
- else {
- char new_site[128];
-
- #ifndef NORELAY
- cpytill(new_site,t + 7,'.');
- #else NORELAY
- cpytill(new_site,rver_buf,'!');
- #endif NORELAY
- inews_site = savestr(new_site);
- }
- if (strNE(tmpbuf,inews_site)) {
- #ifdef DEBUGGING
- if (debug)
- printf("Xref not from %s--ignoring\n",inews_site) FLUSH;
- #endif
- goto wild_goose;
- }
- }
- #endif DBM
- while (*curxref) {
- /* for each newsgroup */
- curxref = cpytill(tmpbuf,curxref,' ');
- #ifdef DBM
- xartnum = index(tmpbuf,'/');
- #else
- xartnum = index(tmpbuf,':');
- #endif DBM
- if (!xartnum) /* probably an old-style Xref */
- break;
- *xartnum++ = '\0';
- if (strNE(tmpbuf,ngname)) {/* not the current newsgroup? */
- x = atol(xartnum);
- if (x)
- if (markread) {
- if (addartnum(x,tmpbuf))
- goto wild_goose;
- }
- #ifdef MCHASE
- else
- subartnum(x,tmpbuf);
- #endif
- }
- while (*curxref && isspace(*curxref))
- curxref++;
- }
- wild_goose:
- free(xref_buf);
- #ifdef DBM
- free(ident_buf);
- #endif DBM
- if (rver_buf != Nullch)
- free(rver_buf);
- }
- return 0;
- }
-
- int
- initctl()
- {
- char *mybuf = buf; /* place to decode rc line */
- register char *s, *c, *h;
- register long i;
- register ART_NUM unread;
-
- #ifdef DELAYMARK
- dmcount = 0;
- #endif
- if ((lastart = getngsize(ng)) < 0) /* this cannot happen (laugh here) */
- return -1;
-
- absfirst = getabsfirst(ng,lastart); /* remember first existing article */
- if (!absfirst) /* no articles at all? */
- absfirst = 1; /* pretend there is one */
- #ifndef lint
- ctlsize = (MEM_SIZE)(OFFSET(lastart)/BITSPERBYTE+20);
- #endif lint
- ctlarea = safemalloc(ctlsize); /* allocate control area */
-
- /* now modify ctlarea to reflect what has already been read */
-
- for (s = rcline[ng] + rcnums[ng]; *s == ' '; s++) ;
- /* find numbers in rc line */
- i = strlen(s);
- #ifndef lint
- if (i >= LBUFLEN-2) /* bigger than buf? */
- mybuf = safemalloc((MEM_SIZE)(i+2));
- #endif lint
- strcpy(mybuf,s); /* make scratch copy of line */
- mybuf[i++] = ','; /* put extra comma on the end */
- mybuf[i] = '\0';
- s = mybuf; /* initialize the for loop below */
- if (strnEQ(s,"1-",2)) { /* can we save some time here? */
- firstbit = atol(s+2)+1; /* ignore first range thusly */
- s=index(s,',') + 1;
- }
- else
- firstbit = 1; /* all the bits are valid for now */
- if (absfirst > firstbit) { /* do we know already? */
- firstbit = absfirst; /* no point calling getngmin again */
- }
- else if (artopen(firstbit) == Nullfp) {
- /* first unread article missing? */
- i = getngmin(".",firstbit); /* see if expire has been busy */
- if (i) { /* avoid a bunch of extra opens */
- firstbit = i;
- }
- }
- firstart = firstbit; /* firstart > firstbit in KILL */
- #ifdef PENDING
- # ifdef CACHESUBJ
- subj_to_get = firstbit;
- # endif
- #endif
- unread = lastart - firstbit + 1; /* assume this range unread */
- for (i=OFFSET(firstbit)/BITSPERBYTE; i<ctlsize; i++)
- ctlarea[i] = 0; /* assume unread */
- #ifdef DEBUGGING
- if (debug & DEB_CTLAREA_BITMAP) {
- printf("\n%s\n",mybuf) FLUSH;
- for (i=1; i <= lastart; i++)
- if (! was_read(i))
- printf("%ld ",(long)i) FLUSH;
- }
- #endif
- for ( ; (c = index(s,',')) != Nullch; s = ++c) {
- /* for each range */
- ART_NUM min, max;
-
- *c = '\0'; /* do not let index see past comma */
- if ((h = index(s,'-')) != Nullch) { /* is there a -? */
- min = atol(s);
- max = atol(h+1);
- if (min < firstbit) /* make sure range is in range */
- min = firstbit;
- if (max > lastart)
- max = lastart;
- if (min <= max) /* non-null range? */
- unread -= max - min + 1;/* adjust unread count */
- for (i=min; i<=max; i++) /* for all articles in range */
- ctl_set(i); /* mark them read */
- }
- else if ((i = atol(s)) >= firstbit && i <= lastart) {
- /* is single number reasonable? */
- ctl_set(i); /* mark it read */
- unread--; /* decrement articles to read */
- }
- #ifdef DEBUGGING
- if (debug & DEB_CTLAREA_BITMAP) {
- printf("\n%s\n",s) FLUSH;
- for (i=1; i <= lastart; i++)
- if (! was_read(i))
- printf("%ld ",(long)i) FLUSH;
- }
- #endif
- }
- #ifdef DEBUGGING
- if (debug & DEB_CTLAREA_BITMAP) {
- fputs("\n(hit CR)",stdout) FLUSH;
- gets(cmd_buf);
- }
- #endif
- if (mybuf != buf)
- free(mybuf);
- toread[ng] = unread;
- return 0;
- }
-
- void
- grow_ctl()
- {
- ART_NUM newlast;
- ART_NUM tmpfirst;
- MEM_SIZE newsize;
- register ART_NUM i;
-
- forcegrow = FALSE;
- newlast = getngsize(ng);
- if (newlast > lastart) {
- ART_NUM tmpart = art;
- #ifndef lint
- newsize = (MEM_SIZE)(OFFSET(newlast)/BITSPERBYTE+2);
- #else
- newsize = Null(MEM_SIZE);
- #endif lint
- if (newsize > ctlsize) {
- newsize += 20;
- ctlarea = saferealloc(ctlarea,newsize);
- ctlsize = newsize;
- }
- toread[ng] += (ART_UNREAD)(newlast-lastart);
- for (i=lastart+1; i<=newlast; i++)
- ctl_clear(i); /* these articles are unread */
- #ifdef CACHESUBJ
- if (subj_list != Null(char**)) {
- #ifndef lint
- subj_list = (char**)saferealloc((char*)subj_list,
- (MEM_SIZE)((OFFSET(newlast)+2)*sizeof(char *)) );
- #endif lint
- for (i=lastart+1; i<=newlast; i++)
- subj_list[OFFSET(i)] = Nullch;
- }
- #endif
- tmpfirst = lastart+1;
- lastart = newlast;
- #ifdef KILLFILES
- #ifdef VERBOSE
- IF(verbose)
- sprintf(buf,
- "%ld more article%s arrived--looking for more to kill...\n\n",
- (long)(lastart - tmpfirst + 1),
- (lastart > tmpfirst ? "s have" : " has" ) );
- ELSE /* my, my, how clever we are */
- #endif
- #ifdef TERSE
- strcpy(buf, "More news--killing...\n\n");
- #endif
- kill_unwanted(tmpfirst,buf,TRUE);
- #endif
- art = tmpart;
- }
- }
-
- !STUFFY!FUNK!
- echo Extracting INIT
- cat >INIT <<'!STUFFY!FUNK!'
- -ESAMPLE="sample"
- !STUFFY!FUNK!
- echo ""
- echo "End of kit 5 (of 9)"
- cat /dev/null >kit5isdone
- config=true
- for iskit in 1 2 3 4 5 6 7 8 9 ; do
- if test -f kit${iskit}isdone; then
- echo "You have run kit ${iskit}."
- else
- echo "You still need to run kit ${iskit}."
- config=false
- fi
- done
- case $config in
- true)
- echo "You have run all your kits. Please read README and then type Configure."
- chmod 755 Configure
- ;;
- esac
- : I do not append .signature, but someone might mail this.
- exit
-