#! /bin/sh
##  $Revision: 1.8 $
##  Send news via NNTP by running several innxmit processes in the background.
##  Usage:
##	nntpsend [-p][-r][-s size][-S][-t timeout][-T limit][host fqdn]...
##	-p		Run innxmit with -p to prune batch files
##	-r		innxmit, don't requeue on unexpected error code
##	-s size		limit the .nntp file to size bytes
##	-S		send via xreplic protocol (send to a slave site)
##	-t timeout	innxmit timeout to make connection (def: 180)
##	-T limit	innxmit connection transmit time limit (def: forever)
##	host fqdn	send to host and qualified domain (def: nntpsend.ctl)
##  If no "host fqdn" pairs appear on the command line, then ${CTLFILE}
##  file is read.
##  =()<. @<_PATH_SHELLVARS>@>()=
. /usr/lib/news/innshellvars

PROGNAME=`basename $0`
LOCK=${LOCKS}/LOCK.${PROGNAME}
CTLFILE=${NEWSLIB}/${PROGNAME}.ctl
LOG=${MOST_LOGS}/${PROGNAME}.log

##  Set defaults.
D_FLAG=
P_FLAG=
R_FLAG=
S_FLAG=
TRUNC_SIZE=
T_FLAG=
TIMELIMIT=

##  Parse JCL.
MORETODO=true
while ${MORETODO} ; do
    case X"$1" in
    X-d)
	D_FLAG="-d"
	;;
    X-p)
	P_FLAG="-p"
	;;
    X-r)
	R_FLAG="-r"
	;;
    X-S)
	S_FLAG="-S"
	;;
    X-s)
	if [ -z "$2" ] ; then
	    echo "${PROGNAME}: option requires an argument -- s" 1>&2
	    exit 1
	fi
	TRUNC_SIZE="$2"
	shift
	;;
    X-s*)
	TRUNC_SIZE="`echo $2 | ${SED} -e 's/-s//'`"
	;;
    X-t)
	if [ -z "$2" ] ; then
	    echo "${PROGNAME}: option requires an argument -- t" 1>&2
	    exit 1
	fi
	T_FLAG="-t$2"
	shift
	;;
    X-t*)
	T_FLAG="$1"
	;;
    X-T)
	if [ -z "$2" ] ; then
	    echo "${PROGNAME}: option requires an argument -- T" 1>&2
	    exit 1
	fi
	TIMELIMIT="-T$2"
	shift
	;;
    X-T*)
	TIMELIMIT="$1"
	;;
    X--)
	shift
	MORETODO=false
	;;
    X-*)
	echo "${PROGNAME}: illegal option -- $1" 1>&2
	exit 1
	;;
    *)
	MORETODO=false
	;;
    esac
    ${MORETODO} && shift
done

