[net.sources] rn version 4.1, part 2 of 8

lwall@sdcrdcf.UUCP (Larry Wall) (10/03/84)

#! /bin/sh

# Make a new directory for the rn sources, cd to it, and run kits 1 thru 8 
# through sh.  When all 8 kits have been run, read README.

echo "This is rn kit 2 (of 8).  If kit 2 is complete, the line"
echo '"'"End of kit 2 (of 8)"'" will echo at the end.'
echo ""
export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
echo Extracting Configure
cat >Configure <<'!STUFFY!FUNK!'
#! /bin/sh
#
# If these # comments don't work, trim them.  Don't worry about the other
# shell scripts, Configure will trim # comments from them for you.
#
# $Header: Configure,v 4.1 84/09/24 11:19:19 lwall Exp $
#
# $Log:	Configure,v $
# Revision 4.1  84/09/24  11:19:19  lwall
# Real baseline.
# 
# Revision 4.0.1.7  84/09/22  16:53:46  lwall
# 2.10.2 inews moved.
# 
# Revision 4.0.1.6  84/09/18  15:51:08  lwall
# 2.10.2 tweaks.
# 
# Revision 4.0.1.5  84/09/14  17:31:45  lwall
# Compensate for greps that do not return status.
# 
# Revision 4.0.1.4  84/09/12  17:50:42  lwall
# Check for sh interpretation.
# Revised ndir checker.
# Qualified test now used only if in /bin, and test is not built in to sh.
# Various anti-brain-damage measures.
# 
# Revision 4.0.1.3  84/09/06  13:46:29  lwall
# Now figures out where manual pages go.
# 
# Revision 4.0.1.2  84/09/05  16:06:28  lwall
# Now determines how to invoke C preprocessor.
# 
# Revision 4.0.1.1  84/09/04  12:02:56  lwall
# Allow recmail on usg systems.
# Fixed $lib lookup.
# 
# Revision 4.0  84/09/04  09:48:13  lwall
# Baseline for netwide release
# 

# Yes, you may rip this off to use in other distribution packages.

echo "Beginning of configuration questions for rn kit."
echo ""

: sanity checks
PATH='.:/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/local:/etc'
export PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh $0; kill $$)

if test ! -t 0; then
    echo "Say 'sh Configure', not 'sh <Configure'"
    exit 1
fi

: some greps do not return status, grrr.
echo "grimblepritz" >grimble
if grep blurfldyick grimble >/dev/null 2>&1 ; then
    contains=contains
else
    if grep grimblepritz grimble >/dev/null 2>&1 ; then
	contains=grep
    else
	contains=contains
    fi
fi
rm grimble
: the following should work in any shell
case $contains in
contains*)
    echo ""
    echo "AGH!  Grep doesn't return a status.  Attempting remedial action."
    cat >contains <<'EOSS'
grep "$1" "$2" >.greptmp && cat .greptmp && test -s .greptmp
EOSS
chmod 755 contains
esac

: first determine how to suppress newline on echo command
echo "Checking echo to see how to suppress newlines..."
(echo "hi there\c" ; echo "") >.echotmp
if $contains c .echotmp >/dev/null 2>&1 ; then
    echo "...using -n."
    n='-n'
    c=''
else
    echo "...using \\\c."
    n=''
    c='\c'
fi
echo $n "Type carriage return to continue.  Your cursor should be here-->$c"
read ans
rm .echotmp

: general instructions
cat <<'EOH'

This installation shell script will examine your system and ask you questions
to determine how rn and its auxiliary files should be installed.  If you
get stuck on a question, you can interrupt and start over without fear of
getting messed up.  Many of the questions will have default answers in
square brackets--typing carriage return will give you the default.

On some of the questions which ask for file or directory names you are
allowed to use the ~name construct to specify the login directory belonging
to "name", even if you don't have a shell which knows about that.  Questions
where this is allowed will be marked "(~name ok)".

Much effort has been expended to ensure that this shell script will run
on any Unix system.  If despite that it blows up on you, your best bet is
to edit Configure and run it again.  (Trying to install rn without having run
Configure is well nigh impossible.)  Also, let me (lwall@sdcrdcf.UUCP) know
that I blew it.

This installation script affects things in two ways: 1) it does direct
variable substitutions on some of the files included in this kit, and
2) it builds a config.h file for inclusion in C programs.  You may edit
any of these files as the need arises after running this script.

EOH
echo $n "[Type carriage return to continue] $c"
read ans

: get list of predefined functions in a handy place
echo ""
if test -f /lib/libc.a; then
    echo "Your C library is in /lib/libc.a.  You're normal."
    libc=/lib/libc.a
else
    if test -f /usr/lib/libc.a; then
	echo "Your C library is in /usr/lib/libc.a, of all places."
	libc=/usr/lib/libc.a
    else
	cat <<'EOM'

I can't seem to find your C library.  I've looked for /lib/libc.a and
/usr/lib/libc.a, but neither of those are there.  What is the full name
EOM
	echo $n "of your C library? $c"
	read libc
    fi
fi
echo ""
echo $n "Extracting names from $libc for later perusal...$c"
if ar t $libc > libc.list; then
    echo "done"
else
    echo ""
    echo "The archiver doesn't think $libc is a reasonable library."
    exit 1
fi

: make some quick guesses about what we are up against
echo ""
echo $n "Hmm...  $c"
if $contains SIGTSTP /usr/include/signal.h >/dev/null 2>&1 ; then
    echo "Looks kind of like a BSD system, but we'll see..."
    echo exit 0 >bsd
    echo exit 1 >usg
    echo exit 1 >v7
else
    if $contains fcntl.o libc.list >/dev/null 2>&1 ; then
	echo "Looks kind of like a USG system, but we'll see..."
	echo exit 1 >bsd
	echo exit 0 >usg
	echo exit 1 >v7
    else
	echo "Looks kind of like a version 7 system, but we'll see..."
	echo exit 1 >bsd
	echo exit 1 >usg
	echo exit 0 >v7
    fi
fi
if $contains vmssystem.o libc.list >/dev/null 2>&1 ; then
    cat <<'EOI'
There is, however, a strange, musty smell in the air that reminds me of
something...hmm...yes...I've got it...there's a VMS nearby, or I'm a Blit.
EOI
    echo "exit 0" >eunice
    eunicefix=unixtovms
    eunice=define
: it so happens the Eunice I know will not run shell scripts in Unix format
else
    echo ""
    echo "Congratulations.  You aren't running Eunice."
    eunicefix=':'
    eunice=undef
    echo "exit 1" >eunice
fi
chmod 755 bsd usg v7 eunice
$eunicefix bsd usg v7 eunice

: see how we invoke the C preprocessor
echo ""
echo "Checking to see how your C preprocessor is invoked..."
cat <<'EOT' >testcpp.c
#define ABC abc
#define XYZ xyz
ABC+XYZ
EOT
echo 'Maybe "cc -E" will work...'
cc -E testcpp.c >testcpp.out 2>&1
if $contains 'abc+xyz' testcpp.out >/dev/null 2>&1 ; then
    echo "Yup, it does."
    cpp='cc -E'
else
    echo 'Nope...maybe "cc -P" will work...'
    cc -P testcpp.c >testcpp.out 2>&1
    if $contains 'abc+xyz' testcpp.out >/dev/null 2>&1 ; then
	echo "Yup, that does."
	cpp='cc -P'
    else
	echo 'Nope...maybe "/lib/cpp" will work...'
	/lib/cpp testcpp.c >testcpp.out 2>&1
	if $contains 'abc+xyz' testcpp.out >/dev/null 2>&1 ; then
	    echo "Hooray, it works!  I was beginning to wonder."
	    cpp='/lib/cpp'
	else
	    echo "I can't find a C preprocessor.  Name one: $c"
	    read cpp
	    $cpp testcpp.c >testcpp.out 2>&1
	    if $contains 'abc+xyz' testcpp.out >/dev/null 2>&1 ; then
		echo "OK, that will do."
	    else
		echo "Sorry, I can't get that to work.  Go find one."
		exit 1
	    fi
	fi
    fi
fi
rm -f testcpp.c testcpp.out

: check for pdp11
echo ""
if usg; then
    : pdp11 is already defined
else
    cat <<'EOT' >pdp11.c
#ifdef pdp11
exit 0
#else
exit 1
#endif
EOT
    $cpp pdp11.c | grep exit >pdp11
    chmod 755 pdp11
    $eunicefix pdp11
    rm pdp11.c
fi
if pdp11; then
    echo "This looks like a pdp11 to me."
else
    echo "This doesn't look like a pdp11 to me."
fi

: see if sh knows # comments
echo ""
echo "Checking your sh to see if it knows about # comments..."
if sh -c '#' >/dev/null 2>&1 ; then
    echo "Your sh handles # comments correctly."
    shsharp=true
    spitshell=cat
    echo ""
    echo "Okay, let's see if #! works on this system..."
    echo "#!/bin/date" > try
    $eunicefix try
    chmod 755 try
    try > today
    if test -s today; then
	echo "It does."
	sharpbang='#!'
    else
	echo "#! /bin/date" > try
	$eunicefix try
	chmod 755 try
	try > today
	if test -s today; then
	    echo "It does."
	    sharpbang='#! '
	else
	    echo "It doesn't."
	    sharpbang=': use '
	fi
    fi
else
    echo "Your sh doesn't grok # comments--I will strip them later on."
    shsharp=false
    echo "exec grep -v '^#'" >spitshell
    chmod 755 spitshell
    $eunicefix spitshell
    spitshell=`pwd`/spitshell
    echo "I presume that if # doesn't work, #! won't work either!"
    sharpbang=': use '
