Subject:  v25i005:  trn 2.0 - threaded newsreader based on rn 4.4, Part02/13
Newsgroups: comp.sources.unix
Approved: vixie@pa.dec.com

Submitted-by: davison@borland.com (Wayne Davison)
Posting-number: Volume 25, Issue 5
Archive-name: trn/part02

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 13)."
# Contents:  HACKERSGUIDE HINTS Pnews.1 Rnmail.1 artio.c backpage.c
#   bits.h cheat.c getactive.c head.h last.c makedepend.SH mt-misc.c
#   ndir.c ndir.h.SH newsetup.1 newsetup.SH newsgroups.1 newsgroups.SH
#   newsnews.SH ngsrch.c only.c rcstuff.h threads.c
# Wrapped by vixie@cognition.pa.dec.com on Tue Dec  3 16:34:51 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'HACKERSGUIDE' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'HACKERSGUIDE'\"
else
echo shar: Extracting \"'HACKERSGUIDE'\" \(4519 characters\)
sed "s/^X//" >'HACKERSGUIDE' <<'END_OF_FILE'
Hacking Notes
X
If you aren't interested in mucking with the innards of rn, don't read this.
X
In the interests of both space and time optimization, things are done inside
rn that don't always conform to the highest ideals of programming.  To the
extent I felt it was practical, I've tried to conform to good programming
practice, but you must realize that my goal was to make a better mousetrap,
so certain conscious tradeoffs were made in the design of rn right from the
start.  In particular, if you want to hack on rn (and I wouldn't blame you,
it's fun), beware of the following:
X  
X  * buf and cmd_buf are reused all over the place.  11-squishing is a good
X    term for it.  No, I'm on a Vax now, but I've been there.
X
X  * The article header is parsed on the fly, while it is being displayed.
X    In fact, practically everything is done on the fly within the article
X    display loop, and there are plenty of state variables.  The header
X    is never explicitly stored in memory; rather, pointers are kept into
X    the file.  The information required to backup pages is not stored in
X    memory, except for 1 buffer's worth.  The information required to do
X    the delayed mark as unread (M) is not stored in memory either.
X
X  * Lots of contortions are gone through to avoid using static memory, or
X    allocating unnecessary memory, or losing track of allocated memory,
X    while at the same time allowing .newsrc lines and header lines to be
X    ANY length up to the amount of memory you have.  Rn spends a great deal
X    of effort being lazy.  Do not use a static buffer when you can use
X    growstr(). 
X
X  * Lots of contortions are gone through to try to do things when people
X    aren't waiting, or have only been waiting a very short time.  Guessing
X    the next article to be opened and opening it, searching ahead for the
X    next article with the same subject, delaying the look up of the number
X    of articles in a newsgroup, writing the rest of the page while the
X    reader is examining the header, cacheing up subjects while the user
X    is reading, checkpointing the .newsrc only while the reader is in the
X    middle of an interesting article, are some of the strategies employed.
X  
X  * There are plenty of goto's.  Most of them involve going back to reprompt,
X    to reask for input, or to just plain do the unstructured things people
X    want to do when they are glaring at a terminal.  If they bother you
X    too much, just think of rn as a big state machine.  If they don't bother
X    you at all, I don't want you hacking on rn.
X
X  * Put all includes at the front of the file, before the first function,
X    or makedepend will not work right.  I could relax this, but makedepend
X    would take about 5 times longer to run.
X
In general then, feel free to hack on rn.  Just don't broadcast untested
patches to the net.  Remember that there are people with limited address
spaces and limited cpu cycles.  If you add a wonderful new feature and
want to publish a patch, put #ifdef's around it so that people who don't
want it or can't afford it can work around it.  THIS MEANS YOU.  We don't
need 57 varieties of mutually incompatible and incomprehensible rn floating
about the net.  Consider telling me about your patch so that I can consider
including it in the standard version.  A COMPLETE PATCH TAKES INTO ACCOUNT
SYSTEM DEPENDENCIES AS DETERMINED BY THE CONFIGURE SCRIPT.
X
X* Don't use ints where rn uses typedefs, in particular, for article numbers.
X* Don't use %d anywhere that someone might need a %ld.  (Just because YOU
X    typedefed it as an int doesn't mean someone else won't need a long.)
X* Don't use %D, that's archaic.
X* Put FLUSHes after printf()s, fputs()es and putchar('\n')s for our poor
X    brethern and sistern without line buffering.
X* Declare the type of every function.  Use void, even if your C compiler
X    doesn't.
X* Follow the style that rn already uses!  This is my pet peeve.  Well, one of
X    them, anyway.  I follow other people's strange styles when modifying
X    their programs, so I'd be much obliged if you did likewise.
X* Use lint.
X* Use RCS.  Start a new branch, like 4.4.[2-9].  (I will use 4.4.1 myself.)
X* Be structured wherever it doesn't interfere with practicality.
X* Long live paranoid programming.  The rest of the program is out to get you.
X    The world is out to destroy the program, not to mention the .newsrc.
X    And then there's always bitrot...
X* Stop reading this lugubrious trash and start thinking for yourself.
X* Thank you and good night.
END_OF_FILE
if test 4519 -ne `wc -c <'HACKERSGUIDE'`; then
    echo shar: \"'HACKERSGUIDE'\" unpacked with wrong size!
