Subject: C News patch CR.E
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.E
(suggested archive name:  patchCR.E)
apply with   patch -p0 <thisfile

Prereq: CR.D
*** README.mastercopy	Mon Jan  2 16:31:19 1995
--- README	Thu Dec 29 19:42:51 1994
***************
*** 1,4 ****
! Cleanup Release of C News, with patch CR.D			Nov 1994
  
  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.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

*** README.changes.mastercopy	Mon Jan  2 16:31:20 1995
--- README.changes	Thu Dec 29 18:23:41 1994
***************
*** 1,3 ****
--- 1,19 ----
+ 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
+ number incorrectly for low-traffic newsgroups, and revisions to inews's
+ interior to remove ersh and thus the last invocation of rsh, at the expense
+ of building somewhat longer message IDs when posting on a server from a
+ client.  Histinfo (used in mkhistory etc.) now ignores nonexistent articles
+ rather than croaking on them.  The newsflag command is now documented.  The
+ configuration setup used for regression tests has been revised to ignore
+ any NEWSCTL (etc.) environment variables that you may happen to have
+ in your environment (which may be right for production use, but are most
+ definitely wrong for the regression tests, which want to supply their own).
+ Quiz no longer offers to fake link(), which can't be done without breaking
+ the locking protocol (oops).  The expovguts messages have been improved.
+ More portability work in dostatfs.  And the usual minor fixes.
+ 
  High points of patch CR.D:
  This one's mostly a cleanup job on CR.B/CR.C.  The one really new item
  is a queuelen appropriate to Taylor UUCP.  The master makefile has been

*** quiz.mastercopy	Mon Jan  2 16:31:20 1995
--- quiz	Thu Dec  1 13:06:16 1994
***************
*** 171,177 ****
  possibly-missing system calls, but it needs to know which are missing.
  !
  newfake=
! mightfake='fcntl fgetline getopt gettimeofday link memcpy mkdir putenv
  	remove rename strchr strerror strspn symlink'
  for fn in $mightfake
  do
--- 171,177 ----
  possibly-missing system calls, but it needs to know which are missing.
  !
  newfake=
! mightfake='fcntl fgetline getopt gettimeofday memcpy mkdir putenv
  	remove rename strchr strerror strspn symlink'
  for fn in $mightfake
  do
***************
*** 403,409 ****
  do
  	uucptype=`$ask 'Which one is most appropriate' ${uucptype-hdb}`
  	case "$uucptype" in
! 	svr4|hdb|tay|sub|old|pre|null)	break	;;
  	esac
  	echo 'Sorry, no such choice is available.'
  done
--- 403,409 ----
  do
  	uucptype=`$ask 'Which one is most appropriate' ${uucptype-hdb}`
  	case "$uucptype" in
! 	svr4|hdb|tay|sub|vo|pre|null)	break	;;
  	esac
  	echo 'Sorry, no such choice is available.'
  done

*** conf/README.mastercopy	Mon Jan  2 16:31:21 1995
--- conf/README	Thu Dec 29 16:10:02 1994
***************
*** 1,10 ****
! This is C News master configuration stuff, including some auxiliary C News
! programs that are quite likely to need site-specific customizing, and some
! odds and ends of maintenance stuff that didn't fit anywhere else.
  
! Subst may possibly be useful enough to deserve installation as a program
! in its own right, which is why a manual page is supplied.
! 
! "build" is the all-singing-all-dancing interactive shell program that sets
! up a bunch of shell files for you to run to install everything.  "build"
! itself does not mess with anything, so it can be run without danger.
--- 1,32 ----
! This is configuration files and miscellaneous oddments that don't fit
! in any of the subsystems.
  
! active.eg	sample active file
! ask		question-asker auxiliary for quiz
! checkfile	ownership/permission checker for make cmp
! cmpto		file comparer for make cmp
! config		sample config file
! cpto		file copier for installation
! cron.proto	prototype file from which sample crontab is generated
! deadfiles	list of files obsoleted by new releases of C News
! inall		do-command-in-all-directories auxiliary for top-level makefile
! libcmp		library-member comparer for make cmp
! mailname.eg	sample mailname file
! mailpaths.eg	sample mailpaths file
! makefilelist	list of makefiles for subst
! maker		make-with-include imitation
! mkdirs		directory maker for installation
! notinlist	list-checker auxiliary for quiz
! organization	sample organization file
! rconfig		regression-test config file
! rsetup		regression-test setup script
! subst		substituter
! subst.1		manpage for subst
! subst.all	list of all non-makefile files to be subst'ed
! sys.eg		sample sys file
! update.ran	ranlib version of library updater for make
! update.sym	symdef version of library updater for make
! useanswers	file-generator auxiliary for quiz
! versionname	version name of C News
! whoami.eg	sample whoami file
! yesno		question-asker auxiliary for quiz

