[unix-pc.sources] B News 2.11 -- official patch #13

arnold@skeeve.UUCP (12/01/87)

Here is patch #13 for B News 2.11. I have not installed it yet on my
machine, nor have I yet updated my uucp-able archive of the news source.
I will post more information when I've done that.

Enjoy.
------------- feed to patch in news source directory ------------------
From rick@seismo.CSS.GOV Mon Nov 23 15:02:37 1987
Path: seismo!rick
From: rick@seismo.CSS.GOV (Rick Adams)
Newsgroups: news.software.b
Subject: news 2.11 src patch #13
Message-ID: <44192@beno.seismo.CSS.GOV>
Date: 23 Nov 87 20:02:37 GMT
Organization: Center for Seismic Studies, Arlington, VA
Lines: 2089

Description:
	This is patch 13 of the news sources.  It addresses the following
	problems (p) and includes several new features (f):

	(p) - The "H" flag in the sys file was broken some versions ago
	causing parts of the history data to be thrown away before it could
	be effectively used by the use of the flag in the sys file.  This
	code has been corrected.

	(f) - Support for NFS client systems which mount LIBDIR and SPOOLDIR
	directories located on a NFS server.

	(f) - LIBDIR/moderators lists the name of the moderators that can
	post to a given moderated group locally.  Moderators no longer have
	to remember to include an Approved: header in their messages.

	(f) - new MODFILEONLY switch in defs.dist.  Turning this switch on
	causes inews to ignore Approved: headers in locally submitted
	articles.  All local moderators *must* be listed in
	LIBDIR/moderators when this switch is in use.

	(f) - The fascist and moderator code will accept groups of users
	(etc/group) as well as a list of users in the LIBDIR/authorized and
	LIBDIR/moderators files, respectively.  Truly a hack - a backslash
	preceding the username signifies a group name instead.

	(f) - Bug groups ala M.I.T. mail to BUGS-XXXX bboards.
	LIBDIR/buggroups contains an entry for each newsgroup that defines
	the beginning of a newsgroup hierarchy of "bug" groups.  Posting to
	a non-existent sub-newsgroup under the declared hierarchy causes
	the posting to be sent to the declared newsgroup instead.

	(f) - recnews update to take advantage of the -x switch in inews.
	You may now specify that a certain site in the sys file should not
	receive the incoming posting no matter what when gatewaying a mail
	message into the news system.

Fix:
	cd to the src directory and apply the following patch.

Index: Makefile.dst
Prereq: 1.27
*** .d/Makefile.dst	Wed Nov  4 14:56:12 1987
--- Makefile.dst	Thu Nov 19 16:54:08 1987
***************
*** 1,2 ****
! # '@(#)Makefile.dst	1.27	11/4/87'
  # Generic Makefile.
--- 1,2 ----
! # '@(#)Makefile.dst	1.28	11/19/87'
  # Generic Makefile.
***************
*** 41,42 ****
--- 41,50 ----
  
+ # Order is important here
+ INST = full
+ #NFSCLIENT INST = nfs
+ 
+ #NFSCLIENT NFSCLIENT= -DNFSCLIENT
+ NFSSPOOLDIR = /nfsnews/$(SPOOLDIR)
+ NFSLIBDIR = /nfsnews/$(LIBDIR)
+ 
  DEFS =	-DRNEWS=\"$(BINDIR)/rnews\" -DSPOOLDIR=\"$(SPOOLDIR)\" \
***************
*** 44,46 ****
  	-DBINDIR=\"$(BINDIR)\" -DNEWSUSR=\"$(NEWSUSR)\" \
! 	-DNEWSGRP=\"$(NEWSGRP)\" ${SERVER}
  
--- 52,54 ----
  	-DBINDIR=\"$(BINDIR)\" -DNEWSUSR=\"$(NEWSUSR)\" \
! 	-DNEWSGRP=\"$(NEWSGRP)\" ${SERVER} ${NFSCLIENT}
  
***************
*** 118,120 ****
  SCRIPTS = sendbatch rmgroup checkgroups
! OTHERS = inews $(UTILS) $(SCRIPTS)
  COMMANDS = readnews checknews postnews vnews
--- 126,129 ----
  SCRIPTS = sendbatch rmgroup checkgroups
! NFSOTHERS = inews
! OTHERS = $(NFSOTHERS) $(UTILS) $(SCRIPTS)
  COMMANDS = readnews checknews postnews vnews
***************
*** 122,126 ****
  # dependencies
! all: $(P) $(OTHERS) $(COMMANDS)
  
! install: all help vnews.help installit
  	chmod 755 ./installit
--- 131,141 ----
  # dependencies
! all: $(INST)all
  
! fullall: $(P) $(OTHERS) $(COMMANDS)
! 
! nfsall: $(P) $(NFSOTHERS) $(COMMANDS)
! 
! install: $(INST)install
! 
! fullinstall: all help vnews.help installit
  	chmod 755 ./installit
***************
*** 149,150 ****
--- 164,179 ----
  
+ nfsinstall: nfsall help vnews.help
+ 	chmod 755 ./installit
+ 	-test -d $(DESTDIR)$(BINDIR) || mkdir $(DESTDIR)$(BINDIR)
+ 	-test -d $(DESTDIR)$(LIBDIR) || mkdir $(DESTDIR)$(LIBDIR)
+ 	for i in $(COMMANDS); do \
+ 		./installit -m 755 -o $(NEWSUSR) -g $(NEWSGRP) -s $$i \
+ 			$(DESTDIR)$(BINDIR); \
+ 	done
+ 	cp help vnews.help $(DESTDIR)$(LIBDIR)
+ 	./installit -m 6755 -o root -g $(NEWSGRP) -s inews \
+ 		$(DESTDIR)$(LIBDIR)
+ 	-rm -f $(DESTDIR)$(BINDIR)/rnews
+ #VMS 	vms -v @euninstal
+ 
  defs.h:	defs.dist localize.sh Makefile.dst Makefile
***************
*** 159,161 ****
  
! update: install.sh makeactive.sh
  	sh install.sh $(SPOOLDIR) $(LIBDIR) $(BINDIR) $(NEWSUSR) $(NEWSGRP) $(OSTYPE)
--- 188,192 ----
  
! update: $(INST)update
! 
! fullupdate: install.sh makeactive.sh
  	sh install.sh $(SPOOLDIR) $(LIBDIR) $(BINDIR) $(NEWSUSR) $(NEWSGRP) $(OSTYPE)
***************
*** 162,163 ****
--- 193,200 ----
  	chmod 6755 $(LIBDIR)/inews
+ 
+ nfsupdate: install.sh
+ 	sh install.sh $(SPOOLDIR) $(LIBDIR) $(BINDIR) $(NEWSUSR) $(NEWSGRP) $(OSTYPE) $(NFSSPOOLDIR) $(NFSLIBDIR)
+ 	chown root $(LIBDIR)/inews
+ 	chmod 6755 $(LIBDIR)/inews
+ 
  

Index: control.c
Prereq: 2.56
*** .d/control.c	Wed Nov  4 14:56:35 1987
--- control.c	Thu Nov 19 16:54:11 1987
***************
*** 21,23 ****
  #ifdef SCCSID
! static char	*SccsId = "@(#)control.c	2.56	11/4/87";
  #endif /* SCCSID */
--- 21,23 ----
  #ifdef SCCSID
! static char	*SccsId = "@(#)control.c	2.57	11/19/87";
  #endif /* SCCSID */
***************
*** 146,147 ****
--- 146,148 ----
  
+ #ifndef NFSCLIENT
  /*
***************
*** 599,600 ****
--- 600,602 ----
  }
+ #endif /* !NFSCLIENT */
  
***************
*** 619,620 ****
--- 621,623 ----
  		error("cancel: Too few arguments.");
+ #ifndef NFSCLIENT
  	(void) strcpy(whatsisname, senderof(&header));
***************
*** 691,692 ****
--- 694,696 ----
  	}
+ #endif /* !NFSCLIENT */
  	return 0;
***************
*** 694,695 ****
--- 698,700 ----
  
+ #ifndef NFSCLIENT
  /*
***************
*** 779,780 ****
--- 784,786 ----
  }
+ #endif /* !NFSCLIENT */
  
***************
*** 970,971 ****
--- 976,978 ----
  
+ #ifndef NFSCLIENT
  /*
***************
*** 1016,1017 ****
--- 1023,1025 ----
  }
+ #endif /* !NFSCLIENT */
  

Index: defs.dist
Prereq: 2.59
*** .d/defs.dist	Sun Oct 18 18:03:03 1987
--- defs.dist	Thu Nov 19 16:54:11 1987
***************
*** 16,18 ****
  
! /*	@(#)defs.dist	2.59	10/15/87	*/
  
--- 16,18 ----
  
! /*	@(#)defs.dist	2.60	11/19/87	*/
  
***************
*** 92,93 ****
--- 92,96 ----
  /* #define ORGDISTRIB	"froozum"	/* For organization wide control message handling */
+ /* #define MODFILEONLY		/* define when local postings to moderated */
+ 				/* groups must be approved by the contents */
+ 				/* of the $(LIB)/moderators file	   */
  
***************
*** 131 ****
--- 134,154 ----
  #endif /* M_XENIX */
