rn version 4.3 (kit 7 of 9)

sources-request at genrad.UUCP sources-request at genrad.UUCP
Sun May 12 22:20:12 AEST 1985


From: lwall at sdcrdcf.UUCP (Larry Wall)

---------------- cut here ---------------
#! /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 7 (of 9).  If kit 7 is complete, the line"
echo '"'"End of kit 7 (of 9)"'" will echo at the end.'
echo ""
export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
echo Extracting term.h
cat >term.h <<'!STUFFY!FUNK!'
/* $Header: term.h,v 4.3 85/05/01 11:51:36 lwall Exp $
 *
 * $Log:	term.h,v $
 * Revision 4.3  85/05/01  11:51:36  lwall
 * Baseline for release with 4.3bsd.
 * 
 */

#ifdef PUSHBACK
EXT char circlebuf[PUSHSIZE];
EXT int nextin INIT(0);
EXT int nextout INIT(0);
#ifdef PENDING
#ifdef FIONREAD
EXT long iocount INIT(0);
#ifndef lint
#define input_pending() (nextin!=nextout || (ioctl(0, FIONREAD, &iocount),(int)iocount))
#else
#define input_pending() bizarre
#endif lint
#else FIONREAD
int circfill();
#ifndef lint
#define input_pending() (nextin!=nextout || circfill())
#else
#define input_pending() bizarre
#endif lint
#endif FIONREAD
#else PENDING
#ifndef lint
#define input_pending() (nextin!=nextout)
#else
#define input_pending() bizarre
#endif lint
#endif PENDING
#else PUSHBACK
#ifdef PENDING
#ifdef FIONREAD	/* must have FIONREAD or O_NDELAY for input_pending() */
#define read_tty(addr,size) read(0,addr,size)
#ifndef lint
#define input_pending() (ioctl(0, FIONREAD, &iocount),(int)iocount)
#else
#define input_pending() bizarre
#endif lint
EXT long iocount INIT(0);

#else FIONREAD

EXT int devtty INIT(0);
EXT bool is_input INIT(FALSE);
EXT char pending_ch INIT(0);
#ifndef lint
#define input_pending() (is_input || (is_input=read(devtty,&pending_ch,1)))
#else
#define input_pending() bizarre
#endif lint
#endif FIONREAD
#else PENDING
#define read_tty(addr,size) read(0,addr,size)
#define input_pending() (FALSE)
#endif PENDING
#endif PUSHBACK

/* stuff wanted by terminal mode diddling routines */

#ifdef TERMIO
EXT struct termio _tty, _oldtty;
#else
EXT struct sgttyb _tty;
EXT int _res_flg INIT(0);
#endif

EXT int _tty_ch INIT(2);
EXT bool bizarre INIT(FALSE);			/* do we need to restore terminal? */

/* terminal mode diddling routines */

#ifdef TERMIO

#define crmode() ((bizarre=1),_tty.c_lflag &=~ICANON,_tty.c_cc[VMIN] = 1,ioctl(_tty_ch,TCSETAF,&_tty))
#define nocrmode() ((bizarre=1),_tty.c_lflag |= ICANON,_tty.c_cc[VEOF] = CEOF,stty(_tty_ch,&_tty))
#define echo()	 ((bizarre=1),_tty.c_lflag |= ECHO, ioctl(_tty_ch, TCSETA, &_tty))
#define noecho() ((bizarre=1),_tty.c_lflag &=~ECHO, ioctl(_tty_ch, TCSETA, &_tty))
#define nl()	 ((bizarre=1),_tty.c_iflag |= ICRNL,_tty.c_oflag |= ONLCR,ioctl(_tty_ch, TCSETAW, &_tty))
#define nonl()	 ((bizarre=1),_tty.c_iflag &=~ICRNL,_tty.c_oflag &=~ONLCR,ioctl(_tty_ch, TCSETAW, &_tty))
#define	savetty() (ioctl(_tty_ch, TCGETA, &_oldtty),ioctl(_tty_ch, TCGETA, &_tty))
#define	resetty() ((bizarre=0),ioctl(_tty_ch, TCSETAF, &_oldtty))
#define unflush_output()

#else

#define raw()	 ((bizarre=1),_tty.sg_flags|=RAW, stty(_tty_ch,&_tty))
#define noraw()	 ((bizarre=1),_tty.sg_flags&=~RAW,stty(_tty_ch,&_tty))
#define crmode() ((bizarre=1),_tty.sg_flags |= CBREAK, stty(_tty_ch,&_tty))
#define nocrmode() ((bizarre=1),_tty.sg_flags &= ~CBREAK,stty(_tty_ch,&_tty))
#define echo()	 ((bizarre=1),_tty.sg_flags |= ECHO, stty(_tty_ch, &_tty))
#define noecho() ((bizarre=1),_tty.sg_flags &= ~ECHO, stty(_tty_ch, &_tty))
#define nl()	 ((bizarre=1),_tty.sg_flags |= CRMOD,stty(_tty_ch, &_tty))
#define nonl()	 ((bizarre=1),_tty.sg_flags &= ~CRMOD, stty(_tty_ch, &_tty))
#define	savetty() (gtty(_tty_ch, &_tty), _res_flg = _tty.sg_flags)
#define	resetty() ((bizarre=0),_tty.sg_flags = _res_flg, stty(_tty_ch, &_tty))
#ifdef LFLUSHO
#ifndef lint
EXT int lflusho INIT(LFLUSHO);
#else
EXT long lflusho INIT(LFLUSHO);
#endif lint
#define unflush_output() (ioctl(_tty_ch,TIOCLBIC,&lflusho))
#else
#define unflush_output()
#endif LFLUSHO
#endif TERMIO

#ifdef TIOCSTI
#ifdef lint
#define forceme(c) ioctl(_tty_ch,TIOCSTI,Null(long*))	/* ghad! */
#else
#define forceme(c) ioctl(_tty_ch,TIOCSTI,c) /* pass character in " " */
#endif lint
#else
#define forceme(c)
#endif

/* termcap stuff */

/*
 * NOTE: if you don't have termlib you'll either have to define these strings
 *    and the tputs routine, or you'll have to redefine the macros below
 */

#ifdef HAVETERMLIB
EXT char *BC INIT(Nullch);		/* backspace character */
EXT char *UP INIT(Nullch);		/* move cursor up one line */
EXT char *CR INIT(Nullch);		/* get to left margin, somehow */
EXT char *VB INIT(Nullch);		/* visible bell */
EXT char *CL INIT(Nullch);		/* home and clear screen */
EXT char *CE INIT(Nullch);		/* clear to end of line */
#ifdef CLEAREOL
EXT char *CM INIT(Nullch);		/* cursor motion -- PWP */
EXT char *HO INIT(Nullch);		/* home cursor -- PWP */
EXT char *CD INIT(Nullch);		/* clear to end of display -- PWP */
#endif CLEAREOL
EXT char *SO INIT(Nullch);		/* begin standout mode */
EXT char *SE INIT(Nullch);		/* end standout mode */
EXT int SG INIT(0);		/* blanks left by SO and SE */
EXT char *US INIT(Nullch);		/* start underline mode */
EXT char *UE INIT(Nullch);		/* end underline mode */
EXT char *UC INIT(Nullch);		/* underline a character, if that's how it's done */
EXT int UG INIT(0);		/* blanks left by US and UE */
EXT bool AM INIT(FALSE);		/* does terminal have automatic margins? */
EXT bool XN INIT(FALSE);		/* does it eat 1st newline after automatic wrap? */
EXT char PC INIT(0);		/* pad character for use by tputs() */
EXT short ospeed INIT(0);	/* terminal output speed, for use by tputs() */
EXT int LINES INIT(0), COLS INIT(0);	/* size of screen */
EXT int just_a_sec INIT(960);			/* 1 sec at current baud rate */
					/* (number of nulls) */

/* define a few handy macros */

#define backspace() tputs(BC,0,putchr) FLUSH
#define clear() tputs(CL,LINES,putchr) FLUSH
#define erase_eol() tputs(CE,1,putchr) FLUSH
#ifdef CLEAREOL
#define clear_rest() tputs(CD,LINES,putchr) FLUSH	/* PWP */
#define maybe_eol() if(erase_screen&&can_home_clear)tputs(CE,1,putchr) FLUSH
#endif CLEAREOL
#define underline() tputs(US,1,putchr) FLUSH
#define un_underline() tputs(UE,1,putchr) FLUSH
#define underchar() tputs(UC,0,putchr) FLUSH
#define standout() tputs(SO,1,putchr) FLUSH
#define un_standout() tputs(SE,1,putchr) FLUSH
#define up_line() tputs(UP,1,putchr) FLUSH
#define carriage_return() tputs(CR,1,putchr) FLUSH
#define dingaling() tputs(VB,1,putchr) FLUSH
#else
  ????????		/* up to you */
#endif

EXT int page_line INIT(1);	/* line number for paging in print_line (origin 1) */

void	term_init();
void	term_set();
#ifdef PUSHBACK
void	pushchar();
void	mac_init();
void	mac_line();
void	show_macros();
#endif
char	putchr();	/* routine for tputs to call */
bool	finish_command();
void	eat_typeahead();
void	settle_down();
#ifndef read_tty
    int		read_tty();
#endif
void	underprint();
#ifdef NOFIREWORKS
    void	no_sofire();
    void	no_ulfire();
#endif
void	getcmd();
int	get_anything();
void	in_char();
int	print_lines();
void	page_init();
void	pad();
void	printcmd();
void	rubout();
void	reprint();
#ifdef CLEAREOL
void	home_cursor();
#endif CLEAREOL
!STUFFY!FUNK!
echo Extracting head.c
cat >head.c <<'!STUFFY!FUNK!'
/* $Header: head.c,v 4.3 85/05/01 11:38:21 lwall Exp $
 *
 * $Log:	head.c,v $
 * Revision 4.3  85/05/01  11:38:21  lwall
 * Baseline for release with 4.3bsd.
 * 
 */

