[comp.sources.unix] v12i033: C News alpha release, Part08/14

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

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


#! /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 8 (of 14)."
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README.SECOND' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README.SECOND'\"
else
echo shar: Extracting \"'README.SECOND'\" \(5898 characters\)
sed "s/^X//" >'README.SECOND' <<'END_OF_FILE'
XC news is a replacement for most of B news with much better performance.
XSee our paper in the winter 1987 Usenix for some details of how.
X
XC news does not include an all-singing-all-dancing news reader.  We think
XLarry Wall's rn is the reader of choice.  There are others.  We have no
Xdesire to write one ourselves.
X
XWe have included the Australian readnews (with permission) as a simple
Xnews reader, for those who wish to dispense with B news completely.
XNote that we have changed it a bit and bugs should be assumed to be our
Xfault not Michael Rourke's.
X
XFor those who have run one of our ancient pre-beta versions, many things
Xhave changed, and in particular the four-field history file format is gone.
X
XSpeaking of file formats...
X
XThe active file format is the 4-field one that B news introduced midway
Xthrough 2.10, unchanged.
X
XThe history file format is like B with one exception:  the second field,
Xwhich few programs ever look at, now consists of two subfields separated
Xby a tilde (~).  The first is the arrival date as a decimal number, the
Xsecond is the expiry date (if any) as a human-readable date (as emitted by
Xrnews) or a decimal number (after expire has gotten its hands on it once).
XExpire is tolerant of human-readable dates in both those places, but other
Xthings may not be.  The best way to get the history file into the new
Xformat is to rebuild it completely (this is RELATIVELY quick).
X
XThe sys file format is like a late-model B news with two extensions.  First,
Xthe second field (groups and distributions) may optionally be split into
Xtwo subfields (newsgroups and distributions, respectively) with a slash.
XThis permits solutions to various tricky problems that can arise in odd
Xsituations if it is impossible to tell what's a newsgroup name and what's
Xa distribution.  Second, there is a new flag in the third field:  f is like
XF except that its output has the size information that the C batcher
Xwants for accurate limiting of batch size.  (Incidentally, note a limitation,
Xone that will be fixed in the definitive release:  with both f and F, having
Xthe same filename in more than one sys-file line is, uh, a bad idea.  The
Xbatcher is flexible enough to get around most needs for this.)
X
XThe way the news articles themselves are stored is totally unchanged; we
Xhave been unable to think of any changes that are worth the trouble.
X
XFinally, there is a new control file, conventionally named
X/usr/lib/news/explist, which is expire's control file (see the expire
Xmanual page) (pre-alpha sites, note that the format has changed).
X
XFile organization:  the one change is that programs are now kept mostly in
X/usr/lib/newsbin, with /usr/lib/news reserved for control files etc.  Most
X(by intent all) of the programs understand four key environment variables:
XNEWSARTS specifies location of articles (default /usr/spool/news), NEWSCTL
Xspecifies location of control files (default /usr/lib/news), NEWSBIN gives
Xlocation of programs (default /usr/lib/newsbin), and NEWSUMASK gives the
Xumask to be used in creating files (default 002).  The environment variables
Xoverride the defaults for testing and for operation in funny situations.
XNote that one or two things (e.g. relaynews), as distributed, will insist
Xon renouncing setuid privileges if invoked with these overrides.
X
XC news is divided into various subsystems, each occupying a directory
Xof its own.
X
XTwo directories -- include and libcnews -- are support stuff (respectively
Xinclude files and library functions) used by most of the subsystems.
X
XThe libc directory contains stuff that is in our C libraries but might not
Xbe in yours.
X
XThe input spooler, which accepts incoming news batches and spools them
Xup for later processing, is in directory input.  Be warned:  it does do one
Xessential function other than spooling -- it strips the stupid "#! cunbatch"
Xheader off 2.11-style batches.  It includes the "rnews" program that goes
Xin /bin (or /usr/bin, or wherever); "rnews" and "cunbatch" are identical
Xin C news.
X
XThe output batcher is in directory batch.  It will work with B news as well,
Xalthough not as well (it really wants to be told the size of an article as
Xwell as its name).
X
XExpire and its friends, including history rebuilding and active-file updating
X(neither of which are done by expire itself in C news) are in directory
Xexpire.
X
Xgngp contains a grep-like program which matches newsgroups, used in inews
Xamong other things.
X
Xtime contains a couple of small programs occasionally useful in maintaining
Xthe history file with its numeric dates -- ctime converts numeric to human
Xand getdate goes the other way.
X
Xnewshist contains a maintenance program which accepts a news message-ID
Xand prints the history line for that article.
X
Xmail contains various bits of software for shipping news via mail, both
Xcleaner and faster than uurec et al.
X
Xlib.proto is a sort of prototype /usr/lib/news containing some useful things
X(notably newsboot, which should be run from /etc/rc on reboot) and some old
Xunnecessary trash (probably).  newsbin.proto is similar for /usr/lib/newsbin.
X
Xrna is the Australian readnews, plus other odds and ends of their software
Xthat we haven't sorted through yet.
X
XAnd rnews is the Augean Stables themselves (read RFC850 if you don't believe
Xus):  the news-relaying software, containing most of the work and most of
Xthe speedup.  Various auxiliaries, sped-up versions of libraries, and other
Xthings proliferate underneath this directory.  Of note is setnewsids, a little
Xsetuid-root (gasp!) program needed on systems which do not permit the
Xsetuid(geteuid()) operation, to make relaynews run with the right ownerships.
XNote, by the way, that the only program now named "rnews" is the one in
Xthe input subsystem, although programs with various related names live under
Xthe rnews directory.  This was a late change, removing much previous
Xconfusion but perhaps creating some of its own.
END_OF_FILE
if test 5898 -ne `wc -c <'README.SECOND'`; then
    echo shar: \"'README.SECOND'\" unpacked with wrong size!
