home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2371 / inews.new < prev   
Encoding:
Text File  |  1990-12-28  |  10.5 KB  |  370 lines

  1. : /bin/sh
  2. # inews [-p] [-debug k] [-x site] [-hMD] [-t subj] [-n ng] [-e exp] [-F ref] \
  3. #  [-d dist] [-a mod] [-f from] [-o org] [-C ng] [file...] - inject news:
  4. #    censor locally-posted article and field the "inews -C" kludge;
  5. #    munge the articles, enforce feeble attempts at Usenet security,
  6. #    generate lots of silly headers.
  7. #
  8. # Yes, it's big, slow and awkward.  The alternative is casting a lot of
  9. # local policy in C.
  10.  
  11. # =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
  12. . ${NEWSCONFIG-/usr/lib/news/bin/config}
  13. export NEWSCTL NEWSBIN NEWSARTS NEWSPATH NEWSUMASK NEWSMASTER NEWSCONFIG
  14. PATH=$NEWSCTL/bin:$NEWSBIN/inject:$NEWSBIN/relay:$NEWSBIN:$NEWSPATH; export PATH
  15. PASSEDFROM='';    export PASSEDFROM    # passed to anne.jones in environ.
  16.  
  17. debug=''            # flags
  18. exclusion=''
  19. hdrspresent=no
  20. autopost=no
  21. waitcmd='status=0'
  22. relayopts=-i            # redirect stdout to log
  23.  
  24. input=/tmp/in$$in        # uncensored input
  25. inhdrs=/tmp/in$$hdr        # generated by tear: headers
  26. inbody=/tmp/in$$body        # generated by tear: body
  27. censart=/tmp/in$$cens        # censored input
  28. nglist=/tmp/in$$ngs        # newsgroups: list
  29. modroute=/tmp/in$$route        # route to moderator's forwarder
  30. exitflag=/tmp/in$$exit        # exit status, if present
  31. outfile=/tmp/in$$out        # relaynews stdout
  32. rmlist="$inhdrs $inbody $input $censart $nglist $modroute $exitflag $outfile"
  33. grpok=/tmp/in$$grp        # flag file: groups okay if present
  34.  
  35. # cluther addition
  36. nosig=no
  37.  
  38. umask $NEWSUMASK
  39.  
  40. # "inews -p": invoke rnews
  41. case "$1" in
  42. -p)
  43.     shift
  44.     cat $* | relaynews -r    # feed directly to relaynews, seat belts off
  45.     exit
  46.     ;;
  47. esac
  48.  
  49. # process arguments: for options, cat headers onto $input; cat files onto $input
  50. >$input
  51. cleanup="test ! -f $HOME/dead.article -o -w $HOME/dead.article &&
  52.   cat $input >>$HOME/dead.article &&
  53.   { echo $0: article in $HOME/dead.article >&2; rm -f $rmlist; }; exit 1"
  54. trap "$cleanup" 0 1 2 3 15
  55. while :
  56. do
  57.     case $# in
  58.     0)    break ;;        # arguments exhausted
  59.     esac
  60.  
  61.     case "$1" in
  62.     # peculiar to C news
  63.         -z) shift; nosig=yes;;
  64.     -debug)    shift; debug="$1" ;;
  65.     -A)    autopost=yes ;;        # wait for free space
  66.     -V)    relayopts= ;;        # verbose: don't redirect stdout (or stderr)
  67.     -W)    waitcmd='wait; status=$?' ;;    # wait for completion
  68.     # useful standard options
  69.     -h)    hdrspresent=yes ;;
  70.     -x)    shift; exclusion="-x $1" ;;    # you're welcome, erik (2.11)
  71.     # silly options supplied by newsreaders
  72.     -a)    shift; echo "Approved: $1" >>$input ;;
  73.     -c)    shift; echo "Control: $1" >>$input ;;
  74.     -d)    shift; echo "Distribution: $1" >>$input ;;
  75.     -e)    shift; echo "Expires: $1" >>$input ;;
  76.     -f)    shift; echo "From: $1" >>$input ;;
  77.     -n)    shift; echo "Newsgroups: $1" >>$input ;;
  78.     -r)    shift; echo "Reply-To: $1" >>$input ;;
  79.     -t)    shift; echo "Subject: $1" >>$input ;;    # aka Title:
  80.     -D)    # obsolete, undocumented: meant "don't check for recordings".
  81.         # last present in B 2.10.1, invoked by readnews for followups.
  82.         ;;
  83.     -F)    # undocumented in B 2.10.1, documented in B 2.11.
  84.         shift; echo "References: $1" >>$input ;;
  85.     -M)    # this apparently just sets From: to the author of the article
  86.         # instead of the poster (moderator), by leaving the From: line
  87.         # alone (under -h); easy to implement.
  88.         ;;
  89.  
  90.     # pass next options as environment variables to anne.jones
  91.     -o)    shift; ORGANIZATION="$1"; export ORGANIZATION ;;
  92.  
  93.     -C)
  94.         cat <<eg >&2
  95. $0: you either want to use addgroup (see newsaux(8)) to make
  96. $0: $2 locally, or this to make it network-wide:
  97. inews -h <<'!'
  98. Control: newgroup $2
  99. Subject: newgroup $2
  100. Newsgroups: $2
  101. Approved: you@hostname
  102.  
  103. Non-empty.
  104. !
  105. eg
  106.         exit 1
  107.         ;;
  108.     -*)
  109.         echo "$0: bad option $1" >&2
  110.         exit 1
  111.         ;;
  112.     *)                    # is a filename; append file
  113.         # B 2.11 kludge: assume -h if input starts with headers.
  114.         # apparently the B 2.11 newsreaders assume this.
  115.         tear /tmp/in$$ <$1
  116.         if test -s $inhdrs; then
  117.             hdrspresent=yes
  118.         fi
  119.  
  120.         case "$hdrspresent" in
  121.         no)    echo "" >>$input; hdrspresent=yes ;;
  122.         esac
  123.         # capture incoming news in case relaynews fails
  124.         if cat $inhdrs $inbody >>$input; then
  125.             : far out
  126.         else
  127.             echo "$0: lost news; cat status $?" >&2
  128.             exit 1
  129.         fi
  130.         fileseen=yes
  131.         ;;
  132.     esac
  133.     shift        # pass option or filename (any value was done above)
  134. done
  135.  
  136. # if no files named, read stdin
  137. case "$fileseen" in
  138. yes)    ;;
  139. *)
  140.     # B 2.11 kludge: assume -h if input starts with headers
  141.     # apparently the B 2.11 newsreaders assume this.
  142.     tear /tmp/in$$
  143.     if test -s $inhdrs; then
  144.         hdrspresent=yes
  145.     fi
  146.  
  147.     case "$hdrspresent" in
  148.     no)    echo "" >>$input; hdrspresent=yes ;;
  149.     esac
  150.     # capture incoming news in case relaynews fails
  151.     if cat $inhdrs $inbody >>$input; then
  152.         : far out
  153.     else
  154.         echo "$0: lost news; cat status $?" >&2
  155.         exit 1
  156.     fi
  157.     ;;
  158. esac
  159. trap '' 1 2 15            # ignore signals to avoid losing articles
  160.  
  161. # run the remainder in the background for the benefit of impatient people
  162. # who lack a window system
  163. (
  164. trap "$cleanup" 0
  165. tear /tmp/in$$ <$input        # output in $inhdrs and $inbody
  166. # canonicalise header keyword capitalisation.
  167. # greps for Control: and Approved: later assume this, as does defhdrs.awk.
  168. canonhdr <$inhdrs >/tmp/in$$realtmp
  169. mv /tmp/in$$realtmp $inhdrs
  170. # pad zero-line articles, since old B [ir]news are confused by them
  171. # and the news readers generate zero-line control messages, alas.
  172. if test ! -s $inbody; then
  173.     (echo '';
  174.      echo This article was probably generated by a buggy news reader.) \
  175.      >$inbody
  176. fi
  177.  
  178. # deduce which tr we have: v6 or v7
  179. case "`echo B | tr A-Z a-z `" in
  180. b)    trversion=v7 ;;
  181. B)    trversion=v6 ;;            # or System V
  182. esac
  183. export trversion
  184.  
  185. # post with new headers and .signature
  186. (anne.jones <$inhdrs        # bash headers
  187. # UNCOMMENTED
  188. #lines="`            # sop to msb, just uncomment to use
  189. #(sed 1d $inbody;    # take out the first (blank) line
  190. #if test -r $HOME/.signature; then
  191. #    echo '-- '
  192. #    sed 4q $HOME/.signature
  193. #fi) | wc -l `"
  194. #echo Lines: $lines
  195. # UNCOMMENTED
  196.  
  197.  # strip invisible chars from body, a la B news.  bells and escapes are right out.
  198.  case "$trversion" in
  199.  v7)    tr -d  '\1-\7\13\15-\37' ;;
  200.  v6)    tr -d '[\1-\7]\13[\15-\37]' ;;
  201.  esac <$inbody
  202.  
  203. if test "$nosig" = "no"; then
  204.  if test -r $HOME/.signature; then
  205.     echo "-- "; sed 4q $HOME/.signature    # glue on first bit of signature
  206.  fi
  207. fi) >$censart
  208. ### the article is fully assembled now in $censart ###
  209.  
  210. # to post or to mail? that is the question; whether 'tis nobler in the mind
  211. # to suffer the slings and arrows of outrageous mailers - Bill Shakespeare
  212. if grep -s '^Control:' $inhdrs >/dev/null; then
  213.     echo "control"            # a dreadful hack around all.all.ctl
  214. else
  215.     sed -n '
  216. /^Newsgroups:[     ]/{
  217. s/^Newsgroups:[     ]*\(.*\)$/\1/p
  218. q
  219. }
  220. ' <$inhdrs
  221. fi >$nglist
  222.  
  223. if test ! -s $nglist; then        # no Newsgroups:
  224.     exit 1                # anne.jones will have already complained
  225. fi
  226.  
  227. # look up groups in active, to determine disposition of this message.
  228. # n, x and (unapproved) m flags are dealt with on the spot; if none are
  229. # seen, the article is posted normally.
  230. # escape egrep metacharacters.  In theory one could add " ' ` \ to the list.
  231. egreppat="^(` sed -e 's/[.+*()|[]/\\\\&/g' -e 's/,/|/g' <$nglist `) "
  232. egrep "$egreppat" $NEWSCTL/active >/dev/null || {
  233.     echo "$0: `cat $nglist` matches no groups in $NEWSCTL/active" >&2
  234.     exit 1
  235. }
  236. rm -f $grpok
  237. egrep "$egreppat" $NEWSCTL/active |
  238.     (while read ng high low flag junk    # look at next group's active entry
  239.     do
  240.         >>$grpok
  241.         case "$flag" in
  242.         [nx])
  243.             echo "$0: sorry, $ng may not be posted to locally." >&2
  244.             trap 0        # this is a child process - no cleanup here
  245.             echo 1 >$exitflag
  246.             exit 1        # dregs in /tmp/in$$*
  247.             ;;
  248.         m)
  249.             if grep -s '^Approved:[     ]' $inhdrs >/dev/null; then
  250.                 :        # just post normally
  251.             else
  252.                 # un-Approved article: mail it to the moderator(s).
  253.                 # look for a route for this group.
  254.                 # a dreadful B 2.11 hack: backbone == all
  255.                 (sed 's/^backbone[     ]/all /' \
  256.                             $NEWSCTL/mailpaths |
  257.                         gngp -a -r "`cat $nglist`";
  258.                         echo 'default    %s') |
  259.                     sed -n "1{s/^[^     ]*[     ][     ]*//
  260.                       s/%s/` echo $ng | tr . - `/;p;q;}" \
  261.                         >$modroute
  262.                 moderator="`cat $modroute `"
  263.                 # TODO: next line confuses nn; change to stdout?
  264.                 echo "$0: mailing your article to $moderator" >&2
  265.                 mail "$moderator" <$censart
  266.                 trap 0    # this is a child process - no cleanup here
  267.                 echo 0 >$exitflag
  268.                 exit 0
  269.             fi
  270.             ;;
  271.  
  272.             # "" matches short active entries,
  273.             #    to be backward compatible.
  274.             # * matches garbage flags, to be cautious.
  275.         y|""|*)
  276.             # okay so far, but wait until we see all Newsgroups:.
  277.             ;;
  278.         esac
  279.     done
  280.     trap 0                    # paranoia - no clean up
  281.     )
  282. if test ! -r $grpok; then
  283.     echo "$0: no active groups in `cat $nglist`" >&2
  284.     exit 1            # abnormal exit - cleans up, makes dead.article
  285. fi
  286. rm -f $grpok
  287. if test -f $exitflag; then
  288.     exitstatus="`cat $exitflag`"
  289.     case "$exitstatus" in
  290.     0)    rm -f $rmlist; trap 0 ;; # normal exit - cleanup, no dead.article
  291.     esac
  292.     exit $exitstatus    # trap 0 may cleanup, make dead.article
  293. fi
  294.  
  295. ### if the article was mailed, that happened above; posting will happen below ###
  296.  
  297. # deal with inadequate free space
  298. case "$autopost" in
  299. no)
  300.     if test "`spacefor 1 articles`" -le 0; then
  301.         echo "$0: too little space free on $NEWSARTS" >&2
  302.         exit 1            # dregs in /tmp/in$$* for trap 0
  303.     fi
  304.     ;;
  305. *)
  306.     iter=0
  307.     while test "`spacefor 1 articles`" -le 0 -o "`spacefor 1 control`" -le 0
  308.     do
  309.         sleep 30
  310.         iter=`expr $iter + 1`
  311.         case "$iter" in
  312.         3)
  313.             mail "$NEWSMASTER" <<!
  314. Subject: free space too low on $NEWSARTS
  315.  
  316. There is too little free space on $NEWSARTS for inews to run comfortably.
  317. !
  318.             ;;
  319.         esac
  320.     done
  321.     ;;
  322. esac
  323.  
  324. # to get here, we must have seen no n, x, nor (unapproved) m flags.
  325. # <$censart is used rather than a pipe to work around a bug in the 4.2 sh
  326. # which made it sometimes return the wrong exit status (that of anne.jones).
  327. # execute relaynews commands on the server, for the sake of locking.
  328. # may not use "exec" or sh will leave /tmp/sh* files from here docs in /tmp.
  329. me="`hostname`"
  330. server=`cat $NEWSCTL/server 2>/dev/null`
  331. case "$server" in
  332. "")    server="$me" ;;            # if no server file, assume this is it
  333. esac
  334. case "$me" in
  335. $server)
  336.     relaynews $relayopts -s $exclusion -d "$debug" <$censart
  337.     status=$?
  338. #    echo "status $? from relaynews" >>/tmp/inewsdebug # DEBUG
  339.     ;;
  340. *)
  341.     # send article+commands to remote shell, including clean up
  342.     (echo "sed 's/^-//' >/tmp/irsh\$\$ <<'!'"    # remove guard
  343.      sed 's/^[^A-EG-Za-z0-9]/-&/' $censart    # prepend guard
  344.      echo !
  345.      cat <<!
  346. PATH=$PATH relaynews $relayopts -s $exclusion -d "$debug" </tmp/irsh\$\$
  347. !
  348.      echo 'echo status $?'
  349.      echo 'rm -f /tmp/irsh$$') |
  350.         rsh $server /bin/sh >$outfile
  351.  
  352.     status=`sed -n '/^status /s///p' $outfile `
  353.     sed '/^status /d' $outfile    # print relaynews's stdout
  354.     ;;
  355. esac
  356. case "$status" in
  357. 0)
  358.     rm -f $rmlist            # far out, it worked: clean up
  359.     if test ! -f $NEWSCTL/sys; then
  360.         echo "$0: $NEWSCTL/sys missing; your news can't leave this machine" >&2
  361.     fi
  362.     trap 0                # normal exit: cleanup done
  363.     ;;
  364. esac
  365. exit $status                # trap 0 may cleanup, make dead.article
  366. ) &
  367. eval $waitcmd                # wait & get status if -W given
  368. trap 0                    # let the background run on unmolested
  369. exit $status
  370.