Subject: C News patch CR.F
Newsgroups: news.software.b

This is a patch for the C News Cleanup Release.  The distribution files
on ftp.cs.toronto.edu and zoo.toronto.edu have been updated to match.
See the README.changes diff below for what's been done.

start of patch CR.F
(suggested archive name:  patchCR.F)
apply with   patch -p0 <thisfile

Prereq: CR.E
*** README.mastercopy	Thu Apr 27 20:48:59 1995
--- README	Tue Mar 21 15:42:37 1995
***************
*** 1,4 ****
! Cleanup Release of C News, with patch CR.E			Jan 1995
  
  The current C News distribution can be retrieved by anonymous FTP from
  ftp.cs.toronto.edu (file pub/c-news/c-news.tar.Z) or ftp.zoo.toronto.edu
--- 1,4 ----
! Cleanup Release of C News, with patch CR.F			March 1995
  
  The current C News distribution can be retrieved by anonymous FTP from
  ftp.cs.toronto.edu (file pub/c-news/c-news.tar.Z) or ftp.zoo.toronto.edu

*** README.changes.mastercopy	Thu Apr 27 20:49:00 1995
--- README.changes	Thu Apr 27 20:41:37 1995
***************
*** 1,3 ****
--- 1,22 ----
+ High points of patch CR.F:
+ CR.G will follow immediately, but the two should be reasonably independent.
+ Another bunch of minor odds and ends.  Small extension to the batchparms
+ syntax to provide a way of temporarily switching off batching to a site.
+ Regression testing is now done with LANG=C in the environment, to suppress
+ internationalization goo.  The old small-address-space version of sys-file
+ handling is gone -- it has portability problems and performance problems,
+ and is not a big space win.  Newsgroup addition is now smarter about the
+ case where you delete and then recreate a newsgroup.  Relaynews now
+ automatically notifies doexpire about use of symlinks, so the magic -l flag
+ doesn't have to be hacked in by hand.  A bug in the copy-if-I-can't-link
+ code in relaynews (it relied on breaking stdio's rules slightly) is fixed.
+ Checkactive now checks for absence of the "control" and "junk" pseudo-groups,
+ since said absence causes various weird problems.  Postnews does its check
+ for "did the user actually write something?" less obtrusively.  The default
+ out.going directory in spacefor is now /var/spool/uucp instead of /usr/...
+ Mkhistory and addmissing cope right with symlinks directly under NEWSARTS.
+ And the usual assortment of small bug fixes and portability improvements.
+ 
  High points of patch CR.E:
  This one is mostly fairly minor things.  The big changes are further work
  on upact, to remove a race condition that would sometimes update the min

*** README.etc.mastercopy	Thu Apr 27 20:49:00 1995
--- README.etc	Wed Mar  8 09:34:43 1995
***************
*** 24,30 ****
  aka	[email-masked]
  aka	utzoo!c-news
  
! (Note that this has changed, c-news used to be on utstat.)

  					Geoff Collyer
--- 24,35 ----
  aka	[email-masked]
  aka	utzoo!c-news
  
! (Note that this has changed, c-news used to be on utstat.)  If you want
! a response, make sure you give us a valid email address to respond to!
! You'd think this wouldn't need comment, but maybe once a week we get
! mail from an address which looks normal... but our reply gets bounced
! back as undeliverable.  Sorry, but we get too much mail to make heroic
! efforts to solve each such problem.

  					Geoff Collyer

*** quiz.mastercopy	Thu Apr 27 20:49:01 1995
--- quiz	Wed Apr 26 22:54:49 1995
***************
*** 223,229 ****
  no)	echo 'Presumably you want to use the dbm library or some local'
  	echo 'equivalent, then.  You will need to include appropriate'
  	echo 'filenames or compiler options when asked about libraries'
! 	echo 'a bit later.'
  	newfake="$newfake dbz.o"	# make dbm look like dbz
  	has=`$notinlist "$fake" dbmclose.o`
  	tmp=`$yesno 'Does your dbm/dbz have a dbmclose() function' $has`
--- 223,231 ----
  no)	echo 'Presumably you want to use the dbm library or some local'
  	echo 'equivalent, then.  You will need to include appropriate'
  	echo 'filenames or compiler options when asked about libraries'
! 	echo 'a bit later.  Be warned that support for non-dbz indexes'
! 	echo 'is increasingly poor, and you may have to work around'
! 	echo 'dbz-specific assumptions in the installation procedure.'
  	newfake="$newfake dbz.o"	# make dbm look like dbz
  	has=`$notinlist "$fake" dbmclose.o`
  	tmp=`$yesno 'Does your dbm/dbz have a dbmclose() function' $has`

*** makefile.mastercopy	Thu Apr 27 20:49:01 1995
--- makefile	Sat Feb 11 01:39:49 1995
***************
*** 81,86 ****
--- 81,88 ----
  mx:	conf/mx.done
  
  conf/mx.done:	msub include/config.make
+ 	: A mysterious fatal error here probably means you gave quiz the
+ 	: wrong answer when it asked you how to do an include in a makefile.
  	cd conf ; make mx
  	touch $@

*** batch/sendbatches.mastercopy	Thu Apr 27 20:49:02 1995
--- batch/sendbatches	Tue Mar 21 16:53:48 1995
***************
*** 112,117 ****
--- 112,121 ----
  	if test " $bpokay" = " x"
  	then
  		continue	# wrong class
