[comp.sources.unix] v12i032: C News alpha release, Part07/14

rsalz@uunet.UU.NET (Rich Salz) (10/22/87)

Submitted-by: utzoo!henry (Henry Spencer)
Posting-number: Volume 12, Issue 32
Archive-name: cnews/part07


#! /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 7 (of 14)."
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'input/newsspool.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'input/newsspool.c'\"
else
echo shar: Extracting \"'input/newsspool.c'\" \(4040 characters\)
sed "s/^X//" >'input/newsspool.c' <<'END_OF_FILE'
X/*
X * newsspool - copy incoming news into incoming directory
X *
X * $Log$
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <string.h>
X#include "news.h"
X#include "newspaths.h"
X
X#ifndef lint
Xstatic char RCSid[] = "$Header$";
X#endif
X
Xint debug = 0;
Xchar *progname;
X
Xextern void error(), exit();
X#ifdef UTZOOERR
Xextern char *mkprogname();
X#else
X#define	mkprogname(a)	(a)
X#endif
X
Xchar buf[BUFSIZ*10];	/* try to get a batch in a few gulps */
X
Xvoid process();
XFILE *outopen();
Xvoid outclose();
Xextern time_t time();
X
X/*
X - main - parse arguments and handle options
X */
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	int c;
X	int errflg = 0;
X	FILE *in;
X	struct stat statbuf;
X	extern int optind;
X	extern char *optarg;
X	extern FILE *efopen();
X	void process();
X
X	progname = mkprogname(argv[0]);
X
X	while ((c = getopt(argc, argv, "d")) != EOF)
X		switch (c) {
X		case 'd':	/* Debugging. */
X			debug++;
X			break;
X		case '?':
X		default:
X			errflg++;
X			break;
X		}
X	if (errflg) {
X		fprintf(stderr, "usage: %s [file] ...\n", progname);
X		exit(2);
X	}
X
X	(void) umask(newsumask());
X
X	if (optind >= argc)
X		process(stdin, "stdin");
X	else
X		for (; optind < argc; optind++)
X			if (STREQ(argv[optind], "-"))
X				process(stdin, "-");
X			else {
X				in = efopen(argv[optind], "r");
X				if (fstat(fileno(in), &statbuf) < 0)
X					error("can't fstat `%s'", argv[optind]);
X				if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
X					error("`%s' is directory!", argv[optind]);
X				process(in, argv[optind]);
X				(void) fclose(in);
X			}
X	exit(0);
X}
X
X/*
X * process - process input file
X */
Xvoid
Xprocess(in, inname)
XFILE *in;
Xchar *inname;
X{
X	register int count;
X	register int first;
X	FILE *out;
X	register char *p;
X	register int n;
X	char outname[MAXFILE];
X
X	out = outopen(outname);
X
X	/* do the copying */
X	first = 1;
X	while ((count = fread(buf, sizeof(char), sizeof(buf), in)) > 0) {
X		if (first) {
X			n = cunskip(buf, count);
X			p = buf + n;
X			count -= n;
X			first = 0;
X		} else
X			p = buf;
X		n = fwrite(p, sizeof(char), count, out);
X		if (n != count)
X			error("write error in output to `%s'", outname);
X	}
X
X	outclose(out, outname);
X}
X
X/*
X - outopen - acquire an output file
X */
XFILE *
Xoutopen(name)
Xchar *name;			/* not the name, but rather space for it */
X{
X	FILE *f;
X
X	(void) strcpy(name, libfile("incoming/ns.XXXXXX"));
X	mktemp(name);
X	f = fopen(name, "w");
X	if (f == NULL)
X		error("unable to create temporary `%s'", name);
X	if (debug)
X		fprintf(stderr, "output into %s\n", name);
X
X	return(f);
X}
X
X/*
X - outclose - close output file, moving it to the right place
X *
X * Names are based on the current time in hopes of keeping input in order.
X */
Xvoid
Xoutclose(f, tmpname)
XFILE *f;
Xchar *tmpname;
X{
X	char name[MAXFILE];
X	register char *p;
X	time_t now;
X
X	if (fclose(f) == EOF)
X		error("fclose error on file `%s'", tmpname);
X
X	(void) strcpy(name, libfile("incoming/"));
X	p = name + strlen(name);
X
X	for (;;) {
X		now = time((time_t *)NULL);
X		sprintf(p, "%ld", now);
X		if (debug)
X			fprintf(stderr, "trying renaming to %s\n", name);
X		if (link(tmpname, name) >= 0)
X			break;
X		if (debug)
X			fprintf(stderr, "failed\n");
X		sleep(1);
X	}
X	if (debug)
X		fprintf(stderr, "succeeded\n");
X	(void) unlink(tmpname);
X}
X
X/*
X - cunskip - inspect block for silly #! cunbatch header
X */
Xint				/* number of chars at start to skip */
Xcunskip(bufp, count)
Xchar *bufp;
Xint count;
X{
X	static char goop[] = "cunbatch";
X#	define	GOOPLEN	(sizeof(goop)-1)	/* strlen(goop) */
X	register char *p;
X	register int nleft;
X
X	nleft = count;
X	p = bufp;
X
X	if (nleft < 2)
X		return(0);
X	if (*p++ != '#' || *p++ != '!')
X		return(0);
X	nleft -= 2;
X
X	while (nleft > 0 && (*p == ' ' || *p == '\t')) {
X		p++;
X		nleft--;
X	}
X
X	if (nleft < sizeof(goop))	/* NUL on goop covers newline */
X		return(0);
X	if (!STREQN(p, goop, GOOPLEN))
X		return(0);
X	p += GOOPLEN;
X	nleft -= GOOPLEN;
X
X	while (nleft > 0 && (*p == ' ' || *p == '\t')) {
X		p++;
X		nleft--;
X	}
X
X	if (nleft == 0 || *p++ != '\n')
X		return(0);
X
X	return(p - bufp);
X}
X
X/*
X - unprivileged - no-op to keep pathname routines happy
X */
Xvoid
Xunprivileged()
X{
X}
END_OF_FILE
if test 4040 -ne `wc -c <'input/newsspool.c'`; then
    echo shar: \"'input/newsspool.c'\" unpacked with wrong size!
