[net.sources] Yet Another Newsreader - vn

bobm@rtech.UUCP (Bob Mcqueer) (05/21/86)

For the last couple of years, I've used my own newsreader, which has
also enjoyed favor with some of my co-workers.  It is a completely
different interface than the other readers, its main goal being to
allow rapid scan of a great volume of news.  Many people have made
suggestions which found their way into this program.

Features:

	Once data has been accumulated, the interface is very rapid.
	You see whole screens of titles at a time, choosing the ones
	you want to read / save / print via cursor positioning,
	search strings, marks, or "choose everything".

	Update of .newsrc under user control, not tied to article presentation.

	Unpacks digest articles, lets you manipulate them as normal articles.

Since it IS a different interface, I would advise you to read the manual
page first, and save your old .newsrc the first time you run it, in case
you misunderstand or decide you don't like the way it works regarding updating
the .newsrc.

In a way, this reader reflects my personal biases, not providing some
features I could care less about, providing some things I or others
thought missing.  Favorable responses from a variety of people have
convinced me that my biases are shared.

Bob McQueer
{amdahl|sun|mtxinu}!rtech!bobm

cut here
-----------------------------------------
#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	README
#	vn.man
#	mf.nore
#	mf.re
#	config.h
#	head.h
#	reader.h
#	tty.h
#	tune.h
#	vn.h
# This archive created: Tue May 20 12:49:33 1986
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README'" '(5680 characters)'
if test -f 'README'
then
	echo shar: over-writing existing file "'README'"
fi
cat << \SHAR_EOF > 'README'
Installation procedure steps for UCB 4.2-like systems:

1) Edit file config.h, which defines system dependent parameters such as
spool directory, and so on.

2) decide which makefile to use, edit it to fill in the correct libraries
for your system.  See notes 2) below for explanation.

3) make vn

4) put the executable where you want it.  put the man page, vn.man
where you want it.  roff it with -man to print it out.

Notes:

1)
	If you modify the default mailer, poster, printer or editor, this is
	their invocation, ufile being a tempfile name.

	"mailer path <ufile" - path obtained from newsarticle, possibly
		modified by user.
	"poster <ufile" - thus the "inews -h" to get header lines from
		file, giving user a chance to modify headers.
	"printer files 2>/dev/null"
	"editor ufile"

	Should you change the hash table size, a few convenient prime numbers:

	211 503 809 1009 1201 1511 2003 2503 3001 4001 5003

	The hash table uses linear probe to resolve collisions.  Works well
	as long as the density stays reasonably low.  I would say to keep
	HASHMAX / HASHSIZE around 60%.  The number of hashtable entries will
	actually be the number of active newsgroups.

	You may also be interested in the header file "tune.h" which contains
	some sizing / performance affecting parameters.

2)
	There are two makefile templates, both very simple, because I
	want to make you think about whether you have the system V
	regular expression library or not.  If you have regex and
	regcmp (as opposed to re_exec and re_comp, the ucb regular
	expression library), I advise you to use them.  regex and
	regcmp are used because they have the ability to keep several
	regular expressions compiled at once.  The file "reg.c" is an
	implementation of regcmp and regex on top of the ucb calls,
	with a special procedure called "regfree" used in place of the
	generic "free" call used with regcmp / regex.  Use the system V
	calls if you have them available because:

		i) They should be faster than the reg.c code, which
		recompiles the "current" ucb string every time you
		switch regular expressions.

		ii) I briefly checked out reg.c once, and it seemed to
		work.  Our system has the "real" calls available, so I
		run with those.  reg.c hasn't been used much.

	If you have regex/regcomp:

		mf.re is the makefile template.  Fill in your local
		libraries (termcap), the library to find regex/regcmp in.
		This makefile defines "regfree" simply to be "free", and
		doesn't link the "reg" object.

	If you don't:

		mf.nore is the makefile template.  Fill in your local
		libraries (termcap).  This makefile pulls in the "reg"
		object, which implements regcmp and regex on top of
		the ucb library, with the special "regfree" call.

	ucb.c defines a couple more trivial system V calls.  Might
	as well use it anyhow.  We are currently running under Ultrix
	on a microvax, and in fact, the Ultrix tmpnam() doesn't work
	right.  Ultrix has regcmp/regex in the normal c runtime library,
	mf.re reflects this.

	Something pretty close to the current vn version used to run here
	on a VAX 780 under BSD 4.2.

