vn 12/86 (part 4 of 4) - remaining source files

Bob Mcqueer bobm at rtech.UUCP
Fri Jan 2 05:50:14 AEST 1987


Bob McQueer
{amdahl, sun, mtxinu, hoptoad, cpsc6a}!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:
#	digest.c
#	envir_set.c
#	groupdir.c
#	hash.c
#	pagefile.c
#	reg.c
#	sig_set.c
#	storage.c
#	strings.c
#	strtok.c
#	term_set.c
#	tmpnam.c
#	tty_set.c
#	userlist.c
#	vnglob.c
# This archive created: Thu Jan  1 11:15:28 1987
export PATH; PATH=/bin:$PATH
echo shar: extracting "'digest.c'" '(5027 characters)'
if test -f 'digest.c'
then
	echo shar: will not over-write existing file "'digest.c'"
else
cat << \SHAR_EOF > 'digest.c'
/*
** vn news reader.
**
** digest.c - digest unpacking routines
**
** see copyright disclaimer / history in vn.c source file
*/

#include <stdio.h>
#include "config.h"
#include "vn.h"
#include "head.h"

extern int Digest;
extern int L_allow;
extern int C_allow;
extern PAGE Page;

extern char *F_head, *T_head, *L_head, *D_head;

digest_page (idx,skip)
int idx;
{
	char *ptr,name[24],*title,*index();
	FILE *fp;
	int i,len;
	char subj[RECLEN],date[RECLEN],from[RECLEN],junk[RECLEN],*str_store();
	long pos;

	Digest = Page.b[idx].art_id;
	sprintf (name,"%d", Digest);

	if ((fp = fopen(name,"r")) == NULL)
		return (-1);

	subj[0] = date[0] = from[0] = junk[0] = '\0';

	skip_header (fp);

	/* skip over some articles if requested to */
	for (i=skip; i > 0; --i)
	{
		if (dig_advance(fp,from,subj,date,junk,&pos) < 0)
			return (-1);
	}

	/* every new call to a digest Page "loses" a small amount of storage */
	title = str_store(Page.b[idx].art_t);
	if ((ptr = index(title,'~')) != 0)
		*ptr = '\0';
	title [C_allow - 20] = '\0';

	for (i=0; i < L_allow &&
			(len = dig_advance(fp,from,subj,date,junk,&pos)) >= 0; ++i)
	{
		Page.b[i].art_id = i+1+skip;
		Page.b[i].art_mark = ' ';
		subj [C_allow] = '\0';
		from [C_allow] = '\0';
		sprintf (name,"%d",len);
		form_title (date,subj,name,from,100);
		strcpy (Page.b[i].art_t,date);
	}

	fclose (fp);

	if (i == 0)
		return (-1);

	Page.h.name = title;
	Page.h.artnum = i;
	return (i);
}

/*
	returns name of file containing "article", NULL for failure
*/
char * digest_extract (s,art)
char *s;
int art;
{
	char name[24];
	FILE *fout,*fin;
	char subj[RECLEN],date[RECLEN],from[RECLEN],bufr[RECLEN];
	char extra[RECLEN];
	char *index();
	long pos;
	int lines;

	sprintf (name,"%d", Digest);
	if ((fin = fopen(name,"r")) == NULL)
		return (NULL);

	for (skip_header (fin); art > 0; --art)
		if ((lines = dig_advance(fin,from,subj,date,extra,&pos)) < 0)
		{
			fclose (fin);
			return (NULL);
		}

	tmpnam(s);

	if ((fout = fopen(s,"w")) == NULL)
	{
		fclose (fin);
		unlink (s);
		return (NULL);
	}

	fseek(fin,0L,0);

	while (fgets(bufr,RECLEN-1,fin) != NULL && index(bufr,':') != NULL)
	{
		if (strncmp(bufr,F_head,FHDLEN) == 0)
		{
			fprintf (fout,"%s%s\n",F_head,from);
			continue;
		}
		if (strncmp(bufr,T_head,THDLEN) == 0)
		{
			fprintf (fout,"%s%s\n",T_head,subj);
			continue;
		}
		if (strncmp(bufr,D_head,DHDLEN) == 0)
		{
			fprintf (fout,"%s%s\n",D_head,date);
			continue;
		}
		/* defer line count header - it comes last */
		if (strncmp(bufr,L_head,LHDLEN) == 0)
			continue;
		fprintf (fout,"%s",bufr);
	}

	/* toss in extra header lines, line count header, extra newline */
	fprintf (fout,"%s%s%d\n\n",extra,L_head,lines);

	fseek (fin,pos,0);

	while (fgets(bufr,RECLEN-1,fin) != NULL && strncmp(bufr,"--------",8) != 0)
		fprintf(fout,"%s",bufr);

	fclose (fin);
	fclose (fout);
	return (s);
}

dig_list (s)
char *s;
{
	char *ptr,*out,*new,ns[L_tmpnam],tmp[RECLEN],*strtok();
	int i;

	prinfo ("Extracting articles .....");
	strcpy (tmp,s);
	out = s;

	for (ptr = strtok(tmp," "); ptr != NULL; ptr = strtok(NULL," "))
	{
		i = atoi(ptr);
		if ((new = digest_extract(ns,i)) != NULL)
		{
			sprintf (out,"%s ",new);
			out += strlen(new) + 1;
		}
	}

	*out = '\0';

	if (*s == '\0')
		strcpy (s,"NULLDIGEST");
}

dig_ulist (s)
char *s;
{
	char *strtok();
	for (s = strtok(s," "); s != NULL; s = strtok(NULL," "))
		unlink (s);
}

/*
	returns # lines in article, -1 for failure
	scans past article, returns position of start.
	also returns "extra" header lines encountered, WITH newlines.
*/
static dig_advance (fp,from,subj,date,extra,pos)
FILE *fp;
char *from,*subj,*date,*extra;
long *pos;
{
	char buf[RECLEN];
	char *ptr, *index();
	int len,state,lcount;

	lcount = state = 0;
	*extra = '\0';

	while (fgets(buf,RECLEN-1,fp) != NULL)
	{
		buf[(len = strlen(buf) - 1)] = '\0';
		for (--len ; len >= 0 && buf[len] == ' ' || buf[len] == '\t'; --len)
			buf[len] = '\0';
		++len;

		switch(state)
		{
		case 0:
			/* skip blank lines before header */
			if (len == 0)
				break;
			state = 1;	/* fall through */
		case 1:
			if (strncmp(buf,F_head,FHDLEN) == 0)
			{
				strcpy (from,buf+FHDLEN);
				break;
			}
			if (strncmp(buf,T_head,THDLEN) == 0)
			{
				strcpy (subj,buf+THDLEN);
				break;
			}
			if (strncmp(buf,D_head,DHDLEN) == 0)
			{
				strcpy (date,buf+DHDLEN);
				break;
			}
			/* put wierd header lines in extra */
			if ((ptr = index(buf,':')) != NULL)
			{
				*ptr = '\0';
				if (index(buf, ' ') == NULL)
				{
					*ptr = ':';
					sprintf(extra,"%s\n",buf);
					extra += strlen(extra);
					break;
				}
				*ptr = ':';
			}
			state = 2;

			/* remember the newline we lopped off */
			*pos = ftell(fp)-strlen(buf)-1;	/* fall through */
		case 2:
			++lcount;
			if (strncmp("--------",buf,8) == 0)
			{
				--lcount;
				return (lcount);
			}
			break;
		}
	}

	return (-1);
}