*** conf/versionname.mastercopy	Mon Jan  2 16:31:21 1995
--- conf/versionname	Thu Dec 29 17:14:58 1994
***************
*** 1 ****
! Cleanup Release, with patch CR.D
--- 1 ----
! Cleanup Release, with patch CR.E

*** conf/rsetup.mastercopy	Mon Jan  2 16:31:22 1995
--- conf/rsetup	Thu Dec 29 15:39:59 1994
***************
*** 0 ****
--- 1,20 ----
+ # variable setup for regression tests
+ # This one overrides incoming values, which may not be right for testing,
+ # and exports the new values so rconfig will see them and defer to them.
+ #
+ NEWSCTL=`pwd`
+ NEWSBIN=`pwd`
+ NEWSARTS=`pwd`/arts
+ NEWSOV=$NEWSARTS
+ 
+ 
+ 
+ # =()<NEWSPATH=@<NEWSPATH>@>()=
+ NEWSPATH=/bin:/usr/bin:/usr/contrib/bin
+ 
+ 
+ 
+ NEWSUMASK=022
+ NEWSCONFIG=`pwd`/../conf/rconfig
+ LOGNAME=regression
+ export NEWSCTL NEWSBIN NEWSARTS NEWSOV NEWSPATH NEWSUMASK NEWSCONFIG LOGNAME

*** conf/useanswers.mastercopy	Mon Jan  2 16:31:22 1995
--- conf/useanswers	Thu Dec 29 15:47:36 1994
***************
*** 162,168 ****
  	echo "URGENTTO=$newscrisis"
  	echo
  	echo "# things for testing"
! 	echo "HERE=. ../conf/config.r ;"
  	echo
  	echo "# fake files needed"
  	echo "HFAKE=$fakehdrs"
--- 162,168 ----
  	echo "URGENTTO=$newscrisis"
  	echo
  	echo "# things for testing"
! 	echo "HERE=. ../conf/rsetup ;"
  	echo
  	echo "# fake files needed"
  	echo "HFAKE=$fakehdrs"

*** conf/deadfiles.mastercopy	Mon Jan  2 16:31:23 1995
--- conf/deadfiles	Mon Jan  2 16:26:16 1995
***************
*** 1,4 ****
--- 1,9 ----
+ conf/config.r
+ conf/substs
+ conf/libcheck
  doc/flow.old
  expire/mkadir
+ inject/ersh
+ libfake/link.c
  util/queuelen.old
  README.old

*** conf/subst.all.mastercopy	Mon Jan  2 16:31:23 1995
--- conf/subst.all	Thu Dec 29 17:17:31 1994
***************
*** 9,16 ****
  batch/usenntpxmit
  batch/viainews
  conf/config
- conf/config.r
  conf/cron.proto
  contrib/snntp/snntpsend
  ctl/checkgroups
  ctl/delsendsys
--- 9,17 ----
  batch/usenntpxmit
  batch/viainews
  conf/config
  conf/cron.proto
+ conf/rconfig
+ conf/rsetup
  contrib/snntp/snntpsend
  ctl/checkgroups
  ctl/delsendsys
***************
*** 73,78 ****
--- 74,80 ----
  man/newsbatch.8cn
  man/newsctl.5
  man/newsdb.5
+ man/newsflag.8cn
  man/newsmail.8cn
  man/newsmaint.8cn
  man/newsoverview.5

*** conf/makefile.mastercopy	Mon Jan  2 16:31:24 1995
--- conf/makefile	Thu Dec 29 18:26:35 1994
***************
*** 51,58 ****
  	test -d $(NEWSARTS)/$(LASTGROUP) -a -d $(NEWSOV)/$(LASTGROUP) ;
  
  mx:
! 	$(MX) checkfile cmpto config.r cpto inall libcheck libcmp maker
! 	$(MX) mkdirs subst update.*
  
  active.times:	active.eg
  	sed 's/ .*/ 0 unknown/' active.eg >$@
--- 51,58 ----
  	test -d $(NEWSARTS)/$(LASTGROUP) -a -d $(NEWSOV)/$(LASTGROUP) ;
  
  mx:
! 	$(MX) checkfile cmpto cpto inall libcmp maker
! 	$(MX) mkdirs rconfig rsetup subst update.*
  
  active.times:	active.eg
  	sed 's/ .*/ 0 unknown/' active.eg >$@

*** conf/rconfig.mastercopy	Mon Jan  2 16:31:24 1995
--- conf/rconfig	Thu Dec 29 15:40:07 1994
***************
*** 0 ****
--- 1,18 ----
+ # fake configuration for regression tests
+ # should be used only in conjunction with rsetup
+ #
+ NEWSCTL=${NEWSCTL-`pwd`}
+ NEWSBIN=${NEWSBIN-`pwd`}
+ NEWSARTS=${NEWSARTS-`pwd`/arts}
+ NEWSOV=$NEWSARTS
+ 
+ 
+ 
+ # =()<NEWSPATH=${NEWSPATH-@<NEWSPATH>@}>()=
+ NEWSPATH=${NEWSPATH-/bin:/usr/bin:/usr/contrib/bin}
+ 
+ 
+ 
+ NEWSUMASK=${NEWSUMASK-022}
+ NEWSCONFIG=${NEWSCONFIG-`pwd`/../conf/rconfig}
+ LOGNAME=${LOGNAME-regression}