+ 	elif test " $bpokay" = " !"
+ 	then
+ 		echo "$sys	backlog ? (disabled in $parms)" >>$log
+ 		continue
  	elif test " $bpokay" != " y"
  	then
  		(

*** batch/makefile.mastercopy	Thu Apr 27 20:49:02 1995
--- batch/makefile	Tue Mar 21 17:00:10 1995
***************
*** 202,207 ****
--- 202,211 ----
  	echo `pwd`/test.2 4000 >>arts/out.going/bar/togo
  	echo `pwd`/test.3 4000 >>arts/out.going/bar/togo
  	echo `pwd`/test.3 4000 >test.left
+ 	echo 'foo u! 500 10 batcher | munch | xmit' >test.bp
+ 	$(HERE) ./sendbatches -f `pwd`/test.bp
+ 	test ! -s output ;
+ 	test ! -s output2 ;
  	$(HERE) ./sendbatches
  	cmp output test.out1
  	cmp output2 test.out2
***************
*** 210,216 ****
  	cmp test.left arts/out.going/bar/togo.next
  	sed '/^$$/q' batchlog | sed '1d;$$d' | sed '$$d' >test.log
  	test ! -s test.log ;
! 	sed '1,/^$$/d' batchlog | sed '1d;$$d' | sed '$$d' >test.log
  	echo 'bar	backlog 1 (batches flowing)' >test.bar
  	cmp test.bar test.log
  	echo 'bar n 5000000 - staller' >batchparms
--- 214,224 ----
  	cmp test.left arts/out.going/bar/togo.next
  	sed '/^$$/q' batchlog | sed '1d;$$d' | sed '$$d' >test.log
  	test ! -s test.log ;
! 	sed '1,/^$$/d' batchlog | sed '/^$$/q' | sed '1d;$$d' | sed '$$d' >test.log
! 	sed 's;/[^ ]*/;/;' test.log >test.log2
! 	echo 'foo	backlog ? (disabled in /test.bp)' >test.logg
! 	cmp test.log2 test.logg
! 	sed '1,/^$$/d' batchlog | sed '1,/^$$/d' | sed '1d;$$d' | sed '$$d' >test.log
  	echo 'bar	backlog 1 (batches flowing)' >test.bar
  	cmp test.bar test.log
  	echo 'bar n 5000000 - staller' >batchparms

*** batch/bpfind.mastercopy	Thu Apr 27 20:49:03 1995
--- batch/bpfind	Fri Mar 10 21:38:15 1995
***************
*** 11,25 ****
  site="$2"
  shift ; shift
  
! awk 'BEGIN { site = "'"$site"'" ; classok = 1 ; defclassok = 1 }
  /^#/ { next }
  /^[ 	]*$/ { next }
  $1 == site && $2 !~ /'"$classpat"'/ { classok = 0 }
  $1 == site { siteline = $0 }
  $1 == "/default/" && $2 !~ /'"$classpat"'/ { defclassok = 0 }
  $1 == "/default/" { defline = $0 }
  END {
  	q = "'"'"'"
  	if (classok == 0 || (siteline == "" && defclassok == 0)) {
  		print "bpokay=x"
  		exit
--- 11,37 ----
  site="$2"
  shift ; shift
  
! awk 'BEGIN {
! 	site = "'"$site"'"
! 	classok = 1
! 	disable = 0
! 	defclassok = 1
! 	defdisable = 0
! }
  /^#/ { next }
  /^[ 	]*$/ { next }
+ $1 == site && $2 ~ /!/ { disable = 1 }
  $1 == site && $2 !~ /'"$classpat"'/ { classok = 0 }
  $1 == site { siteline = $0 }
+ $1 == "/default/" && $2 ~ /!/ { defdisable = 1 }
  $1 == "/default/" && $2 !~ /'"$classpat"'/ { defclassok = 0 }
  $1 == "/default/" { defline = $0 }
  END {
  	q = "'"'"'"
+ 	if (disable == 1 || (siteline == "" && defdisable == 1)) {
+ 		print "bpokay=!"
+ 		exit
+ 	}
  	if (classok == 0 || (siteline == "" && defclassok == 0)) {
  		print "bpokay=x"
  		exit

*** batch/usenntpxmit.mastercopy	Thu Apr 27 20:49:03 1995
--- batch/usenntpxmit	Tue Jan 31 12:40:17 1995
***************
*** 15,21 ****
  
  tmp=/tmp/nntp$$
  cat >$tmp
! nntpxmit $site:$tmp
  if test -s $tmp
  then
  	cat $tmp >>$NEWSSITEDIR/togo.leftover
--- 15,21 ----
  
  tmp=/tmp/nntp$$
  cat >$tmp
! nntpxmit -s $site:$tmp
  if test -s $tmp
  then
  	cat $tmp >>$NEWSSITEDIR/togo.leftover

*** conf/versionname.mastercopy	Thu Apr 27 20:49:04 1995
--- conf/versionname	Tue Mar 21 15:42:44 1995
***************
*** 1 ****
! Cleanup Release, with patch CR.E
--- 1 ----
! Cleanup Release, with patch CR.F

*** conf/rsetup.mastercopy	Thu Apr 27 20:49:04 1995
--- conf/rsetup	Sun Jan  8 15:58:35 1995
***************
*** 17,20 ****
  NEWSUMASK=022
  NEWSCONFIG=`pwd`/../conf/rconfig
  LOGNAME=regression
! export NEWSCTL NEWSBIN NEWSARTS NEWSOV NEWSPATH NEWSUMASK NEWSCONFIG LOGNAME
--- 17,22 ----
  NEWSUMASK=022
  NEWSCONFIG=`pwd`/../conf/rconfig
  LOGNAME=regression
! LANG=C				# affects sort collating order
! export NEWSCTL NEWSBIN NEWSARTS NEWSOV NEWSPATH NEWSUMASK NEWSCONFIG
! export LOGNAME LANG

*** conf/deadfiles.mastercopy	Thu Apr 27 20:49:05 1995
--- conf/deadfiles	Wed Apr 26 23:35:00 1995
***************
*** 4,9 ****
--- 4,12 ----
  doc/flow.old
  expire/mkadir
  inject/ersh
+ libbig/sys.fast.c
  libfake/link.c
+ libfake/fgetline.3
+ libsmall/sys.slow.c
  util/queuelen.old
  README.old

*** conf/subst.all.mastercopy	Thu Apr 27 20:49:05 1995
--- conf/subst.all	Wed Apr 26 23:33:10 1995
***************
*** 10,15 ****
--- 10,16 ----
  batch/viainews
  conf/config
  conf/cron.proto
+ conf/histsetup
  conf/rconfig
  conf/rsetup
  contrib/snntp/snntpsend

*** conf/makefile.mastercopy	Thu Apr 27 20:49:06 1995
--- conf/makefile	Wed Apr 26 22:59:46 1995
***************
*** 12,22 ****
  ALL=$(EGS) report.ctl crontab $(SERVER)
  
  all:	$(ALL)
! 	$(MX) report.ctl config
  
  install:	$(ALL)
  
! LASTGROUP=`egrep -v = $(NEWSCTL)/active | tr . / | sed -n '$$s/ .*//p'`
  
  setup:	$(ALL)
  	$(MKDIR) $(NEWSCTL)/bin
--- 12,22 ----
  ALL=$(EGS) report.ctl crontab $(SERVER)
  
  all:	$(ALL)
! 	$(MX) report.ctl config histsetup
  
  install:	$(ALL)
  
! LASTGROUP=`egrep -v '=|x$$' $(NEWSCTL)/active | tr . / | sed -n '$$s/ .*//p'`
  
  setup:	$(ALL)
  	$(MKDIR) $(NEWSCTL)/bin
***************
*** 23,33 ****
  	$(TO) -n $(NEWSCTL) report.ctl $(SERVER)
  	$(TO) `echo $(NEWSCONFIG) | sed 's;/[^/]*$$;;'` config
  	$(TO) -e -n $(NEWSCTL) $(EGS)
! 	touch $(NEWSCTL)/history
! 	if test ! -s $(NEWSCTL)/history.dir ;\
! 	then \
! 		$(NEWSBIN)/dbz $(NEWSCTL)/history ;\
! 	fi
  	if test -d $(NEWSARTS)/$(LASTGROUP) -a -d $(NEWSOV)/$(LASTGROUP) ;\
  	then \
  		: no adddirs needed ;\
--- 23,29 ----
  	$(TO) -n $(NEWSCTL) report.ctl $(SERVER)
  	$(TO) `echo $(NEWSCONFIG) | sed 's;/[^/]*$$;;'` config
  	$(TO) -e -n $(NEWSCTL) $(EGS)
! 	./histsetup
  	if test -d $(NEWSARTS)/$(LASTGROUP) -a -d $(NEWSOV)/$(LASTGROUP) ;\
  	then \
  		: no adddirs needed ;\
***************
*** 39,53 ****
  	$(TO) $(NEWSCTL) versionname
  
  cmp:	$(ALL)
  	@$(CF) $(UID) $(GID) '^drwx' $(NDIRS)
  	@$(IN) -i $(NEWSCTL) report.ctl
  	@$(IN) `echo $(NEWSCONFIG) | sed 's;/[^/]*$$;;'` config
  	test " `cat $(NEWSCTL)/whoami`" != " nosuchsite" ;
  	test " `cat $(NEWSCTL)/mailname`" != " no.such.domain" ;
  	test -r $(NEWSCTL)/history ;
  	test -s $(NEWSCTL)/history.dir ;
  	test -r $(NEWSCTL)/history.pag ;
! 	@$(IN) $(NEWSCTL) versionname
  	test -d $(NEWSARTS)/$(LASTGROUP) -a -d $(NEWSOV)/$(LASTGROUP) ;
  
  mx:
--- 35,55 ----
  	$(TO) $(NEWSCTL) versionname
  
  cmp:	$(ALL)
+ 	: make sure major directories have right ownership
  	@$(CF) $(UID) $(GID) '^drwx' $(NDIRS)
+ 	: compare some files
  	@$(IN) -i $(NEWSCTL) report.ctl
  	@$(IN) `echo $(NEWSCONFIG) | sed 's;/[^/]*$$;;'` config
+ 	@$(IN) $(NEWSCTL) versionname
+ 	: make sure the whoami and mailname files have been configured
  	test " `cat $(NEWSCTL)/whoami`" != " nosuchsite" ;
  	test " `cat $(NEWSCTL)/mailname`" != " no.such.domain" ;
+ 	: check that crucial files exist
  	test -r $(NEWSCTL)/history ;
  	test -s $(NEWSCTL)/history.dir ;
  	test -r $(NEWSCTL)/history.pag ;
! 	: check that the last newsgroup in active has directories -- too
! 	: expensive to check all of them
  	test -d $(NEWSARTS)/$(LASTGROUP) -a -d $(NEWSOV)/$(LASTGROUP) ;
  
  mx:

*** conf/histsetup.mastercopy	Thu Apr 27 20:49:06 1995
--- conf/histsetup	Thu Apr 27 20:33:58 1995
***************
*** 0 ****
--- 1,33 ----
+ #! /bin/sh
+ 
+ 
+ 
+ # =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
+ . ${NEWSCONFIG-/etc/news/bin/config}
+ 
+ 
+ 
+ PATH=$NEWSCTL/bin:$NEWSBIN:$NEWSPATH ; export PATH
+ umask $NEWSUMASK
+ 
+ cd $NEWSCTL
+ 
+ touch history || exit 1
+ if test -s history
+ then
+ 	# if dbz -v history
+ 	if test -s history.dir
+ 	then
+ 		exit 0
+ 	fi
+ 	echo '*** history file exists but index is not dbz format'
+ 	exit 1
+ fi
+ 
+ lock -o LOCK $$ || { echo '*** cannot get the lock file' ; exit 1 ; }
+ status=1
+ trap 'unlock LOCK ; trap 0 ; exit $status' 0 1 2 15
+ 
+ dbz history || exit
+ 
+ status=0			# and the trap does the exit

*** ctl/reg/n.1r.mastercopy	Thu Apr 27 20:49:07 1995
--- ctl/reg/n.1r	Tue Mar 21 17:04:14 1995
***************
*** 1,4 ****
! new newsgroup comp.lang.beta
  :::
  [email-masked] (David C Lawrence) said to
  create `comp.lang.beta'.
--- 1,4 ----
! newgroup comp.lang.beta
  :::
  [email-masked] (David C Lawrence) said to
  create `comp.lang.beta'.

*** ctl/newgroup.mastercopy	Thu Apr 27 20:49:08 1995
--- ctl/newgroup	Fri Mar  3 09:35:50 1995
***************
*** 136,152 ****
  # do the job
  case "$oldstatus" in
  '')	# new group
  	was="`wc -l <$NEWSCTL/active`"
! 	echo "$g 0000000000 00001 $newstatus" >>$NEWSCTL/active
  	echo "$g `now` $author" >>$NEWSCTL/active.times
  	if test `wc -l <$NEWSCTL/active` -le $was
  	then
  		fail='unable to append new entry to active file'
  	fi
- 	# make the directory since rn will bitch if it's missing
- 	mkpdir $NEWSARTS/`echo $g | tr . / ` $NEWSOV/`echo $g | tr . / `
- 	# and the overview file
- 	touch $NEWSOV/`echo $g | tr . /`/.overview
  	# and a newsgroups entry, if any...
  	awk '	BEGIN { printit = 0 }
  		$0 == "For your newsgroups file:" { printit = NR+1 }
--- 136,161 ----
  # do the job
  case "$oldstatus" in
  '')	# new group
+ 	max=0000000000
+ 	d=`echo $g | tr . /`
+ 	hi=
+ 	if test -d $NEWSARTS/$d			# recreating old group
+ 	then
+ 		hi=`ls -f $NEWSARTS/$d | egrep '^[0-9]+$' | sort -n | tail -1`
+ 	fi
+ 	if test " $hi" != " "			# old articles still there
+ 	then
+ 		max=000$hi
+ 	fi
+ 	mkpdir $NEWSARTS/$d $NEWSOV/$d
+ 	touch $NEWSOV/$d/.overview
  	was="`wc -l <$NEWSCTL/active`"
! 	echo "$g $max 00001 $newstatus" >>$NEWSCTL/active
  	echo "$g `now` $author" >>$NEWSCTL/active.times
  	if test `wc -l <$NEWSCTL/active` -le $was
  	then
  		fail='unable to append new entry to active file'
  	fi
  	# and a newsgroups entry, if any...
  	awk '	BEGIN { printit = 0 }
  		$0 == "For your newsgroups file:" { printit = NR+1 }
***************
*** 176,182 ****
  case "$action" in
  *q*)	;;
  *)	case "$oldstatus" in