##  Parse arguments; host/fqdn pairs.
INPUT=${TMPDIR}/nntpsend$$
cp /dev/null ${INPUT}
while [ $# -gt 0 ]; do
    if [ $# -lt 2 ]; then
	echo "${PROGNAME}:  Bad host/fqdn pair" 1>&2
	exit 1
    fi
    echo "$1 $2" >>${INPUT}
    shift
    shift
done

##  If nothing specified on the command line, read the control file.
if [ ! -s ${INPUT} ] ; then
    if [ ! -r ${CTLFILE} ]; then
	echo "${PROGNAME}: cannot read ${CTLFILE}"
	exit 1
    fi
    ${SED} -e 's/#.*//' -e '/^$/d' -e 's/::\([^:]*\)$/:max:\1/' \
	-e 's/:/ /g' <${CTLFILE} >${INPUT}
fi

##  Go to where the action is.
if [ ! -d ${BATCH} ]; then
    echo "${PROGNAME}: directory ${BATCH} not found" 1>&2
    exit 1
fi
cd ${BATCH}

##  Set up log file.
umask 002
if [ -z "${D_FLAG}" ]; then
    test ! -f ${LOG} && touch ${LOG}
    chmod 0660 ${LOG}
    exec >>${LOG} 2>&1
fi
PPID=$$
echo "${PROGNAME}: [${PPID}] start"

##  Set up environment.
export BATCH PROGNAME PPID INNFLAGS

##  Loop over all sites.
cat ${INPUT} | while read SITE HOST MAXSIZE FLAGS; do
    ## Parse the input parameters.
    if [ -z "${SITE}" -o -z "${HOST}" ] ; then
	echo "Ignoring bad line: ${SITE} ${HOST} ${MAXSIZE} ${FLAGS}" 1>&2
	continue
    fi
    test "${MAXSIZE}" = "max" && MAXSIZE=

    ## Compute the specific parameters for this site.
    if [ -n "${TRUNC_SIZE}" ]; then
	SIZE="${TRUNC_SIZE}"
    else
	SIZE="${MAXSIZE}"
    fi
    D_PARAM=
    R_PARAM=
    S_PARAM=
    TIMEOUT_PARAM=
    TIMELIMIT_PARAM=
    if [ -z "${FLAGS}" ]; then
	MORETODO=false
    else
	MORETODO=true
	set - ${FLAGS}
    fi
    while ${MORETODO} ; do
	case "X$1" in
	X-a)
	    ;;
	X-d)
	    D_PARAM="-d"
	    ;;
	X-p)
	    P_PARAM="-p"
	    ;;
	X-r)
	    R_PARAM="-r"
	    ;;
	X-S)
	    S_PARAM="-S"
	    ;;
	X-t)
	    if [ -z "$2" ] ; then
		echo "${PROGNAME}: option requires an argument -- t" 1>&2
		exit 1
	    fi
	    TIMEOUT_PARAM="-t$2"
	    shift
	    ;;
	X-t*)
	    TIMEOUT_PARAM="$1"
	    ;;
	X-T)
	    if [ -z "$2" ] ; then
		echo "${PROGNAME}: option requires an argument -- T" 1>&2
		exit 1
	    fi
	    TIMELIMIT_PARAM="-T$2"
	    shift
	    ;;
	X-T*)
	    TIMELIMIT_PARAM="$1"
	    ;;
	*)
	    MORETODO=false
	    ;;
	esac
	${MORETODO} && shift
    done
    INNFLAGS="-a"
    if [ -n "${D_FLAG}" ]; then
	INNFLAGS="${INNFLAGS} ${D_FLAG}"
    else
	test -n "${D_PARAM}" && INNFLAGS="${INNFLAGS} ${D_PARAM}"
    fi
    if [ -n "${P_FLAG}" ]; then
	INNFLAGS="${INNFLAGS} ${P_FLAG}"
    else
	test -n "${P_PARAM}" && INNFLAGS="${INNFLAGS} ${P_PARAM}"
    fi
    if [ -n "${R_FLAG}" ]; then
	INNFLAGS="${INNFLAGS} ${R_FLAG}"
    else
	test -n "${R_PARAM}" && INNFLAGS="${INNFLAGS} ${R_PARAM}"
    fi
    if [ -n "${S_FLAG}" ]; then
	INNFLAGS="${INNFLAGS} ${S_FLAG}"
    else
	test -n "${S_PARAM}" && INNFLAGS="${INNFLAGS} ${S_PARAM}"
    fi
    if [ -n "${T_FLAG}" ]; then
	INNFLAGS="${INNFLAGS} ${T_FLAG}"
    else
	test -n "${TIMEOUT_PARAM}" && INNFLAGS="${INNFLAGS} ${TIMEOUT_PARAM}"
    fi
    if [ -n "${TIMELIMIT}" ]; then
	INNFLAGS="${INNFLAGS} ${TIMELIMIT}"
    else
	test -n "${TIMELIMIT_PARAM}" \
	    && INNFLAGS="${INNFLAGS} ${TIMELIMIT_PARAM}"
    fi

    ##  Start sending this site in the background.
    export SITE HOST LOCKS BATCHFILE PROGNAME PPID SIZE TMPDIR
    sh -c '
	BATCHFILE=${HOST}.nntp
	LOCK=${LOCKS}/LOCK.${HOST}
	trap "rm -f ${LOCK} ; exit 1" 1 2 3 15
	shlock -p $$ -f ${LOCK} || {
	    WHY="`cat ${LOCK}`"
	    echo "${PROGNAME}: [${PPID}:$$] ${HOST} locked ${WHY} `date`"
	    exit
	}
	if [ -f ${SITE}.work ] ; then
	    cat ${SITE}.work >>${BATCHFILE}
	    rm -f ${SITE}.work
	fi
	mv ${SITE} ${SITE}.work
	if ctlinnd -s -t30 flush ${SITE} ; then
	    cat ${SITE}.work >>${BATCHFILE}
	    rm -f ${SITE}.work
	    test -n "${SIZE}" && shrinkfile -s${SIZE} -v ${BATCHFILE}
	    if [ -s ${BATCHFILE} ] ; then
		echo "${PROGNAME}: [${PPID}:$$] begin ${HOST} `date`"
		echo "${PROGNAME}: [${PPID}:$$] innxmit ${INNFLAGS} ${HOST} ..."
		eval innxmit ${INNFLAGS} ${HOST} ${BATCH}/${BATCHFILE}
		echo "${PROGNAME}: [${PPID}:$$] end ${HOST} `date`"
	    else
		rm -f ${BATCHFILE}
	    fi
	fi
	rm -f ${LOCK}
    ' &
    sleep 5
done

wait
rm -f ${INPUT}
echo "${PROGNAME}: [${PPID}] stop"