+ 
+ /* for NFS Support */
+ #ifdef NFSCLIENT		/* NFSSYSNAME found in $(LIB)/nfssysname */
+ # define NFSCMDFORMAT "/usr/ucb/rsh %s /usr/lib/news/inews -p < %s"
+ # define NFSCMDARGS NFSSYSNAME,ARTICLE
+ 	/* If NFSCLIENT is flagged in Makefile, then we're compiling code
+ 	 * for an NFS client system.  In this case, inews on the client is
+ 	 * expected to only do some preliminary checking.  The full check is
+ 	 * expected to happen on the host NFSCLIENT.  The two statements above
+ 	 * are used to form a command which is called by system(command) in the
+ 	 * code.  The two arguments are most probably the only pieces of
+ 	 * information that one will need from within the program.  The first
+ 	 * argument (NFSSYSNAME) is the name of the master system that is
+ 	 * suppose to perform the final checks and post the article.  The
+ 	 * second argument (ARTicle) is a string which contains the /tmp
+ 	 * file name of the file that has the article to be posted. Note:
+ 	 * all program and file names should be fully qualified with directory
+ 	 * names for security purposes!!!!
+ 	 */
+ #endif /* NFSCLIENT */

Index: funcs.c
Prereq: 2.36
*** .d/funcs.c	Thu Oct  8 00:20:21 1987
--- funcs.c	Thu Nov 19 16:54:13 1987
***************
*** 18,20 ****
  #ifdef SCCSID
! static char	*SccsId = "@(#)funcs.c	2.36	10/7/87";
  #endif /* SCCSID */
--- 18,20 ----
  #ifdef SCCSID
! static char	*SccsId = "@(#)funcs.c	2.37	11/19/87";
  #endif /* SCCSID */
***************
*** 638,639 ****
--- 638,641 ----
  	char facuser[BUFLEN], facgroups[BUFLEN], factemp[BUFLEN];
+ 	char *getgrplist();
+ 	char *grplist = NULL;
  	register char  *facptr;
***************
*** 647,652 ****
  	facfd = fopen(factemp, "r");
