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