fi
# end of 'input/newsspool.c'
fi
if test -f 'lib.proto/active' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lib.proto/active'\"
else
echo shar: Extracting \"'lib.proto/active'\" \(4724 characters\)
sed "s/^X//" >'lib.proto/active' <<'END_OF_FILE'
Xcontrol 00000 00000 y
Xjunk 00000 00000 y
Xutstat.general 00000 00000 y
Xutstat.hacknews 00000 00000 y
Xutstat.gripes 00000 00000 y
Xutstat.deadletter 00000 00000 m
Xutstat.test 00000 00000 y
Xutstat.control 00000 00000 y
Xutstat.junk 00000 00000 y
Xto.utstat 00000 00000 y
Xto.utgpu 00000 00000 y
Xto.utzoo 00000 00000 y
Xnews.announce.newusers 00000 00000 m
Xut.general 00000 00000 y
Xut.16k 00000 00000 y
Xut.vlsi 00000 00000 y
Xut.supercomputer 00000 00000 y
Xut.theory 00000 00000 y
Xut.na 00000 00000 y
Xtor.general 00000 00000 y
Xtor.news 00000 00000 y
Xtor.news.stats 00000 00000 y
Xont.general 00000 00000 y
Xont.uucp 00000 00000 y
Xont.micro 00000 00000 y
Xont.jobs 00000 00000 y
Xont.events 00000 00000 y
Xont.singles 00000 00000 y
Xont.test 00000 00000 y
Xont.sf-lovers 00000 00000 y
Xcan.general 00000 00000 y
Xcan.jobs 00000 00000 y
Xcan.ai 00000 00000 y
Xcan.politics 00000 00000 y
Xcan.francais 00000 00000 y
Xnews.announce.important 00000 00000 m
Xnews.announce.conferences 00000 00000 m
Xcomp.sys.sun 00000 00000 m
Xcomp.mail.maps 00000 00000 m
Xcomp.org.usenix 00000 00000 y
Xcomp.sources.unix 00000 00000 m
Xcomp.sources.bugs 00000 00000 y
Xcomp.sources.d 00000 00000 y
Xcomp.sources.wanted 00000 00000 y
Xcomp.sources.misc 00000 00000 m
Xcomp.doc 00000 00000 m
Xcomp.doc.techreports 00000 00000 m
Xcomp.laser-printers 00000 00000 m
Xcomp.unix.wizards 00000 00000 y
Xcomp.protocols.tcp-ip 00000 00000 y
Xcomp.bugs.4bsd 00000 00000 y
Xcomp.bugs.4bsd.ucb-fixes 00000 00000 m
Xcomp.bugs.2bsd 00000 00000 y
Xcomp.bugs.sys5 00000 00000 y
Xcomp.bugs.misc 00000 00000 y
Xcomp.lang.c++ 00000 00000 y
Xcomp.lang.c 00000 00000 y
Xcomp.std.c 00000 00000 m
Xcomp.lang.fortran 00000 00000 y
Xcomp.lang.misc 00000 00000 y
Xcomp.mail.uucp 00000 00000 y
Xcomp.mail.elm 00000 00000 m
Xcomp.mail.headers 00000 00000 y
Xcomp.mail.misc 00000 00000 y
Xcomp.windows.x 00000 00000 y
Xcomp.windows.news 00000 00000 y
Xcomp.windows.misc 00000 00000 y
Xcomp.compilers 00000 00000 m
Xcomp.newprod 00000 00000 m
Xcomp.graphics 00000 00000 y
Xcomp.graphics.digest 00000 00000 m
Xcomp.risks 00000 00000 m
Xcomp.society 00000 00000 m
Xcomp.os.research 00000 00000 m
Xcomp.os.minix 00000 00000 y
Xcomp.os.misc 00000 00000 y
Xcomp.std.unix 00000 00000 m
Xcomp.std.misc 00000 00000 m
Xcomp.text 00000 00000 y
Xcomp.text.desktop 00000 00000 m
Xcomp.arch 00000 00000 y
Xcomp.periphs 00000 00000 y
Xcomp.terminals 00000 00000 y
Xcomp.dcom.lans 00000 00000 y
Xcomp.dcom.modems 00000 00000 y
Xcomp.dcom.telecom 00000 00000 m
Xcomp.lsi 00000 00000 y
Xcomp.ai 00000 00000 y
Xcomp.ai.digest 00000 00000 m
Xcomp.unix 00000 00000 m
Xcomp.unix.questions 00000 00000 y
Xcomp.unix.ultrix 00000 00000 m
Xcomp.cog-eng 00000 00000 y
Xcomp.databases 00000 00000 y
Xcomp.edu 00000 00000 y
Xcomp.emacs 00000 00000 y
Xcomp.sys.ibm.pc 00000 00000 y
Xcomp.hypercube 00000 00000 m
Xcomp.misc 00000 00000 y
Xnews.config 00000 00000 y
Xnews.admin 00000 00000 y
Xnews.sysadmin 00000 00000 y
Xnews.software.b 00000 00000 y
Xnews.software.notes 00000 00000 y
Xnews.stargate 00000 00000 y
Xnews.lists 00000 00000 m
Xnews.groups 00000 00000 y
Xnews.newsites 00000 00000 y
Xnews.misc 00000 00000 y
Xsci.crypt 00000 00000 y
Xsci.math 00000 00000 y
Xsci.math.stat 00000 00000 y
Xsci.math.symbolic 00000 00000 y
Xmisc.jobs.offered 00000 00000 y
Xmisc.jobs.resumes 00000 00000 y
Xmisc.jobs.misc 00000 00000 y
Xlist.can-inet 00000 00000 y
Xlist.dtp 00000 00000 y
Xlist.info-nets 00000 00000 y
Xlist.iso 00000 00000 y
Xlist.macsyma 00000 00000 y
Xlist.mh-users 00000 00000 y
Xlist.mh-workers 00000 00000 y
Xlist.mhs_implementation 00000 00000 y
Xlist.namedroppers 00000 00000 y
Xlist.neuron 00000 00000 y
Xlist.news-makers 00000 00000 y
Xlist.nl-kr 00000 00000 y
Xlist.info-postscript 00000 00000 y
Xlist.security 00000 00000 y
Xlist.slug 00000 00000 y
Xlist.texhax 00000 00000 y
Xlist.unix-sw 00000 00000 y
Xlist.unix-tex 00000 00000 y
Xlist.vision-list 00000 00000 y
Xlist.xpert 00000 00000 y
Xlist.ailist 00000 00000 y
Xlist.sun-spots 00000 00000 y
Xlist.bind 00000 00000 y
Xlist.info-1100 00000 00000 y
Xlist.comm-l 00000 00000 m
Xlist.ibm-nets 00000 00000 m
Xlist.license 00000 00000 m
Xlist.mail-l 00000 00000 m
Xlist.nnmail-l 00000 00000 m
Xlist.rscsmods 00000 00000 m
Xlist.rscsv2-l 00000 00000 m
Xlist.s-comput 00000 00000 m
Xlist.sas-l 00000 00000 m
Xlist.servers 00000 00000 m
Xlist.spssx-l 00000 00000 m
Xlist.std-l 00000 00000 m
Xlist.texmag-l 00000 00000 m
Xlist.trafic-l 00000 00000 m
Xlist.trans-l 00000 00000 m
Xlist.usrdir-l 00000 00000 m
Xlist.x400-l 00000 00000 m
Xlist.future-l 00000 00000 m
Xlist.info-futures 00000 00000 m
Xlist.netnws-l 00000 00000 m
Xlist.netmonth 00000 00000 m
Xlist.pc-token 00000 00000 m
Xlist.domain-l 00000 00000 m
Xlist.big-lan 00000 00000 m
Xlist.ibmtcp-l 00000 00000 m
Xlist.humanist 00000 00000 m
Xcomp.sys.mac 00000 00000 y
Xcomp.sys.mac.digest 00000 00000 y
Xcomp.sources.mac 00000 00000 y
END_OF_FILE
if test 4724 -ne `wc -c <'lib.proto/active'`; then
    echo shar: \"'lib.proto/active'\" unpacked with wrong size!
fi
# end of 'lib.proto/active'
fi
if test -f 'rna/defs.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rna/defs.h'\"
else
echo shar: Extracting \"'rna/defs.h'\" \(4972 characters\)
sed "s/^X//" >'rna/defs.h' <<'END_OF_FILE'
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/dir.h>
X#include <stdio.h>
X#include <ctype.h>
X#include <time.h>
X#ifdef USG
X#include <fcntl.h>
X#endif
X#include <signal.h>
X#include <sgtty.h>
X#include "at.h"
X
X#define NEWSVERSION	 "B UNSW 1.1 19 Sep 1984"
X
X/* Things that very well may require local configuration */
X
X#define TIMEZONE	"EST"		/* name of time zone */
X
X#define DFLTSUB "general,general.all"	/* default subscription list	*/
X#define	ADMSUB	"general"		/* Mandatory subscription list */
X#define MODGROUPS "mod.all,all.mod,all.announce"	/* Moderated groups */
X#define DFLTGRP	"general"		/* default newsgroup (for postnews) */
X/* #define MANGRPS	 1		/* if you have mandatory subscriptions
X					   tailored per-person (uses
X					   getclasses()) */
X/*#define OZ	1*/			/* if on Australian network, used
X					   in readnews to get correct return
X					   address */
X/*#define AUSAM	1*/			/* hashed passwd file, locked files */
X#if AUSAM
X#include <passwd.h>
X#else
X#include <pwd.h>
X#endif
X
X#ifdef vax
X/* #define NETPATH	1		/* if you have path finding program
X					   /bin/netpath */
X#endif
X/*#define UNSWMAIL 1*/			/* if you have UNSW "mail" which
X					   allows "-s subject -i include_file"
X					   arguments */
X#define NETID "utstat"
X#ifndef NETID
X#define NETID "utstat"			/* else define it here */
X#endif
X
X#ifndef NETID
X#include <table.h>			/* UNSW only */
X#endif
X
X/* #define MC "/usr/bin/p"			/* pager */
X#define UUNAME "/usr/bin/uuname"
X#define RNEWS	"exec rnews"		/* rnews for uurec to fork */
X#define POSTNEWS "/usr/bin/inews"
X#define CHOWN	"/etc/chown"		/* pathname of chown command */
X#define SHELL	"/bin/sh"		/* if not bourne shell see postnews.c */
X#define MKDIR	"/bin/mkdir"
X#define MAIL	"/bin/mail"
X#if UNSWMAIL
X#define FASTMAIL	"/bin/mail"
X#else
X#define FASTMAIL	MAIL
X#endif
X
X#define HELP	"/usr/lib/news/help.readnews"		/* Help text */
X#define SEQ	"/usr/lib/news/seq"		/* Next sequence number */
X#define SYS	"/usr/lib/news/sys"		/* System subscription lists */
X#define ACTIVE	"/usr/lib/news/active"		/* Active newsgroups */
X#define HISTORY "/usr/lib/news/history"		/* Current articles */
X
X#define MYDOMAIN "uucp"			/* Local domain */
X#define MYORG	"U. of Toronto Statistics" /* My organization */
X#define NEWSROOT "news"			/* news editor */
X
X/* Things you might want to change */
X
X#define NEWSRC  ".newsrc"		/* name of .newsrc file */
X#define	PAGESIZE 24			/* lines on screen */
X#define ARTICLES "articles"		/* default place to save articles */
X#define NEGCHAR	'!'			/* newsgroup negation character	*/
X#define NEGS	"!"			/* ditto (string) */
X#define BADGRPCHARS "/#!"		/* illegal chars in group name */
X#define BUFLEN	256			/* standard buffer size */
X#define ED	"/bin/ed"		/* default, if $EDITOR not set */
X
X/* Things you probably won't want to change */
X
X#define	NGSEPCHAR ','	/* delimit character in news group line		*/
X#define NGSEPS	","	/* ditto */
X#define PSEPS "!"	/* separator in Path: */
X#define PSEPCHAR '!'	/* ditto */
X#define PATHPREF "..!"	/* prefix for addresses worked out from Path: */
X#define TRUE	1
X#define FALSE	0
X
X#ifndef F_SETFD
X#ifdef F_SETFL
X#define F_SETFD F_SETFL		/* SETFL becomes SETFD (close on exec arg
X				   to fcntl) */
X#endif
X#endif
X
Xtypedef enum booltype { false = 0, true } bool;
Xtypedef enum applytype { stop, next, nextgroup, searchgroup } applycom;
Xtypedef applycom (*apcmfunc)();
Xtypedef enum pheadtype { printing, passing, making } pheadcom;
X
X/*
X * header structure
X */
Xtypedef struct header {
X	/* mandatory fields */
X	char	*h_relayversion;
X	char	*h_postversion;
X	char	*h_from;
X	char	*h_date;
X	char	*h_newsgroups;
X	char	*h_subject;
X	char	*h_messageid;
X	char	*h_path;
X	/* optional fields */
X	char	*h_replyto;
X	char	*h_sender;
X	char	*h_followupto;
X	char	*h_datereceived;
X	char	*h_expires;
X	char	*h_references;
X	char	*h_control;
X	char	*h_distribution;
X	char	*h_organisation;
X	char	*h_lines;
X	/* any we don't recognise */
X	char	*h_others;
X} header;
X
X/*
X * internal structure for active file
X */
Xtypedef struct active active;
Xstruct active {
X	char	*a_name;
X	short	a_seq;
X	short	a_low;
X	active	*a_next;
X};
X
X/*
X * internal struct for newsrc file
X */
Xtypedef struct newsrc newsrc;
Xstruct newsrc {
X	char	*n_name;
X	bool	n_subscribe;
X	short	n_last;
X	newsrc	*n_next;
X};
X
Xchar	*strrchr(), *strchr(), *strcat(), *strcpy(), *strpbrk();
Xchar	*itoa(), *convg(), *ngsquash(), *ttoa(), *mgets(), *rconvg();
Xchar	*newstr(), *newstr2(), *newstr3(), *newstr4(), *newstr5(), *catstr();
Xchar	*catstr2(), *bsearch(), *mtempnam(), *newstr6();
Xchar	*getunique(), *getretaddr(), *getsubject();
XFILE	*fopenl(), *fopenf();
Xchar	*memset(), *myalloc(), *myrealloc();
Xlong	time(), atol(), atot();
Xint	strpcmp();
Xactive	*readactive();
Xchar *getenv();
X
X#define NIL(type)	((type *) 0)
X#define NEW(type)	((type *) myalloc(sizeof(type)))
X#define CMP(a, b)	(*(a) != *(b) ? *(a) - *(b) : strcmp(a, b))
X#define CMPN(a, b, n)	(*(a) != *(b) ? *(a) - *(b) : strncmp(a, b, n))
X
X/* bw 9/15/84 */
X#define uid_t int
X#define strchr index
X#define strrchr rindex
END_OF_FILE
if test 4972 -ne `wc -c <'rna/defs.h'`; then
    echo shar: \"'rna/defs.h'\" unpacked with wrong size!