! 
! 	if (facfd != NULL) { /* If no such file, we go with the global default */
! 		while (fscanf(facfd, "%[^:]:%s\n", facuser, factemp) != EOF)
! 		{
  			if (feof(facfd))
--- 649,652 ----
  	facfd = fopen(factemp, "r");
! 	if (facfd != NULL) { /* If no such file, use global default only */
! 		while (fscanf(facfd, "%[^:]:%s\n", facuser, factemp) != EOF) {
  			if (feof(facfd))
***************
*** 653,655 ****
  				break;
! 			if (strncmp(facuser, user, BUFLEN) == 0) {
  				(void) strcat(facgroups, ",");
--- 653,665 ----
  				break;
! 			if (facuser[0] == '#') continue;
! 			if (facuser[0] == '\\') {
! 				if (!grplist) grplist = getgrplist(user);
! 				facptr = facuser;
! 				facptr++;
! 				if (ngmatch(facptr, grplist)) {
! 					(void) strcat(facgroups, ",");
! 					(void) strcat(facgroups, factemp);
! 					continue;
! 				}
! 			} else if (STRNCMP(facuser, user, BUFLEN) == 0) {
  				(void) strcat(facgroups, ",");
***************
*** 694 ****
--- 704,753 ----
  #endif /* FASCIST */
+ 
+ /*  This routine is meant to be called only once.  On a system with a
+  *  large /etc/group file, this routine is a HOG!!!!!  In order to save
+  *  ourselves from pain, this routine will look up groups for "user"
+  * the first time.  After that, it will always return the same results...
+  */
+ 
+ char *
+ getgrplist(user)
+ register char *user;
+ {
+ 	register struct group *gr;
+ 	register struct passwd *pw;
+ 	register char **cp;
+ 	register int len;
+ 	static int grpdone = FALSE;
+ 	static char grplist[LBUFLEN];
+ 
+ #ifdef DEBUG
+ 	fprintf(stderr, "getgrplist entered...\n");
+ #endif /* DEBUG */
+ 
+ 	if (grpdone == FALSE) {
+ #ifdef DEBUG
+ 		fprintf(stderr, "... actually reading /etc/group...\n");
+ #endif /* DEBUG */
+ 		pw = getpwnam(user);
+ 		setgrent();
+ 		while (gr = getgrent()) {
+ 			if (pw) if (pw->pw_gid == gr->gr_gid) {
+ 				strcat(grplist, gr->gr_name);
+ 				strcat(grplist, ",");
+ 				continue;
+ 			}	
+ 			for (cp = gr->gr_mem; cp && *cp; cp++)
+ 				if (STRCMP(*cp, user) == 0) {
+ 					strcat(grplist, gr->gr_name);
+ 					strcat(grplist, ",");
+ 					break;
+ 				}
+ 		}
+ 		if ((len = strlen(grplist))) grplist[len-1] = '\0';
+ 		grpdone = TRUE;
+ 	}
+ #ifdef DEBUG
+ 	fprintf(stderr, "Group list - %s\n", grplist);
+ #endif /* DEBUG */
+ 	return grplist;
+ }

Index: iextern.c
Prereq: 2.18
*** .d/iextern.c	Wed Oct  7 16:52:10 1987
--- iextern.c	Thu Nov 19 16:54:13 1987
***************
*** 6,8 ****
  #ifdef SCCSID
! static char	*SccsId = "@(#)iextern.c	2.18	9/24/87";
  #endif /* SCCSID */
--- 6,8 ----
  #ifdef SCCSID
! static char	*SccsId = "@(#)iextern.c	2.19	11/19/87";
  #endif /* SCCSID */
***************
*** 34 ****
--- 34,36 ----
  char	is_mod[NAMELEN];		/* contains newsgroup if moderated */
+ int	is_mod_file_okay;		/* true if /usr/lib/news/moderators */
+ 					/*  okays posting by the user */

Index: ifuncs.c
Prereq: 2.66
*** .d/ifuncs.c	Thu Oct  8 00:21:23 1987
--- ifuncs.c	Thu Nov 19 16:54:17 1987
***************
*** 18,20 ****
  #ifdef SCCSID
! static char	*SccsId = "@(#)ifuncs.c	2.66	10/7/87";
  #endif /* SCCSID */
--- 18,20 ----
  #ifdef SCCSID
! static char	*SccsId = "@(#)ifuncs.c	2.67	11/19/87";
  #endif /* SCCSID */
***************
*** 64,65 ****
--- 64,66 ----
  
+ #ifndef NFSCLIENT
  #ifndef GENERICPATH
***************
*** 472,473 ****
--- 473,475 ----
  }
+ #endif /* !NFSCLIENT */
  
***************
*** 546,547 ****
--- 548,550 ----
  
+ #ifndef NFSCLIENT
  	idlock(lcident);
***************
*** 577,578 ****
--- 580,582 ----
  #endif /* !DBM */
+ #endif /* !NFSCLIENT */
  	histline[0] = '\0';
***************
*** 580,581 ****
--- 584,586 ----
  	addhist("\t");
+ #ifndef NFSCLIENT
  #ifdef DEBUG
***************
*** 584,585 ****
--- 589,593 ----
  	return FALSE;
+ #else /* NFSCLIENT */
+ 	return TRUE;
+ #endif /* NFSCLIENT */
  }
***************
*** 602,603 ****
--- 610,612 ----
  #endif /* !DBM */
+ 	char tmphline[PATHLEN];
  
***************
*** 626,628 ****
  	/* We assume that history has already been called, calling dbminit. */
! 	p = index(hline, '\t');
  	if (p)
--- 635,638 ----
  	/* We assume that history has already been called, calling dbminit. */
! 	strcpy(tmphline,hline);
! 	p = index(tmphline, '\t');
  	if (p)
***************
*** 629,632 ****
  		*p = 0;
! 	lcase(hline);
! 	lhs.dptr = hline;
  	lhs.dsize = strlen(lhs.dptr) + 1;
--- 639,642 ----
  		*p = 0;
! 	lcase(tmphline);
! 	lhs.dptr = tmphline;
  	lhs.dsize = strlen(lhs.dptr) + 1;
***************
*** 788,790 ****
   */
! ngfcheck(isproc)
  {
--- 798,801 ----
   */
! ngfcheck(user, isproc, is_mod_init)
! char	*user;
  {
***************
*** 793,795 ****
  	register int	i, j;
! 	register int	ngcount, okcount, havealiased;
  	register int	pass;
--- 804,806 ----
  	register int	i, j;
! 	register int	ngcount, okcount, dorecheck;
  	register int	pass;
***************
*** 796,797 ****
--- 807,809 ----
  	char *		ngs[sizeof header.nbuf / 2];
+ 	char *		ngsbug[sizeof header.nbuf / 2];
  	char		uses[sizeof header.nbuf / 2];
***************
*** 800,803 ****
  
! 	havealiased = ngcount = 0;
! 	is_mod[0] = '\0';
  	/*
--- 812,828 ----
  
! /* uses values
! **  0 - haven't seen the newsgroup name anyplace
! **  1 - write newsgroup name back into Newsgroup: line
! **  2 - exact newsgroup name found in active or aliases file
! **  3 - newsgroup name found as prefix in bugs file (but not #2)
! **  4 - (2) plus name in bugs file
! */
! 
! #define NGUNSEEN 0
! #define NGOK 1
! #define NGALIAS 2
! #define NGBUGS 3
! #define NGABUGS 4
! 
! 	ngcount = 0;
  	/*
***************
*** 814,815 ****
--- 839,842 ----
  		ngs[ngcount] = cp;
+ 		ngsbug[ngcount] = (char *) NULL;
+ 		uses[ngcount] = NGUNSEEN;
  		do {
***************
*** 830,832 ****
  		}
! 		uses[ngcount] = 1;	/* it should go in "Newsgroups" line */
  		++ngcount;
--- 857,859 ----
  		}
! 		uses[ngcount] = NGOK;	/* it should go in "Newsgroups" line */
  		++ngcount;
***************
*** 837,839 ****
  recheck:
! 	okcount = 0;
  	rewind(actfp); clearerr(actfp);
--- 864,868 ----
  recheck:
! 	dorecheck = okcount = 0;
! 	is_mod[0] = '\0';
! 	is_mod_file_okay = is_mod_init;
  	rewind(actfp); clearerr(actfp);
***************
*** 842,847 ****
  			continue;	/* strange line in input! */
- 		/* newsgroup 12345 12345 X */
- 		/*  cp +    01234567890123 */
- 		if (!isproc && cp[13]  == 'n')
- 			continue;	/* can't post to this group! */
  		*cp = '\0';
--- 871,872 ----
***************
*** 848,854 ****
  		for (i = 0; i < ngcount; ++i)
! 			if (uses[i] >= 1 && STRCMP(bfr, ngs[i]) == 0) {
! 				uses[i] = 2;	/* it should be localized too */
! 				if (cp[13] == 'm')
! 					strcpy(is_mod, bfr);
! 				++okcount;
  			}
--- 873,890 ----
  		for (i = 0; i < ngcount; ++i)
! 			if (STRCMP(bfr, ngs[i]) == NGUNSEEN) { /* localize? */
! 				/* newsgroup 12345 12345 X */
! 				/*  cp +    01234567890123 */
! 				if (!isproc && cp[13]  == 'n')
! 					uses[i] = NGOK;
! 				else {
! 					if (uses[i] < NGALIAS)
! 						uses[i] = NGALIAS;
! 					if (cp[13] == 'm') {
! 						strcpy(is_mod, bfr);
! 						if (!is_mod_file_okay)
! 						     is_mod_file_okay =
! 						       mod_file_okay(user,bfr);
! 					}
! 					++okcount;
! 				}
  			}
***************
*** 855,856 ****
--- 891,929 ----
  	}
+ 	/*
+ 	** See what groups we can find in the bugs file
+ 	*/
+ 	if ((f = fopen(BUGFILE, "r")) != NULL) {
+ 		while (fgets(bfr, BUFLEN, f) == bfr) {
+ 			if (bfr[0] == '#')
+ 				continue;
+ 			cp = index(bfr, '\n');
+ 			*cp = '.';
+ 			for (i = 0; i < ngcount; ++i) {
+ 				register int bfrlen = strlen(bfr);
+ 				register int ngslen = strlen(ngs[i]);
+ 				if (uses[i] == NGBUGS || uses[i] == NGABUGS)
+ 					continue;
+ 				if (PREFIX(ngs[i], bfr) ||
+ 				    (bfrlen-1 == ngslen &&
+ 				     !STRNCMP(ngs[i], bfr, ngslen))) {
+ 					if (uses[i] == NGALIAS)
+ 						uses[i] = NGABUGS;
+ 					else {
+ 						bfr[bfrlen-1] = '\0';
+ 						cp = "Bug group %s -> %s [ok]";
+ 						log(cp, ngs[i], bfr);
+ 						if (ngsbug[i] == (char *) NULL)
+ 							ngsbug[i] = ngs[i];
+ 						ngs[i] = AllocCpy(bfr);
+ 						bfr[bfrlen-1] = '.';
+ 						uses[i] = NGBUGS;
+ 						okcount++;
+ 						dorecheck++;
+ 					}
+ 				}
+ 			}
+ 		}
+ 		(void) fclose(f);
+ 	}
+ 
  #ifdef ALWAYSALIAS
***************
*** 859,863 ****
  	/*
! 	** Handle groups absent from active file.
  	*/
! 	if (havealiased == 0 && okcount < ngcount) {
  		/*
--- 932,936 ----
  	/*
! 	** Handle groups absent from active and bug_groups files.
  	*/
! 	if (okcount < ngcount) {
  		/*
***************
*** 866,868 ****
  		f = xfopen(ALIASES, "r");
! 		while (okcount < ngcount && fscanf(f, "%s %s%*[^\n]", abuf, bfr) == 2)
  			for (i = 0; i < ngcount; ++i) {
--- 939,944 ----
  		f = xfopen(ALIASES, "r");
! 		while (okcount < ngcount &&
! 		     fscanf(f, "%s %s%*[^\n]", abuf, bfr) == 2) {
! 			if (abuf[0] == '#')
! 				continue;
  			for (i = 0; i < ngcount; ++i) {
***************
*** 869,871 ****
  #ifndef ALWAYSALIAS
! 				if (uses[i] == 2)
  					continue;
--- 945,947 ----
  #ifndef ALWAYSALIAS
! 				if (uses[i] > NGOK && uses[i] != NGBUGS)
  					continue;
***************
*** 872,885 ****
  #endif /* ALWAYSALIAS */
! 				if (STRCMP(ngs[i], abuf) != 0)
  					continue;
! 				if (isproc)
  					cp = "Aliased newsgroup %s to %s";
! 				else
  					cp = "Please change %s to %s";
  				logerr(cp, abuf, bfr);
  				ngs[i] = AllocCpy(bfr);
! 				uses[i] = 2;
! 				++havealiased;
! 				++okcount;
  			}
  		(void) fclose(f);
--- 948,975 ----
  #endif /* ALWAYSALIAS */
! 				cp = (char *) NULL;
! 				if (uses[i] == NGBUGS)
! 				    if (STRCMP(ngsbug[i], abuf) == 0)
! 					cp = "Aliased newsgroup %s to %s";
! 				if (cp == (char *) NULL) {
! 			           if (STRCMP(ngs[i], abuf) != 0)
  					continue;
! 			           if (isproc)
  					cp = "Aliased newsgroup %s to %s";
! 			           else
  					cp = "Please change %s to %s";
+ 				}
  				logerr(cp, abuf, bfr);
+ 				if (uses[i] == NGBUGS) {
+ 					free(ngs[i]);
+ 					ngsbug[i] = (char *) NULL;
+ 				}
  				ngs[i] = AllocCpy(bfr);
! 				++dorecheck;
! #ifdef ALWAYSALIAS
! 				if (uses[i] != NGBUGS)
! #endif /* ALWAYSALIAS */
! 					++okcount;
! 				uses[i] = NGALIAS;
  			}
+ 		}
  		(void) fclose(f);
***************
*** 886,888 ****
  		for (i = 0; i < ngcount; ++i) {
! 			if (uses[i] == 2)
  				continue;
--- 976,978 ----
  		for (i = 0; i < ngcount; ++i) {
! 			if (uses[i] > NGOK)
  				continue;
***************
*** 902,912 ****
  			newssave(infp, (char *) NULL);
- 		/*
- 		 * Unfortunately, if you alias an unmoderated group to a
- 		 * moderated group, you must recheck the active file to see
- 		 * if the new group is moderated. Rude but necessary.
- 		 */
- 		if (havealiased)
- 			goto recheck;	
  	}
  	/*
  	** Zap duplicates.
--- 992,1005 ----
  			newssave(infp, (char *) NULL);
  	}
+ 
  	/*
+ 	 * Unfortunately, if you alias an unmoderated group to a
+ 	 * moderated group, you must recheck the active file to see
+ 	 * if the new group is moderated. Rude but necessary.
+ 	 */
+ 
+ 	if (dorecheck)
+ 		goto recheck;
+ 
+ 	/*
  	** Zap duplicates.
***************
*** 914,926 ****
  	for (i = 0; i < ngcount - 1; ++i) {
! 		if (uses[i] == 0)
  			continue;
! 		for (j = i + 1; j < ngcount; ++j) {
! 			if (uses[j] == 0)
  				continue;
  			if (STRCMP(ngs[i], ngs[j]) != 0)
! 				continue;
! 			logerr("Duplicate %s removed", ngs[j]);
! 			if (uses[i] < uses[j])
! 				uses[i] = uses[j];
! 			uses[j] = 0;
  		}
--- 1007,1063 ----
  	for (i = 0; i < ngcount - 1; ++i) {
! 		if (uses[i] == NGUNSEEN)
  			continue;
! 		for (j = i + 1; ((j < ngcount) && (uses[i] != NGUNSEEN)); ++j){
! 			register int kill = -1;
! 			register int keep = -1;
! 			if (uses[j] == NGUNSEEN)
  				continue;
+ 			if (uses[i] == NGABUGS || uses[j] == NGABUGS) {
+ 				register int k = i;
+ 				register int l = j;
+ 				if (uses[i] == NGABUGS && uses[j] == NGABUGS) {
+ 					if (strlen(ngs[j]) < strlen(ngs[i])) {
+ 						k = j;
+ 						l = i;
+ 					}
+ 				} else if (uses[i] == NGABUGS) {
+ 					k = j;
+ 					l = i;
+ 				}
+ 				strcpy(bfr, ngs[k]);
+ 				strcat(bfr, ".");
+ 				if (PREFIX(ngs[l], bfr)) {
+ 					kill = k;
+ 					keep = l;
+ 					if (uses[k] != NGBUGS ||
+ 					    ngsbug[l] == (char *) NULL)
+ 						logerr("Duplicate %s removed",
+ 							ngs[k]);
+ 				}
+ 			}
+ 			if (kill < 0) {
  			if (STRCMP(ngs[i], ngs[j]) != 0)
! 					continue;
! 				keep = i;
! 				kill = j;
! 				if (uses[j] != NGBUGS)
! 					logerr("Duplicate %s removed", ngs[j]);
! 				if (uses[i] < uses[j])
! 					uses[i] = uses[j];
! 			}
! 			if (kill >= 0) {
! 				if (uses[kill] == NGBUGS) {
! 					if (ngsbug[keep] == (char *) NULL)
! 						ngsbug[keep] = ngsbug[kill];
! 					else if (ngsbug[kill] != (char*) NULL){
! 						sprintf(bfr, "%s,%s",
! 							ngsbug[keep],
! 							ngsbug[kill]);
! 						if (ngsbug[keep] < tbuf || ngsbug[keep] > &tbuf[sizeof tbuf - 1])
! 							free(ngsbug[keep]);
! 						ngsbug[keep] = AllocCpy(bfr);
! 					}
! 				}
! 				uses[kill] = NGUNSEEN;
! 			}
  		}
***************
*** 946,948 ****
  				continue;
! 			j = strlen(ngs[i]);
  			if (j + 2 > avail) {
--- 1083,1088 ----
  				continue;
! 			if (pass == 1)
! 				j = strlen(ngsbug[i] == (char *) NULL ? ngs[i] : ngsbug[i]);
! 			else
! 				j = strlen(ngs[i]);
  			if (j + 2 > avail) {
***************
*** 951,953 ****
  			}
! 			(void) strcpy(cp, ngs[i]);
  			cp += j;
--- 1091,1097 ----
  			}
! 			if (pass == 1)
! 				(void) strcpy(cp,
! 					ngsbug[i] == (char *) NULL ? ngs[i] : ngsbug[i]);
! 			else
! 				(void) strcpy(cp, ngs[i]);
  			cp += j;
***************
*** 965,967 ****
  	*/
! 	for (i = 0; i < ngcount; ++i)
  		if (ngs[i] < tbuf || ngs[i] > &tbuf[sizeof tbuf - 1])
--- 1109,1111 ----
  	*/
! 	for (i = 0; i < ngcount; ++i) {
  		if (ngs[i] < tbuf || ngs[i] > &tbuf[sizeof tbuf - 1])
***************
*** 968,970 ****
--- 1112,1124 ----
  			free(ngs[i]);
+ 		if (ngsbug[i] < tbuf || ngsbug[i] > &tbuf[sizeof tbuf - 1])
+ 			free(ngsbug[i]);
+ 	}
  	return nbuf[0] == '\0';
+ 
+ #undef NGUNSEEN 0
+ #undef NGOK 1
+ #undef NGALIAS 2
+ #undef NGBUGS 3
+ #undef NGABUGS 4
+ 
  }
***************
*** 971,972 ****
--- 1125,1168 ----
  
+ /* Check $LIB/moderators to see if user is listed as a known moderator
+  * of the newsgroup in ngname..... return TRUE if user is ok.
+  */
+ 
+ mod_file_okay(user, ngname)
+ char	*user, *ngname;
+ {
+ 	FILE *mfd;
+ 	char *grplist = NULL;
+ 	char *p, *getgrplist();
+ 	int ret = FALSE;
+ 	char mfn[BUFLEN], mgrp[BUFLEN], mlist[LBUFLEN];
+ 
+ 	sprintf(mfn, "%s/%s", LIB, "moderators");
+ 	mfd = fopen(mfn, "r");
+ 	if (mfd != NULL) 
+ 	   while ((!ret) && fscanf(mfd, "%[^:]:%s\n", mgrp, mlist) != EOF) {
+ 		if (feof(mfd)) break;
+ 		if (mgrp[0] == '#') continue;
+ 		if (!STRCMP(ngname, mgrp)) {
+ 			while (*(p = ((p = rindex(mlist, ',')) ? p : mlist ))
+ 			      && (ret == FALSE)) {
+ 				if (*p == ',') {
+ 					*p = '\0';
+ 					p++;
+ 				}
+ 				if (*p == '\\') {
+ 					*p = '\0';
+ 					p++;
+ 					if (!grplist)
+ 						grplist = getgrplist(user);
+ 					if (ngmatch(p,grplist)) ret = TRUE;
+ 				} else if (!STRCMP(p, user))
+ 					ret = TRUE;
+ 				*p = '\0';
+ 			}
+ 		}
+ 	}
+ 	fclose(mfd);
+ 	return ret;
+ }
+ 
  /*
***************
*** 1427,1429 ****
  		i = DEADTIME;
! 		while (link(SUBFILE, LOCKFILE)) {
  			if (errno != EEXIST)
--- 1623,1625 ----
  		i = DEADTIME;
! 		while (link(SEQFILE, LOCKFILE)) {
  			if (errno != EEXIST)
***************
*** 1444,1445 ****
--- 1640,1645 ----
  #endif /* !VMS */
+ 
+ #ifdef NFSCLIENT
+ #define PROC 0004
+ #endif /* NFSCLIENT */
  

Index: inews.c
Prereq: 2.83
*** .d/inews.c	Wed Nov  4 14:57:35 1987
--- inews.c	Thu Nov 19 16:54:20 1987
***************
*** 19,21 ****
  #ifdef SCCSID
! static char	*SccsId = "@(#)inews.c	2.83	11/4/87";
  #endif /* SCCSID */
--- 19,21 ----
  #ifdef SCCSID
! static char	*SccsId = "@(#)inews.c	2.84	11/19/87";
  #endif /* SCCSID */
***************
*** 80,82 ****
  'c',	' ',		FALSE,	UNKNOWN,UNKNOWN,	header.ctlmsg,
! 'C',	' ',		FALSE,	UNKNOWN,CREATENG,	header.ctlmsg,
  #define hflag	options[9].flag
--- 80,83 ----
  'c',	' ',		FALSE,	UNKNOWN,UNKNOWN,	header.ctlmsg,
! #define COPT 'C'
! COPT,	' ',		FALSE,	UNKNOWN,CREATENG,	header.ctlmsg,
  #define hflag	options[9].flag
***************
*** 139,140 ****
--- 140,142 ----
  	actfp = xfopen(ACTIVE, "r+");
+ #ifndef NFSCLIENT
  #ifdef	LOCKF
***************
*** 192,193 ****
--- 194,196 ----
  	}
+ #endif /* !NFSCLIENT */
  
***************
*** 194,195 ****
--- 197,199 ----
  	if (!STRNCMP(ptr+1, "rnews", 5)) {
+ #ifndef NFSCLIENT
  		mode = PROC;
***************
*** 199,200 ****
--- 203,212 ----
  		}
+ #else /* NFSCLIENT */
+ 		mfd = mailhdr((struct hbuf *)NULL, "Improper use of INEWS");
+ 		if (mfd != NULL) {
+ 		    fprintf(mfd,"System: %s\n\nINEWS is running improperly as RNEWS on slave NFS site by user %s.\n", LOCALSYSNAME, username);
+ 		    (void) mclose(mfd);
+ 		    exit(1);
+ 		}
+ #endif /* NFSCLIENT */
  #ifdef NICENESS
***************
*** 240,242 ****
--- 252,258 ----
  	(void) ftime(&Now);
+ #ifndef NFSCLIENT
  	if (uid == 0 && duid == 0) {
+ #else /* NFSCLIENT */
+         if (duid == 0) {
+ #endif /* NFSCLIENT */
  		/*
***************
*** 245,246 ****
--- 261,269 ----
  		 * when root invokes a setuid program.
+ 		 *
+ 		 * On NFS slave systems, inews is setuid to ROOT.  This allows
+ 		 * inews to setuid/gid (real and effective) to NEWSUSR and
+ 		 * NEWSGRP respectively.  This *must* happen so that the "rsh"
+ 		 * program will run as user NEWSUSR and not as the user running
+ 		 * inews. "rsh" runs as the "real" user even when the program
+ 		 * calling it is setuid.
  		 */
***************
*** 302,303 ****
--- 325,332 ----
  		    found:;
+ #ifdef NFSCLIENT
+ 			if (optpt->optlet == COPT) {
+ 			    fprintf(stderr, "Cannot create new newsgroups from an NFS slave system.\n\n");
+ 			    xxit(1);
+ 			}
+ #endif /* NFSCLIENT */
  			if (optpt->flag == TRUE || (mode != UNKNOWN &&
***************
*** 353,354 ****
--- 382,384 ----
  
+ #ifndef NFSCLIENT
  	if (mode == CREATENG)
***************
*** 355,356 ****
--- 385,387 ----
  		createng();
+ #endif /* !NFSCLIENT */
  
***************
*** 457,458 ****
--- 488,497 ----
  	if (mode == PROC) {
+ #ifdef NFSCLIENT
+ 		mfd = mailhdr((struct hbuf *)NULL, "Improper use of INEWS");
+ 		if (mfd != NULL) {
+ 		    fprintf(mfd,"System: %s\n\nINEWS is running improperly as RNEWS on slave NFS site by user %s.\n", LOCALSYSNAME, username);
+ 		    (void) mclose(mfd);
+ 		    exit(1);
+ 		}
+ #else /* !NFSCLIENT */
  		checkbatch();
***************
*** 472,473 ****
--- 511,513 ----
  		xxit(0);
+ #endif /* !NFSCLIENT */
  	}
***************
*** 497,499 ****
--- 537,541 ----
  #endif /* FASCIST */
+ #ifndef NFSCLIENT
  		ctlcheck();
+ #endif /* !NFSCLIENT */
  	}
***************
*** 500,501 ****
--- 542,544 ----
  
+ #ifndef NFSCLIENT
  	if (mode == CREATENG)
***************
*** 502,503 ****
--- 545,547 ----
  		createng();
+ #endif /* !NFSCLIENT */
  
***************
*** 532,533 ****
--- 576,578 ----
  		LOCALSYSNAME, f);
+ #ifndef NFSCLIENT
  	(void) sprintf(cbuf, "touch %s;chmod 666 %s", f, f);
***************
*** 538,539 ****
--- 583,587 ----
  		fprintf(mfd, "Corrective action failed - check suid bits.\n");
+ #else /* NFSCLIENT */
+ 	fprintf(mfd, "Corrective action must take place on \"%s\", the master NFS news system.\n", NFSSYSNAME);
+ #endif /* NFSCLIENT */
  	(void) mclose(mfd);
***************
*** 559,560 ****
--- 607,609 ----
  		LOCALSYSNAME, dir);
+ #ifndef NFSCLIENT
  	(void) mkdir(dir, 0775);
***************
*** 564,565 ****
--- 613,617 ----
  		fprintf(mfd, "Corrective action failed - check suid bits.\n");
+ #else /* NFSCLIENT */
+ 	fprintf(mfd, "Corrective action must take place on \"%s\", the master NFS news system.\n", NFSSYSNAME);
+ #endif /* NFSCLIENT */
  	(void) mclose(mfd);
***************
*** 611,612 ****
--- 663,665 ----
  
+ #ifndef NFSCLIENT
  dospool(batchcmd, dolhwrite)
***************
*** 836,837 ****
--- 889,891 ----
  }
+ #endif /* !NFSCLIENT */
  
***************
*** 855,858 ****
  	/* Clean up Newsgroups: line */
! 	if (!is_ctl && mode != CREATENG)
! 		is_invalid = ngfcheck(mode == PROC);
  
--- 909,917 ----
  	/* Clean up Newsgroups: line */
! 	if (!is_ctl && mode != CREATENG) {
! #ifdef MODFILEONLY
! 	    if (mode <= UNPROC) header.approved[0] = '\0';
! #endif /* MODFILEONLY */
! 	    is_invalid =
! 		ngfcheck(username, mode == PROC, header.approved[0] != '\0');
! 	}
  
***************
*** 876,877 ****
--- 935,937 ----
  
+ #ifndef NFSCLIENT
  	if (is_invalid) {
***************
*** 901,902 ****
--- 961,963 ----
  	}
+ #endif /* !NFSCLIENT */
  
***************
*** 903,950 ****
  	if (is_mod[0] != '\0' 	/* one of the groups is moderated */
! 		&& header.approved[0] == '\0') { /* and unapproved */
! 		struct hbuf mhdr;
! 		FILE *mfd, *mhopen();
! 		register char *p;
! 		char modadd[BUFLEN], *replyname();
  #ifdef DONTFOWARD
! 		if(mode == PROC) {
! 			logerr("Unapproved article in moderated group %s",
! 				is_mod);
! 			if (localize("junk"))
! 				savehist(histline);
! 			goto writeout;
! 		}
  #endif /* DONTFORWARD */
! 		fprintf(stderr,"%s is moderated and may not be posted to",
! 			is_mod);
! 		fprintf(stderr," directly.\nYour article is being mailed to");
! 		fprintf(stderr," the moderator who will post it for you.\n");
! 		/* Let's find a path to the backbone */
! 		sprintf(bfr, "%s/mailpaths", LIB);
! 		mfd = xfopen(bfr, "r");
! 		do {
! 			if (fscanf(mfd, "%s %s", bfr, modadd) != 2)
! 				xerror("Can't find backbone in %s/mailpaths",
! 					LIB);
! 		} while (STRCMP(bfr, "backbone") != 0 && !ngmatch(is_mod, bfr));
! 		(void) fclose(mfd);
! 		/* fake a header for mailhdr */
! 		mhdr.from[0] = '\0';
! 		mhdr.replyto[0] = '\0';
! 		p = is_mod;
! 		while (*++p)
! 			if (*p == '.')
! 				*p = '-';
! 		sprintf(mhdr.path, modadd, is_mod);
! 		mfd = mhopen(&mhdr);
! 		if (mfd == NULL)
! 			xerror("Can't send mail to %s", mhdr.path);
! 		fprintf(mfd, "To: %s\n", replyname(&mhdr));
! 		lhwrite(&header, mfd);
! 		putc('\n', mfd);
! 		while ((c = getc(infp)) != EOF)
! 			putc(c, mfd);
! 		mclose(mfd);
! 		log("Article mailed to %s", mhdr.path);
! 		xxit(0);
  	}
--- 964,1020 ----
  	if (is_mod[0] != '\0' 	/* one of the groups is moderated */
! 	    && header.approved[0] == '\0') { /* and unapproved */
! 		if (is_mod_file_okay) {
! 			(void) sprintf(header.approved, "%s@%s",
! 					username, FROMSYSNAME);
! 		} else {
! 			struct hbuf mhdr;
! 			FILE *mfd, *mhopen();
! 			register char *p;
! 			char modadd[BUFLEN], *replyname();
! #ifndef NFSCLIENT
  #ifdef DONTFOWARD
! 			if(mode == PROC) {
! 				logerr("Unapproved article in moderated group %s",
! 					is_mod);
! 				if (localize("junk"))
! 					savehist(histline);
! 				goto writeout;
! 			}
  #endif /* DONTFORWARD */
! #endif /* !NFSCLIENT */
! 			fprintf(stderr,"%s is moderated and may not ", is_mod);
! 			fprintf(stderr,"be posted to directly.\nYour ");
! 			fprintf(stderr, "article is being mailed to the ");
! 			fprintf(stderr, "moderator who will post it for ");
! 			fprintf(stderr, "you.\n");
! 			/* Let's find a path to the backbone */
! 			sprintf(bfr, "%s/mailpaths", LIB);
! 			mfd = xfopen(bfr, "r");
! 			do {
! 				if (fscanf(mfd, "%s %s", bfr, modadd) != 2)
! 					xerror("Can't find backbone in %s/mailpaths",
! 						LIB);
! 			} while (STRCMP(bfr, "backbone") != 0
! 			     && !ngmatch(is_mod, bfr));
! 			(void) fclose(mfd);
! 			/* fake a header for mailhdr */
! 			mhdr.from[0] = '\0';
! 			mhdr.replyto[0] = '\0';
! 			p = is_mod;
! 			while (*++p)
! 				if (*p == '.')
! 					*p = '-';
! 			sprintf(mhdr.path, modadd, is_mod);
! 			mfd = mhopen(&mhdr);
! 			if (mfd == NULL)
! 				xerror("Can't send mail to %s", mhdr.path);
! 			fprintf(mfd, "To: %s\n", replyname(&mhdr));
! 			lhwrite(&header, mfd);
! 			putc('\n', mfd);
! 			while ((c = getc(infp)) != EOF)
! 				putc(c, mfd);
! 			mclose(mfd);
! 			log("Article mailed to %s", mhdr.path);
! 			xxit(0);
! 		}
  	}
***************
*** 951,952 ****
--- 1021,1023 ----
  
+ #ifndef NFSCLIENT
  	if (mode != PROC && spool_news != DONT_SPOOL)  {
***************
*** 962,963 ****
--- 1033,1035 ----
  	}
+ #endif /* !NFSCLIENT */
  
***************
*** 965,966 ****
--- 1037,1039 ----
  		exitcode = control(&header);
+ #ifndef NFSCLIENT
  		if (localize("control") && exitcode != 0)
***************
*** 993,994 ****
--- 1066,1068 ----
  		}
+ #endif /* !NFSCLIENT */
  	}