fi
# end of 'README.SECOND'
fi
if test -f 'batch/newsbatch.8.p' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'batch/newsbatch.8.p'\"
else
echo shar: Extracting \"'batch/newsbatch.8.p'\" \(5897 characters\)
sed "s/^X//" >'batch/newsbatch.8.p' <<'END_OF_FILE'
X.TH NEWSBATCH 8 local
X.DA 11 Aug 1987
X.SH NAME
Xsendbatches, batchmake, batchmunch \- news batching to other sites
X.br
Xbatchprep, batchsize, batchxmit \- news batching to other sites
X.br
Xqueuelen, queuemax, roomfor \- news batching to other sites
X.SH SYNOPSIS
X.B $NEWSBIN/batch/sendbatches
X[
X.B \-c
X]
X[ name ... ]
X.PP
X.B \&.../batchmake
X[
X.B \-d
Xdirectory
X]
Xlistfile
X.br
X.B \&.../batchmunch
X.br
X.B \&.../batchprep
Xbatchsize
X.br
X.B \&.../batchsize
X.br
X.B \&.../batchxmit
Xsite
X.br
X.B \&.../queuelen
Xsite
X.br
X.B \&.../queuemax
X.br
X.B \&.../roomfor
Xbatchsize
X.SH DESCRIPTION
X.I Sendbatches
Xadministers batched transmission of news to other sites.
XIt should be run periodically, under userid \fInews\fR,
Xby \fIcron\fR(8) or similar means.
XIt prepares and sends batches of news,
Xsubject to restrictions on available space and length of outbound queues.
X.PP
X\fISendbatches\fR and all its auxiliaries recognize the standard
Xenvironment variables \fB$\&NEWSARTS\fR,
X\fB$\&NEWSCTL\fR, \fB$\&NEWSBIN\fR, and \fB$NEWSUMASK\fR
Xwhich indicate, respectively, non-default locations
Xfor news articles, news control files, and news programs,
Xand a non-default \fIumask\fR (see \fIumask\fR(2)) for file creation
X(the default \fIumask\fR is 002).
X.PP
XEach site that can have batches sent to it needs a \fBb.\fIsite\fR directory
Xunder \fI$\&NEWSCTL/batch\fR.
XBy default \fIsendbatches\fR considers preparation of batches for all
Xsites that have such a directory, in order as given
Xby the \fIsites\fR file (see below).
XIf \fIsendbatches\fR
Xis invoked with \fInames\fR of specific sites, it considers only those
Xsites as candidates for batching, in the order given.
XIf it is invoked with a
X.B \-c
Xoption, the \fInames\fR are classes of sites, which are considered
Xin the order given,
Xwith order within each class set by order in the \fIsites\fR file.
X.PP
XIf there is a \fI$\&NEWSCTL/batch/sites\fR file, it controls ordering of sites
Xand assignment of sites into classes.
XEach line consists of one or more white-space-separated fields,
Xthe first being a site name, and the rest
X(if any)
Xbeing names of classes to which
Xthat site belongs.
XBlank lines and lines beginning with `#' are ignored.
XThe order of lines determines the default order of \fIsendbatches\fR
Xprocessing, with any unmentioned sites going last.
XIf there is no \fIsites\fR file, classes cannot be used and the default
Xsite ordering is alphabetical.
X.PP
XTo use the batcher, names of files to be sent to a specific site should
Xbe appended to a \fItogo\fR file in its \fBb.\fIsite\fR directory.
XThe batcher expects the lines in \fItogo\fR to have two fields, a filename
X(as a full pathname) of an article and its size in bytes.
XA missing size field is arbitrarily assumed to be a default average.
X.PP
X\fISendbatches\fR uses a number of auxiliary programs to do the real work.
XThe search path it uses to find them includes, in order,
Xthe \fBb.\fIsite\fR directory for the site in question,
X\fI$\&NEWSCTL/batch\fR, and \fI$\&NEWSBIN/batch\fR.
XThis permits per-site and per-news-database overrides of the default
Xbehaviors.
X\fISendbatches\fR provides all these programs with an environment
Xvariable \fB$NEWSSITE\fR, containing the name of the site that batches
Xare being prepared for, in case this is useful in customization.
X.PP
XFor each site being considered for batches, \fIsendbatches\fR first
Xdetermines whether there are in fact any articles to be batched.
XAssuming there are, \fIsendbatches\fR then invokes \fIqueuelen\fR
Xto find out how many batches are in the outbound queue for
Xthe site, \fIqueuemax\fR to find out how long queues are allowed to be,
X\fIbatchsize\fR to determine how big batches should be (in bytes),
Xand \fIroomfor\fR
Xto determine how many batches of that size will fit without depleting the
Xavailable spool space too much.
X\fISendbatches\fR limits the number of batches prepared to the minimum of
Xthe limits implied by queue lengths and available space.
X.PP
X\fISendbatches\fR uses \fIbatchprep\fR
Xas necessary
Xto slice chunks out of the \fItogo\fR
Xfile, each chunk containing the
X\fItogo\fR lines for a batch limited to the specified size.
XException:  a single article bigger than the specified size will still go out
Xas one batch.
X.PP
XEach chunk is then processed through \fIbatchmake\fR, which assembles the
Xarticles into a batch, \fIbatchmunch\fR, which performs auxiliary processing
X(e.g. data compression), and \fIbatchxmit\fR,
Xwhich sends the batch on its way (e.g. enqueues it for transmission).
XIf \fIbatchmake\fR is invoked with a \fB\-d\fR option, it \fIchdir\fRs to
Xthe \fIdirectory\fR first, and strips it off the beginning of any article
Xfilename that starts with it.
XSince most articles will come from \fI$\&NEWSARTS\fR, specifying
X\fB\-d\ $\&NEWSARTS\fR to \fIbatchmake\fR will speed it up noticeably.
X.PP
X\fISendbatches\fR logs some information about sites with backlogs in
X\fI$\&NEWSCTL/batchlog\fR, keeping the previous \fIbatchlog\fR in
X\fIbatchlog.o\fR and the one before that in \fIbatchlog.oo\fR.
XThis is intended to help detection and diagnosis of flow problems.
X.SH FILES
X.ta \w'/usr/lib/news/LOCKbatch*'u+3n
X.nf
X/usr/lib/news/LOCKbatch	lock for \fIsendbatches\fR
X/usr/lib/news/LOCKbatch*	lock temporaries
X/usr/lib/news/LOCK	overall news lock (used by \fIbatchprep\fR)
X/usr/lib/news/LOCKTM*	lock temporaries
X/usr/spool/news	default \fB$\&NEWSARTS\fR
X/usr/lib/news	default \fB$\&NEWSCTL\fR
X/usr/lib/newsbin	default \fB$\&NEWSBIN\fR
X$NEWSARTS	local \fB$\&NEWSARTS\fR
X$NEWSCTL	local \fB$\&NEWSCTL\fR
X$NEWSBIN	local \fB$\&NEWSBIN\fR
X
Xalso see text
X.SH SEE ALSO
Xinews(1), compress(1), uux(1)
X.SH HISTORY
XWritten at University of Toronto as part of the C News project.
X.SH BUGS
X\fIBatchprep\fR does not count the `#!\ rnews\ \fInnnn\fR' headers inside
Xbatches when computing batch lengths.
X.PP
X\fIBatchprep\fR arguably should be smarter about determining file sizes
Xin the absence of counts in the \fItogo\fR file.
END_OF_FILE
if test 5897 -ne `wc -c <'batch/newsbatch.8.p'`; then
    echo shar: \"'batch/newsbatch.8.p'\" unpacked with wrong size!
