home *** CD-ROM | disk | FTP | other *** search
- : /bin/sh
- # inews [-p] [-debug k] [-x site] [-hMD] [-t subj] [-n ng] [-e exp] [-F ref] \
- # [-d dist] [-a mod] [-f from] [-o org] [-C ng] [file...] - inject news:
- # censor locally-posted article and field the "inews -C" kludge;
- # munge the articles, enforce feeble attempts at Usenet security,
- # generate lots of silly headers.
- #
- # Yes, it's big, slow and awkward. The alternative is casting a lot of
- # local policy in C.
-
- # =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
- . ${NEWSCONFIG-/usr/lib/news/bin/config}
- export NEWSCTL NEWSBIN NEWSARTS NEWSPATH NEWSUMASK NEWSMASTER NEWSCONFIG
- PATH=$NEWSCTL/bin:$NEWSBIN/inject:$NEWSBIN/relay:$NEWSBIN:$NEWSPATH; export PATH
- PASSEDFROM=''; export PASSEDFROM # passed to anne.jones in environ.
-
- debug='' # flags
- exclusion=''
- hdrspresent=no
- autopost=no
- waitcmd='status=0'
- relayopts=-i # redirect stdout to log
-
- input=/tmp/in$$in # uncensored input
- inhdrs=/tmp/in$$hdr # generated by tear: headers
- inbody=/tmp/in$$body # generated by tear: body
- censart=/tmp/in$$cens # censored input
- nglist=/tmp/in$$ngs # newsgroups: list
- modroute=/tmp/in$$route # route to moderator's forwarder
- exitflag=/tmp/in$$exit # exit status, if present
- outfile=/tmp/in$$out # relaynews stdout
- rmlist="$inhdrs $inbody $input $censart $nglist $modroute $exitflag $outfile"
- grpok=/tmp/in$$grp # flag file: groups okay if present
-
- # cluther addition
- nosig=no
-
- umask $NEWSUMASK
-
- # "inews -p": invoke rnews
- case "$1" in
- -p)
- shift
- cat $* | relaynews -r # feed directly to relaynews, seat belts off
- exit
- ;;
- esac
-
- # process arguments: for options, cat headers onto $input; cat files onto $input
- >$input
- cleanup="test ! -f $HOME/dead.article -o -w $HOME/dead.article &&
- cat $input >>$HOME/dead.article &&
- { echo $0: article in $HOME/dead.article >&2; rm -f $rmlist; }; exit 1"
- trap "$cleanup" 0 1 2 3 15
- while :
- do
- case $# in
- 0) break ;; # arguments exhausted
- esac
-
- case "$1" in
- # peculiar to C news
- -z) shift; nosig=yes;;
- -debug) shift; debug="$1" ;;
- -A) autopost=yes ;; # wait for free space
- -V) relayopts= ;; # verbose: don't redirect stdout (or stderr)
- -W) waitcmd='wait; status=$?' ;; # wait for completion
- # useful standard options
- -h) hdrspresent=yes ;;
- -x) shift; exclusion="-x $1" ;; # you're welcome, erik (2.11)
- # silly options supplied by newsreaders
- -a) shift; echo "Approved: $1" >>$input ;;
- -c) shift; echo "Control: $1" >>$input ;;
- -d) shift; echo "Distribution: $1" >>$input ;;
- -e) shift; echo "Expires: $1" >>$input ;;
- -f) shift; echo "From: $1" >>$input ;;
- -n) shift; echo "Newsgroups: $1" >>$input ;;
- -r) shift; echo "Reply-To: $1" >>$input ;;
- -t) shift; echo "Subject: $1" >>$input ;; # aka Title:
- -D) # obsolete, undocumented: meant "don't check for recordings".
- # last present in B 2.10.1, invoked by readnews for followups.
- ;;
- -F) # undocumented in B 2.10.1, documented in B 2.11.
- shift; echo "References: $1" >>$input ;;
- -M) # this apparently just sets From: to the author of the article
- # instead of the poster (moderator), by leaving the From: line
- # alone (under -h); easy to implement.
- ;;
-
- # pass next options as environment variables to anne.jones
- -o) shift; ORGANIZATION="$1"; export ORGANIZATION ;;
-
- -C)
- cat <<eg >&2
- $0: you either want to use addgroup (see newsaux(8)) to make
- $0: $2 locally, or this to make it network-wide:
- inews -h <<'!'
- Control: newgroup $2
- Subject: newgroup $2
- Newsgroups: $2
- Approved: you@hostname
-
- Non-empty.
- !
- eg
- exit 1
- ;;
- -*)
- echo "$0: bad option $1" >&2
- exit 1
- ;;
- *) # is a filename; append file
- # B 2.11 kludge: assume -h if input starts with headers.
- # apparently the B 2.11 newsreaders assume this.
- tear /tmp/in$$ <$1
- if test -s $inhdrs; then
- hdrspresent=yes
- fi
-
- case "$hdrspresent" in
- no) echo "" >>$input; hdrspresent=yes ;;
- esac
- # capture incoming news in case relaynews fails
- if cat $inhdrs $inbody >>$input; then
- : far out
- else
- echo "$0: lost news; cat status $?" >&2
- exit 1
- fi
- fileseen=yes
- ;;
- esac
- shift # pass option or filename (any value was done above)
- done
-
- # if no files named, read stdin
- case "$fileseen" in
- yes) ;;
- *)
- # B 2.11 kludge: assume -h if input starts with headers
- # apparently the B 2.11 newsreaders assume this.
- tear /tmp/in$$
- if test -s $inhdrs; then
- hdrspresent=yes
- fi
-
- case "$hdrspresent" in
- no) echo "" >>$input; hdrspresent=yes ;;
- esac
- # capture incoming news in case relaynews fails
- if cat $inhdrs $inbody >>$input; then
- : far out
- else
- echo "$0: lost news; cat status $?" >&2
- exit 1
- fi
- ;;
- esac
- trap '' 1 2 15 # ignore signals to avoid losing articles
-
- # run the remainder in the background for the benefit of impatient people
- # who lack a window system
- (
- trap "$cleanup" 0
- tear /tmp/in$$ <$input # output in $inhdrs and $inbody
- # canonicalise header keyword capitalisation.
- # greps for Control: and Approved: later assume this, as does defhdrs.awk.
- canonhdr <$inhdrs >/tmp/in$$realtmp
- mv /tmp/in$$realtmp $inhdrs
- # pad zero-line articles, since old B [ir]news are confused by them
- # and the news readers generate zero-line control messages, alas.
- if test ! -s $inbody; then
- (echo '';
- echo This article was probably generated by a buggy news reader.) \
- >$inbody
- fi
-
- # deduce which tr we have: v6 or v7
- case "`echo B | tr A-Z a-z `" in
- b) trversion=v7 ;;
- B) trversion=v6 ;; # or System V
- esac
- export trversion
-
- # post with new headers and .signature
- (anne.jones <$inhdrs # bash headers
- # UNCOMMENTED
- #lines="` # sop to msb, just uncomment to use
- #(sed 1d $inbody; # take out the first (blank) line
- #if test -r $HOME/.signature; then
- # echo '-- '
- # sed 4q $HOME/.signature
- #fi) | wc -l `"
- #echo Lines: $lines
- # UNCOMMENTED
-
- # strip invisible chars from body, a la B news. bells and escapes are right out.
- case "$trversion" in
- v7) tr -d '\1-\7\13\15-\37' ;;
- v6) tr -d '[\1-\7]\13[\15-\37]' ;;
- esac <$inbody
-
- if test "$nosig" = "no"; then
- if test -r $HOME/.signature; then
- echo "-- "; sed 4q $HOME/.signature # glue on first bit of signature
- fi
- fi) >$censart
- ### the article is fully assembled now in $censart ###
-
- # to post or to mail? that is the question; whether 'tis nobler in the mind
- # to suffer the slings and arrows of outrageous mailers - Bill Shakespeare
- if grep -s '^Control:' $inhdrs >/dev/null; then
- echo "control" # a dreadful hack around all.all.ctl
- else
- sed -n '
- /^Newsgroups:[ ]/{
- s/^Newsgroups:[ ]*\(.*\)$/\1/p
- q
- }
- ' <$inhdrs
- fi >$nglist
-
- if test ! -s $nglist; then # no Newsgroups:
- exit 1 # anne.jones will have already complained
- fi
-
- # look up groups in active, to determine disposition of this message.
- # n, x and (unapproved) m flags are dealt with on the spot; if none are
- # seen, the article is posted normally.
- # escape egrep metacharacters. In theory one could add " ' ` \ to the list.
- egreppat="^(` sed -e 's/[.+*()|[]/\\\\&/g' -e 's/,/|/g' <$nglist `) "
- egrep "$egreppat" $NEWSCTL/active >/dev/null || {
- echo "$0: `cat $nglist` matches no groups in $NEWSCTL/active" >&2
- exit 1
- }
- rm -f $grpok
- egrep "$egreppat" $NEWSCTL/active |
- (while read ng high low flag junk # look at next group's active entry
- do
- >>$grpok
- case "$flag" in
- [nx])
- echo "$0: sorry, $ng may not be posted to locally." >&2
- trap 0 # this is a child process - no cleanup here
- echo 1 >$exitflag
- exit 1 # dregs in /tmp/in$$*
- ;;
- m)
- if grep -s '^Approved:[ ]' $inhdrs >/dev/null; then
- : # just post normally
- else
- # un-Approved article: mail it to the moderator(s).
- # look for a route for this group.
- # a dreadful B 2.11 hack: backbone == all
- (sed 's/^backbone[ ]/all /' \
- $NEWSCTL/mailpaths |
- gngp -a -r "`cat $nglist`";
- echo 'default %s') |
- sed -n "1{s/^[^ ]*[ ][ ]*//
- s/%s/` echo $ng | tr . - `/;p;q;}" \
- >$modroute
- moderator="`cat $modroute `"
- # TODO: next line confuses nn; change to stdout?
- echo "$0: mailing your article to $moderator" >&2
- mail "$moderator" <$censart
- trap 0 # this is a child process - no cleanup here
- echo 0 >$exitflag
- exit 0
- fi
- ;;
-
- # "" matches short active entries,
- # to be backward compatible.
- # * matches garbage flags, to be cautious.
- y|""|*)
- # okay so far, but wait until we see all Newsgroups:.
- ;;
- esac
- done
- trap 0 # paranoia - no clean up
- )
- if test ! -r $grpok; then
- echo "$0: no active groups in `cat $nglist`" >&2
- exit 1 # abnormal exit - cleans up, makes dead.article
- fi
- rm -f $grpok
- if test -f $exitflag; then
- exitstatus="`cat $exitflag`"
- case "$exitstatus" in
- 0) rm -f $rmlist; trap 0 ;; # normal exit - cleanup, no dead.article
- esac
- exit $exitstatus # trap 0 may cleanup, make dead.article
- fi
-
- ### if the article was mailed, that happened above; posting will happen below ###
-
- # deal with inadequate free space
- case "$autopost" in
- no)
- if test "`spacefor 1 articles`" -le 0; then
- echo "$0: too little space free on $NEWSARTS" >&2
- exit 1 # dregs in /tmp/in$$* for trap 0
- fi
- ;;
- *)
- iter=0
- while test "`spacefor 1 articles`" -le 0 -o "`spacefor 1 control`" -le 0
- do
- sleep 30
- iter=`expr $iter + 1`
- case "$iter" in
- 3)
- mail "$NEWSMASTER" <<!
- Subject: free space too low on $NEWSARTS
-
- There is too little free space on $NEWSARTS for inews to run comfortably.
- !
- ;;
- esac
- done
- ;;
- esac
-
- # to get here, we must have seen no n, x, nor (unapproved) m flags.
- # <$censart is used rather than a pipe to work around a bug in the 4.2 sh
- # which made it sometimes return the wrong exit status (that of anne.jones).
- # execute relaynews commands on the server, for the sake of locking.
- # may not use "exec" or sh will leave /tmp/sh* files from here docs in /tmp.
- me="`hostname`"
- server=`cat $NEWSCTL/server 2>/dev/null`
- case "$server" in
- "") server="$me" ;; # if no server file, assume this is it
- esac
- case "$me" in
- $server)
- relaynews $relayopts -s $exclusion -d "$debug" <$censart
- status=$?
- # echo "status $? from relaynews" >>/tmp/inewsdebug # DEBUG
- ;;
- *)
- # send article+commands to remote shell, including clean up
- (echo "sed 's/^-//' >/tmp/irsh\$\$ <<'!'" # remove guard
- sed 's/^[^A-EG-Za-z0-9]/-&/' $censart # prepend guard
- echo !
- cat <<!
- PATH=$PATH relaynews $relayopts -s $exclusion -d "$debug" </tmp/irsh\$\$
- !
- echo 'echo status $?'
- echo 'rm -f /tmp/irsh$$') |
- rsh $server /bin/sh >$outfile
-
- status=`sed -n '/^status /s///p' $outfile `
- sed '/^status /d' $outfile # print relaynews's stdout
- ;;
- esac
- case "$status" in
- 0)
- rm -f $rmlist # far out, it worked: clean up
- if test ! -f $NEWSCTL/sys; then
- echo "$0: $NEWSCTL/sys missing; your news can't leave this machine" >&2
- fi
- trap 0 # normal exit: cleanup done
- ;;
- esac
- exit $status # trap 0 may cleanup, make dead.article
- ) &
- eval $waitcmd # wait & get status if -W given
- trap 0 # let the background run on unmolested
- exit $status
-