fi

: figure out how to guarantee sh startup
echo ""
echo "Checking out how to guarantee sh startup..."
startsh=$sharpbang'/bin/sh'
echo "Let's see if '$startsh' works..."
cat >try <<EOSS
$startsh
set abc
test "$?abc" != 1
EOSS

chmod 755 try
$eunicefix try
if try; then
    echo "Yup, it does."
else
    echo "Nope.  You may have to fix up the shell scripts to make sure sh runs them."
fi
rm -f try today

: find out where common programs are
echo ""
echo "Locating common programs..."
cat <<EOSC >loc
$startsh
for dir in /usr/ucb /bin /usr/bin /usr/local /usr/local/bin /etc /usr/lib
do
    if test -f \$dir/\$1; then
	echo \$dir/\$1
	echo \$1 is in \$dir > /dev/tty
	exit
    fi
done
echo \$1
echo "I don't know where \$1 is" >/dev/tty
EOSC
chmod 755 loc
$eunicefix loc
loclist="test expr sed echo cat rm mv cp tail tr mkdir sort uniq inews grep egrep"
for file in $loclist; do
    eval $file=`loc $file`
done
case $egrep in
egrep)
    $echo "Substituting grep for egrep."
    egrep=$grep
    ;;
esac
case $test in
test)
    echo "Hopefully test is built into your sh."
    ;;
/bin/test)
    echo ""
    echo $n 'Is your "test" built into sh? [n] (OK to guess) '"$c"
    read ans
    case $ans in
    y*) test=test ;;
    esac
    ;;
*)
    test=test
    ;;
esac

: decide how portable to be
$cat <<'EOH'

I can set things up so that your shell scripts and binaries are more portable,
at a noticable cost in performance.  Do you expect to run these scripts and
EOH
$echo $n "binaries on multiple machines? [n] $c"
read ans
case $ans in
    y*) portable=define
	for file in $loclist; do
	    eval $file=$file
	done
	;;
    *)  portable=undef ;;
esac