SYSTEM V:

I would be interested if somebody would #ifdef this thing up for system V.
Very early versions ran on system V.  I would hope that it would not be
terribly difficult to convert.  "sig_set.c" contains all the signal handling.
"tty_set.c" contains all the ioctl() calls.  These two things would obviously
have to change drastically.  You would have to #define index() to be strchr().
The current working directory interface is different, if I remember properly,
envir_set.c bears study.  You should be able to dispense with ucb.c.

NEWS VERSIONS:

I know there's a lot of news versions running out there.  We seem to
be running something called B2.10.2, for those of you whom that signifies
anything to.  Something to look at is your "active" file.  I expect to
find a newsgroup followed by the high, then low, spooling numbers (followed
by a y/n for posting priveledge, which I don't care about).  Earlier news
versions used to only have a single spooling number.  vn is written to
handle this, assuming 0 for a low spool.  My basic assumptions are that
the "active" file gives the newsgroups and spooling information and that
articles will be numeric filenames living in the directory obtained by
replacing periods with slashes in the newsgroup, and prefixing the spool
directory.  I hope these really are "basic" assumptions that work across all
versions.  vn is intended to be highly fault-tolerant regarding what it
finds for header lines - it may not be able to make sense out of an "article",
but it's willing to let you look at it anyway.

RESOURCE USE:

vn should look like people sitting in an editor once it is done with its
reading phase.  During the reading phase, it is beating mercilessly on
the spooling directory, reading file after file.  I have thought from time
to time about having a daemon do this work periodically, building a master
file of title information for vn to access.  Its reading phase would then
be a "pause" rather than a "phase", with the penalty that you couldn't
read anything until the daemon had gotten around to it.

vn maintains a large temporary file containing the users page screens.
Again, it should look a lot like the user is using an editor which has
a temp file out there for its edit buffer.  MAX_C in "tune.h" can be
used to help control the size.

malloc() usage - Around 40 bytes per newsgroup is dynamically allocated,
plus storage for character strings and the current screen structure.
My guess would be on the order of 20K.  It's all "permanent" information
maintained for the entire session, hence unfreed.
SHAR_EOF
echo shar: extracting "'vn.man'" '(12738 characters)'
if test -f 'vn.man'
then
	echo shar: over-writing existing file "'vn.man'"
fi
cat << \SHAR_EOF > 'vn.man'
.TH VN 1 2/1/85
.UC
.SH NAME
vn - visual news reader
.SH SYNOPSIS
.I vn
.SH DESCRIPTION
.I Vn
is a news reader which uses the same 
.B .newsrc
file as
.I readnews
(1), but displays and interacts differently.  It is aimed at allowing
you to rapidly scan a large number of newsgroups, looking for something
you want to read.  The major premise is that you will be interested in a
small number of articles, but will be interested in keeping tabs on a large
number of newsgroups which may contain something interesting from time to time.
It also has the ability to unpackage digests.
.sp
.I Vn
supports the -n, -x and -t options of
.I readnews
(newsgroup, read all articles, and title).  In addition, there
is a -w (writer) option which works like -t, but is a search string to
apply to the "From" header line rather than the subject.  In the -n, -t
and -w options, a leading ! on the string is taken to mean negation.
The rest of the string is a regular expression for the -w and -t options.
.sp
For example:
.sp
-n net.dogs -w !fred -t [Bb]eagle
.sp
For articles in net.dogs about beagles written by somebody other
than fred.  Multiple -w -t options result in the logical "or" of the
-w's anded with the logical "or" of the -t's, whatever order you may specify
them in.  -n options allow the "all" convention, replacing ".all" by
".*" before using the regular expression calls.  -n options are processed
in order given, so that subsequent more specific -n's may partially
undo the effect of previous "alls".
.sp
Options may be given on the command line, in which case they will
supersede those given in the
.B .newsrc
file.  For command line -n options, the "!" unsubscriptions in
.B .newsrc
are also ignored.  This allows you to override all subscription information
by command line specification.
.sp
When
.I vn
is invoked,
there will be a pause (with an explanatory "reading" message and
a series of newsgroups) while vn reads the news.  The newsgroups listed
are ones articles are actually being found in.
The length of the pause depends
on how much news there is.  If there is a lot,
it may take a long time to get through the reading phase.
.sp
Once the reading phase is over, interaction is rapid.
If
.I vn
is backgrounded, it suppresses the "reading" output, so
that it will not halt on tty output until it is ready to begin showing
articles.
.sp
.I Vn
may show you a list of newsgroups which were not mentioned in the
.B .newsrc
file.  Records for these newsgroups will be added, whether
they were scanned for articles or not.  The first time
.I vn
is used, the list may be quite long and scroll off the screen.
Thereafter, there should only be a list when new newsgroups are
created.  This display serves to let you know of their existence,
or of something happening to your
.B .newsrc
file.
.sp
The basic display is a "page" which shows a newsgroup and a list of
titles, number of
lines, and authors for new articles.
Articles which have been updated in the
.B .newsrc
file  are flagged with an underscore preceding the article number.
You also have the ability to "mark" articles for the duration of a session,
shown with an asterisk (col. 1 and 2 are reserved for asterisk and
underscore respectively - 
in normal usage they will be blank, so that the casual user will probably
be unaware of their use until marking and updating are invoked)
.sp
There is a help menu to go with this page.
You may read articles, save them, send them to the printer, either by cursor
position, the whole page, or in specified sets.  Sets are specified either
as a set of article numbers, a regular expression to match the subject /
author / number of lines data on, or an asterisk to indicate the choice
of a set of previously marked articles.  Any of these methods also
accept a leading "!" to indicate negation.
.sp
By default, when you read articles only a couple of the dozen or so
header lines are
shown.  There is an option to allow you to see all the
header lines when you read articles.  The command controlling this toggles
between the two states.
.sp
A similar toggle is used to support ROT13.
.sp
.I Vn
is capable of manipulating digests.  The "d" command unpacks a digest,
and presents you with a page showing the unpacked articles, which can
be accessed as for articles on normal newsgroup pages.
When you leave the digest page(s), you reenter the normal flow of newsgroups.
Digests can also be read as normal articles, of course.
.sp
Order of pages is determined by
order of groups in
.B .newsrc.
Newsgroups which are not
mentioned in
.B .newsrc
will be added, as mentioned previously, and tacked onto the end.
Lines corresponding to non-existent newsgroups will be deleted.
You will probably want to run
.I vn
once, then edit
.B .newsrc
to the desired order of presentation.
.sp
Updating the data for
.B .newsrc
is under user control.  If you do
no "W", "w", "^w", o or O commands, no updating takes place, and you'll see the
articles again the next time you read news.
Breaks result in a "really quit?" query, so you can recover from noisy
lines and prompts for commands you didn't really mean.
If you quit without updating, you will be prompted to make sure you
don't want to do so.
.sp
Commands are single character (no return key required), except that
they may be preceded with numeric characters, which may have
some effect on their actions.  Commands which require further input
cause prompts for the information, this input being
terminated by return.  For prompted input, the erase and kill keys
work.
.sp
.ce 1
Command Menu For Page:
.sp
.nf
[...] = effect of optional number preceding command
pipes are specified by filenames beginning with |
articles specified as a list of numbers, title search string, or
	* to specify marked articles.  ! may be used to negate any

	 q - quit
	 k - move up [number of lines]
	 j - move down [number of lines]
 <back sp> - previous page [number of pages]
  <return> - next page [number of pages]
	 d - unpack digest
	 r - read article [number of articles]
   <space> - read article (alternate 'r')
	 R - read all articles on page
 control-r - specify articles to read
	 s - save or pipe article [number of articles]
	 S - save or pipe all articles on page
 control-s - specify articles to save
 control-t - specify articles to save (alternate ctl-s)
	 p - print article [number of articles]
	 P - print all article on page
 control-p - specify articles to print
	 w - update .newsrc status to cursor
	 W - update .newsrc status for whole newsgroup
 control-w - update .newsrc status for all pages displayed
	 o - recover original .newsrc status for newsgroup
	 O - recover all original .newsrc status
	 # - display count of groups and pages - shown and total
	 % - list newsgroups with new article, updated counts
	 n - specify newsgroup to display and/or resubscribe to
	 u - unsubscribe from group
	 x - mark/unmark article [number of articles]
	 * - mark/unmark article [number of articles]
	 X - erase marks on articles
	 h - toggle flag for display of headers when reading
	 z - toggle rotation for reading
<formfeed> - redraw screen
	 ! - escape to UNIX to execute a command
	 ? - show this help menu
.fi
.sp
When you read articles, there is another help menu, for advancing through
the articles, replying, posting followups, and saving the
articles.  Breaks may be used to
stop the output of an article if you decide that you didn't really
want to read it.  You can jump from the reading portion back to either
page you came from or the NEXT page.
.sp
For replying and posting followups, you will be thrown into an editor
to create the reply or article.
The article will be included in the file you are editing, marked with
"> "'s for excerpting in your reply or followup.  After you exit the
editor, you are prompted to make sure you still want to post or reply,
so you can abort.
.sp
For the "mail reply" choice, you will be shown the address taken from
the article, and you may specify a different one.  This is done with
the article you have been reading still on the screen so that you
may copy the authors suggested path, if present.
.sp
The editor is determined by your EDITOR variable, as for
.I postnews.
If EDITOR is not set, you get
.I vi,
or the default determined at your site.
.sp
.ce 1
Reading menu:
.sp
.nf
         n - next article, if any
         q - quit reading articles, if any more to read
         Q - quit reading, and turn to next page of articles
         r - rewind article to beginning
  <return> - next line
         m - send mail to author of article
         f - post followup to article
         s - save article in a file
         ? - see this help menu
	 z - toggle rotation flag
	 h - toggle header suppression flag

 anything else to continue normal reading
.fi
.sp
.SH FILES
.TP 24
/usr/tmp/*
One temporary file created by
.I tmpnam
(3), and immediately unlinked,
remains open in update mode for duration of session.
Disk space freed by system close of file descriptor at exit.
Can be large, as this file contains the "page" displays.
Temporary files also created by
.I tmpnam
(3) for mailing replies, posting followups and creating digest "articles".
.TP 24
(login directory)/.newsrc
news status file.  Updated following session.  See NEWSRC environment variable.
.TP 24
(login directory)/*.vn
One temporary file created by
.I tmpnam
(3) while updating the .newsrc file.  If the update fails, you are informed,
and this file
may be used to recover the last update.  Unlinked following successful update.
.TP 24
(spool directory)/*
spooling directories containing articles.
.TP 24
/usr/lib/news/active
active newsgroup list.
.SH "ENVIRONMENT VARIABLES"
.TP 24
PS1
used to present prompt string for command on unix escape.
defaults to "$ "
.TP 24
EDITOR
editor used for mailing replies and posting followups.
defaults to "ed".
.TP 24
POSTER
posting program for followups.  defaults to "inews -h".
.TP 24
MAILER
used when mailing replies.  defaults to "/bin/mail".
.TP 24
PRINTER
program used with the print commands for sending articles to
the printer.  defaults to "lpr -p".
.TP 24
NEWSRC
if set, can be used to override the choice of ".newsrc" as the
name for the status file.  Name will still be used relative to
the login directory.
.SH DIAGNOSTICS
user error messages.  self explanatory.
.SH AUTHOR
R. L. McQueer
.SH BUGS
Note that
.I readnews
will rearrange the order of
.B .newsrc.
If you
interleave use of it with
.I vn,
order selection gets hosed.
.sp
If you've really taken advantage of the ability of readnews to skip
articles in the middle of the spooling numbers, be warned that
.I vn
doesn't have it, and will
assume you've read the articles in the middle.
.sp
If the
.B .newsrc
file indicates that you've read articles in a newsgroup with a higher
number than the current spooling number for that newsgroup,
.I vn
will show you the entire newsgroup.  This is intended for recovery in
cases where article spooling has been reset, or to avoid missing articles
because you just changed machines and didn't bother to edit your
.B .newsrc
file.  Rather than miss stuff, you'll see some old stuff again.
.sp
Sometimes a "break" during reading an article will not only halt the
article but suppress the prompt.  A command character will work anyway.
.sp
If a prompt to be displayed on the dialogue line
contains non-printing sequences, stuff on the
line may not get erased when you are prompted, because
.I vn
thinks the string is long enough to overprint its current contents.
This usually comes up when you have escape sequences in your UNIX
prompt, and do a "!" command.
The "overprint" check is made to save a clear-line sequence (kludged in
by overprinting to the end with blanks if the terminal doesn't
have one - annoying at 1200 baud).
.sp
Output during the reading phase which was suppressed by backgrounding
.I vn
does not get started by foregrounding it again without doing a
control-z and a second foreground (it doesn't figure out its background /
foreground status on each output - only on startup and while handling
the SIGTSTP signal).  Actually, this results in a method for having
.I vn
do its reading phase silently in the foreground without redirecting
output, should such a thing be desired.
.sp
Very many -w or -t options cause SLOW reading phases.  It is reccomended
that these be used only when reading a few specific groups.
.sp
Digest extraction will split a single article into several if it contains
embedded ---- lines, the normal separator between articles in digests.
They will all have identical titles.
Digest extraction may not work with human built digests which don't
use the expected syntax for joining articles.  mod.computers.ibm-pc
and mod.computers.mac were used as models for the feature.
SHAR_EOF
echo shar: extracting "'mf.nore'" '(229 characters)'
if test -f 'mf.nore'
then
	echo shar: over-writing existing file "'mf.nore'"
fi
cat << \SHAR_EOF > 'mf.nore'
CFLAGS=	-O
LIBS= -ltermcap

OBJS=	hash.o groupdir.o envir_set.o newsrc.o pagefile.o reader.o storage.o sig_set.o term_set.o tty_set.o userlist.o vn.o vnglob.o digest.o strings.o ucb.o reg.o

vn:	$(OBJS)
	cc -o vn $(OBJS) $(LIBS)
SHAR_EOF
echo shar: extracting "'mf.re'" '(256 characters)'
if test -f 'mf.re'
then
	echo shar: over-writing existing file "'mf.re'"
fi
cat << \SHAR_EOF > 'mf.re'
CFLAGS=	-O -Dregfree=free
REGLIB=
LIBS= -ltermcap

OBJS=	hash.o groupdir.o envir_set.o newsrc.o pagefile.o reader.o storage.o sig_set.o term_set.o tty_set.o userlist.o vn.o vnglob.o digest.o strings.o ucb.o

vn:	$(OBJS)
	cc -o vn $(OBJS) $(REGLIB) $(LIBS)
SHAR_EOF
echo shar: extracting "'config.h'" '(745 characters)'
if test -f 'config.h'
then
	echo shar: over-writing existing file "'config.h'"
fi
cat << \SHAR_EOF > 'config.h'
/*
**	HASHMAX is in effect the number of newsgroups allowed.
**	HASHMAX MUST be less than HASHSIZE.
**	HASHSIZE should be prime - size of hash table newsgroups
**		are entered in, linear probe to resolve collisions
**		(HASHMAX / HASHSIZE = max. density).
*/
#define HASHMAX 500
#define HASHSIZE 809

#define DEF_ED "/usr/ucb/vi"	/* editor to use if no EDITOR variable */
#define DEF_PS1 "$ "		/* ! command prompt if no PS1 */
#define DEF_SAVE "vn.save"	/* save file */
#define DEF_MAIL "/bin/mail"	/* mailer */

#define DEF_PRINT "/usr/ucb/lpr"		/* print command */
#define DEF_POST "/usr/lib/news/inews -h"	/* followup posting command */

#define DEF_NEWSRC ".newsrc"

#define SPOOLDIR "/usr/spool/news"
#define ACTFILE "/usr/lib/news/active"
SHAR_EOF
echo shar: extracting "'head.h'" '(564 characters)'
if test -f 'head.h'
then
	echo shar: over-writing existing file "'head.h'"
fi
cat << \SHAR_EOF > 'head.h'
/*
	header lines and associated lengths.  Strings should
	actually be used once in strings.c
*/ 
#define RHEAD "References: "
#define RHDLEN 12
#define MHEAD "Message-ID: "
#define MHDLEN 12
#define PHEAD "Path: "
#define PHDLEN 6
#define DHEAD "Date: "
#define DHDLEN 6
#define FHEAD "From: "
#define FHDLEN 6
#define FTHEAD "Followup-To: "
#define FTHDLEN 13
#define THEAD "Subject: "
#define THDLEN 9
#define LHEAD "Lines: "
#define LHDLEN 7
#define NHEAD "Newsgroups: "
#define NHDLEN 12

#define CHFIRST "FSL"	/* first char's of those used in page display */
SHAR_EOF
echo shar: extracting "'reader.h'" '(1174 characters)'
if test -f 'reader.h'
then
	echo shar: over-writing existing file "'reader.h'"
fi
cat << \SHAR_EOF > 'reader.h'
#define PAGE_MID ":more (%2d%%):"
#define PAGE_NEXT ":next article:"
#define PAGE_END ":end:"
#define PAGE_NO ":?:"
#define PPR_MAX 18	/* maximum length of PAGE prompts */

/*
	reading commands: no control chars, add help message to helppg
	SAVE, HEADTOG and SETROT are also recognized
*/
#define HPG_HEAD "toggle header print flag"
#define HPG_ROT "toggle rotation"
#define HPG_SAVE "save article in a file"
#define PG_NEXT 'n'
#define HPG_NEXT "next article, if any"
#define PG_QUIT 'q'
#define HPG_QUIT "quit reading articles, if any more to read"
#define PG_FLIP 'Q'
#define HPG_FLIP "quit reading, and turn to next page of articles"
#define PG_FOLLOW 'f'
#define HPG_FOLLOW "post followup to article"
#define PG_REPLY 'm'
#define HPG_REPLY "send mail to author of article"
#define PG_HELP '?'
#define HPG_HELP "see this help menu"
#define PG_REWIND 'r'
#define HPG_REWIND "rewind article to beginning"
#define PG_WIND 'e'
#define HPG_WIND "seek to end of article (to next/end prompt)"
#define PG_STEP '\n'
#define HPG_STEP "next line"
#define HPG_DEF "\n anything else to continue normal reading"
#define HPG_EDEF "\n anything else to try reading next article, if any"
SHAR_EOF
echo shar: extracting "'tty.h'" '(286 characters)'
if test -f 'tty.h'
then
	echo shar: over-writing existing file "'tty.h'"
fi
cat << \SHAR_EOF > 'tty.h'
/*
	term_set and tty_set codes
*/
#define MOVE 100
#define ERASE 101
#define START 102
#define STOP 103
#define RUBSEQ 104
#define ZAP 105
#define ONREVERSE 106
#define OFFREVERSE 107

#define RAWMODE 200
#define COOKED 201
#define SAVEMODE 202
#define RESTORE 203
#define BACKSTOP 204
SHAR_EOF
echo shar: extracting "'tune.h'" '(2173 characters)'
if test -f 'tune.h'
then
	echo shar: over-writing existing file "'tune.h'"
fi
cat << \SHAR_EOF > 'tune.h'
/*
**	buffer size needed for tmpnam()
*/
#ifndef L_tmpnam
#define L_tmpnam 48
#endif

/*
**	maximum number of columns on terminal.  If made smaller, there
**	will be a savings in the size of the temporary file used
**	for holding displays, at the penalty of not being able to use
**	the entire screen width on terminals actually possessing more
**	columns than this.  A block roughly on the order of this value
**	times the number of lines the terminal has is maintained in
**	the temp file, and read / written as displays are interacted
**	with.  MIN_C put here because MAX_C > MIN_C.  MIN_C is the minumum
**	number of columns for which a "reasonable" display can be produced.
**	before making it smaller, look at all uses of C_allow and variable
**	to see that a setting that small won't screw up array bounds.
*/
#define MAX_C 132
#define MIN_C 36

/*
**	large size for general purpose local buffers.  only used in automatic
**	variable declarations.  Used with fgets for buffer size when reading
**	file records, to hold pathnames, commands, etc.  Reduce if you blow
**	out stack storage.  If reduced too far, will eventually show up
**	as syntax errors on reading .newsrc's and the active list, and
**	scrozzled article information arising from truncated header lines.
**	The reply path line will probably be the first thing to cause trouble.
**	Look through the reader to find the worst case chain of declarations
**	(on the order of 12 or so is probably the max).
*/
#define RECLEN 1200

/*
**	to protect against reading entire articles to find non-existent header
**	lines if an article should be hosed, only a limited number of records
**	are searched.  Should be big enough to get down to the "Lines" header
**	entry on legitimate articles.
*/
#define HDR_LINES 18	/* records of article to search for header line */

/* these determine some static array sizes */
#define OPTLINES 60	/* maximum number of option lines in .newsrc */
#define NUMFILTER 24	/* max number of filters on articles */

/* block sizes for allocation routines */
#define STRBLKSIZE 1800	/* string storage allocation block */
#define NDBLKSIZE 50	/* NODE structures to allocate at a time */
SHAR_EOF
echo shar: extracting "'vn.h'" '(4193 characters)'
if test -f 'vn.h'
then
	echo shar: over-writing existing file "'vn.h'"
fi
cat << \SHAR_EOF > 'vn.h'
#include "tune.h"

#define TRUE 1
#define FALSE 0

#define NARGOPT "lprxfuMs"

#define FIL_AUTHOR 'w'
#define FIL_TITLE 't'

/*
	newsrc states
*/
#define NEWS_ON ':'
#define NEWS_OFF '!'

/* bit flags for state of newsgroup */
#define FLG_SCAN 1
#define FLG_SUB 2
#define FLG_PAGE 4
#define FLG_WRIT 8
#define FLG_SPEC 16

#define LIST_SEP " 	,"
#define ED_MARK '>'
#define ART_MARK '*'
#define ART_WRITTEN '_'
#define ART_UNWRITTEN ' '

#define FPFIX "Re: "

#define ANFORM ":%s - ? for help:\n"
#define ANFLINES 1
#define NOFORM "can't open article %s\n"
#define NEWGFORM "groups not mentioned in %s:\n"
#define SAVFORM "save file (%s) ? "
#define UDKFORM "undefined key (x%x) - ? for help"

/*
	page display format and dependent parameters
*/
#define HFORMAT "\n%s (page %d of %d):"
#define DHFORMAT "\n%s (DIGEST EXTRACTION):"
#define TFORMAT "%s ~ %s %s"
#define AFORMAT "\n%c%c%d) "	/* begin with newline - see show routine */
#define CFORMAT "page %d of %d (%d shown), newsgroup %d of %d"
#define RECBIAS 2	/* lines before articles - depends on HFORMAT */
#define AFLEN 5		/* min. char. in article id - depends on AFORMAT */
#define WRCOL 1		/* column of written mark.  depends on AFORMAT */
#define INFOLINE 0	/* HFORMAT TFORMAT leaves for use */

/*
	command characters - don't use numerics
	ALTSAVE is a hack to avoid having to use ctl-s - XON/XOFF.
	Wanted to preserve "s" pneumonic and lower / control /cap
	convention.
*/
#define DIGEST 'd'
#define UP 'k'
#define DOWN 'j'
#define FORWARD '\012'
#define BACK '\010'
#define READ 'r'
#define ALTREAD ' '
#define READALL 'R'
#define READSTRING '\022'
#define SAVE 's'
#define SAVEALL 'S'
#define SAVESTRING '\023'
#define ALTSAVE '\024'
#define PRINT 'p'
#define PRINTALL 'P'
#define PRINTSTRING '\020'
#define MARK 'x'
#define UNMARK 'X'
#define REDRAW '\014'
#define QUIT 'q'
#define SSTAT '#'
#define GRPLIST '%'
#define ORGGRP 'o'
#define ORGSTAT 'O'
#define UPDATE 'w'
#define UNSUBSCRIBE 'u'
#define UPALL 'W'
#define UPSEEN '\027'
#define UNESC '!'
#define NEWGROUP 'n'
#define HEADTOG 'h'
#define SETROT 'z'
#define HELP '?'
#define HELP_HEAD "[...] = effect of optional number preceding command\n\
pipes are specified by filenames beginning with |\n\
articles specified as a list of numbers, title search string, or\n\
	* to specify marked articles.  ! may be used to negate any\n"

#define HHLINES 5	/* lines (CRs + 1) contained in HELP_HEAD */

/*
	state flags for handling breaks / values for sig_set calls.
	BRK_IN, BRK_SESS, BRK_READ and BRK_OUT are the states.  All
	but BRK_INIT are used as calls to sig_set.  BRK_RFIN indicates
	a return from BRK_READ to BRK_SESS (no jump location passed),
*/
#define BRK_INIT 0		/* initial value, indicating uncaught signals */
#define BRK_IN 1		/* in NEWSRC / article scanning phase */
#define BRK_SESS 2		/* in page interactive session */
#define BRK_READ 3		/* reading articles */
#define BRK_RFIN 4		/* finished reading, return to old mode */
#define BRK_OUT 5		/* NEWSRC updating phase */

#define BRK_PR "really quit ? "
#define BRK_MSG "\nQUIT (signal %d)"

/*
	filter structure for article screening:

	rex - regular expression
	hcomp - header line to compare against regular expression
	neg - negation flag indicating "not matching"
*/
typedef struct
{
	char *rex,hcomp,neg;
} FILTER;

/*
	newsgroup structure (node of hash table)
	nd_name - name of newsgroup (key to reach node by)
	pnum - page number
	pages - number of pages for news display
	rdnum - articles read
	orgrd - original articles read number
	pgshwn - pages shown mask
	pgrd - article number on highest conecutively shown page
	art - articles in group
	state - status
*/
typedef struct
{
	char *nd_name;
	int pnum,pages,art,rdnum,orgrd,pgrd;
	unsigned long pgshwn;
	unsigned state;
} NODE;

/*
	newsgroup information for page display
	name - of group
	group - pointer to table entry
	artnum - number of articles
*/
typedef struct
{
	char *name;
	NODE *group;
	int artnum;
} HEAD;

/*
	article information - id (spool) number, title string, mark, written.
*/
typedef struct
{
	int art_id;
	char art_mark;
	char art_written;
	char art_t[MAX_C-AFLEN];
} BODY;

typedef struct
{
	HEAD h;
	BODY *b;
} PAGE;
SHAR_EOF
#	End of shell archive
exit 0