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.