fi
# end of 'rna/defs.h'
fi
if test -f 'rna/expire.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rna/expire.c'\"
else
echo shar: Extracting \"'rna/expire.c'\" \(4537 characters\)
sed "s/^X//" >'rna/expire.c' <<'END_OF_FILE'
X/*
X * expire [ -n newsgroups ] [ -d days ] [ -w weeks ]
X *
X *	delete articles that arrived before the given date (now - days|weeks)
X *	or that have expiry dates in the past
X *
X *	Michael Rourke, UNSW, April 1984.
X */
X
X#include "defs.h"
X#include "at.h"
X
Xchar histname[]	 = HISTORY;
Xchar all[]		 = "all";
X
Xchar *nflag		 = all;
Xlong etime		 = SECINWEEK *2L;
Xchar *newsdir;
Xuid_t	newsuid;
Xlong now;
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X#if AUSAM
X	struct pwent pe;
X	char sbuf[SSIZ];
X#else
X	struct passwd *pp;
X	struct passwd *getpwnam();
X#endif
X
X	for (argv++, argc--; argc > 0; argc--, argv++) {
X		if (argv[0][0] != '-' && argv[0][2] != '\0')
X			break;
X		switch (argv[0][1]) {
X		case 'n':
X			nflag = argv[1]; 
X			break;
X		case 'd':
X			etime = atoi(argv[1]) * SECINDAY; 
X			break;
X		case 'w':
X			etime = atoi(argv[1]) * SECINWEEK; 
X			break;
X		default:
X			argc = -1; 
X			break;
X		}
X		argv++, argc--;
X	}
X	if (argc != 0 || etime < 0) {
X		fprintf(stderr, "Usage: expire [-n newsgroups] [-d days] [-w weeks]\n");
X		exit(1);
X	}
X	time(&now);
X#if AUSAM
X	pe.pw_strings[LNAME] = NEWSROOT;
X	if (getpwuid(&pe, sbuf, sizeof(sbuf)) == PWERROR)
X		error("Password file error.");
X	newsdir = pe.pw_strings[DIRPATH];
X	newsuid = pe.pw_limits.l_uid;
X#else
X	if ((pp = getpwnam(NEWSROOT)) == NULL)
X		error("Password file error.");
X	newsdir = pp->pw_dir;
X	newsuid = pp->pw_uid;
X#endif
X	umask(022);
X	setgid((int) newsuid);
X	setuid((int) newsuid);
X
X	expire(nflag, now - etime);
X	chklow(readactive());
X	exit(0);
X}
X
X
X/*
X * expire articles in the given groups that have arrived before stime
X */
Xexpire(grps, stime)
Xchar *grps;
Xlong stime;
X{
X	register FILE	*f, *tf, *nf;
X	register int i;
X	register char *s, *name;
X	char buf[BUFSIZ];
X	bool		eflag;
X	long pos, tpos, tim;
X	FILE * tmpfile();
X
X	bool		okgrp();
X
X	f = fopenl(histname);
X	tf = NIL(FILE);
X	while (1) {
X		pos = ftell(f);
X		if (fgets(buf, sizeof(buf), f) == NIL(char))
X			break;
X		if ((s = strchr(buf, '>')) == NIL(char))
X			error("Bad format: %s", histname);
X		s += 2;
X		if (*s == 'E')
X			eflag = true, s++;
X		else
X			eflag = false;
X		tim = atol(s);
X		if ((name = strchr(s, ' ')) == NIL(char))
X			error("Bad format: %s", histname);
X		name++;
X		if (!okgrp(name, grps) || (!eflag && tim > stime || eflag &&
X		    tim > now)) {
X			/* don't expire now */
X			if (tf)
X				fputs(buf, tf);
X			continue;
X		}
X		/*
X		 * have something to expire
X		 */
X		if (!tf) {
X			/*
X 			 * start saving unexpired history
X			 */
X			if ((tf = tmpfile()) == NIL(FILE))
X				error("Can't open tmp file.");
X			tpos = ftell(f);
X			rewind(f);
X			for (i = 0; i < pos; i++)
X				putc(getc(f), tf);
X			fseek(f, tpos, 0);
X		}
X		while (*name && (s = strpbrk(name, " \n"))) {
X			*s = '\0';
X			name = newstr3(newsdir, "/", name);
X			unlink(name);
X			free(name);
X			name = s + 1;
X		}
X	}
X	if (tf) {
X		rewind(tf);
X		nf = fopenf(histname, "w");
X		while ((i = getc(tf)) != EOF)
X			putc(i, nf);
X		fclose(nf);
X		fclose(tf);
X	}
X#if !AUSAM
X	unlock(histname);
X#endif
X	fclose(f);
X}
X
X
X/*
X * check that these groups are ok to expire
X */
Xbool
Xokgrp(names, grp)
Xchar *names, *grp;
X{
X	register char *s, *hash, c;
X	register bool	matched;
X
X	if (grp == all)
X		return true;
X	matched = true;
X	while (matched && *names && (s = strpbrk(names, " \n"))) {
X		c = *s;
X		*s = '\0';
X		if ((hash = strchr(names, '#')) == NIL(char))
X			error("Bad format: %s", histname);
X		*--hash = '\0';		/* delete last '/' */
X
X		rconvg(names);
X		matched = (bool) ngmatch(names, grp);
X		convg(names);
X
X		*hash = '/';
X		*s = c;
X		names = s + 1;
X	}
X	return matched;
X}
X
X
X/*
X * set the "low" values in active file
X */
Xchklow(ap)
Xactive *ap;
X{
X	register char *fname;
X	register int low, i;
X	register FILE	*f;
X	struct direct dbuf;
X
X	for ( ; ap; ap = ap->a_next) {
X		low = ap->a_seq + 1;
X		fname = convg(newstr3(newsdir, "/", ap->a_name));
X		if ((f = fopen(fname, "r")) == NIL(FILE)) {
X			warn("Can't open %s", fname);
X			free(fname);
X			continue;
X		}
X		fseek(f, (long) (sizeof(dbuf) * 2), 0);
X		while (fread((char *) & dbuf, sizeof(dbuf), 1, f) == 1) {
X			if (dbuf.d_ino == 0)
X				continue;
X			if (dbuf.d_name[0] != '#')
X				continue;
X			i = atoi(&dbuf.d_name[1]);
X			if (i > 0 && i < low)
X				low = i;
X		}
X		fclose(f);
X		if (low > ap->a_low)
X			setlow(ap->a_name, low);
X		free(fname);
X	}
X}
X
X
X/* VARARGS1 */
Xerror(s, a0, a1, a2, a3)
Xchar *s;
X{
X	fprintf(stderr, "expire: ");
X	fprintf(stderr, s, a0, a1, a2, a3);
X	fprintf(stderr, "\n");
X	exit(1);
X}
X
X
X/* VARARGS1 */
Xwarn(s, a0, a1, a2, a3)
Xchar *s;
X{
X	fprintf(stderr, "expire: Warning: ");
X	fprintf(stderr, s, a0, a1, a2, a3);
X	fprintf(stderr, "\n");
X}
X
X
END_OF_FILE
if test 4537 -ne `wc -c <'rna/expire.c'`; then
    echo shar: \"'rna/expire.c'\" unpacked with wrong size!