*** doc/problems.mastercopy	Mon Jan  2 16:31:25 1995
--- doc/problems	Tue Dec  6 22:37:18 1994
***************
*** 1106,1109 ****
  .DS
  ftp://ftp.cim.mcgill.ca/pub/people/steve/pc/linux/join
  .DE
! Textutils 1.11 reportedly has fixed this.
--- 1106,1113 ----
  .DS
  ftp://ftp.cim.mcgill.ca/pub/people/steve/pc/linux/join
  .DE
! Textutils 1.11 has fixed this.
! Unfortunately, it has introduced a new and different bug that
! makes the
! .I mergeactive
! regression test fail...

*** expire/upact.mastercopy	Mon Jan  2 17:47:17 1995
--- expire/upact	Mon Jan  2 17:47:57 1995
***************
*** 12,28 ****
  umask $NEWSUMASK
  
  maxlen=200			# max length for shell cmd; 200 is pretty safe
- mindirs=2			# minimum # dirs for ls -f
  replace=yes
  what=normal			# update min, make sure max has a 0 on front
  lserr=/dev/null
  for dummy
  do
  	case "$1" in
  	-b)	what=both	;;	# update both max and min
  	-p)	what=plain	;;	# don't do ANYTHING to max
! 	-s)	maxlen=0 ; mindirs=1	;;	# ls is funny, do slow way
  	'-#')	replace=no ; lserr=$NEWSCTL/active.errs	;;	# debugging
  	--)	shift ; break	;;
  	-*)	echo "$0: unknown option \`$1'" >&2 ; exit 2	;;
  	*)	break		;;
--- 12,29 ----
  umask $NEWSUMASK
  
  maxlen=200			# max length for shell cmd; 200 is pretty safe
  replace=yes
  what=normal			# update min, make sure max has a 0 on front
  lserr=/dev/null
+ interpose=
  for dummy
  do
  	case "$1" in
  	-b)	what=both	;;	# update both max and min
  	-p)	what=plain	;;	# don't do ANYTHING to max
! 	-s)	maxlen=0	;;	# ls is funny, do slow way
  	'-#')	replace=no ; lserr=$NEWSCTL/active.errs	;;	# debugging
+ 	-I)	interpose="$2" ; shift ;;	# interpose pgm for testing
  	--)	shift ; break	;;
  	-*)	echo "$0: unknown option \`$1'" >&2 ; exit 2	;;
  	*)	break		;;
***************
*** 32,49 ****
  
  cd $NEWSCTL
  
  # check out the active file
! checkactive -n -q >active.eek
  if test -s active.eek
  then
  	echo "$0: problems in active file -- aborting" >&2
  	cat active.eek >&2
! 	rm -f active.eek
! 	exit 1
! fi
! if test " `awk '{print $1}' active | sort | uniq -d`" != " "
! then
! 	echo "$0: duplicate newsgroups in active file, unable to run" >&2
  	exit 1
  fi
  
--- 33,53 ----
  
  cd $NEWSCTL
  
+ # lock news system momentarily and grab a copy of the active file
+ lock LOCK $$ || exit 1
+ status=1
+ trap 'unlock LOCK ; trap 0 ; exit $status' 0 1 2 15
+ sort active >active.upact || exit	# sort brings related dirs together
+ trap 0 1 2 15
+ unlock LOCK
+ 
  # check out the active file
! checkactive -n -q active.upact >active.eek
  if test -s active.eek
  then
  	echo "$0: problems in active file -- aborting" >&2
  	cat active.eek >&2
! 	rm -f active.eek active.upact
  	exit 1
  fi
  
***************
*** 52,69 ****
  # rather different from his.  Thanks, Bernd!
  
  # first, find minima, efficiently
! # translate names to dirs, sort to bring related ones together (to exploit
! # any kernel caching), turn dirs into "ls -f" commands, run them, pick
! # the desired data out of the output, turn dirs back into names, and
! # sort for input to join
! tr '.' '/' <active | sort |
  	awk 'BEGIN {
  		maxlen = '"$maxlen"'
- 		mindirs = '"$mindirs"'
  		dirs = ""
  		ndirs = 0
  	}