! 	'')	title="new newsgroup $g"	;;
  	*)	title="status change for $g"	;;
  	esac
  	(
--- 185,191 ----
  case "$action" in
  *q*)	;;
  *)	case "$oldstatus" in
! 	'')	title="newgroup $g"	;;
  	*)	title="status change for $g"	;;
  	esac
  	(

*** doc/trouble.mastercopy	Thu Apr 27 20:49:08 1995
--- doc/trouble	Tue Mar 28 23:04:31 1995
***************
*** 184,194 ****
  the situation,
  and you will need to alter \fIspacefor\fR to check
  space on more than one filesystem.
! There is also a problem,
! currently,
  in that the \fIfind\fR command used
! by \fImkhistory\fR and \fIaddmissing\fR will not follow symbolic links;
! a fix for this is coming.
  .PP
  .Ix problems "want to ignore newgroup messages"
  \fIHow do I configure C News so that it will not automatically create any
--- 184,194 ----
  the situation,
  and you will need to alter \fIspacefor\fR to check
  space on more than one filesystem.
! There is also a problem
  in that the \fIfind\fR command used
! by \fImkhistory\fR and \fIaddmissing\fR will not follow symbolic links
! unless they are at the top level, right under NEWSARTS;
! this is hard to fix.
  .PP
  .Ix problems "want to ignore newgroup messages"
  \fIHow do I configure C News so that it will not automatically create any

*** doc/problems.mastercopy	Thu Apr 27 20:49:09 1995
--- doc/problems	Tue Mar 21 16:06:15 1995
***************
*** 502,510 ****
  .Ix relaynews
  \fIRelaynews\fR will try to make symbolic links if real ones fail,
  and copies if both fail.
- .PP
  .Ix expire
! \fIExpire\fR has a \fB\-l\fR option which
  tells it to consider the first filename of an article its `leader',
  not expiring the article under that name until it has expired under
  all others.
--- 502,514 ----
  .Ix relaynews
  \fIRelaynews\fR will try to make symbolic links if real ones fail,
  and copies if both fail.
  .Ix expire
! .Ix doexpire
! If symbolic links are used,
! .I doexpire
! will automatically invoke
! \fIexpire\fR with the \fB\-l\fR option,
! which
  tells it to consider the first filename of an article its `leader',
  not expiring the article under that name until it has expired under
  all others.

*** expire/doexpire.mastercopy	Thu Apr 27 20:49:10 1995
--- expire/doexpire	Wed Apr 26 23:39:46 1995
***************
*** 33,38 ****
--- 33,43 ----
  *)	echo "$0: unknown arguments \`$*'" >&2 ; exit 2	;;
  esac
  
+ if test -f $NEWSCTL/symlinks.used
+ then
+ 	opts="$opts -l"
+ fi
+ 
  lock -o LOCKexpire $$ || {
  	echo "$0: doexpire apparently already running, won't start another" |
  							report 'two doexpires'

*** expire/makefile.mastercopy	Thu Apr 27 20:49:10 1995
--- expire/makefile	Tue Mar 21 17:13:25 1995
***************
*** 98,103 ****
--- 98,104 ----
  	mkdir arts arts/foo arts/bar arts/bar/ugh arts/urp arch arch2
  	mkdir arts/mod arts/mod/mod arts/mod/unmod arch3 arch3/bletch
  	mkdir arts/bletch arts/lost+found arts/barf arts/barf/puke
+ 	mkdir arts/control arts/junk
  	echo 'foo 00103 00001 y ' >>active
  	echo 'foo 00103 00098 y' >>active.after
  	echo 'bar 00099 00001 m' >>active
***************
*** 112,117 ****
--- 113,122 ----
  	echo 'mod.unmod 00016 00016 y' >>active.after
  	echo 'bletch 00099 00001 y' >>active
  	echo 'bletch 00100 00001 y' >>active.after
+ 	echo 'control 00000 00001 y' >>active
+ 	echo 'control 00000 00001 y' >>active.after
+ 	echo 'junk 00000 00001 y' >>active
+ 	echo 'junk 00000 00001 y' >>active.after
  	cat $(AB) >>active
  	cat $(AB) >>active.after
  	echo nevermore >arts/lost+found/1

*** explode/explode.c.mastercopy	Thu Apr 27 20:49:11 1995
--- explode/explode.c	Thu Mar  9 14:59:43 1995
***************
*** 23,28 ****
--- 23,29 ----
  #include <stdio.h>
  #include <ctype.h>
  #include <errno.h>
+ #include "fixerrno.h"
  #include <sys/types.h>
  #include "libc.h"
  #include "news.h"

*** include/sys/time.fake.mastercopy	Thu Apr 27 20:49:11 1995
--- include/sys/time.fake	Thu Mar  9 15:26:08 1995
***************
*** 1,3 ****
--- 1,5 ----
+ #include <time.h>
+ 
  /*
   * fake Berkeley time structures
   */

*** inject/pnews.mastercopy	Thu Apr 27 20:49:12 1995
--- inject/pnews	Mon Jan 30 23:01:18 1995
***************
*** 46,52 ****
  		me="`hostname`"
  		case "$me" in
  		$svr)	args=				;;
! 		*)	args="-c $me -s $server"	;;
  		esac
  	else
  		args=
--- 46,52 ----
  		me="`hostname`"
  		case "$me" in
  		$svr)	args=				;;
! 		*)	args="-c $me -s $svr"		;;
  		esac
  	else
  		args=

*** input/newsspool.c.mastercopy	Thu Apr 27 20:49:13 1995
--- input/newsspool.c	Wed Mar 29 20:33:45 1995
***************
*** 24,30 ****
  int debug = 0;
  char *progname;
  
! extern void error(), exit();
  #ifdef UTZOOERR
  extern char *mkprogname();
  #else
--- 24,30 ----
  int debug = 0;
  char *progname;
  
! extern void error();
  #ifdef UTZOOERR
  extern char *mkprogname();
  #else