#include "EXTERN.h"
#include "common.h"
#include "artio.h"
#include "bits.h"
#include "util.h"
#include "INTERN.h"
#include "head.h"

bool first_one;		/* is this the 1st occurance of this header line? */

static char htypeix[26] =
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

void
head_init()
{
    register int i;

    for (i=HEAD_FIRST+1; i<HEAD_LAST; i++)
	htypeix[*htype[i].ht_name - 'a'] = i;
}

int
set_line_type(bufptr,colon)
char *bufptr;
register char *colon;
{
    char lc[LONGKEY+3];
    register char *t, *f;
    register int i, len;

    for (t=lc,f=bufptr; f<colon; f++, t++) {
	if (isspace(*f))
	/* guard against space before : */
	    break;
	*t = isupper(*f) ? tolower(*f) : *f;
    }
    *t = '\0';
    f = lc;				/* get lc into register */
    len = t - f;

    /* now scan the headtype table, backwards so we don't have to supply an
     * extra terminating value, using first letter as index, and length as
     * optimization to avoid calling subroutine strEQ unnecessarily.  Hauls.
     */
    
    if (islower(*f)) {
	for (i = htypeix[*f - 'a']; *htype[i].ht_name == *f; --i) {
	    if (len == htype[i].ht_length && strEQ(f, htype[i].ht_name)) {
		return i;
	    }
	}
    }
    return SOME_LINE;
}

void
start_header(artnum)
ART_NUM artnum;
{
    register int i;

    for (i=0; i<HEAD_LAST; i++) {
	htype[i].ht_minpos = -1;
	htype[i].ht_maxpos = 0;
    }
    in_header = SOME_LINE;
    first_one = FALSE;
#ifdef ASYNC_PARSE
    parsed_art = artnum;
#endif
}

bool
parseline(art_buf,newhide,oldhide)
char *art_buf;
int newhide, oldhide;
{
    if (*art_buf == ' ' || *art_buf == '\t')
					/* header continuation line? */
	return oldhide;
    else {				/* maybe another header line */
	char *s;

	if (first_one) {		/* did we just pass 1st occurance? */
	    first_one = FALSE;
	    htype[in_header].ht_maxpos = artpos;
					/* remember where line left off */
	}
	s = index(art_buf,':');
	if (s == Nullch || s-art_buf > LONGKEY+2) {
			    /* is it the end of the header? */
	    htype[PAST_HEADER].ht_minpos =
		(*art_buf == '\n') ? ftell(artfp) : artpos;
			    /* remember where body starts */
	    in_header = PAST_HEADER;
	}
	else {	/* it is a new header line */
	    in_header = set_line_type(art_buf,s);
	    first_one = (htype[in_header].ht_minpos < 0);
	    if (first_one)
		htype[in_header].ht_minpos = artpos;
	    if (htype[in_header].ht_flags & HT_HIDE)
		return newhide;
	}
    }
    return FALSE;			/* don't hide this line */
}

#ifdef ASYNC_PARSE
int
parse_maybe(artnum)
ART_NUM artnum;
{
    char tmpbuf[LBUFLEN];

    if (parsed_art == artnum)
	return 0;
    /* no maybe about it now */
    if (artopen(artnum) == Nullfp) {
	return -1;
    }
    start_header(artnum);
    while (in_header) {
	artpos = ftell(artfp);
	if (fgets(tmpbuf,LBUFLEN,artfp) == Nullch)
	    break;
	parseline(tmpbuf,FALSE,FALSE);
    }
    in_header = PAST_HEADER;
    return 0;
}
#endif

/* get the subject line for an article */

char *
fetchsubj(artnum,current_subject,copy)
ART_NUM artnum;				/* article to get subject from */
bool current_subject;			/* is it in a parsed header? */
bool copy;				/* do you want it savestr()ed? */
{
    char *s = Nullch, *t;

#ifdef CACHESUBJ
    if (!subj_list) {
	register ART_NUM i;
	

#ifndef lint
	subj_list =
	  (char**)safemalloc((MEM_SIZE)((OFFSET(lastart)+2)*sizeof(char *)));
#endif lint
	for (i=0; i<=OFFSET(lastart); i++)
	    subj_list[i] = Nullch;
    }
    if (!artnum || artnum > lastart)
	s = nullstr;
    else
	s = subj_list[OFFSET(artnum)];
#endif
    if (s == Nullch) {
	if (current_subject) {
	    s = fetchlines(artnum,SUBJ_LINE);
#ifdef CACHESUBJ
	    subj_list[OFFSET(artnum)] = s;
#endif
	}
	else {
	    s = safemalloc((MEM_SIZE)256);
	    *s = '\0';
	    if (artopen(artnum) != Nullfp) {
		do {
		    if (fgets(s,256,artfp) == Nullch)
			strcpy(s, "Title: \n");
		} while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8));
		s[strlen(s)-1] = '\0';
		t = index(s,':')+1;
		while (*t == ' ') t++;
		strcpy(s, t);
	    }
	    s = saferealloc(s, (MEM_SIZE)strlen(s)+1);
#ifdef CACHESUBJ
	    subj_list[OFFSET(artnum)] = s;
#endif 
	}
    }
#ifdef CACHESUBJ
    if (copy) {
	t = savestr(s);
	return t;
    }
    else
	return s;
#else
    if (copy)
	return s;
    else {
	safecpy(cmd_buf,s,CBUFLEN);	/* hope this is okay--we're */
	free(s);
	return cmd_buf;			/* really scraping for space here */
    }
#endif
}

/* get header lines from an article */

char *
fetchlines(artnum,which_line)
ART_NUM artnum;				/* article to get line from */
int which_line;				/* type of line desired */
{
    char *newbuf, *t, tmp_buf[LBUFLEN];
    register ART_POS curpos;
    int size;
    register ART_POS firstpos;
    register ART_POS lastpos;
    
#ifdef ASYNC_PARSE
    if (parse_maybe(artnum))
	artnum = 0;
#endif
    firstpos = htype[which_line].ht_minpos;
    lastpos = htype[which_line].ht_maxpos;
    if (!artnum || firstpos < 0 || artopen(artnum) == Nullfp) {
	newbuf = safemalloc((unsigned int)1);
	*newbuf = '\0';
	return newbuf;
    }
#ifndef lint
    size = lastpos - firstpos + 1;
#else
    size = Null(int);
#endif lint
#ifdef DEBUGGING
    if (debug && (size < 1 || size > 1000)) {
	printf("Firstpos = %ld, lastpos = %ld\n",(long)firstpos,(long)lastpos);
	gets(tmp_buf);
    }
#endif
    newbuf = safemalloc((unsigned int)size);
    *newbuf = '\0';
    fseek(artfp,firstpos,0);
    for (curpos = firstpos; curpos < lastpos; curpos = ftell(artfp)) {
	if (fgets(tmp_buf,LBUFLEN,artfp) == Nullch)
	    break;
	if (*tmp_buf == ' ' || *tmp_buf == '\t')
	    t = tmp_buf;
	else
	    t = index(tmp_buf,':')+1;
	if (t == Nullch)
	    break;
	else {
	    while (*t == ' ' || *t == '\t') t++;
	    safecat(newbuf,t,size);
	}
    }
    return newbuf;
}

!STUFFY!FUNK!
echo Extracting README
cat >README <<'!STUFFY!FUNK!'
			Rn Kit, Version 4.3

		    Copyright (c) 1985, Larry Wall

You may copy the rn kit in whole or in part as long as you don't try to
make money off it, or pretend that you wrote it.
--------------------------------------------------------------------------

Please read all the directions below before you proceed any further, and
then follow them carefully.  Failure to do so may void your warranty. :-)

After you have unpacked your kit, you should have all the files listed
in MANIFEST.

Installation

1)  Run Configure.  This will figure out various things about your system.
    Some things Configure will figure out for itself, other things it will
    ask you about.  It will then proceed to make config.h, config.sh, Makefile,
    and a bunch of shell scripts.  It will also do a make depend for you.
    You might possibly have to trim # comments from the front of Configure
    if your sh doesn't handle them, but all other # comments will be taken
    care of.

2)  Glance through config.h and common.h to make sure system dependencies
    are correct.  Most of them should have been taken care of by running
    the Configure script.

    If you have any additional changes to make to the C definitions, they
    can be done in the Makefile, in config.h, or in common.h.  If you have
    strange mailboxes on your system you should modify mbox.saver to correctly
    append an article to a mailbox or folder.

    If you are on a machine with limited address space, you may have to
    remove some of the special functions of rn to make it fit.  This is
    easily done by undefining symbols in the System Dependencies section
    of common.h.  You should run "make depend" again to be safe.

3)  make

    This will attempt to make rn in the current directory.

4)  make install

    This will put rn, newsetup, newsgroups, Pnews, and Rnmail into a public
    directory (normally /usr/local/bin), and put a number of files into the
    private rn library (normally /usr/lib/news/rn).  It will also try to put
    the man pages in a reasonable place.

5)  Read the manual entry before running rn.  It's quite different from
    readnews.