fi
# end of 'rna/expire.c'
fi
if test -f 'rna/notes/README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rna/notes/README'\"
else
echo shar: Extracting \"'rna/notes/README'\" \(4667 characters\)
sed "s/^X//" >'rna/notes/README' <<'END_OF_FILE'
XThe files in this distribution are:
X
X	Makefile
X	README
X	active.c
X	at.h
X	defs.h
X	expire.c
X	funcs.c
X	header.c
X	history.c
X	lib
X	lib/bsearch.c
X	lib/memset.c
X	lib/strpbrk.c
X	lib/tmpfile.c
X	lib/tmpnam.c
X	maketime.c
X	man
X	man/postnews.1
X	man/readnews.1
X	man/uurec.8
X	man/uusend.8
X	mtempnam.c
X	news.help
X	newsrc.c
X	postnews.c
X	readnews.c
X	sample.sys
X	uurec.c
X	uusend.c
X
XThis news system is modelled on the USENET news system
Xby Mark Horton (and others).
X
XApart from some minor programs the system has been completely re-written.
XThe aim of re-writing was to produce a system that was:
X	1. smaller
X	2. cleaner
X	3. faster
X	4. was compatible at the site <--> site level with USENET
X	5. had a better user interface ("readnews" and "postnews")
X
XThese goals have been met.
XThe programs "readnews" and "postnews" are 1/3 the previous size, and
Xdoes not require separate I/D space to run on pdp11/70's.
XAlso far fewer processes are needed to use "postnews".
X
XThis system is compatible with USENET at the site <--> site level, provided
Xcommunication is done with Version B format messages (the current 'standard').
XThe messages meet the Standard for the format of ARPA Internet Text messages
X(RFC 822).
X
X"postnews" methods of editing messages is compatible with our local "mail"
Xprogram (also re-written locally).
X
XTo aid someone familiar with USENET to find his/her way around the source:
X    Program changes:
X	"checknews" has become a function of "readnews" (readnews -cC)
X	"postnews" and "inews" are combined into "postnews"
X	"readnews" has the same function (simplified user interface)
X	"expire" has the same function (simplified arguments)
X	"recnews" is not needed
X	"sendnews" has been renamed "uusend" (and simplified)
X	"uurec" has the same function
X    Files:
X	The layout of the news database is the same, except that articles
X	are named #<number> rather than <number>, so that numbers can
X	be a valid newsgroup (like class.6.621).
X
X	"/usr/lib/news/active" has an extra field - the lowest numbered article
X	present in a newsgroup.
X	"/usr/lib/news/history" has a sightly different format.
X	"/usr/lib/news/sys" is compatible, except that the third field
X	is ignored (always expects format B site); colons are allowed in
X	the last field.
X
XTo setup the news system:
X	1. edit the "defs.h" file and make any changes necessary
X	   in particular: MYDOMAIN, MYORG and the paths of SEQ, SYS etc.
X	   MANGRPS should not be defined without making suitable
X	   modifications to getmangrps() in readnews.c
X	   UNSWMAIL is set if you have the version of mail from UNSW,
X	   in particular it allows arguments "-s subject -i include_file"
X	   to specify the subject, and make include_file available to
X	   a ".i" command (like postnews).
X	   AUSAM should not be set unless you have the hashed passwd file,
X	   and locked file facilities of AUSAM.
X	1a. edit "Makefile" for the pathnames of LIBDIR, BINDIR and NETDIR.
X	2. create the account NEWSROOT (defined in defs.h) (this is where
X	   the messages are kept).
X	3. Run the makefile. If you don't have the routines found in
X	   lib/* (bsearch, memset etc.) these can be compiled and
X	   linked in as required.
X	4. Create any groups (using "postnews -c 'newgroup <name>'"),
X	   that require immediate local posting, otherwise groups will
X	   be created automatically when news is received from other sites.
X	   Root and NEWSROOT can also mail to non-existent groups, and
X	   will be asked whether or not to create the new group.
X	5. Set up a pseudo user "rnews" to direct received news into
X	   "postnews -p" (with uid set to NEWSROOT).
X	   How this is done will depend on your network implementation.
X	   It may require a deamon emptying a mail box regularly
X	   (see rnews.sh in this case).
X	   If a mail interface is required, series of messages can be
X	   piped into /usr/lib/news/uurec instead.
X	6. Set up "/usr/lib/news/sys". See sample.sys for an example.
X	   Each line in the "sys" file specifies:
X		host name
X		distribution newsgroups
X		(empty field (system assumes type B interchange))
X		the command needed to send the item to the host.
X	   Note the current host must have the first two fields also.
X	   News transmission can be via "mail" or directly as a
X	   network file transfer.
X	7. Test the system by posting to "to.mysite".
X	8. Arrange for "expire" to be run periodically (via "cron" or "at").
X
XIf you had an existing (old) news system, and wish to transfer the
Xarticles. The best way to do it is run the command:
X
X	find oldnewsdir -type f -a -print ^
X	while read F
X	do
X		postnews -p < $F
X	done
X
XMichael Rourke
XUniversity of New South Wales, Australia	13 June 1984
X(decvax!mulga!michaelr:elecvax)
X(vax135!mulga!michaelr:elecvax)
END_OF_FILE
if test 4667 -ne `wc -c <'rna/notes/README'`; then
    echo shar: \"'rna/notes/README'\" unpacked with wrong size!
fi
# end of 'rna/notes/README'
fi
if test -f 'rnews/anne.jones' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/anne.jones'\"
else
echo shar: Extracting \"'rnews/anne.jones'\" \(4716 characters\)
sed "s/^X//" >'rnews/anne.jones' <<'END_OF_FILE'
X#! /bin/sh
X# anne.jones - censor headers
XPATH=/bin:/usr/bin; export PATH
XNEWSCTL=${NEWSCTL-/usr/lib/news}; export NEWSCTL
XNEWSBIN=${NEWSBIN-/usr/lib/newsbin}; export NEWSBIN
XNEWSARTS=${NEWSARTS-/usr/spool/news}; export NEWSARTS
X
X# pass 0 - dredge up defaults
X#---start mary.brown
Xif test -r $NEWSCTL/domain; then
X	mydomain="`tr -d ' \11' <$NEWSCTL/domain | sed 's/^\.//' `"
Xelse
X	mydomain="uucp"
Xfi
X# badsites="pucc.bitnet!"		# tailor, syntax is "host1!host2!...host3!"
X# "test -r && cat" is used here instead of just "cat" because pre-v8
X# cat's are broken and return good status when they can't read their files.
Xhost=`((test -r $NEWSCTL/whoami && cat $NEWSCTL/whoami) || hostname ||
X	(test -r /etc/whoami && cat /etc/whoami) ||
X	uuname -l || uname -n || echo the_unknown_host) 2>/dev/null`.$mydomain
Xcase "$LOGNAME" in
X# next line assumes stderr is the user's tty
X"")	: ${USER=`who am i <&2 | sed -e 's/[	 ].*//' -e '/!/s/^.*!//' `} ;;
X*)	USER=$LOGNAME ;;
Xesac
Xcase "$NAME" in
X"")
X	if test -s $HOME/.name; then
X		NAME=`cat $HOME/.name`
X	else
X		NAME=`(grep "^$USER:" /etc/passwd || ypmatch "$USER" passwd) |
X			sed 's/^[^:]*:[^:]*:[^:]*:[^:]*:\([^,:]*\).*$/\1/'`
X		# for BTL RJE format, add
X		# | sed -e 's/^[^-]*- *//' -e 's/ *(.*$//'
X		# otherwise for Berkeley format, use this (courtesy Rayan Zachariassen)
X		case "$NAME" in
X		*'&'*)
X			# generate Capitalised login name
X			NM=`echo "$USER" | sed -e 's/^\(.\)\(.*\)/\1:\2/'`
X			NM1=`expr "$NM" : '\(.\):.*' | tr a-z A-Z`
X			NMR=`expr "$NM" : '.:\(.*\)'`
X			CAPNM="$NM1$NMR"
X			# turn & into Capitalised login name
X			NAME=`echo "$NAME" | sed "s:&:$CAPNM:"`
X			;;
X		esac
X	fi
X	;;
Xesac
XREALLYFROM="$USER@$host ($NAME)"
X
Xcase "$PASSEDFROM" in
X"")	FROM="$REALLYFROM" ;;
X*)					# inews -f sender; avoid forgery
X	FROM="$PASSEDFROM"
X	SENDER="$REALLYFROM"
X	;;
Xesac
X#---end mary.brown
Xdefpath="$USER"
Xdeffrom="$FROM"
Xdefdate="`set \`date\`; echo $1, $3-$2-\`echo $6 | sed 's/^..//'\` $4 $5`"
Xdefmsgid="`set \`date\`; echo \<$6$2$3.\`echo $4 | tr -d :\`.$$@$host\>`"
Xdeforg="`sed 1q $NEWSCTL/organi?ation`"
X
Xsed >/tmp/aj$$awk "s/DEFMSGID/$defmsgid/
Xs/DEFPATH/$defpath/
Xs/DEFFROM/$deffrom/
Xs/DEFDATE/$defdate/
Xs/DEFMSGID/$defmsgid/
Xs/DEFORG/$deforg/" <<\!
X# pass 1 - note presence | absence of certain headers
X
X# a header keyword: remember it and its value
X/^[^\t ]*:/ { hdrval[$1] = $0; keyword=$1 }
X# a continuation: concatenate this line to the value
X!/^[^\t ]*:/ { hdrval[keyword] = hdrval[keyword] "\n" $0 }
X
XEND {
X	# pass 2 - deduce & omit & emit headers
X	subjname = "Subject:"
X	ctlname = "Control:"
X	ngname = "Newsgroups:"
X	msgidname = "Message-ID:"
X	typoname =  "Message-Id:"
X	pathname = "Path:"
X	datename = "Date:"
X	fromname = "From:"
X	orgname = "Organization:"
X	distrname = "Distribution:"
X
X	# fill in missing headers
X	if (hdrval[typoname] != "") {	# spelling hack
X		hdrval[msgidname] = hdrval[typoname]
X		hdrval[typoname] = ""
X		# fix spelling: Message-Id: -> Message-ID:
X		nf = split(hdrval[msgidname], fields);	# bust up
X		fields[1] = msgidname;		# fix spelling
X		hdrval[msgidname] = fields[1];	# reassemble...
X		for (i = 2; i <= nf; i++)
X			hdrval[msgidname] = hdrval[msgidname] " " fields[i]
X	}
X	if (hdrval[msgidname] == "")
X		hdrval[msgidname] = msgidname " " "DEFMSGID"
X	if (hdrval[orgname] == "")
X		hdrval[orgname] = orgname " " "DEFORG"
X
X	# replace users headers (if any)
X	hdrval[pathname] = pathname " " "DEFPATH"
X	hdrval[fromname] = fromname " " "DEFFROM"
X	hdrval[datename] = datename " " "DEFDATE"
X
X	# snuff some headers
X	distworld = distrname " world"
X	if (hdrval[distrname] == distworld)
X		hdrval[distrname] = ""
X
X	# the cmsg hack
X	if (substr(hdrval[subjname],1,14) == "Subject: cmsg ")
X		hdrval[ctlname] = ctlname " " substr(hdrval[subjname],15)
X
X	# warn if no Newsgroups:
X	if (hdrval[ngname] == "")
X		print "no newsgroups header!" | "cat >&2"
X
X	# favour Newsgroups: & Control: for benefit of rnews
X	if (hdrval[ngname] != "") {
X		print hdrval[ngname]
X		hdrval[ngname] = ""	# no Newsgroups: to print now
X	}
X	if (hdrval[ctlname] != "") {
X		print hdrval[ctlname]
X		hdrval[ctlname] = ""	# no Control: to print now
X	}
X
X	# B news kludgery: print Path: before From:
X	if (hdrval[pathname] != "") {
X		print hdrval[pathname]
X		hdrval[pathname] = ""	# no Path: to print now
X	}
X	if (hdrval[fromname] != "") {
X		print hdrval[fromname]
X		hdrval[fromname] = ""	# no From: to print now
X	}
X
X	# have pity on readers: put Subject: next
X	if (hdrval[subjname] != "") {
X		print hdrval[subjname]
X		hdrval[subjname] = ""	# no Subject: to print now
X	}
X
X	# print misc. headers in random order
X	for (i in hdrval)
X		if (hdrval[i] != "")
X			print hdrval[i]
X}
X!
X
Xcat $* | tr -d '\1-\7\13\14\16-\37' |	# strip invisible chars, a la B news
X	awk -f /tmp/aj$$awk
Xrm -f /tmp/aj$$awk
END_OF_FILE
if test 4716 -ne `wc -c <'rnews/anne.jones'`; then
    echo shar: \"'rnews/anne.jones'\" unpacked with wrong size!