*** input/rnews.mastercopy	Thu Apr 27 20:49:13 1995
--- input/rnews	Thu Mar  9 15:33:54 1995
***************
*** 19,24 ****
--- 19,25 ----
  		.*)	decompress=	;;
  		*/*)	decompress=	;;
  		esac
+ 		shift
  		;;
  	--)	shift ; break	;;
  	-*)	echo "$0: unknown option \`$1'" >&2 ; exit 2	;;
***************
*** 67,74 ****
  
  # spool it
  case "$decompress" in
! '')	newsspool			;;
! *)	( "$decompress" | newsspool )	;;
  esac >/tmp/ngripe.$$ 2>&1
  if test ! -s /tmp/ngripe.$$
  then
--- 68,75 ----
  
  # spool it
  case "$decompress" in
! '')	newsspool		;;
! *)	$decompress | newsspool	;;
  esac >/tmp/ngripe.$$ 2>&1
  if test ! -s /tmp/ngripe.$$
  then

*** input/newsrun.mastercopy	Thu Apr 27 20:49:14 1995
--- input/newsrun	Fri Mar  3 09:39:59 1995
***************
*** 152,161 ****
  	done
  
  	# Do it.  -c is an optimisation.  -u tells relaynews to unlink
! 	# the ones that work.
  	if test " $list" != " "
  	then
! 		relaynews -c $here -u $stale $list >>$NEWSCTL/log 2>>$NEWSCTL/errlog
  		case "$?" in
  		0)	;;
  		1)	;;	# bad input; news system okay
--- 152,162 ----
  	done
  
  	# Do it.  -c is an optimisation.  -u tells relaynews to unlink
! 	# the ones that work.  -n records use of symlinks.
  	if test " $list" != " "
  	then
! 		relaynews -c $here -n $NEWSCTL/symlinks.used -u $stale \
! 					$list >>$NEWSCTL/log 2>>$NEWSCTL/errlog
  		case "$?" in
  		0)	;;
  		1)	;;	# bad input; news system okay

*** libbig/makefile.mastercopy	Thu Apr 27 20:49:15 1995
--- libbig/makefile	Sat Mar 11 16:54:29 1995
***************
*** 1,8 ****
  MORECFLAGS=-I../relay
  # =()<@<INCLUDE>@>()=
  .include "../include/config.make"
  
! OBJS=active.fast.o sys.fast.o
  ALL=$(OBJS)
  
  u:	$(ALL)
--- 1,13 ----
  MORECFLAGS=-I../relay
+ 
+ 
+ 
  # =()<@<INCLUDE>@>()=
  .include "../include/config.make"
  
! 
! 
! OBJS=active.fast.o
  ALL=$(OBJS)
  
  u:	$(ALL)

*** libc/getabsdate.3.mastercopy	Thu Apr 27 20:49:16 1995
--- libc/getabsdate.3	Wed Feb  8 18:18:09 1995
***************
*** 1,4 ****
! .TH GETABSDATE 3 "27 February 1991"
  .SH NAME
  getabsdate, prsabsdate, getindate, prsindate \- date and time parsers
  .SH SYNOPSIS
--- 1,4 ----
! .TH GETABSDATE 3 "8 February 1995"
  .SH NAME
  getabsdate, prsabsdate, getindate, prsindate \- date and time parsers
  .SH SYNOPSIS
***************
*** 69,77 ****
  and two- or four-digit year,
  and may optionally contain
  a colon-separated time
! (with optional seconds),
  weekday name,
! and signed numeric or alphabetic time zone.
  The day-of-month must precede the year,
  but no other ordering is assumed.
  Four-digit years are encouraged.
--- 69,77 ----
  and two- or four-digit year,
  and may optionally contain
  a colon-separated time
! (with optional seconds) (defaults to 00:00:00),
  weekday name,
! and signed numeric or alphabetic time zone (defaults to local time).
  The day-of-month must precede the year,
  but no other ordering is assumed.
  Four-digit years are encouraged.
***************
*** 124,129 ****
--- 124,143 ----
  modify their
  .I str
  arguments.
+ .PP
+ Using local time as the default time zone is okay,
+ but it should be local time
+ .IR then ,
+ at the specified date and time,
+ whereas in fact the time zone that is used is local time
+ .IR now .
+ (For example, if daylight savings time is in effect when
+ .I getabsdate
+ is called,
+ .I getabsdate
+ will assume it is always in effect.)
+ This is hard to fix without better information on
+ time changes.
  .PP
  The treatment of dashes in
  .I getabsdate

*** libcnews/fopenexcl.c.mastercopy	Thu Apr 27 20:49:16 1995
--- libcnews/fopenexcl.c	Mon Mar  6 12:27:39 1995
***************
*** 1,5 ****
  /*
!  * fopenexcl(name) - fopen(name, "w") with error if name exists
   */
  
  #include <stdio.h>
--- 1,5 ----
  /*
!  * fopenexcl(name) - fopen(name, "w+") with error if name exists
   */
  
  #include <stdio.h>
***************
*** 10,20 ****
  #endif
  
  #ifdef O_RDONLY			/* good, we have a 3-arg open() */
! #define	OPENW(f)	open(f, O_WRONLY|O_CREAT|O_EXCL, 0666)
  #else				/* don't -- must fake it */
  #include <sys/stat.h>
! static struct testbuf;
! #define	OPENW(f)	((stat(f, &testbuf) < 0) ? creat(f, 0666) : -1)
  #endif
  
  FILE *
--- 10,22 ----
  #endif
  
  #ifdef O_RDONLY			/* good, we have a 3-arg open() */
! #define	OPENRW(f)	open(f, O_RDWR|O_CREAT|O_EXCL, 0666)
  #else				/* don't -- must fake it */
  #include <sys/stat.h>
! static struct stat testbuf;
! #define	OPENRW(f)	((stat(f, &testbuf) < 0) ? \
! 				((void)close(creat(f, 0666)), open(f, 2)) : \
! 				-1)
  #endif
  
  FILE *
***************
*** 23,31 ****
  {
  	register int fd;
  
! 	fd = OPENW(name);
  	if (fd < 0)
  		return NULL;		/* name existed or couldn't be made */
  	else
! 		return fdopen(fd, "w");
  }
--- 25,33 ----
  {
  	register int fd;
  
! 	fd = OPENRW(name);
  	if (fd < 0)
  		return NULL;		/* name existed or couldn't be made */
  	else
! 		return fdopen(fd, "w+");
  }

*** libcnews/fakeftime.c.mastercopy	Thu Apr 27 20:49:17 1995
--- libcnews/fakeftime.c	Thu Mar  9 15:28:28 1995
***************
*** 4,10 ****
  
  #include <sys/types.h>
  #include <sys/time.h>
! #include <time.h>
  #include <sys/timeb.h>
  #include <stdlib.h>
  
--- 4,10 ----
  
  #include <sys/types.h>
  #include <sys/time.h>
! /* <sys/time.h> should have included <time.h>, cross your fingers... */
  #include <sys/timeb.h>
  #include <stdlib.h>

*** libdbz/makefile.mastercopy	Thu Apr 27 20:49:17 1995
--- libdbz/makefile	Thu Apr 27 20:34:38 1995
***************
*** 89,94 ****
--- 89,95 ----
  	rmdir xx
  	sed '/>	0/d' $(RHIST) >dbase.used
  	test "`cat dbase.used | wc -l`" -eq "`sed -n '2s/ .*//p' dbase.dir`" ;
+ 	: ./rdbz -v dbase
  	cp $(RHIST) dbase2
  	./rdbz -E 1000 -0 -p $(RPSIZE) -t '	' dbase2
  	cmp $(RHIST) dbase

*** libdbz/dbz.c.mastercopy	Thu Apr 27 20:49:18 1995
--- libdbz/dbz.c	Thu Mar  9 15:09:31 1995
***************
*** 169,179 ****
  #define	DEFCASE	'C'		/* C News -- RFC822 mapping */
  #endif
  #ifndef NOTAGS
! #define	TAGENB	0x80		/* tag enable is top bit, tag is next 5 */
  #define	TAGMASK	0x7c
  #define	TAGSHIFT	24
  #else
! #define	TAGENB	0		/* no tags */
  #define	TAGMASK	0
  #define	TAGSHIFT	0
  #endif
--- 169,179 ----
  #define	DEFCASE	'C'		/* C News -- RFC822 mapping */
  #endif
  #ifndef NOTAGS
! #define	TAGENB	0x80L		/* tag enable is top bit, tag is next 5 */
  #define	TAGMASK	0x7c
  #define	TAGSHIFT	24
  #else
! #define	TAGENB	0L		/* no tags */
  #define	TAGMASK	0
  #define	TAGSHIFT	0
  #endif

*** libfake/dbz.c.mastercopy	Thu Apr 27 20:49:19 1995
--- libfake/dbz.c	Tue Feb 21 12:58:06 1995
***************
*** 9,14 ****
--- 9,16 ----
  dbzfresh(a,b,c,d,e) char *a; long b; { return(dbzagain(a,a)); }
  long dbzsize(a) long a; { return(a); }
  dbzincore(n) int n; { return(0); }
+ dbzwritethrough(n) int n; { return(0); }
+ long dbztagmask(n) long n; { return(0); }
  dbzdebug(n) int n; { return(0); }
  long dbztrim(a) long a; { return(a); }
  int dbzsync() { return(0); }

*** libfake/gettimeofday.c.mastercopy	Thu Apr 27 20:49:20 1995
--- libfake/gettimeofday.c	Wed Feb  8 18:06:10 1995
***************
*** 11,33 ****
  #include <sys/time.h>
  #include <stdlib.h>
  
