[comp.sources.amiga] v91i006: BARN 2.01 - Usenet newsread for the Amiga, Part01/02

amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (02/07/91)

Submitted-by: lordbah@amusing.bisco.kodak.COM (Jeff Van Epps)
Posting-number: Volume 91, Issue 006
Archive-name: news/barn-2.01/part01

I am submitting to comp.sources.amiga my program, "Bah's Amiga Read News".
(Originally I called it ARN, but there is already a newsreader out there
called ARN so I changed the name of mine).

Name: BARN
Version: 2.01
Description: Usenet newsreader for the Amiga.
Distribution: Source is freely distributable.

A replacement for Anews which comes with AmigaUUCP 1.03D -- should also
work with later versions of AmigaUUCP.  The interface is modeled after
"rn" from the UNIX world.  Follows subject threads, has kill files, a
built-in pager, etc.

Probably requires SAS C 5.10 or later to compile, as well as Henry Spencer's
regexp library.

--------------------------------------------------------------------
    Jeff Van Epps    amusing!lordbah@bisco.kodak.com
                     lordbah@cup.portal.com
                     sun!portal!cup.portal.com!lordbah



#!/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 1 (of 2)."
# Contents:  Makefile article.c article.h barn.config configure.c
#   configure.h kill.c kill.h ng.c ng.h raw.c reply.c reply.h
#   screenstuff.h sendpacket.c standard.h trim.sksh variables.h
# Wrapped by tadguy@ab20 on Wed Feb  6 20:05:19 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(782 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
XCFLAGS = -c -O +filter +pure-strings +echo
X#CFLAGS = -c -g3 +filter +pure-strings +echo
XBARN_OBJS = arn.o article.o configure.o ng.o kill.o reply.o raw.o sendpacket.o
XCC = cc
X
X.c.o:
X	$(CC) $(CFLAGS) $<
X
Xall: barn
X
Xbarn: $(BARN_OBJS)
X	$(CC) $(BARN_OBJS) +catch -lregexp -o barn
X
Xtest: main.o article.o
X	blink from lib:c.o+main.o+article.o to test lib lib:$(CC).lib lib:amiga.lib addsym
X
XInstall: barn
X  copy barn uucp:c
X
Xarn.o: arn.c standard.h article.h ng.h kill.h configure.h variables.h reply.h screenstuff.h
X
Xarticle.o: article.c standard.h article.h configure.h variables.h
X
Xconfigure.o: configure.c standard.h configure.h
X
Xkill.o: kill.c standard.h article.h kill.h
X
Xng.o: ng.c standard.h article.h ng.h
X
Xreply.o: reply.c standard.h configure.h variables.h article.h reply.h
X
END_OF_FILE
if test 782 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
chmod +x 'Makefile'
# end of 'Makefile'
fi
if test -f 'article.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'article.c'\"
else
echo shar: Extracting \"'article.c'\" \(9465 characters\)
sed "s/^X//" >'article.c' <<'END_OF_FILE'
X/*
X *	File Name:		article.c
X *	Project:		BARN - Bah's Amiga ReadNews.
X *	Purpose:		Parse header fields in a news article.
X *	Functions:		ParseArticle, GetNextHeader, DumpArticle, DestroyArticle.
X *	Author:			Jeff Van Epps
X *	Created:		02 Sep 89
X *	Last Modified:	05 Jan 91
X *	Comments:
X *	History:
X *		02 Sep 89/JVE	Created.
X *		28 Sep 89/JVE	ParseArticle now stores position within file where
X *						headers end and text begins in article->textpos.
X *		30 Dec 89/JVE	Added "Sender:" to list of useful headers.  This list
X *						will go away when there is a config file to do same.
X *		18 Oct 90/JVE	Use HDR_xxx defines instead of hardcoded strings.
X *						Added GetHeader.
X *		21 Oct 90/JVE	Don't end header search until blank line.
X *		05 Jan 91/JVE	New "subject" field in article_info initialized to
X *						a NULL pointer and set to point at the SUBJECT header
X *						fieldvalue after all headers have been read.
X */
X
X# include	<stdio.h>
X# include	<stdlib.h>
X# include	<string.h>
X# include	"standard.h"
X# include	"article.h"
X# include	"configure.h"
X# include	"variables.h"
X
X
X/****************************************************************************/
X/*	FUNCTION:	ParseArticle												*/
X/*																			*/
X/*	PURPOSE:	Parses headers from article & creates article/header structs*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		filename	 I		Name of file containing article.				*/
X/*																			*/
X/*	RETURNS:																*/
X/*		(ARTICLE_INFO *)	Pointer to newly allocated article structure.	*/
X/*		NULLP(ARTICLE_INFO)	Indication of failure.							*/
X/*																			*/
X/*	COMMENTS:																*/
X/*		Assumes filename contains only digits and is same as article 		*/
X/*		number.																*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	02 Sep 89		Created.										*/
X/*		2.	28 Sep 89		Added textpos to say where headers end.			*/
X/*																			*/
X/****************************************************************************/
X
XARTICLE_INFO *ParseArticle( filename )
X
Xchar	*filename;
X
X{
XFILE			*fp;
Xlong			id;			/* article number (aka filename) */
XARTICLE_INFO	*article;	/* ptr to article information */
XHEADER_INFO		**hdr;		/* handle for header field allocation */
XHEADER_INFO		*h;
X
Xif ( ( fp = fopen( filename, "r" ) ) == NULLP( FILE ) )
X	{
X	perror( filename );
X	return NULLP( ARTICLE_INFO );
X	}
Xelse if ( ( id = atol( filename ) ) <= 0 )
X	{
X	printf( "%s: Bad article number.\n", filename );
X	return NULLP( ARTICLE_INFO );
X	}
X
X/*
X *	Initialize article info structure.
X */
X
Xarticle = (ARTICLE_INFO *) malloc( sizeof( ARTICLE_INFO ) );
Xarticle->number = id;
Xarticle->next = NULLP( ARTICLE_INFO );
Xarticle->headers = NULLP( HEADER_INFO );
Xarticle->beenread = FALSE;
Xarticle->textpos = 0L;
Xarticle->done = FALSE;
Xarticle->subject = NULLP( char );
X
X/*
X *	Get all header fields.
X */
X
Xhdr = &article->headers;
Xwhile ( GetNextHeader( fp, &hdr ) ) 
X	article->textpos = ftell( fp );
Xfclose( fp );
Xfor ( h = article -> headers; h != NULLP( HEADER_INFO ); h = h -> next )
X	if ( strcmp( h -> fieldname, HDR_SUBJECT ) == 0 )
X		{
X		article -> subject = h -> fieldvalue;
X		break;
X		}
Xreturn article;
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	GetNextHeader												*/
X/*																			*/
X/*	PURPOSE:	Parses the next header field out of an article.				*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		fp			 I		FILE pointer to file containing article.		*/
X/*		hdr			I/O		Where to put pointer to newly allocated			*/
X/*							HEADER_INFO structure if we allocate one.		*/
X/*																			*/
X/*	RETURNS:																*/
X/*		TRUE	Successfully parsed another header from article.			*/
X/*		FALSE	Failed/no more headers in article.							*/
X/*																			*/
X/*	COMMENTS:																*/
X/*		Adjusts hdr when done so next call will set correct pointer.		*/
X/*		BBS version terminates header search on a line without a colon,		*/
X/*		or with a space before the colon.  Usenet version terminates		*/
X/*		header search on blank line, ignoring "malformed" header lines.		*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	02 Sep 89		Created.										*/
X/*		2.	30 Dec 89		Added "Sender:" to list of useful headers.		*/
X/*		3.	21 Oct 90		Don't end header search until blank line.		*/
X/*																			*/
X/****************************************************************************/
X
XGetNextHeader( fp, hdr )
X
XFILE			*fp;
XHEADER_INFO		***hdr;
X
X{
Xint				rc;				/* return code from function */
Xchar			buf[BUFSIZ];	/* holds input line from article */
Xchar			*firstspace, *firstcolon, *data;	/* for parsing */
X
Xif ( fgets( buf, BUFSIZ, fp ) == NULL )
X	rc = FALSE;
Xelse
X	{
X	firstspace = strchr( buf, ' ' );
X	firstcolon = strchr( buf, ':' );
X	if ( ( firstcolon == NULL ) || 
X		( ( firstspace != NULL ) && ( firstspace < firstcolon ) ) )
X			{
X			if ( GetVar( VAR_BBS ) || strspn( buf, " \t\r\n" ) == strlen(buf) )
X				rc = FALSE;
X			else					/* junk line, don't end header search */
X				rc = TRUE;
X			}
X	else
X		{
X		*firstcolon = NULL;		/* terminate fieldname string */
X# ifndef ARN_CONFIG
X/*
X *	Until a useful way is found to restrict output to interesting headers,
X *	use this kluge.
X *
X *	Don't actually allocate a header struct because we're not interested in
X *	other headers, but return TRUE so that we continue to try to get headers.
X */
X	if ( strcmp( buf, HDR_FROM ) && strcmp( buf, HDR_SUBJECT ) &&
X		strcmp( buf, HDR_DATE ) && strcmp( buf, HDR_SENDER ) && 
X		strcmp( buf, HDR_TO ) )
X			return TRUE;
X# endif
X		firstcolon++;			/* advance past colon/NULL to value string */
X		data = firstcolon + strspn( firstcolon, " \t" );	/* skip white */
X		data[strlen(data)-1] = NULL;	/* remove trailing newline */
X
X		/*
X		 *	Allocate and fill a new header structure.
X		 */
X
X		**hdr = (HEADER_INFO *) malloc( sizeof( HEADER_INFO ) );
X		(**hdr)->fieldname = strdup( buf );
X		(**hdr)->fieldvalue = strdup( data );
X		(**hdr)->next = NULLP( HEADER_INFO );
X
X		/*
X		 *	Reset the hdr pointer so next call will continue chain correctly.
X		 */
X
X		*hdr = &((**hdr)->next);
X		rc = TRUE;
X		}
X	}
Xreturn rc;
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	DumpArticle													*/
X/*																			*/
X/*	PURPOSE:	Print article/header info for an article.					*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		article		 I		Pointer to article structure to dump.			*/
X/*																			*/
X/*	RETURNS: none															*/
X/*																			*/
X/*	COMMENTS:																*/
X/*		Debugging function.													*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	02 Sep 89		Created.										*/
X/*																			*/
X/****************************************************************************/
X
Xvoid DumpArticle( article )
X
XARTICLE_INFO	*article;
X
X{
XHEADER_INFO		*hdr;
X
Xprintf( "Article: %ld\n", article->number );
Xfor ( hdr = article->headers; hdr != NULLP( HEADER_INFO ); hdr = hdr->next )
X	printf( "\t%s: %s\n", hdr->fieldname, hdr->fieldvalue );
Xprintf( "\n" );
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	DestroyArticle												*/
X/*																			*/
X/*	PURPOSE:	Free all space taken by article/header structure.			*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		article		 I		The article being destroyed.					*/
X/*																			*/
X/*	RETURNS:																*/
X/*																			*/
X/*	COMMENTS:																*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	02 Sep 89		Created.										*/
X/*																			*/
X/****************************************************************************/
X
Xvoid DestroyArticle( article )
X
XARTICLE_INFO	*article;
X
X{
XHEADER_INFO		*hdr, *tmp;
X
Xfor ( hdr = article->headers; hdr != NULLP( HEADER_INFO ); hdr = tmp )
X	{
X	free( hdr->fieldname );
X	free( hdr->fieldvalue );
X	tmp = hdr->next;
X	free( hdr );
X	}
Xfree( article );
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	GetHeader													*/
X/*																			*/
X/*	PURPOSE:	Retrieve a specific header from a message.					*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		headers		 I		List of headers.								*/
X/*		name		 I		Name of header to retrieve.						*/
X/*																			*/
X/*	RETURNS:																*/
X/*																			*/
X/*	COMMENTS:																*/
X/*		Makes a local copy of the header value to be returned.  Gets		*/
X/*		overwritten each call.												*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	18 Oct 90		Created.										*/
X/*																			*/
X/****************************************************************************/
X
Xchar	*GetHeader( headers, name )
X
XHEADER_INFO		*headers;
Xchar			*name;
X
X{
Xstatic char		local[MAXLINE];
X
Xwhile ( headers )
X	{
X	if ( strcmp( headers -> fieldname, name ) == 0 )
X		{
X		strcpy( local, headers -> fieldvalue );
X		return local;
X		}
X	headers = headers -> next;
X	}
Xreturn (char *) NULL;
X}
END_OF_FILE
if test 9465 -ne `wc -c <'article.c'`; then
    echo shar: \"'article.c'\" unpacked with wrong size!
fi
chmod +x 'article.c'
# end of 'article.c'
fi
if test -f 'article.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'article.h'\"
else
echo shar: Extracting \"'article.h'\" \(1949 characters\)
sed "s/^X//" >'article.h' <<'END_OF_FILE'
X/*
X *	File Name:		article.h
X *	Project:		BARN - Bah's Amiga ReadNews.
X *	Purpose:		Define structure holding info for each article.
X *	Author:			Jeff Van Epps
X *	Created:		02 Sep 89
X *	Last Modified:	06 Jan 91
X *	Comments:
X *	History:
X *		02 Sep 89/JVE	Created.
X *		28 Sep 89/JVE	Added textpos.
X *		18 Oct 90/JVE	Added HDR_xxx defines.
X *		06 Jan 91/JVE	Added subject pointer in article_info as a speed
X *						optimization.
X */
X
X/*
X *	Hold header information for an article. Example:
X *
X *	fieldname="From"    fieldvalue="foo@bar.com"
X *	fieldname="Subject"	fieldvalue="Care and Eating of Foo Bars"
X *		etc.
X *
X */
X
Xtypedef struct header_info {
X	char				*fieldname;		/* name of field (before :) */
X	char				*fieldvalue;	/* text of field (after :) */
X	struct header_info	*next;			/* next header in chain */
X	} HEADER_INFO;
X
X/*
X *	Information for each article.
X */
X
Xtypedef struct article_info {
X	long				number;			/* article number within newsgroup */
X	int					beenread;		/* has article been read? */
X	long				textpos;		/* where headers end/text begins */
X	int					done;			/* generic temporary marker */
X	char				*subject;		/* points at value of Subject hdr */
X	struct header_info	*headers;		/* top of header field chain */
X	struct article_info	*next;			/* ptr to next article in newsgroup */
X	} ARTICLE_INFO;
X
X/*
X *	Defines for common header fields.
X */
X
X
X# define	HDR_FROM		"From"
X# define	HDR_TO			"To"
X# define	HDR_CC			"Cc"
X# define	HDR_SUBJECT		"Subject"
X# define	HDR_SENDER		"Sender"
X# define	HDR_DATE		"Date"
X
X/*
X *	Declare functions.
X */
X
X# ifdef sun 
X
XARTICLE_INFO	*ParseArticle();
Xint				GetNextHeader();
Xvoid			DestroyArticle();
Xvoid			DumpArticle();
Xchar			*GetHeader();
X
X# else
X
XARTICLE_INFO	*ParseArticle( char *filename );
Xint				GetNextHeader( FILE *fp, HEADER_INFO ***hdr );
Xvoid			DestroyArticle( ARTICLE_INFO *article );
Xvoid			DumpArticle( ARTICLE_INFO *article );
Xchar			*GetHeader( HEADER_INFO *headers, char *name );
X
X# endif
END_OF_FILE
if test 1949 -ne `wc -c <'article.h'`; then
    echo shar: \"'article.h'\" unpacked with wrong size!
fi
chmod +x 'article.h'
# end of 'article.h'
fi
if test -f 'barn.config' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'barn.config'\"
else
echo shar: Extracting \"'barn.config'\" \(776 characters\)
sed "s/^X//" >'barn.config' <<'END_OF_FILE'
X# arn.config
X#
X# Configuration file for ARN
X
X# 'user' is username used when sending mail or followups
X
Xuser=lordbah
X
X# 'node' is the UUCP name of the machine we're running on
X
Xnode=amusing
X
X# 'domain' is used in constructing 'From:' line in mail.  Thus:
X# From: $node!$user@$domain ($name)
X#
X# This might be specific to our setup, but that's too bad (for now).
X
Xdomain=bisco.kodak.com
X
X# 'name' used in headers.
X
Xname=Lord Bah
X
X# Your favorite editor used to edit replies and followups.
X
Xeditor=stevie
X
X# Name of file used as .newsrc
X
Xnewsrc=.newsrc
X
X# Name of KILL file.  Must start with "KILL"!!
X
Xkill=KILL
X
X# Name of signature file to append to outgoing mail and articles.
X
Xsignature=uulib:.signature
X
X# Set "bbs" to anything when reading a BBS-type repository.
X
X#bbs=true
END_OF_FILE
if test 776 -ne `wc -c <'barn.config'`; then
    echo shar: \"'barn.config'\" unpacked with wrong size!
fi
chmod +x 'barn.config'
# end of 'barn.config'
fi
if test -f 'configure.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'configure.c'\"
else
echo shar: Extracting \"'configure.c'\" \(4912 characters\)
sed "s/^X//" >'configure.c' <<'END_OF_FILE'
X/*
X *	File Name:		configure.c
X *	Project:		BARN - Bah's Amiga ReadNews.
X *	Purpose:		Configuration variable setting, retrieving.
X *	Functions:		Configure, SetVar, GetVar.
X *	Author:			Jeff Van Epps
X *	Created:		20 Oct 90
X *	Last Modified:	20 Oct 90
X *	Comments:
X *		Generic configuration file processor.  Reads lines of the form:
X *			var=value
X *		from a specified configuration file and stores the names and values.
X *		White space WILL be considered significant, so don't put any in there
X *		unless you really want it.  No '=' may appear anywhere else on the line.
X *
X *		SetVar(name,value) changes an existing value or creates a new one.
X *		GetVar(name) returns a pointer to the value of a variable.
X *		Configure(filename) processes a configuration file.
X *
X *		A line in the configuration file beginning with '#' is a comment.
X *		Comment lines and blank lines are skipped.
X *
X *		Currently implemented with static limits for name and value length as
X *		well as number of possible variables.
X *
X *	History:
X *		20 Oct 90/JVE	Created.
X */
X
X# include	<stdio.h>
X# include	<string.h>
X# include	"standard.h"
X# include	"configure.h"
X
X# define	MAX_VARS			20
X# define	MAX_NAME_LEN		10
X# define	MAX_VALUE_LEN		40
X
Xstatic struct {
X	char		name[MAX_NAME_LEN+1];		/* name of variable */
X	char		value[MAX_VALUE_LEN+1];		/* its value */
X	} vars[MAX_VARS];
X
Xstatic int	n_vars = 0;
X
X
X/****************************************************************************/
X/*	FUNCTION:	Configure													*/
X/*																			*/
X/*	PURPOSE:	Parse ARN configuration file.								*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		config_file	 I		Name of configuration file to use.				*/
X/*																			*/
X/*	RETURNS:																*/
X/*																			*/
X/*	COMMENTS:																*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	20 Oct 90		Created.										*/
X/*																			*/
X/****************************************************************************/
X
Xvoid Configure( config_file )
X
Xchar			*config_file;
X
X{
XFILE			*fp;
Xchar			s[MAXLINE], *name, *value;
X
Xif ( ( fp = fopen( config_file, "r" ) ) == NULL )
X	{
X	perror( config_file );
X	exit( 1 );
X	}
Xwhile ( fgets( s, MAXLINE, fp ) != NULL )
X	{
X	s[strlen(s)-1] = NULL;					/* kill trailing newline */
X	if ( s[0] != '\0' && s[0] != '#' )		/* skip blank and comment lines */
X		{
X		if ( ( name = strtok( s, "=" ) ) == NULL )
X			fprintf( stderr, "Can't parse '%s'\n", s );
X		else
X			{
X			value = strtok( NULL, "=" );
X			(void) SetVar( name, value );
X			}
X		}
X	}
Xfclose( fp );
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	SetVar														*/
X/*																			*/
X/*	PURPOSE:	Set the value of a configuration variable.					*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		name		 I		Variable name.									*/
X/*		value		 I		Variable value.									*/
X/*																			*/
X/*	RETURNS:																*/
X/*		OK			Successful.												*/
X/*		ERROR		Unsuccessful.											*/
X/*																			*/
X/*	COMMENTS:																*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	20 Oct 90		Created.										*/
X/*																			*/
X/****************************************************************************/
X
XSetVar( name, value )
X
Xchar			*name;
Xchar			*value;
X
X{
Xint				i;
X
Xif ( strlen( name ) > MAX_NAME_LEN )
X	name[MAX_NAME_LEN-1] = NULL;
Xif ( strlen( value ) > MAX_VALUE_LEN )
X	value[MAX_VALUE_LEN-1] = NULL;
Xfor ( i = 0; i < n_vars; i++ )
X	if ( strcmp( vars[i].name, name ) == 0 )
X		{
X		strcpy( vars[i].value, value );
X		return OK;
X		}
Xif ( n_vars >= MAX_VARS )
X	{
X	fprintf( stderr, "Too many variables!\n" );
X	return ERROR;
X	}
Xstrcpy( vars[i].name, name );
Xstrcpy( vars[i].value, value );
Xn_vars++;
Xreturn OK;
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	GetVar														*/
X/*																			*/
X/*	PURPOSE:	Return value of configuration variable.						*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		name		 I		Name of variable.								*/
X/*																			*/
X/*	RETURNS:																*/
X/*		(char *)		Pointer to value.									*/
X/*		(char *) NULL	No such variable known.								*/
X/*																			*/
X/*	COMMENTS:																*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	20 Oct 90		Created.										*/
X/*																			*/
X/****************************************************************************/
X
Xchar *GetVar( name )
X
Xchar			*name;
X
X{
Xint				i;
X
Xfor ( i = 0; i < n_vars; i++ )
X	if ( strcmp( vars[i].name, name ) == 0 )
X		return vars[i].value;
Xreturn NULLP( char );
X}
END_OF_FILE
if test 4912 -ne `wc -c <'configure.c'`; then
    echo shar: \"'configure.c'\" unpacked with wrong size!
fi
chmod +x 'configure.c'
# end of 'configure.c'
fi
if test -f 'configure.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'configure.h'\"
else
echo shar: Extracting \"'configure.h'\" \(575 characters\)
sed "s/^X//" >'configure.h' <<'END_OF_FILE'
X/*
X *	File Name:		configure.h
X *	Project:		BARN - Bah's Amiga ReadNews.
X *	Purpose:		Configuration variable setting, retrieving.
X *	Author:			Jeff Van Epps
X *	Created:		20 Oct 90
X *	Last Modified:	20 Oct 90
X *	Comments:
X *		For implementation limits, see configure.c.
X *
X *	History:
X *		20 Oct 90/JVE	Created.
X */
X
X# ifdef sun
X
Xextern void		Configure();
Xextern int		SetVar();
Xextern char *	GetVar();
X
X# else  /* amiga */
X
Xextern void		Configure( char *config_file );
Xextern int		SetVar( char *name, char *value );
Xextern char *	GetVar( char *name );
X
X# endif /* sun/amiga */
END_OF_FILE
if test 575 -ne `wc -c <'configure.h'`; then
    echo shar: \"'configure.h'\" unpacked with wrong size!
fi
chmod +x 'configure.h'
# end of 'configure.h'
fi
if test -f 'kill.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kill.c'\"
else
echo shar: Extracting \"'kill.c'\" \(6070 characters\)
sed "s/^X//" >'kill.c' <<'END_OF_FILE'
X/*
X *	File Name:		kill.c
X *	Project:		BARN - Bah's Amiga ReadNews.
X *	Purpose:		Defines functions related to kill list.
X *	Functions:		GetKillList, PutKillList, DestroyKillList.
X *	Author:			Jeff Van Epps
X *	Created:		04 Sep 89
X *	Last Modified:	22 Oct 90
X *	Comments:
X *	History:
X *		04 Sep 89/JVE	Created.
X *		30 Dec 89/JVE	Implemented GetKillList and PutKillList, which were
X *						only stubbed previously.
X *		22 Oct 90/JVE	Added regular expression capability in kill files.
X *						A kill list is no longer just a list of HEADER_INFOs,
X *						it now has its own structure.
X */
X
X# include	<stdio.h>
X# include	<stdlib.h>
X# include	<string.h>
X# include	<fcntl.h>
X# include	<regexp.h>
X# include	"standard.h"
X# include	"article.h"
X# include	"kill.h"
X
X
X/****************************************************************************/
X/*	FUNCTION:	GetKillList													*/
X/*																			*/
X/*	PURPOSE:	Parse the kill file which applies to all newsgroups.		*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		filename	 I		Name of kill file.								*/
X/*																			*/
X/*	RETURNS:																*/
X/*		(KILL_INFO *)	Pointer to start of kill list.						*/
X/*																			*/
X/*	COMMENTS:																*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	30 Dec 89		Created.										*/
X/*																			*/
X/****************************************************************************/
X
XKILL_INFO	*GetKillList( filename )
X
Xchar		*filename;
X
X{
XKILL_INFO	*root = NULLP( KILL_INFO );
XKILL_INFO	**ptr;
XFILE		*fp;
X
Xif ( ( fp = fopen( filename, "r" ) ) != NULLP( FILE ) )
X	{
X	ptr = &root;
X	while ( GetNextKill( fp, &ptr ) ) ;
X	fclose( fp );
X	}
Xreturn root;
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	PutKillList													*/
X/*																			*/
X/*	PURPOSE:	Write back a kill list to specified file.					*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		filename	 I		File in which to put kill list.					*/
X/*		root		 I		Pointer to start of kill list.					*/
X/*																			*/
X/*	RETURNS: none															*/
X/*																			*/
X/*	COMMENTS:																*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	30 Dec 89		Created.										*/
X/*																			*/
X/****************************************************************************/
X
Xvoid PutKillList( filename, root )
X
Xchar		*filename;
XKILL_INFO	*root;
X
X{
XFILE		*fp;
X
Xremove( filename );
Xif ( ( fp = fopen( filename, "a" ) ) != NULLP( FILE ) )
X	{
X	while ( root != NULLP( KILL_INFO ) )
X		{
X		fprintf( fp, "%s: %s\n", root->fieldname, root->fieldvalue );
X		root = root->next;
X		}
X	fclose( fp );
X	}
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	DestroyKillList												*/
X/*																			*/
X/*	PURPOSE:	Release memory consumed by construction of kill list.		*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		root		 I		Pointer to start of kill list.					*/
X/*																			*/
X/*	RETURNS: none															*/
X/*																			*/
X/*	COMMENTS:																*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	04 Sep 89		Created.										*/
X/*																			*/
X/****************************************************************************/
X
Xvoid DestroyKillList( root )
X
XKILL_INFO		*root;
X
X{
XKILL_INFO		*tmp;
X
Xfor ( ; root != NULLP( KILL_INFO ); root = tmp )
X	{
X	tmp = root->next;
X	free( root -> fieldname );
X	free( root -> fieldvalue );
X	free( (char *) ( root -> pattern ) );
X	free( root );
X	}
X}
X
X/****************************************************************************/
X/*	FUNCTION:	GetNextKill													*/
X/*																			*/
X/*	PURPOSE:	Parses the next kill entry from a kill file.				*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		fp			 I		FILE pointer to file containing article.		*/
X/*		hdr			I/O		Where to put pointer to newly allocated			*/
X/*							KILL_INFO structure if we allocate one.			*/
X/*																			*/
X/*	RETURNS:																*/
X/*		TRUE	Successfully parsed another entry from file.				*/
X/*		FALSE	Failed/no more entries.										*/
X/*																			*/
X/*	COMMENTS:																*/
X/*		Adjusts hdr when done so next call will set correct pointer.		*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	22 Oct 90		Created from GetNextHeader.						*/
X/*																			*/
X/****************************************************************************/
X
XGetNextKill( fp, hdr )
X
XFILE			*fp;
XKILL_INFO		***hdr;
X
X{
Xint				rc;				/* return code from function */
Xchar			buf[BUFSIZ];	/* holds input line from article */
Xchar			*firstspace, *firstcolon, *data;	/* for parsing */
X
Xif ( fgets( buf, BUFSIZ, fp ) == NULL )
X	rc = FALSE;
Xelse
X	{
X	firstspace = strchr( buf, ' ' );
X	firstcolon = strchr( buf, ':' );
X	if ( ( firstcolon == NULL ) || 
X	  ( ( firstspace != NULL ) && ( firstspace < firstcolon ) ) )
X		rc = FALSE;
X	else
X		{
X		*firstcolon = NULL;		/* terminate fieldname string */
X		firstcolon++;			/* advance past colon/NULL to value string */
X		data = firstcolon + strspn( firstcolon, " \t" );	/* skip white */
X		data[strlen(data)-1] = NULL;	/* remove trailing newline */
X
X		/*
X		 *	Allocate and fill a new kill structure.
X		 */
X
X		**hdr = (KILL_INFO *) malloc( sizeof( KILL_INFO ) );
X		(**hdr)->fieldname = strdup( buf );
X		(**hdr)->fieldvalue = strdup( data );
X		(**hdr)->pattern = regcomp( data );
X		if ( (**hdr) -> pattern == NULL )
X			fprintf( stderr, "Bad kill pattern '%s'\n", data );
X		(**hdr)->next = NULLP( KILL_INFO );
X
X		/*
X		 *	Reset the hdr pointer so next call will continue chain correctly.
X		 */
X
X		*hdr = &((**hdr)->next);
X		rc = TRUE;
X		}
X	}
Xreturn rc;
X}
END_OF_FILE
if test 6070 -ne `wc -c <'kill.c'`; then
    echo shar: \"'kill.c'\" unpacked with wrong size!
fi
chmod +x 'kill.c'
# end of 'kill.c'
fi
if test -f 'kill.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kill.h'\"
else
echo shar: Extracting \"'kill.h'\" \(918 characters\)
sed "s/^X//" >'kill.h' <<'END_OF_FILE'
X/*
X *	File Name:		kill.h
X *	Project:		BARN - Bah's Amiga ReadNews.
X *	Purpose:		Define kill structures.
X *	Author:			Jeff Van Epps
X *	Created:		04 Sep 89
X *	Last Modified:	22 Oct 90
X *	Comments:
X *		Include "regexp.h" before "kill.h".
X *
X *	History:
X *		04 Sep 89/JVE	Created.
X *		22 Oct 90/JVE	New KILL_INFO structure includes regexp pattern.
X */
X
X/*
X *	A kill list is a list of kill_info structures.  An article matching any
X *	kill structure will be "killed".
X */
X
Xtypedef struct kill_info {
X	char				*fieldname;
X	char				*fieldvalue;
X	struct regexp		*pattern;
X	struct kill_info	*next;			/* ptr to next article in newsgroup */
X	} KILL_INFO;
X
X/*
X *	Function prototypes.
X */
X
X# ifdef sun
X
XKILL_INFO	*GetKillList();
Xvoid		PutKillList();
Xvoid		DestroyKillList();
X
X# else
X
XKILL_INFO	*GetKillList( char *filename );
Xvoid		PutKillList( char *filename, KILL_INFO *root );
Xvoid		DestroyKillList( KILL_INFO *root );
X
X# endif
END_OF_FILE
if test 918 -ne `wc -c <'kill.h'`; then
    echo shar: \"'kill.h'\" unpacked with wrong size!
fi
chmod +x 'kill.h'
# end of 'kill.h'
fi
if test -f 'ng.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ng.c'\"
else
echo shar: Extracting \"'ng.c'\" \(11353 characters\)
sed "s/^X//" >'ng.c' <<'END_OF_FILE'
X/*
X *	File Name:		ng.c
X *	Project:		BARN - Bah's Amiga ReadNews.
X *	Purpose:		Defines functions related to newsgroup list.
X *	Functions:		GetNewsRC, ReadNextMarker, PutNewsRC, DestroyNGList,
X *					NumberCovered, UpdateReadList, Mark.
X *	Author:			Jeff Van Epps
X *	Created:		03 Sep 89
X *	Last Modified:	14 Nov 90
X *	Comments:
X *	History:
X *		03 Sep 89/JVE	Created.
X *		21 Oct 90/JVE	Moved UpdateReadList, Mark from arn.c to here where
X *						they belong.
X *		14 Nov 90/JVE	Made sure a marker for article 0 gets created if
X *						no other articles have been read.
X */
X
X# include	<stdio.h>
X# include	<stdlib.h>
X# include	<string.h>
X# include	<fcntl.h>
X# include	"standard.h"
X# include	"article.h"
X# include	"ng.h"
X
X
X/****************************************************************************/
X/*	FUNCTION:	GetNewsRC													*/
X/*																			*/
X/*	PURPOSE:	Read/parse the .newsrc file.								*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		filename	 I		Name of file containing read newsgroups info.	*/
X/*																			*/
X/*	RETURNS:																*/
X/*																			*/
X/*	COMMENTS:																*/
X/*		Parses lines from user's .newsrc file to see which articles in		*/
X/*		which newsgroups have already been read.							*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	03 Sep 89		Created.										*/
X/*																			*/
X/****************************************************************************/
X
XNG_INFO	*GetNewsRC( filename )
X
Xchar		*filename;
X
X{
XNG_INFO		*root = NULLP( NG_INFO );	/* points to start of ng list */
XNG_INFO		**ptr = &root;				/* where to alloc next ng from */
XMARKER		**marker;					/* where to alloc next marker from */
XFILE		*fp;						/* pointer into .newsrc file */
Xchar		buf[BUFSIZ];
Xchar		*name;						/* newsgroup name */
X
Xif ( ( fp = fopen( filename, "r" ) ) == NULLP( FILE ) )
X	perror( filename );
Xelse
X	{
X	while ( fgets( buf, BUFSIZ, fp ) != NULLP( char ) )
X		{
X		if ( ( name = strtok( buf, " " ) ) == NULLP( char ) )
X			fprintf( stderr, "Bad line in %s: %s", filename, buf );
X		else
X			{
X			*ptr = (NG_INFO *) malloc( sizeof( NG_INFO ) );
X			(*ptr)->next = NULLP( NG_INFO );
X			(*ptr)->markers = NULLP( MARKER );
X			marker = &(*ptr)->markers;
X			while ( ReadNextMarker( &marker ) ) ;
X			(*ptr)->name = strdup( name );
X			ptr = &(*ptr)->next;
X			}
X		}
X	fclose( fp );
X	}
Xreturn root;
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	ReadNextMarker												*/
X/*																			*/
X/*	PURPOSE:	Parse next marker from line.								*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		marker		I/O		Pointer to pointer to next marker.				*/
X/*																			*/
X/*	RETURNS:																*/
X/*		TRUE		Marker parsed.											*/
X/*		FALSE		No marker parsed (end of input line).					*/
X/*																			*/
X/*	COMMENTS:																*/
X/*		markers = [ marker | marker + ',' + markers ]						*/
X/*		marker = [ XXX | XXX + '-' + YYY ]									*/
X/*																			*/
X/*		There may be a list of markers with each marker separated by a		*/
X/*		comma.  Each marker may be either a single number or two numbers	*/
X/*		separated by a dash indicating an inclusive range.  White space		*/
X/*		is not allowed anywhere.											*/
X/*																			*/
X/*		We assume that the string we are parsing has already been subject	*/
X/*		to a strtok() call so that we can just strtok(NULL,x) to continue	*/
X/*		parsing the same string.											*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	03 Sep 89		Created.										*/
X/*																			*/
X/****************************************************************************/
X
XReadNextMarker( marker )
X
XMARKER		***marker;
X
X{
Xint			rc = FALSE;
Xchar		*p, *q;
X
Xif ( ( p = strtok( NULLP( char ), "," ) ) != NULLP( char ) )
X	{
X	**marker = (MARKER *) malloc( sizeof( MARKER ) );
X	(**marker)->next = NULLP( MARKER );
X	(**marker)->from = atol( p );
X	if ( ( q = strchr( p, '-' ) ) != NULLP( char ) )
X		(**marker)->to = atol( ++q );
X	else
X		(**marker)->to = 0L;
X	*marker = &(**marker)->next;
X	rc = TRUE;
X	}
Xreturn rc;
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	PutNewsRC													*/
X/*																			*/
X/*	PURPOSE:	Write read article markers to .newsrc file.					*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		filename	 I		Name of file to which to write .newsrc info.	*/
X/*		root		 I		List of already read articles.					*/
X/*																			*/
X/*	RETURNS: none															*/
X/*																			*/
X/*	COMMENTS:																*/
X/*		Tries to save old .newsrc file as .newsrc.BAK before writing new	*/
X/*		one.																*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	03 Sep 89		Created.										*/
X/*																			*/
X/****************************************************************************/
X
Xvoid PutNewsRC( filename, root )
X
Xchar		*filename;
XNG_INFO		*root;
X
X{
Xchar		backup[BUFSIZ], temp[BUFSIZ];
XFILE		*fp;
XMARKER		*ptr;
X
Xsprintf( backup, "%s.BAK", filename );
X(void) remove( backup );
Xif ( rename( filename, backup ) )
X	{
X	sprintf( temp, "rename(%s,%s)", filename, backup );
X	perror( temp );
X	}
Xelse
X	{
X	if ( ( fp = fopen( filename, "a" ) ) == NULLP( FILE ) )
X		perror( filename );
X	else 
X		{
X		while ( root != NULLP( NG_INFO ) )
X			{
X			fprintf( fp, "%s ", root->name );
X			for ( ptr = root->markers; ptr != NULLP( MARKER ); )
X				{
X				fprintf( fp, "%ld", ptr->from );
X				if ( ptr->to > 0L )
X					fprintf( fp, "-%ld", ptr->to );
X				if ( ptr = ptr->next )
X					fprintf( fp, "," );
X				}
X			fprintf( fp, "\n" );
X			root = root->next;
X			}
X		fclose( fp );
X		}
X	}
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	DestroyNGList												*/
X/*																			*/
X/*	PURPOSE:	Free memory taken by newsgroup list.						*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		root		 I		Pointer to list of newsgroups.					*/
X/*																			*/
X/*	RETURNS: none															*/
X/*																			*/
X/*	COMMENTS:																*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	03 Sep 89		Created.										*/
X/*																			*/
X/****************************************************************************/
X
Xvoid DestroyNGList( root )
X
XNG_INFO		*root;
X
X{
XMARKER		*ptr, *tmp;
XNG_INFO		*next;
X
Xwhile ( root != NULLP( NG_INFO ) )
X	{
X	for ( ptr = root->markers; ptr != NULLP( MARKER ); ptr = tmp )
X		{
X		tmp = ptr->next;
X		free( ptr );
X		}
X	free( root->name );
X	next = root->next;
X	free( root );
X	root = next;
X	}
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	NumberCovered												*/
X/*																			*/
X/*	PURPOSE:	Check whether number is covered by markers.					*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		markers		 I		Marker list.									*/
X/*		number		 I		Number to be checked.							*/
X/*																			*/
X/*	RETURNS:																*/
X/*		TRUE		If number is in list.									*/
X/*		FALSE		If number is not in list.								*/
X/*																			*/
X/*	COMMENTS:																*/
X/*		Markers are assumed to be sorted low->high and non-overlapping.		*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	04 Sep 89		Created.										*/
X/*																			*/
X/****************************************************************************/
X
XNumberCovered( markers, number )
X
XMARKER		*markers;
Xlong		number;
X
X{
Xint			rc = FALSE;
X
Xwhile ( !rc && markers != NULLP( MARKER ) )
X	{
X	if ( markers->from > number )
X		break;
X	else if ( markers->from == number )
X		rc = TRUE;
X	else if ( markers->to >= number )
X		rc = TRUE;
X	markers = markers->next;
X	}
Xreturn rc;
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	UpdateReadList												*/
X/*																			*/
X/*	PURPOSE:	Update the list of articles read due to newly read ones.	*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		ng			I/O		List of read articles.							*/
X/*		new			 I		List containing some newly read articles.		*/
X/*																			*/
X/*	RETURNS: none															*/
X/*																			*/
X/*	COMMENTS:																*/
X/*		Look for articles which are STILL unread, and make a list which		*/
X/*		marks everything except those. If nothing is left unread, the list	*/
X/*		should mark to the greater of the previously highest read article	*/
X/*		and the highest newly read article.									*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	04 Sep 89		Created.										*/
X/*		2.	16 Dec 89		Fixed bug in last mark if last article unread.	*/
X/*		3.	14 Nov 90		Make sure *something* gets marked, i.e. 0-0 if	*/
X/*							nothing else.									*/
X/*																			*/
X/****************************************************************************/
X
Xvoid	UpdateReadList( ng, new )
X
XNG_INFO				*ng;
XARTICLE_INFO		*new;
X
X{
Xlong				beginning, ending;
XMARKER				**where;		/* where to allocate next marker */
XMARKER				*first = NULL;	/* ptr to beginning of new marker list */
XMARKER				*ptr, *tmp;
X
Xfor ( ptr = ng->markers; ptr != NULLP( MARKER ); ptr = tmp )
X	{
X	if ( ptr->to != 0L )
X		ending = ptr->to;
X	else
X		ending = ptr->from;
X	tmp = ptr->next;
X	free( ptr );
X	}
Xbeginning = 1L;
Xwhere = &first;
Xfor ( ; new != NULLP( ARTICLE_INFO ); new = new->next )
X	{
X	if ( ! new->beenread )
X		{
X		if ( new->number != beginning && beginning <= ending )
X			{
X			*where = Mark( beginning, new->number - 1L );
X			where = & (*where)->next;
X			}
X		beginning = new->number + 1L;
X		}
X	else if ( new->number > ending )
X		ending = new->number;
X	}
Xif ( beginning <= ending )
X	*where = Mark( beginning, ending );
X/*
X *	If no markers have been created, create one for article # 0.
X */
Xif ( first == NULL )
X	*where = Mark( 0L, 0L );
Xng->markers = first;
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	Mark														*/
X/*																			*/
X/*	PURPOSE:	Create a marker.											*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		begin		 I		From part of marker.							*/
X/*		end			 I		To part of marker.								*/
X/*																			*/
X/*	RETURNS:																*/
X/*		(MARKER *)			Pointer to new marker.							*/
X/*																			*/
X/*	COMMENTS:																*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	05 Sep 89		Created.										*/
X/*																			*/
X/****************************************************************************/
X
XMARKER	*Mark( begin, end )
X
Xlong			begin, end;
X
X{
XMARKER			*ptr;
X
Xptr = (MARKER *) malloc( sizeof( MARKER ) );
Xptr->from = begin;
Xif ( begin == end )
X	ptr->to = 0L;
Xelse
X	ptr->to = end;
Xptr->next = NULLP( MARKER );
Xreturn ptr;
X}
X
END_OF_FILE
if test 11353 -ne `wc -c <'ng.c'`; then
    echo shar: \"'ng.c'\" unpacked with wrong size!
fi
chmod +x 'ng.c'
# end of 'ng.c'
fi
if test -f 'ng.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ng.h'\"
else
echo shar: Extracting \"'ng.h'\" \(1491 characters\)
sed "s/^X//" >'ng.h' <<'END_OF_FILE'
X/*
X *	File Name:		ng.h
X *	Project:		BARN - Bah's Amiga ReadNews.
X *	Purpose:		Define newsgroup structures.
X *	Author:			Jeff Van Epps
X *	Created:		02 Sep 89
X *	Last Modified:	21 Oct 90
X *	History:
X *		02 Sep 89/JVE	Created.
X *		21 Oct 90/JVE	Added declarations for UpdateReadList, Mark.
X */
X
X/*
X *	MARKER is used to mark either a single number or a range. If to==0,
X *	from indicates the single number to be marked. Otherwise all numbers
X *	between and including from and to should be marked.
X */
X
Xtypedef struct marker_info {
X	long				from, to;	/* article numbers */
X	struct marker_info	*next;		/* pointer to next marker record */
X	} MARKER;
X
X/*
X *	NG_INFO records names of newsgroups and which articles have been read
X *	in each newsgroup.
X */
X
Xtypedef struct ng_info {
X	char			*name;			/* name of newsgroup */
X	MARKER			*markers;		/* ptr to list of article #s read */
X	struct ng_info	*next;			/* ptr to next newsgroup in list */
X	} NG_INFO;
X
X/*
X *	Function prototypes.
X */
X
X# ifdef sun
X
XNG_INFO		*GetNewsRC();
Xint			ReadNextMarker();
Xvoid		PutNewsRC();
Xvoid		DestroyNGList();
Xint			NumberCovered();
Xvoid		UpdateReadList();
XMARKER *	Mark();
X
X# else
X
XNG_INFO		*GetNewsRC( char *filename );
Xint			ReadNextMarker( MARKER ***marker );
Xvoid		PutNewsRC( char *filename, NG_INFO *alreadyread );
Xvoid		DestroyNGList( NG_INFO *alreadyread );
Xint			NumberCovered( MARKER *marker, long number );
Xvoid		UpdateReadList( NG_INFO *ng, ARTICLE_INFO *new );
XMARKER *	Mark( long begin, long end );
X
X# endif
END_OF_FILE
if test 1491 -ne `wc -c <'ng.h'`; then
    echo shar: \"'ng.h'\" unpacked with wrong size!
fi
chmod +x 'ng.h'
# end of 'ng.h'
fi
if test -f 'raw.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'raw.c'\"
else
echo shar: Extracting \"'raw.c'\" \(2268 characters\)
sed "s/^X//" >'raw.c' <<'END_OF_FILE'
X/*
X * raw.c 
X *
X * This is a routine for setting a given stream to raw or cooked mode on the
X * Amiga . This is useful when you are using Lattice C to produce programs
X * that want to read single characters with the "getch()" or "fgetc" call. 
X *
X * Written : 18-Jun-87 By Chuck McManis.
X */
X#include <exec/types.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <stdio.h>
X
X#include <ios1.h>
X#include <error.h>
X
Xextern int      errno;		/* The error variable */
X
X/*
X * Function raw() - Convert the specified file pointer to 'raw' mode. This
X * only works on TTY's and essentially keeps DOS from translating keys for
X * you, also (BIG WIN) it means getch() will return immediately rather than
X * wait for a return. You lose editing features though. 
X */
Xlong
Xraw(fp)
X    FILE           *fp;
X
X{
X    struct MsgPort *mp;		/* The File Handle message port */
X    struct FileHandle *afh;
X    struct UFB     *ufb;
X    long            Arg[1], res;
X
X    ufb = (struct UFB *) chkufb(fileno(fp));	/* Step one, get the file
X						 * handle */
X    afh = (struct FileHandle *) (ufb->ufbfh);
X
X    if (!IsInteractive(afh)) {	/* Step two, check to see if it's a console */
X	errno = ENOTTY;
X	return (-1);
X    }
X    /* Step three, get it's message port. */
X    mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
X    Arg[0] = -1L;
X    res = SendPacket(mp, ACTION_SCREEN_MODE, Arg, 1);	/* Put it in RAW: mode */
X    if (res == 0) {
X	errno = ENXIO;
X	return (-1);
X    }
X    return (0);
X}
X
X/*
X * Function - cooked() this function returns the designate file pointer to
X * it's normal, wait for a <CR> mode. This is exactly like raw() except that
X * it sends a 0 to the console to make it back into a CON: from a RAW: 
X */
X
Xlong
Xcooked(fp)
X    FILE           *fp;
X
X{
X    struct MsgPort *mp;		/* The File Handle message port */
X    struct FileHandle *afh;
X    struct UFB     *ufb;
X    long            Arg[1], res;
X
X    ufb = (struct UFB *) chkufb(fileno(fp));
X    afh = (struct FileHandle *) (ufb->ufbfh);
X    if (!IsInteractive(afh)) {
X	errno = ENOTTY;
X	return (-1);
X    }
X    mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
X    Arg[0] = 0;
X    res = SendPacket(mp, ACTION_SCREEN_MODE, Arg, 1);
X    if (res == 0) {
X	errno = ENXIO;
X	return (-1);
X    }
X    return (0);
X}
END_OF_FILE
if test 2268 -ne `wc -c <'raw.c'`; then
    echo shar: \"'raw.c'\" unpacked with wrong size!
fi
chmod +x 'raw.c'
# end of 'raw.c'
fi
if test -f 'reply.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'reply.c'\"
else
echo shar: Extracting \"'reply.c'\" \(8860 characters\)
sed "s/^X//" >'reply.c' <<'END_OF_FILE'
X/*
X *	File Name:		reply.c
X *	Project:		BARN - Bah's Amiga ReadNews.
X *	Purpose:		Reply via email and post followup article functions.
X *	Functions:		Reply, Followup, IncludeArticle, Sign.
X *	Author:			Jeff Van Epps
X *	Created:		21 Oct 90
X *	Last Modified:	05 Jan 91
X *	Comments:
X *	History:
X *		21 Oct 90/JVE	Created.
X *		14 Nov 90/JVE	Post news by mailing article to inews@bisco rather
X *						than <newsgroup>@ucbvax.berkeley.edu.  Only mail the
X *						article if the user saved his edit.  Same for
X *						email replies.
X *		05 Jan 91/JVE	Use article->subject optimization.
X */
X
X# include	<stdio.h>
X# include	<stdlib.h>
X# include	<string.h>
X# include	<time.h>
X# include	<sys/types.h>
X# include	<sys/stat.h>
X# include	"standard.h"
X# include	"configure.h"
X# include	"variables.h"
X# include	"article.h"
X# include	"reply.h"
X
X# ifdef sun
X
X# define	DEFAULT_EDITOR	"vi"
X# define	TEMPFILE		"/tmp/arnreply"
X
X# else  /* not sun */
X
X# define	DEFAULT_EDITOR	"stevie"
X# define	TEMPFILE		"T:arnreply"
X
X# endif /* sun */
X
X
X/****************************************************************************/
X/*	FUNCTION:	Reply														*/
X/*																			*/
X/*	PURPOSE:	Send a reply to a news article via mail.					*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		article		 I		Article to reply to.							*/
X/*		include		 I		Include article in reply?						*/
X/*																			*/
X/*	RETURNS: none															*/
X/*																			*/
X/*	COMMENTS:																*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	17 Oct 90		Created.										*/
X/*		2.	14 Nov 90		Do not invoke mailer if user has not edited.	*/
X/*																			*/
X/****************************************************************************/
X
Xvoid Reply( article, include )
X
XARTICLE_INFO		*article;
Xint					include;
X
X{
XFILE				*fp;
Xchar				*from, *address, *editor, *hdr;
Xchar				cmd[MAXLINE], temp[MAXLINE];
Xlong				clock;							/* current date & time */
Xint					header_found = FALSE;			/* parsed To: yet? */
Xstruct stat			stats_before, stats_after;
X
Xremove( TEMPFILE );
Xif ( ( fp = fopen( TEMPFILE, "a" ) ) == NULL )
X	{
X	perror( TEMPFILE );
X	return;
X	}
Xtime( &clock );
Xfprintf( fp, "From %s %24.24s remote from %s\n", GetVar( VAR_USER), 
X  ctime( &clock ), GetVar( VAR_NODE ) );
Xfprintf( fp, "Date: %s", ctime( &clock ) );
Xfprintf( fp, "From: %s!%s@%s (%s)\n", GetVar( VAR_NODE ), GetVar( VAR_USER ), 
X  GetVar( VAR_DOMAIN ), GetVar( VAR_NAME ) );
X/*
X *	Use everything after From: up to the first space.
X */
Xfrom = strtok( GetHeader( article -> headers, HDR_FROM ), " \n\r" );
Xfprintf( fp, "%s: %s\n", HDR_TO, from );
Xfprintf( fp, "%s: \n", HDR_CC );
Xfprintf( fp, "%s: %s\n\n", HDR_SUBJECT, article -> subject );
Xif ( include )
X	IncludeArticle( article, fp );
XSign( fp );
Xfclose( fp );
X(void) stat( TEMPFILE, &stats_before );
Xif ( ( editor = GetVar( VAR_EDITOR ) ) == NULL )
X	editor = DEFAULT_EDITOR;
Xsprintf( cmd, "%s %s", editor, TEMPFILE );
Xsystem( cmd );
X(void) stat( TEMPFILE, &stats_after );
Xif ( stats_after.st_mtime != stats_before.st_mtime )
X	{
X	if ( ( fp = fopen( TEMPFILE, "r" ) ) == NULL )
X		{
X		perror( TEMPFILE );
X		return;
X		}
X	while ( ! header_found && fgets( temp, MAXLINE, fp ) != NULL )
X		{
X		if ( ( hdr = strtok( temp, ": " ) ) != NULL && strcmp( hdr, HDR_TO ) == 0 )
X			header_found = TRUE;
X		}
X	if ( ! header_found )
X		{
X		printf( "Header messed!\n" );
X		fclose( fp );
X		return;
X		}
X	if ( ( address = strtok( NULL, " " ) ) == NULL )
X		{
X		printf( "No address given!\n" );
X		fclose( fp );
X		return;
X		}
X	fclose( fp );
X	sprintf( cmd, "rmail <%s >NULL: %s", TEMPFILE, address );
X	system( cmd );
X	}
Xelse
X	{
X	printf( "File not modified.  Mail not sent.  Hit any key.\n" );
X	getchar();
X	}
Xremove( TEMPFILE );
X}
X
X/****************************************************************************/
X/*	FUNCTION:	Followup													*/
X/*																			*/
X/*	PURPOSE:	Post news article as a reply to a news article.				*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		newsgroup	 I		Name of newsgroup.								*/
X/*		article		 I		Article to followup.							*/
X/*		include		 I		Include article in reply?						*/
X/*																			*/
X/*	RETURNS: none															*/
X/*																			*/
X/*	COMMENTS:																*/
X/*		Changed to send mail to inews@bisco.  Newsgroup name is embedded	*/
X/*		in the article.														*/
X/*																			*/
X/*		The newsgroup name has all dots or slashes turned into dashes, then	*/
X/*		mail is sent to <modified newsgroup name>@ucbvax.berkeley.edu,		*/
X/*		which is a gateway for posting.										*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	17 Oct 90		Created.										*/
X/*		2.	14 Nov 90		Mail to bisco rather than Berkeley.  Only		*/
X/*							mail the article if it has been edited by user.	*/
X/*																			*/
X/****************************************************************************/
X
Xvoid Followup( newsgroup, article, include )
X
Xchar				*newsgroup;
XARTICLE_INFO		*article;
Xint					include;
X
X{
XFILE				*fp;
Xchar				*editor;
Xchar				cmd[MAXLINE];
Xlong				clock;							/* current date & time */
Xstruct stat			stats_before, stats_after;
X
Xremove( TEMPFILE );
Xif ( ( fp = fopen( TEMPFILE, "a" ) ) == NULL )
X	{
X	perror( TEMPFILE );
X	return;
X	}
Xtime( &clock );
Xfprintf( fp, "From %s %24.24s remote from %s\n", GetVar( VAR_USER ), 
X  ctime( &clock ), GetVar( VAR_NODE ) );
Xfprintf( fp, "Date: %s", ctime( &clock ) );
Xfprintf( fp, "From: %s!%s@%s (%s)\n", GetVar( VAR_NODE ), GetVar( VAR_USER ), 
X  GetVar( VAR_DOMAIN ), GetVar( VAR_NAME ) );
Xfprintf( fp, "%s: %s\n", HDR_SUBJECT, article -> subject );
Xfprintf( fp, "Newsgroups: %s\n", newsgroup );
Xfprintf( fp, "Followup-To: %s\n", newsgroup );
Xfprintf( fp, "Distribution: world\n" );
Xfprintf( fp, "Reply-To: %s!%s@%s\n", GetVar( VAR_NODE ), GetVar( VAR_USER ),
X  GetVar( VAR_DOMAIN ) );
Xfprintf( fp, "\n" );		/* separate headers from body of article */
Xif ( include )
X	IncludeArticle( article, fp );
XSign( fp );
Xfclose( fp );
X(void) stat( TEMPFILE, &stats_before );
Xif ( ( editor = GetVar( VAR_EDITOR ) ) == NULL )
X	editor = DEFAULT_EDITOR;
Xsprintf( cmd, "%s %s", editor, TEMPFILE );
Xsystem( cmd );
X(void) stat( TEMPFILE, &stats_after );
Xif ( stats_after.st_mtime != stats_before.st_mtime )
X	{
X	sprintf( cmd, "rmail <%s >NULL: inews@bisco", TEMPFILE );
X	system( cmd );
X	}
Xelse
X	{
X	printf( "File not modified.  Article not posted.  Hit any key.\n" );
X	getchar();
X	}
Xremove( TEMPFILE );
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	IncludeArticle												*/
X/*																			*/
X/*	PURPOSE:	Copy article text to file as an inclusion.					*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		article		 I		Article being included.							*/
X/*		output		 I		File being written into.						*/
X/*																			*/
X/*	RETURNS: none															*/
X/*																			*/
X/*	COMMENTS:																*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	21 Oct 90 		Created.										*/
X/*																			*/
X/****************************************************************************/
X
Xvoid IncludeArticle( article, output )
X
XARTICLE_INFO			*article;
XFILE					*output;
X
X{
Xchar					filename[MAXLINE];
Xchar					s[MAXLINE];
XFILE					*art;
X
Xsprintf( filename, "%ld", article -> number );
Xif ( ( art = fopen( filename, "r" ) ) == NULL )
X	printf( "CAN'T OPEN ARTICLE FOR INCLUDE!\n" );
Xelse
X	{
X	fseek( art, article -> textpos, 0 );
X	while ( fgets( s, MAXLINE, art ) != NULL )
X		fprintf( output, "> %s", s );
X	fclose( art );
X	}
X}
X
X
X/****************************************************************************/
X/*	FUNCTION:	Sign														*/
X/*																			*/
X/*	PURPOSE:	Append users .signature.									*/
X/*																			*/
X/*	INPUT PARAMETERS:														*/
X/*		NAME		I/O		DESCRIPTION										*/
X/*		----		---		-----------										*/
X/*		output		 I		File being written to.							*/
X/*																			*/
X/*	RETURNS: none															*/
X/*																			*/
X/*	COMMENTS:																*/
X/*		There is no default .signature file.								*/
X/*																			*/
X/*	HISTORY:																*/
X/*		1.	21 Oct 90		Created.										*/
X/*																			*/
X/****************************************************************************/
X
Xvoid Sign( output )
X
XFILE				*output;
X
X{
XFILE				*sig;
Xchar				*sig_file;		/* filename for .signature */
Xchar				s[MAXLINE];
X
Xif ( ( sig_file = GetVar( VAR_SIGN ) ) != NULL && 
X  ( sig = fopen( sig_file, "r" ) ) != NULL )
X	{
X	while ( fgets( s, MAXLINE, sig ) != NULL )
X		fprintf( output, "%s", s );
X	fclose( sig );
X	}
X}
END_OF_FILE
if test 8860 -ne `wc -c <'reply.c'`; then
    echo shar: \"'reply.c'\" unpacked with wrong size!
fi
chmod +x 'reply.c'
# end of 'reply.c'
fi
if test -f 'reply.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'reply.h'\"
else
echo shar: Extracting \"'reply.h'\" \(644 characters\)
sed "s/^X//" >'reply.h' <<'END_OF_FILE'
X/*
X *	File Name:		reply.h
X *	Project:		BARN - Bah's Amiga ReadNews.
X *	Purpose:		Reply and Followup functions.
X *	Author:			Jeff Van Epps
X *	Created:		21 Oct 90
X *	Last Modified:	21 Oct 90
X *	Comments:
X *	History:
X *		21 Oct 90/JVE	Created.
X */
X
X# ifdef sun
X
Xextern void		Reply();
Xextern void		Followup();
Xextern void		IncludeArticle();
Xextern void		Sign();
X
X# else  /* amiga */
X
Xextern void		Reply( ARTICLE_INFO *article, int include );
Xextern void		Followup( char *newsgroup, ARTICLE_INFO *article, int include );
Xextern void		IncludeArticle( ARTICLE_INFO *article, FILE *output );
Xextern void		Sign( FILE *output );
X
X# endif /* sun/amiga */
END_OF_FILE
if test 644 -ne `wc -c <'reply.h'`; then
    echo shar: \"'reply.h'\" unpacked with wrong size!
fi
chmod +x 'reply.h'
# end of 'reply.h'
fi
if test -f 'screenstuff.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'screenstuff.h'\"
else
echo shar: Extracting \"'screenstuff.h'\" \(871 characters\)
sed "s/^X//" >'screenstuff.h' <<'END_OF_FILE'
X/*
X *	File Name:		screenstuff.h
X *	Project:		BARN - Bah's Amiga ReadNews.
X *	Purpose:		Screen attribute defines.
X *	Author:			Jeff Van Epps
X *	Created:		06 Jan 91
X *	Last Modified:	06 Jan 91
X *	Comments:
X *		If compiling on a Sun we try to use the System V version of the
X *		curses library.  On the Amiga we use ANSI sequences.
X *
X *	History:
X *		06 Jan 91/JVE	Created.
X */
X
X
X# ifdef sun
X
X# include	<curses.h>
X# define	Clear_Screen	clear()
X# define	UL_ON			attron( A_UNDERLINE )
X# define	UL_OFF			attroff( A_UNDERLINE )
X# define	INVERSE_ON		attron( A_REVERSE )
X# define	INVERSE_OFF		attroff( A_REVERSE )
X
X# else  /* not sun */
X
X# define Clear_Screen printf("\x1b[H\x1b[2J")
X# define	UL_ON			printf( "\x1b[4m" )
X# define	UL_OFF			printf( "\x1b[0m" )
X# define	INVERSE_ON		printf("\x9b\x37;38;40m")
X# define	INVERSE_OFF		printf("\x9b\x30;33;40m\033[0m")
X
X# endif /* sun */
END_OF_FILE
if test 871 -ne `wc -c <'screenstuff.h'`; then
    echo shar: \"'screenstuff.h'\" unpacked with wrong size!
fi
chmod +x 'screenstuff.h'
# end of 'screenstuff.h'
fi
if test -f 'sendpacket.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sendpacket.c'\"
else
echo shar: Extracting \"'sendpacket.c'\" \(2093 characters\)
sed "s/^X//" >'sendpacket.c' <<'END_OF_FILE'
X/*
X * Sendpacket.c 
X *
X * An invaluable addition to your Amiga.lib file. This code sends a packet the
X * given message port. This makes working around DOS lots easier. 
X *
X * Note, I didn't write this, those wonderful folks at CBM did. I do suggest
X * however that you may wish to add it to Amiga.Lib, to do so, compile it and
X * say 'oml lib:amiga.lib -r sendpacket.o' 
X */
X
X#include <exec/types.h>
X#include <exec/ports.h>
X#include <exec/memory.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X
X/*
X * Function - SendPacket written by Phil Lindsay, Carolyn Scheppner, and Andy
X * Finkel. This function will send a packet of the given type to the Message
X * Port supplied. 
X */
X
Xlong
XSendPacket(pid, action, args, nargs)
X    struct MsgPort *pid;	/* process indentifier ... (handlers message
X				 * port ) */
X    long            action,	/* packet type ... (what you want handler to
X				 * do )   */
X                    args[],	/* a pointer to a argument list */
X                    nargs;	/* number of arguments in list  */
X{
X    struct MsgPort *replyport;
X    struct StandardPacket *packet;
X
X    long            count, *pargs, res1;
X
X    replyport = (struct MsgPort *) CreatePort(NULL, 0);
X    if (!replyport)
X	return (0);
X
X    /* Allocate space for a packet, make it public and clear it */
X    packet = (struct StandardPacket *)
X	AllocMem((long) sizeof(struct StandardPacket), MEMF_PUBLIC | MEMF_CLEAR);
X    if (!packet) {
X	DeletePort(replyport);
X	return (0);
X    }
X    packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
X    packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
X    packet->sp_Pkt.dp_Port = replyport;
X    packet->sp_Pkt.dp_Type = action;
X
X    /* copy the args into the packet */
X    pargs = &(packet->sp_Pkt.dp_Arg1);	/* address of first argument */
X    for (count = 0; count < nargs; count++)
X	pargs[count] = args[count];
X
X    PutMsg(pid, packet);	/* send packet */
X
X    WaitPort(replyport);
X    GetMsg(replyport);
X
X    res1 = packet->sp_Pkt.dp_Res1;
X
X    FreeMem(packet, (long) sizeof(struct StandardPacket));
X    DeletePort(replyport);
X
X    return (res1);
X}
END_OF_FILE
if test 2093 -ne `wc -c <'sendpacket.c'`; then
    echo shar: \"'sendpacket.c'\" unpacked with wrong size!
fi
chmod +x 'sendpacket.c'
# end of 'sendpacket.c'
fi
if test -f 'standard.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'standard.h'\"
else
echo shar: Extracting \"'standard.h'\" \(535 characters\)
sed "s/^X//" >'standard.h' <<'END_OF_FILE'
X/*
X *  File:			standard.h
X *  Purpose:		Stuff I standardly use.
X *  Functions:
X *  Created:		25 Nov 1988
X *  Last Modified:	19 Oct 1990
X *  Comments:
X *  History:
X *		19 Oct 90/JVE	Added ifdef sun.
X */
X
X/*
X *  NULL pointer to some type.
X */
X
X# define	NULLP( typ )            ( (typ *) 0 )
X
X# undef ERROR
X# define	ERROR				( -1 )
X# undef OK
X# define	OK					0
X
X# undef TRUE
X# define	TRUE				1
X# undef FALSE
X# define	FALSE				0
X
X# define	MAXLINE 			255
X
X# ifdef sun
X
X/*
X *	Delete file.
X */
X
X# define	remove( x )			unlink( (x) )
X
X# endif 
END_OF_FILE
if test 535 -ne `wc -c <'standard.h'`; then
    echo shar: \"'standard.h'\" unpacked with wrong size!
fi
chmod +x 'standard.h'
# end of 'standard.h'
fi
if test -f 'trim.sksh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'trim.sksh'\"
else
echo shar: Extracting \"'trim.sksh'\" \(199 characters\)
sed "s/^X//" >'trim.sksh' <<'END_OF_FILE'
X# Delete news articles over one day old.
Xlc:touch .news* arn.config trim.sksh
Xlc:touch save/*
Xfind uunews: -name "KILL*" -exec lc:touch "{}" ";"
Xfind uunews: -mtime +1 -type f -exec delete "{}" ";"
X
END_OF_FILE
if test 199 -ne `wc -c <'trim.sksh'`; then
    echo shar: \"'trim.sksh'\" unpacked with wrong size!
fi
chmod +x 'trim.sksh'
# end of 'trim.sksh'
fi
if test -f 'variables.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'variables.h'\"
else
echo shar: Extracting \"'variables.h'\" \(635 characters\)
sed "s/^X//" >'variables.h' <<'END_OF_FILE'
X/*
X *	File Name:		variables.h
X *	Project:		BARN - Bah's Amiga ReadNews.
X *	Purpose:		Define names of configuration variables.
X *	Author:			Jeff Van Epps
X *	Created:		20 Oct 90
X *	Last Modified:	25 Nov 90
X *	Comments:
X *	History:
X *		20 Oct 90/JVE	Created.
X *		25 Nov 90/JVE	Added noscroll.
X */
X
X# define	VAR_USER		"user"
X# define	VAR_NODE		"node"
X# define	VAR_DOMAIN		"domain"
X# define	VAR_EDITOR		"editor"
X# define	VAR_NAME		"name"
X# define	VAR_NEWSRC		"newsrc"
X# define	VAR_KILL		"kill"
X# define	VAR_SIGN		"signature"
X# define	VAR_BBS			"bbs"
X# define	VAR_LINES		"lines"
X# define	VAR_COLS		"columns"
X# define	VAR_NOSCROLL	"noscroll"
END_OF_FILE
if test 635 -ne `wc -c <'variables.h'`; then
    echo shar: \"'variables.h'\" unpacked with wrong size!
fi
chmod +x 'variables.h'
# end of 'variables.h'
fi
echo shar: End of archive 1 \(of 2\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.misc.