***************
*** 1039,1040 ****
--- 1113,1115 ----
  		if (mode != PROC) {
+ #ifndef NFSCLIENT
  			int pid;
***************
*** 1057,1058 ****
--- 1132,1143 ----
  		broadcast(mode==PROC);
+ #else /* NFSCLIENT */
+ 			int status;
+ 			char command[LBUFLEN];
+ 
+ 			(void) sprintf(command, NFSCMDFORMAT, NFSCMDARGS);
+ 			status = system(command);
+ 			(void) unlink(ARTICLE);
+ 			exit(status);
+ 		}
+ #endif /* NFSCLIENT */
  	}
***************
*** 1080,1081 ****
--- 1165,1167 ----
  			break;
+ #ifndef NFSCLIENT
   		if (mode == PROC) {	/* zap trailing empty lines */
***************
*** 1118,1119 ****
--- 1204,1206 ----
   		}
+ #endif /* !NFSCLIENT */
  		if (mode != PROC && tty && STRCMP(bfr, ".\n") == 0)
***************
*** 1216,1217 ****
--- 1303,1306 ----
  
+ #ifndef NFSCLIENT
+ 
  /*
***************
*** 1404 ****
--- 1493,1494 ----
  }
+ #endif /* !NFSCLIENT */

Index: install.sh
Prereq: 1.18
*** .d/install.sh	Wed Oct  7 16:53:04 1987
--- install.sh	Thu Nov 19 16:54:21 1987
***************
*** 1,6 ****
! : '@(#)install.sh	1.18	9/24/87'
  