! /* daylight-savings type code for tz_dsttime */
! #ifndef DSTTYPE
! #define	DSTTYPE	1	/* USA */
! #endif
! 
  int
  gettimeofday(tvp, tzp)
  struct timeval *tvp;
  struct timezone *tzp;
  {
- 	register char *tz;
- 
  	(void) time(&tvp->tv_sec);
  	tvp->tv_usec = 0;		/* no good alternative */
  
! 	if (tzp != NULL) {		/* nothing uses this anyway */
! 		tzp->tz_minuteswest = 0;
! 		tzp->tz_dsttime = 0;
! 	}
  }
--- 11,24 ----
  #include <sys/time.h>
  #include <stdlib.h>
  
! /* ARGSUSED */
  int
  gettimeofday(tvp, tzp)
  struct timeval *tvp;
  struct timezone *tzp;
  {
  	(void) time(&tvp->tv_sec);
  	tvp->tv_usec = 0;		/* no good alternative */
  
! 	/* assert(tzp == NULL); */
  }

*** libsmall/makefile.mastercopy	Thu Apr 27 20:49:20 1995
--- libsmall/makefile	Sat Mar 11 16:54:58 1995
***************
*** 1,8 ****
  MORECFLAGS=-I../relay
  # =()<@<INCLUDE>@>()=
  .include "../include/config.make"
  
! OBJS=active.slow.o sys.slow.o
  ALL=$(OBJS)
  
  u:	$(ALL)
--- 1,13 ----
  MORECFLAGS=-I../relay
+ 
+ 
+ 
  # =()<@<INCLUDE>@>()=
  .include "../include/config.make"
  
! 
! 
! OBJS=active.slow.o
  ALL=$(OBJS)
  
  u:	$(ALL)

*** maint/addmissing.mastercopy	Thu Apr 27 20:49:21 1995
--- maint/addmissing	Tue Mar 28 23:01:41 1995
***************
*** 49,55 ****
  them=
  for f in `ls | egrep -v '\.|(^lost\+found$)'`
  do
! 	if test -d $f -a -r $f
  	then
  		them="$them $f"
  	fi
--- 49,55 ----
  them=
  for f in `ls | egrep -v '\.|(^lost\+found$)'`
  do
! 	if test -d $f/.
  	then
  		them="$them $f"
  	fi

*** maint/mergeactive.mastercopy	Thu Apr 27 20:49:22 1995
--- maint/mergeactive	Sun Feb  5 19:10:05 1995
***************
*** 34,40 ****
  cat $* >$tmp
  
  # do some checking
! checkactive -q $tmp >$err 2>&1
  if test -s $err
  then
  	echo "$0: problems in input:" >&2
--- 34,40 ----
  cat $* >$tmp
  
  # do some checking
! checkactive -i -q $tmp >$err 2>&1
  if test -s $err
  then
  	echo "$0: problems in input:" >&2

*** maint/checkactive.mastercopy	Thu Apr 27 20:49:22 1995
--- maint/checkactive	Mon Apr  3 15:32:47 1995
***************
*** 14,24 ****
--- 14,26 ----
  
  quick=n
  numok=n
+ complete=y
  for dummy
  do
  	case "$1" in
  	-q)	quick=y		;;
  	-n)	numok=y		;;
+ 	-i)	complete=n	;;
  	--)	shift ; break	;;
  	-*)	echo "$0: unknown option \`$1'" >&2 ; exit 2	;;
  	*)	break		;;
***************
*** 100,105 ****
--- 102,125 ----
  	exit
  fi
  
+ if test " $complete" = " y"
+ then
+ 	if egrep '^control ' $file >/dev/null
+ 	then
+ 		: okay
+ 	else
+ 		echo "no \`control' pseudo-newsgroup present"
+ 		exit
+ 	fi
+ 	if egrep '^junk ' $file >/dev/null
+ 	then
+ 		: okay
+ 	else
+ 		echo "no \`junk' pseudo-newsgroup present"
+ 		exit
+ 	fi
+ fi
+ 
  case "$quick" in
  y)	status=0 ; exit	;;
  esac
***************
*** 107,113 ****
  # this is pretty slow
  while read newsgroup rest
  do
! 	echo "$newsgroup" | awk -f $NEWSBIN/namecheck.awk
  done <$file | tee $tmp
  if test -s $tmp
  then
--- 127,134 ----
  # this is pretty slow
  while read newsgroup rest
  do
! 	echo "$newsgroup" | awk -f $NEWSBIN/namecheck.awk |
! 							sed "s/^/$newsgroup: /"
  done <$file | tee $tmp
  if test -s $tmp
  then

*** maint/addgroup.mastercopy	Thu Apr 27 20:49:23 1995
--- maint/addgroup	Fri Mar  3 09:32:40 1995
***************
*** 35,45 ****
  lock -v LOCK $$ 5 || exit 1
  trap "unlock LOCK ; trap 0 ; exit 0" 0 1 2 15
  
! echo "$1 0000000000 00001 $2" >>$NEWSCTL/active
  case "$2" in
  [x=]*)	;;
! *)	mkpdir $NEWSARTS/`echo $1 | tr . /` $NEWSOV/`echo $1 | tr . /`	;;
  esac
  
  SENDER=${LOGNAME-${USER-unknown}}@`newshostname`
  echo "$1 `now` $SENDER" >>$NEWSCTL/active.times
--- 35,58 ----
  lock -v LOCK $$ 5 || exit 1
  trap "unlock LOCK ; trap 0 ; exit 0" 0 1 2 15
  
! max=0000000000
  case "$2" in
  [x=]*)	;;
! *)	d=`echo $1 | tr . /`
! 	hi=
! 	if test -d $NEWSARTS/$d			# recreating old group
! 	then
! 		hi=`ls -f $NEWSARTS/$d | egrep '^[0-9]+$' | sort -n | tail -1`
! 	fi
! 	if test " $hi" != " "			# old articles still there
! 	then
! 		max=000$hi
! 	fi
! 	mkpdir $NEWSARTS/$d $NEWSOV/$d
! 	touch $NEWSOV/$d/.overview
! 	;;
  esac
+ echo "$1 $max 00001 $2" >>$NEWSCTL/active
  
  SENDER=${LOGNAME-${USER-unknown}}@`newshostname`
  echo "$1 `now` $SENDER" >>$NEWSCTL/active.times

*** maint/newsdaily.mastercopy	Thu Apr 27 20:49:23 1995
--- maint/newsdaily	Fri Mar  3 09:44:41 1995
***************
*** 170,175 ****
--- 170,176 ----
  # and do other daily chores
  $NEWSBIN/relay/dodelayed
  
+ # if there are dead-newsgroup directories to be deleted when empty, try them
  if test -s dirs.tbd
  then
  	while read dir
***************
*** 204,207 ****
--- 205,226 ----
  	done <dirs.tbd >dirs.ttd
  	cd $NEWSCTL
  	mv dirs.ttd dirs.tbd
+ fi
+ 
+ # if symlinks.used is older than the oldest article, get rid of it
+ if test -f symlinks.used
+ then
+ 	usedat="`cat symlinks.used`"
+ 	case "$usedat" in
+ 	'')	usedat=0	;;
+ 	esac
+ 	oldest="`sed 1q history | sed 's/^[^	]*	//' | sed 's/[~	].*//'`"
+ 	case "$oldest" in
+ 	'')	oldest=`now`	;;
+ 	esac
+ 	# throw in 10000s for a safety margin
+ 	obsoleteness=`echo "$usedat $oldest" | awk '{ print $1 - $2 + 10000 }'`
+ 	case "$obsoleteness" in
+ 	-*)	rm -f symlinks.used	;;
+ 	esac
  fi

*** maint/mkhistory.mastercopy	Thu Apr 27 20:49:24 1995
--- maint/mkhistory	Tue Mar 28 23:01:57 1995
***************
*** 34,40 ****
  them=
  for f in `ls | egrep -v '\.|(^lost\+found$)'`
  do
! 	if test -d $f -a -r $f
  	then
  		them="$them $f"
  	fi
--- 34,40 ----
  them=
  for f in `ls | egrep -v '\.|(^lost\+found$)'`
  do
! 	if test -d $f/.
  	then
  		them="$them $f"
  	fi

*** maint/makefile.mastercopy	Thu Apr 27 20:49:24 1995
--- maint/makefile	Sun Feb  5 19:16:48 1995
***************
*** 60,65 ****
--- 60,66 ----
  	cp ../util/namecheck.awk ../util/canonsys.awk .
  	mkdir arts arts/foo arts/bar arts/bar/ugh arts/urp
  	mkdir arts/bletch arts/lost+found
+ 	mkdir arts/junk arts/control
  	echo nevermore >arts/lost+found/1
  	echo '<okay1>	9999~-	foo/1' >history.gbase
  	echo 'MeSsAge-ID: <okay1>' >arts/foo/1
***************
*** 125,130 ****
--- 126,133 ----
  	: quick verification that checkactive at least runs, not a good test...
  	echo "foo 77 01 m" >active
  	echo "bar 99 77 y" >>active
+ 	echo "control 00 01 y" >>active
+ 	echo "junk 00 01 y" >>active
  	echo "bletch 0000000000 00001 =foo" >>active
  	$(HERE) ./checkactive >ca.out 2>ca.diag
  	test ! -s ca.out ;