6)  Install the Xref patch to header.h, header.c, and inews.c.  These patches
    are found in header.h.?.pat, header.c.?.pat, and inews.c.?.pat, where ? is
    either 1 for news 2.10.1 (or earlier) or 2 for 2.10.2.  Last I heard,
    2.10.3 was going to have the Xref patch built in.  The purpose
    of the Xref patch is to put an Xref: line in the header of articles
    posted to more than one newsgroup.  Rn uses this line to keep from showing
    such postings more than once.  Other than that rn will work without
    this patch, so if you just want to try out rn you can delay putting in
    the patch.

    When you put in the patch and recompile inews, don't forget to define
    DOXREFS in the makefile for inews.  Do NOT define LINKART unless you
    are a Eunice site and really want to do that.  In fact, if you are not
    a Eunice site you needn't install the LINKART part of the patch.

    NOTE: the Makefile that comes with some of the older news systems does not
    have all the dependencies quite right.  In particular, ifuncs.c may
    not recompile when you change header.h.  If this happens when you install
    the Xref patch, inews will start dumping core.  Make sure both inews.o
    and ifuncs.o depend on header.h in the Makefile.

    Eunice users: the inews.c patch contains both the Xref patch and a LINKART
    patch to put a form of "symbolic link" between articles posted to
    multiple newsgroups.  What it does is to put the article into the first
    newsgroup on the Newsgroups line, and in subsequent newsgroups it just
    puts a little file containing the name of the article in the first
    newsgroup.  Rn (when compiled with the LINKART option) is clever about
    these pseudo-articles, and ends up opening the right one.  YOU WILL NOT
    be able to use readnews or vnews on your system without modification,
    though.  If you do this, be sure to define both DOXREFS and LINKART in
    the makefile for inews.c.  If you are using the option in inews that
    copies instead of linking, you will want to rip that out.

    NOTE: if you transmit articles to other systems using xfernews with the
    U flag, Xref's can leak out of your system, as can Date-Received's.  This
    may make neighboring sites unhappy unless they also have the Xref patch
    installed.  For now, either don't use the U flag, or fix the inews/xfernews
    interaction.

7)  Try rn, and play with some of the switches.  You may want to make -/
    default on your system.  This is done in common.h.  You may want to modify
    which header lines are displayed by default--this is done in head.h.

    To change default values of enviroment variables on a system-wide basis
    without recompiling rn, put switches into file INIT in the rn library.

8)  IMPORTANT!  Help save the world!  Communicate any problems and
    suggested patches to me, lwall at sdcrdcf.UUCP (Larry Wall), so we can
    keep the world in sync.  If you have a problem, there's someone else
    out there who either has had or will have the same problem.

    If possible, send in patches such that the patch program will apply them.
    Context diffs are the best, then normal diffs.  Don't send ed scripts--
    I've probably changed my copy since the version you have.

    Watch for rn patches in net.sources.bugs.  Patches will generally be
    applyable (is that a word?) by the patch program.  If you are just
    now bringing up news and aren't sure how many patches there are, write
    to me and I'll send any you don't have.

9)  If you are going to hack on rn, please read the HACKERSGUIDE first.
!STUFFY!FUNK!
echo Extracting MANIFEST
cat >MANIFEST <<'!STUFFY!FUNK!'
After all the rn kits are run you should have the following files:

Filename	Kit Description
--------	--- -----------
Configure        2  A shell script that installs everything system dependent.
EXTERN.h         9  When included, makes other includes not belong to me.
HACKERSGUIDE     5  A brief guide to the contorted innards of rn.
INIT             3  Sample system-wide switch file. (NEW)
INTERN.h         9  When included, makes other includes belong to me.
MANIFEST         7  This list of files.
Makefile.SH      7  The makefile.
NEW              3  List of new features with 4.3 rn.
Pnews.1          8  Manual page for Pnews.
Pnews.SH         5  A news posting shell script that knows about -h.
README           7  Installation instructions.
Rnmail.1         8  Manual page for Rnmail.
Rnmail.SH        7  A mailer that knows about -h.
Wishlist         8  What the next version wants in it.
addng.c          8  Routines for scanning the active file for new newsgroups.
addng.h          9  Public info regarding addng.c.
art.c            4  Routines to display an article.
art.h            8  Public info regarding art.c.
art.help.SH      7  Shell script for help at the article level.
artio.c          8  Reserved for the article abstract type, someday.
artio.h          8  Public info regarding artio.c.
artsrch.c        6  Routines for searching among articles.
artsrch.h        8  Public info regarding artsrch.c.
artstate.h       8  Info on the current state of the article.
backpage.c       8  Routines for paging backwards in articles.
backpage.h       8  Public info regarding backpage.c.
bits.c           3  Bitmap management functions.
bits.h           8  Public info regarding bits.c.
cheat.c          7  Routines to do lookahead of several types.
cheat.h          8  Public info regarding cheat.c.
common.h         3  Global info.
final.c          7  Finalization (exit) routines.
final.h          8  Public info regarding final.c.
head.c           7  Header parsing routines.
head.h           7  Public info regarding head.c.
header.c.1.pat   8  DOXREFS patch for header.c for 2.10.1 news.
header.c.2.pat   8  DOXREFS patch for header.c for 2.10.2 news.
header.h.1.pat   8  DOXREFS patch for header.h for 2.10.1 news.
header.h.2.pat   7  DOXREFS patch for header.h for 2.10.2 news.
help.c           6  Help routines.
help.h           9  Public info regarding help.c.
inews.c.1.pat    6  DOXREFS and LINKART patches for 2.10.1 news.
inews.c.2.pat    6  DOXREFS and LINKART patches for 2.10.2 news.
init.c           1  Initialization (startup) routines.
init.h           9  Public info regarding init.c.
intrp.c          3  Filename expansion and % interpretation routines.
intrp.h          8  Public info regarding intrp.c.
kfile.c          7  KILL file routines.
kfile.h          8  Public info regarding kfile.c.
kitleader        8  Shell script to produce front of kit.
kitlists.c       8  Knapsack packer.
kittrailer       8  Shell script to produce end of kit.
last.c           8  Routines for handling the .rnlast file.
last.h           8  Public info regarding last.c.
makedepend.SH    8  Shell script to generate make dependencies.
makedir.SH       8  Shell script to make nested subdirectories.
makedist         4  Shell script to make a distribution kit.
makekit          8  Shell script to make a kit file.
manifake         8  Shell script to make MANIFEST.new file.
manimake         8  Shell script to make MANIFEST file.
mbox.saver.SH    8  Shell script to save an article to a mailbox.
ndir.c           8  4.2 directory routine emulation.
ndir.h           8  Public info regarding ndir.c.
newsetup.1       8  Manual page for newsetup.
newsetup.SH      7  Shell script to create a .newsrc file.
newsgroups.1     8  Manual page for newsgroups.
newsgroups.SH    8  Shell script to list unsubscribed newsgroups.
newsnews.SH      8  A motd-like file that rn may print at startup.
ng.c             4  Routines to display a newsgroup.
ng.h             1  Public info regarding ng.c.
ng.help.SH       8  Shell script to do newsgroup selection help.
ngdata.c         7  General data fetching routines for a newsgroup.
ngdata.h         8  Public info regarding ngdata.c.
ngsrch.c         7  Routines to search among newsgroups.
ngsrch.h         8  Public info regarding ngsrch.c.
ngstuff.c        4  Support routines for ng.c.
ngstuff.h        8  Public info regarding ng.c.
norm.saver.SH    8  Shell script to save an article to a normal file.
only.c           8  Routines to perform newsgroup restriction.
only.h           8  Public info regarding only.c.
pager.help.SH    8  Shell script for help at the pager level.
rcln.c           5  Routines to mung a .newsrc line.
rcln.h           8  Public info regarding rcln.c.
rcstuff.c        2  Routines to mung the .newsrc file.
rcstuff.h        8  Public info regarding rcstuff.c.
respond.c        6  Various routines for doing things with articles.
respond.h        8  Public info regarding respond.c.
rn.1             1  Manual pages for rn. PLEASE READ.
rn.c             5  Main program.
rn.h             8  Public info regarding rn.c.
search.c         4  Regular expression processing ala emacs.
search.h         8  Public info regarding search.c.
subs.help.SH     8  Shell script for help for escape substitutions.
sw.c             6  Switch processing routines.
sw.h             9  Public info regarding switch.c.
term.c           5  Terminal interface routines.
term.h           7  Public info regarding term.c.
util.c           6  Utility routines.
util.h           8  Public info regarding util.c.
!STUFFY!FUNK!
echo Extracting Rnmail.SH
cat >Rnmail.SH <<'!STUFFY!FUNK!'
case $CONFIG in
    '') . config.sh ;;
esac
echo "Extracting Rnmail (with variable substitutions)"
$spitshell >Rnmail <<!GROK!THIS!
$startsh
# $Header: Rnmail.SH,v 4.3 85/05/01 11:34:18 lwall Exp $
# 
# $Log:	Rnmail.SH,v $
# Revision 4.3  85/05/01  11:34:18  lwall
# Baseline for release with 4.3bsd.
# 
#
# syntax: Rnmail -h headerfile [oldart]		or
#         Rnmail destination-list 		or just
#         Rnmail

export PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)

# System dependencies

mailer="${mailer-/bin/mail}"
# if you change this to something that does signatures, take out signature code

