[comp.sources.unix] v19i083: Cnews production release, Part06/19

rsalz@uunet.uu.net (Rich Salz) (06/27/89)

Submitted-by: utzoo!henry
Posting-number: Volume 19, Issue 83
Archive-name: cnews2/part06

: ---CUT HERE---
echo 'contrib/nntpmail/mailing_lists/distribute':
sed 's/^X//' >'contrib/nntpmail/mailing_lists/distribute' <<'!'
X#!/bin/sh
X#
X# $Header: distribute,v 1.18 88/09/18 22:26:23 lamy Exp $
X#
X# Distribute stdin (presumed to be a digest or direct-mail article from
X# a mailing list) according to the following flags
X#
X# -n newsgroup		post article to specified newsgroup.
X# -a file		append to the file specified.
X# -m people		remail to people, people may be a filename
X#			in which case the contents will be assumed
X#			to be a list of recipients, one to a line.
X#			note that in the case of a file all recipients
X#			will appear on the headers, and therefore
X#			an alias is best used for large lists.
X# -d directory		store into a file named by volume and
X#			issue under "directory".  Useful for digests.
X# -am name		shorthand for '-a name -m /local/share/mail/lists/name'
X# -dm name		shorthand for '-d name -m /local/share/mail/lists/name'
X#
X# Notes:
X# - When using -a or -m alone, a full path is required, which does differ
X#   with what -am and -dm expect (the name of the mailing list only).
X# - If invoked from sendmail, all arguments will be lowercase only!
X#
X# Rayan Zachariassen - rayan@ai.toronto.edu
X# touch-ups by Jean-Francois Lamy - lamy@ai.toronto.edu
X
X#exec 2>&1
X#set -x
Xumask 022
X
XUSAGE='distribute [-n newsgroup] [-a archivefile] [-d archivedir] [-m mailto]'
X
X# could be the same site, though not necessarily
Xthissite=`domainname`.toronto.edu
Xnewsserver=jarvis.csri.toronto.edu
X
X# we keep the archives under our anonymous FTP directory so other people
X# can get at them.
Xarchdir=/local/ftp
Xcd $archdir
X
X# this person receives bounces and such like.  Make it an alias as it
X# will appear on the sender: line of messages.
Xadmin=list-admin
X
XPEOPLE=/local/share/mail/lists
XLOG=/var/log/distribute
X
XMail=/usr/ucb/Mail
Xsendmail=/usr/lib/sendmail
Xcat=/bin/cat
Xrm=/bin/rm
X# This program should be suid daemon, so that sensitive files can be
X# protected.
Xblankcat=/local/lib/mail/bin/appendfile
X
X#
X# Parse arguments
X#
XARTICLE=/tmp/dist$$
Xnewsgroup=""
Xfile=""
Xdirectory=""
Xmailto=""
Xcase $# in
X0|1)	echo Usage: $USAGE
X	exit 1 ;;
Xesac
Xstate=x
Xfor i in $@
Xdo
X	case "$i" in
X	-*)	state=$i ;;
X	*)	case $state in
X		-n)	newsgroup="$i"
X			distribution="`expr $newsgroup : '\([a-z]*\)\.*'`"
X			;;
X		-n*)	newsgroup="$i"
X			distribution="`expr $state : '-n\(.*\)'`"
X			;;
X		-a)	file="$i" ;;
X		-d)	directory="$i" ;;
X		-m)	mailto="$i" ;;
X		-am)	file="$i"
X			mailto="$PEOPLE/$i" ;;
X		-dm)	directory="$i"
X			mailto="$PEOPLE/$i" ;;
X		x)	echo Usage: $USAGE
X			exit 2 ;;
X		esac
X		state=x ;;
X	esac
Xdone
X#
Xcase "${newsgroup}${file}${directory}${mailto}" in
X?*)	$cat - > $ARTICLE ;;
X*)	exec $Mail -s "No options to /local/lib/mail/distribute" rayan
X	exec /bin/mail rayan
X	exit 4 ;;
Xesac
Xcase $file in
X?*)	$blankcat -lists/${file} $ARTICLE ;;
Xesac
Xcase $directory in
X?*)	eval `/usr/ucb/head -40 $ARTICLE \
X	| /usr/bin/fgrep -i digest \
X	| /bin/sed -n \
X	-e 's/.*Vol[^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\)[^0-9]*/VOL=\1 NUM=\2/p'`
X	$blankcat "-$directory/V${VOL}.${NUM}" $ARTICLE ;;
X*)	directory="$archdir" ;;
Xesac
X
X# extract return path from article
X/local/bin/ed - $ARTICLE <<EOF
X1s/From \\([^ ]*\\) .*/\\1/
X1w $ARTICLE.from
X1d
Xw
Xq
XEOF
X
X# forwarding via mail
Xif [ -s $ARTICLE.from ]; then
X	path="`cat $ARTICLE.from`"
X	case $mailto in
X	*/*)	( cd $directory ;
X		if [ -s $mailto ]; then
X			$sendmail -f $path `cat $mailto` < $ARTICLE
X		fi
X		)
X		;;
X	?*)	$sendmail -f $path $mailto < $ARTICLE
X		;;
X	esac
Xelse
X	path="$newsserver!news"
Xfi
X
X# forwarding to newsgroups
Xcase $newsgroup in
X?*)	case $path in
X	*!*!*)	path="`expr $path : '.*!\([^!]*![^!]*\)$'`"
X		case $path in
X		*.*!*)	;;
X		*)	path="`echo $path | sed 's/!/.uucp&/'`" ;;
X		esac ;;
X	*!*)	;;
X	*)	path="`hostname`.toronto.edu!$path" 
X	esac
X# All this does is massage the headers so they look like what news
X# software expects.  To:, Cc: and Resent-*: headers are masked.
X# Reply-To: is turned into references, which is questionable (could
X# just as well be dropped.
X#
X# The From: line is rewritten to use the "address (comments)" form
X# instead of "phrase <route>" form our mailer uses.  Also, addresses
X# with no "@domainname" are assumed to originate locally, and so are
X# given a domain.
X#
X# The Sender: field below reflects the address of the person who
X# maintains our mailing lists.  The Approved: field is in a special
X# form, so that we can do bidirectional gatewaying.  Any message
X# in a newsgroup that bears this stamp will not be fed into the
X# matching mailing list.
X	sed -n -e "1{i\\
X		Path: $path
X		}" \
X	    -e ":a
X		/^[Rr]eceived:/b r
X		/^[Tt][Oo]:/s/^/Original-/
X		/^[Cc][Cc]:/s/^/Original-/
X		/^[Rr][Ee][Ss][Ee][Nn][Tt]-.*/s/^/Original-/
X		s/^[Ii]n-[Rr]eply-[Tt]o:/References:/
X		/^From:/{
X			s/<\([^@]*\)>\$/<\1@$thissite>/
X			s/^From:[ 	][	]*\(.*\)  *<\(.*\)>\$/From: \2 (\1)/
X			}
X		s/-[Ii]d:/-ID:/
X		s/^\([^:]*:\)[	 ]*/\1 /
X		/^\$/{i\\
X			Newsgroups: $newsgroup\\
X			Distribution: $distribution\\
X			Sender: $admin@$thissite\\
X			Approved: $newsgroup@mail.ai.toronto.edu
X			b e
X		}
X		p
X		n
X		b a
X		:r
X		s/.*//g
X		n
X		/^[ 	]/b r
X		b a
X		:e
X		p
X		n
X		b e" < $ARTICLE > ${ARTICLE}.news
X# ${ARTICLE}.news is the article to be posted.  Any method could
X# be used to do it, normally invoking "inews" or even "relaynews" 
X# directly would work.  Our setup is peculiar in that the news server
X# is another machine, for historical (hysterical?) reasons.
X# It turns out that invoking nntp on each article puts more load on
X# the news server than making up a fake batch and mailing it to them,
X# so we do just that.
X		set - `wc -c ${ARTICLE}.news`
X		(echo "#! rnews $1" ; cat ${ARTICLE}.news) |
X			sed -e 's/^/N/' |
X			$sendmail -f"$admin" recnews@jarvis.csri
X#
X# update the logs
X#
X		messageid=`egrep -i '^message-id:[ 	]' $ARTICLE`
X		messageid=`expr "$messageid" : '..........:[ 	]\(.*\)'`
X		time=`date | awk '{print $2,$3,$4}'`
X		echo $time $newsgroup $messageid >> $LOG
Xesac
X$rm -f $ARTICLE $ARTICLE.from $ARTICLE.news
Xexit 0
!
echo 'contrib/nntpmail/mailing_lists/mailgateway':
sed 's/^X//' >'contrib/nntpmail/mailing_lists/mailgateway' <<'!'
X#!/bin/sh
X#
X# mailgateway recipients
X#
X# bidirectional gatewaying utility.
X#
X# - forward a news article to recipients (typically a single alias in
X#   /usr/lib/aliases or equivalent, to avoid long lists of recipients in 
X#   messages)
X# - filter out news control message.
X# - messages fed to the newsgroup from the mailing list are not sent back.
X#   we assume that "distribute" did the feed, and we look for the tell-tale
X#   "Approved" line it tacks on to messages.
X#
X# Jean-Francois Lamy (lamy@ai.toronto.edu) 88-02-27
X
Xmagic="@mail.ai.toronto.edu"  # what distribute uses in Approved: line
Xmail="/usr/lib/sendmail -t"
Xarticle=/tmp/art$$
X
Xcase $# in
X0) echo "$0: no argument (check /usr/lib/news/sys)" | $mail usenet
X   exit 1 ;;
X*) ;;
Xesac
Xcat >$article
X
Xcheck=`awk '
X   /^Subject: cmsg/		 { print "nope" ; exit }
X   /^Control:/			 { print "nope" ; exit }
X   /^$|^[ ][ \t]*$/		 { exit }
X				 { next }
X   ' $article`
X
Xif [ ! "$check" ] ; then
X   if /bin/grep -s $magic $article ; then
X	   : came from distribute
X   else
X          (
X	   echo "rcvdfrom USENET"  # zmailer feature, delete for sendmail.
X	   echo "To: $@"
X	   cat $article ) | $mail
X   fi
Xfi
X/bin/rm -f $article
!
echo 'contrib/nntpmail/mailing_lists/moderate':
sed 's/^X//' >'contrib/nntpmail/mailing_lists/moderate' <<'!'
X#!/bin/sh
X# moderate owner distribution-alias
X#
X# ensure message gets redistributed to a distribution list alias yet
X# error messages come back to the list owner.  This requires invoking
X# the mailer again.
X#
X# A mailing list is then set-up by adding aliases as follows: (articles are
X# mailed to example, administrivia to example-request, error messages go back
X# to example-owner, and the list of recipients is example-people).
X#
X# example: "|/local/lib/mail/bin/moderate example-owner example-people"
X# example-request: lamy
X# example-owner: lamy
X# example-people: ":include:/local/share/mail/lists/example"
X#
X# note that your sendmail may not want the " around the :include, but
X# that zmailer does in the name of RFC-822...
X
Xowner=$1;shift
Xrecipients=$@
Xcat > /tmp/$owner$$
X/bin/ed - /tmp/$owner$$ <<EOF 2>/dev/null
X1d
X/^[Ff][Rr][Oo][Mm]:/t0
X/^\$/i
XResent-From: $owner
XResent-To: $recipients
X.
X1m.
Xs/^From:/Resent-Reply-To:/
Xs/:	*/: /
Xw
Xq
XEOF
X
X/usr/lib/sendmail -t -f$owner  < /tmp/$owner$$
X/bin/rm -f /tmp/$owner$$
!
echo 'contrib/nntpmail/nntp_support/README':
sed 's/^X//' >'contrib/nntpmail/nntp_support/README' <<'!'
XThis directory contains C news support for posting news via NNTP.
X
Xfrontend_inews	parse options, invokes $NEWSBIN/nntp/inews to
X		send the article to the remote NNTP server.
X
X$NEWSBIN/nntp/inews
X		not included here, you can get the NNTP distribution
X		from UCSD.EDU and apply the patches found on
X		bcm.tmc.edu.  This is the C program that sends	
X		the article to a remote server
X
Xserver_inews	if you run an NNTP server, it should call this as its
X		inews (fix common/conf.h).  figures out moderated newsgroups
X		and all that.
X
X	        To repeat: make sure the nntp server invokes server_inews and
X		not $NEWSBIN/nnpt/news (instant infinite loop!).
!
echo 'contrib/nntpmail/nntp_support/frontend_inews':
sed 's/^X//' >'contrib/nntpmail/nntp_support/frontend_inews' <<'!'
X#! /bin/sh
X# inews [-p] [-debug k] [-x site] [-hMD] [-t subj] [-n ng] [-e exp] [-F ref] \
X#  [-d dist] [-a mod] [-f from] [-o org] [-C ng] [file...] - inject news:
X#	censor locally-posted article and field the "inews -C" kludge;
X#	munge the articles, enforce bogus and pathetic attempts at
X#	Usenet security, generate lotsa silly headers.
X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
X. ${NEWSCONFIG-/news/bin/config}
Xexport NEWSCTL NEWSBIN NEWSARTS NEWSPATH NEWSUMASK NEWSMASTER NEWSCONFIG
XPATH=$NEWSCTL/bin:$NEWSBIN/inject:$NEWSBIN/relay:$NEWSBIN:$NEWSPATH; export PATH
XPASSEDFROM='';	export PASSEDFROM	# passed to anne.jones in environ.
X
Xdebug=''			# flags
Xexclusion=''
Xhdrspresent=no
Xautopost=no
Xwaitcmd=''
Xrelayopts=-i			# redirect stdout to log
X
Xwhoami=/tmp/in$$who		# just created to determine effective uid
Xinput=/tmp/in$$in		# uncensored input
Xinhdrs=/tmp/in$$hdr		# generated by tear: headers
Xinbody=/tmp/in$$body		# generated by tear: body
Xcensart=/tmp/in$$cens		# censored input
Xnglist=/tmp/in$$ngs		# newsgroups: list
Xmodroute=/tmp/in$$route		# route to moderator's forwarder
Xexitflag=/tmp/in$$exit		# exit status, if present
Xoutfile=/tmp/in$$out		# relaynews stdout
Xgrpok=/tmp/in$$grp		# flag file: groups okay if present
Xrmlist="$inhdrs $inbody $input $censart $nglist $modroute $exitflag $outfile $grpok"
X
Xumask $NEWSUMASK
X
X# "inews -p": invoke rnews
Xcase "$1" in
X-p)
X	shift
X	exec rnews $*		# rnews, bailing out at or near line 1
X	;;
Xesac
X
X# parse arguments: for options, cat headers onto $input; cat files onto $input
X>$input
Xcleanup="test ! -f $HOME/dead.article -o -w $HOME/dead.article &&
X  cat $input >>$HOME/dead.article &&
X  { echo $0: article in $HOME/dead.article >&2; rm -f $rmlist; }; exit 1"
Xtrap "$cleanup" 0 1 2 3 15
Xwhile :
Xdo
X	case $# in
X	0)	break ;;		# arguments exhausted
X	esac
X
X	case "$1" in
X	# peculiar to C news
X	-debug)	shift; debug="$1" ;;
X	-A)	autopost=yes ;;		# wait for free space
X	-V)	relayopts= ;;		# verbose: don't redirect stdout (or stderr)
X	-W)	waitcmd=wait ;;		# wait for completion
X	# useful standard options
X	-h)	hdrspresent=yes ;;
X	-x)	shift; exclusion="-x $1" ;;	# you're welcome, erik (2.11)
X	# silly options supplied by newsreaders
X	-a)	shift; echo "Approved: $1" >>$input ;;
X	-c)	shift; echo "Control: $1" >>$input ;;
X	-d)	shift; echo "Distribution: $1" >>$input ;;
X	-e)	shift; echo "Expires: $1" >>$input ;;
X	-n)	shift; echo "Newsgroups: $1" >>$input ;;
X	-t)	shift; echo "Subject: $1" >>$input ;;	# aka Title:
X	-D)	# obsolete, undocumented: meant "don't check for recordings".
X		# last present in B 2.10.1, invoked by readnews for followups.
X		;;
X	-F)	# undocumented in B 2.10.1, documented in B 2.11.
X		shift; echo "References: $1" >>$input ;;
X	-M)	# this apparently just sets From: to the author of the article
X		# instead of the poster (moderator), by leaving the From: line
X		# alone (under -h); easy to implement.
X		;;
X
X	# pass next options as environment variables to anne.jones
X	-f)	shift; PASSEDFROM="$1" ;;	# complex due to Sender:
X	-o)	shift; ORGANIZATION="$1"; export ORGANIZATION ;;
X
X	-C)	# megakludge-o-rama
X		# first, permit only to super-users
X		>$whoami
X		case "`ls -l $whoami | awk '{print $3}'`" in
X		root)	: a winner ;;
X		*)
X			echo "$0: only super-users may create news groups" >&2
X			exit 1
X			;;
X		esac
X		rm -f $whoami
X
X		inewsopt="$1"		# for use in message body
X		shift			# skip -C to get ng as $1
X
X		cat <<! >>$input	# generate a control message
XNewsgroups: $1
XControl: newgroup $1
XSubject: newgroup $1
XApproved: above-user@above-host
X
XThis article generated by inews $inewsopt $1.
X!
X		;;
X	-*)
X		echo "$0: bad option $1" >&2
X		exit 1
X		;;
X	*)					# is a filename; append file
X		# B 2.11 kludge: assume -h if input starts with headers.
X		# apparently the B 2.11 newsreaders assume this.
X		tear /tmp/in$$ <$1
X		if test -s $inhdrs; then
X			hdrspresent=yes
X		fi
X
X		case "$hdrspresent" in
X		no)	echo "" >>$input; hdrspresent=yes ;;
X		esac
X		# capture incoming news in case relaynews fails
X		if cat $inhdrs $inbody >>$input; then
X			: far out
X		else
X			echo "$0: lost news; cat status $?" >&2
X			exit 1
X		fi
X		fileseen=yes
X		;;
X	esac
X	shift		# pass option or filename (any value was done above)
Xdone
X
X# if no files named, read stdin
Xcase "$fileseen" in
Xyes)	;;
X*)
X	# B 2.11 kludge: assume -h if input starts with headers
X	# apparently the B 2.11 newsreaders assume this.
X	tear /tmp/in$$
X	if test -s $inhdrs; then
X		hdrspresent=yes
X	fi
X
X	case "$hdrspresent" in
X	no)	echo "" >>$input; hdrspresent=yes ;;
X	esac
X	# capture incoming news in case relaynews fails
X	if cat $inhdrs $inbody >>$input; then
X		: far out
X	else
X		echo "$0: lost news; cat status $?" >&2
X		exit 1
X	fi
X	;;
Xesac
Xtrap '' 1 2 15			# ignore signals to avoid losing articles
X
X# run the remainder in the background for the benefit of impatient people
X# who lack a window system
X(
Xtrap "$cleanup" 0
Xtear /tmp/in$$ <$input		# output in $inhdrs and $inbody
X# pad zero-line articles, since old B [ir]news are confused by them
X# and the news readers generate zero-line control messages, alas.
Xif test ! -s $inbody; then
X	(echo '';
X	 echo This article was probably generated by a buggy news reader.) \
X	 >$inbody
Xfi
X
X# deduce which tr we have: v6 or v7
Xcase "`echo B | tr A-Z a-z `" in
Xb)	trversion=v7 ;;
XB)	trversion=v6 ;;			# or System V
Xesac
Xexport trversion
X
X# post with new headers and .signature
X(anne.jones <$inhdrs		# bash headers
X # echo "Lines: `		# sop to msb, just uncomment to use
X # if test -r $HOME/.signature; then
X #	(cat $inbody; echo "-- "; sed 4q $HOME/.signature) | wc -l
X # else
X #	wc -l <$inbody
X # fi
X # `"
X
X # strip invisible chars from body, a la B news
X case "$trversion" in
X v7)	tr -d '\1-\7\13\14\16-\37' ;;
X v6)	tr -d '[\1-\7]\13\14[\16-\37]' ;;
X esac <$inbody
X
X# the NNTP server does this.
X# if test -r $HOME/.signature; then
X#	echo "-- "; sed 4q $HOME/.signature	# glue on first bit of signature
X# fi
X) >$censart
X
X# do the deed...
X
X$NEWSBIN/nntp/inews <$censart
Xstatus=$?
X
Xcase "$status" in
X0)
X	rm -f $rmlist			# far out, it worked: clean up
X	trap 0				# normal exit: cleanup done
X	;;
Xesac
Xexit $status				# trap 0 may cleanup, make dead.article
X) &
X$waitcmd				# wait if -W given
Xtrap 0					# let the background run on unmolested
Xexit
!
echo 'contrib/nntpmail/nntp_support/server_censor':
sed 's/^X//' >'contrib/nntpmail/nntp_support/server_censor' <<'!'
X#! /bin/sh
X# server.censor - censor headers, assuming input is a mail message.
X#               Some details depend on UofT CSRI environment.
X#		Jean-Francois Lamy, 1987-11-02
X#
XPATH=/bin:/usr/bin; export PATH
XNEWSCTL=${NEWSCTL-/usr/lib/news}; export NEWSCTL
XNEWSBIN=${NEWSBIN-/usr/lib/newsbin}; export NEWSBIN
XNEWSARTS=${NEWSARTS-/usr/spool/news}; export NEWSARTS
X
X# pass 0 - dredge up defaults
Xhost="`hostname`.toronto.edu"
Xdefdate="`set \`date\`; echo $1, $3-$2-\`echo $6 | sed 's/^..//'\` $4 $5`"
Xdefmsgid="`set \`date\`; echo \<$6$2$3.\`echo $4 | tr -d :\`.$$@$host\>`"
X
Xsed -e "s/DEFMSGID/$defmsgid/" -e "s/DEFDATE/$defdate/" <<\! >/tmp/aj$$awk 
X
X# pass 1 - note presence | absence of certain headers
X
X# a header keyword: remember it and its value
X/^[^\t ]*:/ { hdrval[$1] = $0; keyword=$1 }
X# a continuation: concatenate this line to the value
X!/^[^\t ]*:/ { hdrval[keyword] = hdrval[keyword] "\n" $0 }
X
XEND {
X	# pass 2 - deduce & omit & emit headers
X	subjname = "Subject:"
X	ctlname = "Control:"
X	ngname = "Newsgroups:"
X	msgidname = "Message-ID:"
X	typoname =  "Message-Id:"
X	pathname = "Path:"
X	datename = "Date:"
X	fromname = "From:"
X	orgname = "Organization:"
X	distrname = "Distribution:"
X
X	# fill in missing headers
X	if (hdrval[typoname] != "") {	# spelling hack
X		hdrval[msgidname] = hdrval[typoname]
X		hdrval[typoname] = ""
X		# fix spelling: Message-Id: -> Message-ID:
X		nf = split(hdrval[msgidname], fields);	# bust up
X		fields[1] = msgidname;		# fix spelling
X		hdrval[msgidname] = fields[1];	# reassemble...
X		for (i = 2; i <= nf; i++)
X			hdrval[msgidname] = hdrval[msgidname] " " fields[i]
X	}
X
X	# We trust From:, Date: and Message-ID: as generated by mailer.
X	# hdrval[datename] = datename " " "DEFDATE" # in case Date: breaks news
X
X	# NNTP POST command may forget to put a message ID...
X	
X	if (hdrval[msgidname] == "")
X		hdrval[msgidname] = msgidname " " "DEFMSGID"
X	
X	# snuff some headers
X	distworld = distrname " world"
X	if (hdrval[distrname] == distworld)
X		hdrval[distrname] = ""
X
X	# turn Subject: cmsg into a proper Control: header.
X	if (substr(hdrval[subjname],1,14) == "Subject: cmsg ")
X		hdrval[ctlname] = ctlname " " substr(hdrval[subjname],15)
X
X	# warn if no Newsgroups:
X	if (hdrval[ngname] == "")
X		print "no newsgroups header!" | "cat >&2"
X
X	# favour Newsgroups: & Control: for benefit of rnews
X	if (hdrval[ngname] != "") {
X		print hdrval[ngname]
X		hdrval[ngname] = ""	# no Newsgroups: to print now
X	}
X	if (hdrval[ctlname] != "") {
X		print hdrval[ctlname]
X		hdrval[ctlname] = ""	# no Control: to print now
X	}
X
X	# B news kludgery: print Path: before From:
X	if (hdrval[pathname] != "") {
X		print hdrval[pathname]
X		hdrval[pathname] = ""	# no Path: to print now
X	}
X	if (hdrval[fromname] != "") {
X		print hdrval[fromname]
X		hdrval[fromname] = ""	# no From: to print now
X	}
X
X	# have pity on readers: put Subject: next
X	if (hdrval[subjname] != "") {
X		print hdrval[subjname]
X		hdrval[subjname] = ""	# no Subject: to print now
X	}
X
X	# print misc. headers in random order, unless they are empty.
X	for (i in hdrval)
X		if (hdrval[i] != "" && hdrval[i] != i " ")
X			print hdrval[i]
X}
X!
Xcat $* | 
Xsed -e 's/^From:[ 	]*\(.*\)  *<\(.*\)>/From: \2 \(\1\)/' \
X    -e '/^Received:/d' \
X    -e '/^To:/d' \
X    -e '/^X-To:/d' \
X    -e '/^Cc:/d' \
X    -e 's/^Original-//' |
Xtr -d '\1-\7\13\14\16-\37' |	# strip invisible chars, a la B news
X	awk -f /tmp/aj$$awk
Xrm -f /tmp/aj$$awk
!
echo 'contrib/nntpmail/nntp_support/server_inews':
sed 's/^X//' >'contrib/nntpmail/nntp_support/server_inews' <<'!'
X#! /bin/sh -
X#
X# server_inews 
X#
X#   Post article read on stdin.  Arguments are ignored. 
X#   Meant to be invoked by an NNTP server or by a sendmail/zmailer alias (e.g.
X#   feednews: "|/news/bin/server_inews" )
X#
X#   We assume that the From: line can be trusted and if a Path: line is not
X#   present we fake one using the mail path so broken users that rely on it
X#   get a reply address that way.
X#
X#   The message is mailed to moderators of moderated newsgroups mentioned on
X#   the Newsgroups: line, unless a proper Approved: line is seen, in which
X#   case we post directly.
X#
X# original code from Geoff Collyer, C news alpha release
X# heavily reworked for CSRI/ANT environment by Jean-Francois Lamy
X#	(lamy@ai.toronto.edu)
X
XNEWSCTL=${NEWSCTL-/usr/lib/news}
XNEWSBIN=${NEWSBIN-/usr/lib/newsbin}
XNEWSARTS=${NEWSARTS-/usr/spool/news}
XPATH=$NEWSCTL:/usr/lib/news:$NEWSBIN:$NEWSBIN/relay:/bin:/usr/bin:/usr/ucb
Xexport PATH
X
Xdebug=''		# flags
Xexclusion=''
X
Xhostname=`hostname`
X
Xinput=/tmp/in$$in      	# uncensored input
Xfrom=/tmp/in$$from      # return path extracted from From_ or Return-Path: line
Xinhdrs=/tmp/in$$hdr	# generated by tear: headers
Xinbody=/tmp/in$$body	# generated by tear: body
Xcensart=/tmp/in$$cens   # article with censored headers
Xnglist=/tmp/in$$ngs     # newsgroups: raw list with commas
Xngfile=/tmp/in$$ngc	# newsgroups, one per line
Xrtefile=/tmp/in$$rte    # route chosen for each moderated newsgroup
Xrmlist="$inhdrs $inbody $input $from\
X        $censart $nglist $ngfile $modfile $rtefile"
X				       
X# articles plainly mailed to moderators
Xsendnews="/usr/lib/sendmail -t"
X
Xumask 2
Xtrap '' 1 2 15         # ignore signals to avoid losing articles
X
X# capture incoming news in case inews fails
X   if cat >>$input; then
X      : got it.
X   else
X      echo "$0: lost news; cat status $?" >&2
X      exit 1
X   fi
X
X
X# We separate the header from the body.
X   >>$inbody; >>$censart
X   awk 'BEGIN			 { inbody = 0 }
X   inbody != 0			 { print $0 >"'$inbody'"; next}
X   inbody == 0 && /^$|^[ ][ \t]*$/ { inbody = 1; print "" >"'$inbody'"; next }
X   inbody == 0			 { print $0 >"'$censart'" ; next }
X   ' $input
X
X# Extract information from From_ or Return-Path line so that we can give it
X# back to the mailer (we want mail to the moderator to look as if it came from
X# the originator himself).  We then mutate it into a Path: header.
X# if there is a Path: header (e.g. if we are invoked from NNTP, we use that.
X   sed -e '1s/^From \([^ ]*\) .*$/Path: \1/' \
X       -e 's/^Return-Path: \([^ ]*\).*$/Path: \1/' \
X       -e '/^Path: /{
X		   s/^Path: \([^ ]*\).*$/\1/
X		   s/.*'$hostname'[^!]*!//
X		   w '$from'
X		   s/^/Path: /
X		   }' \
X       -e '/^[ 	]*$/q'	<$censart >$inhdrs
X
X
X# produce list of newsgroups
X   sed -n '/^Newsgroups:[ ]/{
X      s/^Newsgroups:[ ]*\(.*\)$/\1/p
X      q
X      }' <$inhdrs >$nglist
X
X# control messages are special: newgroup messages belong to inexistent
X# newsgroups (makes sense) and names with .ctl don't appear in the active file
X# either.  We force a trailing .ctl on newsgroup names so that downstream
X# sites can prevent control articles from getting on mail redistributions
X#
X# Remove tabs after : so that the rest of the world accepts our postings.
X   read ng <$nglist
X   if egrep "^Control:|^Subject: cmsg" $inhdrs >/dev/null ; then
X       ( server_censor <$inhdrs |
X	 sed -e '/^Newsgroups:/{
X                  s/.ctl//g
X		  s/,/.ctl,/g
X		  s/$/.ctl/g
X		  }' \
X	      -e 's/^\([^:]*:\)[	 ]*/\1 /'
X	 tr -d '\1-\7\13\14\16-\37' <$inbody
X       ) >$censart
X       relaynews -r <$censart
X       rm $rmlist
X       exit 0
X   fi
X
X# handle non control messages.  Unknown newsgroups are dropped, as per RFC1036
X# Too bad if Pnews, postnews or the Zmailer router did not complain
Xegrep "^(` sed -e 's/\./\\\\./g' \
X	       -e 's/+/\\\\+/g'  \
X               -e 's/,/ |/g'     \
X               -e 's/$/ /' <$nglist`)" \
X   $NEWSCTL/active >$ngfile
Xexec <$ngfile
Xwhile read ng high low flag   # look at next group's active entry
Xdo
X   case "$flag" in
X   n)
X      echo "$0: $ng may not be posted to." >&2
X      echo "$0: message not sent anywhere." >&2
X      exit 64   # sendmail/Zmailer "bad usage" message
X      ;;
X   m)
X      if grep -s '^Approved:[    ]' $inhdrs; then # just post normally
X         approved=1
X	 newsgroups=${newsgroups+$newsgroups,}$ng
X      else # un-Approved: add moderator to list of recipients
X	 # look for route for this group
X	 while read ngpat route
X	 do
X	    # a dreadful B 2.11 hack: backbone|internet == all
X	       case "$ngpat" in
X	       backbone|internet) ngpat="all" ;;
X	       esac
X	    # we assume that mailpath file has proper wildcards at the
X	    # end, i.e. we always exit via this break.
X	       if (echo $ng $route| gngp -a "$ngpat" >/dev/null) ; then
X		     echo $route >$rtefile
X		     break
X	       fi
X	 done <$NEWSCTL/mailpaths
X
X	 # add to list of moderators unless no moderator is found
X	 # (local newsgroups are assumed to have a catch-all pattern
X	 # to provoke errors)
X         route=`cat $rtefile`
X	 if [ "$route" = "error" ] ; then
X	    echo "$0: no moderator found for news group '$ng'" >&2
X	    echo "$0: message not sent anywhere." >&2
X	    exit 64 # bad usage message.
X	 else
X	    modroute=${modroute+$modroute,}$route
X	 fi
X      fi
X      ;;
X   y)
X      newsgroups=${newsgroups+$newsgroups,}$ng
X      ;;
X   esac
Xdone
X
X# $censart is used rather than a pipe to work around a bug in the 4.2
X# sh which makes it sometimes return the wrong exit status
X
Xif [ "$modroute" ] ; then
X   # mail article to the moderator(s)
X   # Remove headers that may break mailers or cause loops.
X   # strip invisible chars from body, a la B news
X      ( sed -e '/^Newsgroups:/d' -e '/^Path:/d' \
X	    -e '/^To:/d' -e '/^Cc:/d' < $inhdrs
X	echo "To: ${modroute}"
X	tr -d '\1-\7\13\14\16-\37' <$inbody
X      ) >$censart
X      $sendnews -f"`cat $from`" <$censart
Xfi
X
Xif [ "$newsgroups" ] ; then
X   # feed article to news.  Put in cleaned-up newsgroups line (no remote
X   # moderated newsgroups appear).  If a local user posts to a newsgroup with
X   # a local moderator then the approved article does not get posted because
X   # the news server is already in the path.  We fix that with a chain-saw,
X   # pending resolution of the bug in the news relaying software...
X   # strip invisible chars from body, a la B news
X      ( server.censor <$inhdrs |
X	sed ${approved+-e} ${approved+"s/^Path:.*$hostname!/Path: /"} \
X	    -e "s/^Newsgroups:.*\$/Newsgroups: $newsgroups/" \
X   	    -e 's/^\([^:]*:\)[	 ]*/\1 /'
X	tr -d '\1-\7\13\14\16-\37' <$inbody
X      ) >$censart
X
X   if relaynews -r <$censart
X   then
X      rm -f $rmlist      # far out, it worked
X      if [ -s $NEWSCTL/dig.twimc ]; then
X	 $NEWSBIN/digestify $NEWSCTL/dig.twimc
X      fi
X      exit 0
X   else
X      status=$?
X      echo "$0: article could not be posted (relaynews status $status)" >&2
X      echo "$0: failed news in `hostname`:$input " >&2
X      exit $status
X   fi
Xelse
X   rm -f $rmlist
X   exit 0
Xfi
!
echo 'contrib/nntpmail/mail_to_group/README':
sed 's/^X//' >'contrib/nntpmail/mail_to_group/README' <<'!'
XPOSTING VIA MAIL
X
XWe wanted our users to be able to mail to the newsgroups, so we wrote a
Xsendmail/zmailer transport agent to support this.  You must edit your
Xmailer configuration file so that mail to a newsgroup gets sent to that
Xuser agent.  The default router.cf distributed with zmailer does that.
X
Xusenet:	      sendmail-compatible transport agent.  Our mailer invokes it on 
X              local names it can find in the active newsgroup file, so the 
X	      message gets posted.  usenet then arranges for a real inews
X	      to get invoked by either
X	      a) calling inews itself
X	      b) pushing the message with NNTP to a news server
X	         (see ../nntp_support)
X	      c) remailing the message to a news server
X	         (inferior to b, but it can be made to work. see
X		 ../fake_nntp_via_mail)
X
XPosting via mail ensures proper return addresses and automagically supports
Xwhatever fancy processing the mailer does (hiding workstation names, producing
XFull.Name@do.ma.in forms, whatever), In fact, we changed our set-up to use a
Xfake inews that mails the article to the newsgroups.
X
Xfrontend_inews
X	      This fake inews parses the arguments and mails to the list
X	      of newsgroups so that the From: and other headers get generated
X	      by a program that really knows what it is doing.  The mailer
X	      will then arrange for injection in the news flow.
X
X	      This inews gets invoked by Pnews et al.  It would traditionally
X	      go in /usr/lib/news/inews.  Make sure that it does not get
X	      invoked by NNTP on a news server, for that would cause a nice
X	      infinite loop.
X
!
echo 'contrib/nntpmail/mail_to_group/ROADMAP':
sed 's/^X//' >'contrib/nntpmail/mail_to_group/ROADMAP' <<'!'
XThe news setup around {ai,theory,na}.toronto.edu looks
Xroughly like this:
X
X      inews (really frontend_inews)
X        |
X        | The article is turned into a mail message by inews.
X	|
X  mail comp.whatever,...
X        |
X        | at this point proper return addresses are on, etc.
X	|
X   usenet transport agent
X	|
X	| NNTP (or mail to feednews@news-server)
X	|
X  news-server.csri
X	|
X        |  NNTP server (if mail to feednews, alias that pipes to server_inews)
X	|
X    server_inews (figures out if group is moderated and so on)
X	|
X 	|
X	|
X     relaynews (actual posting)
!
echo 'contrib/nntpmail/mail_to_group/frontend_inews':
sed 's/^X//' >'contrib/nntpmail/mail_to_group/frontend_inews' <<'!'
X#! /bin/sh
X# inews [-p] [-d k] [-x site] [-hMD] [-t subj] [-n ng] [-e exp] [-F ref] \
X#  [-d dist] [-a mod] [-f from] [-o org] [-C ng] [file...] - inject news:
X#
X# pseudo-inews that posts by mailing the message, so that whatever
X# fancy processing the mailer does to generate a return address
X# takes place.
X#
X# The mailer normally ends up invoking a "usenet" transport agent
X# which would either call a real inews or post via nntp, as appropriate.
X#
X# Checks for moderators and suchlike are assumed to take place when the
X# message is actually posted on the real news server.
X#
X# Jean-Francois Lamy (lamy@ai.toronto.edu) 88-02-11
X
X#NEWSCTL=${NEWSCTL-/usr/lib/news}
X#NEWSBIN=${NEWSBIN-/usr/lib/newsbin}
X#NEWSARTS=${NEWSARTS-/usr/spool/news}
XNEWSCTL=/local/share/news
XNEWSBIN=/local/lib/news
XNEWSARTS=/var/spool/news
XPATH=$NEWSBIN:$NEWSCTL:$NEWSBIN/relay:/bin:/usr/bin:/usr/ucb; export PATH
X
Xallowed=sandra\|rayan\|lamy		# tailor: local news admin (may be "")
Xhdrspresent=no
X
Xwhoami=/tmp/cn$$who		# just created to determine effective uid
Xinput=/tmp/cn$$in		# uncensored input
Xcensart=/tmp/cn$$cens		# censored input
Xrmlist="$input $whoami $censart"
Xegrep=egrep
X
X# figure out where to mail the message.  We mail even if we are on the
X# news server, in order to garantee proper return addresses
X   servaddr=nntp
X
Xumask 2
Xtrap '' 1 2 15			# ignore signals to avoid losing articles
X
X# "inews -p": invoke rnews
Xcase "$1" in
X-p)
X	shift
X	exec rnews $*		# rnews, bailing out at or near line 1
X	;;
Xesac
X
X# parse arguments for options, cat headers onto $input; cat files onto $input
X>$input
Xwhile :
Xdo
X	case $# in
X	0)	break ;;		# arguments exhausted
X	esac
X
X	case "$1" in
X	-debug)	shift; debug="$1" ;;		# peculiar to C news
X	-x)	shift; exclusion="-x $1" ;;	# you're welcome, erik (2.11)
X	-h)	hdrspresent=yes ;;
X	-M)	# TODO: what's this *really* do? dunno, find out
X		;;
X	-D)	# obsolete, undocumented: meant "don't check for recordings".
X		# last present in B 2.10.1, invoked by readnews for followups.
X		;;
X	-t)	shift; echo "Subject: $1" >>$input ;;
X	-n)	shift; echo "Newsgroups: $1" >>$input ;;
X	-e)	shift; echo "Expires: $1" >>$input ;;
X	-F)	# undocumented in B 2.10.1, documented in B 2.11.
X		shift; echo "References: $1" >>$input ;;
X	-d)	shift; echo "Distribution: $1" >>$input ;;
X	-a)	shift; echo "Approved: $1" >>$input ;;
X
X	# pass next options as environment variables to client.censor
X
X	-f)	shift; PASSEDFROM="$1" ;;	# complex due to Sender:
X	-o)	shift; ORGANIZATION="$1"; export ORGANIZATION ;;
X
X	-[cC])
X		# megakludge-o-rama
X		# first, permit only to super-users
X		>$whoami
X		whoever = "`ls -l $whoami | awk '{print $3}'`"
X		case $whoever in
X		root|$allowed)	: a winner ;;
X		*)
X			echo "$0: $1 restricted to super-users " >&2
X			exit 1
X			;;
X		esac
X		rm -f $whoami
X		case "$1" in
X		-C)	cat <<! >>$input		# generate -C header
XNewsgroups: $ng
XSubject: newgroup $2
XControl: newgroup $2
XApproved: $whoever@`hostname`.`domainname`
X
Xcreated by inews -C
X!		 	
X			shift
X			;;
X		-c)	cat <<! >>$input		# generate -c header
XNewsgroups: $ng
XSubject: $2
XControl: $2
XApproved: $whoever@`hostname`.`domainname`
X
Xcreated by inews -c.
X!
X			shift
X			;;
X		esac
X		;;
X	-*)
X		echo "$0: bad option $1" >&2
X		exit 1
X		;;
X	*)
X		case "$hdrspresent" in
X		no)	echo "" >>$input; hdrspresent=yes ;;
X		esac
X		cat "$1" >>$input		# is a filename; append file
X		fileseen=yes
X		;;
X	esac
X	shift		# pass option or filename (any value was done above)
Xdone
X
X# if no files named, read stdin
Xcase "$fileseen" in
Xyes)	;;
X*)
X	case "$hdrspresent" in
X	no)	echo "" >>$input; hdrspresent=yes ;;
X	esac
X	# capture incoming news in case inews fails
X	if cat >>$input; then
X		: far out
X	else
X		echo "$0: lost news; cat returned status $?" >&2
X		exit 1
X	fi
X	;;
Xesac
X
X(
X# trivial censoring, before passing on to mailer.
X# The Newsgroups: line is turned into a To: line.
XORGANIZATION=${ORGANIZATION=`cat ${NEWSCTL}/organi?ation`}
Xawk "BEGIN		{ subject = 0; body = 0; skipping = 0 ;
X			  newsgroups = 0; distribution = 0; organization = 0;
X			}
Xbody == 1		{ print; next }
X/^[A-Za-z-]*:[ ]*$/	{ next }
X/^$|^[ ][ \t]*$/        { if (!body) {
X			    if (!organization) 
X			       print \"Organization: $ORGANIZATION\";
X			    if (!newsgroups) print \"To: $groups\";
X			    if (!subject) print \"Subject: (none)\"; 
X			  }
X			  print; body = 1; next
X			}
X/^Organization:/	{ organization = 1; skipping = 0; print; next }
X/^Newsgroups:/		{ \$1 = \"To:\" ; 
X			  newsgroups = 1; skipping = 0; print; next }
X/^Distribution:/	{ distribution = 1; skipping = 0; print; next }
X/^Subject:/		{ subject = 1; skipping = 0; print; next }
X/^To:|^Cc:|^X-To:/	{ skipping = 1; next }
X/^From |^Return-Path:/	{ skipping = 1; next }
X/^Apparently-To:/	{ skipping = 1; next }
X/^[ 	]/		{ if (skipping) next }
X			{ print }
X" <$input >$censart
Xif test -r $HOME/.signature; then
X   echo "-- " >>$censart
X   sed 5q $HOME/.signature >>$censart	# glue on first bit of signature
Xfi
X
Xif /usr/lib/sendmail -t ${PASSEDFROM+-f"$PASSEDFROM"} <$censart
Xthen
X	rm -f $rmlist		# far out, it worked
X	exit 0
Xelse
X	status=$?
X	echo\
X"$0: could not send article to server; sendmail returned status $status" >&2
X	echo "$0: processed news article can be found in $input" >&2
X	exit $status
Xfi
X) &
!
echo 'contrib/nntpmail/mail_to_group/usenet':
sed 's/^X//' >'contrib/nntpmail/mail_to_group/usenet' <<'!'
X#!/bin/sh
X#
X# usenet newsgroup1 ... newsgroupn
X#
X# sendmail-compatible usenet transport agent.
X#                   Jean-Francois Lamy (lamy@ai.toronto.edu), 89-06-02
X#                   based on code by Rayan Zachariassen.
X#
X# The arguments are the newsgroups to which the article should be posted. A
X# complete message, including To:, From: and From_ line expected on stdin.
X# This assumes of course that the necessary magic has been done so that
X# the mailer recognizes newsgroup name and decides to use the usenet transport
X# agent on them.
X#
X# Notes:
X#
X# - this script should ultimately result in the invocation of a real
X#   "inews" that deals with moderated newsgroups and invokes relaynews.
X#   This version calls nntp, which results in calling a real inews on
X#   the news server.
X#   
X# - The news program invoked by this script should trust From: lines
X#   (otherwise workstation name hiding, full-name id generation and
X#   all other smarts done by the mailer will be lost)
X#
X# - newsgroup "postnews" is ignored, and is used so one can mail
X#   to a postnews alias a message with a Newsgroups: header, with
X#   postnews aliased to postnews@usenet, where usenet is a fake host
X#   handled by this transport agent.
X#
X# - Normally a From_ line of site!user and a From: line of user@site
X#   should be produced. If your sendmail cannot be coerced into rewriting
X#   envelope and headers differently you will need to kludge it here.
X#
X#
X# ZMailer notes:
X#
X# - The default router.cf does the appropriate things, provided that
X#   scheduler.cf contains:
X#	usenet/*	1m	10 0 0	root	daemon	sm -c $channel usenet
X#   sm.cf contains:
X#	usenet	m	/local/lib/mail/bin/usenet	usenet $u
X#      (adjust this to reflect the actual location of the installed copy of
X#       this script, of course)
X#   hosts.transport contains a line with:
X#       usenet usenet!  
X#   and that the aliases file contains aliases of the form
X#       gradnews: gradnews@usenet
X#      for all newsgroup names that don't have embedded ".").
X
X
X# this version forwards the article via NNTP
XNNTPSERVER="jarvis.csri" ; export NNTPSERVER
X# make sure this does not end up calling this script again!
Xinews=/local/lib/news/nntp_inews
X
Xorgflag=0
Xorg="`cat /local/share/news/organi?ation`"
X[ "$org" ] || orgflag=1  # do not print empty Organization: header
X
Xfrom=/tmp/from$$
X
Xfor i in $@
Xdo
X	groups="${groups+$groups,}$i"
Xdone
X
Xawk "BEGIN		{ subject = 0; body = 0; skipping = 0 ;
X			  newsgroups = 0; distribution = 0;
X			  organization = $orgflag; }
Xbody == 1		{ print; next }
X/^$|^[ ][ \\t]*$/	{ if (!body) {
X			    np = split(path,parts,\"!\");
X			    if (!organization && np == 1)
X			        print \"Organization: $org\";
X			    if (!newsgroups) print \"Newsgroups: $groups\";
X			    if (!subject) print \"Subject: (none)\"; 
X			  }
X			  print; body = 1; next
X			}
X/^To:|^X-To:|^Cc:|^Apparently-To:/	{ skipping=1 ; next }
X/^Received:/		{ skipping = 1; next }
X/^Newsgroups:/		{ newsgroups = 1; skipping = 0; printf(\"%s\",\$0);
X		        if (\"$groups\" != \"\" && \"$groups\" != \"postnews\")
X			     printf(\",%s\\n\",\"$groups\");
X			  else printf(\"\\n\");
X			  next }
X/^Organi[sz]ation:/	{ organization = 1; skipping = 0; print; next }
X/^Distribution:/	{ distribution = 1; skipping = 0; print; next }
X/^Subject:/		{ subject = 1; skipping = 0; print; next }
X/^From |^Return-Path:/	{ print \$2 > from ; path = \$2 ; skipping = 1; next }
X/^[ 	]/		{ if (skipping) next }
X/^[A-Za-z-]*:[ \\t]*$/	{ if (!body) next }
X			{ print }
X" from="$from" - >/tmp/usenet.$$-1
X
Xif [ -s $from ]; then
X   (echo -n "Path: "; cat $from ; cat /tmp/usenet.$$-1 ) > /tmp/usenet.$$-2
X   $inews /tmp/usenet.$$-2
Xfi
Xrm $from /tmp/usenet.$$-*
Xexit 0
!
echo 'contrib/rn.mod/cdiff.addng.c':
sed 's/^X//' >'contrib/rn.mod/cdiff.addng.c' <<'!'
X*** addng.old.c	Sat Jun  3 05:56:19 1989
X--- addng.c	Sat Jun  3 05:56:20 1989
X***************
X*** 1,4
X! /* $Header: addng.c,v 1.1 89/06/03 05:29:01 geoff Exp $
X   *
X   *	UW Mods:
X   *		GETNG_YNQ - typing Q gets you out of the newsgroup loop
X
X--- 1,4 -----
X! /* $Header: addng.c,v 1.2 89/06/03 05:35:30 geoff Exp $
X   *
X   *	UW Mods:
X   *		GETNG_YNQ - typing Q gets you out of the newsgroup loop
X***************
X*** 3,10
X   *	UW Mods:
X   *		GETNG_YNQ - typing Q gets you out of the newsgroup loop
X   * $Log:	addng.c,v $
X!  * Revision 1.1  89/06/03  05:29:01  geoff
X!  * Initial revision
X   * 
X   * Revision 1.3  87/09/10  19:39:47  sahayman
X   * newlist for SERVER now asks for all groups from the dawn of time
X
X--- 3,10 -----
X   *	UW Mods:
X   *		GETNG_YNQ - typing Q gets you out of the newsgroup loop
X   * $Log:	addng.c,v $
X!  * Revision 1.2  89/06/03  05:35:30  geoff
X!  * nuke a useless stat.
X   * 
X   * Revision 1.3  87/09/10  19:39:47  sahayman
X   * newlist for SERVER now asks for all groups from the dawn of time
X***************
X*** 183,189
X  char *ngnam;
X  ART_NUM ngsize;
X  {
X-     char tst[128];
X      long time();
X   
X      sprintf(tst, ngsize ? "%s/%s/1" : "%s/%s" ,spool,getngdir(ngnam));
X
X--- 183,188 -----
X  char *ngnam;
X  ART_NUM ngsize;
X  {
X      long time();
X   
X      /*
X***************
X*** 186,192
X      char tst[128];
X      long time();
X   
X-     sprintf(tst, ngsize ? "%s/%s/1" : "%s/%s" ,spool,getngdir(ngnam));
X      /*
X       * After a long oddyssey of changes, we have
X       * restored the patch 19 behaviour here.
X
X--- 185,190 -----
X  {
X      long time();
X   
X      /*
X       * After a long oddyssey of changes, we have
X       * restored the patch 19 behaviour here.
X***************
X*** 192,197
X       * restored the patch 19 behaviour here.
X       * This gives the minimum number of wrong answers.
X       * ..sah 87/07/29
X       */
X  
X      if (stat(tst,&filestat) < 0)
X
X--- 190,197 -----
X       * restored the patch 19 behaviour here.
X       * This gives the minimum number of wrong answers.
X       * ..sah 87/07/29
X+      * Bzzt!  Wrong!  Article 1 will always be long gone; nuke da stat(2).
X+      * - geoff
X       */
X      /* not there, assume something good */
X      return (ngsize ? 0L : time(Null(long *)));
X***************
X*** 193,204
X       * This gives the minimum number of wrong answers.
X       * ..sah 87/07/29
X       */
X! 
X!     if (stat(tst,&filestat) < 0)
X! 	return (ngsize ? 0L : time(Null(long *)));
X! 	/* not there, assume something good */
X!     else
X! 	return filestat.st_mtime;
X  }
X  
X  bool
X
X--- 193,200 -----
X       * Bzzt!  Wrong!  Article 1 will always be long gone; nuke da stat(2).
X       * - geoff
X       */
X!     /* not there, assume something good */
X!     return (ngsize ? 0L : time(Null(long *)));
X  }
X  
X  bool
X
X
X
!
echo 'contrib/rn.mod/README':
sed 's/^X//' >'contrib/rn.mod/README' <<'!'
XThe cdiff.* files contain a pair of rn speedups, relative to rn
Xpatchlevel 40 as modified by U of Waterloo: they remove some expensive
Xstat system calls.  The base U of Waterloo rn contains two other handy
Xchanges:  a -q which disables the interrogation when the active file
Xchanges, and a third answer during the interrogation: "q" means "I
Xdon't care, just show me some news, right now".
X
XThe changes to ngdata.c prevent rn stating every file under
X/usr/spool/news that might contain an article before opening it.
X
XThe changes to addng.c prevent rn stating all ~700 directories under
X/usr/spool/news every time the active file changes (this is known as
X"the rn huddle").  In the one timing trial we did, this reduced start
Xup time after touching active from 56 seconds elapsed on a Sun 3 to 8
Xseconds.  Before making these changes, longer huddles in the range of
X10 to 15 minutes were observed on Sun 3s and 4s, perhaps because the
Xactive file was touched in a different spot.
X
XUnfortunately the new addng.c code means that you will get an even
Xlonger interrogation after the shorter huddle than you previously
Xwould, as many groups will be spuriously considered "new".  If you have
X-q available, you can keep up with new groups by just reading the
X"control" pseudo-group with "ihave", "sendme" and "cancel" in your
Xcontrol kill file.
X
XThe theory behind the 700 stats in the newgroup huddle was apparently
Xthat if rn stats group/1, and it exists, then group must be a
Xnewly-created group.  There's gotta be a better way.  With rapid
Xexpiry, group/1 won't be around for long in most groups, causing rn to
Xmiss some new groups, and in "valuable" groups with long expiry times,
Xgroup/1 will be around for a very long time, making rn spuriously think
Xthat the old groups are new.  Proper fixes for this problem involve
Xreworking rn's strategy for determining new newsgroups completely,
Xusing the "active.times" file.  The file "better.way" is an attempt
Xto do exactly that.
!
echo 'contrib/rn.mod/cdiff.ngdata.c':
sed 's/^X//' >'contrib/rn.mod/cdiff.ngdata.c' <<'!'
X*** ngdata.old.c	Sat Jun  3 05:56:22 1989
X--- ngdata.c	Sat Jun  3 05:56:22 1989
X***************
X*** 1,4
X! /* $Header: ngdata.c,v 1.1 89/06/03 05:44:45 geoff Exp $
X   *
X   * Modified to work with NNTP server.  -- Phil Lapsley
X   * $Log:	ngdata.c,v $
X
X--- 1,4 -----
X! /* $Header: ngdata.c,v 1.2 89/06/03 05:55:42 geoff Exp $
X   *
X   * Modified to work with NNTP server.  -- Phil Lapsley
X   * $Log:	ngdata.c,v $
X***************
X*** 2,9
X   *
X   * Modified to work with NNTP server.  -- Phil Lapsley
X   * $Log:	ngdata.c,v $
X!  * Revision 1.1  89/06/03  05:44:45  geoff
X!  * Initial revision
X   * 
X   * Revision 1.2  87/07/29  14:28:38  sahayman
X   * SERVER changes merged in
X
X--- 2,9 -----
X   *
X   * Modified to work with NNTP server.  -- Phil Lapsley
X   * $Log:	ngdata.c,v $
X!  * Revision 1.2  89/06/03  05:55:42  geoff
X!  * nuke da stats
X   * 
X   * Revision 1.2  87/07/29  14:28:38  sahayman
X   * SERVER changes merged in
X***************
X*** 240,246
X      register ART_NUM min = 1000000;
X      register ART_NUM maybe;
X      register char *p;
X-     char tmpbuf[128];
X      
X      dirp = opendir(dirname);
X      if (!dirp)
X
X--- 240,245 -----
X      register ART_NUM min = 1000000;
X      register ART_NUM maybe;
X      register char *p;
X      
X      dirp = opendir(dirname);
X      if (!dirp)
X***************
X*** 250,263
X  	    for (p = dp->d_name; *p; p++)
X  		if (!isdigit(*p))
X  		    goto nope;
X! 	    if (*dirname == '.' && !dirname[1])
X! 		stat(dp->d_name, &filestat);
X! 	    else {
X! 		sprintf(tmpbuf,"%s/%s",dirname,dp->d_name);
X! 		stat(tmpbuf, &filestat);
X! 	    }
X! 	    if (! (filestat.st_mode & S_IFDIR))
X! 		min = maybe;
X  	}
X        nope:
X  	;
X
X--- 249,264 -----
X  	    for (p = dp->d_name; *p; p++)
X  		if (!isdigit(*p))
X  		    goto nope;
X! 	    /*
X! 	     * dp->d_name is all-numeric.  anyone dopey enough to create
X! 	     * an all-numeric component of a newsgroup name should be chopped
X! 	     * into tiny bits and the bits should be jumped on.  even given
X! 	     * such dopes, rn should not attempt to read a directory later on,
X! 	     * and it wouldn't be the end of the world if it did anyway.
X! 	     * so i'll take the miniscule risk in return for getting to
X! 	     * NUKE DA stat(2)s! - geoff
X! 	     */
X! 	    min = maybe;
X  	}
X        nope:
X  	;
X***************
X*** 265,268
X      closedir(dirp);
X      return min==1000000 ? 0 : min;
X  }
X- 
X
X--- 266,268 -----
X      closedir(dirp);
X      return min==1000000 ? 0 : min;
X  }
X
!
echo done


-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.