fi
# end of 'rnews/anne.jones'
fi
if test -f 'rnews/history.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/history.c'\"
else
echo shar: Extracting \"'rnews/history.c'\" \(4899 characters\)
sed "s/^X//" >'rnews/history.c' <<'END_OF_FILE'
X/*
X * history file bashing
X *
X * B news pulls a dirty (and undocumented) trick and converts message-id's
X * to lower case before using them as keys in the dbm file.  For the sake of
X * the news readers, we do the same, under protest.  Grump.
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include "news.h"
X#include "newspaths.h"
X#include "headers.h"
X
X/* give 0 & 2 pretty, SVIDish names */
X#ifndef SEEK_SET
X#define SEEK_SET 0
X#define SEEK_END 2
X#endif
X
Xtypedef struct {
X	char *dptr;
X	int dsize;
X} datum;
X
Xstatic FILE *fp = NULL;
Xstatic char filename[MAXFILE];
X
X/* forward decls */
Xextern datum fetch(), getposhist();
X
Xstatic
Xhistname()
X{
X	if (filename[0] == '\0')
X		(void) strcpy(filename, libfile("history"));
X}
X
Xstatic int
Xopenhist()
X{
X	int status = 0;
X	static int opened = NO;
X
X	histname();
X	if (fp == NULL)
X		if ((fp = fopenwclex(filename, "a+")) == NULL)
X			status |= ST_DROPPED;	/* fopenwclex complained already */
X	if (opened++ == NO && dbminit(filename) < 0)
X		status |= ST_DROPPED;	/* dbminit will honk */
X	return status;
X}
X
Xstatic datum
Xgetposhist(msgid)		/* return seek offset of history entry */
Xchar *msgid;
X{
X	register char *lcmsgid;
X	datum msgidkey, offset;
X
X	msgidkey.dptr = NULL;
X	if (openhist()&ST_DROPPED)
X		return msgidkey;		/* no data base */
X
X	/* dirty trick (part 1 of 2): convert copy of msgid to lower case */
X	lcmsgid = strsave(msgid);
X	strlower(lcmsgid);
X
X	msgidkey.dptr = lcmsgid;
X	msgidkey.dsize = strlen(lcmsgid) + 1;	/* include NUL */
X	offset = fetch(msgidkey);	/* look up offset by l.c. msgid */
X
X	free(lcmsgid);
X	return offset;
X}
X
Xint
Xalreadyseen(msgid)		/* return true if found in the data base */
Xchar *msgid;
X{
X	datum posdatum;
X
X	posdatum = getposhist(msgid);
X	return posdatum.dptr != NULL;
X}
X
Xchar *				/* NULL if no history entry */
Xgethistory(msgid)		/* return existing history entry, if any */
Xchar *msgid;
X{
X	long pos = 0;
X	static char histent[MAXLINE+1];
X	datum posdatum;
X
X	histent[0] = '\0';
X	posdatum = getposhist(msgid);
X	if (posdatum.dptr != NULL && posdatum.dsize == sizeof pos) {
X		memcpy((char *)&pos, posdatum.dptr, sizeof pos); /* align */
X		if (fseek(fp, pos, SEEK_SET) != -1 &&
X		    fgets(histent, sizeof histent, fp) != NULL)
X			return histent;
X	}
X	return NULL;
X}
X
Xchar *
Xfindfiles(histent)		/* side-effect: trims \n */
Xchar *histent;
X{
X	char *tabp;
X
X	trim(histent);
X	tabp = rindex(histent, '\t');
X	if (tabp != NULL)
X		++tabp;		/* skip to start of files list */
X	return tabp;
X}
X
Xint
Xhistory(hdrs)				/* generate history entries */
Xregister struct headers *hdrs;
X{
X	register char *lcmsgid;
X	int status = 0;
X	time_t now;
X	long pos;
X	char msgid[MAXLINE];			/* Message-ID sans \t & \n */
X	char expiry[MAXLINE];			/* Expires sans \t & \n */
X	datum msgidkey, posdatum;
X
X	/* strip \n & \t to keep history file format sane */
X	sanitise(hdrs->h_msgid, msgid, sizeof msgid);
X	sanitise(hdrs->h_expiry, expiry, sizeof expiry);
X
X	/* TODO: is the 3rd parameter needed anymore? */
X	timestamp(stdout, &now, (char **)NULL);
X	(void) printf(" got %s", msgid);	/* NB: no newline */
X
X	status |= openhist();
X	if (status&ST_DROPPED)
X		return status;
X
X	/* generate history file entry */
X	(void) fseek(fp, 0L, SEEK_END);
X	pos = ftell(fp);			/* get seek ptr for dbm */
X	/*
X	 * B 2.10.3+ rnews puts out a leading space before received time
X	 * if the article contains an Expires: header; tough.
X	 * C news does this right instead of compatibly.
X	 *
X	 * The second field is really two: time-received and Expires: value,
X	 * separated by a tilde.  This is an attempt at partial compatibility
X	 * with B news, in that C expire can cope with B news history files.
X	 */
X	(void) fprintf(fp, "%s\t%ld~%s\t%s\n", msgid, now, expiry, hdrs->h_files);
X	(void) fflush(fp);			/* for crash-proofness */
X	if (ferror(fp))
X		status = fulldisk(status|ST_DROPPED, filename);
X
X	/* record (msgid, position) in data base */
X
X	/* dirty trick (part 2 of 2): convert copy of msgid to lower case */
X	lcmsgid = strsave(msgid);
X	strlower(lcmsgid);
X
X	msgidkey.dptr = lcmsgid;
X	msgidkey.dsize = strlen(lcmsgid) + 1;	/* include NUL */
X	/*
X	 * There is no point to storing pos in network byte order,
X	 * since dbm files are machine-dependent and so can't be shared
X	 * by dissimilar machines anyway.
X	 */
X	posdatum.dptr = (char *)&pos;
X	posdatum.dsize = sizeof pos;
X#ifdef NOSTOREVAL
X	/* original v7 dbm store() returned no value */
X	(void) store(msgidkey, posdatum);
X#else
X	if (store(msgidkey, posdatum) < 0)	/* store l.c. msgid */
X		status = fulldisk(status|ST_DROPPED, filename);
X#endif
X	free(lcmsgid);
X	return status;
X}
X
X/* strip \n & \t from dirty into clean, which is no more than cleanlen long */
Xsanitise(dirty, clean, cleanlen)
Xchar *dirty;
Xregister char *clean;
Xunsigned cleanlen;
X{
X	if (dirty == NULL)
X		(void) strncpy(clean, "", (int)cleanlen);
X	else
X		(void) strncpy(clean, dirty, (int)cleanlen);
X	for (; *clean != '\0'; ++clean)
X		if (*clean == '\t' || *clean == '\n')
X			*clean = ' ';
X}
END_OF_FILE
if test 4899 -ne `wc -c <'rnews/history.c'`; then
    echo shar: \"'rnews/history.c'\" unpacked with wrong size!