! 	length($1) + length(dirs) > maxlen && ndirs >= mindirs {
  		if (ndirs == 1)
  			print "echo " substr(dirs, 2) ":"
  		print "ls -f" dirs
--- 56,72 ----
  # rather different from his.  Thanks, Bernd!
  
  # first, find minima, efficiently
! # translate names to dirs, turn dirs into "ls -f" commands, run them, pick
! # the desired data out of the output, turn dirs back into names, sort again,
! # and merge in old-max values
! tr '.' '/' <active.upact |
  	awk 'BEGIN {
  		maxlen = '"$maxlen"'
  		dirs = ""
  		ndirs = 0
+ 		print "cd '"$NEWSARTS"'"
  	}
! 	length($1) + length(dirs) > maxlen && ndirs > 0 {
  		if (ndirs == 1)
  			print "echo " substr(dirs, 2) ":"
  		print "ls -f" dirs
***************
*** 77,83 ****
  			print "echo " substr(dirs, 2) ":"
  		print "ls -f" dirs
  		print "echo /.:"		# simplifies later logic
! 	}' | ( cd $NEWSARTS ; sh 2>$lserr ) |
  	awk -F' ' 'BEGIN {
  		OFMT = "%.12g"
  		big = 99999999999
--- 80,86 ----
  			print "echo " substr(dirs, 2) ":"
  		print "ls -f" dirs
  		print "echo /.:"		# simplifies later logic
! 	}' | sh 2>$lserr |
  	awk -F' ' 'BEGIN {
  		OFMT = "%.12g"
  		big = 99999999999
***************
*** 95,120 ****
  		next
  	}
  	$0 ~ /\/\.:$/ {
! 		if (dir != "" && highest != small)
! 			print dir, highest, lowest
  		dir = substr($0, 1, length($0)-3)	# trim off /.:
  		lowest = big
  		highest = small
! 	}' | tr '/' '.' | sort >active.lows
  
! # lock news system
  lock LOCK $$ || exit 1
  status=1
  trap 'unlock LOCK ; trap 0 ; exit $status' 0 1 2 15
  
! # combine results with active file, carefully
  extra=
  case "$what" in
! both)	extra='$6 != "-" && $6 > $3 {
! 		s = "000000000000000" $6
  		len = length($3)
! 		if (length($6) > len)
! 			len = length($6) + 1
  		s = substr(s, length(s)-len+1)
  		if (s !~ /^0/)
  			s = "0" s
--- 98,136 ----
  		next
  	}
  	$0 ~ /\/\.:$/ {
! 		if (dir != "") {
! 			if (highest != small)
! 				print dir, highest, lowest
! 			else
! 				print dir, "-", "-"
! 		}
  		dir = substr($0, 1, length($0)-3)	# trim off /.:
  		lowest = big
  		highest = small
! 	}' | tr '/' '.' | sort |
! 	join -o 1.1 2.2 1.2 1.3 - active.upact >active.hilow
! # active.hilow now is newsgroup, old max, high file, low file
! 
! # testing hook
! if test " $interpose" != " "
! then
! 	$interpose
! fi
  
! # lock news system again
  lock LOCK $$ || exit 1
  status=1
  trap 'unlock LOCK ; trap 0 ; exit $status' 0 1 2 15
  
! # decide on any extra processing needed
  extra=
  case "$what" in
! both)	extra='$7 != "-" && $7 > $3 {
! 		# update max from high file
! 		s = "000000000000000" $7
  		len = length($3)
! 		if (length($7) > len)
! 			len = length($7) + 1
  		s = substr(s, length(s)-len+1)
  		if (s !~ /^0/)
  			s = "0" s
***************
*** 123,144 ****
  	;;
  normal)	extra='$3 !~ /^0/ { $3 = "0" $3 }'	;;
  esac
  awk '{ print $1, $2, $3, $4, NR }' active | sort |
! 	join -a1 -e - -o 1.5 1.1 1.2 1.3 1.4 2.2 2.3 - active.lows |
  	sort -n |
  	awk 'BEGIN { OFMT = "%.12g" }
  	$1 == "-" { next }		# no longer in active file
  	'"$extra"'
  	{
! 		if ($7 == "-" || $7 == "")
! 			s = $3 + 1
! 		else
! 			s = $7
  		if (length(s) < 5) {
  			s = "00000" s
  			s = substr(s, length(s)-5+1)
  		}
! 		print $2, ($3 ""), s, $5
  	}' >active.tmp
  
  # check that everything looks okay
--- 139,169 ----
  	;;
  normal)	extra='$3 !~ /^0/ { $3 = "0" $3 }'	;;
  esac
+ 
+ # build new active file, cautiously
+ # The result of the join is line number (for the sort -n that restores the
+ # old order of the active file), newsgroup, active max, active min, active
+ # flags, old max, high file, low file.
  awk '{ print $1, $2, $3, $4, NR }' active | sort |