static skip_header (fp)
FILE *fp;
{
	char buf[RECLEN];

	while (fgets(buf,RECLEN-1,fp) != NULL)
		if (strncmp("--------",buf,8) == 0)
			break;
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'envir_set.c'" '(2931 characters)'
if test -f 'envir_set.c'
then
	echo shar: will not over-write existing file "'envir_set.c'"
else
cat << \SHAR_EOF > 'envir_set.c'
/*
** vn news reader.
**
** envir_set.c - routine to obtain pertinent environment variable settings
**		and set up file / directory names
**
** see copyright disclaimer / history in vn.c source file
*/

#include <stdio.h>
#include <pwd.h>
#include <sys/param.h>
#include "config.h"

extern char *Editor,*Ps1,*Mailer,*Printer,*Poster;
extern char *Onews, *Newsrc, *Orgdir, *Savedir, *Ccfile;	/* path names */
extern char Cxitop[], Cxitor[], Cxrtoi[], Cxptoi[];

#ifdef SYSV
extern char *getcwd();
#define getwd(a) getcwd(a,sizeof(a))
#define	MAXPATHLEN 240
#else
extern char *getwd();
#endif

/*
	environment variable, original directory string setup.
*/

envir_set ()
{
 	char dbuf [MAXPATHLEN], *rcname, *ccname, *keyxln;
	char *getenv(), *getcwd(), *str_store();
	struct passwd *ptr, *getpwuid();

	if ((Ps1 = getenv("PS1")) == NULL)
		Ps1 = DEF_PS1;
	if ((Editor = getenv("EDITOR")) == NULL)
		Editor=DEF_ED;
	if ((Mailer = getenv("MAILER")) == NULL)
		Mailer=DEF_MAIL;
	if ((Poster = getenv("POSTER")) == NULL)
		Poster=DEF_POST;
	if ((Printer = getenv("PRINTER")) == NULL)
		Printer=DEF_PRINT;
	if ((rcname = getenv("NEWSRC")) == NULL)
		rcname=DEF_NEWSRC;
	if ((ccname = getenv("CCFILE")) == NULL)
		ccname=DEF_CCFILE;
	if ((keyxln = getenv("VNKEY")) == NULL)
		keyxln=DEF_KEYXLN;
	Savedir = getenv("VNSAVE");

	/*
		set original directory strings.  create empty Newsrc if it doesn't exist
	*/

	ptr = getpwuid (getuid());
	if ((Orgdir = getwd(dbuf)) == NULL)
		printex ("cannot stat pwd");
	Orgdir = str_store (Orgdir);
	if (Savedir == NULL)
		Savedir = Orgdir;
	if (*rcname != '/')
	{
		sprintf (dbuf, "%s/%s",ptr->pw_dir,rcname);
		Newsrc = str_store (dbuf);
	}
	else
		Newsrc = str_store (rcname);
	if (*ccname != '/')
	{
		sprintf (dbuf, "%s/%s",ptr->pw_dir,ccname);
		Ccfile = str_store (dbuf);
	}
	else
		Ccfile = str_store (ccname);
	sprintf (dbuf, "%s/%s%s",ptr->pw_dir,".vn","XXXXXX");
	Onews = str_store (mktemp(dbuf));
	if (access (Newsrc,0) != 0)
		creat (Newsrc,0666);

	if (*keyxln != '/')
	{
		sprintf(dbuf, "%s/%s",ptr->pw_dir,keyxln);
		set_kxln(dbuf);
	}
	else
		set_kxln(keyxln);
}

static
set_kxln(fname)
char *fname;
{
	FILE *fp;
	int i;
	char bufr[80];
	char in,out,*ptr;
	char *index(), xln_str();

	for (i=0; i < 128; ++i)
		Cxitop[i] = Cxitor[i] = Cxptoi[i] = Cxrtoi[i] = i;

	if ((fp = fopen(fname,"r")) != NULL)
	{
		while(fgets(bufr,79,fp) != NULL)
		{
			if (strncmp(bufr+1,"==",2) == 0)
				ptr = bufr+2;
			else
				ptr = index(bufr+1,'=');
			if (ptr == NULL)
				continue;
			*ptr = '\0';
			++ptr;
			in = xln_str(bufr+1);
			out = xln_str(ptr);
			switch(bufr[0])
			{
			case 'r':
			case 'R':
				Cxrtoi[out] = in;
				Cxitor[in] = out;
				break;
			case 'p':
			case 'P':
				Cxptoi[out] = in;
				Cxitop[in] = out;
			default:
				break;
			}
		}
		fclose(fp);
	}
}

static char
xln_str(s)
char *s;
{
	if (*s < '0' || *s > '9')
		return(*s & 0x7f);
	return((char)(atoi(s) & 0x7f));
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'groupdir.c'" '(686 characters)'
if test -f 'groupdir.c'
then
	echo shar: will not over-write existing file "'groupdir.c'"
else
cat << \SHAR_EOF > 'groupdir.c'
/*
** vn news reader.
**
** groupdir.c - translation between newsgroup name and directory
**
** see copyright disclaimer / history in vn.c source file
*/

#include <stdio.h>
#include "config.h"
#include "vn.h"

extern PAGE Page;

/*
	g_dir converts newsgroup name to directory string
*/
g_dir(s,t)
char *s,*t;
{
	char *ptr, *index();
	sprintf (t,"%s/%s",SPOOLDIR,s);
	for (ptr=t+strlen(SPOOLDIR)+1; (ptr = index(ptr,'.')) != NULL; *ptr = '/')
		;
}


/*
	change directory to group
*/
cd_group ()
{
	char dbuf [RECLEN];
	g_dir ((Page.h.group)->nd_name,dbuf);
	if (chdir(dbuf) < 0)
	{
		Page.h.artnum = 1;
		Page.b[0].art_id = 0;
		strcpy (Page.b[0].art_t, "CANNOT FIND NEWSGROUP");
	}
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'hash.c'" '(1842 characters)'
if test -f 'hash.c'
then
	echo shar: will not over-write existing file "'hash.c'"
else
cat << \SHAR_EOF > 'hash.c'
/*
** vn news reader.
**
** hash.c - hash table routines
**
** see copyright disclaimer / history in vn.c source file
*/

#include <stdio.h>
#include "config.h"
#include "tune.h"
#include "vn.h"

/*
** hash table manipulation routines:
**	also sets Ncount, allocates Newsorsder array, and sets Newsorder
**	initially to order newsgroups were entered in (active file order)
*/

extern int Ncount;
extern NODE **Newsorder;

static NODE *Tab [HASHSIZE];	/* hash Table */

hashinit ()
{
	int i;
	for (i=0; i < HASHSIZE; ++i)
		Tab[i] = NULL;
	Ncount = 0;
}

/*
	enter new node (name s, articles n, low l) in hash Table, 
	initial flags = 0.  As nodes are entered, pnum item is temporarily
	used to indiacte entry order for initial construction of Newsorder
	array via entry_order();
*/
NODE *hashenter(s,n,l)
char *s;
int n;
int l;
{
	char *str_store();
	NODE *ptr,*node_store();
	int i;

	i=hash(s);
	ptr = node_store();
	ptr->next = Tab[i];
	Tab[i] = ptr;
	if (l > n)
		l = n;
	ptr->pnum = Ncount;
	++Ncount;
	ptr->rdnum = l;
	ptr->state = 0;
	ptr->art = n;
	ptr->nd_name = str_store(s);
	return (ptr);
}

NODE *hashfind(s)
char *s;
{
	NODE *ptr;

	for (ptr = Tab[hash(s)]; ptr != NULL && strcmp(ptr->nd_name,s) != 0;
					ptr = ptr->next)
		    ;
	return (ptr);
}

/*
** entry order is called after all hash_enter's have been done, PRIOR
** to the use of pnum item for anything else.  It constructs the initial
** Newsorder array.
*/
entry_order()
{
	int i;
	NODE *ptr;

	if ((Newsorder = (NODE **) malloc(Ncount*sizeof(NODE *))) == NULL)
		printex("Cannot allocate memory for Newsorder array");
	for (i=0; i < HASHSIZE; ++i)
	{
		for (ptr = Tab[i]; ptr != NULL; ptr = ptr->next)
			Newsorder[ptr->pnum] = ptr;
	}
}

static hash (s)
char *s;
{
	int rem;
	for (rem=0; *s != '\0'; ++s)
		rem = (rem*128 + (*s&0x7f)) % HASHSIZE;
	return (rem);
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'pagefile.c'" '(5053 characters)'
if test -f 'pagefile.c'
then
	echo shar: will not over-write existing file "'pagefile.c'"
else
cat << \SHAR_EOF > 'pagefile.c'
/*
** vn news reader.
**
** pagefile.c - routines to deal with page display tempfile
**
** see copyright disclaimer / history in vn.c source file
*/

#include <stdio.h>

#ifdef SYSV
#include <sys/types.h>
#include <fcntl.h>
#endif

#include <sys/file.h>
#include "vn.h"
#include "head.h"

extern int Ncount,Lrec,L_allow,Cur_page,C_allow;
extern int Nwopt, Nnwopt, Ntopt, Nntopt;
extern char *Wopt[], *Topt[], *Negtopt[], *Negwopt[];
extern NODE **Newsorder;
extern PAGE Page;
extern int Digest;

extern char *Aformat;

extern char *T_head, *F_head, *L_head;

static int Tdes;	/* temp file descriptor */
static int Pgsize;	/* block size for seeking file */

/*
	routines which deal with the temp file containing
	display pages.  Note the "invisible" file feature -
	tempfile is unlinked from /usr/tmp immediately.  when
	Tdes is closed by UNIX the disk space will be given back.
*/

temp_open ()
{
	char tmpart [L_tmpnam];
	Lrec = -1;
	tmpnam (tmpart);
	Pgsize = sizeof (HEAD) + L_allow * sizeof(BODY);
	if ((Tdes = open(tmpart,O_RDWR|O_CREAT)) < 0)
		printex ("can't open %s",tmpart);
	unlink (tmpart);
}

/*
	create page records for newsgroup s
	all articles between low and hi are to be included.
*/
outgroup (s,low,hi)
char *s;
int low,hi;
{
	int i,aid;
	char title[RECLEN],gd[RECLEN];
	g_dir(s,gd);
	if (chdir(gd) < 0)
	{
		grp_indic(s,0);
		return;
	}
	grp_indic(s,1);
	aid = 0;
	for (i=low+1; i <= hi; ++i)
	{
		if (digname (i,title) >= 0)
		{
			Page.b[aid].art_id = i;
			Page.b[aid].art_mark = ' ';
			strcpy (Page.b[aid].art_t, title);
			if ((++aid) >= L_allow)
			{

				/* start next page */
				Page.h.artnum = L_allow;
				do_write ();
				++Lrec;
				aid = 0;
			}
		}
	}

	/* last page (partial) */
	if (aid != 0)
	{
		Page.h.artnum = aid;
		do_write ();
		++Lrec;
	}
}

/*
	set current page to n.  use Pgsize and lseek to find it in
	temp file (descriptor Tdes).
*/
find_page (n)
int n;
{
	long off,lseek();
	int i,last;
	Cur_page = n;
	off = Pgsize;
	off *= (long) n;
	lseek (Tdes, off, 0);
	if (read(Tdes, (char *) &(Page.h), sizeof(HEAD)) < sizeof(HEAD))
		printex("bad temp file read");
	i = Pgsize - sizeof(HEAD);
	if (read(Tdes, (char *) Page.b, i) < i)
		printex("bad temp file read");
	last = -1;
	for (i=0; i < Ncount; ++i)
	{
		if ((Newsorder[i])->pages > 0)
		{
			if ((Newsorder[i])->pnum > n)
				break;
			last = i;
		}
	}
	if (last < 0)
		printex ("can't find page %d",n);
	Page.h.group = Newsorder[last];
	Page.h.name = (Page.h.group)->nd_name;
	cd_group ();
}

write_page ()
{
	long off,lseek();
	if (!Digest)
	{
		off = Pgsize;
		off *= (long) Cur_page;
		lseek (Tdes, off, 0);
		do_write();
	}
}

static do_write()
{
	int num;

	if (write(Tdes, (char *) &(Page.h), sizeof(HEAD)) < sizeof(HEAD))
		printex ("Bad temp file write");
	num = L_allow * sizeof(BODY);
	if (write(Tdes, (char *) Page.b, num) < num)
		printex ("Bad temp file write");
}

/*
	find article title:
	n - articles id
	t - returned title - must have storage for RECLEN, assumed to be
		> 3 * max title length also.
*/
static digname (n, t)
int n;
char *t;
{
	int i,j;
	FILE *fp,*fopen();
	char ff [MAX_C+1],fn [MAX_C+1],fl [MAX_C+1],*index();

	/* open article */
	sprintf (t,"%d", n);
	if ((fp = fopen(t,"r")) == NULL)
		return (-1);

	/* get subject, from and lines by reading article */
	ff[0] = fn[0] = fl[0] = '?';
	ff[1] = fn[1] = fl[1] = '\0';
	ff[C_allow] = fn[C_allow] = fl[C_allow] = '\0';
	for (i = 0; i < HDR_LINES && fgets(t,RECLEN-1,fp) != NULL; ++i)
	{
		if (index(CHFIRST,t[0]) == NULL)
			continue;
		t[strlen(t) - 1] = '\0';
		if (strncmp(T_head,t,THDLEN) == 0)
		{
			for (j=0; j < Nntopt; ++j)
			{
				if (regex(Negtopt[j],t+THDLEN) != NULL)
				{
					fclose(fp);
					return(-1);
				}
			}
			if (Ntopt > 0)
			{
				for (j=0; j < Ntopt; ++j)
				{
					if (regex(Topt[j],t+THDLEN) != NULL)
						break;
				}
				if (j >= Ntopt)
				{
					fclose(fp);
					return(-1);
				}
			}
			strncpy(fn,t+THDLEN,C_allow);
			continue;
		}
		if (strncmp(F_head,t,FHDLEN) == 0)
		{
			for (j=0; j < Nnwopt; ++j)
			{
				if (regex(Negwopt[j],t+FHDLEN) != NULL)
				{
					fclose(fp);
					return(-1);
				}
			}
			if (Nwopt > 0)
			{
				for (j=0; j < Nwopt; ++j)
				{
					if (regex(Wopt[j],t+FHDLEN) != NULL)
						break;
				}
				if (j >= Nwopt)
				{
					fclose(fp);
					return(-1);
				}
			}
			strncpy(ff,t+FHDLEN,C_allow);
			continue;
		}
		if (strncmp(L_head,t,LHDLEN) == 0)
		{
			strncpy(fl,t+LHDLEN,C_allow);
			break;
		}
	}

	fclose (fp);

	/* reject empty or 1 line files */
	if (i < 2)
		return (-1);

	form_title (t,fn,fl,ff,n);
	return (0);
}

form_title (t,fn,fl,ff,n)
char *t,*fn,*fl,*ff;
int n;
{
	char *ptr,*index();
	int i;

	if ((ptr = index(ff,'(')) != NULL && strlen(ptr) > 3)
		ff = ptr;
	sprintf (t,TFORMAT,fn,fl,ff);
	sprintf(ff,Aformat,' ',' ',n);
	i = C_allow - strlen(ff) + 1;	/* remember newline in Aformat */
	t[i] = '\0';
	ctl_xlt(t);
	return (0);
}

/* replace control characters in titles */
static ctl_xlt(s)
char *s;
{
	while (*s != '\0')
	{
		if (*s < ' ')
			*s += 'A' - 1;
		++s;
	}
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'reg.c'" '(1656 characters)'
if test -f 'reg.c'
then
	echo shar: will not over-write existing file "'reg.c'"
else
cat << \SHAR_EOF > 'reg.c'
/*
** vn news reader.
**
** reg.c - implementation of regex / regcmp on top of UCB library
**
** see copyright disclaimer / history in vn.c source file
*/

#include <stdio.h>

#define RGBLKSIZE 20

struct _regtab
{
	struct _regtab *link;
	char *regstr;
};

typedef struct _regtab REGTAB;

static REGTAB *Chain = NULL;
static REGTAB *Free = NULL;
static REGTAB *Compiled = NULL;

regfree(s)
char *s;
{
	REGTAB *ptr,*cmp,*old;

	cmp = (REGTAB *) s;
	old = NULL;

	for (ptr = Chain; ptr != NULL; ptr = (old = ptr)->link)
	{
		if (ptr == cmp)
		{
			if (old == NULL)
				Chain = Chain->link;
			else
				old->link = ptr->link;
			ptr->link = Free;
			Free = ptr;
			break;
		}
	}
}

char *regcmp(str)
char *str;
{
	int i;
	char *str_store();
	char *re_comp();

	if (re_comp(str) != NULL)
	{
		Compiled = NULL;	/* make sure we're OK */
		return(NULL);
	}

	if (Free == NULL)
	{
		Free = (REGTAB *) malloc(RGBLKSIZE * sizeof(REGTAB));
		if (Free == NULL)
			printex ("regcmp: memory allocation failure");
		for (i = 0; i < RGBLKSIZE - 1; ++i)
			Free[i].link = Free + i + 1;
		Free[i].link = NULL;
	}

	Compiled = Free;
	Free = Free->link;

	Compiled->link = Chain;
	Chain = Compiled;
	Compiled->regstr = str_store(str);

	return ((char *) Compiled);
}

char *regex(reg,str)
char *reg,*str;
{
	REGTAB *cmp;

	cmp = (REGTAB *) reg;

	if (cmp == Compiled)
	{
		if (re_exec(str))
			return(str);
		return (NULL);
	}

	for (Compiled = Chain; Compiled != NULL; Compiled = Compiled->link)
	{
		if (Compiled == cmp)
			break;
	}

	if (Compiled == NULL)
		printex ("regex: bad pointer");

	re_comp(Compiled->regstr);

	if (re_exec(str))
		return(str);

	return(NULL);
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'sig_set.c'" '(4501 characters)'
if test -f 'sig_set.c'
then
	echo shar: will not over-write existing file "'sig_set.c'"
else
cat << \SHAR_EOF > 'sig_set.c'
/*
** vn news reader.
**
** sig_set.c - signal handler
**
** see copyright disclaimer / history in vn.c source file
*/

#include <stdio.h>
#include <sys/signal.h>
#include <sgtty.h>
#include <setjmp.h>
#include "tty.h"
#include "vn.h"
#include "config.h"

extern int L_allow;
extern char *Version;

static int Sigflag=BRK_INIT;	/* phase of interaction */
static FILE **Fpseek;		/* article reading file pointer pointer */
static int Foreground;
static jmp_buf Jumploc;		/* for BRK_SESS phase */
static char *Cur_scn;		/* current group name being scanned */

/*
	interrupt handler - unusual termination (longjmp and printex aborts)
	if not abort, remember to reset signal trap
	CAUTION - the passing of a jump buffer is a little dicey - assumes
	type jump_buf is an array.

	sigcatch and sig_set control a lot of i/o on stderr also, since
	it is so intimately related to signal interaction.  Note that the
	SIGTSTP action causes a "stopped on tty output" if raw terminal
	mode is restored by tty_set(RESTORE).  We don't get it if we were
	already cooked since tty_set avoids calling ioctl if it doesn't
	have to.
*/
static sigcatch (sig)
int sig;
{
	char buf [MAX_C+1];
	int pgrp;

	/* disable signal while processing it */
	signal (sig,SIG_IGN);

	switch (sig)
	{
	case SIGINT:
	case SIGQUIT:
		break;

#ifdef JOBCONTROL
	case SIGTSTP:
		/* ignore SIGTTOU so we don't get stopped if [kc]sh grabs the tty */
		signal(SIGTTOU, SIG_IGN);
		tty_set (SAVEMODE);
		term_set (MOVE,0,L_allow+RECBIAS-1);
		printf ("\n");
		Foreground = 0;
		fflush (stdout);
		fflush (stderr);
		signal(SIGTTOU, SIG_DFL);

		/* Send the TSTP signal to suspend our process group */
		signal(SIGTSTP, SIG_DFL);
		sigsetmask(0);
		kill (0, SIGTSTP);

		/* WE ARE NOW STOPPED */

		/*
				WELCOME BACK!
				if terminals process group is ours, we are foregrounded again
				and can turn newsgroup name printing back on
			*/
		tty_set (RESTORE);
		switch (Sigflag)
		{
		case BRK_SESS:
			signal (SIGTSTP,sigcatch);
			longjmp (Jumploc,1);
		case BRK_IN:
			ioctl (1,TIOCGPGRP,&pgrp);
			if (pgrp == getpgrp(0))
			{
				Foreground = 1;
				if (Cur_scn != NULL)
					fgprintf ("    %s\n",Cur_scn);
			}
			break;
		default:
			break;
		}
		signal (SIGTSTP,sigcatch);
		return;
#endif
	default:
		printex (BRK_MSG,sig);
	}

	/* QUIT and INTERRUPT signals */
	switch (Sigflag)
	{
	case BRK_SESS:
		/* if in session, ask if really a quit, do longjump if not */
		term_set (ERASE);
		tty_set (RAWMODE);
		user_str (buf, BRK_PR, 1);
		if (buf[0] == 'y')
			printex (BRK_MSG,sig);
		signal (sig,sigcatch);
		longjmp (Jumploc,1);
	case BRK_READ:
		/* if reading seek file to end to abort page printing */
		printf ("\n");
		if (*Fpseek == NULL || fseek(*Fpseek,0L,2) < 0)
			putchar ('\07');
		break;
	default:
		printex (BRK_MSG,sig);
	}
	signal (sig,sigcatch);
}

/*
	sig_set controls what will be done with a signal when picked up by
	sigcatch.  grp_indic / fgprintf is included here to keep knowledge
	of TSTP state localized.
*/
/* VARARGS */
sig_set (flag,dat)
int flag, *dat;
{
	int i, *xfer, pgrp;
	if (Sigflag == BRK_INIT)
	{
		Cur_scn = NULL;
		signal (SIGINT,sigcatch);
		signal (SIGQUIT,sigcatch);
		signal (SIGHUP,sigcatch);
		signal (SIGTERM,sigcatch);
#ifdef JOBCONTROL
		signal (SIGTSTP,sigcatch);
		ioctl (1,TIOCGPGRP,&pgrp);
		if (pgrp == getpgrp(0))
		{
			Foreground = 1;
			fgprintf ("Visual News, Release %s, reading:\n",Version);
		}
		else
			Foreground = 0;
#else
		Foreground = NOJOB_FG;
#endif
	}
	switch (flag)
	{
	case BRK_IN:
	case BRK_OUT:
		Sigflag = flag;
		break;
	case BRK_READ:
		if (Sigflag != BRK_SESS)
			printex ("unexpected read state, sig_set\n");
		Fpseek = (FILE **) dat;
		Sigflag = BRK_READ;
		break;
	case BRK_SESS:
		xfer = (int *) Jumploc;
		for (i=0; i < sizeof(Jumploc) / sizeof(int); ++i)
			xfer[i] = dat[i];
		Sigflag = BRK_SESS;
		break;
	case BRK_RFIN:
		if (Sigflag != BRK_READ)
			printex ("unexpected finish state, sig_set\n");
		Sigflag = BRK_SESS;
		break;
	default:
		printex ("bad state %d, sig_set\n",flag);
	}
}

grp_indic (s,ok)
char *s;
int ok;
{
	NODE *ptr,*hashfind();

	/* we go to hash table because s might be a temporary buffer */
	if ((ptr = hashfind(s)) != NULL)
	{
		Cur_scn = ptr->nd_name;
		if (Foreground)
		{
			if (ok)
				fgprintf("    %s\n",Cur_scn);
			else
				fgprintf("    %s - Can't access spool directory\n",Cur_scn);
		}
	}
}

fgprintf (fs,a,b,c,d,e)
char *fs;
int a,b,c,d,e;
{
	if (Foreground)
		fprintf (stderr,fs,a,b,c,d,e);
	fflush (stderr);
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'storage.c'" '(1309 characters)'
if test -f 'storage.c'
then
	echo shar: will not over-write existing file "'storage.c'"
else
cat << \SHAR_EOF > 'storage.c'
/*
** vn news reader.
**
** storage.c - storage allocation routines
**
** see copyright disclaimer / history in vn.c source file
*/

#include <stdio.h>
#include "vn.h"

extern char *malloc();

extern int L_allow;

extern PAGE Page;
/*
	Storage allocaters.  One more call to malloc in entry_order routine.
*/

char *str_store (s)
char *s;
{
	static unsigned av_len = 0;	/* current storage available */
	static char *avail;
	int len;

	if (s == NULL)
		s = "";

	if ((len = strlen(s)+1) > av_len)
	{
		if (len > STRBLKSIZE)
			av_len = len;
		else
			av_len = STRBLKSIZE;
		if ((avail = malloc(av_len)) == NULL)
			printex ("can't allocate memory for string storage");
	}
	strcpy (avail,s);
	s = avail;
	avail += len;
	av_len -= len;
	return (s);
}

/*
** called after number of terminal lines (L_allow) is known, to set
** up storage for Page.
*/
page_alloc ()
{
	char *body;

	if ((body = malloc(L_allow*sizeof(BODY))) == NULL)
		printex ("can't allocate memory for display storage");

	Page.b = (BODY *) body;
}

NODE
*node_store()
{
	static int nd_avail = 0;
	static NODE *nd;
	NODE *ret;

	if (nd_avail <= 0)
	{
		if ((nd = (NODE *) malloc(sizeof(NODE)*NDBLKSIZE)) == NULL)
			printex ("can't allocate memory for newsgroup table");
		nd_avail = NDBLKSIZE;
	}
	--nd_avail;
	ret = nd;
	++nd;
	return(ret);
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'strings.c'" '(720 characters)'
if test -f 'strings.c'
then
	echo shar: will not over-write existing file "'strings.c'"
else
cat << \SHAR_EOF > 'strings.c'
/*
** vn news reader.
**
** strings.c - character strings
**
** see copyright disclaimer / history in vn.c source file
*/

#include "vn.h"
#include "head.h"

char *Version = "12/86";

char *No_msg = "No articles";
char *Hdon_msg = "Headers being printed";
char *Hdoff_msg = "Headers being suppressed";
char *Roton_msg = "ROT 13";
char *Rotoff_msg = "NO ROT";

char *Aformat = AFORMAT;

char *Contstr = "  ******** any key to continue ********";

char *R_head = RHEAD;
char *M_head = MHEAD;
char *P_head = PHEAD;
char *D_head = DHEAD;
char *F_head = FHEAD;
char *FT_head = FTHEAD;
char *T_head = THEAD;
char *L_head = LHEAD;
char *N_head = NHEAD;
char *RT_head = RTHEAD;
char *TO_head = TOHEAD;
char *DIS_head = DISHEAD;
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'strtok.c'" '(1082 characters)'
if test -f 'strtok.c'
then
	echo shar: will not over-write existing file "'strtok.c'"
else
cat << \SHAR_EOF > 'strtok.c'
/*
** vn news reader.
**
** strtok.c - strtok() and strpbrk() string routines using UCB index().
**
** see copyright disclaimer / history in vn.c source file
*/

#include <stdio.h>

char *strpbrk (s,del)
char *s, *del;
{
	char *ptr,*index();
	if (s == NULL)
		return (NULL);
	for (; *del != '\0'; ++del)
		if ((ptr = index(s,*del)) != NULL)
			return (ptr);
	return (NULL);
}

char *strtok(str,delim)
char *str, *delim;
{
	char *tokstart, *tokend, *first_ch (), *last_ch();
	static char *save=NULL;

	if (str != NULL)
		save = str;

	if (save == NULL)
		return (NULL);

	tokstart = first_ch (save, delim);
	tokend = last_ch (tokstart, delim);
	save = first_ch (tokend, delim);
	*tokend = '\0';

	if (*tokstart == '\0')
		return (NULL);

	return (tokstart);
}

static char *first_ch (str,delim)
char *str,*delim;
{
	char *index ();
	char *f;

	for (f = str; *f != '\0' && index(delim,*f) != NULL; ++f)
		;

	return (f);
}

static char *last_ch (str,delim)
char *str,*delim;
{
	char *index ();
	char *f;

	for (f = str; *f != '\0' && index(delim,*f) == NULL; ++f)
		;

	return (f);
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'term_set.c'" '(4914 characters)'
if test -f 'term_set.c'
then
	echo shar: will not over-write existing file "'term_set.c'"
else
cat << \SHAR_EOF > 'term_set.c'
/*
** vn news reader.
**
** term_set.c - terminal control, hides termcap interface
**
** see copyright disclaimer / history in vn.c source file
*/

#include <stdio.h>
#include "tty.h"
#include "vn.h"

extern int L_allow, C_allow;
extern char *Ku, *Kd, *Kl, *Kr;	

static outc (c)
char c;
{
	putchar (c);
}

/*
	term_set controls terminal through termcap
	START sets global parameters related to terminal also,
	as well as allocating display buffer which depends on
	terminal lines, and allocating escape strings.  RESTART
	simply re-issues the initialization - used following system
	calls that could have goofed up the terminal state.
*/

/*
** Escape strings.
*/

static char *Cm,*Cl,*So,*Se,*Te,*Bc,*Ce,*Ti,*Ks,*Ke;
#ifdef USEVS
static char *Vs,*Ve;
#endif

static int Backspace;		/* backspace works */
static int Overstrike;		/* terminal overstrikes */

static t_setup()
{
	int i;
	char *tgetstr(), *getenv(), *str_store();
	char *c, tc_buf[2048],optstr[2048];

	c = optstr;
	if (tgetent(tc_buf,getenv("TERM")) != 1)
		printex ("%s - unknown terminal",getenv("TERM"));

	/* get needed capabilities */
	Cm = str_store(tgetstr("cm",&c));
	Cl = str_store(tgetstr("cl",&c));
	So = str_store(tgetstr("so",&c));
	Se = str_store(tgetstr("se",&c));
	Te = str_store(tgetstr("te",&c));
	Ti = str_store(tgetstr("ti",&c));
	Bc = str_store(tgetstr("bc",&c));
	Ce = str_store(tgetstr("ce",&c));
	Kd = str_store(tgetstr("kd",&c));
	Ke = str_store(tgetstr("ke",&c));
	Kl = str_store(tgetstr("kl",&c));
	Kr = str_store(tgetstr("kr",&c));
	Ks = str_store(tgetstr("ks",&c));
	Ku = str_store(tgetstr("ku",&c));
#ifdef USEVS
	Vs = str_store(tgetstr("vs",&c));
	Ve = str_store(tgetstr("ve",&c));
#endif
	Backspace = tgetflag("bs");
	Overstrike = tgetflag("os");

	if ( *Cm == '\0' || *Cl == '\0')
	{
		printex ("cursor control and erase capability needed");
	}

	/*
	** Checks for arrow keys which don't issue something beginning
	** with <ESC>.  This is more paranoid than we need to be, strictly
	** speaking - we could get away with any string which didn't
	** conflict with controls used for commands.  However, that would
	** be a maintenance headache - we will simply reserve <ESC> as the
	** only char not to be used for commands, and punt on terminals
	** which don't send reasonable arrow keys.  It would be confusing
	** to have keys work partially, also.  I know of no terminal with
	** one arrow key beginning with an escape, and another beginning
	** with something else, but let's be safe.  This also insists on
	** definitions for all 4 arrows, which seems reasonable.
	*/

	if ((*Ku != '\0' && *Ku != '\033') || *Kl != *Ku || *Kr != *Ku || *Kd != *Ku)
	{
		fgprintf("WARNING: arrow keys will not work for this terminal");
		Ku = Kd = Kl = Kr = Kd = Ke = "";
	}

	if (Overstrike)
		fgprintf ("WARNING: terminal overstrikes - can't update display without erase\n");

	i = RECBIAS+1 < HHLINES+2 ? HHLINES+2 : RECBIAS+1;
	if ((L_allow = tgetnum("li")) < i)
	{
		if (L_allow < 0)
			printex ("can't determine number of lines on terminal");
		printex ("too few lines for display - %d needed", i);
	}

	/*
	** C_allow set so as to not use extreme right column.
	** Avoids "bad wraparound" problems - we're deciding it's best
	** to ALWAYS assume no automargin, and take care of it ourselves
	*/
	if((C_allow = tgetnum("co")) > MAX_C)
		C_allow = MAX_C;
	else
		--C_allow;
	if (C_allow < MIN_C)
	{
		if (C_allow < 0)
			printex("can't determine number of columns on terminal.");
		printex ("too few columns for display - %d needed",MIN_C);
	}

	L_allow -= RECBIAS;
	page_alloc();
	tputs(Ti,1,outc);
	tputs(Ks,1,outc);
#ifdef USEVS
	tputs(Vs,1,outc);
#endif
}

/* VARARGS */
term_set(cmd,x,y)
int cmd,x,y;
{
	char *tgoto();
	int i;
	switch (cmd)
	{
	case MOVE:
		tputs (tgoto(Cm,x,y),1,outc);
		break;
	case ERASE:
		tputs(Cl,1,outc);
		break;
	case ONREVERSE:
		tputs(So,1,outc);
		break;
	case OFFREVERSE:
		tputs(Se,1,outc);
		break;
	case START:
		t_setup();
		break;
	case RESTART:
		tputs(Ti,1,outc);
		tputs(Ks,1,outc);
#ifdef USEVS
		tputs(Vs,1,outc);
#endif
		break;
	case STOP:
		term_set (MOVE,0,L_allow+RECBIAS-1);
		printf ("\n");
		tputs(Ke,1,outc);
		tputs(Te,1,outc);
#ifdef USEVS
		tputs(Ve,1,outc);
#endif
		break;
	case RUBSEQ:
		if (Overstrike)
		{
			/* space overprint is futile */
			if (Backspace)
				putchar('\010');
			else
				tputs(Bc,1,outc);
			break;
		}
		if (Backspace)
			printf("%c %c",'\010','\010');
		else
		{
			tputs(Bc,1,outc);  
			putchar(' ');  
			tputs(Bc,1,outc);
		}
		break;
	case ZAP:
		if (Ce != NULL && *Ce != '\0')
			tputs(Ce,1,outc);
		else
		{
			if (Overstrike)
				break;		/* punt */
			for (i=x; i < y; ++i)
				putchar(' ');
			if (Backspace)
			{
				for (i=x; i < y; ++i)
					putchar('\010');
			}
			else
			{
				for (i=x; i < y; ++i)
					tputs(Bc,1,outc);
			}
		}
		break;
	default:
		printex ("term_set unknown code (%d)",cmd);
		break;
	}
	return (0);
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'tmpnam.c'" '(420 characters)'
if test -f 'tmpnam.c'
then
	echo shar: will not over-write existing file "'tmpnam.c'"
else
cat << \SHAR_EOF > 'tmpnam.c'
/*
** vn news reader.
**
** tmpnam.c - tmpnam() replacement for UCB, also uses non-generic name.
**
** see copyright disclaimer / history in vn.c source file
*/

#include <stdio.h>
#include "config.h"

char *tmpnam (buf)
char *buf;
{
	static char *ptr = VNTEMPNAME;

	/* depends on string initialized above */
	sprintf (ptr+TMP_XOFFSET,"XXXXXX");

	mktemp (ptr);

	if (buf != NULL)
		strcpy (buf,ptr);

	return (ptr);
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'tty_set.c'" '(2552 characters)'
if test -f 'tty_set.c'
then
	echo shar: will not over-write existing file "'tty_set.c'"
else
cat << \SHAR_EOF > 'tty_set.c'
/*
** vn news reader.
**
** tty_set.c - interface to ioctl (system tty interface)
**
** see copyright disclaimer / history in vn.c source file
*/

#ifdef SYSV
#include <termio.h>
#else
#include <sgtty.h>
#endif

#include "tty.h"

extern char Erasekey,Killkey;

#ifdef SYSV
static struct termio C_tp, O_tp;
#else
static struct sgttyb C_tp;
static unsigned short O_lflag;
#endif

static unsigned S_flag=0;
static int R_ignore=0;		/* up/down counter of reset calls to ignore */

#define IO_GOT 1	/* have polled for original terminal mode */
#define IO_RAW 2	/* in RAW (CBREAK actually) mode */

/*
	tty_set handles ioctl calls.  SAVEMODE, RESTORE are used around
	system calls and interrupts to assure cooked mode, and restore
	raw if raw on SAVEMODE.  The pair results in no calls to ioctl
	if we are cooked already when SAVEMODE is called, and may be nested,
	provided we desire no "restore" of cooked mode after restoring raw.

	When we get the original terminal mode, we also save erase and kill.

	sig_set makes an ioctl call to get process group leader.  Otherwise
	ioctl calls should come through here.
*/
tty_set(cmd)
int cmd;
{
	int rc;
	unsigned mask;

	switch (cmd)
	{
	case BACKSTOP:
#ifdef JOBCONTROL
		if ((rc = ioctl(1,TIOCLGET,&mask)) != 0)
			break;
		mask |= LTOSTOP;
		rc = ioctl(1,TIOCLSET,&mask);
#else
		rc = 0;
#endif
		break;
	case RAWMODE:
		if ((S_flag & IO_RAW) != 0)
		{
			rc = 0;
			break;
		}
		if ((S_flag & IO_GOT) == 0)
		{
			/* Save original modes, get erase / kill */
#ifdef SYSV
			rc = ioctl(0,TCGETA,&C_tp);
			O_tp = C_tp;
			Erasekey = C_tp.c_cc[VERASE];
			Killkey = C_tp.c_cc[VKILL];
#else
			rc = ioctl(0,TIOCGETP,&C_tp);
			O_lflag = C_tp.sg_flags;
			Erasekey = C_tp.sg_erase;
			Killkey = C_tp.sg_kill;
#endif
		}
#ifdef SYSV
		C_tp.c_lflag &= ~(ECHO | ICANON);
		C_tp.c_cc[VMIN] = 1;
		rc = ioctl(0,TCSETAW,&C_tp);
#else
		C_tp.sg_flags |= CBREAK;
		C_tp.sg_flags &= ~ECHO;
		rc = ioctl(0,TIOCSETP,&C_tp);
#endif
		S_flag = IO_GOT|IO_RAW;
		break;
	case COOKED:
		if ((S_flag & IO_RAW) != 0)
		{
#ifdef SYSV
			C_tp = O_tp;
			rc = ioctl(0,TCSETAW,&C_tp);
#else
			C_tp.sg_flags = O_lflag;
			rc = ioctl(0,TIOCSETP,&C_tp);
#endif
			S_flag &= ~IO_RAW;
		}
		else
			rc = 0;
		break;
	case SAVEMODE:
		if ((S_flag & IO_RAW) != 0)
		{
			tty_set(COOKED);
			R_ignore = 0;
		}
		else
			++R_ignore;
		rc = 0;
		break;
	case RESTORE:
		if (R_ignore <= 0)
		{
			tty_set(RAWMODE);
		}
		else
			--R_ignore;
		rc = 0;
		break;
	default:
		rc = -1;
	}
	if (rc < 0)
		printex ("ioctl failure, tty_set: %d",cmd);
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'userlist.c'" '(1923 characters)'
if test -f 'userlist.c'
then
	echo shar: will not over-write existing file "'userlist.c'"
else
cat << \SHAR_EOF > 'userlist.c'
/*
** vn news reader.
**
** userlist.c - generate user's list of articles
**
** see copyright disclaimer / history in vn.c source file
*/

#include <stdio.h>
#include "vn.h"

extern PAGE Page;

/*
	generate user list of articles - either article numbers
	are input directly (numeric list), or input is a search
	string - invoke regular expression library and examine titles
	search string "*" reserved for marked articles.  Strings may
	be prefixed with '!' for negation.
*/
userlist (list)
char *list;
{
	int i,j,anum[RECLEN/2],acount;
	char neg, *s, sbuf[MAX_C+1], *reg, *regex(), *regcmp(), *index(), *strtok();

	user_str (sbuf,"Articles or title search string : ",1);
	if (sbuf[0] == '!')
	{
		neg = '!';
		s = sbuf+1;
	}
	else
	{
		neg = '\0';
		s = sbuf;
	}
	for (i=0; s[i] != '\0'; ++i)
	{
		if (index(LIST_SEP,s[i]) == NULL)
		{
			if (s[i] < '0' || s[i] > '9')
				break;
		}
	}
	acount = 0;

	if (s[i] == '\0')
	{
		for (s = strtok(s,LIST_SEP); s != NULL; s = strtok(NULL,LIST_SEP))
		{
			anum[acount] = atoi(s);
			++acount;
		}
	}
	else
	{
		if (s[0] == ART_MARK)
		{
			for (i=0; i < Page.h.artnum; ++i)
			{
				if (Page.b[i].art_mark == ART_MARK)
				{
					anum[acount] = Page.b[i].art_id;
					++acount;
				}
			}
		}
		else
		{
			reg = regcmp(s,(char *) 0);
			if (reg != NULL)
			{
				for (i=0; i < Page.h.artnum; ++i)
				{
					if (regex(reg,Page.b[i].art_t) != NULL)
					{
						anum[acount] = Page.b[i].art_id;
						++acount;
					}
				}
				regfree (reg);
			}
			else
				preinfo ("bad regular expression syntax");
		}
	}

	/* algorithm is inefficient, but we're only handling a few numbers */
	*list = '\0';
	for (i=0; i < Page.h.artnum; ++i)
	{
		for (j=0; j < acount && anum[j] != Page.b[i].art_id; ++j)
			;
		if (neg == '!')
		{
			if (j < acount)
				continue;
		}
		else
		{
			if (j >= acount)
				continue;
		}
		sprintf (list,"%d ",Page.b[i].art_id);
		list += strlen(list);
	}
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'vnglob.c'" '(1613 characters)'
if test -f 'vnglob.c'
then
	echo shar: will not over-write existing file "'vnglob.c'"
else
cat << \SHAR_EOF > 'vnglob.c'
/*
** vn news reader.
**
** vnglob.c - global variables - see string.c also
**
** see copyright disclaimer / history in vn.c source file
*/

#include <stdio.h>
#include "config.h"
#include "vn.h"
#include "head.h"

/*
	global data structure
*/
NODE **Newsorder;		/* .newsrc file order */

char *Editor,*Ps1,*Mailer,*Printer,*Poster;

char Erasekey, Killkey;		/* user keys from stty */
char *Newsrc, *Orgdir;		/* .newsrc file, and original pwd */
char *Onews;			/* temp. file for backing up .newsrc */
char *Savefile = DEF_SAVE;	/* file in which to save articles */
char *Savedir;			/* default directory for saved articles */
char *Ccfile;			/* author_copy file, stored /bin/mail fmt */

int Rot;	/* rotation */
int Headflag;	/* header printing flag */
int Digest;	/* if non-zero, digest article */

char *Ku, *Kd, *Kl, *Kr;	/* Cursor movement capabilities */

/* character translation arrays for commands */
char Cxitop[128], Cxitor[128], Cxrtoi[128], Cxptoi[128];

/*
	cur_page - current page displayed;
	lrec - last record
	l_allow - lines allowed for article display
	c_allow - columns allowed
	ncount = newsorder index
	nfltr - number of filters
*/
int Cur_page, Lrec, L_allow, C_allow, Ncount, Nfltr;

/*
	article filtration options.
*/
char *Wopt[NUMFILTER];		/* regular expressions for -w options */
char *Topt[NUMFILTER];		/* regular expressions for -t options */
char *Negwopt[NUMFILTER];	/* regular expressions for negated -w options */
char *Negtopt[NUMFILTER];	/* regular expressions for negated -t options */

int Nwopt, Ntopt, Nnwopt, Nntopt;

int Nounsub, Listfirst;
/*
	current page
*/
PAGE Page;
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0



More information about the Comp.sources.unix mailing list