fi
# end of 'rnews/history.c'
fi
if test -f 'rnews/sh/anne.jones' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/sh/anne.jones'\"
else
echo shar: Extracting \"'rnews/sh/anne.jones'\" \(4716 characters\)
sed "s/^X//" >'rnews/sh/anne.jones' <<'END_OF_FILE'
X#! /bin/sh
X# anne.jones - censor headers
XPATH=/bin:/usr/bin; export PATH
XNEWSCTL=${NEWSCTL-/usr/lib/news}; export NEWSCTL
XNEWSBIN=${NEWSBIN-/usr/lib/newsbin}; export NEWSBIN
XNEWSARTS=${NEWSARTS-/usr/spool/news}; export NEWSARTS
X
X# pass 0 - dredge up defaults
X#---start mary.brown
Xif test -r $NEWSCTL/domain; then
X	mydomain="`tr -d ' \11' <$NEWSCTL/domain | sed 's/^\.//' `"
Xelse
X	mydomain="uucp"
Xfi
X# badsites="pucc.bitnet!"		# tailor, syntax is "host1!host2!...host3!"
X# "test -r && cat" is used here instead of just "cat" because pre-v8
X# cat's are broken and return good status when they can't read their files.
Xhost=`((test -r $NEWSCTL/whoami && cat $NEWSCTL/whoami) || hostname ||
X	(test -r /etc/whoami && cat /etc/whoami) ||
X	uuname -l || uname -n || echo the_unknown_host) 2>/dev/null`.$mydomain
Xcase "$LOGNAME" in
X# next line assumes stderr is the user's tty
X"")	: ${USER=`who am i <&2 | sed -e 's/[	 ].*//' -e '/!/s/^.*!//' `} ;;
X*)	USER=$LOGNAME ;;
Xesac
Xcase "$NAME" in
X"")
X	if test -s $HOME/.name; then
X		NAME=`cat $HOME/.name`
X	else
X		NAME=`(grep "^$USER:" /etc/passwd || ypmatch "$USER" passwd) |
X			sed 's/^[^:]*:[^:]*:[^:]*:[^:]*:\([^,:]*\).*$/\1/'`
X		# for BTL RJE format, add
X		# | sed -e 's/^[^-]*- *//' -e 's/ *(.*$//'
X		# otherwise for Berkeley format, use this (courtesy Rayan Zachariassen)
X		case "$NAME" in
X		*'&'*)
X			# generate Capitalised login name
X			NM=`echo "$USER" | sed -e 's/^\(.\)\(.*\)/\1:\2/'`
X			NM1=`expr "$NM" : '\(.\):.*' | tr a-z A-Z`
X			NMR=`expr "$NM" : '.:\(.*\)'`
X			CAPNM="$NM1$NMR"
X			# turn & into Capitalised login name
X			NAME=`echo "$NAME" | sed "s:&:$CAPNM:"`
X			;;
X		esac
X	fi
X	;;
Xesac
XREALLYFROM="$USER@$host ($NAME)"
X
Xcase "$PASSEDFROM" in
X"")	FROM="$REALLYFROM" ;;
X*)					# inews -f sender; avoid forgery
X	FROM="$PASSEDFROM"
X	SENDER="$REALLYFROM"
X	;;
Xesac
X#---end mary.brown
Xdefpath="$USER"
Xdeffrom="$FROM"
Xdefdate="`set \`date\`; echo $1, $3-$2-\`echo $6 | sed 's/^..//'\` $4 $5`"
Xdefmsgid="`set \`date\`; echo \<$6$2$3.\`echo $4 | tr -d :\`.$$@$host\>`"
Xdeforg="`sed 1q $NEWSCTL/organi?ation`"
X
Xsed >/tmp/aj$$awk "s/DEFMSGID/$defmsgid/
Xs/DEFPATH/$defpath/
Xs/DEFFROM/$deffrom/
Xs/DEFDATE/$defdate/
Xs/DEFMSGID/$defmsgid/
Xs/DEFORG/$deforg/" <<\!
X# pass 1 - note presence | absence of certain headers
X
X# a header keyword: remember it and its value
X/^[^\t ]*:/ { hdrval[$1] = $0; keyword=$1 }
X# a continuation: concatenate this line to the value
X!/^[^\t ]*:/ { hdrval[keyword] = hdrval[keyword] "\n" $0 }
X
XEND {
X	# pass 2 - deduce & omit & emit headers
X	subjname = "Subject:"
X	ctlname = "Control:"
X	ngname = "Newsgroups:"
X	msgidname = "Message-ID:"
X	typoname =  "Message-Id:"
X	pathname = "Path:"
X	datename = "Date:"
X	fromname = "From:"
X	orgname = "Organization:"
X	distrname = "Distribution:"
X
X	# fill in missing headers
X	if (hdrval[typoname] != "") {	# spelling hack
X		hdrval[msgidname] = hdrval[typoname]
X		hdrval[typoname] = ""
X		# fix spelling: Message-Id: -> Message-ID:
X		nf = split(hdrval[msgidname], fields);	# bust up
X		fields[1] = msgidname;		# fix spelling
X		hdrval[msgidname] = fields[1];	# reassemble...
X		for (i = 2; i <= nf; i++)
X			hdrval[msgidname] = hdrval[msgidname] " " fields[i]
X	}
X	if (hdrval[msgidname] == "")
X		hdrval[msgidname] = msgidname " " "DEFMSGID"
X	if (hdrval[orgname] == "")
X		hdrval[orgname] = orgname " " "DEFORG"
X
X	# replace users headers (if any)
X	hdrval[pathname] = pathname " " "DEFPATH"
X	hdrval[fromname] = fromname " " "DEFFROM"
X	hdrval[datename] = datename " " "DEFDATE"
X
X	# snuff some headers
X	distworld = distrname " world"
X	if (hdrval[distrname] == distworld)
X		hdrval[distrname] = ""
X
X	# the cmsg hack
X	if (substr(hdrval[subjname],1,14) == "Subject: cmsg ")
X		hdrval[ctlname] = ctlname " " substr(hdrval[subjname],15)
X
X	# warn if no Newsgroups:
X	if (hdrval[ngname] == "")
X		print "no newsgroups header!" | "cat >&2"
X
X	# favour Newsgroups: & Control: for benefit of rnews
X	if (hdrval[ngname] != "") {
X		print hdrval[ngname]
X		hdrval[ngname] = ""	# no Newsgroups: to print now
X	}
X	if (hdrval[ctlname] != "") {
X		print hdrval[ctlname]
X		hdrval[ctlname] = ""	# no Control: to print now
X	}
X
X	# B news kludgery: print Path: before From:
X	if (hdrval[pathname] != "") {
X		print hdrval[pathname]
X		hdrval[pathname] = ""	# no Path: to print now
X	}
X	if (hdrval[fromname] != "") {
X		print hdrval[fromname]
X		hdrval[fromname] = ""	# no From: to print now
X	}
X
X	# have pity on readers: put Subject: next
X	if (hdrval[subjname] != "") {
X		print hdrval[subjname]
X		hdrval[subjname] = ""	# no Subject: to print now
X	}
X
X	# print misc. headers in random order
X	for (i in hdrval)
X		if (hdrval[i] != "")
X			print hdrval[i]
X}
X!
X
Xcat $* | tr -d '\1-\7\13\14\16-\37' |	# strip invisible chars, a la B news
X	awk -f /tmp/aj$$awk
Xrm -f /tmp/aj$$awk
END_OF_FILE
if test 4716 -ne `wc -c <'rnews/sh/anne.jones'`; then
    echo shar: \"'rnews/sh/anne.jones'\" unpacked with wrong size!