! 	join -a1 -e - -o 1.5 1.1 1.2 1.3 1.4 2.2 2.3 2.4 - active.hilow |
  	sort -n |
  	awk 'BEGIN { OFMT = "%.12g" }
  	$1 == "-" { next }		# no longer in active file
  	'"$extra"'
  	{
! 		# find a new value for min
! 		if ($8 != "-" && $8 != "")	# there was a low file
! 			s = $8			# use it
! 		else if ($6+0 != $3+0)		# oldmax != newmax, race cond!
! 			s = $4			# use old value to be safe
! 		else				# no files and no race
! 			s = $3 + 1		# use max+1
! 
  		if (length(s) < 5) {
  			s = "00000" s
  			s = substr(s, length(s)-5+1)
  		}
! 		print $2, ($3 ""), s, $5	# the "" forces string version
  	}' >active.tmp
  
  # check that everything looks okay
***************
*** 154,161 ****
  	echo "$0: active.tmp is bad (short) -- aborting" >&2
  	exit			# with status=1
  fi
! rm -f active.eek active.lows
  
  case "$replace" in
  no)	status=0 ; exit	;;
  esac
--- 179,187 ----
  	echo "$0: active.tmp is bad (short) -- aborting" >&2
  	exit			# with status=1
  fi
! rm -f active.eek active.hilow active.upact	# clean up temporaries
  
+ # if we weren't asked to install it, don't
  case "$replace" in
  no)	status=0 ; exit	;;
  esac

*** expire/makefile.mastercopy	Mon Jan  2 17:36:16 1995
--- expire/makefile	Mon Jan  2 17:31:17 1995
***************
*** 111,117 ****
  	echo 'mod.unmod 00016 00001 y' >>active
  	echo 'mod.unmod 00016 00016 y' >>active.after
  	echo 'bletch 00099 00001 y' >>active
! 	echo 'bletch 00099 00100 y' >>active.after
  	cat $(AB) >>active
  	cat $(AB) >>active.after
  	echo nevermore >arts/lost+found/1
--- 111,117 ----
  	echo 'mod.unmod 00016 00001 y' >>active
  	echo 'mod.unmod 00016 00016 y' >>active.after
  	echo 'bletch 00099 00001 y' >>active
! 	echo 'bletch 00100 00001 y' >>active.after
  	cat $(AB) >>active
  	cat $(AB) >>active.after
  	echo nevermore >arts/lost+found/1
***************
*** 218,240 ****
  	test -f arch2/bar/99 ;
  	test ! -f arts/urp/99 ;
  	cmp history history.after
  	: "that's it for expire, on to upact"
! 	$(HERE) ./upact $(UPACTOPT) '-#'
! 	cmp active.after active.tmp || diff active.after active.tmp
  	test ! -s active.errs ;
  	mv active.tmp active
  	$(HERE) ./upact $(UPACTOPT)
! 	cmp active.after active || diff active.after active
! 	sed '/^foo /s/103/009/' active.after >active
  	$(HERE) ./upact -b $(UPACTOPT)
! 	cmp active.after active || diff active.after active
  	: "success!"
  
  rclean:
  	rm -f junk history history.pag history.dir history.o active active.tmp
  	rm -f history.n* *mon.out history.proto history.after test.out doit
! 	rm -f active.old active.new explist.reg lint active.after test.stderr
! 	rm -f active.errs explist.regw $(BARFS) canonsys.awk namecheck.awk sys
  	rm -rf arts arch arch2 arch3 bin
  
  clean:	rclean
--- 218,247 ----
  	test -f arch2/bar/99 ;
  	test ! -f arts/urp/99 ;
  	cmp history history.after
+ 	test -s history.dir ;
+ 	test -s history.pag ;
  	: "that's it for expire, on to upact"
! 	echo "sed '/bletch/s/099/100/' active >active.up" >junk
! 	echo "mv active.up active" >>junk
! 	$(MX) junk
! 	$(HERE) ./upact $(UPACTOPT) -I `pwd`/junk '-#'
  	test ! -s active.errs ;
+ 	cmp active.after active.tmp || diff active.after active.tmp
  	mv active.tmp active
+ 	sed '/bletch/s/001 /101 /' active.after >active.after2
  	$(HERE) ./upact $(UPACTOPT)
! 	cmp active.after2 active || diff active.after2 active
! 	sed '/^foo /s/103/009/' active.after2 >active
  	$(HERE) ./upact -b $(UPACTOPT)
! 	cmp active.after2 active || diff active.after2 active
  	: "success!"
  
  rclean:
  	rm -f junk history history.pag history.dir history.o active active.tmp
  	rm -f history.n* *mon.out history.proto history.after test.out doit
! 	rm -f active.old active.new explist.reg lint active.after* test.stderr
! 	rm -f active.errs explist.regw $(BARFS)
! 	rm -f canonsys.awk namecheck.awk sys L*
  	rm -rf arts arch arch2 arch3 bin
  
  clean:	rclean

*** inject/defaults.c.mastercopy	Mon Jan  2 16:31:27 1995
--- inject/defaults.c	Thu Dec 29 21:59:56 1994
***************
*** 32,37 ****
--- 32,40 ----
  int usggcos;			/* strictly speaking, "BTL RJE format" */
  time_t now;
  long pid;