***************
*** 132,137 ****
--- 135,142 ----
  	: give mergeactive a try
  	echo "foo 0 nobody" >active.times
  	echo "bar 0 nobody" >>active.times
+ 	echo "control 0 nobody" >>active.times
+ 	echo "junk 0 nobody" >>active.times
  	echo "bletch 0 regression@here" >>active.times
  	echo "foo 22 21 m" >active.new
  	echo "bletch 777 002 =foo" >>active.new

*** man/relaynews.8cn.mastercopy	Thu Apr 27 20:49:27 1995
--- man/relaynews.8cn	Thu Jan 12 19:21:11 1995
***************
*** 33,38 ****
--- 33,42 ----
  .B \-o
  days
  ]
+ [
+ .B \-n
+ notefile
+ ]
  .SH DESCRIPTION
  .I Relaynews
  installs locally
***************
*** 96,101 ****
--- 100,112 ----
  .I days
  old to be dropped
  (usually to stop accidentally-retransmitted old articles).
+ .B \-n
+ causes the current time (as decimal ASCII) to be written into
+ the
+ .I notefile
+ (which should be an absolute pathname) once if
+ .I relaynews
+ finds it necessary to use symbolic links when filing articles.
  .PP
  .B \-x
  prevents generation of

*** man/postnews.1cn.mastercopy	Thu Apr 27 20:49:28 1995
--- man/postnews.1cn	Mon Apr  3 11:48:01 1995
***************
*** 1,6 ****
  .\" =()<.ds c @<NEWSCTL>@>()=
  .ds c /etc/news
! .TH POSTNEWS 1 "21 Nov 1990"
  .BY "C News"
  .SH NAME
  postnews \- simple interactive news-posting interface
--- 1,9 ----
  .\" =()<.ds c @<NEWSCTL>@>()=
  .ds c /etc/news
! .\"
! .\"
! .\"
! .TH POSTNEWS 1 "3 April 1995"
  .BY "C News"
  .SH NAME
  postnews \- simple interactive news-posting interface
***************
*** 15,25 ****
  provides a simple interactive interface for posting news.
  It prompts the user for the \fInewsgroup\fR if it is not given as an argument
  (more than one group can be given, with groups separated by commas but no
! white space),
! prompts for the article's subject,
! drops the user into his choice of text editor with a prototype
! article,
! checks (when the editor terminates) that the article has been edited
  reasonably, and then posts it.
  .PP
  If the article has not been written out from the editor, or if the
--- 18,32 ----
  provides a simple interactive interface for posting news.
  It prompts the user for the \fInewsgroup\fR if it is not given as an argument
  (more than one group can be given, with groups separated by commas but no
! white space).
! Then it prompts for the article's subject.
! Then it
! drops the user into his choice of text editor
! (as indicated by the VISUAL and EDITOR environment variables)
! with a prototype
! article.
! When the editor terminates,
! it checks that the article has been edited
  reasonably, and then posts it.
  .PP
  If the article has not been written out from the editor, or if the

*** man/newsbatch.8cn.mastercopy	Thu Apr 27 20:49:28 1995
--- man/newsbatch.8cn	Fri Mar 10 21:39:38 1995
***************
*** 4,10 ****
  .ds b /usr/libexec/news
  .\" =()<.ds c @<NEWSCTL>@>()=
  .ds c /etc/news
! .TH NEWSBATCH 8 "3 Oct 1994"
  .BY "C News"
  .SH NAME
  sendbatches, batchsplit \- news batching to other sites
--- 4,13 ----
  .ds b /usr/libexec/news
  .\" =()<.ds c @<NEWSCTL>@>()=
  .ds c /etc/news
! .\"
! .\"
! .\"
! .TH NEWSBATCH 8 "10 March 1995"
  .BY "C News"
  .SH NAME
  sendbatches, batchsplit \- news batching to other sites
***************
*** 162,167 ****
--- 165,180 ----
  and `n' for NNTP feeds;
  user-defined classes should be uppercase letters.
  .PP
+ If the character `!' appears anywhere in the
+ class field of a
+ .I batchparms
+ line, that
+ .I disables
+ the line.
+ Any site whose batching would have been controlled by that line
+ will have no batching attempted for it under any circumstances.
+ This provides a way to turn a site off temporarily.
+ .PP
  The third field is the size of batches to be prepared (before compression),
  in bytes.
  It may optionally be two sizes separated by `\-',
***************
*** 402,404 ****
--- 415,422 ----
  .PP
  There ought to be an encoder using MIME's base64 encoding
  and suitable descriptive headers.
+ .PP
+ The logging is overly simplistic and doesn't work well when
+ selective batching (controlled by
+ .I site
+ arguments, classes, or disabling) is being done.

*** man/checkactive.8.mastercopy	Thu Apr 27 20:49:29 1995
--- man/checkactive.8	Sun Feb  5 19:21:17 1995
***************
*** 7,13 ****
  .\"
  .\"
  .\"
! .TH CHECKACTIVE 8CN "30 Nov 1994"
  .BY "C News"
  .SH NAME
  checkactive \- check format of news active file
--- 7,13 ----
  .\"
  .\"
  .\"
! .TH CHECKACTIVE 8CN "5 Feb 1995"
  .BY "C News"
  .SH NAME
  checkactive \- check format of news active file
***************
*** 17,22 ****
--- 17,24 ----
  .B \-q
  ] [
  .B \-n
+ ] [
+ .B \-i
  ] [ file ]
  .SH DESCRIPTION
  .I Checkactive
***************
*** 45,50 ****
--- 47,61 ----
  which is relatively slow for a large
  .I active
  file.
+ .PP
+ The
+ .B \-i
+ (incomplete) option indicates that the input is only part of an
+ .I active
+ file and might be incomplete,
+ e.g. it might not have entries for the
+ ``control'' and ``junk''
+ pseudo-newsgroups.
  .SH SEE ALSO
  newsdb(5)
  .SH HISTORY

*** nov/expovguts.c.mastercopy	Thu Apr 27 20:49:30 1995
--- nov/expovguts.c	Thu Mar  9 14:26:54 1995
***************
*** 60,65 ****
--- 60,66 ----
  
  	start = atol(argv[optind+1]);
  	stop = atol(argv[optind]);		/* tentatively */
+ 	inname = argv[optind+2];
  	if (start == 0) {
  		fprintf(stderr, "%s: in expiring `%s',\n", progname, inname);
  		fprintf(stderr, "\tfound problem in active file:  min == 0\n",
***************
*** 76,82 ****
  	if (debug)
  		printf("start %ld, stop %ld\n", start, stop);
  
- 	inname = argv[optind+2];
  	tmpname = str3save(inname, ".tmp", "");
  
  	amap = malloc((size_t)(stop - start));
--- 77,82 ----

*** readnews/postnews.mastercopy	Thu Apr 27 20:49:30 1995
--- readnews/postnews	Tue Mar 21 15:40:49 1995
***************
*** 11,17 ****
  umask 077				# private
  
  tmp=/tmp/pn$$
! term="rm -f $tmp ; trap 0 ; exit 0"
  trap "$term" 0 1 2
  
  if test " $VISUAL" != " "
--- 11,18 ----
  umask 077				# private
  
  tmp=/tmp/pn$$
! tmpcopy=/tmp/pnc$$
! term="rm -f $tmp $tmpcopy ; trap 0 ; exit 0"
  trap "$term" 0 1 2
  
  if test " $VISUAL" != " "
***************
*** 77,88 ****
  esac
  
  echo >>$tmp
! echo DELETE THIS LINE "(but DO NOT delete the blank line after the headers above)" >>$tmp
! if test -r $NEWSCTL/postdefltdist
! then
! 	echo 'DELETE THIS LINE (You may want to change the "Distribution" header)' >>$tmp
! fi
! echo REPLACE THIS LINE WITH YOUR TEXT >>$tmp
  
  trap : 2
  PATH="$oldpath"
--- 78,85 ----
  esac
  
  echo >>$tmp
! echo "REPLACE THIS LINE WITH YOUR TEXT (leave the preceding blank line alone)" >>$tmp
! cp $tmp $tmpcopy
  
  trap : 2
  PATH="$oldpath"
***************
*** 90,96 ****
  PATH=$newpath
  trap "$term" 2
  
! while egrep '^(DELETE|REPLACE) THIS LINE' $tmp >/dev/null
  do
  	echo 'This posting does not appear to have been edited properly.'
  	echo 'Abandon it [y] ? ' | tr -d "$newline"
--- 87,93 ----
  PATH=$newpath
  trap "$term" 2
  
! while cmp -s $tmp $tmpcopy
  do
  	echo 'This posting does not appear to have been edited properly.'
  	echo 'Abandon it [y] ? ' | tr -d "$newline"

*** relay/makefile.mastercopy	Thu Apr 27 20:49:31 1995
--- relay/makefile	Sat Mar 11 16:56:08 1995
***************
*** 8,14 ****
  ALL=$(PROGS)
  
  OBJ=relaynews.o active.o article.o control.o \
! 	fileart.o hdrdefs.o hdrparse.o \
  	hdrmunge.o history.o io.o procart.o sys.o transmit.o trbatch.o \
  	ihave.o morefds.o
  
--- 8,14 ----
  ALL=$(PROGS)
  
  OBJ=relaynews.o active.o article.o control.o \
! 	fileart.o fsys.o hdrdefs.o hdrparse.o \
  	hdrmunge.o history.o io.o procart.o sys.o transmit.o trbatch.o \
  	ihave.o morefds.o
  
***************
*** 25,30 ****
--- 25,33 ----
  
  cmp:	$(PROGS)
  	@$(IN) $(DEST) $(PROGS)
+ 	: check that relaynews is NOT set-uid
+ 	test " `ls -l $(DEST)/relaynews | awk '$$1 ~ /s/`" = " " ;
+ 	: check that obsolete staleness program is NOT present
  	test ! -f $(DEST)/staleness ;
  
  relaynews: $(OBJ) $(LIB)

*** relay/relayrun.mastercopy	Thu Apr 27 20:49:32 1995
--- relay/relayrun	Tue Jan  3 15:41:52 1995
***************
*** 12,15 ****
  ?*)	stale="-o $stale"	;;
  esac
  