fi
# end of 'batch/newsbatch.8.p'
fi
if test -f 'libcnews/ngmatch.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libcnews/ngmatch.c'\"
else
echo shar: Extracting \"'libcnews/ngmatch.c'\" \(5712 characters\)
sed "s/^X//" >'libcnews/ngmatch.c' <<'END_OF_FILE'
X/*
X * ngmatch - newsgroup name matching
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include "news.h"
X
X#define truth(bool) ((bool)? "yes": "no")
X
X#ifndef STATIC
X#define STATIC /* static */
X#endif
X
X#define ALL "all"			/* word wildcard */
X
Xstatic int debug = NO;
X
Xmatchdebug(state)
Xint state;
X{
X	debug = state;
X}
X
X/*
X * ngmatch returns true iff the newsgroup(s) in ngs match
X * the pattern(s) in ngpat, where
X *
X * 	ngpats: { ngpat { "," ngpat }* }?
X *	ngpat: "!"? word { "." word }*
X *	word: { alphanum }+ | "all"
X *
X * Only one group need match for success.  (Redundant?)
X *
X * For each group, note the depth of each match against the patterns,
X * negated or not.  Ignore mismatches.  The deepest match wins at the end;
X * if it's a tie, negated matches are rejections.
X *
X * A match of any group against the patterns is a success.
X * Failure to match any pattern with a group is a mismatch of that group.
X * Failure to match any group against any pattern is a total failure.
X *
X * "all" in a pattern is a wildcard that matches exactly one word;
X * it does not cross "." (NGDELIM) delimiters.
X */
X
Xint
Xngmatch(ngpat, ngs)
Xchar *ngpat, *ngs;
X{
X	register char *ngp;			/* point at current group */
X	register char *ngcomma;
X	register char *rngpat = ngpat;
X
X	if (debug)
X		(void) fprintf(stderr, "ngmatch(`%s', `%s')\n", rngpat, ngs);
X	for (ngp = ngs; ngp != NULL; ngp = ngcomma) {
X		register int match;
X
X		INDEX(ngp, NGSEP, ngcomma);
X		if (ngcomma != NULL)
X			*ngcomma = '\0';	/* will be restored below */
X		match = mpatsmatch(rngpat, ngp);	/* try 1 group, multi-patterns */
X		if (ngcomma != NULL)
X			*ngcomma++ = NGSEP;	/* point after the comma */
X		if (match)
X			return YES;
X	}
X	return NO;				/* no pattern matched any group */
X}
X
X/*
X * Match one group against multiple patterns, as above.
X */
XSTATIC int
Xmpatsmatch(ngpat, grp)
Xchar *ngpat, *grp;
X{
X	register char *patp;		/* point at current pattern */
X	register char *patcomma;
X	register int depth;
X	register int faildeepest = 0, hitdeepest = 0;	/* in case of no match */
X	register int negation;
X
X	if (debug)
X		(void) fprintf(stderr, "mpatsmatch(`%s', `%s')\n", ngpat, grp);
X	for (patp = ngpat; patp != NULL; patp = patcomma) {
X		negation = 0;
X		INDEX(patp, NGSEP, patcomma);
X		if (patcomma != NULL)
X			*patcomma = '\0';	/* will be restored below */
X		if (*patp == NGNEG) {
X			++patp;
X			++negation;
X		}
X		depth = onepatmatch(patp, grp);	/* try 1 pattern, 1 group */
X		if (patcomma != NULL)
X			*patcomma++ = NGSEP;	/* point after the comma */
X		if (depth == 0)			/* mis-match */
X			;			/* ignore it */
X		else if (negation) {
X			/* record ordinal # of deepest negated matched word */
X			if (depth > faildeepest)
X				faildeepest = depth;
X		} else {
X			/* record ordinal # of deepest plain matched word */
X			if (depth > hitdeepest)
X				hitdeepest = depth;
X		}
X	}
X	if (debug)
X		(void) fprintf(stderr, "mpatsmatch(`%s', `%s') returns %s\n",
X			ngpat, grp, truth(hitdeepest > faildeepest));
X	return hitdeepest > faildeepest;
X}
X
X/*
X * Match a pattern against a group by looking at each word of pattern in turn.
X *
X * On a match, return the ordinal number of the rightmost word that matches.
X * If group runs out first, the match fails; else it succeeds.
X * On a failure, return zero.
X */
XSTATIC int
Xonepatmatch(patp, grp)			/* match 1 pattern vs 1 group */
Xchar *patp, *grp;
X{
X	register char *rpatwd;		/* used by word match (inner loop) */
X	register char *patdot, *grdot;	/* point at dots after words */
X	register char *patwd, *grwd;	/* point at current words */
X	register int depth = 0;
X
X	for (patwd = patp, grwd = grp; patwd != NULL && grwd != NULL;
X	    patwd = patdot, grwd = grdot, depth++) {
X		register int match;
X
X	    	/* null-terminate words */
X	    	INDEX(patwd, NGDELIM, patdot);
X		if (patdot != NULL)
X			*patdot = '\0';		/* will be restored below */
X	    	INDEX(grwd, NGDELIM, grdot);
X		if (grdot != NULL)
X			*grdot = '\0';		/* will be restored below */
X
X		/*
X		 * Match one word of pattern with one word of group.
X		 * A pattern word of "all" matches any group word.
X		 */
X#ifdef FAST_STRCMP
X		match = STREQ(patwd, grwd) || STREQ(patwd, ALL);
X#else
X		match = NO;
X		for (rpatwd = patwd; *rpatwd == *grwd++; )
X			if (*rpatwd++ == '\0') {
X				match = YES;		/* literal match */
X				break;
X			}
X		if (!match) {
X			/* ugly special case match for "all" */
X			rpatwd = patwd;
X			match = *rpatwd++ == 'a' && *rpatwd++ == 'l' &&
X			        *rpatwd++ == 'l' && *rpatwd   == '\0';
X		}
X#endif				/* FAST_STRCMP */
X
X		if (patdot != NULL)
X			*patdot++ = NGDELIM;	/* point after the dot */
X		if (grdot != NULL)
X			*grdot++ = NGDELIM;
X		if (!match) {
X			depth = 0;		/* words differed - mismatch */
X			break;
X		}
X	}
X	/* if group name ran out before pattern, then match fails */
X	if (grwd == NULL && patwd != NULL)
X		depth = 0;
X	if (debug)
X		(void) fprintf(stderr, "onepatmatch(`%s', `%s') returns %d\n",
X			patp, grp, depth);
X	return depth;
X}
X
X#ifdef CROSS_POSTINGS_RESTRICTED
X/*
X * ngtopsame(ngs) - true iff ngs are all in the same top-level distribution
X */
Xint
Xngtopsame(ngs)
Xregister char *ngs;
X{
X	register char *nextng;
X
X	INDEX(ngs, NGSEP, nextng);
X	if (nextng == NULL)		/* no groups left */
X		return YES;
X	++nextng;			/* skip NGSEP */
X	return firstsame(ngs, nextng) && ngtopsame(nextng);
X}
X
X/*
X * firstsame(ng1, ng2) - true iff first characters (up to the first
X * NGDELIM or NGSEP) are the same in each string.  Neither string
X * is guaranteed to be null-terminated (a small lie; one *is*).
X */
XSTATIC int
Xfirstsame(ng1, ng2)
Xregister char *ng1, *ng2;
X{
X	register int ng1brk;
X	static char delimstr[] = { NGSEP, NGDELIM, '\0' };
X	extern int strcspn();
X
X	ng1brk = strcspn(ng1, delimstr);
X	return ng1brk == strcspn(ng2, delimstr) && STREQN(ng1, ng2, ng1brk);
X}
X#endif
END_OF_FILE
if test 5712 -ne `wc -c <'libcnews/ngmatch.c'`; then
    echo shar: \"'libcnews/ngmatch.c'\" unpacked with wrong size!
