home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume1
/
rn
/
part07
< prev
next >
Wrap
Internet Message Format
|
1986-11-30
|
63KB
Date: Tue, 7 May 85 14:01:47 pdt
From: allegra!sdcrdcf!RDCF.SDC.UUCP!lwall (Larry Wall)
Newsgroups: mod.sources
Subject: rn version 4.3 (kit 7 of 9)
Reply-To: lwall@sdcrdcf.UUCP
Organization: System Development Corporation R&D, Santa Monica
#! /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@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