! exec relaynews -c `pwd` $stale $*
--- 12,15 ----
  ?*)	stale="-o $stale"	;;
  esac
  
! exec relaynews -c `pwd` $stale $* >>$NEWSCTL/log 2>>$NEWSCTL/errlog

*** relay/fsys.c.mastercopy	Thu Apr 27 20:49:32 1995
--- relay/fsys.c	Sat Mar 11 16:55:39 1995
***************
*** 0 ****
--- 1,57 ----
+ /*
+  * news sys file reading functions (fast, big, in-memory version)
+  * formerly libbig/sys.fast.c
+  */
+ 
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include "news.h"
+ #include "ngmatch.h"
+ #include "system.h"
+ 
+ /* imports */
+ extern struct system *currsys, *firstsys;
+ 
+ /* private */
+ static struct system *thissys = NULL;
+ 
+ void
+ remmysys(sys)				/* remember this system */
+ struct system *sys;
+ {
+ 	thissys = sys;
+ }
+ 
+ struct system *
+ mysysincache()				/* optimisation */
+ {
+ 	return thissys;
+ }
+ 
+ void
+ setupsys(fp)
+ FILE *fp;
+ {
+ 	rewind(fp);
+ }
+ 
+ boolean
+ donesys()
+ {
+ 	return NO;
+ }
+ 
+ /* ARGSUSED */
+ void
+ rewsys(fp)
+ FILE *fp;
+ {
+ 	currsys = firstsys;
+ }
+ 
+ void
+ advcurrsys()	/* advance currsys to the next in-core sys entry, if any. */
+ {
+ 	if (currsys != NULL)
+ 		currsys = currsys->sy_next;
+ }

*** relay/fileart.c.mastercopy	Thu Apr 27 20:49:33 1995
--- relay/fileart.c	Thu Mar  9 15:22:23 1995
***************
*** 98,103 ****
--- 98,105 ----
  static int goodngs;			/* asgnartnum reads goodngs */
  static int junkgroups;			/* count "junked" groups */
  static boolean debug = NO;
+ static boolean slinknoted = NO;		/* have we noted use of symlinks? */
+ extern char *slinkfile;			/* in relaynews.c */
  
  static char dbglink[] = "linking `%s' to `%s'... ";
  static char dbgsymlink[] = "symlinking `%s' to `%s'... ";
***************
*** 108,113 ****
--- 110,118 ----
  static char logxcl[] = "all groups `%s' excluded in active\n";
  static char dbgcopy[] = "couldn't link or symlink; copying `%s' to `%s'... ";
  
+ /* forward */
+ STATIC int lnkcmp();
+ 
  void
  filedebug(state)		/* set debugging state */
  boolean state;
***************
*** 193,198 ****
--- 198,212 ----
  		worked = symlink(fullartfile(oname), artname) == 0;
  		if (worked && lp != NULL)
  			lp->l_type = 's';
+ 		if (worked && !slinknoted && slinkfile != NULL) {
+ 			register FILE *f = fopen(slinkfile, "w");
+ 
+ 			if (f != NULL) {
+ 				fprintf(f, "%ld\n", (long)time((time_t *)NULL));
+ 				fclose(f);
+ 			}
+ 			slinknoted = 1;
+ 		}
  		free(oname);
  	}
  	return worked;
***************
*** 275,281 ****
  		art->a_tmpf = strsave(SPOOLTMP);
  		(void) mktemp(art->a_tmpf);
  		art->a_unlink = YES;
! 		art->a_artf = fopenwclex(art->a_tmpf, "w");
  		if (art->a_artf == NULL)
  			persistent(art, '\0', "", "");	/* can't open article */
  	}
--- 289,295 ----
  		art->a_tmpf = strsave(SPOOLTMP);
  		(void) mktemp(art->a_tmpf);
  		art->a_unlink = YES;
! 		art->a_artf = fopenwclex(art->a_tmpf, "w+");
  		if (art->a_artf == NULL)
  			persistent(art, '\0', "", "");	/* can't open article */
  	}
***************
*** 664,670 ****
  	register struct link *lp, *olp;
  	register char *ngs;
  	struct stat statb;
- 	STATIC int lnkcmp();
  
  	if (art->a_filed)
  		return;				/* don't file twice */