fi
# end of 'libcnews/ngmatch.c'
fi
if test -f 'rna/man/postnews.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rna/man/postnews.1'\"
else
echo shar: Extracting \"'rna/man/postnews.1'\" \(5207 characters\)
sed "s/^X//" >'rna/man/postnews.1' <<'END_OF_FILE'
X.TH POSTNEWS 1
X.SH NAME
Xpostnews \- submit news articles
X.SH SYNOPSIS
X.B postnews
X.RB [ -h ]
X.RB [ -s
Xsubject]
X.RB [ -n
Xnewsgroups]
X.RB [ -d
Xdistribution]
X.br
X.in +9
X.RB [ -e
Xexpiredate ..]
X.RB [ -r
Xreferences]
X.RB [ -i
Xinterpfile]
X.br
X.in -9
X.P
X.B postnews
X.B -c
Xcontrol_command
X.RB [ -n
Xnewsgroups]
X.RB [ -d
Xdistribution]
X.br
X.P
X.B postnews
X.B -p
X.SH DESCRIPTION
X.I Postnews
Xsubmits news articles to the network news system.
XNormally
X.I postnews
Xis used interactively, in which case no arguments are required,
Xand
X.I postnews
Xwill prompt the user for the subject, newsgroup and distribution
Xfields.
XIf any other fields are required they must be specified on the command
Xline.
XThe article text may then be entered, and may be terminated by a `.' or EOT.
XLike
X.IR mail (1),
Xcommands are available while entering an article, to escape to an
Xeditor, interpolate the current article or run a shell command.
X.P
XThe second two forms of the
X.B postnews
Xcommand are for news administration use only.
X.I Postnews
Xis often called by
X.IR readnews (1)
Xto post follow-up articles, and post new articles;
Xmany flag arguments are provided for this purpose.
X.P
XOptional flags are:
X.TP
X.B -h
Xis used when input is redirected from a file containing an article.
XIt specifies that headers are present at the beginning of the article,
Xand that these headers should be included with the article header instead
Xof as text.
XOnly headers the user may set are permitted.
X.TP
X\fB-s \fIsubject\fR
Xspecifies the subject of the article.
XIf it is not specified in this way it must be specified interactively.
XThis must be carefully chosen to be brief yet descriptive.
X.TP
X\fB-n \fInewsgroups\fR
Xspecifies a comma separated list of newsgroups to which the article
Xwill be posted.
XThe default is
X.BR general .
X.TP
X\fB-d \fIdistribution\fR
Xusually not specified, is the same format as a newsgroup,
Xand is used to restrict the article's distribution to those
Xhosts which subscribe to the group(s) specified.
X.TP
X\fB-e \fIexpiredate\fR ..
Xspecifies a date for the article to expire (instead of the usual default).
XThe format of the date arguments are as follows:
X.RS 5
X.TP 14
X.IR day :
X(
X.I dayofweek
X[ 
X.B week
X] ) |
X.BR 1 .. 31
X.RS 2
X.TP 14
X.IR dayofweek :
X.B sunday
X| ... | 
X.B saturday
X|
X.B tomorrow
X|
X.B today
X.RE
X.TP
X.IR month :
X.B january
X| ... | 
X.B december
X.TP
X.IR year :
X.BR 1970 .. 2038
X.RE
X.P
X.RS 5
XThe arguments
X.I day
X,
X.I month
Xand
X.I year
Xare order-independent,
Xand words may be shortened to a non-ambiguous abbreviation.
X.P
XAs the time must be in the future, unspecified
X.I day
X,
X.I month
Xand
X.I year
Xarguments default to the `next' day, month or year as necessary;
Xotherwise the current day, month and year are used.
X.P
X.RE
X.TP
X\fB-r \fIreferences\fR
Xusually used by
X.IR readnews (1)
Xwhen posting a followup article.
X.I references
Xcontain the message-id of the article being followed up.
X.TP
X\fB-i \fIinterpfile\fR
Xusually used by
X.IR readnews (1)
Xwhen posting a followup article.
X.I interpfile
Xis the file available to the `.i' command when entering an
Xarticle interactively.
X.TP
X\fB-c \fIcontrol_command\fR
Xspecifies special control commands.
XCommands are
X\fR`\fBnewgroup \fIgroupname\fR'
Xto create a new newsgroup (news admin only)
Xand
X\fR`\fBcancel \fImessageid\fR'
Xto cancel a message (sender or news admin only).
XNewsgroups and distribution may be specified to
Xlimit the scope of the control command.
X.TP
X.B -p
Xindicates the article on standard input has come from
Xanother host (and contains headers etc.) - news admin only.
X.P
XWhen entering an article interactively,
Xa
X.RB \&' . '
Xor EOT
Xby itself on a line terminates entering and posts the article.
XOther commands are available:
X.TP
X\&\fB.e\fR
XEdit the article collected so far (see
X.IR ed (1)).
XAfter editing further lines may be appended to the article.
X.TP
X\&\fB.i\fR
XInterpolate
Xthe file specified by the
X.B -i
Xflag
Xonto the end of the message. The interpolated item
Xis indented by four spaces.
X.TP
X\&\fB.!\fIcmd\fR or \fB!\fIcmd\fR
XShell escape.
X.IR Cmd
Xis executed.
X.TP
X.B DEL
XCauses posting to be aborted, and the article entered so far
Xis saved in
X.BR $HOME/dead.article .
X.P
XWhen posting an article, the environment is checked for information
Xabout the sender.
XIf
X.B NAME
Xis found,
Xits value is used for the full name, rather than the system value
X(found in
X.BR /etc/passwd ).
XIf
X.B ORGANIZATION
Xis found,
Xthe value overrides the system default organization.
XAn alternative editor (for the
X.B .e
Xcommand) may be used by setting
X.B EDITOR
Xin the environment.
X.P
XAfter local installation of the article,
X.I postnews
Xwill transmit the article to all systems that subscribe to the
Xnewsgroups that the articles belong to.
X.SH FILES
X.ta 24
X.nf
X/usr/lib/news/active	current newsgroups
X/usr/lib/news/seq	contains next sequence number
X/usr/lib/news/history	messageids of all articles received
X/usr/lib/news/sys	subscriptions lists for other hosts
X%news		where the articles are kept
X%news/itmp*	temporary articles
X$HOME/dead.article	saved article when aborted
X.fi
X.SH SEE ALSO
Xreadnews(1), mail(1), uusend(8), uurec(8).
X.SH BUGS
XThe headers can't be altered by using the `.e' command.
X.SH AUTHOR
XMichael Rourke, University of N.S.W. (decvax!mulga!michaelr:elecvax)
END_OF_FILE
if test 5207 -ne `wc -c <'rna/man/postnews.1'`; then
    echo shar: \"'rna/man/postnews.1'\" unpacked with wrong size!
