#! /bin/sh
# injnews [-debug k] [-x site] [-ANV] - `sensible' news injection interface:
#	censor locally-posted article on stdin; munge the article, enforce
#	feeble attempts at Usenet security, generate lots of silly headers.
#
# Yes, it's slow.  The alternative is casting a lot of local policy in C.

# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
. ${NEWSCONFIG-/var/lib/news/bin/config}
export NEWSCTL NEWSBIN NEWSARTS NEWSPATH NEWSUMASK NEWSMASTER NEWSCONFIG
PATH=$NEWSCTL/bin:$NEWSBIN/inject:$NEWSBIN:$NEWSPATH; export PATH

debug=''			# flags
exclusion=''
autopost=no; export autopost
relayopts=-i; export relayopts	# redirect stdout to log
badsites=; export badsites	# export to pnews

input=/tmp/in$$in		# uncensored input; save on error
inhdrs=/tmp/in$$hdr		# generated by tear: headers
inbody=/tmp/in$$body		# generated by tear: body
censart=/tmp/in$$cens		# censored input
outfile=/tmp/in$$out		# relaynews stdout
rmlist="$input $inhdrs $inbody $censart $outfile"

umask $NEWSUMASK

# process arguments: for options, cat headers onto $input; cat files onto $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

### option processing ###

while :
do
	case $# in
	0)	break ;;		# arguments exhausted
	esac

	case "$1" in
	# peculiar to C news
	-debug)	shift; debug="$1" ;;
	-A)	autopost=yes ;;			# wait for free space
	-N)	justfilter=yes ;;
	-V)	relayopts= ;;	# verbose: don't redirect stdout (or stderr)
	# useful standard option
	-x)	shift; badsites="$badsites$1!" ;; # you're welcome, erik (B 2.11)
	*)					# bad option or a file name
		echo "usage: $0 [-debug k] [-x site] [-ANV]" >&2
		exit 1
		;;
	esac
	shift					# pass option
done

### beat up article on stdin ###
cat >$input					# **

if
	case "$justfilter" in	# ** pnews takes 3.2 seconds
	yes) pnews /tmp/in$$ <$input ;;	# output in $inhdrs & $inbody
	*)   pnews /tmp/in$$ <$input >$censart ;;	# output in $inhdrs & $inbody
	esac
then	:
else	exit $?			# clean up; pnews will have complained
fi

# 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

ngs=` awk '
	# a dreadful hack around all.all.ctl
	/^Control:/	{ print "control"; ngs=""; exit }
	/^Newsgroups:/	{ ngs=$2 }		# save for END
	END		{ if (ngs != "") print ngs }
	' $inhdrs `
case "$ngs" in			# any Newsgroups:?
'')	exit 1 ;;		# nope: pnews will have already complained
esac

# 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.
# POLICY: what happens to = groups; how are m articles mailed?
actflag="` actflag $ngs `"		# ** takes 0.4 seconds
case "$actflag" in
'')
	echo "$0: $ngs: no groups in active file" >&2
	exit 1
	;;
[nx]*)
	# TODO: deal better when only some groups are n or x.
	set $actflag
	ng="$2"
	echo "$0: sorry, $ng may not be posted to locally." >&2
	exit 1
	;;
m*)
	if grep -s '^Approved:[	 ]' $inhdrs >/dev/null; then
		:		# just post normally
	else
		case "$justfilter" in
		yes)	;;
		*)
			set $actflag
			ng="$2"
			# unApproved article: mail to a moderator.
			moderator="` modroute $ng `"
			echo "mailing your article to $moderator"
			mail "$moderator" <$censart
			;;
		esac
		trap "rm -f $rmlist; exit 0" 0	# normal exit - no dead.article
		exit 0
	fi
	;;

y|*)				# * matches garbage flags, to be cautious.
	# okay
	;;
esac

### if the article was mailed, that happened above; posting will follow ###

# 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).
# may not use "exec" or sh will leave /tmp/sh* files from here docs in /tmp.

if
	case "$justfilter" in
	yes)	: ;;
	*)
		# relayopts="$relayopts -s -d ''$debug" \
		PATH=$NEWSCTL/bin:$NEWSBIN/input:$NEWSBIN:$NEWSPATH
		newsspool -g 0 <$censart		# TODO: pass relayopts
		;;
	esac
then
	# POLICY: warn the user about missing sys file?
	if test ! -f $NEWSCTL/sys; then
		echo "$0: $NEWSCTL/sys missing; your news can't leave this machine" >&2
	fi
	trap "rm -f $rmlist; exit 0" 0		# normal exit - no dead.article
	exit 0
else
	exit $?				# trap 0 may cleanup, make dead.article
fi