! if test "$#" != 6
  then
! 	echo "usage: $0 spooldir libdir bindir nuser ngroup ostype"
  	exit 1
--- 1,6 ----
! : '@(#)install.sh	1.19	11/19/87'
  
! if test "$#" -lt 6
  then
! echo "usage: $0 spooldir libdir bindir nuser ngroup ostype [nfs_spooldir nfs_libdir]"
  	exit 1
***************
*** 13,14 ****
--- 13,16 ----
  OSTYPE=$6
+ NFSSPOOLDIR=$7
+ NFSLIBDIR=$8
  
***************
*** 31,33 ****
  	v7)	SYSNAME=`uuname -l`
! 		touch $LIBDIR/history.pag $LIBDIR/history.dir;;
  	*)	echo "$0: Unknown Ostype"
--- 33,42 ----
  	v7)	SYSNAME=`uuname -l`
! 		if test "$NFSSPOOLDIR" = ""
! 		then
! 			touch $LIBDIR/history.pag $LIBDIR/history.dir
! 		else
! 			rm -f $LIBDIR/history.dir $LIBDIR/history.pag
! 			ln -s $NFSLIBDIR/history.dir $LIBDIR/history.dir
! 			ln -s $NFSLIBDIR/history.pag $LIBDIR/history.pag
! 		fi;;
  	*)	echo "$0: Unknown Ostype"
***************
*** 43,54 ****
  : Ensure SPOOLDIR exists