fi
# end of 'rna/man/postnews.1'
fi
if test -f 'rna/readnews.lint' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rna/readnews.lint'\"
else
echo shar: Extracting \"'rna/readnews.lint'\" \(5157 characters\)
sed "s/^X//" >'rna/readnews.lint' <<'END_OF_FILE'
Xheader.c(126): warning: possible pointer alignment problem
X
Xreadnews.c(268): warning: possible pointer alignment problem
Xreadnews.c(269): warning: possible pointer alignment problem
Xreadnews.c(345): warning: com set but not used in function subs
Xreadnews.c(953): warning: possible pointer alignment problem
Xreadnews.c(1256): warning: possible pointer alignment problem
Xreadnews.c(1256): warning: possible pointer alignment problem
X
Xfuncs.c(232): warning: long assignment may lose accuracy
X
Xactive.c(103): warning: possible pointer alignment problem
X
Xnewsrc.c(82): warning: possible pointer alignment problem
Xnewsrc.c(90): warning: possible pointer alignment problem
Xnewsrc.c(115): warning: possible pointer alignment problem
Xnewsrc.c(153): warning: possible pointer alignment problem
X
Xhistory.c(109): warning: possible pointer alignment problem
Xhistory.c(120): warning: possible pointer alignment problem
Xhistory.c(172): warning: long assignment may lose accuracy
Xhistory.c(172): warning: long assignment may lose accuracy
X
Xmaketime.c(413): warning: long assignment may lose accuracy
Xmaketime.c(413): warning: long assignment may lose accuracy
Xmaketime.c(413): warning: long assignment may lose accuracy
Xmaketime.c(444): warning: long assignment may lose accuracy
Xmaketime.c(444): warning: long assignment may lose accuracy
Xmaketime.c(445): warning: long assignment may lose accuracy
Xmaketime.c(445): warning: long assignment may lose accuracy
X
Xsprintf value declared inconsistently	llib-lc:llib-lc(287)  ::  header.c(469)
X
Xqsort, arg. 2 used inconsistently	llib-lc:llib-lc(210)  ::  readnews.c(132)
Xapply, arg. 3 used inconsistently	newsrc.c(138)  ::  readnews.c(144)
Xapply, arg. 3 used inconsistently	newsrc.c(138)  ::  readnews.c(146)
Xapply, arg. 3 used inconsistently	newsrc.c(138)  ::  readnews.c(154)
Xwait, arg. 1 used inconsistently	llib-lc:llib-lc(138)  ::  readnews.c(1163)
Xqsort, arg. 2 used inconsistently	llib-lc:llib-lc(210)  ::  readnews.c(1265)
Xsprintf value declared inconsistently	llib-lc:llib-lc(287)  ::  readnews.c(859)
X
Xsprintf value declared inconsistently	llib-lc:llib-lc(287)  ::  funcs.c(238)
X
Xerror defined( maketime.c(237) ), but never used
Xfputs returns value which is always ignored
Xungetc returns value which is always ignored
Xsprintf returns value which is always ignored
Xalist defined( active.c(13) ), but never used
Xendpwent returns value which is always ignored
Xsignal returns value which is sometimes ignored
Xfflush returns value which is sometimes ignored
Xsubsub returns value which is sometimes ignored
Xstrcpy returns value which is sometimes ignored
Xseen returns value which is sometimes ignored
Xfclose returns value which is always ignored
X_flsbuf returns value which is always ignored
Xsystem returns value which is always ignored
Xstrncpy returns value which is always ignored
Xclose returns value which is always ignored
Xfseek returns value which is always ignored
Xgtty returns value which is always ignored
Xstty returns value which is always ignored
Xnewstr6 defined( funcs.c(81) ), but never used
Xngsquash defined( funcs.c(196) ), but never used
Xgetunique defined( funcs.c(220) ), but never used
Xchown returns value which is always ignored
Xunlink returns value which is sometimes ignored
Xrconvg defined( funcs.c(350) ), but never used
Xreadln defined( funcs.c(392) ), but never used
Xapplyng defined( funcs.c(420) ), but never used
Xgetseq defined( active.c(23) ), but never used
Xsetlow defined( active.c(141) ), but never used
Xinitgrp defined( active.c(167) ), but never used
Xcancel defined( history.c(73) ), but never used
Xchkhist defined( history.c(86) ), but never used
Xopenhist defined( history.c(140) ), but never used
Xwritehist defined( history.c(156) ), but never used
Xclosehist defined( history.c(165) ), but never used
X
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(149)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(150)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(151)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(152)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(227)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(228)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(229)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(230)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(1158)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(1159)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(1160)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(1161)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(1166)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(1167)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(1168)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  readnews.c(1169)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  newsrc.c(251)
Xsignal, arg. 2 used inconsistently	llib-lc:llib-lc(117)  ::  newsrc.c(252)
END_OF_FILE
if test 5157 -ne `wc -c <'rna/readnews.lint'`; then
    echo shar: \"'rna/readnews.lint'\" unpacked with wrong size!