fi
# end of 'rnews/sh/anne.jones'
fi
if test -f 'rnews/test/demo/batch.small' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/test/demo/batch.small'\"
else
echo shar: Extracting \"'rnews/test/demo/batch.small'\" \(4218 characters\)
sed "s/^X//" >'rnews/test/demo/batch.small' <<'END_OF_FILE'
X#! rnews 633
XNewsgroups: net.slug,net.wretched,net.general
XPath: rabbit!alice!npoiv!npois!hou5f!hou5b!hou5c!hou5e!hou5a!hou5d!hogpc!houxe!lime!we13!otuxa!ll1!sb1!burl!mhuxv!mhuxi!mhuxj!mhuxt!eagle!harpo!decvax!decwrl!amd70!rocksvax!bimmler
XFrom: bimmler@rocksvax.UuCp
XSubject: Re: Re: RE: re: rE: Orphaned Response
XMessage-ID: <123@drugs.ca>
XDate-Received: the epoch
XRelay-Version: version A; site rti.uucp
XPosting-Version: version A+; site trt.uucp
X
X> *NONE*:*:0:root
X> daemon:*:1:daemon,uucp
X> sys:*:2:bin,sys
X> bin70:*:3:
X> uucp70:*:4:
X> general:*:5:adams,al
X
XI agree!
X-- 
XSluggola Slimebreath, Cretins Unlimited.
X<insert silly graphics here>
X#! rnews 1025
XNewsgroups: net.drugs,net.emacs
XSubject: Re: Re: RE: re: rE: Re: Re: Orpha - (nf)
XMessage-ID: <willy.geoff@barek>
XHideous-Name: UCBVAX.@MIT-MC.@udel-relay.ARPA.chris.umcp-cs@UDEL-Relay
XDate-Received: yesterday
XRelay-Version: version A+; site rosen.rich
XPath: research!ihnp4!ihnp3!ihnp1!packard!topaz!cbosgd!drugvax!root
X
X> daemon:*:1:daemon,uucp
X> sys:*:2:bin,sys
X> bin70:*:3:
X> uucp70:*:4:
X> general:*:5:adams,al
X
XYou're all a bunch of fascists!
X-- 
XFish Face, Morons Incorporated
X<insert life story here>
XUUCP: ucbvax!mit-mc%udel-relay.arpa@ff:umcp-cs::udel-relay
XARPA: @brl.arpa:ucbvax!mit-mc%udel-relay.arpa@ff:umcp-cs::udel-relay
XCSnet: @brl.arpa:ucbvax!mit-mc%udel-relay.arpa@ff:umcp-cs::udel-relay%csnet-relay
XDEC E-net: rhea::@brl.arpa:ucbvax!mit-mc%udel-relay.arpa@ff:umcp-cs::udel-relay%csnet-relay
XCDNnet: rhea::@brl.arpa:ucbvax!mit-mc%udel-relay.arpa@ff:umcp-cs::udel-relay%csnet-relay.vision.ubc.cdn
XBITnet: psuvax1!rhea::@brl.arpa:ucbvax!mit-mc%udel-relay.arpa@ff:umcp-cs::udel-relay%csnet-relay.vision.ubc.cdn
X#! rnews 993
XNewsgroups: net.general,comp.unix.lizards,comp.unix.bozos
XPath: vt100aa!uw-muskrat!lbl-clams!MAILER-DAEMON
XDate: 4 May 83 00:16:37 VDT (Wed)
XFrom: lbl-clams!MAILER-DAEMON (Mail Delivery Subsystem)
XTo: uw-muskrat!vt100aa!yzuxab!nail
XRelayed-by: somsite.UUCP
XPast-on-by: another.CCCP
XMunged-up-by: erewhon.UUCP
XPosting-version: 2.9E3
XSubject: Returned mail: Who knows why?
XMessage-Id: <8305040716.AA21547@LBL-CLAMS.BARFA>
XReceived: by LBL-CLAMS.BARFA (3.320/3.21)
X	id AA21547; 4 May 83 00:16:37 VDT (Wed)
X
X   ----- Transcript of session follows -----
Xsparrow@gatech.barfa... Connecting to gatech.tcp...
Xsparrow@gatech.barfa... Like, who knows, man?
X
X   ----- Unsent message follows -----
XDate: 4 May 83 00:16:37 VDT (Wed)
XFrom: vt100aa!yzuxab!nail@uw-muskrat.UUCP
XMessage-Id: <8305040716.AA21545@LBL-CLAMS.BARFA>
XReceived: by LBL-CLAMS.BARFA (3.320/3.21)
X	id AA21545; 4 May 83 00:16:37 VDT (Wed)
XTo: vt100aa!uw-muskrat!lbl-clams!sparrow@gatech.barfa
X
XPlease take my name off your mailing list.
X
X#! rnews 554
XNewsgroups: alt.bozos,bozos.unix
XPath: uw-muskrat!ucbvax!decvax!decwrl!ucbvax!anode!cathode!bozos
XDate: Tue May  3 21:35:59
XMessage-Id: <8305040716.AA21555@LBL-CLAMS.BARFA>
XVia: BRL-UNIX
XVia: Twi-UNIX@Somehost
XVia: Twenex-20@Elsewhere
XVia: Godknows@Where
XFrom: The UNIX Bozos
XRealaid-by: Twit.UUCP
XNonconformant-to: Any RFC's you've ever read.
XLost-by: MIT-BOZOS
XFound-by: MIT-OZ
XMessage-Id: <8305040716.AA21549@MIT-OZ.BARFA>
XRemailed-to: UW-MUSKRAT@LBL-CLAMS.BARFA
XEventually-for: your eyes only.
XSubject: And now for something completely different...
X
X#! rnews 463
XPath: ucbvax!decvax!decwrl!anode!bnode!cnode!slime
XDate: Wed May  4 12:13:14
XMessage-Id: <8301829293.AA839282@CNODE.UUCP>
XVia: CNODE.UUCP
XVia: BNODE.UUCP
XVia: Anode.Electron
XVia: DecWhirl
XVia: DecHax
XNewsgroups: newt.toad
XSubject: Re: And now for something completely different...
X
XThe greatest thing since Monty Boa! I loved it. Thank you.
XWhen can we expect the next installment???
X
XNot afraid to sign my real name,
XThanks (as they say) in advance,
X
XHandy Solo
X#! rnews 471
XPath: ucbvax!decvax!decwrl!anode!bnode!cnode!demon
XDate: Wed May  4 12:13:14
XMessage-Id: <8301829294.AA839282@CNODE.UUCP>
XVia: CNODE.UUCP
XVia: BNODE.UUCP
XVia: Anode.Photon
XVia: DecWhirl
XVia: DecHax
XApparantly-for: /dev/null
XNewsgroups: newt.toad
XSubject: Re: And now for something completely different...
X
XIt stank. What a waste of my damn long-distance UUCP phone bill.
XThis sort of dreck belongs in the bit bucket, not on a public
Xnetwork like plaNET.
X
XThe Mad Flamer.
END_OF_FILE
if test 4218 -ne `wc -c <'rnews/test/demo/batch.small'`; then
    echo shar: \"'rnews/test/demo/batch.small'\" unpacked with wrong size!