: set up shell script to do ~ expansion
cat >filexp <<EOSS
$startsh
: expand filename
case \$1 in
~/*|~)
    $echo \$1 | $sed "s/~/\${HOME-\$LOGDIR}/"
    ;;
~*)
    if $test -f /bin/csh; then
	/bin/csh -f -c "glob \$1"
	$echo ""
    else
	name=\`$expr x\$1 : '..\([^/]*\)'\`
	dir=\`$sed </etc/passwd -n -e "/^\${name}:/{s/^[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\).*"'\$'"/\1/" -e p -e q -e '}'\`
	if $test ! -d "\$dir"; then
	    me=\`basename \$0\`
	    $echo "\$me: can't locate home directory for: \$name" >&2
	    exit 1
	fi
	case \$1 in
	*/*)
	    $echo \$dir/\`$expr x\$1 : '..[^/]*/\(.*\)'\`
	    ;;
	*)
	    $echo \$dir
	    ;;
	esac
    fi
    ;;
*)
    $echo \$1
    ;;
esac
EOSS
chmod 755 filexp
$eunicefix filexp

: now get the site name
$echo ""
hostcmd=''
$echo "Figuring out site name..."
$echo 'Maybe "hostname" will work...'
if ans=`sh -c hostname 2>&1` ; then
    sitename=$ans
    hostcmd=hostname
else
    $echo 'No, maybe "uuname -l" will work...'
    if ans=`sh -c 'uuname -l' 2>&1` ; then
	sitename=$ans
	hostcmd='uuname -l'
    else
	$echo 'Strange.  Maybe "uname -n" will work...'
	if ans=`sh -c 'uname -n' 2>&1` ; then
	    sitename=$ans
	    hostcmd='uname -n'
	else
	    $echo 'Oh well, maybe I can mine it out of whoami.h...'
	    if ans=`sh -c $contains' sysname /usr/include/whoami.h' 2>&1` ; then
		sitename=`$echo "$ans" | $sed 's/^.*"\(.*\)"/\1/'`
		hostcmd="sed -n -e '"'/sysname/s/^.*\"\\(.*\\)\"/\1/{'"' -e p -e q -e '}' </usr/include/whoami.h"
	    else
		echo "Does this machine have an identity crisis or something?"
		sitename=''
	    fi
	fi
    fi
fi
: you do not want to know about this
set $sitename
sitename=$1

: translate upper to lower if necessary
case $sitename in
    *[A-Z]*)
	sitename=`$echo $sitename | tr [A-Z] [a-z]`
	$echo "(Normalizing case in your site name)"
	;;
esac

: verify guess
if $test "$sitename" ; then
    $echo 'Your site name appears to be "'$sitename'".'
    $echo $n "Is this correct? [y] $c"
    read ans
    case $ans in
      y*|'')  ;;
      *)      sitename='' ;;
    esac
fi

: bad guess or no guess
while $test "X$sitename" = X ; do
    $echo $n "Please type the (one word) name of your site: $c"
    read sitename
    case $hostcmd in
    sed*)
	$echo "(That doesn't agree with your whoami.h file, by the way.)"
	;;
    *)
	$echo "(That doesn't agree with your $hostcmd command, by the way.)"
	;;
    esac
    hostcmd=''
done

: get organizaton name
$cat << 'EOH'

Please type the name of your organization as you want it to appear on the
Organization line of outgoing articles.  (It's nice if this also specifies
your location.  Your city name is probably sufficient if well known.)
For example: "University of Southern North Dakota, Hoople"
EOH
$echo $n "Organization: $c"
read orgname

: get news administrator name
if $contains "^news:" /etc/passwd >/dev/null 2>&1 ; then
    dflt=news
else
    if $contains "^usenet:" /etc/passwd >/dev/null 2>&1 ; then
	dflt=news
    else
	if eunice; then
	    dflt=system
	else
	    dflt=root
	fi
    fi
fi
cat <<'EOM'

Many systems keep their news in a private directory, or have a non-superuser
in charge of administering news.  What is the login name (not directory) that
EOM
echo $n "is used for news administration? [$dflt] $c"
read newsadmin
case $newsadmin in
'') newsadmin=$dflt ;;
esac
case $newsadmin in
root) isadmin=undef ;;
*)    isadmin=define ;;
esac

: figure out news library
echo ""
lib=/usr/lib/news
libexp=$lib
while $test ! -d $libexp; do
    $echo ""
    $echo $n "$libexp not found--where is the news library? (~name ok) $c"
    read lib
    case $lib in
    ~*)
	libexp=`filexp $lib`
	echo "(That is $libexp on this particular system.)"
	case $portable in
	  undef) lib=$libexp ;;
	esac
	;;
    *)
	libexp=$lib
	;;
    esac
done
$echo "LIB = $lib"
if $test -f $libexp/inews; then
    echo "Aha!  Inews is really in $libexp!  Maybe this is 2.10.2..."
    case $inews in
    inews) 
	: null
	;;
    *)
	echo "(Make sure $inews isn't an old version.)"
	;;
    esac
    inews=$libexp/inews
fi

: find out how to find out full name
$echo ""
if bsd; then
    dflt=y
else
    dflt=n
fi
$echo "Does your /etc/passwd file keep full names in Berkeley format (name first"
$echo $n "thing after ':')? [$dflt] $c"
read ans
case $ans in
  '') ans=$dflt ;;
esac
case $ans in
  y*)
    passnam=define
    berknam=define
    usgnam=undef
    nametype=bsd
    ;;
  *)
    $echo ""
    if usg; then
	dflt=y
    else
	dflt=n
    fi
    $echo "Does your passwd file keep full names in USG format (name sandwiched"
    $echo $n "between a '-' and a '(')? [$dflt] $c"
    read ans
    case $ans in
      '') ans=$dflt ;;
    esac
    case $ans in
      n*)
	$echo "Full name will be taken from ~/.fullname"
	passnam=undef
	berknam=undef
	usgnam=undef
	nametype=other
	;;
      *)
	passnam=define
	berknam=undef
	usgnam=define
	nametype=usg
	;;
    esac
    ;;
esac

: see if we should throw a -i into the Makefile
$echo ""
if pdp11; then
    if usg; then
	ans=/usr/man/unix/man1/cc.1
    else
	ans=/usr/man/man1/cc.1
    fi
    if $contains '\-i' $ans >/dev/null 2>&1 ; then
	$echo $n "Your system appears to have separate I and D space.  Is this true? [y] $c"
	read ans
	case $ans in
	    n*|f*) iandd='' ;;
	    *)     iandd='-i' ;;
	esac
    else
	$echo "Your system appears to NOT have separate I and D space."
	$echo $n "Is this correct? [y] $c"
	read ans
	case $ans in
	    n*|f*) iandd='-i' ;;
	    *)     iandd='' ;;
	esac
    fi
else
    $echo "Not a pdp11--assuming no separate I and D."
fi

: index or strcpy
$echo ""
if $contains index.o libc.list >/dev/null 2>&1 ; then
    $echo "Your system appears to use index() and rindex() rather than strchr()"
    $echo $n "and strrchr().  Is this correct? [y] $c"
    read ans
    case $ans in
	n*|f*) strchr='define' ;;
	*)     strchr='undef' ;;
    esac
else
    $echo "Your system appears to use strchr() and strrchr() rather than index()"
    $echo $n "and rindex().  Is this correct? [y] $c"
    read ans
    case $ans in
	n*|f*) strchr=undef ;;
	*)     strchr=define ;;
    esac
fi

: determine how to determine when a file is a mailbox
$cat <<'EOM'

In saving articles, rn wants to differentiate between saving to mailbox
format files and normal files.  It does this by examining the first character
of the file in question.  On most systems the first line starts "From...",
so the first character is F.  On other systems there are magic cookies like
control codes between articles, so one of those would be first.  On your
system, if a file is in mailbox format, what is the first character of
EOM
echo $n "that file? [F] $c"
read mboxchar
case $mboxchar in
'') mboxchar=F ;;
esac
case $mboxchar in
'F') ;;
*)  cat <<'EOM'
You will need to edit the shell script mbox.saver to properly append an
article to a mailbox.  The arguments to the script are documented in
EOM
    case $shsharp in
    false)
	echo "comments in mbox.saver.std."
	;;
    true)
	echo "comments in the shell script itself."
	;;
    esac
esac

: where do we get termlib routines from
$echo ""
if $test -r /usr/lib/libtermlib.a || $test -r /usr/local/lib/libtermlib.a ; then
    termlib='-ltermlib'
    havetlib=define
    $echo "Termlib library found."
else
    if $test -d /usr/lib/terminfo || $test -d /etc/term; then
	termlib='-lcurses'
	havetlib=define
	$echo "Terminfo library found."
    else
	if $test -r /usr/lib/libtermcap.a || $test -r /usr/local/lib/libtermcap.a ; then
	    termlib='-ltermcap'
	    havetlib=define
	    $echo "Termcap library found."
	else
	    $echo $n "Your system appears to NOT have termlib-style routines.  Is this true? [y] $c"
	    read ans
	    case $ans in
		n*|f*) havetlib=define
		      $echo "Then where are the termlib-style routines kept (specify either -llibname"
		      $echo $n " or full pathname (~name ok))? $c"
		      read ans
		      termlib=`filexp $ans`
		      ;;
		*)    havetlib=undef
		      termlib=''
		      $echo "You will have to play around with term.c then."
		      ;;
	    esac
	    $echo ""
	fi
    fi
fi

: see if there is a whoami file
if $test -r /usr/include/whoami.h ; then
    whoami=define
    $echo "whoami.h found."
else
    whoami=undef
fi

: see if this is a termio system
if $test -r /usr/include/termio.h ; then
    termio=define
    $echo "termio.h found."
else
    if $test -r /usr/include/sgtty.h ; then
	termio=undef
	$echo "sgtty.h found."
    else
	termio=undef
	$echo "Neither termio.h nor sgtty.h found--you could have problems."
    fi
fi

: see if there is a vfork
if $contains vfork.o libc.list >/dev/null 2>&1 ; then
    $echo "vfork() found."
    novfork='undef'
else
    $echo "No vfork() found--will use fork() instead."
    novfork='define'
fi

: see if there is a getpw
if $contains getpw.o libc.list >/dev/null 2>&1 ; then
    $echo "getpw() found."
    getpwent='undef'
else
    $echo "No getpw() found--will use getpwent() instead."
    getpwent='define'
fi

: see how we will look up site name
douname=undef
gethostname=undef
phostname=undef
if $contains gethostname.o libc.list >/dev/null 2>&1 ; then
    $echo "gethostname() found."
    gethostname=define
else
    if $contains uname.o libc.list >/dev/null 2>&1 ; then
	$echo "uname() found."
	douname=define
    else
	case $hostcmd in
	  '') ;;
	  *)
	    $cat <<EOT

There is no gethostname() or uname() on this system.  You have two
possibilites at this point:

1)  You can have your site name ($sitename) compiled into rn, which lets rn
    start up faster, but makes your binaries non-portable, or
2)  you can have rn use a
	
	popen("$hostcmd","r")

    which will start slower but be more portable.

Option 1 will use whoami.h if you have one.  If you want option 2 but with
a different command, you can edit config.h after this shell script is done.

EOT
	    case $portable in
	    define) dflt=n ;;
	    *)      dflt=y ;;
	    esac
	    $echo $n "Do you want your site name compiled in? [$dflt] $c"
	    read ans
	    case $ans in
	      '') phostname=$portable ;;
	      n*) phostname=define ;;
	      *)  hostcmd='' ;;
	    esac
	    ;;
	esac
	case $hostcmd in
	  '')
	    case $whoami in
	      define)
		$echo 'No hostname function--using whoami.h.'
		;;
	      undef)
		$echo 'No hostname function--hardwiring "'$sitename'".'
		;;
	    esac
	    ;;
	esac
    fi
fi

: see if we need -ljobs and if we have sigset, etc.
if $test -r /usr/lib/libjobs.a || $test -r /usr/local/lib/libjobs.a ; then
    $echo "Jobs library found."
    normsig=undef
    jobslib='-ljobs'
else
    if bsd; then
	$echo "No jobs library found.  (I suppose this is 4.2...)"
    else
	$echo "No jobs library found.  (That's okay, we all have our faults.)"
    fi
    normsig=define
    jobslib=''
fi

: see if there are directory access routines out there
if $test -r /usr/lib/libndir.a || $test -r /usr/local/lib/libndir.a ; then
    $echo "Ndir library found."
    ndirlib='-lndir'
    libndir=define
    usendir=undef
else
    ndirlib=''
    libndir=undef
    if $contains readdir.o libc.list >/dev/null 2>&1 ; then
	$echo "No ndir library found, but you have readdir() so we'll hope this is 4.2bsd."
	usendir=undef
    else
	$echo "No ndir library found and no readdir() found--using ./ndir.c."
	usendir=define
    fi
fi

: locate spool directory
spool=/usr/spool/news
ans=$spool
while $test ! -d $ans; do
    $echo ""
    $echo $n "$ans not found--where is news spooled? (~name ok) $c"
    read spool
    case $spool in
    ~*)
	ans=`filexp $spool`
	echo "(That is $ans on this particular system.)"
	case $portable in
	  undef) spool=$ans ;;
	esac
	;;
    *)
	ans=$spool
	;;
    esac
done
$echo "SPOOL = $spool"

: locate active file
active=$lib/active
myactive=$libexp/active
while $test ! -f $myactive; do
    $echo ""
    $echo $n "$myactive not found--where is the active file? (~name ok) $c"
    read active
    case $active in
    ~*)
	myactive=`filexp $active`
	echo "(That is $myactive on this particular system.)"
	case $portable in
	  undef) active=$myactive ;;
	esac
	;;
    *)
	myactive=$active
	;;
    esac
    if $test -d $myactive ; then
	myactive=$myactive/active
	active=$active/active
    fi
done
$echo "ACTIVE = $active"

: check for 2.10.2
echo ""
if $contains ' [0-9][0-9]* [0-9]' $myactive >/dev/null 2>&1; then
    echo "Looks like you are running at least 2.10.2 news."
    mininact=define
else
    echo "It doesn't look like you are running 2.10.2 news yet.  Are you planning"
    echo $n "to install it in the near future? [y] $c"
    read ans
    case $ans in
    n*) mininact=undef ;;
    *)  mininact=define ;;
    esac
fi


: check for void type
$echo ""
$echo "Checking to see if your C compiler groks the void type..."
$cat >try.c <<'EOCP'
void main();
EOCP
if cc -c try.c >/dev/null 2>&1 ; then
    novoid='undef'
    $echo "Yup, it does."
else
    novoid='define'
    $echo "Nope, it doesn't (boo hiss).  I will substitute int."
fi
$rm try.*

: find out which shell people like to use most
ans='blurfl'
while $test ! -f "$ans" ; do
    case $ans in
      blurfl) ;;
      *) $echo "$ans does not appear to exist." ;;
    esac
    if $test -f /bin/ksh; then
	dflt='/bin/ksh'
    else
	if $test -f /bin/csh; then
	    dflt='/bin/csh'
	else
	    dflt='/bin/sh'
	fi
    fi
    $echo ""
    $echo "Give the full path name of the shell most people like to use on your"
    $echo $n "system: [$dflt] $c"
    read ans
    case $ans in
      '') ans=$dflt ;;
    esac
done
pref=$ans

: locate the preferred pager for this system
pager='blurfl'
while $test ! -f "$pager" ; do
    case $pager in
      blurfl)
	$echo ""
	$echo "(If your kernel does terminal paging then you may answer this with '/bin/cat'.)"
	;;
      /*) $echo "$pager does not appear to exist."
	$echo ""
        ;;
      *) $echo "Please give the full path name."
	$echo ""
        ;;
    esac
    $echo $n "What pager is used on your system? [/usr/ucb/more] $c"
    read pager
    case $pager in
      '') pager='/usr/ucb/more' ;;
    esac
done

: determine default editor
dflt=/usr/ucb/vi
defeditor='blurfl'
while $test ! -f "$defeditor" ; do
    case $defeditor in
      blurfl) ;;
      *) $echo "$defeditor does not appear to exist." ;;
    esac
    $echo ""
    $echo $n "What is the default editor on your system? [$dflt] $c"
    read defeditor
    case $defeditor in
      '') defeditor=$dflt ;;
    esac
done

: determine mailer for Rnmail to use
echo ""
if $test -f /usr/lib/sendmail; then
    mailer=/usr/lib/sendmail
else
    if usg && $test -f $libexp/recmail; then
	mailer=$libexp/recmail
    else
	mailer=/bin/mail
    fi
fi
echo "Mail sender is $mailer"

: determine where public executables go
if $test -d /usr/local/bin; then
    dflt=/usr/local/bin
else
    if $test -d /usr/local; then
	dflt=/usr/local
    else
	if $test -d /usr/bin; then
	    dflt=/usr/bin
	else
	    dflt=/bin
	fi
    fi
fi
rnbin='blurfl'
while $test ! -d "$rnbin" ; do
    case $rnbin in
      blurfl) ;;
      *) $echo "$rnbin does not appear to exist." ;;
    esac
    $echo ""
    $echo $n "Where do you want to put the public executables? [$dflt] $c"
    read rnbin
    rnbin=`filexp $rnbin`
    case $rnbin in
      '') rnbin=$dflt ;;
    esac
done

: determine where private executables go
dflt=$lib/rn
$echo ""
$echo "Rn has a number of auxiliary programs that need not be visible to the"
$echo "whole world.  Where do you want to put these private executables?"
$echo $n "[$dflt] (~name ok) $c"
read rnlib
case $rnlib in
  '') rnlib=$dflt ;;
esac
case $portable in
undef)
    rnlib=`filexp $rnlib`
    echo "RNLIB = $rnlib"
    ;;
esac
: must not allow self reference
case $rnlib in
  /*)
    filexp=$rnlib/filexp
    ;;
  *)
    filexp=`pwd`/filexp
    ;;
esac

: determine where manual pages go
if $test -d /usr/man/local/man1; then
    dflt=/usr/man/local/man1
else
    dflt=/usr/man/man1
fi
mansrc='blurfl'
while $test ! -d "$mansrc" ; do
    case $mansrc in
      blurfl) ;;
      *) $echo "$mansrc does not appear to exist." ;;
    esac
    $echo ""
    $echo $n "Where do the manual pages go? [$dflt] $c"
    read mansrc
    mansrc=`filexp $mansrc`
    case $mansrc in
      '') mansrc=$dflt ;;
    esac
done

: get the local distribution prefixes
if $test -f $libexp/sys ; then
    $sed <$libexp/sys -n -e "s/^$sitename://p" | \
    $sed -e "s/:.*//" -e "s/,/ /g" | tr ' ' '\012' | \
    $sed -e "/^to./d" -e "/^net$/d" -e "/^fa$/d" -e "/^mod$/d" > .distlist
fi

$cat <<'EOH'

Distribution groups are the things you use on the Distribution line to limit
where an article will go to.  You are likely to be a member of several
distribution groups, such as organization, city, state, province, country,
continent, etc.  For example, Los Angeles has the distribution prefix "la",
New Jersey has the prefix "nj", and Europe has the prefix "eur".

The categories you will be asked are: 

local organization	(Could be just one machine or a cluster or an office)
organization		att, dec, kgb, ...
city			la, ny, mosc, ...
state/province		ca, nj, bc, ...
country			usa, can, rok, whatever
continent		na (North America, not "Not Applicable"), eur, etc.

(If you don't have a distribution prefix in any of these categories then
just hit return.)

EOH
if $test -f .distlist; then
    distlist=`tr '\012' ' ' <.distlist`
    if $test "$distlist" ; then
	$echo "(These are the distributions in your sys file: $distlist)"
	$echo ""
    fi
fi
$echo $n "What is the distribution prefix for your local organization? $c"
read locpref
case $locpref in
  '') locpref=none ;;
esac
$echo $n "What is the distribution prefix for your organization? $c"
read orgpref
case $orgpref in
  '') orgpref=none ;;
esac
$echo $n "What is the distribution prefix for your city? $c"
read citypref
case $citypref in
  '') citypref=none ;;
esac
$echo $n "What is the distribution prefix for your state/province? $c"
read statepref
case $statepref in
  '') statepref=none ;;
esac
$echo $n "What is the distribution prefix for your country? $c"
read cntrypref
case $cntrypref in
  '') cntrypref=none ;;
esac
$echo $n "What is the distribution prefix for your continent? $c"
read contpref
case $contpref in
  '') contpref=none ;;
esac

$echo ""
$echo "If you have any other distribution groups you will need to edit Pnews"
$echo "and newsetup to add them."
$echo ""

: determine root id
rootid=`$sed </etc/passwd -e "/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*"'$'"/\1/" -e "q" -e "}" -e "d"`
case $rootid in
  '') rootid=0 ;;
  *)  $echo "Root uid = $rootid" ;;
esac

: weed out incompatibilities
case $douname in
  define) whoami=undef ;;
esac

: preserve RCS keywords in files with variable substitution, grrr
Log='$Log'
Header='$Header'

: Warnings
if v7; then
    cat <<'EOM'

NOTE: the V7 compiler may ignore some #undefs that rn uses.  If so, you will
get messages about redefining EXT.  Ignore them.
EOM
fi

if pdp11; then
    cat <<'EOM'

NOTE: the PDP-11 does not have enough data space to do subject caching
reliably.  That feature will be disabled automatically.  Subject searching
will tend to be slow.
EOM
fi

$echo ""
$echo "End of configuration questions."
$echo ""

: create config.sh file
$echo ""
$echo "Creating config.sh..."
$spitshell <<EOT >config.sh
$startsh
# config.sh
# This file was produced by running the Configure script.

n="$n"
c="$c"
libc="$libc"
eunicefix="$eunicefix"
eunice="$eunice"
cpp="$cpp"
shsharp="$shsharp"
startsh="$startsh"
spitshell="$spitshell"
test="$test"
expr="$expr"
sed="$sed"
echo="$echo"
cat="$cat"
rm="$rm"
mv="$mv"
cp="$cp"
tail="$tail"
tr="$tr"
mkdir="$mkdir"
sort="$sort"
uniq="$uniq"
inews="$inews"
grep="$grep"
egrep="$egrep"
contains="$contains"
lib="$lib"
libexp="$libexp"
nametype="$nametype"
iandd="$iandd"
termlib="$termlib"
jobslib="$jobslib"
ndirlib="$ndirlib"
libndir="$libndir"
usendir="$usendir"
pager="$pager"
mailer="$mailer"
rnbin="$rnbin"
filexp="$filexp"
distlist="$distlist"
Log="$Log"
Header="$Header"
sitename="$sitename"
orgname="$orgname"
isadmin="$isadmin"
newsadmin="$newsadmin"
rnlib="$rnlib"
mansrc="$mansrc"
spool="$spool"
active="$active"
mininact="$mininact"
pref="$pref"
defeditor="$defeditor"
rootid="$rootid"
mboxchar="$mboxchar"
locpref="$locpref"
orgpref="$orgpref"
citypref="$citypref"
statepref="$statepref"
cntrypref="$cntrypref"
contpref="$contpref"
strchr="$strchr"
novoid="$novoid"
novfork="$novfork"
portable="$portable"
passnam="$passnam"
berknam="$berknam"
usgnam="$usgnam"
whoami="$whoami"
termio="$termio"
normsig="$normsig"
havetlib="$havetlib"
getpwent="$getpwent"
gethostname="$gethostname"
douname="$douname"
phostname="$phostname"
hostcmd="$hostcmd"
CONFIG=true
EOT

CONFIG=true

: now put these in environment for subsequent shell scripts
export n
export c
export libc
export eunicefix
export eunice
export cpp
export shsharp
export spitshell
export startsh
export test
export expr
export sed
export echo
export cat
export rm
export mv
export cp
export tail
export tr
export mkdir
export sort
export uniq
export inews
export grep
export egrep
export contains
export lib
export nametype
export iandd
export termlib
export jobslib
export ndirlib
export libndir
export usendir
export pager
export mailer
export rnbin
export filexp
export distlist
export Log
export Header
export sitename
export orgname
export isadmin
export newsadmin
export rnlib
export mansrc
export spool
export active
export mininact
export pref
export defeditor
export rootid
export mboxchar
export locpref
export orgpref
export citypref
export statepref
export cntrypref
export contpref
export strchr
export novoid
export novfork
export portable
export passnam
export berknam
export usgnam
export whoami
export termio
export normsig
export havetlib
export getpwent
export gethostname
export douname
export phostname
export hostcmd
export CONFIG

: create config.h file
$echo ""
$echo "Creating config.h..."
$cat <<EOT >config.h
/* config.h
 * This file was produced by running the Configure script.
 * Feel free to modify any of this as the need arises.
 */

/* name of the site.  May be overridden by gethostname, uname, etc. */
#define SITENAME "$sitename"

/* name of the organization, may be a file name */
#define ORGNAME "$orgname"

/* login name of news administrator, if any. */
#$isadmin NEWSADMIN "$newsadmin"

/* news library, may use only ~ and %l expansion */
#define LIB "$lib"

/* rn private library, may use ~ expansion, %x and %l */
#define RNLIB "$rnlib"

/* location of the news spool directory, may use ~ expansion, %x and %l */
#define SPOOL "$spool"

/* location of the active file, may use ~ expansion, %x and %l */
#define ACTIVE "$active"

/* default shell--ok to be a slow shell like csh */
#define PREFSHELL "$pref"

/* default editor */
#define DEFEDITOR "$defeditor"

/* root uid */
#define ROOTID $rootid

/* what is the first character of a mailbox? */
#define MBOXCHAR '$mboxchar'

/* how to cancel an article */
#define CANCEL "$inews -h <%h"

/* distribution groups */
#define LOCDIST "$locpref"
#define ORGDIST "$orgpref"
#define CITYDIST "$citypref"
#define STATEDIST "$statepref"
#define CNTRYDIST "$cntrypref"
#define CONTDIST "$contpref"

#$strchr	index strchr	/* cultural */
#$strchr	rindex strrchr	/*  differences? */
#$novoid	void int	/* is void to be avoided? */
#$novfork	vfork fork	/* is vfork too virtual? */
#$eunice	EUNICE		/* no linking? */
#$eunice	VMS		/* not currently used, here just in case */
#$usendir	USENDIR		/* include ndir.c? */
#$libndir	LIBNDIR		/* include /usr/include/ndir.h? */
#$mininact	MININACT	/* include 2.10.2 optimization? */
#$portable	PORTABLE	/* do we do extra lookups to start up? */
#$passnam	PASSNAMES	/* do names come from the passwd file? */
				/*  (undef to take name from ~/.fullname) */
#$berknam	BERKNAMES	/* if so, are they Berkeley format? */
				/* (that is, ":name,stuff:") */
#$usgnam	USGNAMES	/* or are they USG format? */
				/* (that is, ":stuff-name(stuff):") */
#$whoami	WHOAMI		/* should we include whoami.h? */
#$termio	TERMIO		/* is this a termio system? */
#$normsig	NORMSIG		/* use signal rather than sigset? */
#$havetlib	HAVETERMLIB	/* do we have termlib-style routines? */
#$getpwent	GETPWENT	/* need we include slow getpwent? */
#$gethostname	GETHOSTNAME	/* do we have a gethostname function? */
#$douname	DOUNAME		/* do we have a uname function? */
#$phostname	PHOSTNAME "$hostcmd"	/* how to get host name with popen */
EOT

$rm -f libc.list .distlist kit*isdone

echo ""
echo "Doing variable substitutions on various files..."
echo ""
set `$grep <MANIFEST '\.SH' | awk '{print $1}'`
for file in $*; do
    sh <$file
done

echo ""
echo "Remaking make dependencies..."
makedepend
!STUFFY!FUNK!
echo Extracting ng.c
cat >ng.c <<'!STUFFY!FUNK!'
/* $Header: ng.c,v 4.1 84/09/24 12:01:53 lwall Exp $
 *
 * $Log:	ng.c,v $
 * Revision 4.1  84/09/24  12:01:53  lwall
 * Real baseline.
 * 
 * Revision 4.0.1.6  84/09/19  17:09:39  lwall
 * Ifdef'ed some stuff that should have been.
 * 
 * Revision 4.0.1.5  84/09/19  10:14:10  lwall
 * Maybe not clear() on End of newsgroup.
 * 
 * Revision 4.0.1.4  84/09/18  16:59:39  lwall
 * Defined s for = command.
 * 
 * Revision 4.0.1.3  84/09/12  17:43:05  lwall
 * Fixed overzealous cast.
 * 
 * Revision 4.0.1.2  84/09/10  15:16:39  lwall
 * Delinted.
 * 
 * Revision 4.0.1.1  84/09/06  17:03:10  lwall
 * Implemented newsgroup exit commands.
 * 
 * Revision 4.0  84/09/04  09:51:39  lwall
 * Baseline for netwide release
 * 
 */

#include "EXTERN.h"
#include "common.h"
#include "rn.h"
#include "term.h"
#include "final.h"
#include "util.h"
#include "artsrch.h"
#include "cheat.h"
#include "help.h"
#include "kfile.h"
#include "rcstuff.h"
#include "head.h"
#include "artstate.h"
#include "bits.h"
#include "art.h"
#include "artio.h"
#include "ngstuff.h"
#include "intrp.h"
#include "respond.h"
#include "ngdata.h"
#include "backpage.h"
#include "rcln.h"
#include "last.h"
#include "INTERN.h"
#include "ng.h"
#include "artstate.h"			/* somebody has to do it */

/* art_switch() return values */

#define AS_NORM 0
#define AS_INP 1
#define AS_ASK 2
#define AS_CLEAN 3

ART_NUM recent_art = 0;		/* previous article # for '-' command */
ART_NUM curr_art = 0;                /* current article # */

void
ng_init()
{

#ifdef KILLFILES
    open_kfile(KF_GLOBAL);
#endif
}

/* do newsgroup on line ng with name ngname */

/* assumes that we are chdir'ed to SPOOL, and assures that that is
 * still true upon return, but chdirs to SPOOL/ngname in between
 *
 * If you can understand this routine, you understand most of the program.
 * The basic structure is:
 *	for each desired article
 *		for each desired page
 *			for each line on page
 *				if we need another line from file
 *					get it
 *					if it's a header line
 *						do special things
 *				for each column on page
 *					put out a character
 *				end loop
 *			end loop
 *		end loop
 *	end loop
 *
 *	(Actually, the pager is in another routine.)
 *
 * The chief problem is deciding what is meant by "desired".  Most of
 * the messiness of this routine is due to the fact that people want
 * to do unstructured things all the time.  I have used a few judicious
 * goto's where I thought it improved readability.  The rest of the messiness
 * arises from trying to be both space and time efficient.  Have fun.
 */

int
do_newsgroup(start_command)
char *start_command;			/* command to fake up first */
{
    register long i;			/* scratch */
    int skipstate;			/* how many unavailable articles */
					/*   have we skipped already? */
    
    char *whatnext = "%sWhat next? [%s]";

#ifdef ARTSEARCH
    srchahead = (scanon && ((ART_NUM)toread[ng]) >= scanon ? -1 : 0);
					/* did they say -S? */
#endif
    
    if (eaccess(ngdir,5)) {		/* directory read protected? */
	if (eaccess(ngdir,0)) {
#ifdef VERBOSE
	    IF(verbose)
		printf("\nNewsgroup %s does not have a spool directory!\n",
		    ngname);
	    ELSE
#endif
#ifdef TERSE
		printf("\nNo spool for %s!\n",ngname);
#endif
#ifdef CATCHUP
	    catch_up(ng);
#endif
	    toread[ng] = TR_NONE;
	}
	else {
#ifdef VERBOSE
	    IF(verbose)
		printf("\nNewsgroup %s is not currently accessible.\n",
		    ngname);
	    ELSE
#endif
#ifdef TERSE
		printf("\n%s not readable.\n",ngname);
#endif
	    toread[ng] = TR_NONE;	/* make this newsgroup invisible */
					/* (temporarily) */
	}
	return -1;
    }

    /* chdir to newsgroup subdirectory */

    if (chdir(ngdir)) {
	printf(nocd,ngdir);
	return -1;
    }

#ifdef CACHESUBJ
    subj_list = Null(char **);		/* no subject list till needed */
#endif
    
    /* initialize control bitmap */

    if (initctl())
	return -1;

    /* FROM HERE ON, RETURN THRU CLEANUP OR WE ARE SCREWED */
    
    in_ng = TRUE;			/* tell the world we are here */
    forcelast = TRUE;			/* if 0 unread, do not bomb out */
    art=firstart;
    
    /* remember what newsgroup we were in for sake of posterity */

    writelast();

    /* do they want a special top line? */

    firstline = getval("FIRSTLINE",Nullch);

    /* see if there are any special searches to do */

#ifdef KILLFILES
    open_kfile(KF_LOCAL);
#ifdef VERBOSE
    IF(verbose)
	kill_unwanted(firstart,"Looking for articles to kill...\n\n",TRUE);
    ELSE
#endif
#ifdef TERSE
	kill_unwanted(firstart,"Killing...\n\n",TRUE);
#endif
#endif
    
    /* now read each unread article */

    rc_changed = doing_ng = TRUE;	/* enter the twilight zone */
    skipstate = 0;			/* we have not skipped anything (yet) */
    checkcount = 0;			/* do not checkpoint for a while */
    do_fseek = FALSE;			/* start 1st article at top */
    if (art > lastart)
	art=firstart;			/* init the for loop below */
    for (; art<=lastart+1; ) {		/* for each article */

	/* do we need to "grow" the newsgroup? */

	if (art > lastart || forcegrow)
	    grow_ctl();
	check_first(art);		/* make sure firstart is still 1st */
	if (start_command) {		/* fake up an initial command? */
	    prompt = whatnext;
	    strcpy(buf,start_command);
	    free(start_command);
	    start_command = Nullch;
	    art = lastart+1;
	    goto article_level;
	}
	if (art>lastart) {		/* are we off the end still? */
	    ART_NUM ucount = 0;		/* count of unread articles left */

	    for (i=firstart; i<=lastart; i++)
		/*NOSTRICT*/
		if (!(ctl_read(i)))
		    ucount++;		/* count the unread articles */
#ifdef DEBUGGING
	    /*NOSTRICT*/
	    if (debug && ((ART_NUM)toread[ng]) != ucount)
		printf("(toread=%ld sb %ld)",(long)toread[ng],(long)ucount);
#endif
	    /*NOSTRICT*/
	    toread[ng] = (ART_UNREAD)ucount;	/* this is perhaps pointless */
	    art = lastart + 1;		/* keep bitmap references sane */
	    if (art != curr_art) {
		recent_art = curr_art;
					/* remember last article # (for '-') */
		curr_art = art;      /* remember this article # */
	    }
	    if (erase_screen)
		clear();			/* clear the screen */
	    else
		fputs("\n\n",stdout);
#ifdef VERBOSE
	    IF(verbose)
		printf("End of newsgroup %s.",ngname);
					/* print pseudo-article */
	    ELSE
#endif
#ifdef TERSE
		printf("End of %s",ngname);
#endif
	    if (ucount) {
		printf("  (%ld article%s still unread)",
		    (long)ucount,ucount==1?nullstr:"s");
	    }
	    else {
		if (!forcelast)
		    goto cleanup;	/* actually exit newsgroup */
	    }
	    prompt = whatnext;
#ifdef ARTSEARCH
	    srchahead = 0;		/* no more subject search mode */
#endif
	    fputs("\n\n",stdout);
	    skipstate = 0;		/* back to none skipped */
	}
	else if /*NOSTRICT*/ (!reread && was_read(art)) {
					/* has this article been read? */
	    art++;			/* then skip it */
	    continue;
	}
	else if /*NOSTRICT*/ (!reread && !was_read(art)
	    && artopen(art) == Nullfp) {	/* never read it, & cannot find it? */
	    if (errno != ENOENT) {	/* has it not been deleted? */
#ifdef VERBOSE
		IF(verbose)
		    printf("\n(Article %ld exists but is unreadable.)\n",
			(long)art);
		ELSE
#endif
#ifdef TERSE
		    printf("\n(%ld unreadable.)\n",(long)art);
#endif
		skipstate = 0;
		sleep(2);
	    }
	    switch(skipstate++) {
	    case 0:
		clear();
#ifdef VERBOSE
		IF(verbose)
		    fputs("Skipping unavailable article",stdout);
		ELSE
#endif
#ifdef TERSE
		    fputs("Skipping",stdout);
#endif
		for (i = just_a_sec/3; i; --i)
		    putchar(PC);
		fflush(stdout);
		sleep(1);
		break;
	    case 1:
		fputs("..",stdout);
		fflush(stdout);
		break;
	    default:
		putchar('.');
		fflush(stdout);
#define READDIR
#ifdef READDIR
		{			/* fast skip patch */
		    ART_NUM newart;
		    
		    if (! (newart=getngmin(".",art)))
			newart = lastart+1;
		    for (i=art; i<newart; i++)
			oneless(i);
		    art = newart - 1;
		}
#endif
		break;
	    }
	    oneless(art);		/* mark deleted as read */
	    art++;			/* try next article */
	    continue;
	}
	else {				/* we have a real live article */
	    skipstate = 0;		/* back to none skipped */
	    if (art != curr_art) {
		recent_art = curr_art;
					/* remember last article # (for '-') */
		curr_art = art;      /* remember this article # */
	    }
	    if (!do_fseek) {		/* starting at top of article? */
		artline = 0;		/* start at the beginning */
		topline = -1;		/* and remember top line of screen */
					/*  (line # within article file) */
	    }
	    clear();			/* clear screen */
	    artopen(art);		/* make sure article file is open */
	    if (artfp == Nullfp) {	/* could not find article? */
		printf("Article %ld of %s is not available.\n\n",
		    (long)art,ngname);
		prompt = whatnext;
#ifdef ARTSEARCH
		srchahead = 0;
#endif
	    }
	    else {			/* found it, so print it */
		switch (do_article()) {
		case DA_CLEAN:		/* quit newsgroup */
		    goto cleanup;
		case DA_TOEND:		/* do not mark as read */
		    goto reask_article; 
		case DA_RAISE:		/* reparse command at end of art */
		    goto article_level;
		case DA_NORM:		/* normal end of article */
		    break;
		}
	    }
	    mark_as_read(art);		 /* mark current article as read */
	    reread = FALSE;
	    do_hiding = TRUE;
#ifdef ROTATION
	    rotate = FALSE;
#endif
	}

/* if these gotos bother you, think of this as a little state machine */

reask_article:
#ifdef MAILCALL
	setmail();
#endif
	setdfltcmd();
	standout();			/* enter standout mode */
	printf(prompt,mailcall,dfltcmd);/* print prompt, whatever it is */
	un_standout();			/* leave standout mode */
	putchar(' ');
	fflush(stdout);
reinp_article:
	eat_typeahead();
#ifdef PENDING
	look_ahead();			/* see what we can do in advance */
	if (!input_pending())
	    collect_subjects();		/* loads subject cache until */
					/* input is pending */
#endif
	getcmd(buf);
	if (errno || *buf == '\f') {
	    if (LINES < 100 && !int_count)
		*buf = '\f';		/* on CONT fake up refresh */
	    else {
		putchar('\n');		/* but only on a crt */
		goto reask_article;
	    }
	}
article_level:

	/* parse and process article level command */

	switch (art_switch()) {
	case AS_INP:			/* multichar command rubbed out */
	    goto reinp_article;
	case AS_ASK:			/* reprompt "End of article..." */
	    goto reask_article;
	case AS_CLEAN:			/* exit newsgroup */
	    goto cleanup;
	case AS_NORM:			/* display article art */
	    break;
	}
    }					/* end of article selection loop */
    
/* shut down newsgroup */

cleanup:
#ifdef KILLFILES
    kill_unwanted(firstart,"\nCleaning up...\n\n",FALSE);
					/* do cleanup from KILL file, if any */
#endif
    in_ng = FALSE;			/* leave newsgroup state */
    if (artfp != Nullfp) {		/* article still open? */
	fclose(artfp);			/* close it */
	artfp = Nullfp;			/* and tell the world */
	openart = 0;
    }
    putchar('\n');
    yankback();				/* do a Y command */
    restore_ng();			/* reconstitute .newsrc line */
    doing_ng = FALSE;			/* tell sig_catcher to cool it */
    free(ctlarea);			/* return the control area */
#ifdef CACHESUBJ
    if (subj_list) {
	for (i=OFFSET(lastart); i>=0; --i)
	    if (subj_list[i])
		free(subj_list[i]);
	/*NOSTRICT*/
	free((char*)subj_list);
    }
#endif
    write_rc();				/* and update .newsrc */
    rc_changed = FALSE;			/* tell sig_catcher it is ok */
    if (chdir(spool)) {
	printf(nocd,spool);
	sig_catcher(0);
    }
#ifdef KILLFILES
    if (localkfp) {
	fclose(localkfp);
	localkfp = Nullfp;
    }
#endif
    return 0;
}					/* Whew! */

/* decide what to do at the end of an article */

int
art_switch()
{
    register ART_NUM i;
      
    setdef(buf,dfltcmd);
#ifdef VERIFY
    printcmd();
#endif
    switch (*buf) {
    case 'p':			/* find previous unread article */
	do {
	    if (art <= firstart)
		break;
	    art--;
	} while /*NOSTRICT*/ (was_read(art) || artopen(art) == Nullfp);
#ifdef ARTSEARCH
	srchahead = 0;
#endif
	return AS_NORM;
    case 'P':			/* goto previous article */
	if (art > absfirst)
	    art--;
	else {
#ifdef VERBOSE
	    IF(verbose)
		fputs("\n\
There are no articles prior to this one.\n\
",stdout);
	    ELSE
#endif
#ifdef TERSE
		fputs("\nNo previous articles\n",stdout);
#endif
	    return AS_ASK;
	}
	reread = TRUE;
#ifdef ARTSEARCH
	srchahead = 0;
#endif
	return AS_NORM;
    case '-':
	if (recent_art)
	    art = recent_art;
	reread = TRUE;
#ifdef ARTSEARCH
	srchahead = -(srchahead != 0);
#endif
	return AS_NORM;
    case 'n':		/* find next unread article? */
	if (art > lastart) {
	    if (toread[ng])
		art = firstart;
	    else
		return AS_CLEAN;
	}
#ifdef ARTSEARCH
	else if (scanon && srchahead) {
	    *buf = Ctl('n');
	    goto normal_search;
	}
#endif
	else
	    art++;
#ifdef ARTSEARCH
	srchahead = 0;
#endif
	return AS_NORM;
    case 'N':			/* goto next article */
	if (art > lastart)
	    art = absfirst;
	else
	    art++;
	if (art <= lastart)
	    reread = TRUE;
#ifdef ARTSEARCH
	srchahead = 0;
#endif
	return AS_NORM;
    case '$':
	art = lastart+1;
	forcelast = TRUE;
#ifdef ARTSEARCH
	srchahead = 0;
#endif
	return AS_NORM;
    case '1': case '2': case '3':	/* goto specified article */
    case '4': case '5': case '6':	/* or do something with a range */
    case '7': case '8': case '9': case '.':
	forcelast = TRUE;
	switch (numnum()) {
	case NN_INP:
	    return AS_INP;
	case NN_ASK:
	    return AS_ASK;
	case NN_REREAD:
	    reread = TRUE;
	    break;
	case NN_NORM:
	    /*NOSTRICT*/
	    if (was_read(art)) {
		art = firstart;
		pad(just_a_sec/3);
	    }
	    else
		return AS_ASK;
	    break;
	}
	return AS_NORM;
    case Ctl('k'):
	edit_kfile();
	return AS_ASK;
    case 'K':
    case 'k':
    case Ctl('n'): case Ctl('p'):
    case '/': case '?':
#ifdef ARTSEARCH
normal_search:
    {		/* search for article by pattern */
	char cmd = *buf;
	
	reread = TRUE;		/* assume this */
	switch (art_search(buf,TRUE)) {
	case SRCH_ERROR:
	    return AS_ASK;
	case SRCH_ABORT:
	    return AS_INP;
	case SRCH_INTR:
#ifdef VERBOSE
	    IF(verbose)
		printf("\n(Interrupted at article %ld)\n",(long)art);
	    ELSE
#endif
#ifdef TERSE
		printf("\n(Intr at %ld)\n",(long)art);
#endif
	    art = curr_art;
			    /* restore to current article */
	    return AS_ASK;
	case SRCH_DONE:
	    fputs("done\n",stdout);
	    pad(just_a_sec/3);	/* 1/3 second */
	    if (srchahead)
		art = firstart;
	    else
		art = curr_art;
	    reread = FALSE;
	    return AS_NORM;
	case SRCH_SUBJDONE:
#ifdef UNDEF
	    fputs("\n\n\n\nSubject not found.\n",stdout);
	    pad(just_a_sec/3);	/* 1/3 second */
#endif
	    art = firstart;
	    reread = FALSE;
	    return AS_NORM;
	case SRCH_NOTFOUND:
	    fputs("\n\n\n\nNot found.\n",stdout);
	    art = curr_art;  /* restore to current article */
	    return AS_ASK;
	case SRCH_FOUND:
	    if (cmd == Ctl('n') || cmd == Ctl('p'))
		oldsubject = TRUE;
	    break;
	}
	return AS_NORM;
    }
#else
    buf[1] = '\0';
    notincl(buf);
    return AS_ASK;
#endif
    case 'u':			/* unsubscribe from this newsgroup? */
	rcchar[ng] = NEGCHAR;
	return AS_CLEAN;
    case 'M':
#ifdef DELAYMARK
	if (art <= lastart) {
	    delay_unmark(art);
	    printf("\nArticle %ld will return.\n",(long)art);
	}
#else
	notincl("M");
#endif
	return AS_ASK;
    case 'm':
	if (art <= lastart) {
	    unmark_as_read(art);
	    printf("\nArticle %ld marked as still unread.\n",(long)art);
	}
	return AS_ASK;
    case 'c':			/* catch up */
      reask_catchup:
#ifdef VERBOSE
	IF(verbose)
	    in_char("\nDo you really want to mark everything as read? [yn] ");
	ELSE
#endif
#ifdef TERSE
	    in_char("\nReally? [ynh] ");
#endif
	putchar('\n');
	setdef(buf,"y");
#ifdef VERIFY
	printcmd();
#endif
	if (*buf == 'h') {
#ifdef VERBOSE
	    IF(verbose)
		fputs("\
Type y or SP to mark all articles as read.\n\
Type n to leave articles marked as they are.\n\
",stdout);
	    ELSE
#endif
#ifdef TERSE
		fputs("\
y or SP to mark all read.\n\
n to forget it.\n\
",stdout);
#endif
	    goto reask_catchup;
	}
	else if (*buf == 'n' || *buf == 'q') {
	    return AS_ASK;
	}
	else if (*buf != 'y') {
	    fputs(hforhelp,stdout);
	    goto reask_catchup;
	}
	for (i = firstart; i <= lastart; i++) {
	    /*NOSTRICT*/
	    ctl_set(i);		/* mark as read */
	}
#ifdef DELAYMARK
	if (dmfp)
	    yankback();
#endif
	art = lastart+1;
	return AS_NORM;
    case 'q':			/* go back up to newsgroup level? */
	return AS_CLEAN;
    case 'j':
	putchar('\n');
	if (art <= lastart)
	    mark_as_read(art);
	return AS_ASK;
    case 'h':			/* help? */
	help_art();
	return AS_ASK;
    case '&':
	if (switcheroo()) /* get rest of command */
	    return AS_INP;	/* if rubbed out, try something else */
	return AS_ASK;
    case '#':
#ifdef VERBOSE
	IF(verbose)
	    printf("\nThe last article is %ld.\n",(long)lastart);
	ELSE
#endif
#ifdef TERSE
	    printf("\n%ld\n",(long)lastart);
#endif
	return AS_ASK;
    case '=': {
	char tmpbuf[128];
#ifndef CACHESUBJ
	char *s;
#endif
	
	page_line = 1;
	putchar('\n');
#ifdef CACHESUBJ
	if (!subj_list)
	    fetchsubj(art,TRUE,FALSE);
#endif
	for (i=firstart; i<=lastart && !int_count; i++) {
	    /*NOSTRICT*/
	    if (!was_read(i) &&
	      (
#ifdef CACHESUBJ
	      subj_list[OFFSET(i)] != Nullch || fetchsubj(i,FALSE,FALSE)
#else
	      s = fetchsubj(i,FALSE,FALSE)
#endif
	      ) ) {
		sprintf(tmpbuf,"%5d ", i);
		safecpy(tmpbuf + 6,
#ifdef CACHESUBJ
		subj_list[OFFSET(i)],
#else
		s,
#endif
		120);
		if (print_lines(tmpbuf,NOMARKING))
		    break;
	    }
	}
	int_count = 0;
	return AS_ASK;
    }
    case '^':
	art = firstart;
#ifdef ARTSEARCH
	srchahead = 0;
#endif
	return AS_NORM;
#if defined(CACHESUBJ) && defined(DEBUGGING)
    case 'D':
	printf("\nFirst article: %ld\n",(long)firstart);
	if (!subj_list)
	    fetchsubj(art,TRUE,FALSE);
	if (subj_list != Null(char **)) {
	    for (i=1; i<=lastart && !int_count; i++) {
		if (subj_list[OFFSET(i)])
		    /*NOSTRICT*/
		    printf("%5d %c %s\n",
			i, (was_read(i)?'y':'n'), subj_list[OFFSET(i)]);
	    }
	}
	int_count = 0;
	return AS_ASK;
#endif
    case 'v':
	if (art <= lastart) {
	    reread = TRUE;
	    do_hiding = FALSE;
	}
	return AS_NORM;
#ifdef ROTATION
    case Ctl('x'):
#endif
    case Ctl('r'):
#ifdef ROTATION
	rotate = (*buf==Ctl('x'));
#endif
	if (art <= lastart)
	    reread = TRUE;
	return AS_NORM;
#ifdef ROTATION
    case 'X':
	rotate = !rotate;
	/* FALL THROUGH */
#else
    case Ctl('x'):
    case 'x':
    case 'X':
	notincl("x");
	return AS_ASK;
#endif
    case 'l': case Ctl('l'):		/* refresh screen */
	if (art <= lastart) {
	    reread = TRUE;
	    clear();
	    do_fseek = TRUE;
	    artline = topline;
	    if (artline < 0)
		artline = 0;
	}
	return AS_NORM;
    case 'b': case Ctl('b'):		/* back up a page */
	if (art <= lastart) {
	    ART_LINE target;

	    reread = TRUE;
	    clear();
	    do_fseek = TRUE;
	    target = topline - (LINES - 2);
	    artline = topline;
	    do {
		artline--;
	    } while (artline >= 0 && artline > target &&
		vrdary(artline-1) >= 0);
	    topline = artline;
	    if (artline < 0)
		artline = 0;
	}
	return AS_NORM;
    case '!':			/* shell escape */
	if (escapade())
	    return AS_INP;
	return AS_ASK;
    case 'C': {
	cancel_article();
	return AS_ASK;
    }
    case 'R':
    case 'r': {			/* reply? */
	reply();
	return AS_ASK;
    }
    case 'F':
    case 'f': {			/* followup command */
	followup();
	forcegrow = TRUE;		/* recalculate lastart */
	return AS_ASK;
    }
    case '|':
    case 'w': case 'W':
    case 's': case 'S':		/* save command */
	if (save_article() == SAVE_ABORT)
	    return AS_INP;
	return AS_ASK;
#ifdef DELAYMARK
    case 'Y':				/* yank back M articles */
	yankback();
	art = firstart;			/* from the beginning */
	return AS_NORM;			/* pretend nothing happened */
#endif
    case '\n':
	fputs(badcr,stdout);
	return AS_ASK;
    default:
	printf("\n%s",hforhelp);
	return AS_ASK;
    }
}

#ifdef MAILCALL
/* see if there is any mail */

void
setmail()
{
    if (! (mailcount++)) {
	char *mailfile = filexp(getval("MAILFILE",MAILFILE));
	
	if (stat(mailfile,&filestat) < 0 || !filestat.st_size)
	    mailcall = nullstr;
	else
	    mailcall = "(Mail) ";
    }
    mailcount %= 10;			/* check every 10 articles */
}
#endif

void
setdfltcmd()
{
    if (toread[ng]) {
#ifdef ARTSEARCH
	if (srchahead)
	    dfltcmd = "^Nnpq";
	else
#endif
	    dfltcmd = "npq";
    }
    else {
	if (art > lastart)
	    dfltcmd = "qnp";
	else
	    dfltcmd = "npq";
    }
}

!STUFFY!FUNK!
echo Extracting inews.c.1.pat
cat >inews.c.1.pat <<'!STUFFY!FUNK!'
*** inews.c.old	Tue Sep  4 16:42:01 1984
--- inews.c	Tue Sep  4 16:38:10 1984
***************
*** 515,520
  	}
  	for (;;) {
  		sprintf(bfr, "%s/%ld", dirname(ngname), ngsize+1);
  		if (link(ARTICLE, bfr) == 0) break;
  		e = errno;	/* keep log from clobbering it */
  		fprintf(stderr, "Cannot install article as %s\n", bfr);

--- 515,525 -----
  	}
  	for (;;) {
  		sprintf(bfr, "%s/%ld", dirname(ngname), ngsize+1);
+ #ifdef LINKART
+ 		if (mylink(ARTICLE, bfr) == 0) break;
+ 				/* on first file inits ARTICLE, on subsequent */
+ 				/* files "links" to first article */
+ #else
  		if (link(ARTICLE, bfr) == 0) break;
  #endif
  		e = errno;	/* keep log from clobbering it */
***************
*** 516,521
  	for (;;) {
  		sprintf(bfr, "%s/%ld", dirname(ngname), ngsize+1);
  		if (link(ARTICLE, bfr) == 0) break;
  		e = errno;	/* keep log from clobbering it */
  		fprintf(stderr, "Cannot install article as %s\n", bfr);
  		log("Cannot install article as %s", bfr);

--- 521,527 -----
  				/* files "links" to first article */
  #else
  		if (link(ARTICLE, bfr) == 0) break;
+ #endif
  		e = errno;	/* keep log from clobbering it */
  		fprintf(stderr, "Cannot install article as %s\n", bfr);
  		log("Cannot install article as %s", bfr);
***************
*** 542,547
  		strcpy(firstbufname, bfr);
  	sprintf(bfr, "%s/%ld ", ngname, ngsize+1);
  	addhist(bfr);
  	return TRUE;
  }
  

--- 548,554 -----
  		strcpy(firstbufname, bfr);
  	sprintf(bfr, "%s/%ld ", ngname, ngsize+1);
  	addhist(bfr);
+ #ifndef DOXREFS
  	return TRUE;
  #else DOXREFS
  	return ngsize+1;
***************
*** 543,548
  	sprintf(bfr, "%s/%ld ", ngname, ngsize+1);
  	addhist(bfr);
  	return TRUE;
  }
  
  /*

--- 550,558 -----
  	addhist(bfr);
  #ifndef DOXREFS
  	return TRUE;
+ #else DOXREFS
+ 	return ngsize+1;
+ #endif DOXREFS
  }
  
  /*
***************
*** 553,558
  	register char *ptr;
  	register FILE *tfp;
  	int badgroup = 0, goodgroup = 0;
  
  	/* Fill up the rest of header. */
  	if (mode != PROC) {

--- 563,572 -----
  	register char *ptr;
  	register FILE *tfp;
  	int badgroup = 0, goodgroup = 0;
+ #ifdef DOXREFS
+ 	register char *porig;
+ 	register char *nextxref = header.xref; 
+ #endif DOXREFS
  
  	/* Fill up the rest of header. */
  	if (mode != PROC) {
***************
*** 565,570
  	if (mode==PROC)
  		log("from %s relay %s", header.from, header.relayversion);
  
  	/* Write article to temp file. */
  	tfp = xfopen(mktemp(ARTICLE), "w");
  	lhwrite(&header, tfp);

--- 579,591 -----
  	if (mode==PROC)
  		log("from %s relay %s", header.from, header.relayversion);
  
+ #ifdef LINKART
+ 	*ARTICLE = '\0';	/* tell mylink() to snarf the name */
+ #else !LINKART
+ #ifdef DOXREFS
+ 	/* Open temp file for article, but link before writing */
+ 	tfp = xfopen(mktemp(ARTICLE), "w");
+ #else DOXREFS
  	/* Write article to temp file. */
  	tfp = xfopen(mktemp(ARTICLE), "w");
  	lhwrite(&header, tfp);
***************
*** 577,582
  	}
  	fclose(tfp);
  	fclose(infp);
  
  	if (is_ctl) {
  		control(&header);

--- 598,605 -----
  	}
  	fclose(tfp);
  	fclose(infp);
+ #endif DOXREFS
+ #endif LINKART
  
  	if (is_ctl) {
  		control(&header);
***************
*** 593,598
  			}
  		}
  	} else {
  		for (ptr = nbuf; *ptr;) {
  			if (*ptr == '-') {
  				while (*ptr++)

--- 616,622 -----
  			}
  		}
  	} else {
+ #ifndef DOXREFS
  		for (ptr = nbuf; *ptr;) {
  #else
  		sprintf(nextxref,"%s ",SYSNAME);
***************
*** 594,599
  		}
  	} else {
  		for (ptr = nbuf; *ptr;) {
  			if (*ptr == '-') {
  				while (*ptr++)
  					;

--- 618,642 -----
  	} else {
  #ifndef DOXREFS
  		for (ptr = nbuf; *ptr;) {
+ #else
+ 		sprintf(nextxref,"%s ",SYSNAME);
+ 		nextxref += strlen(nextxref);
+ 		for (ptr = nbuf, porig=header.nbuf;;) {
+ 			int namlen=strlen(ptr);
+ 
+ 			while (*porig && (strncmp(porig,ptr,namlen) ||
+ 				porig[namlen] != NGDELIM)) {
+ 				strcpy(nextxref,"0 ");
+ 				nextxref += 2;
+ 				while (*porig && *porig++ != NGDELIM)
+ 					;
+ 					/* skip unmatched newsgroup */
+ 			}
+ 			if (!*ptr)
+ 				break;
+ 			while (*porig && *porig++ != NGDELIM)
+ 				;	/* skip matching newsgroup */
+ #endif
  			if (*ptr == '-') {
  				while (*ptr++)
  					;
***************
*** 597,602
  			if (*ptr == '-') {
  				while (*ptr++)
  					;
  				continue;
  			}
  			strcpy(bfr, dirname(ptr));

--- 640,649 -----
  			if (*ptr == '-') {
  				while (*ptr++)
  					;
+ #ifdef DOXREFS
+ 				strcpy(nextxref,"0 ");
+ 				nextxref += 2;
+ #endif
  				continue;
  			}
  			strcpy(bfr, dirname(ptr));
***************
*** 610,615
  			}
  			else
  				goodgroup++;
  			if (*nbuf)
  				localize(ptr);
  			while (*ptr++)

--- 657,663 -----
  			}
  			else
  				goodgroup++;
+ #ifndef DOXREFS
  			if (*nbuf)
  				localize(ptr);
  #else DOXREFS
***************
*** 612,617
  				goodgroup++;
  			if (*nbuf)
  				localize(ptr);
  			while (*ptr++)
  				;
  		}

--- 660,673 -----
  #ifndef DOXREFS
  			if (*nbuf)
  				localize(ptr);
+ #else DOXREFS
+ 			if (*nbuf)
+ 				sprintf(nextxref,"%d ",localize(ptr));
+ 			else
+ 				strcat(nextxref,"0 ");
+ 			while (*nextxref)
+ 				nextxref++;
+ #endif DOXREFS
  			while (*ptr++)
  				;
  		}
***************
*** 616,621
  				;
  		}
  	}
  
  #ifdef NOFORWARD
  	if (*nbuf)

--- 672,683 -----
  				;
  		}
  	}
+ #ifdef DOXREFS
+ 	if (goodgroup < 2 || badgroup)
+ 	    header.xref[0] = '\0';
+ 	else
+ 	    *(nextxref-1) = '\0';
+ #endif
  
  #ifdef LINKART
  	tfp = xfopen(ARTICLE,"w");	/* open 1st article localized */
***************
*** 617,622
  		}
  	}
  
  #ifdef NOFORWARD
  	if (*nbuf)
  #endif

--- 679,703 -----
  	    *(nextxref-1) = '\0';
  #endif
  
+ #ifdef LINKART
+ 	tfp = xfopen(ARTICLE,"w");	/* open 1st article localized */
+ #endif
+ 
+ #if defined(LINKART) || defined(DOXREFS)
+ 	/* Now that xref is constructed, write article to temp file. */
+ 	/* (We ought to detect no room at this point and clean up.) */ 
+ 	lhwrite(&header, tfp);
+ 	while (fgets(bfr, BUFLEN, infp) != NULL) {
+ 		/*
+ 		if (!strncmp(bfr, "From ", 5))
+ 			putc('>', tfp);
+ 		*/
+ 		fputs(bfr, tfp);
+ 	}
+ 	fclose(tfp);
+ 	fclose(infp);
+ #endif LINKART || DOXREFS
+ 
  #ifdef NOFORWARD
  	if (*nbuf)
  #endif
***************
*** 861,863
  		mclose(fd);
  	}
  }

--- 942,966 -----
  		mclose(fd);
  	}
  }
+ 
+ #ifdef LINKART
+ mylink(tmpart,linkfrom)
+ char *tmpart, *linkfrom;
+ {
+     struct stat statbuf;
+ 
+     if (stat(linkfrom,&statbuf)==0)
+ 	return -1;
+     if (!*tmpart)
+ 	strcpy(tmpart,linkfrom);
+     else {
+ 	FILE *linkfp = fopen(linkfrom,"w");
+ 
+ 	if (!linkfp)
+ 	    return -1;
+ 	fprintf(linkfp,"%s\n",tmpart);
+ 	fclose(linkfp);
+     }
+     return 0;
+ }
+ #endif LINKART
!STUFFY!FUNK!
echo Extracting only.h
cat >only.h <<'!STUFFY!FUNK!'
/* $Header: only.h,v 4.1 84/09/24 12:04:15 lwall Exp $
 *
 * $Log:	only.h,v $
 * Revision 4.1  84/09/24  12:04:15  lwall
 * Real baseline.
 * 
 * Revision 4.0.1.1  84/09/10  15:22:47  lwall
 * Delinted.
 * 
 * Revision 4.0  84/09/04  09:51:58  lwall
 * Baseline for netwide release
 * 
 */

#ifndef NBRA
#include "search.h"
#endif

#ifdef ONLY
    char *ngtodo[NGMAX];		/* restrictions in effect */
#   ifdef SPEEDOVERMEM
	COMPEX *compextodo[NGMAX];	/* restrictions in compiled form */
#   endif
#endif

int maxngtodo INIT(0);			/*  0 => no restrictions */
					/* >0 => # of entries in ngtodo */

void	only_init();
bool	inlist();	/* return TRUE if ngname is in command line list */
			/* or if there was no list */
void	setngtodo();
#ifdef ONLY
    void	end_only();
#endif
!STUFFY!FUNK!
echo ""
echo "End of kit 2 (of 8)"
cat /dev/null >kit2isdone
config=true
for iskit in 1 2 3 4 5 6 7 8; 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