+ char *server = NULL;
+ char *client = NULL;
+ size_t ntrimmed = 0;		/* number of chars trimmed off client */
  
  /*
   * main - parse arguments and handle options
***************
*** 44,50 ****
  
  	if (argc > 0)
  		progname = argv[0];
! 	while ((c = getopt(argc, argv, "dp:t:u")) != EOF)
  		switch (c) {
  		case 'd':
  			++debug;
--- 47,53 ----
  
  	if (argc > 0)
  		progname = argv[0];
! 	while ((c = getopt(argc, argv, "dp:t:c:s:u")) != EOF)
  		switch (c) {
  		case 'd':
  			++debug;
***************
*** 55,60 ****
--- 58,69 ----
  		case 't':
  			now = atol(optarg);
  			break;
+ 		case 'c':
+ 			client = optarg;
+ 			break;
+ 		case 's':
+ 			server = optarg;
+ 			break;
  		case 'u':
  			usggcos++;
  			break;
***************
*** 68,77 ****
--- 77,113 ----
  		exit(2);
  	}
  
+ 	if (client != NULL && server != NULL)
+ 		trimclient();
  	getdefaults();
  	exit(0);
  }
  
+ /*
+  - trimclient - null out (in client) common suffix of client and server
+  * length of suffix left in ntrimmed
+  */
+ trimclient()
+ {
+ 	register size_t clen = strlen(client);
+ 	register char *c = client + clen;
+ 	register char *s = server + strlen(server);
+ 
+ 	for (; *c == *s && c > client && s > server; c--, s--)
+ 		continue;
+ 	if (*c != *s)
+ 		c++;		/* c -> last identical char */
+ 	else if (c > client && s == server && *(c-1) == '.')
+ 		c--;		/* server name considered to have . on front */
+ 	if (c > client && *(c-1) == '.') {
+ 		/* must not end with . */
+ 		while (*(c-1) == '.' && *c != '\0')
+ 			c++;
+ 	}
+ 	*c = '\0';
+ 	ntrimmed = clen - (c - client);
+ }
+ 
  getdefaults()
  {
  	register char *name, *domainsuf, *org;
***************
*** 97,102 ****
--- 133,146 ----
  	intcode(now == 0? time(&now): now);
  	(void) putchar('.');
  	intcode((time_t)(pid == 0? getpid(): pid));
+ 	if (client != NULL) {
+ 		(void) putchar('.');
+ 		intcode((time_t)ntrimmed);
+ 		if (*client != '\0') {
+ 			(void) putchar('.');
+ 			(void) fputs(client, stdout);
+ 		}
+ 	}
  	(void) fputs(domainsuf, stdout);
  	(void) putchar('>');

*** inject/pnews.mastercopy	Mon Jan  2 16:31:27 1995
--- inject/pnews	Thu Dec 29 21:36:12 1994
***************
*** 39,59 ****
  if tear $prefix &&	# output in $inhdrs and $inbody ** takes 0.4 seconds
  	canonhdr -dm <$inhdrs >$hdrs	# dredge up defaults ** takes 0.1 secs
  then
! 	# get time & pid from the server
! 	server="` cat $NEWSCTL/server 2>/dev/null `"
! 	case "$server" in
! 	"")	me="$server" ;;		# if no server file, assume this is it
! 	*)	me="` hostname `"	;;
! 	esac
! 	case "$me" in
! 	$server) args= ;;
! 	*)	args="`
! 			(echo PATH=$PATH
! 			 echo 'echo -p $$ -t'
! 			 echo now) |
! 				ersh $server /bin/sh
! 		`" ;;
! 	esac
  
  	# POLICY: msgid format; usg gcos?
  	# tailor: add -u for USG GCOS fields
--- 39,56 ----
  if tear $prefix &&	# output in $inhdrs and $inbody ** takes 0.4 seconds
  	canonhdr -dm <$inhdrs >$hdrs	# dredge up defaults ** takes 0.1 secs
  then
! 	# are we a client of a server?
! 	if test -r $NEWSCTL/server
! 	then
! 		svr="`cat $NEWSCTL/server`"
! 		me="`hostname`"
! 		case "$me" in
! 		$svr)	args=				;;
! 		*)	args="-c $me -s $server"	;;
! 		esac
! 	else
! 		args=
! 	fi
  
  	# POLICY: msgid format; usg gcos?
  	# tailor: add -u for USG GCOS fields

*** input/makefile.mastercopy	Mon Jan  2 16:31:28 1995
--- input/makefile	Wed Dec 28 22:05:54 1994
***************
*** 118,124 ****
  	echo 'echo "$$*" ; cat >&2' >bin/report
  	echo ':' >bin/domkov
  	mkdir decompressors
! 	echo 'sed 1d $$*' >decompressors/dejunk
  	$(MX) bin/* decompressors/*
  	mkdir arts arts/in.coming ;		# but not bad, yet
  
--- 118,124 ----
  	echo 'echo "$$*" ; cat >&2' >bin/report
  	echo ':' >bin/domkov
  	mkdir decompressors
! 	echo 'sed 1d' >decompressors/dejunk
  	$(MX) bin/* decompressors/*
  	mkdir arts arts/in.coming ;		# but not bad, yet

*** libdbz/makefile.mastercopy	Mon Jan  2 16:31:29 1995
--- libdbz/makefile	Tue Dec 13 23:36:24 1994
***************
*** 37,43 ****
  lint:
  	lint $(LINTFLAGS) dbzmain.c dbz.c dbzdbm.c
  
! rdbz tdbz fake byteflip:	$(LIBS)
  
  rdbz.o:	dbz.c
  	cp dbz.c rdbz.c
--- 37,43 ----
  lint:
  	lint $(LINTFLAGS) dbzmain.c dbz.c dbzdbm.c
  
! rdbz tdbz fake byteflip:	$(LIB)
  
  rdbz.o:	dbz.c
  	cp dbz.c rdbz.c

*** maint/histinfo.c.mastercopy	Mon Jan  2 16:31:29 1995
--- maint/histinfo.c	Mon Dec 19 00:46:07 1994
***************
*** 6,11 ****
--- 6,13 ----
  #include <sys/types.h>
  #include <sys/stat.h>		/* for modified time (date received) */
  #include <string.h>
+ #include <errno.h>
+ #include "fixerrno.h"
  #include "config.h"
  #include "fgetfln.h"
  #include "alloc.h"
***************
*** 16,22 ****
  char *progname;
  int debug;
  
- FILE *efopen();
  
  char *spdir;
  int spdirlen;
--- 18,23 ----
***************
*** 56,64 ****
  	
  	while ((inname = fgetline(stdin, (size_t *)NULL)) != NULL)
  		if (strchr(inname, '.') == NULL) {	/* skip dot names */
! 			in = efopen(inname, "r");
! 			process(in, inname);
! 			(void) fclose(in);
  		}
  	exit(0);
  }
--- 57,70 ----
  	
  	while ((inname = fgetline(stdin, (size_t *)NULL)) != NULL)
  		if (strchr(inname, '.') == NULL) {	/* skip dot names */
! 			errno = 0;
! 			in = fopen(inname, "r");
! 			if (in == NULL && errno != ENOENT)
! 				error("cannot open file `%s'", inname);
! 			if (in != NULL) {
! 				process(in, inname);
! 				(void) fclose(in);
! 			}
  		}
  	exit(0);
  }

