rsalz@uunet.uu.net (Rich Salz) (06/28/89)
Submitted-by: utzoo!henry Posting-number: Volume 19, Issue 91 Archive-name: cnews2/part14 : ---CUT HERE--- echo 'nntpdiffs/cdiff.1.5.5': sed 's/^X//' >'nntpdiffs/cdiff.1.5.5' <<'!' XOnly in .: Cnews.diff XCommon subdirectories: ../nntp.1.5.5/common and ./common XCommon subdirectories: ../nntp.1.5.5/doc and ./doc XCommon subdirectories: ../nntp.1.5.5/inews and ./inews XCommon subdirectories: ../nntp.1.5.5/rrnpatches and ./rrnpatches XCommon subdirectories: ../nntp.1.5.5/server and ./server XCommon subdirectories: ../nntp.1.5.5/support and ./support XCommon subdirectories: ../nntp.1.5.5/xfer and ./xfer XCommon subdirectories: ../nntp.1.5.5/xmit and ./xmit Xdiff -c -r ../nntp.1.5.5/server/Makefile ./server/Makefile X*** ../nntp.1.5.5/server/Makefile Tue Jun 6 22:46:14 1989 X--- ./server/Makefile Tue Jun 6 23:33:45 1989 X*************** X*** 3,8 **** X--- 3,9 ---- X # X X SRVROBJ = main.o serve.o access.o access_inet.o access_dnet.o active.o \ X+ batch.o \ X ahbs.o globals.o group.o help.o ihave.o list.o misc.o netaux.o \ X newgroups.o newnews.o nextlast.o ngmatch.o post.o parsit.o scandir.o \ X slave.o spawn.o strcasecmp.o subnet.o time.o xhdr.o fakesyslog.o \ X*************** X*** 9,14 **** X--- 10,16 ---- X ../common/version.o X X SRVRSRC = main.c serve.c access.c access_inet.c access_dnet.c active.c \ X+ batch.c \ X ahbs.c globals.c group.c help.c ihave.c list.c misc.c netaux.c \ X newgroups.c newnews.c nextlast.c ngmatch.c post.c parsit.c scandir.c \ X slave.c spawn.c strcasecmp.c subnet.c time.c xhdr.c fakesyslog.c \ X*************** X*** 19,25 **** X SRCS = ${SRVRSRC} X X # -ldbm here if you've #define'ed DBM in ../common/conf.h X! LIBS = X X CFLAGS = -O X X--- 21,27 ---- X SRCS = ${SRVRSRC} X X # -ldbm here if you've #define'ed DBM in ../common/conf.h X! LIBS = -ldbm X X CFLAGS = -O X XOnly in ./server: batch.c Xdiff -c -r ../nntp.1.5.5/server/ihave.c ./server/ihave.c X*** ../nntp.1.5.5/server/ihave.c Tue Jun 6 22:46:12 1989 X--- ./server/ihave.c Tue Jun 6 23:47:02 1989 X*************** X*** 52,59 **** X (void) strcat(errbuf, " NNTP server out of space. Try later."); X X retcode = 0; /* indicates that an error occurred */ X! } else retcode = X! spawn(rnews, "rnews", (char *) 0, CONT_XFER, ERR_XFERFAIL, errbuf); X X if (retcode <= 0) X printf("%d %s\r\n", ERR_XFERFAIL, errbuf); X--- 52,65 ---- X (void) strcat(errbuf, " NNTP server out of space. Try later."); X X retcode = 0; /* indicates that an error occurred */ X! } else X! #ifdef UNBATCHED_INPUT X! retcode = spawn(rnews, "rnews", (char *) 0, CONT_XFER, X! ERR_XFERFAIL, errbuf); X! #else X! /* C news input hook */ X! retcode = batch_input_article(CONT_XFER, ERR_XFERFAIL, errbuf); X! #endif X X if (retcode <= 0) X printf("%d %s\r\n", ERR_XFERFAIL, errbuf); Xdiff -c -r ../nntp.1.5.5/server/misc.c ./server/misc.c X*** ../nntp.1.5.5/server/misc.c Tue Jun 6 22:46:12 1989 X--- ./server/misc.c Tue Jun 6 23:33:46 1989 X*************** X*** 80,86 **** X * X * Side effects: opens dbm database X * (only once, keeps it open after that). X- * Converts "msg_id" to lower case. X */ X X #ifndef NDBM X--- 80,85 ---- X*************** X*** 113,122 **** X datum key, content; X #endif USGHIST X static FILE *hfp = NULL; /* history file, text version */ X- X- for (cp = msg_id; *cp != '\0'; ++cp) X- if (isupper(*cp)) X- *cp = tolower(*cp); X X #ifdef USGHIST X hfp = fopen(histfile(msg_id), "r"); X--- 112,117 ---- Xdiff -c -r ../nntp.1.5.5/server/newnews.c ./server/newnews.c X*** ../nntp.1.5.5/server/newnews.c Tue Jun 6 22:48:36 1989 X--- ./server/newnews.c Tue Jun 6 23:33:46 1989 X*************** X*** 249,257 **** X * Side effects: Seeks in history file, modifies line. X */ X X! seekuntil(fp, key, line, linesize) X FILE *fp; X! char *key; X char *line; X int linesize; X { X--- 249,257 ---- X * Side effects: Seeks in history file, modifies line. X */ X X! seekuntil(fp, akey, line, linesize) X FILE *fp; X! char *akey; X char *line; X int linesize; X { X*************** X*** 258,264 **** X--- 258,267 ---- X char datetime[32]; X register int c; X register long top, bot, mid; X+ extern long dtol(); X+ char key[30]; X X+ (void) sprintf(key, "%ld", dtol(akey)); /* akey -> time_t in ascii */ X bot = 0; X (void) fseek(fp, 0L, 2); X top = ftell(fp); X*************** X*** 321,326 **** X--- 324,332 ---- X } X X X+ /* X+ * C news version of getword. X+ */ X getword(fp, w, line, linesize) X FILE *fp; X register char *w; X*************** X*** 328,363 **** X int linesize; X { X register char *cp; X X if (fgets(line, linesize, fp) == NULL) X return (0); X! if (cp = index(line, '\t')) { X! /* X! * The following gross hack is present because the history file date X! * format is braindamaged. They like "mm/dd/yy hh:mm", which is useless X! * for relative comparisons of dates using something like atoi() or X! * strcmp. So, this changes their format into yymmddhhmm. Sigh. X! * X! * 12345678901234 ("x" for cp[x]) X! * mm/dd/yy hh:mm (their lousy representation) X! * yymmddhhmm (our good one) X! * 0123456789 ("x" for w[x]) X! */ X! *cp = '\0'; X! (void) strncpy(w, cp+1, 15); X! w[0] = cp[7]; /* Years */ X! w[1] = cp[8]; X! w[2] = cp[1]; /* Months */ X! w[3] = cp[2]; X! w[4] = cp[4]; /* Days */ X! w[5] = cp[5]; X! w[6] = cp[10]; /* Hours */ X! w[7] = cp[11]; X! w[8] = cp[13]; /* Minutes */ X! w[9] = cp[14]; X! w[10] = '\0'; X! } else X! w[0] = '\0'; X return (1); X } X X--- 334,356 ---- X int linesize; X { X register char *cp; X+ extern char *index(); X X if (fgets(line, linesize, fp) == NULL) X return (0); X! w[0] = '\0'; /* in case of bad format */ X! if (cp = index(line, '\t')) { /* find 2nd field */ X! register char *endp; X! X! *cp++ = '\0'; X! endp = index(cp, '~'); /* end of date-received */ X! if (endp == NULL) X! endp = index(cp, '\t'); /* end of expiry */ X! if (endp != NULL) { X! (void) strncpy(w, cp, endp - cp); X! w[endp - cp] = '\0'; X! } X! } X return (1); X } X Xdiff -c -r ../nntp.1.5.5/server/serve.c ./server/serve.c X*** ../nntp.1.5.5/server/serve.c Tue Jun 6 22:48:36 1989 X--- ./server/serve.c Tue Jun 6 23:41:46 1989 X*************** X*** 263,268 **** X--- 263,279 ---- X X (void) fflush(stdout); X X+ (void) fflush(stdout); X+ X+ #ifndef UNBATCHED_INPUT X+ { X+ char errbuf[2 * NNTP_STRLEN]; X+ X+ enqpartbatch(CONT_XFER, ERR_XFERFAIL, errbuf); X+ } X+ #endif X+ X+ X #ifdef LOG X if (ferror(stdout)) X syslog(LOG_ERR, "%s disconnect: %m", hostname); X*************** X*** 311,317 **** X #ifdef PROFILE X profile(); X #endif X- X exit(0); X } X X--- 322,327 ---- ! echo 'relay/regress/out/active': sed 's/^X//' >'relay/regress/out/active' <<'!' Xcontrol 0000000001 00000 y Xjunk 0000000000 00000 y Xfoo 0000000000 00000 y Xbar 0000000000 00000 y Xtest.a 0000000002 00000 y Xtest.b 0000000002 00000 y Xtest.c 0000000001 00000 y Xbaz 0000000000 00000 y ! echo 'relay/regress/out/art1': sed 's/^X//' >'relay/regress/out/art1' <<'!' XPath: host!user XFrom: user@host XMessage-ID: <#1@host> XNewsgroups: test.a X X## This should appear in test/a/1 ! echo 'relay/regress/out/art2': sed 's/^X//' >'relay/regress/out/art2' <<'!' XPath: host!user XFrom: user@host XMessage-ID: <#2@host> XNewsgroups: test.b X X## This should appear in test/b/1 ! echo 'relay/regress/out/art3': sed 's/^X//' >'relay/regress/out/art3' <<'!' XPath: host!user XFrom: user@host XMessage-ID: <#3@host> XNewsgroups: test.a,test.b X X## This should appear in test/a/2 X## This should appear in test/b/2 ! echo 'relay/regress/out/art4': sed 's/^X//' >'relay/regress/out/art4' <<'!' XPath: host!user XFrom: user@host XMessage-ID: <#4@host> XNewsgroups: test.c X XThis should get cancelled. ! echo 'relay/regress/out/art5': sed 's/^X//' >'relay/regress/out/art5' <<'!' XPath: host!user XFrom: user@host XMessage-ID: <#5@host> XNewsgroups: test.c XControl: cancel <#4@host> X X## This should appear in test/c/2 ! echo 'relay/regress/out/batch': sed 's/^X//' >'relay/regress/out/batch' <<'!' X#! rnews 108 XPath: host!user XFrom: user@host XMessage-ID: <#1@host> XNewsgroups: test.a X X## This should appear in test/a/1 X#! rnews 108 XPath: host!user XFrom: user@host XMessage-ID: <#2@host> XNewsgroups: test.b X X## This should appear in test/b/1 X#! rnews 149 XPath: host!user XFrom: user@host XMessage-ID: <#3@host> XNewsgroups: test.a,test.b X X## This should appear in test/a/2 X## This should appear in test/b/2 X#! rnews 101 XPath: host!user XFrom: user@host XMessage-ID: <#4@host> XNewsgroups: test.c X XThis should get cancelled. X#! rnews 134 XPath: host!user XFrom: user@host XMessage-ID: <#5@host> XNewsgroups: test.c XControl: cancel <#4@host> X X## This should appear in test/c/2 ! echo 'relay/regress/out/errlog': sed 's/^X//' >'relay/regress/out/errlog' <<'!' ! echo 'relay/regress/out/history': sed 's/^X//' >'relay/regress/out/history' <<'!' X<#1@host> TIME~- test.a/1 X<#2@host> TIME~- test.b/1 X<#3@host> TIME~- test.a/2 test.b/2 X<#4@host> TIME~- test.c/1 X<#5@host> TIME~- control/1 ! echo 'relay/regress/out/log': sed 's/^X//' >'relay/regress/out/log' <<'!' XTIME host + <#1@host> foo XTIME host + <#2@host> foo XTIME host + <#3@host> foo XTIME host + <#4@host> foo XTIME host + <#5@host> foo ! echo 'relay/regress/out/run': sed 's/^X//' >'relay/regress/out/run' <<'!' X#! /bin/sh X# run relaynews test Xhere=`pwd` XNEWSARTS=$here XNEWSBIN=$here XNEWSCTL=$here Xexport NEWSARTS NEWSBIN NEWSCTL X X./relaynews -r <batch >stdout 2>stderr Xecho $? >status ! echo 'relay/regress/out/sys': sed 's/^X//' >'relay/regress/out/sys' <<'!' XME:all Xfoo:all:f:/dev/null ! echo 'relay/regress/out/whoami': sed 's/^X//' >'relay/regress/out/whoami' <<'!' Xhostb ! echo 'relay/regress/out/stdout': sed 's/^X//' >'relay/regress/out/stdout' <<'!' ! echo 'relay/regress/out/stderr': sed 's/^X//' >'relay/regress/out/stderr' <<'!' ! echo 'relay/regress/out/test/a/1': sed 's/^X//' >'relay/regress/out/test/a/1' <<'!' XPath: hostb!host!user XFrom: user@host XMessage-ID: <#1@host> XNewsgroups: test.a X X## This should appear in test/a/1 ! echo 'relay/regress/out/test/a/2': sed 's/^X//' >'relay/regress/out/test/a/2' <<'!' XXref: hostb test.a:2 test.b:2 XPath: hostb!host!user XFrom: user@host XMessage-ID: <#3@host> XNewsgroups: test.a,test.b X X## This should appear in test/a/2 X## This should appear in test/b/2 ! echo 'relay/regress/out/test/b/1': sed 's/^X//' >'relay/regress/out/test/b/1' <<'!' XPath: hostb!host!user XFrom: user@host XMessage-ID: <#2@host> XNewsgroups: test.b X X## This should appear in test/b/1 ! echo 'relay/regress/out/test/b/2': sed 's/^X//' >'relay/regress/out/test/b/2' <<'!' XXref: hostb test.a:2 test.b:2 XPath: hostb!host!user XFrom: user@host XMessage-ID: <#3@host> XNewsgroups: test.a,test.b X X## This should appear in test/a/2 X## This should appear in test/b/2 ! echo 'relay/regress/out/control/1': sed 's/^X//' >'relay/regress/out/control/1' <<'!' XPath: hostb!host!user XFrom: user@host XMessage-ID: <#5@host> XNewsgroups: test.c XControl: cancel <#4@host> X X## This should appear in test/c/2 ! echo 'relay/regress/out/status': sed 's/^X//' >'relay/regress/out/status' <<'!' X0 ! echo 'relay/regress/regress': sed 's/^X//' >'relay/regress/regress' <<'!' X#! /bin/sh XPATH=".:$PATH" Xecho removing old dregs... Xrm -rf tmp Xecho making new working subtree... Xmkdir tmp 2>/dev/null Xchmod +x master/run Xcp ../relaynews master/* tmp Xcd tmp Xchmod u+w * Xecho running relaynews... X./run Xecho comparing output... Xsed 's/^... .. ..:..:..\..../TIME/' log >.log && mv .log log Xsed 's/ [0-9][0-9]*~/ TIME~/' history >.history && mv .history history Xrm -f gmon.out history.* relaynews X# diff -r ../out . Xfor f in `find . -type f -print` Xdo X cmp $f ../out/$f Xdone ! echo 'relay/regress/master/active': sed 's/^X//' >'relay/regress/master/active' <<'!' Xcontrol 0000000000 00000 y Xjunk 0000000000 00000 y Xfoo 0000000000 00000 y Xbar 0000000000 00000 y Xtest.a 0000000000 00000 y Xtest.b 0000000000 00000 y Xtest.c 0000000000 00000 y Xbaz 0000000000 00000 y ! echo 'relay/regress/master/art1': sed 's/^X//' >'relay/regress/master/art1' <<'!' XPath: host!user XFrom: user@host XMessage-ID: <#1@host> XNewsgroups: test.a X X## This should appear in test/a/1 ! echo 'relay/regress/master/art2': sed 's/^X//' >'relay/regress/master/art2' <<'!' XPath: host!user XFrom: user@host XMessage-ID: <#2@host> XNewsgroups: test.b X X## This should appear in test/b/1 ! echo 'relay/regress/master/art3': sed 's/^X//' >'relay/regress/master/art3' <<'!' XPath: host!user XFrom: user@host XMessage-ID: <#3@host> XNewsgroups: test.a,test.b X X## This should appear in test/a/2 X## This should appear in test/b/2 ! echo 'relay/regress/master/art4': sed 's/^X//' >'relay/regress/master/art4' <<'!' XPath: host!user XFrom: user@host XMessage-ID: <#4@host> XNewsgroups: test.c X XThis should get cancelled. ! echo 'relay/regress/master/art5': sed 's/^X//' >'relay/regress/master/art5' <<'!' XPath: host!user XFrom: user@host XMessage-ID: <#5@host> XNewsgroups: test.c XControl: cancel <#4@host> X X## This should appear in test/c/2 ! echo 'relay/regress/master/batch': sed 's/^X//' >'relay/regress/master/batch' <<'!' X#! rnews 108 XPath: host!user XFrom: user@host XMessage-ID: <#1@host> XNewsgroups: test.a X X## This should appear in test/a/1 X#! rnews 108 XPath: host!user XFrom: user@host XMessage-ID: <#2@host> XNewsgroups: test.b X X## This should appear in test/b/1 X#! rnews 149 XPath: host!user XFrom: user@host XMessage-ID: <#3@host> XNewsgroups: test.a,test.b X X## This should appear in test/a/2 X## This should appear in test/b/2 X#! rnews 101 XPath: host!user XFrom: user@host XMessage-ID: <#4@host> XNewsgroups: test.c X XThis should get cancelled. X#! rnews 134 XPath: host!user XFrom: user@host XMessage-ID: <#5@host> XNewsgroups: test.c XControl: cancel <#4@host> X X## This should appear in test/c/2 ! echo 'relay/regress/master/errlog': sed 's/^X//' >'relay/regress/master/errlog' <<'!' ! echo 'relay/regress/master/history': sed 's/^X//' >'relay/regress/master/history' <<'!' ! echo 'relay/regress/master/history.dir': sed 's/^X//' >'relay/regress/master/history.dir' <<'!' ! echo 'relay/regress/master/history.pag': sed 's/^X//' >'relay/regress/master/history.pag' <<'!' ! echo 'relay/regress/master/log': sed 's/^X//' >'relay/regress/master/log' <<'!' ! echo 'relay/regress/master/run': sed 's/^X//' >'relay/regress/master/run' <<'!' X#! /bin/sh X# run relaynews test Xhere=`pwd` XNEWSARTS=$here XNEWSBIN=$here XNEWSCTL=$here Xexport NEWSARTS NEWSBIN NEWSCTL X X./relaynews -r <batch >stdout 2>stderr Xecho $? >status ! echo 'relay/regress/master/sys': sed 's/^X//' >'relay/regress/master/sys' <<'!' XME:all Xfoo:all:f:/dev/null ! echo 'relay/regress/master/whoami': sed 's/^X//' >'relay/regress/master/whoami' <<'!' Xhostb ! echo 'relay/README': sed 's/^X//' >'relay/README' <<'!' XThis is relaynews, the heart of C News: article filing. X XIf you're starting here, you are in the wrong place: go to ../conf and Xrun "build". X XSubdirectories are: X Xads some silliness Xanews stuff for conversion to and from the old A News format Xaux auxiliary programs of various kinds Xctl control-message shell files Xaltctl alternative, not recommended, versions of rmgroup and sendgroups Xsh shell files, including inews and postnews and their flunkies Xregress regression-test facilities for relaynews X Xihave.not.c is an alternate version of ihave.c for sites that specifically Xwish to disable ihave/sendme (typically because of foolishness like Xproprietary newsgroups). X XTo run a regression test, "make r". ! echo 'relay/active.c': sed 's/^X//' >'relay/active.c' <<'!' X/* X * active file access functions X */ X X#include <stdio.h> X#include <ctype.h> X#include <sys/types.h> X#include <sys/stat.h> X#include "libc.h" X#include "news.h" X#include "config.h" X#include "active.h" X X/* ordinal numbers of fields */ X#define CURRFIELD 2 /* current article # */ X#define FLAGFIELD 4 /* y/n/m/x/= flag */ X X/* flag field values */ X#define FLAGOKAY 'y' /* ordinary unmoderated group */ X#define FLAGBAD 'n' /* unmoderated but locally-restricted group */ X#define FLAGMOD 'm' /* moderated group */ X#define FLAGNEVER 'x' /* unwanted group: don't file in this one */ X#define FLAGGOTO '=' /* see another group (following) instead */ X X/* imports */ Xextern char *actfind(); Xextern statust actfload(), actfsync(), actfwrnum(); X X/* forwards */ Xextern char *findflag(); XFORWARD char *fieldfind(); X X/* exports */ Xchar actrelnm[] = "active"; X Xstatic FILE *actfp = NULL; Xstatic struct lastngcache { X char *lnc_ng; /* newsgroup name */ X char *lnc_line; /* matching active file line */ X} lnc = { NULL, NULL }; X X/* X * return a pointer to the active file entry for ng X * (or a pointed-to group (by ``=group'')), or 0 if no entry exists. X * since actlook is called repeatedly for the same newsgroup, X * actlook caches the last newsgroup looked-up and the result. X */ XSTATIC char * Xactlook(ang) Xregister char *ang; X{ X register char *ngline, *ng, *flag; X register int loopbreak = 100; X X if (lnc.lnc_ng != NULL && STREQ(lnc.lnc_ng, ang)) X return lnc.lnc_line; X X if (actload() != ST_OKAY) X return NULL; X ng = strsave(ang); X while ((ngline = actfind(actfp, ng, strlen(ng))) != NULL && X (flag = findflag(ngline)) != NULL && *flag == FLAGGOTO && X --loopbreak > 0) { X free(ng); X ng = strsvto(flag+1, '\n'); /* follow "=ng" pointer */ X } X if (loopbreak <= 0) /* "infinite" loop broken */ X ngline = NULL; X X nnfree(&lnc.lnc_ng); X lnc.lnc_ng = ng; X lnc.lnc_line = ngline; X return ngline; X} X X/* X * Find the active entry for ng (or a pointed-to group (by ``=group'')) X * and add inc to its 2nd field (highest number). X * Return the resultant number. X */ Xlong Xincartnum(ng, inc) Xchar *ng; Xint inc; X{ X char testnum[40]; X register char *line = actlook(ng); X register long nextart = -1; X X if (line != NULL) { X register char *artnum, *pastartnum; X X pastartnum = artnum = fieldfind(line, CURRFIELD); X if (artnum == NULL) X return nextart; X while (isascii(*pastartnum) && isdigit(*pastartnum)) X ++pastartnum; X nextart = atol(artnum) + inc; X X /* update active file article # in place, from nextart */ X if (pastartnum-artnum > sizeof testnum || X !ltozan(testnum, nextart, pastartnum-artnum) || X !ltozan(artnum, nextart, pastartnum-artnum)) { X (void) fprintf(stderr, X"%s: article number (%ld) too big for group `%s' active field of %d digits\n", X progname, nextart, ng, pastartnum-artnum); X return -1; X } X X /* give the implementation a chance to write line to disk */ X if (actfwrnum(actfp, line) != ST_OKAY) { X warning("can't update active file", ""); X nextart = -1; X } X } X return nextart; X} X X/* X * Reload the active file cache. X */ Xstatust Xactload() X{ X register statust status = ST_OKAY; X X if (actfp == NULL && X (actfp = fopenwclex(ctlfile(actrelnm), "r+")) == NULL) X status |= ST_DROPPED; X status |= actfload(actfp); X return status; X} X X/* X * Write back to disk the active file cache, if any, and flush the X * last-newsgroup-cache, since it refers to the (now invalid) active file cache. X */ Xstatust Xactsync() X{ X register statust status = ST_OKAY; X X if (actfp != NULL) { X lnc.lnc_ng = lnc.lnc_line = NULL; X status |= actfsync(actfp); X if (nfclose(actfp) == EOF || status != ST_OKAY) { X warning("error writing `%s'", ctlfile(actrelnm)); X status |= ST_DROPPED; X } X } X actfp = NULL; X return status; X} X X/* X * Return YES iff any group in ngs (or a pointed-to group (by ``=group'')) X * matches thisflag. X */ Xboolean Xisflag(ngs, thisflag) Xregister char *ngs; Xint thisflag; X{ X register char *newng, *flag, *ng; X register boolean result = NO; X X for (ng = ngs; !result && ng != NULL; ng = newng) { X newng = index(ng, NGSEP); X if (newng != NULL) X *newng = '\0'; /* restored below */ X X flag = findflag(actlook(ng)); X if (flag != NULL && *flag == thisflag) X result = YES; X X if (newng != NULL) X *newng++ = NGSEP; /* point at next group */ X } X return result; X} X XSTATIC char * Xfieldfind(ngline, fieldno) /* return address of field "fieldno" in ngline */ Xregister char *ngline; Xregister int fieldno; X{ X register int field; X X for (field = 1; ngline != NULL && field < fieldno; ++field) { X ngline = index(ngline, ' '); X if (ngline != NULL) X ngline++; /* point at next field */ X } X return ngline; X} X Xchar * Xfindflag(ngline) /* return address of flag field in ngline */ Xregister char *ngline; X{ X return fieldfind(ngline, FLAGFIELD); X} X X/* X * Are any groups in ngs moderated? X */ Xboolean Xmoderated(ngs) Xregister char *ngs; X{ X return isflag(ngs, FLAGMOD); X} X X/* X * Are any groups in ngs unwanted? X */ Xboolean Xunwanted(ngs) Xregister char *ngs; X{ X return isflag(ngs, FLAGNEVER); X} X X/* X * Return 0 or a malloced newsgroup name corresponding to "ong", X * but without an "=" flag in its active file entry. X * This is done by tracing the chain of "=ng" pointers (in actlook()), if any. X */ Xchar * Xrealngname(ong) Xchar *ong; X{ X register char *ngline = actlook(ong); X X if (ngline == NULL) X return NULL; /* no such ong */ X return strsvto(ngline, ' '); X} ! echo 'relay/active.h': sed 's/^X//' >'relay/active.h' <<'!' X/* imports from active.c */ Xextern statust actload(), actsync(); Xextern long incartnum(); Xextern char *realngname(); Xextern boolean isflag(), unwanted(), moderated(); X X#define nxtartnum(ng) incartnum(ng, 1) X#define prevartnum(ng) incartnum(ng, -1) ! echo 'relay/ads/1': sed 's/^X//' >'relay/ads/1' <<'!' XINEWS. We have Xthe technology Xtoday to bring 'em Xback tomorrow. X X By the 1990s, fighter pilots will need an inte- Xgrated electronic warfare suite that fuses the Xcapabilities of multiple warning and response sys- Xtems. Advanced technology that provides complete Xprotection with greater reliability. That system is the XIntegrated Electronic Warfare System - INEWS. X The TRW/Westinghouse Joint Venture is the Xonly team that offers such a powerful combination Xof advanced technologies and specific, long-term Xexperience for INEWS. X Our Phase I and II VHSIC contracts, together Xwith our VHSIC 1750A program, will increase pro- Xcessing speed and memory and reduce space and Xpower demands. Our wideband microwave trans- Xmitters and receivers can make functional integra- Xtion a cost-effective, operational reality. Our detector Xtechnologies ensure instant warning of all fore- Xseeable threats. And our expendables technology Xprovides a wide range of threat-response options. X TRW and Westinghouse with XHoneywell, Perkin-Elmer, and Tracor. XThe team with the technology today Xto bring 'em back tomorrow. X X TRW ! echo 'relay/ads/2': sed 's/^X//' >'relay/ads/2' <<'!' XINEWS. Technology on a totally different plane. X X The Raytheon-Northrop joint Xventure team brings state-of-the-art Xtechnology to the competition for Xthe Integrated Electronic Warfare XSystem. INEWS will go aboard the Xnext generation of tactical aircraft. X The combination of Raytheon Xand Northrop unites their comple- Xmentary capabilities in the design, Xdevelopment and production of Xinnovative EW systems. X Team members AT&T Tech- Xnology Systems (Bell Labs), GTE, XMagnavox and Tracor provide Xadditional experience which is Xkey to successful integration of Xadvanced technologies. X No other EW team provides Xthis same level of expertise in Xradar systems, surface-to-air mis- Xsiles and advanced tactical and Xstrategic aircraft. Strengths that Xare essential to INEWS develop- Xment and support. X The Raytheon and Northrop Xjoint venture team. Expertise on a Xtotally different plane. X XRaytheon NORTHROP XJoint venture program office X6380 Hollister Avenue XGoleta, CA 93117 ! echo 'relay/ads/3': sed 's/^X//' >'relay/ads/3' <<'!' XINEWS. XTheir future Xdepends on it. X XIn the 1990's and beyond, our pilots' survival and Xtheir mission success will rely on an effective XIntegrated Electronic Warfare Systems (INEWS). XGuaranteeing the best INEWS for tomorrow Xmeans selecting the right team to build it today. X With Honeywell, Perkin-Elmer, and Tracor, Xthe TRW/Westinghouse team brings an un- Xrivaled program and technology baseline to XINEWS. Together we are concentrating on Xsystem level development...providing risk Xreduction where it counts: system software Xand system integration. X Our team offers Ada on VHSIC, complete XINEWS system simulation, expert system devel- Xopment for full situation awareness and response Xmanagement, and reliability and maintainability Xrisk reduction to reduce operation and support Xcosts while increasing system availability. The XTRW/Westinghouse INEWS--reliable perform- Xance to beat the threat, sustainable in conflict, Xaffordable for a lifetime. X INEWS: The System for Their Future-- Xfrom TRW and Westinghouse. X X TRW ! echo 'relay/ads/README': sed 's/^X//' >'relay/ads/README' <<'!' XThese are reproduced verbatim from Aviation Week. ! echo 'relay/anews/a.samp': sed 's/^X//' >'relay/anews/a.samp' <<'!' XA123@utcs.fun Xnet.rec.drugs.crack Xucbvax!ucbarpa!foo XApr 1 00:00:00 1986 XWhee! XBoy I like this stuff! ! echo 'relay/anews/a.samp.to.b': sed 's/^X//' >'relay/anews/a.samp.to.b' <<'!' XMessage-ID: 123@utcs.fun XNewsgroups: net.rec.drugs.crack XPath: ucbvax!ucbarpa!foo XFrom: ucbvax!ucbarpa!foo XDate: Apr 1 00:00:00 1986 XSubject: Whee! X XBoy I like this stuff! ! echo 'relay/anews/a.to.b': sed 's/^X//' >'relay/anews/a.to.b' <<'!' X#! /bin/sh X# a.to.b: A-format news to B-format converter (thanks, Norman) XPATH=/bin:/usr/bin:/usr/ucb; export PATH X Xsed ' X1s/^A/Message-ID: / X2s/^/Newsgroups: / X3{ Xs/^/Path: /p Xs/Path/From/ X} X4s/^/Date: / X5{ Xs/^/Subject: /p Xs/.*// X} X' ! echo 'relay/anews/b.samp': sed 's/^X//' >'relay/anews/b.samp' <<'!' XPath: ucbvax!ucbarpa!foo XFrom: ucbvax!ucbarpa!foo XSubject: Whee! XNewsgroups: net.rec.drugs.crack XMessage-ID: 123@utcs.fun XDate: Apr 1 00:00:00 1986 XHideous-Name: #@$%ucbarpa^edu&*foo X XBoy I like this stuff! ! echo 'relay/anews/b.samp.to.a': sed 's/^X//' >'relay/anews/b.samp.to.a' <<'!' XA123@utcs.fun Xnet.rec.drugs.crack Xucbvax!ucbarpa!foo XApr 1 00:00:00 1986 XWhee! XBoy I like this stuff! ! echo 'relay/anews/b.to.a': sed 's/^X//' >'relay/anews/b.to.a' <<'!' X#! /bin/sh X# bnewstoa: B-format news to A-format converter (why, oh, why?) (thanks, Norman) XPATH=/bin:/usr/bin:/usr/ucb; export PATH X Xawk ' XNR==1,/^$/ { # headers: save A headers only X if ($0 ~ /^Message-ID: /) X msgid=$2 X else if ($0 ~ /^Newsgroups: /) X ngs=$2 X else if ($0 ~ /^Path: /) X path=$2 X else if ($0 ~ /^Date: /) { X date = $2 # skip "Date:" X for (i = 3; i <= NF; i++) X date = date " " $i # append remaining fields X } else if ($0 ~ /^Subject: /) X subj=$2 X else if ($0 ~ /^$/) { # end of headers: spew out A-format equivalent X print "A" msgid X print ngs X print path X print date X print subj X inbody = "yes" X noblanksyet = "yes" X } X} Xinbody=="yes" { # copy body except first blank line, if present X if ($0 ~ /^$/ && noblanksyet == "yes") X noblanksyet = "no" X else X print X} X' ! echo 'relay/anews/README': sed 's/^X//' >'relay/anews/README' <<'!' XThese are some ill-documented utilities for converting between A News and XB News formats. Probably not of any interest to anyone any more, but we Xinclude them just in case. ! echo 'relay/article.c': sed 's/^X//' >'relay/article.c' <<'!' X/* X * article creation and destruction X */ X#include <stdio.h> X#include <sys/types.h> X#include "libc.h" X#include "news.h" X#include "headers.h" X#include "article.h" X Xvoid Xartinit(art) Xregister struct article *art; X{ X art->a_status = ST_OKAY; X hdrinit(&art->h); X art->a_haccum = NULL; X art->a_hnext = NULL; X art->a_hpalloced = 0; X art->a_hpused = 0; X art->a_hptrs = NULL; X art->a_hbytesleft = 0; X art->a_files = NULL; X art->a_tmpf = NULL; X art->a_artf = NULL; X art->a_unlink = NO; X art->a_filed = NO; X art->a_xref = NO; X art->a_blvmax = NO; X art->a_charswritten = 0; X art->a_unread = 0; X} X Xvoid Xartfree(art) Xregister struct article *art; X{ X freeheaders(&art->h); X /* a_haccum is currently not malloced */ X art->a_hptrs = NULL; /* don't free a_hptrs; see hdrsave() */ X nnfree(&art->a_files); X nnfree(&art->a_tmpf); X if (art->a_artf != NULL) { X (void) fprintf(stderr, "%s: a_artf still open in artfree()\n", X progname); X if (nfclose(art->a_artf) == EOF) { X art->a_status |= ST_DROPPED; X warning("error closing %s", art->a_tmpf); X } X art->a_artf = NULL; X } X} ! echo 'relay/article.h': sed 's/^X//' >'relay/article.h' <<'!' X/* X * All the information needed to describe an article as it is processed. X */ X X#define MINSHPTRS 30 /* initial value for sh_alloced */ X Xstruct article { X statust a_status; /* article status bits */ X struct headers h; /* strictly from headers in input: */ X char *a_haccum; /* accumulated output headers, if any */ X char *a_hnext; /* -> first free byte in a_haccum */ X short a_hpalloced; /* indices in a_hptrs */ X short a_hpused; /* indices currently in use */ X char **a_hptrs; /* -> array of ptrs to lines in a_haccum */ X unsigned a_hbytesleft; /* in a_haccum */ X char *a_files; /* filenames for history, added in filing, from h.h_ngs */ X char *a_tmpf; /* temp link name or first spool dir link */ X FILE *a_artf; /* stream corresponding to a_tmpf */ X boolean a_unlink; /* true iff a_tmpf should be unlinked when done */ X boolean a_filed; /* true iff article has been filed */ X boolean a_xref; /* true iff Xref: header generated yet */ X boolean a_blvmax; /* true iff a_unread is to be believed */ X long a_charswritten; /* into spool directory, for batcher */ X long a_unread; /* bytes of article input yet unread */ X}; X X/* return name of at least one link, for printing in error messages, etc. */ X#define spoolnm(art) ((art)->a_unlink? (art)->a_tmpf: (art)->a_files) X X/* imports from article.c */ Xextern void artinit(), artfree(); ! echo 'relay/caches.c': sed 's/^X//' >'relay/caches.c' <<'!' X/* X * cache control X */ X X#include <stdio.h> X#include <sys/types.h> X#include "news.h" X#include "active.h" X#include "caches.h" X#include "transmit.h" X Xstatust Xloadcaches() /* reload in-core caches from disk */ X{ X return actload(); X} X Xstatust Xsynccaches() /* force in-core caches to disk */ X{ X return actsync() | trclose(); X} ! echo 'relay/caches.h': sed 's/^X//' >'relay/caches.h' <<'!' X/* imports from caches.c */ Xextern statust loadcaches(), synccaches(); ! echo 'relay/control.c': sed 's/^X//' >'relay/control.c' <<'!' X/* X * Implement the Usenet control messages, as per RFC 1036 (nee 850). 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 * ihave message-ID-list remotesys generate a sendme from message-ID-list X * sendme message-ID-list remotesys send articles named to remotesys X * (ihave/sendme is semi-documented in the RFCs, kludgey and broken in B2.10.) X * X * newgroup groupname must be Approved: X * rmgroup groupname must be Approved:; allow some local control over this X * sendsys mail to Reply-To: else From: X * senduuname ditto X * version ditto X */ X X#include <stdio.h> X#include <ctype.h> X#include <sys/types.h> X X#include "libc.h" X#include "news.h" X#include "config.h" X#include "headers.h" X#include "article.h" X#include "caches.h" X#include "history.h" X X#define NO_FILES "" X#define SUBDIR binfile("ctl") /* holds shell scripts */ 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/* imports from news */ Xextern statust snufffiles(); Xextern void ihave(), sendme(); X X/* forwards */ XFORWARD statust cancelart(); XFORWARD void runctlmsg(), bombctlmsg(); X X/* X * Implement control message specified in "art". 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 * We handle cancels in this process for speed and dbm access. X * We handle ihave & sendme in this process for dbm access and X * to work around syntax restrictions (<>). X * X * In future, one could pass header values to scripts as arguments or X * in environment, as NEWS* variables, to save time in the scripts. X */ Xvoid Xctlmsg(art) Xstruct article *art; X{ X int pid, deadpid; X int wstatus; X char *inname = art->a_tmpf, *ctlcmd = art->h.h_ctlcmd; X static char nmcancel[] = "cancel "; X static char nmihave[] = "ihave "; X static char nmsendme[] = "sendme "; X X if (STREQN(ctlcmd, nmcancel, STRLEN(nmcancel))) { X art->a_status |= cancelart(ctlcmd + STRLEN(nmcancel)); X return; X } X if (STREQN(ctlcmd, nmihave, STRLEN(nmihave))) { X ihave(ctlcmd + STRLEN(nmihave), art); X return; X } X if (STREQN(ctlcmd, nmsendme, STRLEN(nmsendme))) { X sendme(ctlcmd + STRLEN(nmsendme), art); X return; X } X X art->a_status |= synccaches(); X (void) fflush(stdout); X (void) fflush(stderr); X X pid = fork(); X if (pid == 0) /* child? */ X runctlmsg(ctlcmd, inname); X else if (pid == -1) X warning("fork failed", ""); X X /* lint complains about &wstatus on 4.2+BSD; too bad, lint's wrong. */ X while ((deadpid = wait(&wstatus)) != pid && deadpid != -1) X ; X X /* wrong kid returned, fork failed or child screwed up? */ X if (deadpid == -1 || pid == -1 || wstatus != 0) X art->a_status |= ST_DROPPED; /* admin got err.msg. by mail */ X art->a_status |= loadcaches(); X} X XSTATIC boolean 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 X/* X * In theory (RFC 1036 nee 850), we should verify that the user issuing X * the cancel (the Sender: of this article or From: if no Sender) is the X * Sender: or From: of the original article or the local super-user. X * X * In practice, this is a lot of work and since anyone can forge news X * (and thus cancel anything), not worth the effort. X * X * Ignore ST_ACCESS while cancelling an already-seen article since the X * article may have been cancelled before or may have a fake history entry X * because the cancel arrived before the article. X * X * If the article being cancelled has not been seen yet, generate a history X * file entry for the cancelled article in case it arrives after the cancel X * control. The history file entry will cause the cancelled article to be X * rejected as a duplicate. X */ XSTATIC statust Xcancelart(msgidstr) Xchar *msgidstr; X{ X register char *wsp; X register char *msgid = strsave(msgidstr); X register int idbytes; X register char *wholemsgid = msgid; X register statust status = ST_OKAY; X X /* skip leading whitespace in msgid */ X while (*msgid != '\0' && isascii(*msgid) && isspace(*msgid)) X ++msgid; X /* replace trailing whitespace with NULs; `wsp >= msgid' is not safe */ X idbytes = strlen(msgid); X for (wsp = msgid + idbytes - 1; idbytes-- > 0 && X isascii(*wsp) && isspace(*wsp); --wsp) X *wsp = '\0'; X X if (alreadyseen(msgid)) { X register char *histent, *filelist; X X histent = gethistory(msgid); X if (histent != NULL && (filelist = findfiles(histent)) != NULL) X status |= snufffiles(filelist) & ~ST_ACCESS; X } else { X status |= fakehist(msgid, DEFEXP, NO_FILES); /* start log */ X (void) putchar('\n'); /* end log line */ X } X free(wholemsgid); X return status; X} X X/* X * Execute a non-builtin control message by searching $NEWSCTL/bin and X * $NEWSBIN/ctl for the command named by the control message. X * runctlmsg is called from a child of relaynews, so it must always X * call _exit() rather than exit() to avoid flushing stdio buffers. X * X * Enforce at least minimal security: the environment was standardised at X * startup, including PATH and IFS; close non-standard file descriptors; X * reject shell metacharacters in ctlcmd. X */ XSTATIC void Xrunctlmsg(ctlcmd, inname) /* child process */ Xregister char *ctlcmd, *inname; X{ X register char *cmd; X register int cmdstat; X X closeall(1); X if (!safecmd(ctlcmd)) { X (void) fprintf(stderr, X "%s: control `%s' looks unsafe to execute\n", progname, ctlcmd); X _exit(1); X } X cmd = malloc((unsigned) STRLEN("PATH=") + strlen(ctlfile("bin")) + X STRLEN(":") + strlen(SUBDIR) + STRLEN(";") + strlen(ctlcmd) + X STRLEN(" <") + strlen(inname) + 1); X if (cmd == NULL) { X warning("can't allocate memory in runctlmsg", ""); X _exit(1); X } X (void) strcpy(cmd, "PATH="); X (void) strcat(cmd, ctlfile("bin")); X (void) strcat(cmd, ":"); X (void) strcat(cmd, SUBDIR); X (void) strcat(cmd, ";"); X (void) strcat(cmd, ctlcmd); X (void) strcat(cmd, " <"); X (void) strcat(cmd, inname); X X cmdstat = system(cmd); X if (cmdstat != 0) X bombctlmsg(cmd, cmdstat); X free(cmd); X _exit(0); X} X X/* X * Notify the local news administrator by mail that "cmd" failed X * with "cmdstat" status, and _exit with bad status (again avoid stdio X * buffer flushing in the child). X */ XSTATIC void Xbombctlmsg(cmd, cmdstat) Xchar *cmd; Xint cmdstat; X{ X register char *mailcmd; X register FILE *mailf; X X mailcmd = malloc((unsigned)STRLEN("PATH=") + strlen(newspath()) + X STRLEN(" mail ") + strlen(newsmaster()) + 1); X if (mailcmd == NULL) { X warning("can't allocate memory in bombctlmsg", ""); X _exit(1); X } X (void) sprintf(mailcmd, "PATH=%s mail %s", newspath(), newsmaster()); 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); X} ! echo 'relay/control.h': sed 's/^X//' >'relay/control.h' <<'!' X/* imports from control.c */ Xextern void ctlmsg(); ! echo 'relay/cpu.h': sed 's/^X//' >'relay/cpu.h' <<'!' X/* X * CPU-specific definitions X */ X X#ifndef MAXLONG X#define MAXLONG ((long)(~(unsigned long)0 >> 1)) X#endif ! echo 'relay/ctl/checkgroups': sed 's/^X//' >'relay/ctl/checkgroups' <<'!' X#! /bin/sh X# checkgroups - check active file for missing or extra newsgroups. X# stdin must a checkgroups news article, sends mail to $NEWSMASTER X# after updating $nl/newsgroups from $nl/localgroups X# based on v1.4 of 9/4/84 X X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()= X. ${NEWSCONFIG-/usr/lib/news/bin/config} Xexport NEWSCTL NEWSBIN NEWSARTS XPATH=$NEWSCTL/bin:$NEWSBIN:$NEWSPATH ; export PATH Xumask $NEWSUMASK X X# generate newsgroups from localgroups & beheaded stdin (checkgroups article). X# appending to newsgroups instead of overwriting is a hack, X# but is about the best we can do until checkgroups is defined. X(cat $NEWSCTL/localgroups; sed '1,/^$/d') >>$NEWSCTL/newsgroups X# backup newsgroups, then strip duplicates Xcp $NEWSCTL/newsgroups $NEWSCTL/newsgroups.bac || exit 1 Xsort -u -o $NEWSCTL/newsgroups $NEWSCTL/newsgroups.bac X X# generate list of approved newsgroups from $nl/newsgroups X# [^.]*\. in next two egreps was net.|mod.|fa., which is inadequate - geoff X(echo junk; echo control; sed 's/[ \ ].*//' $NEWSCTL/newsgroups | X egrep "^([^.]*\.|general)") | sort -u >/tmp/$$a X X# generate list of locally-present newsgroups from $nl/active Xegrep "^([^.]*\.|general|junk|control)" $NEWSCTL/active | sed 's/ .*//' | X sort -u >/tmp/$$b X X# compare 'em & note differences Xcomm -13 /tmp/$$a /tmp/$$b >/tmp/$$remove Xcomm -23 /tmp/$$a /tmp/$$b >/tmp/$$add X Xif test -s /tmp/$$remove; then X echo "The following newsgroups are not valid and should be removed." X sed "s/^/ /" /tmp/$$remove X echo "" X echo "You can do this by executing the commands:" X sed "s;.*; $NEWSBIN/maint/delgroup &;" /tmp/$$remove X echo "" Xfi 2>&1 >/tmp/$$out X Xif test -s /tmp/$$add; then X echo "The following newsgroups were missing." # "and were added." X sed "s/^/ /" /tmp/$$add X echo "" X X# for i in `cat /tmp/$$add` X# do X# *** "Subject: cmsg " is a hideous botch of a kludge-hack; avoid it! X# inews -h <<! X#Control: newgroup $i X#Newsgroups: control X#Subject: newgroup $i X#Distribution: general X# X#Create $i locally. X#! X# done X Xfi 2>&1 >>/tmp/$$out X Xif test -s /tmp/$$out; then X (echo "Subject: Problems with your active file"; echo ""; X cat /tmp/$$out) | mail $NEWSMASTER Xfi X Xrm -f /tmp/$$* # clean up temporaries ! echo 'relay/ctl/newgroup': sed 's/^X//' >'relay/ctl/newgroup' <<'!' X#! /bin/sh X# newgroup group flag - create group (4-field version: B-2.10.3+ compatible) X# subject to our sys file group pattern X X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()= X. ${NEWSCONFIG-/usr/lib/news/bin/config} Xexport NEWSCTL NEWSBIN NEWSARTS XPATH=$NEWSCTL/bin:$NEWSBIN/relay:$NEWSBIN:$NEWSPATH ; export PATH # include mkpdir Xumask $NEWSUMASK X XF=/tmp/nc$$ X Xtrap "rm -f $F; exit 0" 0 Xcat >$F X X# unapproved ctl msg? then quit Xgrep -s '^Approved:' $F >/dev/null || { rm -f $F; exit 0; } X XSENDER="`grep '^Sender:' $F | sed 's/^[^:]*: *//'`" Xcase "$SENDER" in X"") SENDER="`grep '^From:' $F | sed 's/^[^:]*: *//' `" ;; Xesac X Xgreppat="^`echo $1 | sed 's/\./\\\\./g' ` " Xif grep -s "$greppat" $NEWSCTL/active >/dev/null; then # group exists? X export SENDER X chamod "$1" "$2" # change moderated flag if needed X exit Xfi X Xme="`newshostname`" Xgngppat=`awk -f $NEWSBIN/relay/canonsys.awk $NEWSCTL/sys | X egrep "^($me|ME):" | X awk -F: ' X{ X fields = split($2, field2, "/") # split ngs/dists X print field2[1] # print only ngs X exit X}' ` X Xif gngp -a "$gngppat" >/dev/null <<! X$1 X! Xthen # no group in active, but sys file likes it: make it X case "$2" in X moderated) flag=m ;; X *) flag=y ;; X esac X echo "$1 0000000000 00000 $flag" >>$NEWSCTL/active X (echo "$1 `getdate now` $SENDER" >>$NEWSCTL/active.times) # rn hook X # make the directory since rn will bitch if it's missing X mkpdir $NEWSARTS/`echo $1 | tr . / ` X echo "newsgroup $1 was created by $SENDER." | mail $NEWSMASTER Xfi ! echo 'relay/ctl/rmgroup': sed 's/^X//' >'relay/ctl/rmgroup' <<'!' X#! /bin/sh X# rmgroup group - snuff group X X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()= X. ${NEWSCONFIG-/usr/lib/news/bin/config} Xexport NEWSCTL NEWSBIN NEWSARTS XPATH=$NEWSCTL/bin:$NEWSBIN:$NEWSPATH ; export PATH Xumask $NEWSUMASK X XF=/tmp/nc$$ X Xcat >$F X X# unapproved ctl msg? then quit Xegrep '^Approved:' $F >/dev/null || { rm -f $F; exit 0; } X X# quit if no active entry Xegrep "^`echo $1 | sed 's/\./\\\\./g'` " $NEWSCTL/active >/dev/null || X { rm -f $F; exit 0; } X XSENDER="`grep '^Sender:' $F | sed 's/^[^:]*: *//'`" Xcase "$SENDER" in X"") X SENDER="`grep '^From:' $F | sed 's/^[^:]*: *//'`" X ;; Xesac X X# tell the local usenet administrator to do it by hand Xecho "rmgroup $1 says $SENDER" | mail $NEWSMASTER X Xrm -f $F* ! echo 'relay/ctl/sendsys': sed 's/^X//' >'relay/ctl/sendsys' <<'!' X#! /bin/sh X# sendsys - mail sys file to sender identified in stdin's headers X X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()= X. ${NEWSCONFIG-/usr/lib/news/bin/config} Xexport NEWSCTL NEWSBIN NEWSARTS XPATH=$NEWSCTL/bin:$NEWSBIN/relay:$NEWSBIN:$NEWSPATH ; export PATH Xumask $NEWSUMASK X XSENDER="`newsreply`" X(echo "Subject: response from `newshostname` to your sendsys"; echo ""; Xcase "$1" in X"") cat $NEWSCTL/sys ;; X*) awk -f $NEWSBIN/relay/canonsys.awk $NEWSCTL/sys | egrep "^$1:" ;; Xesac ) | mail "$SENDER" Xecho "$NEWSCTL/sys file has been sent to $SENDER. Remain calm." | mail $NEWSMASTER ! echo 'relay/ctl/senduuname': sed 's/^X//' >'relay/ctl/senduuname' <<'!' X#! /bin/sh X# senduuname - mail `uuname` to sender identified in stdin's headers X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()= X. ${NEWSCONFIG-/usr/lib/news/bin/config} Xexport NEWSCTL NEWSBIN NEWSARTS XPATH=$NEWSCTL/bin:$NEWSBIN/relay:$NEWSBIN:$NEWSPATH ; export PATH Xumask $NEWSUMASK X XSENDER="`newsreply`" X(echo "Subject: response to your senduuname"; echo ""; uuname) | mail "$SENDER" Xecho "uuname output sent to $SENDER" | mail $NEWSMASTER ! echo 'relay/ctl/version': sed 's/^X//' >'relay/ctl/version' <<'!' X#! /bin/sh X# version - mail version id to sender identified in stdin's headers X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()= X. ${NEWSCONFIG-/usr/lib/news/bin/config} Xexport NEWSCTL NEWSBIN NEWSARTS XPATH=$NEWSCTL/bin:$NEWSBIN/relay:$NEWSBIN:$NEWSPATH ; export PATH Xumask $NEWSUMASK X XSENDER="`newsreply`" Xecho C | mail "$SENDER" ! echo 'relay/aux/mailnews': sed 's/^X//' >'relay/aux/mailnews' <<'!' X#! /bin/sh X# send news by mail, encoded for protection X X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()= X. ${NEWSCONFIG-/usr/lib/news/bin/config} X XPATH=$NEWSCTL/bin:$NEWSBIN/batch:$NEWSBIN:$NEWSPATH ; export PATH X Xcase $# in X0) echo "Usage: $0 destination ..." >&2 X exit 1 X ;; Xesac X X( echo ; bencode ) | mail $* ! echo 'relay/aux/sendnews': sed 's/^X//' >'relay/aux/sendnews' <<'!' X#! /bin/sh X# sendnews destination... - protect & mail article on stdin to destinations XPATH=/bin:/usr/bin; export PATH X Xcase $# in X0) X echo "usage: $0 destination..." >&2 X exit 1 ;; Xesac X(echo ''; sed 's/^/N/') | mail $* ! echo 'relay/aux/canonsys.awk': sed 's/^X//' >'relay/aux/canonsys.awk' <<'!' X# canonicalise the sys file: X# delete comments & leading whitespace, collapse continued lines X# rewritten to avoid assignment to $0, which is broken in older awks X/^/ { thisln = $0 } X/^#/ { partline = ""; next } # delete comments X/^[\t ]/ { X for (s = substr(thisln, n); s ~ /^[\t ]/; s = substr(thisln, ++n)) X ; # skip leading whitespace X thisln = s X} X/\\$/ { partline = partline substr(thisln, 1, length(thisln)-1); next } X{ # non-continued line X partline = partline thisln # terminate the whole entry X if (partline != "") X print partline X partline = "" X} XEND { X if (partline != "") X print partline # flush any partial line X} ! echo 'relay/aux/chamod': sed 's/^X//' >'relay/aux/chamod' <<'!' X#!/bin/sh X# chamod ng flag - change the "moderated" flag for ng to flag X X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()= X. ${NEWSCONFIG-/usr/lib/news/bin/config} Xexport NEWSCTL NEWSBIN NEWSARTS XPATH=$NEWSCTL/bin:$NEWSBIN:$NEWSPATH ; export PATH Xumask $NEWSUMASK X Xcase "$1" in X"") X echo "$0: null newsgroup not permitted" >&2 X exit 1 X ;; Xesac Xcase "$2" in Xmoderated) flag=m ;; X*) flag=y ;; Xesac X Xaflag=`awk "/$1/"' { print $4 }' $NEWSCTL/active` Xif test "$aflag" != "$flag" -a \( "$aflag" = m -o "$aflag" = y \); then X # old & new flags differ & old flag is m or y X # watch closely - shell quoting is tricky here X awk ' X$1 == "'$1'" { # this line is for first arg. X print $1, $2, $3, "'$flag'" X next X} X { print } X' $NEWSCTL/active >$NEWSCTL/active.new X cp $NEWSCTL/active $NEWSCTL/active.old X cp $NEWSCTL/active.new $NEWSCTL/active X rm -f $NEWSCTL/active.new X X case "$flag" in X m) pfx="" ;; X *) pfx=un ;; X esac X echo "newsgroup $1 was changed to ${pfx}moderated by $SENDER" | X mail $NEWSMASTER Xfi ! echo 'relay/aux/mkpdir': sed 's/^X//' >'relay/aux/mkpdir' <<'!' X#! /bin/sh X# mkpdir dir ... - make directory and parents X X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()= X. ${NEWSCONFIG-/usr/lib/news/bin/config} Xexport NEWSCTL NEWSBIN NEWSARTS XPATH=$NEWSCTL/bin:$NEWSBIN/relay:$NEWSBIN:$NEWSPATH ; export PATH # must include this file's dir. X Xumask $NEWSUMASK X Xstatus=0 Xfor dir Xdo X mkdir "$dir" 2>/dev/null X if test ! -d "$dir"; then X mkpdir "`echo $dir | sed 's;/[^/]*$;;'`" X mkdir "$dir" X if test ! -d "$dir"; then X status=1 X fi X fi Xdone Xexit $status ! echo 'relay/aux/newsreply': sed 's/^X//' >'relay/aux/newsreply' <<'!' X#! /bin/sh X# newsreply - print return address from news article on stdin X# This version assumes a domain mailer (user@host.domain works) or X# "internet" in mailpaths file, unless $NEWSCTL/replyusepath exists. X X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()= X. ${NEWSCONFIG-/usr/lib/news/bin/config} Xexport NEWSCTL NEWSBIN NEWSARTS XPATH=$NEWSCTL/bin:$NEWSBIN:$NEWSPATH ; export PATH Xumask $NEWSUMASK X Xart=/tmp/nc$$ Xmroute=/tmp/ncm$$ X Xcat >$art X Xif test -r $NEWSCTL/replyusepath Xthen X sender="`grep '^Path:' $art | sed 's/^[^:]*://' `" X echo "$sender" X rm -f $art X exit 0 Xfi X X# pick out the appropriate header Xsender="` grep '^Reply-To:' $art `" Xcase "$sender" in X"") sender="` grep '^From:' $art `" ;; Xesac X X# strip header keyword, full name & duplicate lines, print result. X# this copes with "address", "address (full name)" and "full name <address>". Xsender=` echo "$sender" | sed 's/^[^:]*:[ ]*// Xs/ (.*)// Xs/.*<\(.*\)>/\1/ X1q' ` X X# B 2.11 mailpaths/"internet" hack Xcat $NEWSCTL/mailpaths | X while read ngpat route junk X do X case "$ngpat" in X internet) X echo "$route" >$mroute X break X ;; X esac X done Xif test -s $mroute; then X sed "s/%s/` X echo $sender | sed 's/\(.*\)@\(.*\)/\2!\1/' X `/" <$mroute # the real B 2.11 hack: u@d -> route!d!u Xelse X echo $sender Xfi X Xrm -f $art $mroute ! echo done -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.