! for i in $SPOOLDIR $SPOOLDIR/.rnews
! do
! 	if test ! -d $i
! 	then
! 		mkdir $i
! 	fi
! 	chmod 777 $i
! 	chown $NEWSUSR $i
! 	chgrp $NEWSGRP $i
! done
  
--- 52,72 ----
  : Ensure SPOOLDIR exists
! if test "$NFSSPOOLDIR" = ""
! then
! 	for i in $SPOOLDIR $SPOOLDIR/.rnews
! 	do
! 		if test ! -d $i
! 		then
! 			mkdir $i
! 		fi
! 		chmod 777 $i
! 		chown $NEWSUSR $i
! 		chgrp $NEWSGRP $i
! 	done
! else
! 	rm -rf $SPOOLDIR
! 	ln -s $NFSSPOOLDIR $SPOOLDIR
! 	chmod 777 $SPOOLDIR
! 	chown $NEWSUSR $SPOOLDIR
! 	chgrp $NEWSGRP $SPOOLDIR
! fi
  
***************
*** 58,60 ****
  : Ensure certain files in LIBDIR exist
! touch $LIBDIR/history $LIBDIR/active $LIBDIR/log $LIBDIR/errlog $LIBDIR/users
  chmod 666 $LIBDIR/users
--- 76,86 ----
  : Ensure certain files in LIBDIR exist
! if test "$NFSLIBDIR" = ""
! then
! 	touch $LIBDIR/history $LIBDIR/active
! else
! 	rm -f $LIBDIR/history $LIBDIR/active
! 	ln -s $NFSLIBDIR/history $LIBDIR/history
! 	ln -s $NFSLIBDIR/active $LIBDIR/active
! fi
! touch  $LIBDIR/log $LIBDIR/errlog $LIBDIR/users
  chmod 666 $LIBDIR/users
***************
*** 62,63 ****
--- 88,91 ----
  : If no sys file, make one.
+ if test "$NFSLIBDIR" = ""
+ then
  if test ! -f $LIBDIR/sys
***************
*** 74,75 ****
--- 102,107 ----
  fi
+ else
+ 	rm -f $LIBDIR/sys
+ 	ln -s $NFSLIBDIR/sys $LIBDIR/sys
+ fi
  
***************
*** 82,83 ****
--- 114,117 ----
  : If no mailpaths, make one.
+ if test "$NFSLIBDIR" = ""
+ then
  if test ! -s $LIBDIR/mailpaths
***************
*** 91,95 ****
  fi
  
! sh makeactive.sh $LIBDIR $SPOOLDIR $NEWSUSR $NEWSGRP
  
  for i in $LIBDIR/ngfile $BINDIR/inews $LIBDIR/localgroups $LIBDIR/moderators \
--- 125,141 ----
  fi
+ else
+ 	rm -f $LIBDIR/mailpaths
+ 	ln -s $NFSLIBDIR/mailpaths $LIBDIR/mailpaths
+ fi
  
! if test "$NFSLIBDIR" = ""
! then
! 	sh makeactive.sh $LIBDIR $SPOOLDIR $NEWSUSR $NEWSGRP
! else
! 	rm -f $LIBDIR/newsgroups
! 	ln -s $NFSLIBDIR/newsgroups $LIBDIR/newsgroups
! fi
  
+ if test "$NFSLIBDIR" = ""
+ then
  for i in $LIBDIR/ngfile $BINDIR/inews $LIBDIR/localgroups $LIBDIR/moderators \
***************
*** 117,118 ****
--- 163,165 ----
  fi
+ fi
  
***************
*** 129,130 ****
--- 176,183 ----
  : if no aliases file, make one
+ if test "$NFSLIBDIR" != ""
+ then
+ 	rm -f $LIBDIR/aliases
+ 	ln -s $NFSLIBDIR/aliases $LIBDIR/aliases
+ 	rm -f $LIBDIR/aliases.new
+ else
  if test ! -f $LIBDIR/aliases
***************
*** 151,152 ****
--- 204,206 ----
  fi
+ fi
  
***************
*** 153,154 ****
--- 207,210 ----
  : if no distributions file, make one
+ if test "$NFSLIBDIR" = ""
+ then
  if test ! -f $LIBDIR/distributions
***************
*** 165,166 ****
--- 221,226 ----
  echo site particpates in a regional distribution such as '"ba"' or '"dc"'.
+ fi
+ else
+ 	rm -f $LIBDIR/distributions
+ 	ln -s $NFSLIBDIR/distributions $LIBDIR/distributions
  fi

Index: iparams.h
Prereq: 2.17
*** .d/iparams.h	Fri Nov 21 16:04:36 1986
--- iparams.h	Thu Nov 19 16:54:21 1987
***************
*** 4,6 ****
  
! /*	@(#)iparams.h	2.17	11/21/86	*/
  
--- 4,6 ----
  
! /*	@(#)iparams.h	2.18	11/19/87	*/
  
***************
*** 20,21 ****
--- 20,25 ----
  