*** maint/makefile.mastercopy	Mon Jan  2 16:31:30 1995
--- maint/makefile	Sun Jan  1 18:34:23 1995
***************
*** 28,34 ****
  setup:
  
  cmp:	$(ALL)
! 	@$(IN) $(DEST) $(DPROGS)
  	@$(IN) $(UIBIN) $(UI)
  	$(DEST)/checkactive -q
  
--- 28,35 ----
  setup:
  
  cmp:	$(ALL)
! 	@$(IN) $(DEST) $(NORMAL)
! 	@$(IN) -i $(DEST) $(CUSTOM)
  	@$(IN) $(UIBIN) $(UI)
  	$(DEST)/checkactive -q

*** man/newsflag.8cn.mastercopy	Mon Jan  2 16:31:31 1995
--- man/newsflag.8cn	Tue Dec 13 13:47:17 1994
***************
*** 0 ****
--- 1,46 ----
+ .\" =()<.ds a @<NEWSARTS>@>()=
+ .ds a /var/news
+ .\" =()<.ds b @<NEWSBIN>@>()=
+ .ds b /usr/libexec/news
+ .\" =()<.ds c @<NEWSCTL>@>()=
+ .ds c /etc/news
+ .\"
+ .\"
+ .\"
+ .TH NEWSFLAG 8CN "13 Dec 1994"
+ .BY "C News"
+ .SH NAME
+ newsflag \- change active-file flag for newsgroup
+ .SH SYNOPSIS
+ .B \*b/maint/newsflag
+ newsgroup
+ newval
+ .SH DESCRIPTION
+ .I Newsflag
+ sets the fourth field of
+ .IR newsgroup 's
+ entry in the
+ .I active
+ file (see
+ .IR newsdb (5))
+ to
+ .IR newval ,
+ doing proper locking to ensure safe modification of the file.
+ For example, to change newsgroup
+ .I x.y.z
+ from unmoderated to moderated:
+ .PP
+ .RS
+ .nf
+ newsflag x.y.z m
+ .fi
+ .RE
+ .PP
+ The effect is purely local; no control message (to propagate the
+ change to other machines) is sent.
+ .SH FILES
+ \*c/active
+ .SH SEE ALSO
+ newsdb(5)
+ .SH HISTORY
+ Written by Henry Spencer for C News.