fi
# end of 'rnews/test/demo/batch.small'
fi
if test -f 'rnews/test/lib/active' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/test/lib/active'\"
else
echo shar: Extracting \"'rnews/test/lib/active'\" \(5114 characters\)
sed "s/^X//" >'rnews/test/lib/active' <<'END_OF_FILE'
Xgeneral 00268
Xhacknews 00211
Xgripes 00021
Xdeadletter 00002
Xtest 00091
Xcontrol 06684
Xjunk 02296
Xto.utcs 00035
Xto.utcsstat 00043
Xto.utzoo 00017
Xto.oscvax 00009
Xto.bnr-vpa 00015
Xto.utflis 00004
Xto.lsuc 00024
Xto.utgumby 00006
Xto.darwin 00017
Xto.utcsri 00000
Xto.utcsscb 00004
Xto.mnetor 00008
Xto.ryesone 00016
Xut.general 00145
Xut.16k 00012
Xut.vlsi 00018
Xut.supercomputer 00114
Xtor.general 00159
Xont.general 00248
Xont.uucp 00209
Xont.micro 00114
Xont.jobs 00164
Xont.events 00576
Xont.singles 00082
Xont.test 00080
Xont.sf-lovers 00059
Xcan.general 00387
Xcan.jobs 00083
Xcan.ai 00079
Xcan.politics 01070
Xmod.announce 00005
Xmod.announce.newusers 00020
Xmod.conferences 00020
Xnet.announce 00145
Xnet.announce.newusers 00339
Xnet.announce.arpa-internet 00102
Xmod.os 00005
Xmod.os.os9 00011
Xmod.os.unix 00008
Xmod.techreports 00061
Xmod.newslists 00426
Xmod.map 00260
Xmod.sources 00512
Xmod.sources.doc 00062
Xmod.motss 00051
Xmod.music 00175
Xmod.movies 00020
Xnet.general 04393
Xnet.followup 06795
Xnet.bugs 00853
Xnet.bugs.v7 00185
Xnet.bugs.uucp 00725
Xnet.bugs.usg 00618
Xnet.bugs.4bsd 02200
Xnet.bugs.2bsd 00371
Xnet.unix-wizards 20463
Xnet.unix 09127
Xnet.periphs 01118
Xnet.dcom 02085
Xnet.info-terms 01019
Xnet.emacs 02146
Xnet.jobs 02592
Xnet.jobs.d 00051
Xnet.text 01241
Xmod.computers.laser-printers 00506
Xnet.micro.ns32k 00038
Xmod.computers.68k 00098
Xnet.micro.68k 01724
Xnet.micro.pc 09399
Xnet.micro.hp 00232
Xmod.computers.pyramid 00050
Xmod.computers.sun 00034
Xmod.computers.vax 01917
Xmod.computers.ridge 00053
Xmod.computers.sequent 00039
Xmod.computers.apollo 00285
Xmod.computers.ibm-pc 00087
Xnet.micro.att 01482
Xmod.computers.macintosh 00024
Xmod.mac 00147
Xmod.mac.binaries 00020
Xmod.mac.sources 00007
Xnet.micro.mac 07201
Xnet.micro.apple 02923
Xnet.micro.atari8 00344
Xnet.micro.atari16 01512
Xnet.micro.atari 02958
Xmod.amiga 00026
Xmod.amiga.sources 00018
Xmod.amiga.binaries 00002
Xnet.micro.amiga 04147
Xnet.micro.cbm 02407
Xnet.micro.cpm 05545
Xnet.micro.6809 00916
Xnet.micro 14940
Xnet.micro.ti 00211
Xnet.micro.trs-80 00767
Xmod.computers.workstations 00232
Xmod.computers.masscomp 00033
Xmod.human-nets 00020
Xmod.comp-soc 00121
Xnet.lan 01718
Xmod.protocols.tcp-ip 00647
Xmod.protocols.kermit 00048
Xmod.protocols.appletalk 00162
Xnet.lang 02570
Xmod.std.c 00149
Xnet.lang.c++ 00297
Xnet.lang.c 10065
Xmod.compilers 00115
Xmod.std.unix 00252
Xnet.lang.f77 00580
Xnet.lang.mod2 00566
Xnet.lang.prolog 00810
Xnet.lang.apl 00245
Xnet.lang.st80 00408
Xnet.lang.lisp 00973
Xnet.lang.pascal 00610
Xnet.lang.ada 01006
Xnet.lang.forth 00482
Xmod.std.mumps 00035
Xmod.test 00016
Xnet.crypt 00834
Xnet.sources 05327
Xnet.sources.bugs 00961
Xnet.sources.mac 01239
Xnet.sources.games 00744
Xnet.sources.d 00392
Xnet.usenix 00676
Xnet.decus 00449
Xnet.rumor 02930
Xnet.lsi 00175
Xmod.vlsi 00136
Xnet.mail 01759
Xnet.mail.headers 00745
Xnet.news 04700
Xnet.news.sa 00352
Xnet.news.adm 00875
Xnet.news.stargate 00279
Xnet.news.b 01288
Xnet.news.config 00916
Xnet.news.group 06094
Xnet.news.newsite 01007
Xnet.news.notes 00107
Xmod.ai 00807
Xnet.ai 03492
Xnet.arch 03753
Xnet.database 00364
Xmod.telecom 00424
Xnet.rec.nude 00764
Xnet.net-people 01190
Xnet.singles 14892
Xnet.social 01226
Xnet.analog 00978
Xnet.astro 01968
Xnet.astro.expert 00274
Xnet.music.synth 01470
Xmod.music.love-hounds 00000
Xmod.music.gaffa 00013
Xnet.auto 11794
Xnet.auto.tech 01379
Xnet.aviation 03288
Xnet.bio 00632
Xnet.books 03894
Xnet.cog-eng 00792
Xnet.columbia 02821
Xnet.college 01701
Xnet.comics 03998
Xmod.recipes 00243
Xnet.cooks 06818
Xnet.wines 00754
Xmod.newprod 00051
Xnet.consumers 05937
Xnet.consumers.house 00353
Xnet.cse 00876
Xnet.cycle 01863
Xnet.eunice 00266
Xnet.games 02947
Xnet.games.go 00319
Xnet.games.emp 00519
Xnet.games.frp 03310
Xnet.games.rogue 03176
Xnet.games.hack 02251
Xnet.games.trivia 02536
Xnet.games.pbm 00677
Xnet.games.video 00645
Xnet.games.chess 00436
Xnet.games.board 00302
Xnet.puzzle 01929
Xnet.garden 01077
Xmod.graphics 00030
Xnet.graphics 01811
Xnet.ham-radio 04272
Xnet.ham-radio.packet 00294
Xnet.internat 00180
Xnet.invest 01626
Xnet.jokes 19972
Xnet.jokes.d 01799
Xnet.kids 03443
Xmod.legal 00193
Xnet.legal 04428
Xmod.mag 00003
Xmod.mag.otherrealms 00016
Xnet.mag 00277
Xnet.sci 01463
Xnet.math 03395
Xnet.math.stat 00282
Xnet.math.symbolic 00152
Xnet.med 04313
Xnet.misc 09685
Xnet.motss 03609
Xnet.nlang 04701
Xnet.nlang.celts 00328
Xnet.nlang.greek 00286
Xnet.nlang.india 01715
Xnet.nlang.africa 00227
Xnet.pets 02425
Xnet.physics 04690
Xnet.poems 01200
Xmod.politics.arms-d 00220
Xmod.politics 00105
Xnet.politics.terror 00008
Xmod.risks 00108
Xnet.railroad 01019
Xnet.bicycle 02765
Xmod.rec.guns 00171
Xmod.psi 00008
Xmod.philosophy 00000
Xmod.philosophy.tech 00000
Xnet.rec 00468
Xnet.rec.birds 00383
Xnet.rec.bridge 00553
Xnet.rec.photo 02250
Xnet.rec.scuba 00335
Xnet.rec.skydive 00365
Xnet.rec.ski 00745
Xnet.rec.boat 00487
Xnet.rec.wood 00513
Xnet.research 00524
Xnet.roots 00262
Xnet.sport 00952
Xnet.sport.baseball 03241
Xnet.sport.hockey 00984
Xnet.sport.football 01735
Xnet.sport.hoops 01390
Xnet.suicide 01014
Xnet.space 06815
Xnet.startrek 06255
Xnet.taxes 01189
Xnet.travel 02825
Xnet.tv 05426
Xnet.tv.soaps 01025
Xnet.tv.drwho 02704
Xnet.veg 00891
Xnet.video 02951
Xnet.wanted.sources 02628
Xnet.wanted 09291
Xna.forsale 00644
Xnet.wobegon 00557
Xnet.test 02560
Xtalk.religion 00000
END_OF_FILE
if test 5114 -ne `wc -c <'rnews/test/lib/active'`; then
    echo shar: \"'rnews/test/lib/active'\" unpacked with wrong size!
fi
# end of 'rnews/test/lib/active'
fi
echo shar: End of archive 7 \(of 14\).
##  End of shell archive.
exit 0