fi
# end of 'rna/readnews.lint'
fi
if test -f 'rnews/control.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/control.c'\"
else
echo shar: Extracting \"'rnews/control.c'\" \(6110 characters\)
sed "s/^X//" >'rnews/control.c' <<'END_OF_FILE'
X/*
X * Implement the control messages.
X * These are fairly infrequent and can afford to be done by
X * separate programs.  They are:
X *
X * cancel message-ID		restricted to Sender: else From: or root, in theory
X *
X * newgroup groupname		restrict this, in theory
X * rmgroup groupname		allow some local control over this
X *
X * sendsys			to Reply-To: else From:
X * senduuname			to Reply-To: else From:
X * version			to Reply-To: else From: (NB seismo)
X *
X * ihave message-ID-list remotesys	some day ...
X * sendme message-ID-list remotesys	some day ...
X *
X * TODO: one shell file only for controls? or more common scripts?
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#ifdef lint
X#include <sgtty.h>			/* for TIOCNOTTY, if present */
X#ifdef TIOCNOTTY			/* 4.2BSD or later berklix */
X#include <sys/wait.h>
X#endif					/* TIOCNOTTY */
X#endif					/* lint */
X#include <sys/types.h>
X
X#include "news.h"
X#include "newspaths.h"
X#include "headers.h"
X#include "history.h"
X
X#define SUBDIR "ctl"			/* holds shell scripts */
X
X#ifndef USENET
X#define USENET "usenet"			/* mail address of usenet admin. */
X#endif
X
X/*
X * These are shell meta-characters, except for /, which is included
X * since it allows people to escape from the control directory.
X */
X#define SHELLMETAS "<>|&;({$=*?[`'\"/"
X
X/*
X * Implement control message specified in hdrs.
X * Because newgroup and rmgroup may modify the active file, for example,
X * we must flush in-core caches to disk first and reload them afterward.
X * TODO: pass header values to scripts as args or in environ,
X *	as NEWS* variables.
X */
Xint
Xctlmsg(hdrs)
Xstruct headers *hdrs;
X{
X	int status = ST_OKAY, pid, deadpid;
X#ifdef lint
X#ifdef TIOCNOTTY			/* 4.2BSD or later berklix */
X	union wait wstatus;
X#else					/* TIOCNOTTY */
X	int wstatus;
X#endif					/* TIOCNOTTY */
X#else					/* lint */
X	int wstatus;
X#endif					/* lint */
X	char *inname = hdrs->h_tmpf, *ctlcmd = hdrs->h_ctlcmd;
X	static char nmcancel[] = "cancel ";
X
X	/* process cancels in this process for speed and dbm access */
X	if (STREQN(ctlcmd, nmcancel, STRLEN(nmcancel)))
X		return cancelart(ctlcmd + STRLEN(nmcancel));
X
X	status |= synccaches();		/* sync in-core copies to disk */
X	if ((pid = fork()) == 0) {	/* child process */
X		int cmdstat;
X		char *cmd;
X
X		/*
X		 * Enforce at least minimal security:
X		 * standardise the environment, including PATH and IFS -
X		 * a local addition to libc (TODO: do it by hand);
X		 * reject shell metacharacters in ctlcmd.
X		 */
X		standard();			/* close most files, etc. */
X		if (!safecmd(ctlcmd))
X			_exit(1);		/* don't flush stdio buffers */
X
X		cmd = emalloc((unsigned)STRLEN("exec ") +
X			strlen(libfile(SUBDIR)) + STRLEN(SFNDELIM) +
X			strlen(ctlcmd) + STRLEN(" <") + strlen(inname) + 1);
X		(void) sprintf(cmd, "exec %s/%s <%s", libfile(SUBDIR),
X			ctlcmd, inname);
X
X		cmdstat = system(cmd);			/* punt */
X		if (cmdstat != 0) {			/* intercepted */
X			char *mailcmd;
X			FILE *mailf;
X			extern char *progname;
X	
X			mailcmd = emalloc((unsigned)STRLEN("PATH=") +
X				STRLEN(STDPATH) + STRLEN(" mail ") +
X				STRLEN(USENET) + 1);
X			/*
X			 * Honk at the usenet administrator &
X			 * mark this article as dropped.
X			 */
X			(void) sprintf(mailcmd, "PATH=%s mail %s",
X				STDPATH, USENET);
X			mailf = popen(mailcmd, "w");
X			if (mailf == NULL)
X				mailf = stderr;
X			(void) fprintf(mailf,
X			"%s: control message `%s' exited with status 0%o\n",
X				progname, cmd, cmdstat);
X			if (mailf != stderr)
X				(void) pclose(mailf);
X			free(mailcmd);
X			_exit(1);			/* don't flush */
X		}
X		free(cmd);
X		_exit(0);				/* don't flush */
X	}
X	while ((deadpid = wait(&wstatus)) != pid && deadpid != -1)
X		;
X
X	/* wrong kid returned, fork failed or child screwed up? */
X	if (deadpid != pid || pid == -1
X#ifndef lint
X	    || wstatus != 0
X#endif						/* lint */
X	    )
X		status |= ST_DROPPED;		/* admin got err.msg. by mail above */
X	status |= loadcaches();			/* reload in-core copies */
X	return status;
X}
X
Xstatic int
Xsafecmd(cmd)			/* true if it's safe to system(3) cmd */
Xchar *cmd;
X{
X	register char *s;
X
X	for (s = cmd; *s != '\0'; s++)
X		if (STREQN(s, "..", strlen("..")))
X			return NO;
X	for (s = SHELLMETAS; *s != '\0'; s++)
X		if (index(cmd, *s) != NULL)
X			return NO;
X	return YES;
X}
X
Xstatic int
Xcancelart(msgidstr)
Xchar *msgidstr;
X{
X	register char *wsp;
X	/* TODO: someday free this storage */
X	/* copy msgidstr into malloc'ed store */
X	register char *msgid = strsave(msgidstr);
X	int status = ST_OKAY;
X
X	/* skip leading whitespace in msgid */
X	while (*msgid != '\0' && isascii(*msgid) && isspace(*msgid))
X		++msgid;
X
X	/* eliminate trailing whitespace in msgid */
X	for (wsp = msgid + strlen(msgid) - 1; wsp >= msgid &&
X	    isascii(*wsp) && isspace(*wsp); --wsp)
X		*wsp = '\0';
X
X	/* cancel article if seen, else generate history entry for it */
X	if (alreadyseen(msgid)) {
X		char *histent, *filelist;
X
X		/*
X		 * In theory (RFC 850), inews should verify that the
X		 * user issuing the cancel (the Sender: of this
X		 * article or From: if no Sender) is the Sender: or
X		 * From: of the original article or the super-user on
X		 * this machine.
X		 *
X		 * In practice, this is a lot of work and since
X		 * anyone can forge news (and thus cancel anything),
X		 * not worth the effort.
X		 *
X		 * Ignore ST_ACCESS since the article may have been
X		 * cancelled before or may have a fake history entry
X		 * because the cancel arrived before the article.
X		 */
X		histent = gethistory(msgid);
X		if (histent != NULL &&
X		    (filelist = findfiles(histent)) != NULL)
X			status |= snufffiles(filelist) & ~ST_ACCESS;
X	} else {
X		/*
X		 * Generate a history file entry for the cancelled article
X		 * in case it arrives after the cancel control.
X		 * The history file entry will cause the cancelled article
X		 * to be rejected as a duplicate.
X		 *
X		 * Forge up the necessary header struct members
X		 * (see history() for details).
X		 */
X		static struct headers hdrs;	/* static to zero parts */
X
X		hdrs.h_msgid = msgid;
X		/* any unlinkable file is OK, so use root */
X		(void) strcpy(hdrs.h_files, "/");
X		hdrs.h_expiry = "-";		/* use default expiry */
X		status |= history(&hdrs);
X		(void) putchar('\n');		/* end log line */
X	}
X	return status;
X}
END_OF_FILE
if test 6110 -ne `wc -c <'rnews/control.c'`; then
    echo shar: \"'rnews/control.c'\" unpacked with wrong size!