*** nov/expovguts.c.mastercopy	Mon Jan  2 16:31:31 1995
--- nov/expovguts.c	Wed Dec 28 18:06:05 1994
***************
*** 60,68 ****
  
  	start = atol(argv[optind+1]);
  	stop = atol(argv[optind]);		/* tentatively */
! 	if (start > stop+1 || start == 0) {
! 		fprintf(stderr, "%s: min (%s) is 0 or exceeds max (%s) + 1\n",
! 				progname, argv[optind+1], argv[optind]);
  		exit(2);
  	}
  	stop += 100;				/* a bit of headroom */
--- 60,75 ----
  
  	start = atol(argv[optind+1]);
  	stop = atol(argv[optind]);		/* tentatively */
! 	if (start == 0) {
! 		fprintf(stderr, "%s: in expiring `%s',\n", progname, inname);
! 		fprintf(stderr, "\tfound problem in active file:  min == 0\n",
! 							argv[optind+1]);
! 		exit(2);
! 	}
! 	if (start > stop+1) {
! 		fprintf(stderr, "%s: in expiring `%s',\n", progname, inname);
! 		fprintf(stderr, "\tfound problem in active file:  min (%s) > max (%s) + 1\n",
! 					argv[optind+1], argv[optind]);
  		exit(2);
  	}
  	stop += 100;				/* a bit of headroom */
***************
*** 126,134 ****
  	}
  
  	if (nbad > 0) {
! 		fprintf(stderr, "%s: in expiring `%s',\n", progname, inname);
! 		fprintf(stderr, "\tfound %d files with numbers < min (%ld)\n",
  								nbad, start);
  	}
  }
  
--- 133,143 ----
  	}
  
  	if (nbad > 0) {
! 		fprintf(stderr, "%s: (warning) in expiring `%s',\n", progname,
! 								inname);
! 		fprintf(stderr, "\tfound %d files with numbers < min (%ld),\n",
  								nbad, start);
+ 		fprintf(stderr, "\tindicating problems with upact\n");
  	}
  }

*** nov/expov.mastercopy	Mon Jan  2 16:31:32 1995
--- nov/expov	Wed Dec 28 18:09:00 1994
***************
*** 46,53 ****
  			echo "	...using fallback code" >&2
  
  			# fallback
! 			# could use one less temporary if certain systems
! 			# didn't have buggy implementations of sort -o
  			sort $o/.overview >$o/.sov
  			ls | egrep '^[0-9]+$' | join -t'	' - $o/.sov |
  							sort -n >$o/.nov
--- 46,53 ----
  			echo "	...using fallback code" >&2
  
  			# fallback
! 			# could use one less temporary if GNU sort didn't
! 			# have bugs in -o
  			sort $o/.overview >$o/.sov
  			ls | egrep '^[0-9]+$' | join -t'	' - $o/.sov |
  							sort -n >$o/.nov

*** util/dostatfs.c.mastercopy	Mon Jan  2 16:31:32 1995
--- util/dostatfs.c	Mon Jan  2 16:07:09 1995
***************
*** 17,35 ****
  #include <sys/mount.h>
  
  /* Second, assorted variations... */
! #ifdef BSD4_4
! #define	UNIT	f_bsize
  #endif
  #ifdef sun
  #include <sys/vfs.h>
  #define	UNIT	f_bsize
  #endif
  #ifdef _AIX
  #include <sys/statfs.h>
  #endif
  #ifdef M_XENIX		/* SCO */
  #include <sys/statfs.h>
  #define	STATFS(fs, result)	statfs(fs, &result, (int)sizeof(result), 0)
  #endif
  
  /* Finally, some defaults to simplify the above. */
--- 17,55 ----
  #include <sys/mount.h>
  
  /* Second, assorted variations... */
! #ifdef linux
! #define	sun	1	/* Linux happens to be the same as Sun for this... */
! #else
! #ifdef __linux__
! #define	sun	1	/* a Linux by any other name... */
! #endif
! #endif
! #ifdef hpux
! #define	sun	1	/* likewise HP */
  #endif
+ #ifdef __FreeBSD__
+ #define	BSD4_4	1	/* and FreeBSD is sort of 4.4 */
+ #endif
+ 
  #ifdef sun
  #include <sys/vfs.h>
  #define	UNIT	f_bsize
  #endif
+ 
  #ifdef _AIX
  #include <sys/statfs.h>
+ #define	UNIT	f_fsize
  #endif
+ 
  #ifdef M_XENIX		/* SCO */
  #include <sys/statfs.h>
  #define	STATFS(fs, result)	statfs(fs, &result, (int)sizeof(result), 0)
+ #define	UNIT	f_fsize
+ #define	f_bavail	f_bfree	/* talk about kludges */
+ #endif
+ 
+ #ifdef BSD4_4
+ #define	UNIT	f_bsize
  #endif
  
  /* Finally, some defaults to simplify the above. */