--- 678,683 ----
***************
*** 727,734 ****
  fileart(art)
  register struct article *art;
  {
- /*	if (art->a_filed)
- 		return;			/* don't file twice */
  	mklinks(art);
  	if (goodngs == 0)
  		mkjunklink(art);
--- 740,745 ----

*** relay/relaynews.c.mastercopy	Thu Apr 27 20:49:33 1995
--- relay/relaynews.c	Thu Jan 12 19:18:35 1995
***************
*** 56,61 ****
--- 56,62 ----
  char *progname = "relaynews";
  struct options opts;
  struct newsconf newsconf;
+ char *slinkfile = NULL;
  
  /* privates */
  static boolean uunlink = NO;
***************
*** 176,182 ****
  {
  	int c, errflg = 0;
  
! 	while ((c = getopt(argc, argv, "a:b:c:d:ho:sux")) != EOF)
  		switch (c) {
  		case 'a':
  			optsp->dupsokay = YES;
--- 177,183 ----
  {
  	int c, errflg = 0;
  
! 	while ((c = getopt(argc, argv, "a:b:c:d:hn:o:sux")) != EOF)
  		switch (c) {
  		case 'a':
  			optsp->dupsokay = YES;
***************
*** 201,206 ****
--- 202,210 ----
  			break;
  		case 'h':		/* keep no history of rejects */
  			optsp->histreject = NO;
+ 			break;
+ 		case 'n':		/* note use of symlinks in this file */
+ 			slinkfile = optarg;
  			break;
  		case 'o':
  			/* "oldness": drop articles older than this many days */

*** util/canonhdr.c.mastercopy	Thu Apr 27 20:49:34 1995
--- util/canonhdr.c	Thu Mar  9 15:23:21 1995
***************
*** 20,25 ****
--- 20,26 ----
  extern FILE *efopen();
  extern char *strsave(), *str3save();
  extern char *ascingmtime();
+ extern time_t getabsdate();
  
  /* exports */
  char *progname;

*** util/dostatfs.c.mastercopy	Thu Apr 27 20:49:35 1995
--- util/dostatfs.c	Mon Feb 27 11:58:27 1995
***************
*** 13,19 ****
   * a few attempts...
   */
  
! /* First, pick up one popular header on general principles. */
  #include <sys/mount.h>
  
  /* Second, assorted variations... */
--- 13,20 ----
   * a few attempts...
   */
  
! /* First, pick up a few popular headers on general principles. */
! #include <sys/param.h>
  #include <sys/mount.h>
  
  /* Second, assorted variations... */

*** util/makefile.mastercopy	Thu Apr 27 20:49:35 1995
--- util/makefile	Tue Mar 21 17:05:14 1995
***************
*** 96,109 ****
  	echo 'echo 0' >>$@
  
  r:	$(ALL) rclean
! 	$(MX) $(PROGS)
! 	: If this fails, your make is broken, and later regression tests
! 	: would fail spuriously for that reason.
! 	echo $$NEWSARTS >tmp.mc
! 	test " `cat tmp.mc`" = " " ;
! 	: looks like make is okay
! 	# 756362361 is Mon, 20 Dec 1993 04:39:21 GMT -- checked by calculator
  	: ctime
  	test "`./ctime -u 756362361`" = "Mon Dec 20 04:39:21 1993"
  	test "`./ctime -i 756362361`" = "Mon, 20 Dec 1993 04:39:21 GMT"
  	: getabsdate
--- 96,126 ----
  	echo 'echo 0' >>$@
  
  r:	$(ALL) rclean
! 	$(MX) $(PROGS) shellcheck
! 	: If this fails, you missed a vital path directory, and later
! 	: regression tests would fail messily for that reason.
! 	$(HERE) test " `echo hi | wc -l`" -eq 1 ;
! 	: If this fails, you have a buggy shell, probably bash, and the
! 	: C News locking system will not work properly as a result.
! 	./shellcheck
! 	: a sketchy test of locking
! 	$(HERE) ./lock LOCKtest $$$$
! 	test -s LOCKtest ;
! 	: If the following fails, you probably have either a buggy make
! 	: or a buggy shell, e.g. an old version of bash.
! 	$(HERE) if ./lock -o LOCKtest $$$$ ; then false ; else true ; fi
! 	test -s LOCKtest ;
! 	: test that touchlock really does update locks
! 	echo hi >tmp.lock
! 	sleep 2
! 	$(HERE) ./touchlock LOCKtest
! 	test -s LOCKtest ;
! 	test " `find L* -newer tmp.lock -print`" = " LOCKtest" ;
! 	: and try unlocking things
! 	$(HERE) ./unlock LOCKtest
! 	test ! -f LOCKtest ;
  	: ctime
+ 	: 756362361 is Mon, 20 Dec 1993 04:39:21 GMT -- checked by calculator
  	test "`./ctime -u 756362361`" = "Mon Dec 20 04:39:21 1993"
  	test "`./ctime -i 756362361`" = "Mon, 20 Dec 1993 04:39:21 GMT"
  	: getabsdate
***************
*** 170,176 ****
  	: but more needed... someday...
  
  rclean:
! 	rm -f tmp.* report.ctl
  	rm -rf arts
  
  clean:	rclean
--- 187,193 ----
  	: but more needed... someday...
  
  rclean:
! 	rm -f tmp.* report.ctl L*
  	rm -rf arts
  
  clean:	rclean

*** util/lock.mastercopy	Thu Apr 27 20:49:36 1995
--- util/lock	Sat Mar  4 22:38:48 1995
***************
*** 36,43 ****
  status=1
  trap 'rm -f $ltemp ; trap 0 ; exit $status' 0 1 2 15
  echo "$pid" >$ltemp || exit 1
! first=y
! while test " $persist" = " y" -o " $first" = " y"
  do
  	if newslock $ltemp $lock
  	then
--- 36,42 ----
  status=1
  trap 'rm -f $ltemp ; trap 0 ; exit $status' 0 1 2 15
  echo "$pid" >$ltemp || exit 1
! while :
  do
  	if newslock $ltemp $lock
  	then
***************
*** 44,56 ****
  		status=0
  		touch $lock		# make the date current
  		exit
! 	fi
! 	if test ! -f $ltemp
  	then
  		echo "$0: \`$ltemp' disappeared!!" >&2
  		exit
  	fi
- 	test " $verbose" = " y" && echo 'news system locked, waiting...'
  	sleep $sleep
- 	first=n
  done
--- 43,60 ----
  		status=0
  		touch $lock		# make the date current
  		exit
! 	elif test ! -f $ltemp
  	then
  		echo "$0: \`$ltemp' disappeared!!" >&2
  		exit
+ 	elif test " $persist" = " n"
+ 	then
+ 		exit
+ 	fi
+ 
+ 	if test " $verbose" = " y"
+ 	then
+ 		echo 'news system locked, waiting...'
  	fi
  	sleep $sleep
  done

*** util/unlock.mastercopy	Thu Apr 27 20:49:36 1995
--- util/unlock	Sat Mar  4 21:10:42 1995
***************
*** 7,12 ****
--- 7,13 ----
  PATH=$NEWSCTL/bin:$NEWSBIN:$NEWSPATH ; export PATH
  umask $NEWSUMASK
  
+ status=0
  for lname
  do
  	case "$lname" in
***************
*** 17,24 ****
  	if test ! -f "$lock"
  	then
  		echo "$0: cannot find \`$lock'" >&2
  	else
  		rm -f "$lock"		# alas, no useful exit status
  	fi
  done
! exit 0
--- 18,26 ----
  	if test ! -f "$lock"
  	then
  		echo "$0: cannot find \`$lock'" >&2
+ 		status=1
  	else
  		rm -f "$lock"		# alas, no useful exit status
  	fi
  done
! exit $status

*** util/touchlock.mastercopy	Thu Apr 27 20:49:37 1995
--- util/touchlock	Sat Mar  4 21:07:01 1995
***************
*** 7,12 ****
--- 7,13 ----
  PATH=$NEWSCTL/bin:$NEWSBIN:$NEWSPATH ; export PATH
  umask $NEWSUMASK
  
+ status=0
  for lname
  do
  	case "$lname" in
***************
*** 17,23 ****
  	if test ! -f "$lock"
  	then
  		echo "$0: cannot find \`$lock'" >&2
  	else
! 		touch "$lock"
  	fi
  done
--- 18,26 ----
  	if test ! -f "$lock"
  	then
  		echo "$0: cannot find \`$lock'" >&2
+ 		status=1
  	else
! 		touch "$lock" || status=1
  	fi
  done
+ exit $status

*** util/sfshproto.mastercopy	Thu Apr 27 20:49:37 1995
--- util/sfshproto	Tue Mar 21 17:38:53 1995
***************
*** 27,33 ****
  incoming)	arg="$NEWSARTS/in.coming" ; desire=5000 ;;
  articles)	arg="$NEWSARTS" ; desire=5000 ;;
  control)	arg="$NEWSCTL" ; desire=3000 ;;		# for expire, mostly
! outbound)	arg="/usr/spool/uucp" ; desire=10000 ;;	# ignore $3
  batchfiles)	arg="$NEWSARTS/out.going" ; desire=5000 ;;
  archive)	arg="$NEWSARTS" ; desire=1 ;;		# system-specific
  *)		arg="$2" ; desire = 1 ;;
--- 27,33 ----
  incoming)	arg="$NEWSARTS/in.coming" ; desire=5000 ;;
  articles)	arg="$NEWSARTS" ; desire=5000 ;;
  control)	arg="$NEWSCTL" ; desire=3000 ;;		# for expire, mostly
! outbound)	arg="/var/spool/uucp" ; desire=10000 ;;	# ignore $3
  batchfiles)	arg="$NEWSARTS/out.going" ; desire=5000 ;;
  archive)	arg="$NEWSARTS" ; desire=1 ;;		# system-specific
  *)		arg="$2" ; desire = 1 ;;

*** util/sfcproto.mastercopy	Thu Apr 27 20:49:38 1995
--- util/sfcproto	Tue Mar 21 17:38:46 1995
***************
*** 22,28 ****
  incoming)	arg="$NEWSARTS/in.coming" ; blocks=5000 ; inodes=1000	;;
  articles)	arg="$NEWSARTS" ; blocks=5000 ; inodes=1000 ; est='-e 3000' ;;
  control)	arg="$NEWSCTL" ; blocks=3000 ; inodes=100		;;
! outbound)	arg="/usr/spool/uucp" ; blocks=10000 ; inodes=1000	;;
  batchfiles)	arg="$NEWSARTS/out.going" ; blocks=5000 ; inodes=1000 ; est='-e 100000'	;;
  archive)	arg="$NEWSARTS" ; blocks=1 ; inodes=1 ; est='-e 3000'	;;
  *)		arg="$2" ; blocks=1 ; inodes=1 ; est='-e 3000'		;;
--- 22,28 ----
  incoming)	arg="$NEWSARTS/in.coming" ; blocks=5000 ; inodes=1000	;;
  articles)	arg="$NEWSARTS" ; blocks=5000 ; inodes=1000 ; est='-e 3000' ;;
  control)	arg="$NEWSCTL" ; blocks=3000 ; inodes=100		;;
! outbound)	arg="/var/spool/uucp" ; blocks=10000 ; inodes=1000	;;
  batchfiles)	arg="$NEWSARTS/out.going" ; blocks=5000 ; inodes=1000 ; est='-e 100000'	;;
  archive)	arg="$NEWSARTS" ; blocks=1 ; inodes=1 ; est='-e 3000'	;;
  *)		arg="$2" ; blocks=1 ; inodes=1 ; est='-e 3000'		;;

*** util/now.c.mastercopy	Thu Apr 27 20:49:38 1995
--- util/now.c	Thu Mar  9 15:30:11 1995
***************
*** 6,11 ****
--- 6,12 ----
  #include <stdio.h>
  #include <stdlib.h>
  #include <time.h>
+ #include "libc.h"
  
  /*
   - main - do it all

*** util/shellcheck.mastercopy	Thu Apr 27 20:49:38 1995
--- util/shellcheck	Tue Mar 21 16:25:32 1995
***************
*** 0 ****
--- 1,10 ----
+ #! /bin/sh
+ trap 'rm -f tmp.trap ; trap 0 ; exit $st' 0
+ ( touch tmp.trap )
+ if test -f tmp.trap
+ then
+ 	st=0
+ else
+ 	st=1
+ fi
+ exit 1