fi
# end of 'rnews/control.c'
fi
if test -f 'rnews/inews' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/inews'\"
else
echo shar: Extracting \"'rnews/inews'\" \(6183 characters\)
sed "s/^X//" >'rnews/inews' <<'END_OF_FILE'
X#! /bin/sh
X# inews [-p] [-d k] [-x site] [-hMD] [-t subj] [-n ng] [-e exp] [-F ref] \
X#  [-d dist] [-a mod] [-f from] [-o org] [-C ng] [file...] - inject news:
X#	censor locally-posted article and field the "inews -C" kludge;
X#	munge the articles, enforce bogus and pathetic attempts at
X#	Usenet security, generate lotsa silly headers.
XNEWSCTL=${NEWSCTL-/usr/lib/news}	# export NEWSCTL
XNEWSBIN=${NEWSBIN-/usr/lib/newsbin}	# export NEWSBIN
XNEWSARTS=${NEWSARTS-/usr/spool/news}	# export NEWSARTS
XPATH=$NEWSCTL:$NEWSBIN:$NEWSBIN/relay:/bin:/usr/bin:/usr/ucb; export PATH
XPASSEDFROM='';	export PASSEDFROM	# passed to anne.jones in environ.
Xallowed=geoff			# tailor: local news admin (may be "")
Xdebug=''			# flags
Xexclusion=''
Xhdrspresent=no
Xwhoami=/tmp/in$$who		# just created to determine effective uid
Xinput=/tmp/in$$in		# uncensored input
Xinhdrs=/tmp/in$$hdr		# generated by tear: headers
Xinbody=/tmp/in$$body		# generated by tear: body
Xcensart=/tmp/in$$cens		# censored input
Xnglist=/tmp/in$$ngs		# newsgroups: list
Xmodroute=/tmp/in$$route		# route to moderator's forwarder
Xrmlist="$inhdrs $inbody $input $censart $nglist $modroute"
X
Xumask 2
Xtrap '' 1 2 15			# ignore signals to avoid losing articles
X
X# "inews -p": invoke rnews
Xcase "$1" in
X-p)
X	shift
X	exec rnews $*		# rnews, bailing out at or near line 1
X	;;
Xesac
X
X# parse arguments: for options, cat headers onto $input; cat files onto $input
X>$input
Xwhile :
Xdo
X	case $# in
X	0)	break ;;		# arguments exhausted
X	esac
X
X	case "$1" in
X	-debug)	shift; debug="$1" ;;		# peculiar to C news
X	-x)	shift; exclusion="-x $1" ;;	# you're welcome, erik (2.11)
X	-h)	hdrspresent=yes ;;
X	-M)	# TODO: what's this *really* do? dunno, find out
X		;;
X	-D)	# obsolete, undocumented: meant "don't check for recordings".
X		# last present in B 2.10.1, invoked by readnews for followups.
X		;;
X	-t)	shift; echo "Subject: $1" >>$input ;;
X	-n)	shift; echo "Newsgroups: $1" >>$input ;;
X	-e)	shift; echo "Expires: $1" >>$input ;;
X	-F)	# undocumented in B 2.10.1, documented in B 2.11.
X		shift; echo "References: $1" >>$input ;;
X	-d)	shift; echo "Distribution: $1" >>$input ;;
X	-a)	shift; echo "Approved: $1" >>$input ;;
X
X	# pass next options as environment variables to anne.jones
X	-f)	shift; PASSEDFROM="$1" ;;	# complex due to Sender:
X	-o)	shift; ORGANIZATION="$1"; export ORGANIZATION ;;
X
X	-[cC])
X		# megakludge-o-rama
X		# first, permit only to super-users
X		>$whoami
X		case "`ls -l $whoami | awk '{print $3}'`" in
X		root|$allowed)	: a winner ;;
X		*)
X			echo "$0: only super-users may create news groups" >&2
X			exit 1
X			;;
X		esac
X		rm -f $whoami
X		case "$1" in
X		-c)	echo "Distribution: general" >>$input ;;
X		esac
X		shift			# skip -C
X		case "$1" in
X		*.*.*)	ng=news.announce ;;
X		*.*)	ng="$1" ;;
X		*)	ng="$1.$1" ;;
X		esac
X		cat <<! >>$input		# generate -C header
XNewsgroups: $ng.ctl
XSubject: cmsg newgroup $1
XControl: newgroup $1
X
Xcreated by inews -C or inews -c.
X!
X		;;
X	-*)
X		echo "$0: bad option $1" >&2
X		exit 1
X		;;
X	*)
X		case "$hdrspresent" in
X		no)	echo "" >>$input; hdrspresent=yes ;;
X		esac
X		cat "$1" >>$input		# is a filename; append file
X		fileseen=yes
X		;;
X	esac
X	shift		# pass option or filename (any value was done above)
Xdone
X
X# if no files named, read stdin
Xcase "$fileseen" in
Xyes)	;;
X*)
X	case "$hdrspresent" in
X	no)	echo "" >>$input; hdrspresent=yes ;;
X	esac
X	# capture incoming news in case inews fails
X	if cat >>$input; then
X		: far out
X	else
X		echo "$0: lost news; cat status $?" >&2
X		exit 1
X	fi
X	;;
Xesac
X
X# run the remainder in the background for the benefit of impatient people
X( # mary.brown <$input >$censart	# censor the headers, glue on .signature
Xtear /tmp/in$$ <$input		# output in $inhdrs and $inbody
X# bounce zero-line articles (bad idea for control messages)
X#if test ! -s $inbody; then
X#	echo "$0: no article body" >&2
X#	rm -f $rmlist
X#	exit 1
X#fi
X# post with new headers and .signature
X(anne.jones <$inhdrs		# bash headers
X tr -d '\1-\7\13\14\16-\37' <$inbody # strip invisible chars from body, a la B news
X if test -r $HOME/.signature; then
X	echo "-- "; sed 4q $HOME/.signature	# glue on first bit of signature
X fi) >$censart
X
X# to post or to mail? that is the question; whether 'tis nobler in the mind
X# to suffer the slings and arrows of outrageous mailers ... Bill Shakespeare
Xsed -n '/^Newsgroups:[	 ]/{
Xs/^Newsgroups:[	 ]*\(.*\)$/\1/p
Xq
X}' <$inhdrs >$nglist
Xegrep "^(` sed 's/\./\\\\./
Xs/,/|/' <$nglist `) " $NEWSCTL/active |
X	while read ng high low flag	# look at next group's active entry
X	do
X		case "$flag" in
X		n)
X			echo "$0: bugger off, $ng may not be posted to." >&2
X			exit 1
X			;;
X		m)
X			if grep -s '^Approved:[	 ]' $inhdrs; then
X				rm $modroute		# just post normally
X			else
X				# un-Approved: mail it to the moderator(s).
X				echo "%s" >$modroute	# in case no route
X				# look for route for this group
X				while read ngpat route
X				do
X					# a dreadful B 2.11 hack:
X					# backbone|internet == all
X					case "$ngpat" in
X					backbone|internet)	ngpat="all" ;;
X					esac
X					if gngp -a "$ngpat" $nglist >/dev/null; then
X						echo "$route" >$modroute
X						break	# take only 1st match
X					fi
X				done <$NEWSCTL/mailpaths
X			fi
X			# ngpat and route are not set here, damn it!
X			if test -s $modroute; then
X				# a mod group! mail article to this moderator
X				sendnews `sed "s/%s/\`echo $ng | tr . - \`/" \
X					$modroute` <$censart
X				rm -f $rmlist
X				exit 0
X			# $censart is used rather than a pipe to work around a bug in the 4.2 sh
X			# which made it sometimes return the wrong exit status (that of anne.jones).
X			elif serverrnews $exclusion -d "$debug" <$censart	# -s $NEWSARTS -l $NEWSCTL
X			then
X				rm -f $rmlist		# far out, it worked
X				exit 0
X			else
X				status=$?
X				echo "$0: failed news in $input; inews status $status" >&2
X				exit $status
X			fi
X			;;
X		y)
X			# $censart is used rather than a pipe to work around a bug in the 4.2 sh
X			# which made it sometimes return the wrong exit status (that of anne.jones).
X			if serverrnews $exclusion -d "$debug" <$censart	# -s $NEWSARTS -l $NEWSCTL
X			then
X				rm -f $rmlist		# far out, it worked
X				exit 0
X			else
X				status=$?
X				echo "$0: failed news in $input; inews status $status" >&2
X				exit $status
X			fi
X			;;
X		esac
X	done
X) &
END_OF_FILE
if test 6183 -ne `wc -c <'rnews/inews'`; then
    echo shar: \"'rnews/inews'\" unpacked with wrong size!