fi
# end of 'HACKERSGUIDE'
fi
if test -f 'HINTS' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'HINTS'\"
else
echo shar: Extracting \"'HINTS'\" \(2647 characters\)
sed "s/^X//" >'HINTS' <<'END_OF_FILE'
Here's some helpful hints for getting the most out of trn:
X
The 'X' command in the thread selector (kinda like catchup/yes) can be made
the default action on the last page of selections by using the command-line
option:  -XX.  This lets you browse all the pages, making selections as you
go, and then mark everything that was not selected as read when you press
space at the last page.
X----------
If you like to select a little, read a little, and then select a little more,
try using the command-line option:  -XDD.  This makes the 'D' command the
default on all pages of the thread selector.  Thus you can select the things
you want to read on the current page, press space, and you will read the
selected articles immediately (if there were any).  All other articles on the
current page will be marked as read.  (Don't use -XXD, because new articles
might have arrived while reading, and they could be marked as read without
ever seeing them.)
X----------
I like to use the -xls command-line option to only have the long and short
modes in the thread selector (leaving out the mid-sized one).  Press 'L' to
switch modes.
X----------
Keep in mind that you can create a file called .trninit and point trn at
it by definining the environment variable TRNINIT.  Depending on your shell,
you might use "setenv TRNINIT ~/.trninit" or some other type of assignment
X(put the definition in your shell's rc file).  Then put all your command-line
options in this file.
X----------
I like to redefine the 'u' keys in the following way:  'u' visits the "Set
unread?" prompt (except at the thread selector), 'U' goes directly to the
already-read article selector, and Ctrl-U unsubscribes from the group (even
while in the thread selector).  Put the following 3 macros in your .trninit
file to accomplish this:
X
u	%(%m=[anp]?U:u)
U	%(%m=[anp]?U+:U)
X^U	%(%m=t?+u:u)
X----------
If you like the way that 'q' worked in the thread selector in trn 1.x, put
the following macro in your .trninit file:
X
q	%(%m=t?+:q)
X----------
If you want to be able to save your shar headers in a file as they are
extracted and you have access to "unshar" (a program that can extract
shar files while saving the headers in UNSHAR.HDR), twiddle the external
extract command to send the entire article:
X
X        (regular)                          (nntp)
X-EEXSAVER="%e <%A"               -EEXSAVER "%e <%P/rrn%a.%$"
X
and then point the UNSHAR variable at unshar instead of /bin/sh:
X
X-EUNSHAR="unshar -s"
X
Note that this assumes that any other commands you execute with "e dir|command"
can also handle the entire article as input (uuencoded and shipped files are
not affected).
X----------
END_OF_FILE
if test 2647 -ne `wc -c <'HINTS'`; then
    echo shar: \"'HINTS'\" unpacked with wrong size!
fi
# end of 'HINTS'
fi
if test -f 'Pnews.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Pnews.1'\"
else
echo shar: Extracting \"'Pnews.1'\" \(3869 characters\)
sed "s/^X//" >'Pnews.1' <<'END_OF_FILE'
X.\" $Id: Pnews.1,v 4.4.1.1 1991/09/25 19:36:48 sob Exp sob $
X.\" 
X.\" $Log: Pnews.1,v $
X.\" Revision 4.4.1.1  1991/09/25  19:36:48  sob
X.\" Changed quote macro to "standard" one
X.\"
X.\" Revision 4.4  1991/09/09  20:18:23  sob
X.\" release 4.4
X.\"
X.\" 
X.\" This software is Copyright 1991 by Stan Barber. 
X.\"
X.\" Permission is hereby granted to copy, reproduce, redistribute or otherwise
X.\" use this software as long as: there is no monetary profit gained
X.\" specifically from the use or reproduction of this software, it is not
X.\" sold, rented, traded or otherwise marketed, and this copyright notice is
X.\" included prominently in any copy made. 
X.\"
X.\" The author make no claims as to the fitness or correctness of this software
X.\" for any use whatsoever, and it is provided as is. Any use of this software
X.\" is at the user's own risk. 
X.\"
X.de Sh
X.br
X.ne 5
X.PP
X\fB\\$1\fR
X.PP
X..
X.de Sp
X.if t .sp .5v
X.if n .sp
X..
X.\"
X.\"     Set up \*(-- to give an unbreakable dash;
X.\"     string Tr holds user defined translation string.
X.\"     Bell System Logo is used as a dummy character.
X.\"
X.ie n \{\
X.tr \(bs-\*(Tr
X.ds -- \(bs-
X.if (\n(.H=4u)&(1m=24u) .ds -- \(bs\h'-12u'\(bs\h'-12u'-\" diablo 10 pitch
X.if (\n(.H=4u)&(1m=20u) .ds -- \(bs\h'-12u'\(bs\h'-8u'-\" diablo 12 pitch
X.ds L" ""
X.ds R" ""
X.ds L' '
X.ds R' '
X'br\}
X.el\{\
X.ds -- \(em\|
X.tr \*(Tr
X.ds L" ``
X.ds R" ''
X.ds L' `
X.ds R' '
X'br\}
X.TH PNEWS 1 LOCAL
X.SH NAME
Pnews - a program for posting news articles
X.SH SYNOPSIS
X.B Pnews newsgroup title
X.br
X  or
X.br
X.B Pnews -h headerfile [oldarticle]
X.br
X  or
X.br
X.B Pnews
X.SH DESCRIPTION
Pnews is a friendly interface for posting news articles.
It will ask several questions, then allow you to enter your article,
and then post it using the inews(1) program.
If you type h and a carriage return at any point,
X.I Pnews
will tell you what it wants to know.
X.PP
The -h form is used when invoked from
X.IR rn .
If your editor can edit multiple files, and you want the article to which
you are replying to show up as an alternate file, define the environment
variable NEWSPOSTER as \*(L"Pnews -h %h %A\*(R".
You can also modify the the NEWSHEADER environment variable to change the
header file that
X.I rn
passes to Pnews.
X.SH ENVIRONMENT
X.IP AUTHORCOPY 8
If defined, contains the name of a file to which the finished article will
be appended.
X.Sp
Default: article not saved
X.IP DOTDIR 8
Where to find your dot files, if they aren't in your home directory.
This is primarily for accounts which are shared by more than one person.
X.Sp
Default: $HOME
X.IP EDITOR 8
The editor you want to use, if VISUAL is undefined.
X.Sp
Default: whatever your news administrator installed, usually vi.
X.IP HOME 8
Your home directory.
X.Sp
Default: $LOGDIR
X.IP LOGDIR 8
Your home directory if HOME is undefined.
X.IP LOGNAME 8
Your login name, if USER is undefined.
X.Sp
Default: value of \*(L"whoami\*(R".
X.IP NAME 8
Your full name.
X.Sp
Default: name from /etc/passwd, or ~/.fullname.
X.IP NEWSORG 8
XEither the name of your organization, or the name of a file containing the
name of your organization. (For use at organizations where the ORGANIZATION
environmental variable is in use for other purposes). If both NEWSORG and
ORGANIZATION are set, NEWSORG will override ORGANIZATION.
X.IP ORGANIZATION 8
XEither the name of your organization, or the name of a file containing the
name of your organization.
X.Sp
Default: whatever your news administrator chose.
X.IP REPLYTO 8
The contents of a \*(L"Reply-To:\*(R" header line to insert into your message.
X.Sp
Default: header line not inserted.
X.IP USER 8
Your login name.
X.Sp
Default: $LOGNAME
X.IP VISUAL 8
The editor you want to use.
X.Sp
Default: $EDITOR
X.SH FILES
X$DOTDIR/.article
X.br
X~/dead.article
X.SH SEE ALSO
rn(1), Rnmail(1), inews(1)
X.SH DIAGNOSTICS
X.SH BUGS
Not the speediest program in the world, but maybe that's a blessing to the
net.
END_OF_FILE
if test 3869 -ne `wc -c <'Pnews.1'`; then
    echo shar: \"'Pnews.1'\" unpacked with wrong size!
fi
# end of 'Pnews.1'
fi
if test -f 'Rnmail.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Rnmail.1'\"
else
echo shar: Extracting \"'Rnmail.1'\" \(3823 characters\)
sed "s/^X//" >'Rnmail.1' <<'END_OF_FILE'
X.\" $Id: Rnmail.1,v 4.4.1.1 1991/09/25 19:36:48 sob Exp sob $
X.\" 
X.\" $Log: Rnmail.1,v $
X.\" Revision 4.4.1.1  1991/09/25  19:36:48  sob
X.\" Changed quote macro to "standard" one
X.\"
X.\" Revision 4.4  1991/09/09  20:18:23  sob
X.\" release 4.4
X.\"
X.\" 
X.\" This software is Copyright 1991 by Stan Barber. 
X.\"
X.\" Permission is hereby granted to copy, reproduce, redistribute or otherwise
X.\" use this software as long as: there is no monetary profit gained
X.\" specifically from the use or reproduction of this software, it is not
X.\" sold, rented, traded or otherwise marketed, and this copyright notice is
X.\" included prominently in any copy made. 
X.\"
X.\" The author make no claims as to the fitness or correctness of this software
X.\" for any use whatsoever, and it is provided as is. Any use of this software
X.\" is at the user's own risk. 
X.\"
X.de Sh
X.br
X.ne 5
X.PP
X\fB\\$1\fR
X.PP
X..
X.de Sp
X.if t .sp .5v
X.if n .sp
X..
X.\"
X.\"     Set up \*(-- to give an unbreakable dash;
X.\"     string Tr holds user defined translation string.
X.\"     Bell System Logo is used as a dummy character.
X.\"
X.ie n \{\
X.tr \(bs-\*(Tr
X.ds -- \(bs-
X.if (\n(.H=4u)&(1m=24u) .ds -- \(bs\h'-12u'\(bs\h'-12u'-\" diablo 10 pitch
X.if (\n(.H=4u)&(1m=20u) .ds -- \(bs\h'-12u'\(bs\h'-8u'-\" diablo 12 pitch
X.ds L" ""
X.ds R" ""
X.ds L' '
X.ds R' '
X'br\}
X.el\{\
X.ds -- \(em\|
X.tr \*(Tr
X.ds L" ``
X.ds R" ''
X.ds L' `
X.ds R' '
X'br\}
X.TH RNMAIL 1 LOCAL
X.SH NAME
Rnmail - a program for replying via mail
X.SH SYNOPSIS
X.B Rnmail destination_list
X.br
X  or
X.br
X.B Rnmail -h headerfile [oldarticle]
X.br
X  or
X.br
X.B Rnmail
X.SH DESCRIPTION
Rnmail is a friendly interface for mailing replies to news articles.
It will ask several questions, then allow you to enter your letter,
and then mail it off.
If you type h and a carriage return at any point,
X.I Rnmail
will tell you what it wants to know.
X.PP
The -h form is used when invoked from
X.IR rn .
If your editor can edit multiple files, and you want the article to which
you are replying to show up as an alternate file, define the environment
variable MAILPOSTER as \*(L"Rnmail -h %h %A\*(R".
You can also modify the the MAILHEADER environment variable to change the
header file that
X.I rn
passes to Rnmail.
X.SH ENVIRONMENT
X.IP DOTDIR 8
If defined, specifies a place other than your home directory where 'dot' files
may be stored.
This is primarily for accounts which are shared by more than one person.
X.Sp
Default: $HOME
X.IP EDITOR 8
The editor you want to use, if VISUAL is undefined.
X.Sp
Default: whatever your news administrator installed, usually vi.
X.IP HOME 8
Your home directory.
X.Sp
Default: $LOGDIR
X.IP LOGDIR 8
Your home directory if HOME is undefined.
X.IP LOGNAME 8
Your login name, if USER is undefined.
X.Sp
Default: value of \*(L"whoami\*(R".
X.IP MAILRECORD 8
If defined, contains the name of a file to which the finished message will
be appended.
X.Sp
Default: message not saved
X.IP NEWSORG 8
XEither the name of your organization, or the name of a file containing the
name of your organization. (For use at organizations where the ORGANIZATION
environmental variable is in use for other purposes). If both NEWSORG and 
ORGANIZATION are set, NEWSORG will override ORGANIZATION.
X.Sp
Default: whatever your news administrator chose.
X.IP ORGANIZATION 8
XEither the name of your organization, or the name of a file containing the
name of your organization.
X.Sp
Default: whatever your news administrator chose.
X.IP REPLYTO 8
The contents of a \*(L"Reply-To:\*(R" header line to insert into your message.
X.Sp
Default: header line not inserted.
X.IP USER 8
Your login name.
X.Sp
Default: $LOGNAME
X.IP VISUAL 8
The editor you want to use.
X.Sp
Default: $EDITOR
X.SH FILES
X$DOTDIR/.letter
X.br
X~/dead.letter
X.SH SEE ALSO
rn(1), Pnews(1), mail(1)
X.SH DIAGNOSTICS
X.SH BUGS
Uses /bin/mail in the absence of sendmail.
END_OF_FILE
if test 3823 -ne `wc -c <'Rnmail.1'`; then
    echo shar: \"'Rnmail.1'\" unpacked with wrong size!
fi
# end of 'Rnmail.1'
fi
if test -f 'artio.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'artio.c'\"
else
echo shar: Extracting \"'artio.c'\" \(5092 characters\)
sed "s/^X//" >'artio.c' <<'END_OF_FILE'
X/* $Id: artio.c,v 4.4 1991/09/09 20:18:23 sob Exp sob $
X *
X * $Log: artio.c,v $
X * Revision 4.4  1991/09/09  20:18:23  sob
X * release 4.4
X *
X *
X * 
X */
X/* This software is Copyright 1991 by Stan Barber. 
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made. 
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk. 
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#ifdef SERVER
X#include "server.h"
X#endif
X#include "INTERN.h"
X#include "artio.h"
X
void
artio_init()
X{
X    ;
X}
X
X/* open an article, unless it's already open */
X
XFILE *
artopen(artnum)
ART_NUM artnum;
X{
X#ifdef SERVER
X    return nntpopen(artnum,GET_ARTICLE);
X#else
X    char artname[MAXFILENAME];		/* filename of current article */
X
X    if (artnum < 1)
X	return Nullfp;
X    if (openart == artnum) {		/* this article is already open? */
X	fseek(artfp,0L,0);		/* just get to the beginning */
X	return artfp;			/* and say we succeeded */
X    }
X    if (artfp != Nullfp) {		/* it was somebody else? */
X	fclose(artfp);			/* put them out of their misery */
X	openart = 0;			/* and remember them no more */
X    }
X    sprintf(artname,"%ld",(long)artnum);
X					/* produce the name of the article */
X    if (artfp = fopen(artname,"r"))	/* if we can open it */
X	openart = artnum;		/* remember what we did here */
X#ifdef LINKART
X    {
X	char tmpbuf[256];
X	char *s;
X
X	if (fstat(fileno(artfp),&filestat))
X	    return artfp;
X	if (filestat.st_size < (sizeof tmpbuf)) {
X	    fgets(tmpbuf,(sizeof tmpbuf),artfp);
X	    if (*tmpbuf == '/') {	/* is a "link" to another article */
X		fclose(artfp);
X		if (s=index(tmpbuf,'\n'))
X		    *s = '\0';
X		if (!(artfp = fopen(tmpbuf,"r")))
X		    openart = 0;
X		else {
X		    if (*linkartname)
X			free(linkartname);
X		    linkartname = savestr(tmpbuf);
X		}
X	    }
X	    else
X		fseek(artfp,0L,0);		/* get back to the beginning */
X	}
X    }
X#endif
X    return artfp;			/* and return either fp or NULL */
X#endif /* SERVER */
X}
X
X#ifdef SERVER
static long our_pid=0;
X
XFILE *
nntpopen(artnum,function)
ART_NUM artnum;
ART_PART function;
X{
X    char artname[MAXFILENAME];		/* filename of current article */
X    char intrpwork[MAXFILENAME];	/* filename of current article */
X    if (our_pid == 0)
X	our_pid = getpid();
X    if (artnum < 1)
X	return Nullfp;
X    if ((openart == artnum) && (openpart >= function))
X    {					/* this article is already open? */
X	fseek(artfp,0L,0);		/* just get to the beginning */
X	return artfp;			/* and say we succeeded */
X    }
X    if (artfp != Nullfp) {		/* it was somebody else? */
X	fclose(artfp);			/* put them out of their misery */
X	nntpclose();
X	openart = 0;			/* and remember them no more */
X    }
X    interp(intrpwork,MAXFILENAME-1,"%P");
X    sprintf(artname,"%s/rrn%ld.%ld", intrpwork,(long) artnum, our_pid);
X    artfp = fopen(artname, "w+");	/* create the temporary article */
X    if (artfp == Nullfp) {
X	UNLINK(artname);
X	return Nullfp;
X    }
X    switch (function){
X	    case GET_STATUS:
X		function = GET_HEADER;	/* fall through */
X	    case GET_HEADER:
X		sprintf(ser_line, "HEAD %ld", (long)artnum);
X		break;
X	    case GET_ARTICLE:
X		sprintf(ser_line, "ARTICLE %ld", (long)artnum);
X		break;
X    }	    
X#ifdef DEBUGGING
X    if (debug & DEB_NNTP)
X	printf(">%s\n", ser_line) FLUSH;
X#endif
X    put_server(ser_line);		/* ask the server for the article */
X    if (nntp_get(ser_line, sizeof(ser_line)) < 0) {
X	fprintf(stderr, "\nrrn: Unexpected close of server socket.\n");
X	finalize(1);
X    }
X#ifdef DEBUGGING
X    if (debug & DEB_NNTP)
X	printf("<%s\n", ser_line) FLUSH;
X#endif
X    if (*ser_line == CHAR_FATAL) {	/* Fatal error */
X		fprintf(stderr,"\nrrn: %s\n",ser_line);
X		finalize(1);
X	}
X    if (*ser_line != CHAR_OK) {		/* and get it's reaction */
X	fclose(artfp);
X	artfp = Nullfp;
X	UNLINK(artname);
X 	errno = ENOENT;		/* Simulate file-not-found */
X        return Nullfp;
X    }
X
X    for (;;) {
X        if (nntp_get(ser_line, sizeof(ser_line)) < 0) {
X	    fprintf(stderr, "\nrrn: Unexpected close of server socket.\n");
X	    finalize(1);
X	}
X	if (ser_line[0] == '.' && ser_line[1] == '\0')
X		break;
X	fputs((ser_line[0] == '.' ? ser_line + 1 : ser_line), artfp);
X	putc('\n', artfp);
X    }
X    openpart = function;
X    if (function == GET_HEADER)
X	 putc('\n', artfp); /* req'd blank line after header */
X    fseek(artfp, 0L, 0);		/* Then get back to the start */
X    openart = artnum;
X    return artfp;			/* and return either fp or NULL */
X}
X
void
nntpclose()
X{
X    char artname[MAXFILENAME];		/* filename of current article */
X    char intrpwork[MAXFILENAME];	/* filename of current article */
X    if (our_pid == 0)
X	our_pid = getpid();
X    interp(intrpwork,MAXFILENAME-1,"%P");
X    sprintf(artname, "%s/rrn%ld.%ld", intrpwork,(long) openart, our_pid);
X    UNLINK(artname);
X}
X#endif
END_OF_FILE
if test 5092 -ne `wc -c <'artio.c'`; then
    echo shar: \"'artio.c'\" unpacked with wrong size!
fi
# end of 'artio.c'
fi
if test -f 'backpage.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'backpage.c'\"
else
echo shar: Extracting \"'backpage.c'\" \(2658 characters\)
sed "s/^X//" >'backpage.c' <<'END_OF_FILE'
X/* $Id: backpage.c,v 4.4 1991/09/09 20:18:23 sob Exp sob $
X *
X * $Log: backpage.c,v $
X * Revision 4.4  1991/09/09  20:18:23  sob
X * release 4.4
X *
X *
X * 
X */
X/* This software is Copyright 1991 by Stan Barber. 
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made. 
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk. 
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "intrp.h"
X#include "final.h"
X#include "INTERN.h"
X#include "backpage.h"
X
ART_LINE maxindx = -1;
long lseek();
X
void
backpage_init()
X{
X    char *varyname;
X    
X    varyname = filexp(VARYNAME);
X    close(creat(varyname,0600));
X    varyfd = open(varyname,2);
X    UNLINK(varyname);
X    if (varyfd < 0) {
X	printf(cantopen,varyname) FLUSH;
X	sig_catcher(0);
X    }
X    
X}
X
X/* virtual array read */
X
ART_POS
vrdary(indx)
ART_LINE indx;
X{
X    int subindx;
X    long offset;
X
X#ifdef DEBUGGING
X    if (indx > maxindx) {
X	printf("vrdary(%ld) > %ld\n",(long)indx, (long)maxindx) FLUSH;
X	return 0;
X    }
X#endif
X    if (indx < 0)
X	return 0;
X    subindx = indx % VARYSIZE;
X    offset = (indx - subindx) * sizeof(varybuf[0]);
X    if (offset != oldoffset) {
X	if (oldoffset >= 0) {
X#ifndef lint
X	    (void)lseek(varyfd,oldoffset,0);
X	    write(varyfd, (char *)varybuf,sizeof(varybuf));
X#endif /* lint */
X	}
X#ifndef lint
X	(void)lseek(varyfd,offset,0);
X	read(varyfd,(char *)varybuf,sizeof(varybuf));
X#endif /* lint */
X	oldoffset = offset;
X    }
X    return varybuf[subindx];
X}
X
X/* write to virtual array */
X
void
vwtary(indx,newvalue)
ART_LINE indx;
ART_POS newvalue;
X{
X    int subindx;
X    long offset;
X
X#ifdef DEBUGGING
X    if (indx < 0)
X	printf("vwtary(%ld)\n",(long)indx) FLUSH;
X    if (!indx)
X	maxindx = 0;
X    if (indx > maxindx) {
X	if (indx != maxindx + 1)
X	    printf("indx skipped %d-%d\n",maxindx+1,indx-1) FLUSH;
X	maxindx = indx;
X    }
X#endif
X    subindx = indx % VARYSIZE;
X    offset = (indx - subindx) * sizeof(varybuf[0]);
X    if (offset != oldoffset) {
X	if (oldoffset >= 0) {
X#ifndef lint
X	    (void)lseek(varyfd,oldoffset,0);
X	    write(varyfd,(char *)varybuf,sizeof(varybuf));
X#endif /* lint */
X	}
X#ifndef lint
X	(void)lseek(varyfd,offset,0);
X	read(varyfd,(char *)varybuf,sizeof(varybuf));
X#endif /* lint */
X	oldoffset = offset;
X    }
X    varybuf[subindx] = newvalue;
X}
X
END_OF_FILE
if test 2658 -ne `wc -c <'backpage.c'`; then
    echo shar: \"'backpage.c'\" unpacked with wrong size!
fi
# end of 'backpage.c'
fi
if test -f 'bits.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bits.h'\"
else
echo shar: Extracting \"'bits.h'\" \(2599 characters\)
sed "s/^X//" >'bits.h' <<'END_OF_FILE'
X/* $Id: bits.h,v 4.4 1991/09/09 20:18:23 sob Exp sob $
X *
X * $Log: bits.h,v $
X * Revision 4.4  1991/09/09  20:18:23  sob
X * release 4.4
X *
X *
X * 
X */
X/* This software is Copyright 1991 by Stan Barber. 
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made. 
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk. 
X */
X
XEXT char *ctlarea INIT(Nullch);	/* one bit for each article in current newsgroup */
X			/* with the following interpretation: */
X			/*	0 => unread  */
X			/*	1 => read    */
X
X/* if subscripting is faster than shifting on your machine, define this */
X#undef USESUBSCRIPT
X#ifdef USESUBSCRIPT
XEXT char powerof2[] INIT({1,2,4,8,16,32,64,128});
X#define pow2(x) powerof2[x]
X#else
X#define pow2(x) (1 << (x))
X#endif
X
X#ifdef lint
XEXT bool nonesuch INIT(FALSE);
X#define ctl_set(a)
X#define ctl_clear(a)
X#define ctl_read(a) nonesuch
X#define was_read(a) nonesuch
X#else
X#define ctl_set(a) (ctlarea[(OFFSET(a)) / BITSPERBYTE] |= pow2((OFFSET(a)) % BITSPERBYTE))
X#define ctl_clear(a) (ctlarea[(OFFSET(a)) / BITSPERBYTE] &= ~pow2((OFFSET(a)) % BITSPERBYTE))
X#define ctl_read(a) ((ctlarea[(OFFSET(a)) / BITSPERBYTE] & pow2((OFFSET(a)) % BITSPERBYTE)) != 0)
X
X#define was_read(a) ((a)<firstbit || ctl_read(a))
X#endif /* lint */
X
XEXT ART_NUM absfirst INIT(0);	/* 1st real article in current newsgroup */
XEXT ART_NUM firstart INIT(0);	/* minimum unread article number in newsgroup */
XEXT ART_NUM firstbit INIT(0);	/* minimum valid bit, usually == firstart */
XEXT ART_NUM lastart INIT(0);	/* maximum article number in newsgroup */
X
X#ifdef DELAYMARK
XEXT FILE *dmfp INIT(Nullfp);
XEXT char *dmname INIT(Nullch);
XEXT int dmcount INIT(0);
X#endif
X
void	bits_init ANSI((void));
void	checkpoint_rc ANSI((void));
void	restore_ng ANSI((void));
void	onemore ANSI((ART_NUM));
void	oneless ANSI((ART_NUM));
void	unmark_as_read ANSI((void));
X#ifdef USETHREADS
void	set_read ANSI((ART_NUM,int,bool_int));
void	set_unread ANSI((ART_NUM,int));
X#endif
void	delay_unmark ANSI((ART_NUM));
void	mark_as_read ANSI((void));
void	check_first ANSI((ART_NUM));
X#ifdef DELAYMARK
X    void	yankback ANSI((void));
X#endif
int	chase_xrefs ANSI((ART_NUM,int));
int	initctl ANSI((void));
void	grow_ctl ANSI((ART_NUM));
END_OF_FILE
if test 2599 -ne `wc -c <'bits.h'`; then
    echo shar: \"'bits.h'\" unpacked with wrong size!
fi
# end of 'bits.h'
fi
if test -f 'cheat.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cheat.c'\"
else
echo shar: Extracting \"'cheat.c'\" \(3484 characters\)
sed "s/^X//" >'cheat.c' <<'END_OF_FILE'
X/* $Id: cheat.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
X *
X * $Log: cheat.c,v $
X * Revision 4.4.2.1  1991/12/01  18:05:42  sob
X * Patchlevel 2 changes
X *
X * Revision 4.4  1991/09/09  20:18:23  sob
X * release 4.4
X *
X *
X * 
X */
X/* This software is Copyright 1991 by Stan Barber. 
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made. 
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk. 
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "intrp.h"
X#include "search.h"
X#include "ng.h"
X#include "bits.h"
X#include "artio.h"
X#include "term.h"
X#include "artsrch.h"
X#include "head.h"
X#include "INTERN.h"
X#include "cheat.h"
X
X/* see what we can do while they are reading */
X
X#ifdef PENDING
X#   ifdef ARTSEARCH
X	COMPEX srchcompex;		/* compiled regex for searchahead */
X#   endif
X#endif
X
void
cheat_init()
X{
X    ;
X}
X
X#ifdef PENDING
void
look_ahead()
X{
X#ifdef ARTSEARCH
X    register char *h, *s;
X
X#ifdef DEBUGGING
X    if (debug && srchahead) {
X	printf("(%ld)",(long)srchahead);
X	fflush(stdout);
X    }
X#endif
X    if (srchahead && srchahead < art) {	/* in ^N mode? */
X	char *pattern;
X
X	pattern = buf+1;
X	strcpy(pattern,": *");
X	h = pattern + strlen(pattern);
X	interp(h,(sizeof buf) - (h-buf),"%\\s");
X	{			/* compensate for notesfiles */
X	    register int i;
X	    for (i = 24; *h && i--; h++)
X		if (*h == '\\')
X		    h++;
X	    *h = '\0';
X	}
X#ifdef DEBUGGING
X	if (debug & DEB_SEARCH_AHEAD) {
X	    fputs("(hit CR)",stdout);
X	    fflush(stdout);
X	    gets(buf+128);
X	    printf("\npattern = %s\n",pattern);
X	}
X#endif
X	if ((s = compile(&srchcompex,pattern,TRUE,TRUE)) != Nullch) {
X				    /* compile regular expression */
X	    printf("\n%s\n",s);
X	    srchahead = 0;
X	}
X	if (srchahead) {
X	    srchahead = art;
X	    for (;;) {
X		srchahead++;	/* go forward one article */
X		if (srchahead > lastart) { /* out of articles? */
X#ifdef DEBUGGING
X		    if (debug)
X			fputs("(not found)",stdout);
X#endif
X		    break;
X		}
X		if (!was_read(srchahead) &&
X		    wanted(&srchcompex,srchahead,0)) {
X				    /* does the shoe fit? */
X#ifdef DEBUGGING
X		    if (debug)
X			printf("(%ld)",(long)srchahead);
X#endif
X#ifdef SERVER
X		    nntpopen(srchahead,GET_HEADER);
X#else
X		    artopen(srchahead);
X#endif
X		    break;
X		}
X		if (input_pending())
X		    break;
X	    }
X	    fflush(stdout);
X	}
X    }
X    else
X#endif
X    {
X	if (art+1 <= lastart)/* how about a pre-fetch? */
X#ifdef SERVER
X	    nntpopen(art+1,GET_HEADER);	/* look for the next article */
X#else
X	    artopen(art+1);	/* look for the next article */
X#endif
X    }
X}
X#endif
X
X/* see what else we can do while they are reading */
X
void
collect_subjects()
X{
X#ifdef PENDING
X# ifdef CACHESUBJ
X    ART_NUM oldart = openart;
X    ART_POS oldartpos;
X
X    if (!in_ng || !srchahead)
X	return;
X    if (oldart)			/* remember where we were in art */
X	oldartpos = ftell(artfp);
X    if (srchahead >= subj_to_get)
X	subj_to_get = srchahead+1;
X    while (!input_pending() && subj_to_get <= lastart)
X	fetchsubj(subj_to_get++,FALSE,FALSE);
X    if (oldart) {
X	artopen(oldart);
X	fseek(artfp,oldartpos,0);	/* do not screw the pager */
X    }
X# endif
X#endif
X}
X
END_OF_FILE
if test 3484 -ne `wc -c <'cheat.c'`; then
    echo shar: \"'cheat.c'\" unpacked with wrong size!
fi
# end of 'cheat.c'
fi
if test -f 'getactive.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'getactive.c'\"
else
echo shar: Extracting \"'getactive.c'\" \(2631 characters\)
sed "s/^X//" >'getactive.c' <<'END_OF_FILE'
X/* $Id: getactive.c,v 4.4 1991/09/09 20:18:23 sob Exp sob $
X *
X * $Log: getactive.c,v $
X * Revision 4.4  1991/09/09  20:18:23  sob
X * release 4.4
X *
X *
X * 
X *
X */
X/* This software is Copyright 1991 by Stan Barber. 
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made. 
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk. 
X */
X#include <stdio.h>
X#include "config.h"
X#include <signal.h>
X/* what to do with ansi prototypes -- '()' == ignore, 'x' == use */
X#ifndef ANSI
X#   define ANSI(x) ()
X#endif
X#include "INTERN.h"
X#ifdef SERVER
X#include "server.h"
X#endif
X
main(argc, argv)
X	int		argc;
X	char	 	*argv[];
X{
X	char		ser_line[NNTP_STRLEN];
X	char		command[32];
X	int		response;
X	char 		*action;
X	register char	*server;
X	register FILE	*actfp;
X
X	if (argc < 2 || argc > 3) {
X		fprintf(stderr, "Usage: getactive [active|distributions|newsgroups] filename\n");
X		exit(1);
X	}
X	if (argc == 2) action = "ACTIVE";
X	else{
X		 action = argv[1];
X		 argc--;
X		 argv++;
X	}
X	if ((server = get_server_name(1)) == NULL)
X		exit(1);
X	response = server_init(server);
X	if (response < 0) {
X		fprintf(stderr,
X			"getactive: Can't get %s file from server %s.\n",
X				action, server);
X		exit(1);
X	}
X
X	if (handle_server_response(response, server) < 0)
X		exit(1);
X
X	sprintf(command,"LIST %s",action);
X	put_server(command); 
X#ifdef HAVESIGHOLD
X 	sighold(SIGINT);
X#endif
X	(void) get_server(ser_line, sizeof(ser_line));
X	if (*ser_line != CHAR_OK) {		/* and then see if that's ok */
X		fprintf(stderr,
X			"getactive: Can't get %s file from server.\n",action);
X		fprintf(stderr, "Server said: %s\n", ser_line);
X		exit(1);
X	}
X
X	actfp = fopen(argv[1], "w");		/* and get ready */
X	if (actfp == NULL) {
X		close_server();
X		perror(argv[1]);
X		exit(1);
X	}
X
X	while (get_server(ser_line, sizeof(ser_line)) >= 0) {  /* while */
X		if (ser_line[0] == '.')		/* there's another line */
X			break;			/* get it and write it to */
X		if (actfp != NULL) {		/* the temporary active file */
X			fputs(ser_line, actfp);
X			putc('\n', actfp);
X		}
X	}
X
X	if (ferror(actfp)) {
X	     perror(argv[1]);
X	     exit(1);
X	}
X
X	if (fclose(actfp) == EOF) {
X	     perror(argv[1]);
X	     exit(1);
X	}
X
X#ifdef HAVESIGHOLD
X
X	exit(0);
X	sigrelse(SIGINT);
X#endif
X	close_server();
X	exit(0);
X}
END_OF_FILE
if test 2631 -ne `wc -c <'getactive.c'`; then
    echo shar: \"'getactive.c'\" unpacked with wrong size!
fi
# end of 'getactive.c'
fi
if test -f 'head.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'head.h'\"
else
echo shar: Extracting \"'head.h'\" \(5071 characters\)
sed "s/^X//" >'head.h' <<'END_OF_FILE'
X/* $Id: head.h,v 4.4 1991/09/09 20:18:23 sob Exp sob $
X *
X * $Log: head.h,v $
X * Revision 4.4  1991/09/09  20:18:23  sob
X * release 4.4
X *
X *
X * 
X */
X/* This software is Copyright 1991 by Stan Barber. 
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made. 
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk. 
X */
X
X#define HEAD_FIRST 1
X
X/* types of header lines (if only C really believed in enums)
X * (These must stay in alphabetic order at least in the first letter.
X * Within each letter it helps to arrange in increasing likelihood.)
X */
X
X#define PAST_HEADER	0	/* body */
X#define SOME_LINE	1	/* unrecognized */
X#define ARTID_LINE	2	/* article-i.d. */
X#define APPR_LINE	3	/* approved */
X#define ACAT_LINE	4	/* ACategory (ClariNet) */
X#define ANPA_LINE	5	/* ANPA (ClariNet) */
X#define CODES_LINE	6	/* Codes (ClariNet) */
X#define DIST_LINE	7	/* distribution */
X#define DATE_LINE	8	/* date */
X#define RECEIVED_LINE	9	/* date-received */
X#define EXPIR_LINE	10	/* expires */
X#define FOLLOW_LINE	11	/* followup-to */
X#define FROM_LINE	12	/* from */
X#define FORM_LINE	13	/* Format (ClariNet) */
X#define KEYW_LINE	14	/* keywords */
X#define LINES_LINE	15	/* lines */
X#define MESSID_LINE	16	/* message-id */
X#define NFFR_LINE	17	/* nf-from */
X#define NFID_LINE	18	/* nf-id */
X#define NGS_LINE	19	/* newsgroups */
X#define NOTE_LINE	20	/* Note (ClariNet) */
X#define ORG_LINE	21	/* organization */
X#define PATH_LINE	22	/* path */
X#define POSTED_LINE	23	/* posted */
X#define PVER_LINE	24	/* posting-version */
X#define PRI_LINE	25	/* Priority (ClariNet) */
X#define REPLY_LINE	26	/* reply-to */
X#define REFS_LINE	27	/* references */
X#define RVER_LINE	28	/* relay-version */
X#define SENDER_LINE	29	/* sender */
X#define SUMRY_LINE	30	/* summary */
X#define SUBJ_LINE	31	/* subject */
X#define SLUG_LINE	32	/* Slugword (ClariNet) */
X#define XREF_LINE	33	/* xref */
X#define XSUP_LINE	34	/* X-Supersedes (ClariNet) */
X#define HEAD_LAST	35	/* one more than the last one above */
X
struct headtype {
X    char *ht_name;		/* header line identifier */
X#ifdef pdp11
X    short ht_minpos;
X    short ht_maxpos;
X#else
X    ART_POS ht_minpos;		/* pointer to beginning of line in article */
X    ART_POS ht_maxpos;		/* pointer to end of line in article */
X#endif
X    char ht_length;		/* could make these into nybbles but */
X    char ht_flags;		/* it wouldn't save space normally */
X};				/* due to alignment considerations */
X
X#define HT_HIDE 1	/* -h on this line */
X#define HT_MAGIC 2	/* do any special processing on this line */
X
X/* This array must stay in the same order as the list above */
X
X#ifndef DOINIT
XEXT struct headtype htype[HEAD_LAST];
X#else
struct headtype htype[HEAD_LAST] = {
X /* name             minpos   maxpos  length   flag */
X    {"BODY",		0,	0,	4,	0		},
X    {"unrecognized",	0,	0,	12,	0		},
X    {"article-i.d.",	0,	0,	12,	HT_HIDE		},
X    {"approved",	0,	0,	8,	HT_HIDE		},
X    {"acategory",	0,	0,	9,	HT_HIDE		},
X    {"anpa",		0,	0,	4,	HT_HIDE		},
X    {"codes",		0,	0,	5,	HT_HIDE		},
X    {"distribution",	0,	0,	12,	0		},
X#ifdef USETHREADS
X    {"date",		0,	0,	4,	HT_MAGIC	},
X#else
X    {"date",		0,	0,	4,	0		},
X#endif
X    {"date-received",	0,	0,	13,	0		},
X    {"expires",		0,	0,	7,	HT_HIDE|HT_MAGIC},
X    {"followup-to",	0,	0,	11,	0		},
X    {"from",		0,	0,	4,	HT_MAGIC	},
X    {"format",		0,	0,	6,	HT_HIDE		},
X    {"keywords",	0,	0,	8,	0		},
X    {"lines",		0,	0,	5,	0		},
X    {"message-id",	0,	0,	10,	HT_HIDE		},
X    {"nf-from",		0,	0,	7,	HT_HIDE		},
X    {"nf-id",		0,	0,	5,	HT_HIDE		},
X    {"newsgroups",	0,	0,	10,	HT_MAGIC|HT_HIDE},
X    {"note",		0,	0,	4,	0,		},
X    {"organization",	0,	0,	12,	0		},
X    {"path",		0,	0,	4,	HT_HIDE		},
X    {"posted",		0,	0,	6,	HT_HIDE		},
X    {"posting-version",	0,	0,	15,	HT_HIDE		},
X    {"priority",	0,	0,	8,	HT_HIDE		},
X    {"reply-to",	0,	0,	8,	HT_HIDE		},
X    {"references",	0,	0,	10,	HT_HIDE		},
X    {"relay-version",	0,	0,	13,	HT_HIDE		},
X    {"sender",		0,	0,	6,	HT_HIDE		},
X    {"summary",		0,	0,	7,	0		},
X    {"subject",		0,	0,	7,	HT_MAGIC	},
X    {"slugword",	0,	0,	8,	HT_HIDE		},
X    {"xref",		0,	0,	4,	HT_HIDE		},
X    {"x-supersedes",	0,	0,	12,	HT_HIDE		}
X};
X#endif
X
X#ifdef ASYNC_PARSE
XEXT ART_NUM parsed_art INIT(0);
X#endif
X
XEXT char in_header INIT(0);		/* are we decoding the header? */
X
X#ifdef CACHESUBJ
X    EXT char **subj_list INIT(Null(char **));
X#endif
X
void	head_init ANSI((void));
int	set_line_type ANSI((char *,char *));
void	start_header ANSI((ART_NUM));
bool    parseline ANSI((char *,int,int));
X#ifdef ASYNC_PARSE
X    int		parse_maybe ANSI((ART_NUM));
X#endif
char	*fetchsubj ANSI((ART_NUM,bool_int,bool_int));
char	*fetchlines ANSI((ART_NUM,int));
X
X#ifdef DEBUGGING
void	dumpheader ANSI((char *));
X#endif
END_OF_FILE
if test 5071 -ne `wc -c <'head.h'`; then
    echo shar: \"'head.h'\" unpacked with wrong size!
fi
# end of 'head.h'
fi
if test -f 'last.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'last.c'\"
else
echo shar: Extracting \"'last.c'\" \(2086 characters\)
sed "s/^X//" >'last.c' <<'END_OF_FILE'
X/* $Id: last.c,v 4.4 1991/09/09 20:23:31 sob Exp sob $
X *
X * $Log: last.c,v $
X * Revision 4.4  1991/09/09  20:23:31  sob
X * release 4.4
X *
X *
X * 
X */
X/* This software is Copyright 1991 by Stan Barber. 
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made. 
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk. 
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "rn.h"
X#include "util.h"
X#include "intrp.h"
X#include "INTERN.h"
X#include "last.h"
X
char *lastname = Nullch;	/* path name of .rnlast file */
X
void
last_init(tcbuf)
char *tcbuf;
X{
X    lastname = savestr(filexp(LASTNAME));
X    if ((tmpfp = fopen(lastname,"r")) != Nullfp &&
X	fgets(tcbuf,1024,tmpfp) != Nullch) {
X	tcbuf[strlen(tcbuf)-1] = '\0';
X	lastngname = savestr(tcbuf);
X	fgets(tcbuf,1024,tmpfp);
X	lasttime = atol(tcbuf);
X	fgets(tcbuf,1024,tmpfp);
X	lastactsiz = atol(tcbuf);
X	if (fgets(tcbuf,1024,tmpfp) != Nullch)
X	    lastnewtime = atol(tcbuf);
X	else
X	    lastnewtime = (lasttime? lasttime : time(Null(time_t*))-24L*60*60);
X	if (fgets(tcbuf,1024,tmpfp) != Nullch)
X	    lastnewsize = atol(tcbuf);
X	else
X	    lastnewsize = 0;
X	fclose(tmpfp);
X    }
X    else {
X	lastngname = nullstr;
X	lasttime = 0;
X	lastactsiz = 0;
X	lastnewsize = 0;
X	/* Use yesterday as an initial value for finding new groups. */
X	lastnewtime = time(Null(time_t*)) - 24L*60*60;
X    }
X}
X
X/* put out certain values for next run of rn */
X
void
writelast()
X{
X    if ((tmpfp = fopen(lastname,"w")) != Nullfp) {
X	fprintf(tmpfp,"%s\n%ld\n%ld\n%ld\n%ld\n",
X	    (ngname==Nullch?nullstr:ngname),(long)lasttime,(long)lastactsiz,
X	    (long)lastnewtime,(long)lastnewsize);
X	fclose(tmpfp);
X    }
X    else
X	printf(cantcreate,lastname) FLUSH;
X}
END_OF_FILE
if test 2086 -ne `wc -c <'last.c'`; then
    echo shar: \"'last.c'\" unpacked with wrong size!
fi
# end of 'last.c'
fi
if test -f 'makedepend.SH' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makedepend.SH'\"
else
echo shar: Extracting \"'makedepend.SH'\" \(2576 characters\)
sed "s/^X//" >'makedepend.SH' <<'END_OF_FILE'
case $CONFIG in
X    '') . ./config.sh ;;
esac
echo "Extracting makedepend (with variable substitutions)"
X$spitshell >makedepend <<!GROK!THIS!
X$startsh
X# $Id: makedepend.SH,v 4.4 1991/09/09 20:23:31 sob Exp sob $
X#
X# $Log: makedepend.SH,v $
X# Revision 4.4  1991/09/09  20:23:31  sob
X# release 4.4
X#
X# 
X# This software is Copyright 1991 by Stan Barber. 
X#
X# Permission is hereby granted to copy, reproduce, redistribute or otherwise
X# use this software as long as: there is no monetary profit gained
X# specifically from the use or reproduction of this software, it is not
X# sold, rented, traded or otherwise marketed, and this copyright notice is
X# included prominently in any copy made. 
X#
X# The author make no claims as to the fitness or correctness of this software
X# for any use whatsoever, and it is provided as is. Any use of this software
X# is at the user's own risk. 
export PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
X
X$cat /dev/null >.deptmp
X$echo "(Note: this is going to take a while.)"
X$rm -f X*.c
for file in *.c; do
X    filebase=\`basename \$file .c\`
X    $echo "Finding dependencies for \$filebase.o."
X    $sed -n <\$file >X\$file \\
X	-e "/^\${filebase}_init(/q" \\
X	-e '/^#/{' \\
X	-e 's|/\*.*$||' \\
X	-e p \\
X	-e '}'
X    $cpp -I/usr/local/include X\$file | $sed  \\
X	-e '/^# *line/s/line//' \
X	-e '/^# *[0-9]/!d' \\
X	-e 's/^.*"\(.*\)".*\$/'\$filebase'.o: \1/' \\
X	-e 's|: \./|: |' \\
X	-e 's|: X|: |' | \\
X	$uniq | $sort | $uniq >> .deptmp
done
X
for file in *.SH; do
X    $echo \`basename \$file .SH\`: \$file config.sh \; /bin/sh \$file >> .deptmp
done
X
X$sed <Makefile >Makefile.new -e '1,/^# AUTOMATICALLY/!d'
X
if $test -s .deptmp; then
X    echo "Updating Makefile..."
X    echo "# If this runs make out of memory, delete /usr/include lines." >>Makefile.new
X    $sed -e 's/\\\$/\$\$/g' .deptmp >>Makefile.new
else
X    $echo "You don't seem to have a proper C preprocessor.  Using grep instead."
X    $egrep '^#include ' *.c *.h >.deptmp
X    echo "Updating Makefile..."
X    <.deptmp $sed -n 's|c:#include "\(.*\)".*\$\$|o: \1|p' >> Makefile.new
X    <.deptmp $sed -n 's|c:#include <\(.*\)>.*\$\$|o: /usr/include/\1|p' >> Makefile.new
X    <.deptmp $sed -n 's|h:#include "\(.*\)".*\$\$|h: \1|p' >> Makefile.new
X    <.deptmp $sed -n 's|h:#include <\(.*\)>.*\$\$|h: /usr/include/\1|p' >> Makefile.new
fi
X$mv Makefile Makefile.old
X$mv Makefile.new Makefile
X$echo "# WARNING: Put nothing here or make depend will gobble it up!" >> Makefile
rm .deptmp X*.c
X
X!GROK!THIS!
X$eunicefix makedepend
chmod 755 makedepend
END_OF_FILE
if test 2576 -ne `wc -c <'makedepend.SH'`; then
    echo shar: \"'makedepend.SH'\" unpacked with wrong size!
fi
# end of 'makedepend.SH'
fi
if test -f 'mt-misc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mt-misc.c'\"
else
echo shar: Extracting \"'mt-misc.c'\" \(4834 characters\)
sed "s/^X//" >'mt-misc.c' <<'END_OF_FILE'
X/* $Id: mt-misc.c,v 4.4.3.1 1991/11/22 04:12:15 davison Trn $
X**
X** $Log: mt-misc.c,v $
X** Revision 4.4.3.1  1991/11/22  04:12:15  davison
X** Trn Release 2.0
X** 
X*/
X
X#include "EXTERN.h"
X#include "common.h"
X#include "threads.h"
X#include "mthreads.h"
X
char *lib, *rnlib, *mtlib, *spool, *threaddir, *homedir;
int locked = 0, cron_locking = 0;
X
void
mt_init()
X{
X    /* Set up a nice friendly umask. */
X    umask(002);
X
X    /* Init the directory strings, possibly translating them into real paths */
X    homedir = getenv("HOME");
X    if (homedir == Nullch) {
X	homedir = getenv("LOGDIR");
X    }
X    spool = savestr(file_exp(SPOOL));
X    lib = savestr(file_exp(LIB));
X    rnlib = savestr(file_exp(RNLIB));
X    mtlib = savestr(file_exp(MTLIB));
X    threaddir = savestr(file_exp(THREAD_DIR));
X}
X
X/* Make sure we're not already running by creating a lock file. */
long
mt_lock(which_lock, sig)
int which_lock;
int sig;
X{
X    char buff[LBUFLEN], *filename;
X    FILE *fp;
X
X    sprintf(buff, "%s.%ld", file_exp(MTPRELOCK), (long)getpid());
X    if ((fp = fopen(buff, "w")) == Nullfp) {
X	log_entry("Unable to create lock temporary `%s'.\n", buff);
X	wrap_it_up(1);
X    }
X    fprintf(fp, "%s%ld\n", which_lock == DAEMON_LOCK ? "pid " : nullstr,
X	(long)getpid());
X    fclose(fp);
X
X    /* Try to link to lock file. */
X    if (which_lock == DAEMON_LOCK) {
X	filename = file_exp(MTDLOCK);
X    } else {
X	filename = file_exp(MTLOCK);
X    }
X  dolink:
X    while (link(buff, filename) < 0) {
X      long otherpid;
X	if ((fp = fopen(filename, "r")) == Nullfp) {
X	    log_entry("unable to open %s\n", filename);
X	    if (cron_locking) {
X		goto Sleep;
X	    }
X	    unlink(buff);
X	    wrap_it_up(1);
X	}
X	if (fscanf(fp, "%ld", &otherpid) != 1) { 
X	    log_entry("unable to read pid from %s\n", filename);
X	    fclose(fp);
X	    if (cron_locking) {
X		goto Sleep;
X	    }
X	    unlink(buff);
X	    wrap_it_up(1);
X	}
X	fclose(fp);
X	if (kill(otherpid, sig) == -1 && errno == ESRCH) {
X	    if (unlink(filename) == -1) {
X		log_entry("unable to unlink lockfile %s\n", filename);
X		unlink(buff);
X		wrap_it_up(1);
X	    }
X	    goto dolink;
X	}
X	if (cron_locking) {
X	  Sleep:
X	    sleep(60);
X	    continue;
X	}
X	unlink(buff);
X	return otherpid;
X    }
X    unlink(buff);			/* remove temporary LOCK.<pid> file */
X    locked |= which_lock;
X    return 0;				/* return success */
X}
X
void
mt_unlock(which_lock)
int which_lock;
X{
X    which_lock &= locked;
X    if (which_lock & PASS_LOCK) {
X	unlink(file_exp(MTLOCK));		/* remove single-pass lock */
X    }
X    if (which_lock & DAEMON_LOCK) {
X	unlink(file_exp(MTDLOCK));		/* remove daemon lock */
X    }
X    locked &= ~which_lock;
X}
X
X/* Interpret rn's %x prefixes and ~name expansions without including tons
X** of useless source.  NOTE:  names that don't start with '/', '%' or '~'
X** are prefixed with the SPOOL directory.  (Note that ~'s don't work yet.)
X*/
char *
file_exp(name)
char *name;
X{
X    static char namebuf[MAXFILENAME];
X
X    if (*name == '/') {	/* fully qualified names are left alone */
X	return name;
X    }
X    switch (name[0]) {
X    case '%':			/* interpret certain %x values */
X	switch (name[1]) {
X	case 'P':
X	    strcpy(namebuf, spool);
X	    break;
X	case 'w':
X	    strcpy(namebuf, mtlib);
X	    break;
X	case 'W':
X	    strcpy(namebuf, threaddir);
X	    break;
X	case 'x':
X	    strcpy(namebuf, lib);
X	    break;
X	case 'X':
X	    strcpy(namebuf, rnlib);
X	    break;
X	default:
X	    log_entry("Unknown expansion: %s\n", name);
X	    wrap_it_up(1);
X	}
X	strcat(namebuf, name+2);
X	break;
X    case '~':
X    {
X	char *s = name + 1;
X
X	if (!*s || *s == '/') {
X	    sprintf(namebuf, "%s%s", homedir, s);
X	} else {
X	    log_entry("~name expansions not implemented.");
X	    wrap_it_up(1);
X	}
X    }
X    default:			/* all "normal" names are relative to SPOOL */
X	sprintf(namebuf, "%s/%s", spool, name);
X	break;
X    }
X    return namebuf;
X}
X
X#ifndef lint
X/* A malloc that bombs-out when memory is exhausted. */
char *
safemalloc(amount)
MEM_SIZE amount;
X{
X    register char *cp;
X    char *malloc();
X
X    if ((cp = malloc(amount)) == Nullch) {
X	log_error("malloc(%ld) failed.\n", (long)amount);
X	wrap_it_up(1);
X    }
X    return cp;
X}
X
X/* paranoid version of realloc */
char *
saferealloc(where,size)
char *where;
MEM_SIZE size;
X{
X    char *ptr;
X    char *realloc();
X
X    ptr = realloc(where,size?size:1);	/* realloc(0) is NASTY on our system */
X    if (ptr == Nullch) {
X	log_error("realloc(..., %ld) failed.\n", (long)size);
X	wrap_it_up(1);
X    }
X    return ptr;
X}
X#endif
X
X/* Create a malloc'ed copy of a string. */
char *
savestr(str)
char *str;
X{
X    register MEM_SIZE len = strlen(str) + 1;
X    register char *newaddr = safemalloc(len);
X
X    bcopy(str, newaddr, (int)len);
X
X    return newaddr;
X}
X
X#ifndef lint
X/* Free some memory if it hasn't already been freed. */
void
safefree(pp)
char **pp;
X{
X    if (*pp) {
X	free(*pp);
X	*pp = Nullch;
X    }
X}
X#endif
END_OF_FILE
if test 4834 -ne `wc -c <'mt-misc.c'`; then
    echo shar: \"'mt-misc.c'\" unpacked with wrong size!
fi
# end of 'mt-misc.c'
fi
if test -f 'ndir.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ndir.c'\"
else
echo shar: Extracting \"'ndir.c'\" \(2455 characters\)
sed "s/^X//" >'ndir.c' <<'END_OF_FILE'
X/* $Id: ndir.c,v 4.4 1991/09/09 20:23:31 sob Exp sob $
X *
X * $Log: ndir.c,v $
X * Revision 4.4  1991/09/09  20:23:31  sob
X * release 4.4
X *
X *
X * 
X */
X/* This software is Copyright 1991 by Stan Barber. 
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made. 
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk. 
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "INTERN.h"
X#include "ndir.h"
X
X#ifdef USENDIR
X/*
X * support for Berkeley directory reading routine on a V7 file system
X */
X
X/*
X * open a directory.
X */
DIR *
opendir(name)
char *name;
X{
X	register DIR *dirp;
X	register int fd;
X	char *malloc();
X
X	if ((fd = open(name, 0)) == -1)
X		return NULL;
X	if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
X		close (fd);
X		return NULL;
X	}
X	dirp->dd_fd = fd;
X	dirp->dd_loc = 0;
X	return dirp;
X}
X
X/*
X * read an old style directory entry and present it as a new one
X */
X#ifndef pyr
X#define	ODIRSIZ	14
X
struct	olddirect {
X	ino_t	od_ino;
X	char	od_name[ODIRSIZ];
X};
X#else	/* an Pyramid in the ATT universe */
X#define	ODIRSIZ	248
X
struct	olddirect {
X	long	od_ino;
X	short	od_fill1, od_fill2;
X	char	od_name[ODIRSIZ];
X};
X#endif
X
X/*
X * get next entry in a directory.
X */
struct direct *
readdir(dirp)
register DIR *dirp;
X{
X	register struct olddirect *dp;
X	static struct direct dir;
X
X	for (;;) {
X		if (dirp->dd_loc == 0) {
X			dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
X			    DIRBLKSIZ);
X			if (dirp->dd_size <= 0)
X				return NULL;
X		}
X		if (dirp->dd_loc >= dirp->dd_size) {
X			dirp->dd_loc = 0;
X			continue;
X		}
X		dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
X		dirp->dd_loc += sizeof(struct olddirect);
X		if (dp->od_ino == 0)
X			continue;
X		dir.d_ino = dp->od_ino;
X		strncpy(dir.d_name, dp->od_name, ODIRSIZ);
X		dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
X		dir.d_namlen = strlen(dir.d_name);
X		dir.d_reclen = DIRSIZ(&dir);
X		return (&dir);
X	}
X}
X
X/*
X * close a directory.
X */
void
closedir(dirp)
register DIR *dirp;
X{
X	close(dirp->dd_fd);
X	dirp->dd_fd = -1;
X	dirp->dd_loc = 0;
X	free(dirp);
X}
X
X#endif /* USENDIR */
END_OF_FILE
if test 2455 -ne `wc -c <'ndir.c'`; then
    echo shar: \"'ndir.c'\" unpacked with wrong size!
fi
# end of 'ndir.c'
fi
if test -f 'ndir.h.SH' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ndir.h.SH'\"
else
echo shar: Extracting \"'ndir.h.SH'\" \(2298 characters\)
sed "s/^X//" >'ndir.h.SH' <<'END_OF_FILE'
X: create config.h file
echo "Extracting ndir.h (with variable substitutions)"
X. ./config.sh
X$cat <<EOT >ndir.h
X/*
X * This file was produced by running the ndir.h.SH script, which
X * gets its values from config.sh, which is generally produced by
X * running Configure.
X */
X/* $Id: ndir.h.SH,v 4.4 1991/09/09 20:23:31 sob Exp sob $
X *
X * $Log: ndir.h.SH,v $
X# Revision 4.4  1991/09/09  20:23:31  sob
X# release 4.4
X#
X *
X * 
X */
X/* This software is Copyright 1991 by Stan Barber. 
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made. 
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk. 
X */
X
X#ifdef LIBNDIR
X#   include <ndir.h>
X#else
X#   ifndef USENDIR
X#	include $dirinc
X#   else
X
X#ifndef DEV_BSIZE
X#define	DEV_BSIZE	512
X#endif
X#define DIRBLKSIZ	DEV_BSIZE
X#define	MAXNAMLEN	255
X
struct	direct {
X	long	d_ino;			/* inode number of entry */
X	short	d_reclen;		/* length of this record */
X	short	d_namlen;		/* length of string in d_name */
X	char	d_name[MAXNAMLEN + 1];	/* name must be no longer than this */
X};
X
X/*
X * The DIRSIZ macro gives the minimum record length which will hold
X * the directory entry.  This requires the amount of space in struct direct
X * without the d_name field, plus enough space for the name with a terminating
X * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
X */
X#undef DIRSIZ
X#define DIRSIZ(dp) \
X    ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
X
X/*
X * Definitions for library routines operating on directories.
X */
typedef struct _dirdesc {
X	int	dd_fd;
X	long	dd_loc;
X	long	dd_size;
X	char	dd_buf[DIRBLKSIZ];
X} DIR;
X#ifndef NULL
X#define NULL 0
X#endif
extern	DIR *opendir ANSI((char *));
extern	struct direct *readdir ANSI((DIR *));
extern	long telldir ANSI((DIR *));
extern	void seekdir ANSI((DIR *));
X#define rewinddir(dirp)	seekdir((dirp), (long)0)
extern	void closedir ANSI((DIR *));
X
X#   endif
X#endif
XEOT
END_OF_FILE
if test 2298 -ne `wc -c <'ndir.h.SH'`; then
    echo shar: \"'ndir.h.SH'\" unpacked with wrong size!
fi
# end of 'ndir.h.SH'
fi
if test -f 'newsetup.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'newsetup.1'\"
else
echo shar: Extracting \"'newsetup.1'\" \(2278 characters\)
sed "s/^X//" >'newsetup.1' <<'END_OF_FILE'
X.\" $Id: newsetup.1,v 4.4.1.1 1991/09/25 19:36:48 sob Exp sob $
X.\" 
X.\" $Log: newsetup.1,v $
X.\" Revision 4.4.1.1  1991/09/25  19:36:48  sob
X.\" Changed quote macro to "standard" one
X.\"
X.\" Revision 4.4  1991/09/09  20:23:31  sob
X.\" release 4.4
X.\"
X.\"
X.\" This software is Copyright 1991 by Stan Barber. 
X.\"
X.\" Permission is hereby granted to copy, reproduce, redistribute or otherwise
X.\" use this software as long as: there is no monetary profit gained
X.\" specifically from the use or reproduction of this software, it is not
X.\" sold, rented, traded or otherwise marketed, and this copyright notice is
X.\" included prominently in any copy made. 
X.\"
X.\" The author make no claims as to the fitness or correctness of this software
X.\" for any use whatsoever, and it is provided as is. Any use of this software
X.\" is at the user's own risk. 
X.\" 
X.\" 
X.de Sh
X.br
X.ne 5
X.PP
X\fB\\$1\fR
X.PP
X..
X.de Sp
X.if t .sp .5v
X.if n .sp
X..
X.\"
X.\"     Set up \*(-- to give an unbreakable dash;
X.\"     string Tr holds user defined translation string.
X.\"     Bell System Logo is used as a dummy character.
X.\"
X.ie n \{\
X.tr \(bs-\*(Tr
X.ds -- \(bs-
X.if (\n(.H=4u)&(1m=24u) .ds -- \(bs\h'-12u'\(bs\h'-12u'-\" diablo 10 pitch
X.if (\n(.H=4u)&(1m=20u) .ds -- \(bs\h'-12u'\(bs\h'-8u'-\" diablo 12 pitch
X.ds L" ""
X.ds R" ""
X.ds L' '
X.ds R' '
X'br\}
X.el\{\
X.ds -- \(em\|
X.tr \*(Tr
X.ds L" ``
X.ds R" ''
X.ds L' `
X.ds R' '
X'br\}
X.TH NEWSETUP 1 LOCAL
X.SH NAME
newsetup - a program to set up a .newsrc file
X.SH SYNOPSIS
X.B newsetup
X.SH DESCRIPTION
The
X.I newsetup
program creates a new .newsrc file containing all of the currently active
newsgroups.
It tries to put them in a reasonable order, i.e. local newsgroups earlier,
but you'll probably want to change the ordering anyway (if you use
X.IR rn )
in order to put interesting newsgroups first.
If you already have a .newsrc, it will be backed up with the name
X\*(L".oldnewsrc\*(R".
X.SH ENVIRONMENT
X.IP DOTDIR 8
Where to put your .newsrc, if not in your home directory.
X.Sp
Default: $HOME
X.IP HOME 8
Your home directory.
X.Sp
Default: $LOGDIR
X.IP LOGDIR 8
Your home directory if HOME is undefined.
X.SH FILES
X/usr/lib/news/active or a reasonable facsimile
X.br
X${DOTDIR-{$HOME-$LOGDIR}}/.newsrc
X.SH SEE ALSO
rn(1), newsrc(5)
X.SH DIAGNOSTICS
X.SH BUGS
END_OF_FILE
if test 2278 -ne `wc -c <'newsetup.1'`; then
    echo shar: \"'newsetup.1'\" unpacked with wrong size!
fi
# end of 'newsetup.1'
fi
if test -f 'newsetup.SH' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'newsetup.SH'\"
else
echo shar: Extracting \"'newsetup.SH'\" \(3286 characters\)
sed "s/^X//" >'newsetup.SH' <<'END_OF_FILE'
case $CONFIG in
X    '') . ./config.sh ;;
esac
echo "Extracting newsetup (with variable substitutions)"
X$spitshell >newsetup <<!GROK!THIS!
X$startsh
X#
X# $Id: newsetup.SH,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
X# 
X# $Log: newsetup.SH,v $
X# Revision 4.4.2.1  1991/12/01  18:05:42  sob
X# Fixed problems with CTRLA flag.
X#
X# Revision 4.4.1.2  1991/11/09  20:54:14  sob
X# Changes from eggert@twinsun.com to get rid of old code.
X#
X# Revision 4.4.1.1  1991/09/25  19:38:08  sob
X# various fixed
X#
X# Revision 4.4  1991/09/09  20:23:31  sob
X# release 4.4
X#
X#
X# 
X# This software is Copyright 1991 by Stan Barber. 
X#
X# Permission is hereby granted to copy, reproduce, redistribute or otherwise
X# use this software as long as: there is no monetary profit gained
X# specifically from the use or reproduction of this software, it is not
X# sold, rented, traded or otherwise marketed, and this copyright notice is
X# included prominently in any copy made. 
X#
X# The author make no claims as to the fitness or correctness of this software
X# for any use whatsoever, and it is provided as is. Any use of this software
X# is at the user's own risk. 
X
export PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
X
X: syntax: newsetup
X
X: System dependencies
X: You will want to change the definitions below to reflect the distribution
X: areas around you.  If you have more areas than this you will need to modify
X: the sed below.
X
locorg="$locpref"
organization="$orgpref"
city="$citypref"
state="$statepref"
cntry="$cntrypref"
cont="$contpref"
X#NORMALactive="${active-/usr/lib/news/active}"
X#NNTPactive="/tmp/active.\$\$"
X
dotdir="\${DOTDIR-\${HOME-\$LOGDIR}}"
newsrc="\${NEWSRC-\$dotdir/.newsrc}"
X$rm -f \$newsrc-old
X$echo "Creating \$newsrc to be used by news programs."
X#NNTPrnlib=$rnlib
X#NNTPcase \$rnlib in
X#NNTP~*) rnlib=\`$filexp \$rnlib\` ;;
X#NNTPesac
X#NNTPif \$rnlib/getactive ACTIVE \$active; then
X#NNTP    true;
X#NNTPelse
X#NNTP    exit 1;
X#NNTPfi
X#NORMALcase \$active in
X#NORMAL~*) active=\`$filexp \$active\` ;;
X#NORMALesac
X
if $test -s \$newsrc ; then
X    $echo "Saving your current \$newsrc as \$newsrc-old..."
X    $mv -f \$newsrc \$newsrc-old
fi
X
X: newsrc order determined here
X
X$sed <\$active '
X	/^to\./d
X	/ [^mny][^ ]*$/d
X	s/ .*//
X	s/^/ /
X	s/^ '\$locorg'\./01&/
X	s/^ '\$organization'\./02&/
X	s/^ '\$city'\./03&/
X	s/^ '\$state'\./04&/
X	s/^ '\$cntry'\./05&/
X	s/^ '\$cont'\./06&/
X	s/^ news\./07&/
X	s/^ comp\./08&/
X	s/^ sci\./09&/
X	s/^ rec\./10&/
X	s/^ soc\./11&/
X	s/^ talk\./13&/
X	s/^ control\$/14&/
X	s/^ junk\$/14&/
X	s/^ test\$/14&/
X	/\.test\$/s/^[0-9]*/14/
X	s/^ .*\./12&/
X	s/^ /00&/
X' |
X$sort -u |
X$sed '
X	/^14 /!s/\$/:/
X	/^14 /s/\$/!/
X	s/^[0-9][0-9] //
X' >\$newsrc
X
X#NNTP$rm -f \$active
X
X$cat <<'EOH'
Done.
X
If you have never used the news system before, you may find the articles
in news.announce.newusers to be helpful.  There is also a manual entry for rn.
X
To get rid of newsgroups you aren't interested in, use the 'u' command.
Type h for help at any time while running rn.
XEOH
X!GROK!THIS!
case "$isrrn" in
define)  sed < newsetup -e '/^#NNTP/s/^#NNTP//' -e '/^#NORMAL/d' > newsetup.new ;;
X*) sed < newsetup -e '/^#NNTP/d' -e '/^#NORMAL/s/^#NORMAL//' > newsetup.new ;;
esac
mv newsetup.new newsetup
X$eunicefix newsetup
chmod 755 newsetup
END_OF_FILE
if test 3286 -ne `wc -c <'newsetup.SH'`; then
    echo shar: \"'newsetup.SH'\" unpacked with wrong size!
fi
# end of 'newsetup.SH'
fi
if test -f 'newsgroups.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'newsgroups.1'\"
else
echo shar: Extracting \"'newsgroups.1'\" \(2385 characters\)
sed "s/^X//" >'newsgroups.1' <<'END_OF_FILE'
X.\" $Id: newsgroups.1,v 4.4.1.1 1991/09/25 19:36:48 sob Exp sob $
X.\" 
X.\" $Log: newsgroups.1,v $
X.\" Revision 4.4.1.1  1991/09/25  19:36:48  sob
X.\" Changed quote macro to "standard" one
X.\"
X.\" Revision 4.4  1991/09/09  20:23:31  sob
X.\" release 4.4
X.\"
X.\"
X.\" This software is Copyright 1991 by Stan Barber. 
X.\"
X.\" Permission is hereby granted to copy, reproduce, redistribute or otherwise
X.\" use this software as long as: there is no monetary profit gained
X.\" specifically from the use or reproduction of this software, it is not
X.\" sold, rented, traded or otherwise marketed, and this copyright notice is
X.\" included prominently in any copy made. 
X.\"
X.\" The author make no claims as to the fitness or correctness of this software
X.\" for any use whatsoever, and it is provided as is. Any use of this software
X.\" is at the user's own risk. 
X.\" 
X.\" 
X.de Sh
X.br
X.ne 5
X.PP
X\fB\\$1\fR
X.PP
X..
X.de Sp
X.if t .sp .5v
X.if n .sp
X..
X.\"
X.\"     Set up \*(-- to give an unbreakable dash;
X.\"     string Tr holds user defined translation string.
X.\"     Bell System Logo is used as a dummy character.
X.\"
X.ie n \{\
X.tr \(bs-\*(Tr
X.ds -- \(bs-
X.if (\n(.H=4u)&(1m=24u) .ds -- \(bs\h'-12u'\(bs\h'-12u'-\" diablo 10 pitch
X.if (\n(.H=4u)&(1m=20u) .ds -- \(bs\h'-12u'\(bs\h'-8u'-\" diablo 12 pitch
X.ds L" ""
X.ds R" ""
X.ds L' '
X.ds R' '
X'br\}
X.el\{\
X.ds -- \(em\|
X.tr \*(Tr
X.ds L" ``
X.ds R" ''
X.ds L' `
X.ds R' '
X'br\}
X.TH NEWSGROUPS 1 LOCAL
X.SH NAME
newsgroups - a program to list unsubscribed newsgroups.
X.SH SYNOPSIS
X.B newsgroups pattern flag
X.SH DESCRIPTION
The
X.I newsgroups
program compares your .newsrc file with the file of active newsgroups,
and prints a list of unsubscribed newsgroups matching pattern.
If the second argument \*(L"flag\*(R" is present, only newsgroups not
found in your .newsrc are listed, and the display is not paged.
If the second argument is missing, the display is paged, and an additional
list of unsubscribed newsgroups occurring in your .newsrc is printed.
X.SH ENVIRONMENT
X.IP DOTDIR 8
Where to find your .newsrc, if not in your home directory.
X.Sp
Default: $HOME
X.IP HOME 8
Your home directory.
X.Sp
Default: $LOGDIR
X.IP LOGDIR 8
Your home directory if HOME is undefined.
X.SH FILES
X/usr/lib/news/active or a reasonable facsimile
X.br
X${DOTDIR-{$HOME-$LOGDIR}}/.newsrc
X.SH SEE ALSO
rn(1), newsrc(5)
X.SH DIAGNOSTICS
X.SH BUGS
The flag argument is a kludge.
END_OF_FILE
if test 2385 -ne `wc -c <'newsgroups.1'`; then
    echo shar: \"'newsgroups.1'\" unpacked with wrong size!
fi
# end of 'newsgroups.1'
fi
if test -f 'newsgroups.SH' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'newsgroups.SH'\"
else
echo shar: Extracting \"'newsgroups.SH'\" \(2780 characters\)
sed "s/^X//" >'newsgroups.SH' <<'END_OF_FILE'
case $CONFIG in
X    '') . ./config.sh ;;
esac
echo "Extracting newsgroups (with variable substitutions)"
X$spitshell >newsgroups <<!GROK!THIS!
X$startsh
X# $Id: newsgroups.SH,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
X# 
X# $Log: newsgroups.SH,v $
X# Revision 4.4.2.1  1991/12/01  18:05:42  sob
X# Patchlevel 2 changes
X#
X# Revision 4.4.1.1  1991/09/25  19:38:08  sob
X# various fixed
X#
X# Revision 4.4  1991/09/09  20:23:31  sob
X# release 4.4
X#
X# 
X# This software is Copyright 1991 by Stan Barber. 
X#
X# Permission is hereby granted to copy, reproduce, redistribute or otherwise
X# use this software as long as: there is no monetary profit gained
X# specifically from the use or reproduction of this software, it is not
X# sold, rented, traded or otherwise marketed, and this copyright notice is
X# included prominently in any copy made. 
X#
X# The author make no claims as to the fitness or correctness of this software
X# for any use whatsoever, and it is provided as is. Any use of this software
X# is at the user's own risk. 
X
export PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
X
X: syntax: newsgroups [pattern] [pipeflag]
X
X: System Dependencies
X
X: You might want to change pager to a "make column" program if you have one.
X: On the other hand, if your kernel does paging, cat would probably do.
pager="${pager-/usr/ucb/more}"
X#NORMALactive="${active-/usr/lib/news/active}"
X
X#NORMALcase \$active in
X#NORMAL~*) active=\`$filexp \$active\` ;;
X#NORMALesac
X
X#NNTPactive="/tmp/active.\$\$"
X
X#NNTPcase \$rnlib in
X#NNTP~*) rnlib=\`$filexp \$rnlib\` ;;
X#NNTPesac
X
X: End of system dependencies, hopefully
X
X#NNTPif $rnlib/getactive ACTIVE \$active; then
X#NNTP    true;
X#NNTPelse
X#NNTP    exit 1;
X#NNTPfi
X
if $test \$# -ge 2 ; then
X    pager=$cat
else
X    $echo "Completely unsubscribed newsgroups:"
fi
X
dotdir=\${DOTDIR-\${HOME-\$LOGDIR}}
newsrc=\${NEWSRC-\$dotdir/.newsrc}
X
X: Throwing .newsrc into the pot twice is a lovely hack to prevent
X: bogus newsgroups from showing up as unsubscribed.
X
X$cat \$newsrc \$newsrc \$active | \\
X$sed -n	-e '/^options/d' \\
X	-e '/^[	 ]/d' \\
X	-e '/^control/d' \\
X	-e '/^to\./d' \\
X 	-e '/ x\$/d' \\
X	-e 's/^\([^ !:]*\)[ !:].*\$/\1/' \\
X	-e "/.*\$1/p" | \\
X$sort | $uniq -u | \$pager
X#NNTP$rm -f \$active
if $test \$# -ge 2 ; then
X    exit
fi
X$echo $n "[Type return to continue] $c"
read tmp
X$echo ""
X$echo "Unsubscribed but mentioned in \$newsrc:"
X$sed -n < \$newsrc \\
X	-e "/\$1.*!/"'s/^\([^!]*\)!.*\$/\1/p' | \\
X$sort | \$pager
X!GROK!THIS!
case "$isrrn" in
define)  sed < newsgroups -e '/^#NNTP/s/^#NNTP//' -e '/^#NORMAL/d' > newsgroups.new ;;
X*) sed < newsgroups -e '/^#NNTP/d' -e '/^#NORMAL/s/^#NORMAL//' > newsgroups.new ;;
esac
mv newsgroups.new newsgroups
X$eunicefix newsgroups
chmod 755 newsgroups
END_OF_FILE
if test 2780 -ne `wc -c <'newsgroups.SH'`; then
    echo shar: \"'newsgroups.SH'\" unpacked with wrong size!
fi
# end of 'newsgroups.SH'
fi
if test -f 'newsnews.SH' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'newsnews.SH'\"
else
echo shar: Extracting \"'newsnews.SH'\" \(2161 characters\)
sed "s/^X//" >'newsnews.SH' <<'END_OF_FILE'
X: see end of file for revision information
case $CONFIG in
X    '') . ./config.sh ;;
esac
echo "Extracting newsnews (with variable substitutions)"
cat >newsnews <<!GROK!THIS!
X			*** NEWS NEWS ***
X
Welcome to trn.  There are more options to trn than you want to think about, so
we won't list them here.  If you want to find out about them, read the manual
page(s).  There are some important things to remember, though:
X
X  * Trn is an extention of rn.  Where possible, the command syntax is the same.
X  * To access all the new features, specify the options -x and -X.  These
X    options MAY be on by default, but it won't hurt to be redundant.
X  * Trn runs in cbreak mode.  This means you don't have to type carriage return
X    on single character commands.  (There are some multi-character commands.)
X  * At ANY prompt, you may type 'h' for help.  There are many different help
X    menus, depending on the context.  Also, typing <esc>h in the middle of a
X    multi-character command will list escape substitutions.
X  * Typing a space to any prompt means to do the normal thing.  You could
X    spend all day reading news and never hit anything but the space bar.
X
This particular message comes from $rnlib/newsnews, and will only
appear once.  If your news administrator puts a new message in here, it
will be displayed for you the first time you run trn after the change.
X
Wayne Davison	davison@borland.com
X!GROK!THIS!
X$eunicefix newsnews
X#
X# $Id: newsnews.SH,v 4.4 1991/09/09 20:23:31 sob Exp sob $
X# 
X# $Log: newsnews.SH,v $
X# Revision 4.4  1991/09/09  20:23:31  sob
X# release 4.4
X#
X#
X#
X# This software is Copyright 1991 by Stan Barber. 
X#
X# Permission is hereby granted to copy, reproduce, redistribute or otherwise
X# use this software as long as: there is no monetary profit gained
X# specifically from the use or reproduction of this software, it is not
X# sold, rented, traded or otherwise marketed, and this copyright notice is
X# included prominently in any copy made. 
X#
X# The author make no claims as to the fitness or correctness of this software
X# for any use whatsoever, and it is provided as is. Any use of this software
X# is at the user's own risk. 
X
END_OF_FILE
if test 2161 -ne `wc -c <'newsnews.SH'`; then
    echo shar: \"'newsnews.SH'\" unpacked with wrong size!
fi
# end of 'newsnews.SH'
fi
if test -f 'ngsrch.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ngsrch.c'\"
else
echo shar: Extracting \"'ngsrch.c'\" \(3430 characters\)
sed "s/^X//" >'ngsrch.c' <<'END_OF_FILE'
X/* $Id: ngsrch.c,v 4.4 1991/09/09 20:23:31 sob Exp sob $
X *
X * $Log: ngsrch.c,v $
X * Revision 4.4  1991/09/09  20:23:31  sob
X * release 4.4
X *
X *
X * 
X */
X/* This software is Copyright 1991 by Stan Barber. 
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made. 
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk. 
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "rcstuff.h"
X#include "final.h"
X#include "search.h"
X#include "rn.h"
X#include "util.h"
X#include "term.h"
X#include "rcln.h"
X#include "INTERN.h"
X#include "ngsrch.h"
X
X#ifdef NGSORONLY
X    COMPEX ngcompex;
X#endif
X
void
ngsrch_init()
X{
X#ifdef ZEROGLOB
X    init_compex(&ngcompex);
X#endif	/* ZEROGLOB */
X    ;
X}
X
X#ifdef NGSEARCH
int
ng_search(patbuf,get_cmd)
char *patbuf;				/* if patbuf != buf, get_cmd must */
int get_cmd;				/*   be set to FALSE!!! */
X{
X    char *pattern;			/* unparsed pattern */
X    register char cmdchr = *patbuf;	/* what kind of search? */
X    register char *s;
X    bool backward = cmdchr == '?';	/* direction of search */
X
X    int_count = 0;
X    if (get_cmd && buf == patbuf)
X	if (!finish_command(FALSE))		/* get rest of command */
X	    return NGS_ABORT;
X    for (pattern = patbuf+1; *pattern == ' '; pattern++) ;
X    if (*pattern) {
X	ng_doread = FALSE;
X    }
X    s = rindex(pattern,cmdchr);
X    if (s != Nullch && *(s-1) != '\\') {
X	*s++ = '\0';
X	if (index(s,'r') != Nullch)
X	    ng_doread = TRUE;
X    }
X    if ((s = ng_comp(&ngcompex,pattern,TRUE,TRUE)) != Nullch) {
X					/* compile regular expression */
X	printf("\n%s\n",s) FLUSH;
X	return NGS_ERROR;
X    }
X    fputs("\nSearching...",stdout) FLUSH;	/* give them something to read */
X    fflush(stdout);
X    for (;;) {
X	if (int_count) {
X	    int_count = 0;
X	    return NGS_INTR;
X	}
X	if (backward) {
X	    if (ng > 0)
X		--ng;
X	    else
X		ng = nextrcline;
X	}
X	else {
X	    if (ng >= nextrcline)
X		ng = 0;
X	    else
X		++ng;
X	}
X	if (ng == current_ng)
X	    return NGS_NOTFOUND;
X	if (ng == nextrcline || toread[ng] < TR_NONE || !ng_wanted())
X	    continue;
X	if (toread[ng] == TR_NONE)
X	    set_toread(ng);
X	
X	if (toread[ng] > TR_NONE)
X	    return NGS_FOUND;
X	else if (toread[ng] == TR_NONE)
X	    if (ng_doread)
X		return NGS_FOUND;
X	    else
X		printf("\n[0 unread in %s--skipping]",rcline[ng]) FLUSH;
X    }
X}
X
bool
ng_wanted()
X{
X    return execute(&ngcompex,rcline[ng]) != Nullch;
X}
X#endif
X
X#ifdef NGSORONLY
char *
ng_comp(compex,pattern,RE,fold)
COMPEX *compex;
char *pattern;
bool_int RE;
bool_int fold;
X{
X    char ng_pattern[128];
X    register char *s = pattern, *d = ng_pattern;
X
X    if (!*s) {
X	if(compex->expbuf)
X	    return Nullch;			/* reuse old pattern */
X	else
X	    return "No previous search pattern";
X    }
X    for (; *s; s++) {
X	if (*s == '.') {
X	    *d++ = '\\';
X	    *d++ = *s;
X	}
X	else if (*s == '?') {
X	    *d++ = '.';
X	}
X	else if (*s == '*') {
X	    *d++ = '.';
X	    *d++ = *s;
X	}
X	else if (strnEQ(s,"all",3)) {
X	    *d++ = '.';
X	    *d++ = '*';
X	    s += 2;
X	}
X	else
X	    *d++ = *s;
X    }
X    *d = '\0';
X    return compile(compex,ng_pattern,RE,fold);
X}
X#endif
X
END_OF_FILE
if test 3430 -ne `wc -c <'ngsrch.c'`; then
    echo shar: \"'ngsrch.c'\" unpacked with wrong size!
fi
# end of 'ngsrch.c'
fi
if test -f 'only.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'only.c'\"
else
echo shar: Extracting \"'only.c'\" \(2852 characters\)
sed "s/^X//" >'only.c' <<'END_OF_FILE'
X/* $Id: only.c,v 4.4 1991/09/09 20:23:31 sob Exp sob $
X *
X * $Log: only.c,v $
X * Revision 4.4  1991/09/09  20:23:31  sob
X * release 4.4
X *
X *
X * 
X */
X/* This software is Copyright 1991 by Stan Barber. 
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made. 
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk. 
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "search.h"
X#include "util.h"
X#include "final.h"
X#include "ngsrch.h"
X#include "INTERN.h"
X#include "only.h"
X
void
only_init()
X{
X    ;
X}
X
void
setngtodo(pat)
char *pat;
X{
X    char *s;
X
X#ifdef ONLY
X    if (!*pat)
X	return;
X    if (maxngtodo < NGMAX) {
X	ngtodo[maxngtodo] = savestr(pat);
X#ifdef SPEEDOVERMEM
X#ifndef lint
X	compextodo[maxngtodo] = (COMPEX*)safemalloc(sizeof(COMPEX));
X#endif /* lint */
X	init_compex(compextodo[maxngtodo]);
X	compile(compextodo[maxngtodo],pat,TRUE,TRUE);
X	if ((s = ng_comp(compextodo[maxngtodo],pat,TRUE,TRUE)) != Nullch) {
X					    /* compile regular expression */
X	    printf("\n%s\n",s) FLUSH;
X	    finalize(1);
X	}
X#endif
X	maxngtodo++;
X    }
X#else
X    notincl("o");
X#endif
X}
X
X/* if command line list is non-null, is this newsgroup wanted? */
X
bool
inlist(ngnam)
char *ngnam;
X{
X#ifdef ONLY
X    register int i;
X#ifdef SPEEDOVERMEM
X
X    if (maxngtodo == 0)
X	return TRUE;
X    for (i=0; i<maxngtodo; i++) {
X	if (execute(compextodo[i],ngnam))
X	    return TRUE;
X    }
X    return FALSE;
X#else
X    COMPEX ilcompex;
X    char *s;
X
X    if (maxngtodo == 0)
X	return TRUE;
X    init_compex(&ilcompex);
X    for (i=0; i<maxngtodo; i++) {
X	if ((s = ng_comp(&ilcompex,ngtodo[i],TRUE,TRUE)) != Nullch) {
X					    /* compile regular expression */
X	    printf("\n%s\n",s) FLUSH;
X	    finalize(1);
X	}
X	
X	if (execute(&ilcompex,ngnam) != Nullch) {
X	    free_compex(&ilcompex);
X	    return TRUE;
X	}
X    }
X    free_compex(&ilcompex);
X    return FALSE;
X#endif
X#else
X    return TRUE;
X#endif
X}
X
X#ifdef ONLY
void
end_only()
X{
X    if (maxngtodo) {			/* did they specify newsgroup(s) */
X	int whicharg;
X
X#ifdef VERBOSE
X	IF(verbose)
X	    printf("\nRestriction %s%s removed.\n",ngtodo[0],
X		maxngtodo > 1 ? ", etc." : nullstr) FLUSH;
X	ELSE
X#endif
X#ifdef TERSE
X	    fputs("\nExiting \"only\".\n",stdout) FLUSH;
X#endif
X	for (whicharg = 0; whicharg < maxngtodo; whicharg++) {
X	    free(ngtodo[whicharg]);
X#ifdef SPEEDOVERMEM
X	    free_compex(compextodo[whicharg]);
X#ifndef lint
X	    free((char*)compextodo[whicharg]);
X#endif /* lint */
X#endif
X	}
X	maxngtodo = 0;
X    }
X}
X#endif
END_OF_FILE
if test 2852 -ne `wc -c <'only.c'`; then
    echo shar: \"'only.c'\" unpacked with wrong size!
fi
# end of 'only.c'
fi
if test -f 'rcstuff.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rcstuff.h'\"
else
echo shar: Extracting \"'rcstuff.h'\" \(2263 characters\)
sed "s/^X//" >'rcstuff.h' <<'END_OF_FILE'
X/* $Id: rcstuff.h,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
X *
X * $Log: rcstuff.h,v $
X * Revision 4.4.2.1  1991/12/01  18:05:42  sob
X * Patchlevel 2 changes
X *
X * Revision 4.4  1991/09/09  20:27:37  sob
X * release 4.4
X *
X *
X * 
X */
X/* This software is Copyright 1991 by Stan Barber. 
X *
X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
X * use this software as long as: there is no monetary profit gained
X * specifically from the use or reproduction of this software, it is not
X * sold, rented, traded or otherwise marketed, and this copyright notice is
X * included prominently in any copy made. 
X *
X * The author make no claims as to the fitness or correctness of this software
X * for any use whatsoever, and it is provided as is. Any use of this software
X * is at the user's own risk. 
X */
X
XEXT char **rcline INIT(NULL);/* pointers to lines of .newsrc */
XEXT ART_UNREAD *toread INIT(NULL);
X			/* number of articles to be read in newsgroup */
X			/* <0 => invalid or unsubscribed newsgroup */
X#define TR_ONE ((ART_UNREAD) 1)
X#define TR_NONE ((ART_UNREAD) 0)
X#define TR_UNSUB ((ART_UNREAD) -1)
X			/* keep this one as -1, some tests use >= TR_UNSUB */
X#define TR_BOGUS ((ART_UNREAD) -2)
X#define TR_JUNK ((ART_UNREAD) -3)
X
X#ifdef USETHREADS
X#define RCCHAR(ch) ((ch) == '0' ? ':' : (ch))
X#endif
X
XEXT char *rcchar INIT(NULL); /* holds the character : or ! while spot is \0 */
XEXT char *rcnums INIT(NULL); /* offset from rcline to numbers on line */
XEXT ACT_POS *softptr INIT(NULL);
X			/* likely ptr to active file entry for newsgroup */
XEXT bool paranoid INIT(FALSE);	/* did we detect some inconsistency in .newsrc? */
XEXT int maxrcline INIT(0);	/* current maximum # of lines in .newsrc */
X
bool	rcstuff_init ANSI((void));
bool	get_ng ANSI((char *,bool_int));	/* return TRUE if newsgroup can be found or added */
NG_NUM	add_newsgroup ANSI((char *,char_int));
X#ifdef RELOCATE
X    NG_NUM	relocate_newsgroup ANSI((NG_NUM,NG_NUM));/* move newsgroup around */
X#endif
void	list_newsgroups ANSI((void));
NG_NUM	find_ng ANSI((char *));	/* return index of newsgroup */
void	cleanup_rc ANSI((void));
void	sethash ANSI((NG_NUM));
int	hash ANSI((char *));
void	newsrc_check ANSI((void));
void	write_rc ANSI((void));
void	get_old_rc ANSI((void));
END_OF_FILE
if test 2263 -ne `wc -c <'rcstuff.h'`; then
    echo shar: \"'rcstuff.h'\" unpacked with wrong size!
fi
# end of 'rcstuff.h'
fi
if test -f 'threads.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'threads.c'\"
else
echo shar: Extracting \"'threads.c'\" \(2934 characters\)
sed "s/^X//" >'threads.c' <<'END_OF_FILE'
X/* $Id: threads.c,v 4.4.3.1 1991/11/22 04:12:21 davison Trn $
X**
X** $Log:	threads.c,v $
X** Revision 4.4.3.1  1991/11/22  04:12:21  davison
X** Trn Release 2.0
X** 
X*/
X
X#include "EXTERN.h"
X#include "common.h"
X#include "INTERN.h"
X#include "threads.h"
X
X#ifdef USETHREADS
X
extern char *threaddir;
X
X/* Change a newsgroup name into the name of the thread data file.  We
X** subsitute any '.'s in the group name into '/'s (unless LONG_THREAD_NAMES
X** is defined), prepend the path, and append the '/.thread' (or '.th') on to
X** the end.
X*/
char *
thread_name(group)
char *group;
X{
X    static char name_buff[MAXFILENAME];
X#ifndef LONG_THREAD_NAMES
X    char group_buff[512];
X    register char *ptr;
X
X    strcpy(group_buff, group);
X    ptr = group = group_buff;
X    while ((ptr = index(ptr, '.'))) {
X	*ptr = '/';
X    }
X#endif
X#ifdef SUFFIX
X    sprintf(name_buff, "%s/%s%s", threaddir, group, SUFFIX);
X#else
X    sprintf(name_buff, "%s/%s", threaddir, group);
X#endif
X
X    return name_buff;
X}
X
X/* Determine this machine's byte map for WORDs and LONGs.  A byte map is an
X** array of BYTEs (sizeof (WORD) or sizeof (LONG) of them) with the 0th BYTE
X** being the byte number of the high-order byte in my <type>, and so forth.
X*/
void
mybytemap(map)
BMAP *map;
X{
X    union {
X	BYTE b[sizeof (LONG)];
X	WORD w;
X	LONG l;
X    } u;
X    register BYTE *mp;
X    register int i, j;
X
X    mp = &map->w[sizeof (WORD)];
X    u.w = 1;
X    for (i = sizeof (WORD); i > 0; i--) {
X	for (j = 0; j < sizeof (WORD); j++) {
X	    if (u.b[j] != 0) {
X		break;
X	    }
X	}
X	if (j == sizeof (WORD)) {
X	    goto bad_news;
X	}
X	*--mp = j;
X	while (u.b[j] != 0 && u.w) {
X	    u.w <<= 1;
X	}
X    }
X
X    mp = &map->l[sizeof (LONG)];
X    u.l = 1;
X    for (i = sizeof (LONG); i > 0; i--) {
X	for (j = 0; j < sizeof (LONG); j++) {
X	    if (u.b[j] != 0) {
X		break;
X	    }
X	}
X	if (j == sizeof (LONG)) {
X	  bad_news:
X	    /* trouble -- set both to *something* consistent */
X	    for (j = 0; j < sizeof (WORD); j++) {
X		map->w[j] = j;
X	    }
X	    for (j = 0; j < sizeof (LONG); j++) {
X		map->l[j] = j;
X	    }
X	    return;
X	}
X	*--mp = j;
X	while (u.b[j] != 0 && u.l) {
X	    u.l <<= 1;
X	}
X    }
X}
X
X/* Transform each WORD's byte-ordering in a buffer of the designated length.
X*/
void
wp_bmap(buf, len)
WORD *buf;
int len;
X{
X    union {
X	BYTE b[sizeof (WORD)];
X	WORD w;
X    } in, out;
X    register int i;
X
X    if (word_same) {
X	return;
X    }
X    while (len--) {
X	in.w = *buf;
X	for (i = 0; i < sizeof (WORD); i++) {
X	    out.b[my_bmap.w[i]] = in.b[mt_bmap.w[i]];
X	}
X	*buf++ = out.w;
X    }
X}
X
X/* Transform each LONG's byte-ordering in a buffer of the designated length.
X*/
void
lp_bmap(buf, len)
LONG *buf;
int len;
X{
X    union {
X	BYTE b[sizeof (LONG)];
X	LONG l;
X    } in, out;
X    register int i;
X
X    if (long_same) {
X	return;
X    }
X    while (len--) {
X	in.l = *buf;
X	for (i = 0; i < sizeof (LONG); i++) {
X	    out.b[my_bmap.l[i]] = in.b[mt_bmap.l[i]];
X	}
X	*buf++ = out.l;
X    }
X}
X
X#endif /* USETHREADS */
END_OF_FILE
if test 2934 -ne `wc -c <'threads.c'`; then
    echo shar: \"'threads.c'\" unpacked with wrong size!
fi
# end of 'threads.c'
fi
echo shar: End of archive 2 \(of 13\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 13 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