# your site name
case $portable in
define) sitename=\`$hostcmd\` ;;
undef) sitename="$sitename" ;;
esac
# your organization name
orgname="$orgname"
# what pager you use--if you have kernal paging use cat
pager="\${PAGER-$pager}"
# how you derive full names, bsd, usg, or other
nametype="$nametype"
# default editor
defeditor="$defeditor"
# how not to do a newline with echo
n="$n"
c="$c"

test=${test-test}
sed=${sed-sed}
echo=${echo-echo}
cat=${cat-cat}
grep=${grep-grep}
rm=${rm-rm}

!GROK!THIS!
$spitshell >>Rnmail <<'!NO!SUBS!'
tmpart=/tmp/rnmail$$
dotdir=${DOTDIR-${HOME-$LOGDIR}}

headerfile=""
case $# in
0) ;;
*)  case $1 in
    -h)
	headerfile="$2"
	case $# in
	3) oldart=$3 ;;
	esac
	;;
    esac
    ;;
esac

case $headerfile in
'')
    case $# in
    0)
	to=h
	while $test "$to" = h ; do
	    $echo ""
	    $echo $n "To: $c"
	    read to
	    case $to in
	    h)
		$cat <<'EOH'

Type the net address of those people that you wish the message sent to.
Note that you will be asked later for additional addresses of people to
whom the message is not addressed but you wish to get copies.

Separate multiple addresses with spaces.

EOH
		;;
	    esac
	done
	;;
    *)
	to="$*"
	;;
    esac
    to=`$echo "$to" | $sed 's/  */ /g'`

    title=h
    while $test "$title" = h ; do
	$echo ""
	$echo $n "Title/Subject: $c"
	read title
	case $title in
	h)
	    $cat <<'EOH'

Type the title for your message.  
EOH
	    ;;
	esac
    done

# now build a file with a header for them to edit
    
    orgname=${ORGANIZATION-$orgname}
    case $orgname in
    /*) orgname=`$cat $orgname` ;;
    esac

    $cat > $tmpart <<EOHeader
To: $to
Subject: $title
Organization: $orgname
Cc:
Bcc:

EOHeader

    ;;
*)
    $cat < $headerfile  > $tmpart
    ;;
esac


file=h
while $test "$file" = h ; do
    $echo ""
    $echo $n "Prepared file to include [none]: $c"
    read file
    case $file in
    h)
	$cat <<'EOH'

If you have already produced the body of your message, type the filename
for it here.  If you just want to proceed directly to the editor, type a
RETURN.  In any event, you will be allowed to edit as many times as you
want before you send off the message.
EOH
	;;
    '')
	$echo "" >> $tmpart
	state=edit
	;;
    *)
	$cat $file >>$tmpart
	state=ask
	;;
    esac
done

$echo ""

while true ; do
    case $state in
    edit)
	rescue="sleep 1; $cat $tmpart >>${HOME-$LOGDIR}/dead.letter ; $echo saved in ${HOME-$LOGDIR}/dead.letter ; $rm -f $tmpart; exit"
	trap "$rescue" 1
	trap : 2
	tmp=h
	while $test "$tmp" = h ; do
	    $echo $n "Editor [${VISUAL-${EDITOR-$defeditor}}]: $c"
	    read tmp
	    case $tmp in
	    h)
		$cat <<'EOH'

Type a return to get the default editor, or type the name of the editor you
prefer.  The default editor depends on the VISUAL and EDITOR environment
variables.

EOH
		;;
	    '')
		;;
	    *)
		VISUAL=$tmp
		export VISUAL
		;;
	    esac
	done
	${VISUAL-${EDITOR-$defeditor}} $tmpart $oldart
	trap "$rescue" 2
	state=ask
	;;
	
    ask)
	$echo ""
	$echo $n "Send, abort, edit, or list? $c"
	read ans
	
	case $ans in
	a*)
	    state=rescue
	    ;;
	e*)
	    state=edit
	    ;;
	l*)
	    $pager $tmpart
	    state=ask
	    ;;
	s*)
	    state=send
	    ;;
	h*)
	    $cat <<'EOH'

Type s to send the message, a to abort and append the message to dead.letter,
e to edit the message again, or l to list the message.
EOH
	esac
	;;
    
    send)
	if $test -f $dotdir/.signature; then
	    echo $n "Append .signature file? [y] $c"
	    read ans
	    case $ans in
	    ''|y*) cat $dotdir/.signature >> $tmpart
	    esac
	fi
	case $mailer in
	*sendmail)
	    $mailer -t <$tmpart
	    ;;
# but recmail does not know about Bcc, alas
	*recmail)
	    $mailer <$tmpart
	    ;;
	*)
	    set X `$sed <$tmpart -n -e '/^To:/{' -e 's/To: *//p' -e q -e '}'`
	    shift
	    set X "$@" `$sed <$tmpart -n -e '/^Cc:/{' -e 's/Cc: *//p' -e q -e '}'`
	    shift
	    set X "$@" `$sed <$tmpart -n -e '/^Bcc:/{' -e 's/Bcc: *//p' -e q -e '}'`
	    shift
	    $grep -v "^Bcc:"  <$tmpart | $mailer "$@"
	    ;;
	esac
	case $? in
	0)
	    state=cleanup
	    ;;
	*)
	    state=rescue
	    ;;
	esac
	;;
    rescue)
	$cat $tmpart >> ${HOME-$LOGDIR}/dead.letter
	$echo "Message saved to ${HOME-$LOGDIR}/dead.letter"
	state=cleanup
	;;
    cleanup)
	$rm -f $tmpart
	exit
	;;
    esac
done
!NO!SUBS!
$eunicefix Rnmail
chmod 755 Rnmail
!STUFFY!FUNK!
echo Extracting kfile.c
cat >kfile.c <<'!STUFFY!FUNK!'
/* $Header: kfile.c,v 4.3 85/05/01 11:41:53 lwall Exp $
 *
 * $Log:	kfile.c,v $
 * Revision 4.3  85/05/01  11:41:53  lwall
 * Baseline for release with 4.3bsd.
 * 
 */

#include "EXTERN.h"
#include "common.h"
#include "term.h"
#include "util.h"
#include "artsrch.h"
#include "ng.h"
#include "bits.h"
#include "intrp.h"
#include "ngstuff.h"
#include "rcstuff.h"
#include "rn.h"
#include "INTERN.h"
#include "kfile.h"

static bool exitcmds = FALSE;

void
kfile_init()
{
    ;
}

#ifndef KILLFILES
int
edit_kfile()
{
    notincl("^K");
    return -1;
}

#else KILLFILES

char killglobal[] = KILLGLOBAL;
char killlocal[] = KILLLOCAL;

void
mention(str)
char *str;
{
#ifdef NOFIREWORKS
    no_sofire();
#endif
    standout();
    fputs(str,stdout);
    un_standout();
    putchar('\n');
    fflush(stdout);
}

int
do_kfile(kfp,entering)
FILE *kfp;
int entering;
{
    art = lastart+1;
    fseek(kfp,0L,0);			/* rewind file */
    while (fgets(buf,LBUFLEN,kfp) != Nullch) {
	buf[strlen(buf)-1] = '\0';
	if (strnEQ(buf,"THRU",4)) {
	    firstart = atol(buf+4)+1;
	    continue;
	}
	if (*buf == 'X') {		/* exit command? */
	    if (entering) {
		exitcmds = TRUE;
		continue;
	    }
	    strcpy(buf,buf+1);
	}
	else {
	    if (!entering)
		continue;
	}
	if (*buf == '&') {
	    mention(buf);
	    switcheroo();
	}
	else if (*buf == '/' && firstart <= lastart) {
	    mention(buf);
	    switch (art_search(buf, (sizeof buf), FALSE)) {
	    case SRCH_ABORT:
		continue;
	    case SRCH_INTR:
#ifdef VERBOSE
		IF(verbose)
		    printf("\n(Interrupted at article %ld)\n",(long)art)
		      FLUSH;
		ELSE
#endif
#ifdef TERSE
		    printf("\n(Intr at %ld)\n",(long)art) FLUSH;
#endif
		return -1;
	    case SRCH_DONE:
		break;
	    case SRCH_SUBJDONE:
		fputs("\tsubject not found (???)\n",stdout) FLUSH;
		break;
	    case SRCH_NOTFOUND:
		fputs("\tnot found\n",stdout) FLUSH;
		break;
	    case SRCH_FOUND:
		fputs("\tfound\n",stdout) FLUSH;
	    }
	}
    }
    return 0;
}

void
kill_unwanted(starting,message,entering)
ART_NUM starting;
char *message;
int entering;
{
    bool intr = FALSE;			/* did we get an interrupt? */
    ART_NUM oldfirst;
    bool anytokill = (toread[ng] > 0);

    if (localkfp || globkfp) {
	if (!entering && !exitcmds)
	    return;
	exitcmds = FALSE;
	oldfirst = firstart;
	firstart = starting;
	clear();
	if (message)
	    fputs(message,stdout) FLUSH;
	if (localkfp)
	    intr = do_kfile(localkfp,entering);
	if (globkfp && !intr)
	    intr = do_kfile(globkfp,entering);
	if (entering && localkfp && !intr)
	    setthru(lastart);
	putchar('\n') FLUSH;
	if (entering)
	    get_anything();
	if (anytokill)			/* if there was anything to kill */
	    forcelast = FALSE;		/* allow for having killed it all */
	firstart = oldfirst;
    }
}

void
setthru(thru)
ART_NUM thru;
{
    FILE *newkfp;

    fseek(localkfp,0L,0);		/* rewind current file */
    strcpy(buf,filexp(getval("KILLLOCAL",killlocal)));
    UNLINK(buf);			/* to prevent file reuse */
    if (newkfp = fopen(buf,"w")) {
	fprintf(newkfp,"THRU %ld\n",(long)thru);
	while (fgets(buf,LBUFLEN,localkfp) != Nullch) {
	    if (strnEQ(buf,"THRU",4))
		continue;
	    fputs(buf,newkfp);
	}
	fclose(newkfp);
	open_kfile(KF_LOCAL);		/* and reopen local file */
    }
    else
	printf(cantcreate,buf) FLUSH;
}

/* edit KILL file for newsgroup */

int
edit_kfile()
{
    int r = -1;

    if (in_ng)
	strcpy(buf,filexp(getval("KILLLOCAL",killlocal)));
    else
	strcpy(buf,filexp(getval("KILLGLOBAL",killglobal)));
    if ((r = makedir(buf,MD_FILE)) >= 0) {
	sprintf(cmd_buf,"%s %s",
	    filexp(getval("VISUAL",getval("EDITOR",defeditor))),buf);
	printf("\nEditing %s KILL file:\n%s\n",
	    (in_ng?"local":"global"),cmd_buf) FLUSH;
	resetty();			/* make sure tty is friendly */
	r = doshell(sh,cmd_buf);/* invoke the shell */
	noecho();			/* and make terminal */
	crmode();			/*   unfriendly again */
	open_kfile(in_ng);
    }
    else
	printf("Can't make %s\n",buf) FLUSH;
    return r;
}

void
open_kfile(local)
int local;
{
    char *kname = filexp(local ?
	getval("KILLLOCAL",killlocal) :
	getval("KILLGLOBAL",killglobal)
	);
    
    stat(kname,&filestat);
    if (!filestat.st_size)		/* nothing in the file? */
	UNLINK(kname);			/* delete the file */
    if (local) {
	if (localkfp)
	    fclose(localkfp);
	localkfp = fopen(kname,"r");
    }
    else {
	if (globkfp)
	    fclose(globkfp);
	globkfp = fopen(kname,"r");
    }
}

void
kf_append(cmd)
char *cmd;
{
    strcpy(cmd_buf,filexp(getval("KILLLOCAL",killlocal)));
    if (makedir(cmd_buf,MD_FILE) >= 0) {
#ifdef VERBOSE
	IF(verbose)
	    printf("\nDepositing command in %s...",cmd_buf);
	ELSE
#endif
#ifdef TERSE
	    printf("\n--> %s...",cmd_buf);
#endif
	fflush(stdout);
	sleep(2);
	if ((tmpfp = fopen(cmd_buf,"a")) != Nullfp) {
	    fseek(tmpfp,0L,2);		/* get to EOF for sure */
	    fprintf(tmpfp,"%s\n",cmd);
	    fclose(tmpfp);
	    fputs("done\n",stdout) FLUSH;
	}
	else
	    printf(cantopen,cmd_buf) FLUSH;
    }
}
#endif KILLFILES
!STUFFY!FUNK!
echo Extracting ngdata.c
cat >ngdata.c <<'!STUFFY!FUNK!'
/* $Header: ngdata.c,v 4.3 85/05/01 11:44:38 lwall Exp $
 *
 * $Log:	ngdata.c,v $
 * Revision 4.3  85/05/01  11:44:38  lwall
 * Baseline for release with 4.3bsd.
 * 
 */

#include "EXTERN.h"
#include "common.h"
#include "ndir.h"
#include "rcstuff.h"
#include "rn.h"
#include "intrp.h"
#include "final.h"
#include "rcln.h"
#include "INTERN.h"
#include "ngdata.h"

void
ngdata_init()
{
/* The following is only for systems that do not zero globals properly */
#ifdef ZEROGLOB
# ifdef CACHEFIRST
    for (i=0; i<MAXRCLINE; i++)
	abs1st[i] = 0;
# endif
#endif	/* ZEROGLOB */

    /* open the active file */

    actfp = fopen(filexp(ACTIVE),"r");
    if (actfp == Nullfp) {
	printf(cantopen,filexp(ACTIVE)) FLUSH;
	finalize(1);
    }
}

/* find the maximum article number of a newsgroup */

ART_NUM
getngsize(num)
register NG_NUM num;
{
    register int len;
    register char *nam;
    char tmpbuf[80];
    ART_POS oldsoft;

    nam = rcline[num];
    len = rcnums[num] - 1;
    softtries++;
#ifdef DEBUGGING
    if (debug & DEB_SOFT_POINTERS)
	printf("Softptr = %ld\n",(long)softptr[num]) FLUSH;
#endif
    oldsoft = softptr[num];
    if ((softptr[num] = findact(tmpbuf, nam, len, (long)oldsoft)) >= 0) {
	if (softptr[num] != oldsoft) {
	    softmisses++;
	    writesoft = TRUE;
	}
    }
    else {
	softptr[num] = 0;
	if (rcchar[num] == ':')		/* unsubscribe quietly */
	    rcchar[num] = NEGCHAR;
	return TR_BOGUS;		/* well, not so quietly, actually */
    }
	
#ifdef DEBUGGING
    if (debug & DEB_SOFT_POINTERS) {
	printf("Should be %ld\n",(long)softptr[num]) FLUSH;
    }
#endif
#ifdef MININACT
    {
	register char *s;
	ART_NUM tmp;

	for (s=tmpbuf+len+1; isdigit(*s); s++) ;
	if (tmp = atol(s))
#ifdef CACHEFIRST
	    abs1st[num] = tmp;
#else
	    abs1st = tmp;
#endif
    }
#endif
    return atol(tmpbuf+len+1);
}

ACT_POS
findact(outbuf,nam,len,suggestion)
char *outbuf;
char *nam;
int len;
long suggestion;
{
    ACT_POS retval;

    fseek(actfp,100000L,1);	/* hopefully this forces a reread */
    if (suggestion == 0L || fseek(actfp,suggestion,0) < 0 ||
      fgets(outbuf,80,actfp) == Nullch ||
      outbuf[len] != ' ' ||
      strnNE(outbuf,nam,len)) {
#ifdef DEBUGGING
	if (debug & DEB_SOFT_POINTERS)
	    printf("Missed, looking for %s in %sLen = %d\n",nam,outbuf,len)
	      FLUSH;
#endif
	fseek(actfp,0L,0);
#ifndef lint
	retval = (ACT_POS)ftell(actfp);
#else
	retval = Null(ACT_POS);
#endif lint
	while (fgets(outbuf,80,actfp) != Nullch) {
	    if (outbuf[len] == ' ' && strnEQ(outbuf,nam,len))
		return retval;
#ifndef lint
	    retval = (ACT_POS) ftell(actfp);
#endif lint
	}
	return (ACT_POS) -1;		/* well, not so quietly, actually */
    }
    else
#ifndef lint
	return (ACT_POS) suggestion;
#else
	return retval;
#endif lint
    /*NOTREACHED*/
}

/* determine the absolutely first existing article number */

ART_NUM
getabsfirst(ngnum,ngsize)
register NG_NUM ngnum;
ART_NUM ngsize;
{
    register ART_NUM a1st;
#ifndef MININACT
    char dirname[MAXFILENAME];
#endif

#ifdef CACHEFIRST
    if (a1st = abs1st[ngnum])
	return a1st;
#endif
#ifdef MININACT
    getngsize(ngnum);
# ifdef CACHEFIRST
    return abs1st[ngnum];
# else
    return abs1st;
# endif
#else not MININACT
    sprintf(dirname,"%s/%s",spool,getngdir(rcline[ngnum]));
    a1st = getngmin(dirname,0L);
    if (!a1st)				/* nothing there at all? */
	a1st = ngsize+1;		/* aim them at end of newsgroup */
# ifdef CACHEFIRST
    abs1st[ngnum] = a1st;
# endif
    return a1st;
#endif MININACT
}

/* scan a directory for minimum article number greater than floor */

ART_NUM
getngmin(dirname,floor)
char *dirname;
ART_NUM floor;
{
    register DIR *dirp;
    register struct direct *dp;
    register ART_NUM min = 1000000;
    register ART_NUM maybe;
    register char *p;
    char tmpbuf[128];
    
    dirp = opendir(dirname);
    if (!dirp)
	return 0;
    while ((dp = readdir(dirp)) != Null(struct direct *)) {
	if ((maybe = atol(dp->d_name)) < min && maybe > floor) {
	    for (p = dp->d_name; *p; p++)
		if (!isdigit(*p))
		    goto nope;
	    if (*dirname == '.' && !dirname[1])
		stat(dp->d_name, &filestat);
	    else {
		sprintf(tmpbuf,"%s/%s",dirname,dp->d_name);
		stat(tmpbuf, &filestat);
	    }
	    if (! (filestat.st_mode & S_IFDIR))
		min = maybe;
	}
      nope:
	;
    }
    closedir(dirp);
    return min==1000000 ? 0 : min;
}

!STUFFY!FUNK!
echo Extracting final.c
cat >final.c <<'!STUFFY!FUNK!'
/* $Header: final.c,v 4.3 85/05/01 11:38:08 lwall Exp $
 *
 * $Log:	final.c,v $
 * Revision 4.3  85/05/01  11:38:08  lwall
 * Baseline for release with 4.3bsd.
 * 
 */

#include "EXTERN.h"
#include "common.h"
#include "util.h"
#include "term.h"
#include "ng.h"
#include "init.h"
#include "bits.h"
#include "last.h"
#include "rcstuff.h"
#include "INTERN.h"
#include "final.h"

void
final_init()
{
#ifdef SIGTSTP
    sigset(SIGTSTP, stop_catcher);	/* job control signals */
    sigset(SIGCONT, cont_catcher);	/* job control signals */
#endif

    sigset(SIGINT, int_catcher);	/* always catch interrupts */
    sigset(SIGHUP, sig_catcher);	/* and hangups */
#ifndef lint
    sigignore(SIGEMT);
#endif lint

    sigset(SIGILL, sig_catcher);
    sigset(SIGTRAP, sig_catcher);
    sigset(SIGFPE, sig_catcher);
    sigset(SIGBUS, sig_catcher);
    sigset(SIGSEGV, sig_catcher);
    sigset(SIGSYS, sig_catcher);
    sigset(SIGTERM, sig_catcher);
#ifdef SIGXCPU
    sigset(SIGXCPU, sig_catcher);
#endif
#ifdef SIGXFSZ
    sigset(SIGXFSZ, sig_catcher);
#endif
}

void					/* very much void */
finalize(status)
int status;
{
    if (bizarre)
	resetty();
    UNLINK(lockname);
    if (status < 0) {
	chdir("/usr/tmp");
	sigset(SIGILL,SIG_DFL);
	abort();
    }
    exit(status);
}

/* come here on interrupt */

int
int_catcher()
{
    sigset(SIGINT,int_catcher);
#ifdef DEBUGGING
    if (debug)
	write(2,"int_catcher\n",12);
#endif
    if (!waiting) {
	if (int_count) {		/* was there already an interrupt? */
	    write(2,"\nBye-bye.\n",10);
	    sig_catcher(0);		/* emulate the other signals */
	}
	int_count++;
    }
}

/* come here on signal other than interrupt, stop, or cont */

int
sig_catcher(signo)
{
#ifdef VERBOSE
    static char *signame[] = {
	"",
	"HUP",
	"INT",
	"QUIT",
	"ILL",
	"TRAP",
	"IOT",
	"EMT",
	"FPE",
	"KILL",
	"BUS",
	"SEGV",
	"SYS",
	"PIPE",
	"ALRM",
	"TERM",
	"???"
#ifdef SIGTSTP
	,"STOP",
	"TSTP",
	"CONT",
	"CHLD",
	"TTIN",
	"TTOU",
	"TINT",
	"XCPU",
	"XFSZ"
#ifdef SIGPROF
	,"VTALARM",
	"PROF"
#endif
#endif
	};
#endif

#ifdef SIGTTOU
#ifndef lint
    sigignore(SIGTTOU);
#endif lint
#endif
#ifdef DEBUGGING
    if (debug) {
	printf("\nSIG%s--.newsrc not restored in debug\n",signame[signo]);
	finalize(-1);
    }
#endif
    if (panic)
	abort();
    (void) sigset(SIGILL,SIG_DFL);
    panic = TRUE;			/* disable terminal I/O */
    if (doing_ng) {			/* need we reconstitute rc line? */
	yankback();
	restore_ng();			/* then do so (hope this works) */
    }
    doing_ng = FALSE;
    if (rc_changed)			/* need we write .newsrc out? */
	write_rc();			/* then do so */
    rc_changed = FALSE;
    if (signo != SIGHUP)
#ifdef VERBOSE
	IF(verbose)
	    printf("\nCaught %s%s--.newsrc restored\n",
		signo ? "a SIG" : "an internal error", signame[signo]);
	ELSE
#endif
#ifdef TERSE
	    printf("\nSignal %d--bye bye\n",signo);
#endif
    switch (signo) {
    case SIGBUS:
    case SIGILL:
    case SIGSEGV:
	finalize(-signo);
    }
    finalize(1);				/* and blow up */
}

#ifdef SIGTSTP
/* come here on stop signal */

int
stop_catcher()
{
    if (!waiting) {
	checkpoint_rc();		/* good chance of crash while stopped */
	resetty();			/* this is the point of all this */
#ifdef DEBUGGING
	if (debug)
	    write(2,"stop_catcher\n",13);
#endif
	sigset(SIGTSTP,SIG_DFL);	/* enable stop */
#ifdef BSD42
	sigsetmask(sigblock(0) & ~(1 << (SIGTSTP-1)));
#endif
	kill(0,SIGTSTP);		/* and do the stop */
    }
    sigset(SIGTSTP,stop_catcher);	/* unenable the stop */
}

/* come here on cont signal */

int
cont_catcher()
{
    sigset(SIGCONT,cont_catcher);
    savetty();
#ifdef MAILCALL;
    mailcount = 0;			/* force recheck */
#endif
    if (!panic) {
	if (!waiting) {
#ifdef DEBUGGING
	    if (debug)
		write(2,"cont_catcher\n",13);
#endif
	    noecho();			/* set no echo */
	    crmode();			/* set cbreak mode */
	    forceme("\f");		/* cause a refresh */
					/* (defined only if TIOCSTI defined) */
	}
    }
}
#endif

!STUFFY!FUNK!
echo Extracting head.h
cat >head.h <<'!STUFFY!FUNK!'
/* $Header: head.h,v 4.3 85/05/01 11:38:31 lwall Exp $
 *
 * $Log:	head.h,v $
 * Revision 4.3  85/05/01  11:38:31  lwall
 * Baseline for release with 4.3bsd.
 * 
 */

#define HEAD_FIRST 1

/* types of header lines (if only C really believed in enums)
 * (These must stay in alphabetic order at least in the first letter.
 * Within each letter it helps to arrange in increasing likelihood.)
 */

#define PAST_HEADER	0	/* body */
#define SOME_LINE	1	/* unrecognized */
#define ARTID_LINE	2	/* article-i.d. */
#define APPR_LINE	3	/* approved */
#define DIST_LINE	4	/* distribution */
#define DATE_LINE	5	/* date */
#define RECEIVED_LINE	6	/* date-received */
#define EXPIR_LINE	7	/* expires */
#define FOLLOW_LINE	8	/* followup-to */
#define FROM_LINE	9	/* from */
#define KEYW_LINE	10	/* keywords */
#define LINES_LINE	11	/* lines */
#define MESSID_LINE	12	/* message-id */
#define NFFR_LINE	13	/* nf-from */
#define NFID_LINE	14	/* nf-id */
#define NGS_LINE	15	/* newsgroups */
#define ORG_LINE	16	/* organization */
#define PATH_LINE	17	/* path */
#define POSTED_LINE	18	/* posted */
#define PVER_LINE	19	/* posting-version */
#define REPLY_LINE	20	/* reply-to */
#define REFS_LINE	21	/* references */
#define RVER_LINE	22	/* relay-version */
#define SENDER_LINE	23	/* sender */
#define SUMRY_LINE	24	/* summary */
#define SUBJ_LINE	25	/* subject */
#define XREF_LINE	26	/* xref */

#define HEAD_LAST	27	/* one more than the last one above */

struct headtype {
    char *ht_name;		/* header line identifier */
#ifdef pdp11
    short ht_minpos;
    short ht_maxpos;
#else
    ART_POS ht_minpos;		/* pointer to beginning of line in article */
    ART_POS ht_maxpos;		/* pointer to end of line in article */
#endif
    char ht_length;		/* could make these into nybbles but */
    char ht_flags;		/* it wouldn't save space normally */
};				/* due to alignment considerations */

#define HT_HIDE 1	/* -h on this line */
#define HT_MAGIC 2	/* do any special processing on this line */

/* This array must stay in the same order as the list above */

#ifndef DOINIT
EXT struct headtype htype[HEAD_LAST];
#else
struct headtype htype[HEAD_LAST] = {
 /* name             minpos   maxpos  length   flag */
    {"BODY",		0,	0,	4,	0		},
    {"unrecognized",	0,	0,	12,	0		},
    {"article-i.d.",	0,	0,	12,	HT_HIDE		},
    {"approved",	0,	0,	8,	HT_HIDE		},
    {"distribution",	0,	0,	12,	0		},
    {"date",		0,	0,	4,	0		},
    {"date-received",	0,	0,	13,	0		},
    {"expires",		0,	0,	7,	HT_HIDE|HT_MAGIC},
    {"followup-to",	0,	0,	11,	0		},
    {"from",		0,	0,	4,	0		},
    {"keywords",	0,	0,	8,	0		},
    {"lines",		0,	0,	5,	0		},
    {"message-id",	0,	0,	10,	0		},
    {"nf-from",		0,	0,	7,	HT_HIDE		},
    {"nf-id",		0,	0,	5,	HT_HIDE		},
    {"newsgroups",	0,	0,	10,	HT_MAGIC|HT_HIDE},
    {"organization",	0,	0,	12,	0		},
    {"path",		0,	0,	4,	HT_HIDE		},
    {"posted",		0,	0,	6,	HT_HIDE		},
    {"posting-version",	0,	0,	15,	HT_HIDE		},
    {"reply-to",	0,	0,	8,	0		},
    {"references",	0,	0,	10,	0		},
    {"relay-version",	0,	0,	13,	HT_HIDE		},
    {"sender",		0,	0,	6,	0		},
    {"summary",		0,	0,	7,	0		},
    {"subject",		0,	0,	7,	HT_MAGIC	},
    {"xref",		0,	0,	4,	HT_HIDE		}
};
#endif

#ifdef ASYNC_PARSE
EXT ART_NUM parsed_art INIT(0);
#endif

EXT char in_header INIT(0);		/* are we decoding the header? */

#ifdef CACHESUBJ
    EXT char **subj_list INIT(Null(char **));
#endif

void	head_init();
int	set_line_type();
void	start_header();
bool    parseline();
#ifdef ASYNC_PARSE
    int		parse_maybe();
#endif
char	*fetchsubj();
char	*fetchlines();
!STUFFY!FUNK!
echo Extracting newsetup.SH
cat >newsetup.SH <<'!STUFFY!FUNK!'
case $CONFIG in
    '') . config.sh ;;
esac
echo "Extracting newsetup (with variable substitutions)"
$spitshell >newsetup <<!GROK!THIS!
$startsh
# $Header: newsetup.SH,v 4.3 85/05/01 11:43:05 lwall Exp $
# 
# $Log:	newsetup.SH,v $
# Revision 4.3  85/05/01  11:43:05  lwall
# Baseline for release with 4.3bsd.
# 

export PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)

: syntax: newsetup

: System dependencies
: You will want to change the definitions below to reflect the distribution
: areas around you.  If you have more areas than this you will need to modify
: the sed below.

locorg="$locpref"
organization="$orgpref"
city="$citypref"
state="$statepref"
cntry="$cntrypref"
cont="$contpref"
active="${active-/usr/lib/news/active}"

dotdir="\${DOTDIR-\${HOME-\$LOGDIR}}"
$rm -f \$dotdir/.oldnewsrc
$echo "Creating .newsrc in \$dotdir to be used by news programs."

case \$active in
~*) active=\`$filexp \$active\` ;;
esac

: NOTE: SED WILL NOT TAKE MORE THAN 10 WFILES, SO BEWARE

$sort <\$active | $sed >/tmp/n.tmp\$\$	\\
	-e 's/^\([^ ]*\) .*\$/\1:/'	\\
	-e '/^control:/{'		\\
	-e "  w /tmp/n.test\$\$"	\\
	-e '  d'			\\
	-e '}'				\\
	-e '/^junk:/{'			\\
	-e "  w /tmp/n.test\$\$"	\\
	-e '  d'			\\
	-e '}'				\\
	-e '/test:/{'			\\
	-e "  w /tmp/n.test\$\$"	\\
	-e '  d'			\\
	-e '}'				\\
	-e "/^net\./{"			\\
	-e "  w /tmp/n.net\$\$"		\\
	-e '  d'			\\
	-e '}'				\\
	-e "/^mod\./{"			\\
	-e "  w /tmp/n.mod\$\$"		\\
	-e '  d'			\\
	-e '}'				\\
	-e "/^\$locorg\./{"		\\
	-e "  w /tmp/n.\$locorg\$\$"	\\
	-e '  d'			\\
	-e '}'				\\
	-e "/^\$organization\./{"	\\
	-e "  w /tmp/n.\$organization\$\$"	\\
	-e '  d'			\\
	-e '}'				\\
	-e "/^\$city\./{"		\\
	-e "  w /tmp/n.\$city\$\$"	\\
	-e '  d'			\\
	-e '}'				\\
	-e "/^\$state\./{" 		\\
	-e "  w /tmp/n.\$state\$\$"	\\
	-e '  d'			\\
	-e '}'				\\
	-e "/^fa\./{"			\\
	-e "  w /tmp/n.fa\$\$"		\\
	-e '  d'			\\
	-e '}'

$sed </tmp/n.tmp\$\$ >/tmp/n.local\$\$	\\
	-e "/^\$cntry\./{" 		\\
	-e "  w /tmp/n.\$cntry\$\$"	\\
	-e '  d'			\\
	-e '}'				\\
	-e "/^\$cont\./{" 		\\
	-e "  w /tmp/n.\$cont\$\$"	\\
	-e '  d'			\\
	-e '}'				\\
	-e "/^to\./{"			\\
	-e "  w /tmp/n.to\$\$"		\\
	-e '  d'			\\
	-e '}'				\\
	-e "/\./{"			\\
	-e "  w /tmp/n.misc\$\$"	\\
	-e '  d'			\\
	-e '}'


if $test -s \$dotdir/.newsrc ; then
    $echo "Saving your current .newsrc as .oldnewsrc..."
    $mv -f \$dotdir/.newsrc \$dotdir/.oldnewsrc
fi

: newsrc order determined here
$cat \\
    /tmp/n.local\$\$ \\
    /tmp/n.\$locorg\$\$ \\
    /tmp/n.\$organization\$\$ \\
    /tmp/n.\$city\$\$ \\
    /tmp/n.\$state\$\$ \\
    /tmp/n.\$cntry\$\$ \\
    /tmp/n.\$cont\$\$ \\
    /tmp/n.mod\$\$ \\
    /tmp/n.net\$\$ \\
    /tmp/n.fa\$\$ \\
    /tmp/n.misc\$\$ \\
    /tmp/n.test\$\$ \\
| $uniq >\$dotdir/.newsrc

$rm -f	/tmp/n.to\$\$ \\
	/tmp/n.tmp\$\$ \\
	/tmp/n.local\$\$ \\
	/tmp/n.\$locorg\$\$ \\
	/tmp/n.\$organization\$\$ \\
	/tmp/n.\$city\$\$ \\
	/tmp/n.\$state\$\$ \\
	/tmp/n.\$cntry\$\$ \\
	/tmp/n.\$cont\$\$ \\
	/tmp/n.mod\$\$ \\
	/tmp/n.net\$\$ \\
	/tmp/n.fa\$\$ \\
	/tmp/n.misc\$\$ \\
	/tmp/n.test\$\$

$cat <<'EOH'
Done.

If you have never used the news system before, you may find the articles
in net.announce.newuser to be helpful.  There is also a manual entry for rn.

To get rid of newsgroups you aren't interested in, use the 'u' command.
Type h for help at any time while running rn.
EOH
!GROK!THIS!
$eunicefix newsetup
chmod 755 newsetup
!STUFFY!FUNK!
echo Extracting Makefile.SH
cat >Makefile.SH <<'!STUFFY!FUNK!'
case $CONFIG in
    '') . config.sh ;;
esac
echo "Extracting Makefile (with variable substitutions)"
cat >Makefile <<!GROK!THIS!
# $Header: Makefile.SH,v 4.3 85/05/01 11:33:26 lwall Exp $
#
# $Log:	Makefile.SH,v $
# Revision 4.3  85/05/01  11:33:26  lwall
# Baseline for release with 4.3bsd.
# 

CC = $cc
rnbin = $rnbin
rnlib = $rnlib
mansrc = $mansrc
manext = $manext
CFLAGS = $iandd -O
LDFLAGS = $iandd
NDIRC = $ndirc
NDIRO = $ndiro

libs = $ndirlib $termlib $jobslib
!GROK!THIS!
cat >>Makefile <<'!NO!SUBS!'

public = rn newsetup newsgroups Pnews Rnmail
private = norm.saver mbox.saver ng.help art.help pager.help subs.help makedir filexp Pnews.header
manpages = rn.1 Pnews.1 Rnmail.1 newsetup.1 newsgroups.1
util = Makefile makedepend newsnews

h1 = addng.h art.h artio.h artsrch.h backpage.h bits.h cheat.h common.h
h2 = final.h head.h help.h init.h intrp.h kfile.h last.h ndir.h ng.h
h3 = ngdata.h ngsrch.h ngstuff.h only.h rcln.h rcstuff.h
h4 = respond.h rn.h search.h sw.h term.h util.h

h = $(h1) $(h2) $(h3) $(h4)

c1 = addng.c art.c artio.c artsrch.c backpage.c bits.c cheat.c
c2 = final.c head.c help.c init.c intrp.c kfile.c last.c $(NDIRC) ng.c
c3 = ngdata.c ngsrch.c ngstuff.c only.c rcln.c rcstuff.c
c4 = respond.c rn.c search.c sw.c term.c util.c

c = $(c1) $(c2) $(c3) $(c4)

obj1 = addng.o art.o artio.o artsrch.o backpage.o bits.o cheat.o
obj2 = final.o head.o help.o init.o intrp.o kfile.o last.o $(NDIRO) ng.o
obj3 = ngdata.o ngsrch.o ngstuff.o only.o rcln.o rcstuff.o
obj4 = respond.o rn.o search.o sw.o term.o util.o

obj = $(obj1) $(obj2) $(obj3) $(obj4)

lintflags = -phbvxac

add1 = Makefile.old Pnews Rnmail art.help
add2 = bsd config.h config.sh eunice filexp
add3 = loc makedepend makedir mbox.saver newsetup
add4 = newsgroups newsnews ng.help norm.saver pager.help
add5 = pdp11 rn subs.help usg v7

addedbyconf = $(add1) $(add2) $(add3) $(add4) $(add5)

# grrr
SHELL = /bin/sh

.c.o:
	$(CC) -c $(CFLAGS) $*.c

all: $(public) $(private) $(util)
	touch all

rn: $(obj)
	$(CC) $(LDFLAGS) $(obj) $(libs) -o rn

# if a .h file depends on another .h file...
$(h):
	touch $@

install: rn
# won't work with csh
	export PATH || exit 1
	- mv $(rnbin)/rn $(rnbin)/rn.old
	- if test `pwd` != $(rnbin); then cp $(public) $(rnbin); fi
	cd $(rnbin); chmod 755 $(public)
	chmod 755 makedir
	- ./makedir `./filexp $(rnlib)`
	- if test `pwd` != `./filexp $(rnlib)`; then cp INIT $(private) `./filexp $(rnlib)`; fi
	cd `./filexp $(rnlib)`; chmod 755 $(private)
	- if test ! -f `./filexp $(rnlib)/newsnews`; then cp newsnews `./filexp $(rnlib)`; fi
	- if test `pwd` != $(mansrc); then\
for page in $(manpages); do\
cp $$page $(mansrc)/`basename $$page .1`.$(manext);\
done;\
fi

clean:
	rm -f *.o

realclean:
	rm -f rn *.o core $(addedbyconf)

# The following lint has practically everything turned on.  Unfortunately,
# you have to wade through a lot of mumbo jumbo that can't be suppressed.
# If the source file has a /*NOSTRICT*/ somewhere, ignore the lint message
# for that spot.

lint:
	lint $(lintflags) $(defs) $(c) > rn.fuzz

depend:
	makedepend

# AUTOMATICALLY GENERATED MAKE DEPENDENCIES--PUT NOTHING BELOW THIS LINE
$(obj):
	@ echo "You haven't done a "'"make depend" yet!'; exit 1
!NO!SUBS!
$eunicefix Makefile
!STUFFY!FUNK!
echo Extracting ngsrch.c
cat >ngsrch.c <<'!STUFFY!FUNK!'
/* $Header: ngsrch.c,v 4.3 85/05/01 11:44:51 lwall Exp $
 *
 * $Log:	ngsrch.c,v $
 * Revision 4.3  85/05/01  11:44:51  lwall
 * Baseline for release with 4.3bsd.
 * 
 */

#include "EXTERN.h"
#include "common.h"
#include "rcstuff.h"
#include "final.h"
#include "search.h"
#include "rn.h"
#include "util.h"
#include "term.h"
#include "rcln.h"
#include "INTERN.h"
#include "ngsrch.h"

#ifdef NGSORONLY
    COMPEX ngcompex;
#endif

void
ngsrch_init()
{
#ifdef ZEROGLOB
    init_compex(&ngcompex);
#endif	/* ZEROGLOB */
    ;
}

#ifdef NGSEARCH
int
ng_search(patbuf,get_cmd)
char *patbuf;				/* if patbuf != buf, get_cmd must */
int get_cmd;				/*   be set to FALSE!!! */
{
    char *pattern;			/* unparsed pattern */
    register char cmdchr = *patbuf;	/* what kind of search? */
    register char *s;
    bool backward = cmdchr == '?';	/* direction of search */

    int_count = 0;
    if (get_cmd && buf == patbuf)
	if (!finish_command(FALSE))		/* get rest of command */
	    return NGS_ABORT;
    for (pattern = patbuf+1; *pattern == ' '; pattern++) ;
    if (*pattern) {
	ng_doread = FALSE;
    }
    s = rindex(pattern,cmdchr);
    if (s != Nullch && *(s-1) != '\\') {
	*s++ = '\0';
	if (index(s,'r') != Nullch)
	    ng_doread = TRUE;
    }
    if ((s = ng_comp(&ngcompex,pattern,TRUE,TRUE)) != Nullch) {
					/* compile regular expression */
	printf("\n%s\n",s) FLUSH;
	return NGS_ABORT;
    }
    fputs("\nSearching...",stdout) FLUSH;	/* give them something to read */
    fflush(stdout);
    for (;;) {
	if (int_count) {
	    int_count = 0;
	    return NGS_INTR;
	}
	if (backward) {
	    if (ng > 0)
		--ng;
	    else
		ng = nextrcline;
	}
	else {
	    if (ng >= nextrcline)
		ng = 0;
	    else
		++ng;
	}
	if (ng == current_ng)
	    return NGS_NOTFOUND;
	if (ng == nextrcline || toread[ng] < TR_NONE || !ng_wanted())
	    continue;
	if (toread[ng] == TR_NONE)
	    set_toread(ng);
	
	if (toread[ng] > TR_NONE)
	    return NGS_FOUND;
	else if (toread[ng] == TR_NONE)
	    if (ng_doread)
		return NGS_FOUND;
	    else
		printf("\n[0 unread in %s--skipping]",rcline[ng]) FLUSH;
    }
}

bool
ng_wanted()
{
    return execute(&ngcompex,rcline[ng]) != Nullch;
}
#endif

#ifdef NGSORONLY
char *
ng_comp(compex,pattern,RE,fold)
COMPEX *compex;
char *pattern;
bool RE;
bool fold;
{
    char ng_pattern[128];
    register char *s = pattern, *d = ng_pattern;

    if (!*s)
	return Nullch;			/* reuse old pattern */
    for (; *s; s++) {
	if (*s == '.') {
	    *d++ = '\\';
	    *d++ = *s;
	}
	else if (*s == '?') {
	    *d++ = '.';
	}
	else if (*s == '*') {
	    *d++ = '.';
	    *d++ = *s;
	}
	else if (strnEQ(s,"all",3)) {
	    *d++ = '.';
	    *d++ = '*';
	    s += 2;
	}
	else
	    *d++ = *s;
    }
    *d = '\0';
    return compile(compex,ng_pattern,RE,fold);
}
#endif

!STUFFY!FUNK!
echo Extracting art.help.SH
cat >art.help.SH <<'!STUFFY!FUNK!'
case $CONFIG in
    '') . config.sh ;;
esac
echo "Extracting art.help (with variable substitutions)"
$spitshell >art.help <<!GROK!THIS!
$startsh
# $Header: art.help.SH,v 4.3 85/05/01 11:35:34 lwall Exp $
# 
# $Log:	art.help.SH,v $
# Revision 4.3  85/05/01  11:35:34  lwall
# Baseline for release with 4.3bsd.
# 
# 
$pager <<'EOT'
Article Selection commands:

n,SP	Scan forward for next unread article.
N	Go to next article.
^N	Scan forward for next unread article with same subject.
p,P,^P	Same as n,N,^N, only going backwards.
-	Go to previously displayed article.
number	Go to specified article.
range{,range} command{:command}
	Apply one or more commands to one or more ranges of articles.
	Ranges are of the form: number | number-number.  You may use . for
	the current article, and $ for the last article.
 	Valid commands are: j, m, M, s, S, and !.
/pattern/modifiers
	Scan forward for article containing pattern in the subject line.
	(Use ?pat? to scan backwards; append h to scan headers, a to scan
	entire articles, r to scan read articles, c to make case sensitive.
/pattern/modifiers:command{:command}
	Apply one or more commands to the set of articles matching pattern.
	Use a K modifier to save entire command to the KILL file for this
	newsgroup.  Commands m and M, if first, imply an r modifier.
 	Valid commands are: j, m, M, s, S, and !.
f,F	Submit a followup article (F = include this article).
r,R	Reply through net mail (R = include this article).
s ...	Save to file or pipe via sh.
S ...	Save via preferred shell.
w,W	Like s and S but save without the header.
| ...	Same as s|...
C	Cancel this article, if yours.
^R,v	Restart article (v=verbose).
^X	Restart article, rot13 mode.
c	Catch up (mark all articles as read).
^B	Back up one page.
^L	Refresh the screen.  You can get back to the pager with this.
X	Refresh screen in rot13 mode.
^	Go to first unread article.  Disables subject search mode.
$	Go to end of newsgroup.  Disables subject search mode.
#       Print last article number.
&	Print current values of command-line switches.
&switch {switch}
	Set or unset more switches.
&&	Print current macro definitions.
&&def	Define a new macro.
j	Junk this article (mark it read).  Stays at end of article.
m	Mark article as still unread.
M	Mark article as still unread upon exiting newsgroup or Y command.
Y	Yank back articles marked temporarily read via M.
k	Mark current SUBJECT as read.
K	Mark current SUBJECT as read, and save command in KILL file.
=	List subjects of unread articles.
u	Unsubscribe to this newsgroup.
^K	Edit local KILL file (the one for this newsgroup).
q	Quit this newsgroup for now.
Q	Quit newsgroup, staying at current newsgroup.
EOT

!GROK!THIS!
$eunicefix art.help
chmod 755 art.help
!STUFFY!FUNK!
echo Extracting cheat.c
cat >cheat.c <<'!STUFFY!FUNK!'
/* $Header: cheat.c,v 4.3 85/05/01 11:36:46 lwall Exp $
 *
 * $Log:	cheat.c,v $
 * Revision 4.3  85/05/01  11:36:46  lwall
 * Baseline for release with 4.3bsd.
 * 
 */

#include "EXTERN.h"
#include "common.h"
#include "intrp.h"
#include "search.h"
#include "ng.h"
#include "bits.h"
#include "artio.h"
#include "term.h"
#include "artsrch.h"
#include "head.h"
#include "INTERN.h"
#include "cheat.h"

/* see what we can do while they are reading */

#ifdef PENDING
#   ifdef ARTSEARCH
	COMPEX srchcompex;		/* compiled regex for searchahead */
#   endif
#endif

void
cheat_init()
{
    ;
}

#ifdef PENDING
void
look_ahead()
{
#ifdef ARTSEARCH
    register char *h, *s;

#ifdef DEBUGGING
    if (debug && srchahead) {
	printf("(%ld)",(long)srchahead);
	fflush(stdout);
    }
#endif
    if (srchahead && srchahead < art) {	/* in ^N mode? */
	char *pattern;

	pattern = buf+1;
	strcpy(pattern,": *");
	h = pattern + strlen(pattern);
	interp(h,(sizeof buf) - (h-buf),"%s");
	h[24] = '\0';		/* compensate for notesfiles */
	while (*h) {
	    if (index("\\[.^*$'\"",*h) != Nullch)
		*h++ = '.';
	    else
		h++;
	}
#ifdef DEBUGGING
	if (debug & DEB_SEARCH_AHEAD) {
	    fputs("(hit CR)",stdout);
	    fflush(stdout);
	    gets(buf+128);
	    printf("\npattern = %s\n",pattern);
	}
#endif
	if ((s = compile(&srchcompex,pattern,TRUE,TRUE)) != Nullch) {
				    /* compile regular expression */
	    printf("\n%s\n",s);
	    srchahead = 0;
	}
	if (srchahead) {
	    srchahead = art;
	    for (;;) {
		srchahead++;	/* go forward one article */
		if (srchahead > lastart) { /* out of articles? */
#ifdef DEBUGGING
		    if (debug)
			fputs("(not found)",stdout);
#endif
		    break;
		}
		if (!was_read(srchahead) &&
		    wanted(&srchcompex,srchahead,0)) {
				    /* does the shoe fit? */
#ifdef DEBUGGING
		    if (debug)
			printf("(%ld)",(long)srchahead);
#endif
		    artopen(srchahead);
		    break;
		}
		if (input_pending())
		    break;
	    }
	    fflush(stdout);
	}
    }
    else
#endif
    {
	if (art+1 <= lastart)/* how about a pre-fetch? */
	    artopen(art+1);	/* look for the next article */
    }
}
#endif

/* see what else we can do while they are reading */

void
collect_subjects()
{
#ifdef PENDING
# ifdef CACHESUBJ
    ART_NUM oldart = openart;
    ART_POS oldartpos;

    if (!in_ng || !srchahead)
	return;
    if (oldart)			/* remember where we were in art */
	oldartpos = ftell(artfp);
    if (srchahead >= subj_to_get)
	subj_to_get = srchahead+1;
    while (!input_pending() && subj_to_get <= lastart)
	fetchsubj(subj_to_get++,FALSE,FALSE);
    if (oldart) {
	artopen(oldart);
	fseek(artfp,oldartpos,0);	/* do not screw the pager */
    }
# endif
#endif
}

!STUFFY!FUNK!
echo Extracting header.h.2.pat
cat >header.h.2.pat <<'!STUFFY!FUNK!'
*** header.old.h	Tue Apr 30 14:33:33 1985
--- header.h		Tue Apr 30 14:33:35 1985
***************
*** 35,39
  	char	approved[BUFLEN];	/* Approved:		*/
  	char	nf_id[BUFLEN];		/* Nf-ID:		*/
  	char	nf_from[BUFLEN];	/* Nf-From:		*/
  	char	*unrec[NUNREC];		/* unrecognized lines	*/
  };

--- 35,42 -----
  	char	approved[BUFLEN];	/* Approved:		*/
  	char	nf_id[BUFLEN];		/* Nf-ID:		*/
  	char	nf_from[BUFLEN];	/* Nf-From:		*/
+ #ifdef DOXREFS
+ 	char	xref[BUFLEN];		/* Xref:		*/
+ #endif DOXREFS
  	char	*unrec[NUNREC];		/* unrecognized lines	*/
  };
!STUFFY!FUNK!
echo ""
echo "End of kit 7 (of 9)"
cat /dev/null >kit7isdone
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



More information about the Mod.sources mailing list