fi
# end of 'rnews/inews'
fi
if test -f 'rnews/sh/inews' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/sh/inews'\"
else
echo shar: Extracting \"'rnews/sh/inews'\" \(6183 characters\)
sed "s/^X//" >'rnews/sh/inews' <<'END_OF_FILE'
X#! /bin/sh
X# inews [-p] [-d k] [-x site] [-hMD] [-t subj] [-n ng] [-e exp] [-F ref] \
X#  [-d dist] [-a mod] [-f from] [-o org] [-C ng] [file...] - inject news:
X#	censor locally-posted article and field the "inews -C" kludge;
X#	munge the articles, enforce bogus and pathetic attempts at
X#	Usenet security, generate lotsa silly headers.
XNEWSCTL=${NEWSCTL-/usr/lib/news}	# export NEWSCTL
XNEWSBIN=${NEWSBIN-/usr/lib/newsbin}	# export NEWSBIN
XNEWSARTS=${NEWSARTS-/usr/spool/news}	# export NEWSARTS
XPATH=$NEWSCTL:$NEWSBIN:$NEWSBIN/relay:/bin:/usr/bin:/usr/ucb; export PATH
XPASSEDFROM='';	export PASSEDFROM	# passed to anne.jones in environ.
Xallowed=geoff			# tailor: local news admin (may be "")
Xdebug=''			# flags
Xexclusion=''
Xhdrspresent=no
Xwhoami=/tmp/in$$who		# just created to determine effective uid
Xinput=/tmp/in$$in		# uncensored input
Xinhdrs=/tmp/in$$hdr		# generated by tear: headers
Xinbody=/tmp/in$$body		# generated by tear: body
Xcensart=/tmp/in$$cens		# censored input
Xnglist=/tmp/in$$ngs		# newsgroups: list
Xmodroute=/tmp/in$$route		# route to moderator's forwarder
Xrmlist="$inhdrs $inbody $input $censart $nglist $modroute"
X
Xumask 2
Xtrap '' 1 2 15			# ignore signals to avoid losing articles
X
X# "inews -p": invoke rnews
Xcase "$1" in
X-p)
X	shift
X	exec rnews $*		# rnews, bailing out at or near line 1
X	;;
Xesac
X
X# parse arguments: for options, cat headers onto $input; cat files onto $input
X>$input
Xwhile :
Xdo
X	case $# in
X	0)	break ;;		# arguments exhausted
X	esac
X
X	case "$1" in
X	-debug)	shift; debug="$1" ;;		# peculiar to C news
X	-x)	shift; exclusion="-x $1" ;;	# you're welcome, erik (2.11)
X	-h)	hdrspresent=yes ;;
X	-M)	# TODO: what's this *really* do? dunno, find out
X		;;
X	-D)	# obsolete, undocumented: meant "don't check for recordings".
X		# last present in B 2.10.1, invoked by readnews for followups.
X		;;
X	-t)	shift; echo "Subject: $1" >>$input ;;
X	-n)	shift; echo "Newsgroups: $1" >>$input ;;
X	-e)	shift; echo "Expires: $1" >>$input ;;
X	-F)	# undocumented in B 2.10.1, documented in B 2.11.
X		shift; echo "References: $1" >>$input ;;
X	-d)	shift; echo "Distribution: $1" >>$input ;;
X	-a)	shift; echo "Approved: $1" >>$input ;;
X
X	# pass next options as environment variables to anne.jones
X	-f)	shift; PASSEDFROM="$1" ;;	# complex due to Sender:
X	-o)	shift; ORGANIZATION="$1"; export ORGANIZATION ;;
X
X	-[cC])
X		# megakludge-o-rama
X		# first, permit only to super-users
X		>$whoami
X		case "`ls -l $whoami | awk '{print $3}'`" in
X		root|$allowed)	: a winner ;;
X		*)
X			echo "$0: only super-users may create news groups" >&2
X			exit 1
X			;;
X		esac
X		rm -f $whoami
X		case "$1" in
X		-c)	echo "Distribution: general" >>$input ;;
X		esac
X		shift			# skip -C
X		case "$1" in
X		*.*.*)	ng=news.announce ;;
X		*.*)	ng="$1" ;;
X		*)	ng="$1.$1" ;;
X		esac
X		cat <<! >>$input		# generate -C header
XNewsgroups: $ng.ctl
XSubject: cmsg newgroup $1
XControl: newgroup $1
X
Xcreated by inews -C or inews -c.
X!
X		;;
X	-*)
X		echo "$0: bad option $1" >&2
X		exit 1
X		;;
X	*)
X		case "$hdrspresent" in
X		no)	echo "" >>$input; hdrspresent=yes ;;
X		esac
X		cat "$1" >>$input		# is a filename; append file
X		fileseen=yes
X		;;
X	esac
X	shift		# pass option or filename (any value was done above)
Xdone
X
X# if no files named, read stdin
Xcase "$fileseen" in
Xyes)	;;
X*)
X	case "$hdrspresent" in
X	no)	echo "" >>$input; hdrspresent=yes ;;
X	esac
X	# capture incoming news in case inews fails
X	if cat >>$input; then
X		: far out
X	else
X		echo "$0: lost news; cat status $?" >&2
X		exit 1
X	fi
X	;;
Xesac
X
X# run the remainder in the background for the benefit of impatient people
X( # mary.brown <$input >$censart	# censor the headers, glue on .signature
Xtear /tmp/in$$ <$input		# output in $inhdrs and $inbody
X# bounce zero-line articles (bad idea for control messages)
X#if test ! -s $inbody; then
X#	echo "$0: no article body" >&2
X#	rm -f $rmlist
X#	exit 1
X#fi
X# post with new headers and .signature
X(anne.jones <$inhdrs		# bash headers
X tr -d '\1-\7\13\14\16-\37' <$inbody # strip invisible chars from body, a la B news
X if test -r $HOME/.signature; then
X	echo "-- "; sed 4q $HOME/.signature	# glue on first bit of signature
X fi) >$censart
X
X# to post or to mail? that is the question; whether 'tis nobler in the mind
X# to suffer the slings and arrows of outrageous mailers ... Bill Shakespeare
Xsed -n '/^Newsgroups:[	 ]/{
Xs/^Newsgroups:[	 ]*\(.*\)$/\1/p
Xq
X}' <$inhdrs >$nglist
Xegrep "^(` sed 's/\./\\\\./
Xs/,/|/' <$nglist `) " $NEWSCTL/active |
X	while read ng high low flag	# look at next group's active entry
X	do
X		case "$flag" in
X		n)
X			echo "$0: bugger off, $ng may not be posted to." >&2
X			exit 1
X			;;
X		m)
X			if grep -s '^Approved:[	 ]' $inhdrs; then
X				rm $modroute		# just post normally
X			else
X				# un-Approved: mail it to the moderator(s).
X				echo "%s" >$modroute	# in case no route
X				# look for route for this group
X				while read ngpat route
X				do
X					# a dreadful B 2.11 hack:
X					# backbone|internet == all
X					case "$ngpat" in
X					backbone|internet)	ngpat="all" ;;
X					esac
X					if gngp -a "$ngpat" $nglist >/dev/null; then
X						echo "$route" >$modroute
X						break	# take only 1st match
X					fi
X				done <$NEWSCTL/mailpaths
X			fi
X			# ngpat and route are not set here, damn it!
X			if test -s $modroute; then
X				# a mod group! mail article to this moderator
X				sendnews `sed "s/%s/\`echo $ng | tr . - \`/" \
X					$modroute` <$censart
X				rm -f $rmlist
X				exit 0
X			# $censart is used rather than a pipe to work around a bug in the 4.2 sh
X			# which made it sometimes return the wrong exit status (that of anne.jones).
X			elif serverrnews $exclusion -d "$debug" <$censart	# -s $NEWSARTS -l $NEWSCTL
X			then
X				rm -f $rmlist		# far out, it worked
X				exit 0
X			else
X				status=$?
X				echo "$0: failed news in $input; inews status $status" >&2
X				exit $status
X			fi
X			;;
X		y)
X			# $censart is used rather than a pipe to work around a bug in the 4.2 sh
X			# which made it sometimes return the wrong exit status (that of anne.jones).
X			if serverrnews $exclusion -d "$debug" <$censart	# -s $NEWSARTS -l $NEWSCTL
X			then
X				rm -f $rmlist		# far out, it worked
X				exit 0
X			else
X				status=$?
X				echo "$0: failed news in $input; inews status $status" >&2
X				exit $status
X			fi
X			;;
X		esac
X	done
X) &
END_OF_FILE
if test 6183 -ne `wc -c <'rnews/sh/inews'`; then
    echo shar: \"'rnews/sh/inews'\" unpacked with wrong size!
fi
# end of 'rnews/sh/inews'
fi
echo shar: End of archive 8 \(of 14\).
##  End of shell archive.
exit 0