+ #ifdef NFSCLIENT
+ extern	char	*NFSSYSNAME;
+ #endif /* NFSCLIENT */
+ 
  struct msgtype {
***************
*** 29,31 ****
  extern	FILE	*infp, *actfp;
! extern	int	tty, is_ctl;
  extern	char	filename[BUFLEN], is_mod[NAMELEN], not_here[SBUFLEN], *DFLTNG;
--- 33,35 ----
  extern	FILE	*infp, *actfp;
! extern	int	tty, is_ctl, is_mod_file_okay;
  extern	char	filename[BUFLEN], is_mod[NAMELEN], not_here[SBUFLEN], *DFLTNG;

Index: localize.client
*** /dev/null	Thu Nov 19 16:28:13 1987
--- localize.client	Thu Nov 19 16:54:22 1987
***************
*** 0 ****
--- 1,168 ----
+ # -- DISCUSSION --
+ # 
+ # With this latest release of the Netnews software, it may appear to some that
+ # the new NNTP support code and the new NFS support code do more or less the
+ # same thing.  You're probably asking yourself, "What are the differences if
+ # any and what do I go by to help me choose which way to go?"  Well, first let
+ # me say that neither method is better than the other.  I can clearly see a
+ # use for both models right here at Rutgers University.  And, that's what we
+ # really have here - two different models - two different means of supporting
+ # a distributed network news system.  The difference between the two is
+ # mostly one of administration.
+ # 
+ # The NNTP extensions to the Netnews code allow your users to take advantage
+ # of something that only rn users were able to take advantage of up until now.
+ # Now, your users may use their favorite user interface program to access the
+ # news from a distant host.  Administratively, the NNTP model implies that
+ # complete control of the news system is done solely on the master NNTP
+ # server.  If you do not need the ability to have some level of control at the
+ # client system level, use of the NNTP extensions is definitely the way to go.
+ # 
+ # The NFS extensions allows for local administration of the news system at the
+ # client level.  Right after installation, most of the administrative files in
+ # LIBDIR will simply be soft links to the same files on the NFS master.
+ # However, you can break these links and create actual files on the client.
+ # Certainly, some files must remain as links.  Files such as "active" or
+ # "newsgroups" should always remain as links to the master NFS system for
+ # instance.  The ability to break links may, for example, allow you to choose
+ # a different set of users to apply the fascist code to or name a moderator of
+ # a moderated newsgroup but only allow him to post from his client (and not
+ # from the NFS master news server), etc...  Essentially, the NFS client
+ # version of inews is a stripped down version of the real thing.  The only
+ # thing it doesn't do is attempt to write to NFSSPOOLDIR and NFSLIBDIR.  All
+ # consistency checks performed by the real inews in the normal case are
+ # performed by the NFS client version on the local system.  So, if you're
+ # environment is such that you need local administrative control on the client
+ # systems, the use of the NFS extensions is your best bet.
+ # 
+ # 
+ # -- INSTALLATION --
+ # 
+ # The file "localize.client" is a slightly modified copy of the shell script
+ # used at Rutgers University to establish a particular system as a news NFS
+ # client system.  One should be familiar with NFS before attempting to use
+ # this new feature.  News should be installed on the master NFS server before
+ # attempting to install it on client system(s).
+ # 
+ # The NFSCLIENT code is enabled by including the NFSCLIENT (non-optional),
+ # NFSSPOOLDIR (optional) and NFSLIBDIR (optional) definitions in your Makefile
+ # edit script. NFSSPOOLDIR and NFSLIBDIR are needed only during the initial
+ # installation of the code and are, in fact, only used by the Makefile when
+ # calling the install.sh script.  NFSSPOOLDIR and NFSLIBDIR default to
+ # /nfsnews/$(SPOOLDIR) and /nfsnews/$(LIBDIR) where "nfsnews" is expected to
+ # be a mount point or soft link on the local system which ultimately points at
+ # the master system.
+ # 
+ # With the NFSCLIENT code enabled the Makefile and installation scripts will
+ # do the following:
+ # 
+ # 	o - On an NFS client system, only a small number of the programs in
+ # 	this source directory need to be compiled.  Makefile will be
+ # 	configured to compile only those modules.
+ # 
+ # 	o - The installation script will attempt to install only those
+ # 	modules compiled.  It will also attempt to establish a soft link
+ # 	from SPOOLDIR to NFSSPOOLDIR.  It will create a local LIBDIR,
+ # 	install a very select group of programs in it and attempt to create
+ # 	soft links from the local LIBDIR configuration files to those found
+ # 	in NFSLIBDIR.  Obviously, news should be installed on the master NFS
+ # 	server first.
+ # 
+ # *NOTE* - You will need to create a file called LIBDIR/nfssysname.  In it,
+ # place the fully qualified host name of the system which is to act as the NFS
+ # news server.  You do this right after installing the software.
+ # 
+ # 
+ # -- CAVEATS --
+ # 
+ # 	Under the default configuration, an NFS client will attempt to use
+ # 	"rsh" to send news from the client to the server.  To make this
+ # 	work, inews on the client will set itself to run both real and
+ # 	effectively as the "news" user.  Unfortunately, rsh requires that
+ # 	the real uid match between the two systems.  The hidden implication
+ # 	here is that the .rhosts file in the news home directory on the
+ # 	master NFS system will have to be modified to allow all clients to
+ # 	rsh to it.
+ # 
+ # 	If you look below, you'll see that edits have been made to
+ # 	NFSCMDFORMAT and NFSCMDARGS which are located in defs.dist.  In
+ # 	effect, you may change the program that inews attempts to use to
+ # 	deliver articles to the NFS server.  In this example, I'm using a
+ # 	modified nntpxmit which will accept a host name and a file name as
+ # 	its arguments.  For those of you who are aware of how nntpxmit
+ # 	works, the new -a switch says that the file contains the actual
+ # 	article as opposed to a list of filenames containing articles.  This
+ # 	feature will be supported in nntpxmit 1.4.  With the new nntpxmit,
+ # 	the .rhosts hacking mentioned above will not be needed.
+ # 
+ # -- BUGS --
+ # 
+ # 	I don't know of any.  This code has been running at Rutgers since
+ # 	version 2.10.3 of news.
+ # 
+ # 	I have not attempted to run this code together with Stan Barber's
+ # 	nntp support code.  Offhand, I'm guessing that you'll be in for some
+ # 	nasty surprises if you attempt to do so.
+ # 
+ # -- WHERE TO FIND HELP --
+ # 
+ # 	This script and a real working knowledge of NFS is all one really
+ # 	needs.  However, I'm am willing to answer most any question
+ # 	regarding the NFS support code.  My address and telephone number are
+ # 	given below....
+ #
+ #  Mel Pleasant
+ #  (201) 932-2023  --  uucp: {most-any-backbone-site}!rutgers!pleasant
+ #		   internet: pleasant@RUTGERS.EDU
+ #
+ rm -f Makefile
+ cp Makefile.dst Makefile
+ chmod u+w Makefile
+ ed - Makefile  <<'EOF'
+ /HOME=/s/exptools//
+ /NEWSGRP/s/news/daemon/
+ /BATCHDIR/s;batch;newsbatch/batch;
+ /BINDIR/s;bin;local/bin;
+ /UUXFLAGS/s/-r -z/-r -z -n -gd/
+ /LNRNEWS/s/ln/ln -s/
+ g/^#NFSCLIENT /s///
+ g/^#V7 /s///
+ g/^#USG /d
+ g/^#BSD4_3 /d
+ g/^#BSD4_2 /s///
+ g/^#BSD4_1 /d
+ g/#NOTVMS/s/#NOTVMS.*//
+ w
+ q
+ EOF
+ rm -f defs.h
+ cp defs.dist defs.h
+ chmod u+w defs.h
+ ed - defs.h <<'EOF'
+ /ROOTID/s/10/100/
+ /N_UMASK/s/000/022/
+ /DFLTSUB/s/general,all.announce/all,all.all/
+ /ADMSUB/s/general,all.announce/announce,all.announce,general,all.general/
+ /DFTXMIT/s/-z/-z -gd/
+ s;uux;/usr/bin/uux;
+ /UXMIT/s/-z/-z -gd/
+ s;uux;/usr/bin/uux;
+ /DFTEDITOR/s;vi;/bin/emacs;
+ /INTERNET/s;/\* ;;
+ /MYDOMAIN/s/\.UUCP//
+ /GHNAME/s;/\* ;;
+ /DOXREFS/s;/\* ;;
+ /BSD4_2/s;/\* ;;
+ /ALWAYSALIAS/s;/\* ;;
+ /SENDMAIL/s;/\* ;;
+ /MYORG/s/Frobozz Inc., St. Louis/Rutgers Univ., New Brunswick, N.J./
+ /FASCIST/s;/\* ;;
+ s/all\.all/systems.dev/
+ /ORGDISTRIB/s;/\* ;;
+ s/froozum/ru/
+ /MODFILEONLY/s;/\* ;;
+ /NFSCMDFORMAT/s;".*";"/usr/lib/news/nntpxmit -a \\"%s\\" \\"%s\\"";
+ /NFSCMDARGS/s/NFSSYSNAME,ARTICLE/ARTICLE,NFSSYSNAME/
+ w
+ q
+ EOF

Index: params.h
Prereq: 2.26
*** .d/params.h	Wed Nov  4 14:57:43 1987
--- params.h	Thu Nov 19 16:54:23 1987
***************
*** 4,6 ****
  
! /*	@(#)params.h	2.26	11/4/87	*/
  
--- 4,6 ----
  
! /*	@(#)params.h	2.27	11/19/87	*/
  
***************
*** 67,69 ****
  extern	char	*SPOOL, *LIB, *BIN, *SUBFILE, *ACTIVE;
! extern	char	*LOCKFILE, *SEQFILE, *ARTFILE;
  extern	char	*news_version, *Progname;
--- 67,69 ----
  extern	char	*SPOOL, *LIB, *BIN, *SUBFILE, *ACTIVE;
! extern	char	*LOCKFILE, *SEQFILE, *ARTFILE, *BUGFILE;
  extern	char	*news_version, *Progname;

Index: pathinit.c
Prereq: 1.24
*** .d/pathinit.c	Thu Oct  8 00:22:31 1987
--- pathinit.c	Thu Nov 19 16:54:24 1987
***************
*** 36,38 ****
  #ifdef SCCSID
! static char	*SccsId = "@(#)pathinit.c	1.24	10/7/87";
  #endif /* SCCSID */
--- 36,38 ----
  #ifdef SCCSID
! static char	*SccsId = "@(#)pathinit.c	1.25	11/19/87";
  #endif /* SCCSID */
***************
*** 58,62 ****
  char *LOCKFILE, *SEQFILE, *ARTICLE, *INFILE, *TELLME;
  
! int c_cancel(), c_newgroup(), c_ihave(), c_sendme(), c_rmgroup(),
      c_sendsys(), c_version(), c_checkgroups(), c_unimp();
  
--- 58,67 ----
  char *LOCKFILE, *SEQFILE, *ARTICLE, *INFILE, *TELLME;
+ int c_cancel();
  
! #ifdef NFSCLIENT
! char *NFSSYSNAME;
! #else /* !NFSCLIENT */
! int c_newgroup(), c_ihave(), c_sendme(), c_rmgroup(),
      c_sendsys(), c_version(), c_checkgroups(), c_unimp();
+ #endif /* !NFSCLIENT */
  
***************
*** 64,65 ****
--- 69,71 ----
  	"cancel", NULL, c_cancel,
+ #ifndef NFSCLIENT
  	"newgroup", NULL, c_newgroup,
***************
*** 73,74 ****
--- 79,81 ----
  	"delsub", NULL, c_unimp,
+ #endif /* !NFSCLIENT */
  	NULL, NULL, NULL
***************
*** 78,80 ****
  #if defined(INEW) || defined(READ)
! char *ALIASES;
  #endif /* INEW || READ */
--- 85,87 ----
  #if defined(INEW) || defined(READ)
! char *ALIASES, *BUGFILE;
  #endif /* INEW || READ */
***************
*** 123,125 ****
--- 130,146 ----
  	extern char *mydomain();
+ #endif /* CHKN */
  
+ #ifdef HOME
+ 	/* Relative to the home directory of user HOME */
+ 	(void) sprintf(bfr, "%s/%s", logdir(HOME), SPOOLDIR);
+ 	SPOOL = AllocCpy(bfr);
+ 	(void) sprintf(bfr, "%s/%s", logdir(HOME), LIBDIR);
+ 	LIB = AllocCpy(bfr);
+ #else /* !HOME */
+ 	/* Fixed paths defined in Makefile */
+ 	SPOOL = AllocCpy(SPOOLDIR);
+ 	LIB = AllocCpy(LIBDIR);
+ #endif /* !HOME */
+ 
+ #ifndef CHKN
  	uname(&ubuf);
***************
*** 154,167 ****
  
- #ifdef HOME
- 	/* Relative to the home directory of user HOME */
- 	(void) sprintf(bfr, "%s/%s", logdir(HOME), SPOOLDIR);
- 	SPOOL = AllocCpy(bfr);
- 	(void) sprintf(bfr, "%s/%s", logdir(HOME), LIBDIR);
- 	LIB = AllocCpy(bfr);
- #else /* !HOME */
- 	/* Fixed paths defined in Makefile */
- 	SPOOL = AllocCpy(SPOOLDIR);
- 	LIB = AllocCpy(LIBDIR);
- #endif /* !HOME */
- 
  #ifdef LOGDIR
--- 175,176 ----
***************
*** 200,201 ****
--- 209,211 ----
  	Sprintf(ALIASES, "%s/aliases", LIB);
+ 	Sprintf(BUGFILE, "%s/buggroups", LIB);
  # endif /* READ || INEW */
***************
*** 204,205 ****
--- 214,216 ----
  	Sprintf(SEQFILE, "%s/seq", LIB);
+ #ifndef NFSCLIENT
  	Sprintf(ARTICLE, "%s/.arXXXXXX", SPOOL);
***************
*** 206,207 ****
--- 217,223 ----
  	Sprintf(INFILE, "%s/.inXXXXXX", SPOOL);
+ #else /* NFSCLIENT */
+ 	Sprintf(ARTICLE, "/tmp/.arXXXXXX", SPOOL);
+ 	Sprintf(INFILE, "/tmp/.inXXXXXX", SPOOL);
+ 	parse_nfssysname();
+ #endif /* NFSCLIENT */
  /*
***************
*** 352,353 ****
--- 368,397 ----
  #endif /* NOTIFY */
+ #ifdef NFSCLIENT
+ parse_nfssysname()
+ {
+ 	FILE *nfsfd;
+ 	extern FILE *mailhdr();
+ 	char *nfsp;
+ 	char buf[BUFSIZ];
+ 
+ 	sprintf(buf, "%s/nfssysname", LIB);
+ 
+ 	if ((nfsfd = fopen(buf, "r"))) {
+ 		(void) fgets(buf, sizeof buf, nfsfd);
+ 		(void) fclose(nfsfd);
+ 		if (nfsp = index(buf, '\n')) *nfsp = '\0';
+ 		NFSSYSNAME = AllocCpy(buf);
+ 		return;
+ 	}
+ 
+ 	if (nfsfd = mailhdr((struct hbuf *)NULL, "Missing File")) {
+ 		(void) fprintf(nfsfd, "Can't find %s.\n\n", buf);
+ 		(void) fprintf(nfsfd, "On an NFS client, inews cannot ");
+ 		(void) fprintf(nfsfd, "operate without this file.\n");
+ 		(void) mclose(nfsfd);
+ 	}
+ 
+ 	xerror("Can't find %s.\nComplain to your new/systems manager.\n", buf);
+ }	
+ #endif /* NFSCLIENT */
  #endif /* INEW */

Index: postnews.c
Prereq: 1.34
*** .d/postnews.c	Wed Nov  4 14:57:57 1987
--- postnews.c	Thu Nov 19 16:54:27 1987
***************
*** 19,21 ****
  #ifdef SCCSID
! static char	*SccsId = "@(#)postnews.c	1.34	11/4/87";
  #endif /* SCCSID */
--- 19,21 ----
  #ifdef SCCSID
! static char	*SccsId = "@(#)postnews.c	1.35	11/19/87";
  #endif /* SCCSID */
***************
*** 107,109 ****
  		getpr("In what newsgroup was the article posted? ",ng);
! 		if (!valid_ng(ng, &i, &j, &canpost))
  			if (canpost == 'i' )
--- 107,109 ----
  		getpr("In what newsgroup was the article posted? ",ng);
! 		if (!valid_ng(ng, &i, &j, &canpost, TRUE))
  			if (canpost == 'i' )
***************
*** 304,306 ****
  #endif	/* !SERVER */
! 		if (valid_ng(buf, &i, &i, &canpost)) {
  			if (n++ != 0)
--- 304,306 ----
  #endif	/* !SERVER */
! 		if (valid_ng(buf, &i, &i, &canpost, FALSE)) {
  			if (n++ != 0)
***************
*** 925,929 ****
  /* verify that newsgroup exists, and get number of entries */
! valid_ng(ng, maxart, minart, canpost)
! char *ng;
  long *maxart, *minart;
  char *canpost;
--- 925,931 ----
  /* verify that newsgroup exists, and get number of entries */
! valid_ng(ng, maxart, minart, canpost, exact)
!      char *ng;
!      
  long *maxart, *minart;
+ int exact;
  char *canpost;
***************
*** 930,933 ****
  {
! 	char ng_check[BUFLEN], ng_read[BUFLEN];
  	FILE *fp;
  
--- 932,936 ----
  {
! 	char ng_check[BUFLEN], ng_read[BUFLEN], *cp;
  	FILE *fp;
+ 	int found_ng;
  
***************
*** 964,966 ****
  	}
! 	*canpost = 'i';
  	*maxart = 0;
--- 967,969 ----
  	}
! 	(void) fclose(fp);
  	*maxart = 0;
***************
*** 967,970 ****
  	*minart = 0;
  	(void) fclose(fp);
! 	return FALSE;
  }
--- 970,992 ----
  	*minart = 0;
+ 	*canpost = 'i';
+ 	if (exact) {
+ 		return FALSE;
+ 	}
+ 	if ((fp = fopen(BUGFILE, "r")) == NULL) {
+ 		return FALSE;
+ 	}
+ 	found_ng = FALSE;
+ 	while (!found_ng && fgets(ng_check, BUFLEN, fp) == ng_check) {
+ 		if (ng_check[0] == '#')
+ 			continue;
+ 		cp = index(ng_check, '\n');
+ 		*cp = '.';
+ 		if (prefix(ng, ng_check))
+ 			found_ng = TRUE;
+ 	}
  	(void) fclose(fp);
! 	if (!found_ng)
! 		return FALSE;
! 	*canpost = 'y';
! 	return TRUE;
  }

Index: process.c
Prereq: 2.17
*** .d/process.c	Wed Dec 17 18:23:25 1986
--- process.c	Thu Nov 19 16:54:28 1987
***************
*** 18,20 ****
  #ifdef SCCSID
! static char	*SccsId = "@(#)process.c	2.17	12/16/86";
  #endif /* SCCSID */
--- 18,20 ----
  #ifdef SCCSID
! static char	*SccsId = "@(#)process.c	2.18	11/19/87";
  #endif /* SCCSID */
***************
*** 40,41 ****
--- 40,42 ----
  'h',	'\0',	FALSE,	OPTION,	ANY,		UNKNOWN,(char *)NULL,
+ 'A',	'\0',	FALSE,	OPTION, UNKNOWN,	UNKNOWN,(char *)NULL,
  #ifdef TMAIL

Index: recnews.c
Prereq: 2.15
*** .d/recnews.c	Wed Nov  4 14:58:14 1987
--- recnews.c	Thu Nov 19 16:54:30 1987
***************
*** 1,3 ****
  /*
!  * recnews [to newsgroup] [from user] [approved by]
   *
--- 1,3 ----
  /*
!  * recnews [to newsgroup] [from user] [approved by] [exclude site]
   *
***************
*** 45,46 ****
--- 45,48 ----
   *		 for use with local groups for mailing lists with 2.11.
+  * pleasant@rutgers.EDU: add fourth argument which uses the -x switch in inews
+  *
   */
***************
*** 48,50 ****
  #ifdef SCCSID
! static char	*SccsId = "@(#)recnews.c	2.15	11/4/87";
  #endif /* SCCSID */
--- 50,52 ----
  #ifdef SCCSID
! static char	*SccsId = "@(#)recnews.c	2.16	11/19/87";
  #endif /* SCCSID */
***************
*** 92,93 ****
--- 94,96 ----
  char	approved[BFSZ];		/* Approved: */
+ char	not_this_site[BFSZ];	/* Don't post to this site */
  int	fromset;		/* from passed on command line */
***************
*** 123,124 ****
--- 126,131 ----
  		approved[0] = '\0';
+ 	if (argc > 4 && *argv[4]) {
+ 		sprintf(not_this_site, " -x \"%s\"", argv[4]);
+ 	} else
+ 		not_this_site[0] = '\0';
  
***************
*** 176,178 ****
  		case INCLUSIVE:
! 			sprintf(cmdbuf,"exec %s -p", inews);
  			pipe = popen(cmdbuf,"w");
--- 183,185 ----
  		case INCLUSIVE:
! 			sprintf(cmdbuf,"exec %s%s -p", inews, not_this_site);
  			pipe = popen(cmdbuf,"w");
***************
*** 196,200 ****
  			sprintf(cmdbuf,
! 				"exec %s -t \"%s\" -n \"%s\" -f \"%s\"%s",
  				inews, *subject ? subject : "(none)",
! 				newsgroup, from, approved);
  #ifdef debug
--- 203,207 ----
  			sprintf(cmdbuf,
! 				"exec %s -t \"%s\" -n \"%s\" -f \"%s\"%s%s",
  				inews, *subject ? subject : "(none)",
! 				newsgroup, from, approved, not_this_site);
  #ifdef debug
***************
*** 224,227 ****
  			sprintf(cmdbuf,
! 				"exec \"%s\" -t \"%s\" -n \"%s\" -f \"%s\"%s",
! 				inews, subject, newsgroup, from, approved);
  #ifdef debug
--- 231,235 ----
  			sprintf(cmdbuf,
! 				"exec \"%s\" -t \"%s\" -n \"%s\" -f \"%s\"%s%s",
! 				inews, subject, newsgroup, from, approved,
! 				not_this_site);
  #ifdef debug

Index: uname.c
Prereq: 2.16
*** .d/uname.c	Wed Oct  7 16:55:03 1987
--- uname.c	Thu Nov 19 16:54:31 1987
***************
*** 23,25 ****
  #ifdef SCCSID
! static char	*SccsId = "@(#)uname.c	2.16	9/24/87";
  #endif /* SCCSID */
--- 23,25 ----
  #ifdef SCCSID
! static char	*SccsId = "@(#)uname.c	2.17	11/19/87";
  #endif /* SCCSID */
***************
*** 43,44 ****
--- 43,46 ----
  	gethostname(uptr->nodename, sizeof (uptr->nodename));
+ 	for (cp = uptr->nodename; *cp == '\0'; cp++)
+ 		if (isupper(*cp)) *cp = tolower(*cp);
  	cp = mydomain();

Index: patchlevel.h
Prereq: 12
*** .d/patchlevel.h	Wed Nov  4 14:46:19 1987
--- patchlevel.h	Thu Nov 19 17:28:23 1987
***************
*** 1,3 ****
! #define	PATCHLEVEL	12
  
! #define NEWS_VERSION   "B 2.11 11/04/87"
--- 1,3 ----
! #define	PATCHLEVEL	13
  
! #define NEWS_VERSION   "B 2.11 11/19/87"



-- 
Arnold Robbins -- The Basement Computer
UUCP:	{ gatech, emory, gt-eedsp, bakerst, gladys }!skeeve!arnold

/bin/csh: Just Say NO!