#!@_PATH_SH@ ## $Revision: 5999 $ ## Daily news maintenance. ## Optional arguments: ## expdir=xxx Directory in which to build new history file ## tmpdir=xxx Working directory for `sort' and such ## expirectl=xxx Use xxx as expire.ctl file ## flags=xxx Pass xxx flags to expire ## lowmark Create and use a lowmark file ## noexpire Do not expire ## noexplog Do not log expire output ## nologs Do not scan logfiles ## nomail Do not capture and mail output ## norenumber Do not renumber the active file ## norm Do not remove certain old files ## norotate Do not rotate logfiles ## nostat Do not run innstat ## notdaily Not a daily run, and therefore implies nologs. ## delayrm Delay unlink files, then do it quicker (expire -z) ## /full/path Path to a program to run before expiring . @LIBDIR@/innshellvars EXPLOG=${MOST_LOGS}/expire.log INNSTAT=${PATHBIN}/innstat HOSTNAME=`hostname` DATE=`date` TAGGEDHASH=@DO_DBZ_TAGGED_HASH@ SORT=sort ## If your expire does not pause or throttle innd, enable this next line: #MESSAGE="Expiration script $$" ## Renumber all at once, or in steps? Set to the delay if steps (that ## may take a long time!). RENUMBER= PROGNAME=news.daily LOCK=${LOCKS}/LOCK.${PROGNAME} ## Set defaults. DAILY=true DOEXPIRE=true DOEXPLOG=true DOEXPIREOVER=false DOLOGS=true DOMAIL=true DORENUMBER=true DORM=true DOSTAT=true EXPIRECTL= EXPDIR= EXPIREFLAGS="-v1" EXPIREOVER=expireover LOWMARKFILE= RMFILE= HISTDIR="`dirname ${HISTORY}`" TOUT=600 # timeout value for ctlinnd commands if [ -z "${HISTDIR}" -o X"." = X"${HISTDIR}" -o ! -d "${HISTDIR}" ]; then if [ -d "${PATHETC}/hist" ]; then HISTDIR="${PATHETC}/hist" else HISTDIR="${PATHETC}" fi fi if [ "${ENABLEOVERVIEW}" = "true" ]; then DOEXPIREOVER=true RMFILE=${MOST_LOGS}/expire.rm fi EXPIREOVERFLAGS= PROGRAMS= POSTPROGRAMS= REASON= SCANARG= DOGROUPBASEEXPIRY=false if [ "${GROUPBASEEXPIRY}" = "true" ]; then if [ "${ENABLEOVERVIEW}" = "true" ]; then DOGROUPBASEEXPIRY=true else DOEXPIREOVER=false RMFILE= fi fi ## Parse JCL. for I do case "X$I" in Xdelayrm) RMFILE=${MOST_LOGS}/expire.rm ;; Xexpctl=*) EXPIRECTL=`expr "${I}" : 'expctl=\(.*\)'` case ${EXPIRECTL} in /*) ;; *) EXPIRECTL=`/bin/pwd`/${EXPIRECTL} ;; esac ;; Xexpdir=*) EXPDIR=`expr "${I}" : 'expdir=\(.*\)'` ;; Xtmpdir=*) TMPDIR=`expr "${I}" : 'tmpdir=\(.*\)'` ;; Xexpireover) DOEXPIREOVER=true RMFILE=${MOST_LOGS}/expire.rm ;; Xexpireoverflags=*) EXPIREOVERFLAGS=`expr "${I}" : 'expireoverflags=\(.*\)'` ;; Xflags=*) EXPIREFLAGS=`expr "${I}" : 'flags=\(.*\)'` ;; Xlowmark) LOWMARKFILE=${MOST_LOGS}/expire.lowmark DORENUMBER=false ;; Xnotdaily) DAILY=false DOLOGS=false ;; Xnoexpire) DOEXPIRE=false ;; Xnoexpireover) DOEXPIREOVER=false RMFILE= ;; Xnoexplog) DOEXPLOG=false ;; Xnologs) DOLOGS=false ;; Xnomail) DOMAIL=false MAIL="cut -c 1-1022 | ${SED} -e 's/^~/~~/'" ;; Xnonn) # Ignore this. ;; Xnorenumber) DORENUMBER=false ;; Xnorm) DORM=false ;; Xnorotate) SCANARG="${SCANARG} norotate" ;; Xnostat) DOSTAT=false ;; X/*) PROGRAMS="${PROGRAMS} ${I}" ;; Xpostexec=*) POSTEXEC=`expr "${I}" : 'postexec=\(.*\)'` POSTPROGRAMS="${POSTPROGRAMS} ${POSTEXEC}" ;; *) echo "Unknown flag ${I}" 1>&2 exit 1 ;; esac done ## ## Setup mail subject and command ## if ${DAILY} ; then MAILSUBJ="${HOSTNAME} Daily Usenet report for ${DATE}" else MAILSUBJ="${HOSTNAME} intermediate usenet report for ${DATE}" fi MAIL="cut -c 1-1022 | ${SED} -e 's/^~/~~/' | \ ${MAILCMD} -s '$MAILSUBJ' ${NEWSMASTER}" # # Sanity check. Shouldn't we just bail out here with an error # instead of trying to patch things up? # ${DOEXPIRE} || { EXPDIR= RMFILE= } test -n "${EXPDIR}" && { test -z "${REASON}" && REASON="Expiring $$ on ${EXPDIR}" EXPIREFLAGS="${EXPIREFLAGS} '-d${EXPDIR}' '-r${REASON}'" } test -n "${RMFILE}" && { if ${DOGROUPBASEEXPIRY} ; then EXPIREOVERFLAGS="${EXPIREOVERFLAGS} -z${RMFILE}" else EXPIREFLAGS="${EXPIREFLAGS} -z${RMFILE}" fi } test -n "${LOWMARKFILE}" && { EXPIREOVERFLAGS="${EXPIREOVERFLAGS} -Z${LOWMARKFILE}" } if ${DOMAIL} ; then ## Try to get a temporary file. TEMP=${TMPDIR}/doex$$ test -f ${TEMP} && { echo "Temporary file ${TEMP} exists" | eval ${MAIL} exit 1 } touch ${TEMP} chmod 0660 ${TEMP} exec 3>&1 >${TEMP} 2>&1 fi cd ${PATHETC} ## Show the status of the news system. ${DOSTAT} && { ${INNSTAT} echo '' } ## Lock out others. trap 'rm -f ${LOCK} ; exit 1' 1 2 3 15 shlock -p $$ -f ${LOCK} || { ( echo "$0: Locked by `cat ${LOCK}`"; ${INNSTAT} ) | eval ${MAIL} exit 1 } ## Run any user programs. if [ -n "${PROGRAMS}" ] ; then for P in ${PROGRAMS} ; do echo '' echo "${P}:" eval ${P} done fi ${DOLOGS} && { echo '' scanlogs ${SCANARG} } # group-based expiry (delete expired overview first) if [ ${DOGROUPBASEEXPIRY} = true -a ${DOEXPIREOVER} = true ] ; then if ${DOEXPLOG}; then echo "${EXPIREOVER} start `date`: (${EXPIREOVERFLAGS})" >>${EXPLOG} fi ( cd ${HISTDIR} ; exec 2>&1 ; eval ${EXPIREOVER} "${EXPIREOVERFLAGS}" ) \ >>${EXPLOG} if ${DOEXPLOG}; then echo "${EXPIREOVER} end `date`" >>${EXPLOG} fi test -n "${LOWMARKFILE}" && { echo "lowmarkrenumber begin `date`: (${LOWMARKFILE})" >>${EXPLOG} ctlinnd -s -t`wc -l <${ACTIVE}` lowmark ${LOWMARKFILE} 2>&1 echo "lowmarkrenumber end `date`" >>${EXPLOG} rm -f ${MOST_LOGS}/expire.lastlowmark mv ${LOWMARKFILE} ${MOST_LOGS}/expire.lastlowmark } test -n "${RMFILE}" -a -s "${RMFILE}" && { mv ${RMFILE} ${RMFILE}.$$ && RMFILE=${RMFILE}.$$ test -n "${TMPDIR}" && SORT="${SORT} -T ${TMPDIR}" ${SORT} -u -o ${RMFILE} ${RMFILE} if ${DOEXPLOG}; then echo " expirerm start `date`" >>${EXPLOG} fi expirerm ${RMFILE} if ${DOEXPLOG}; then echo " expirerm end `date`" >>${EXPLOG} fi } DOEXPIREOVER=false fi ## The heart of the matter: prologs, expire, epilogs. if ${DOEXPIRE} ; then ## Wait to be fairly certain innwatch is not in the middle of a pass ## Since we're locked, innwatch will pause now till we're done sleep 30 ## See if we're throttled for lack of space. SERVERMODE=`ctlinnd -t $TOUT mode 2>/dev/null | ${SED} 1q` case "${SERVERMODE}" in 'Server paused'*'[innwatch:'*) ## If paused, by innwatch, then turn pause into throttle ## as we're going to stay that way for a while now ctlinnd -t $TOUT -s throttle \ "`expr \"${SERVERMODE}\" : 'Server paused \(.*\)'`" || { ( echo "$0: Cannot throttle while innwatch paused"; ${INNSTAT} ) | eval ${MAIL} exit 1 } esac case "${SERVERMODE}" in *space*" -- throttling") echo "${SERVERMODE} -- trying to recover" THROTTLED=true EXPIREFLAGS="${EXPIREFLAGS} -n" MESSAGE= ;; *"[innwatch:"*) echo "${SERVERMODE} -- pressing on" THROTTLED=false EXPIREFLAGS="${EXPIREFLAGS} -n" MESSAGE= DORENUMBER=false ;; *) THROTTLED=false ;; esac ## Throttle server if we need to. if [ -n "${MESSAGE}" ] ; then ctlinnd -t $TOUT -s -t120 throttle "${MESSAGE}" 2>&1 || { ( echo "$0: Cannot throttle news"; ${INNSTAT} ) | eval ${MAIL} exit 1 } fi # # Get rid of an old expire RMFILE since news.daily locks itself and # we would not get here if another instance were still running. # if [ -n "${RMFILE}" ] ; then rm -f ${RMFILE} fi ## Actual expire the articles (finally!). test -n "${EXPIRECTL}" && EXPIREFLAGS="${EXPIREFLAGS} ${EXPIRECTL}" if ${DOEXPLOG}; then echo "expire begin `date`: (${EXPIREFLAGS})" >>${EXPLOG} ( cd ${HISTDIR}; exec 2>&1 ; eval expire "${EXPIREFLAGS}" ) \ | ${SED} -e '/No such file or directory/d' \ -e 's/^/ /' >>${EXPLOG} echo "expire end `date`" >>${EXPLOG} else eval expire "${EXPIREFLAGS}" 2>&1 | grep -v 'No such file or directory' fi ## If built on another filesystem, move history files. if [ -n "${EXPDIR}" ] ; then if [ ! -f ${EXPDIR}/history.n -o ! -f ${EXPDIR}/history.n.done ] ; then ( echo "$0: No new history files"; ${INNSTAT} ) | eval ${MAIL} exit 1 fi cp /dev/null ${HISTORY} mv -f ${EXPDIR}/history.n ${HISTORY} mv -f ${EXPDIR}/history.n.dir ${HISTORY}.dir if [ X${TAGGEDHASH} = XDO ] ; then mv -f ${EXPDIR}/history.n.pag ${HISTORY}.pag else mv -f ${EXPDIR}/history.n.index ${HISTORY}.index mv -f ${EXPDIR}/history.n.hash ${HISTORY}.hash fi rm -f ${EXPDIR}/history.n.done case "${EXPIREFLAGS}" in *-n*) ;; *) MESSAGE="${REASON}" ;; esac fi ## Restart the server if we need to. if ${THROTTLED} || test -n "${MESSAGE}" ; then ctlinnd -t "$TOUT" -s go "${MESSAGE}" 2>&1 || { ( echo "$0: Cannot unthrottle news"; ${INNSTAT} ) | eval ${MAIL} exit 1 } fi if ${DOEXPLOG}; then echo " all done `date`" >>${EXPLOG} fi fi ## Remove old sockets. ${DORM} && find ${TEMPSOCKDIR} -name "${TEMPSOCK}" -mtime +2 -exec rm -f '{}' ';' ## Did we became throttled during the run? SERVERMODE=`ctlinnd mode 2>/dev/null | ${SED} 1q` case "${SERVERMODE}" in *space*" -- throttling") ## We did, try to unthrottle the server. echo "${SERVERMODE} -- trying to recover" ctlinnd -s go "" ;; esac ## Release the lock now, everything below this must be able to withstand ## simultaneous news.daily's running. We do this so innwatch can start ## monitoring again asap after the expire is done -- removing the ## articles isn't critical, nor is the renumber. rm ${LOCK} ## Remove the articles that are supposed to go if [ ${DOEXPIRE} = true -a ${DOGROUPBASEEXPIRY} != true ] ; then test -n "${RMFILE}" -a -s "${RMFILE}" && { mv ${RMFILE} ${RMFILE}.$$ && RMFILE=${RMFILE}.$$ test -n "${TMPDIR}" && SORT="${SORT} -T ${TMPDIR}" ${SORT} -u -o ${RMFILE} ${RMFILE} if ${DOEXPLOG}; then echo " expirerm start `date`" >>${EXPLOG} fi expirerm ${RMFILE} if ${DOEXPLOG}; then echo " expirerm end `date`" >>${EXPLOG} fi ${DOEXPIREOVER} && { if ${DOEXPLOG}; then echo " ${EXPIREOVER} start `date`" >>${EXPLOG} fi ( cd ${HISTDIR} ; eval ${EXPIREOVER} "${EXPIREOVERFLAGS}" 2>&1 ) | \ grep -v 'No such file or directory' DOEXPIREOVER=false if ${DOEXPLOG}; then echo " ${EXPIREOVER} end `date`" >>${EXPLOG} fi } test -n "${LOWMARKFILE}" && { echo "lowmarkrenumber begin `date`: (${LOWMARKFILE})" >>${EXPLOG} ctlinnd -s -t`wc -l <${ACTIVE}` lowmark ${LOWMARKFILE} 2>&1 echo "lowmarkrenumber end `date`" >>${EXPLOG} rm -f ${MOST_LOGS}/expire.lastlowmark mv ${LOWMARKFILE} ${MOST_LOGS}/expire.lastlowmark } } # expire overview lines for files we just removed if ${DOEXPIREOVER}; then if ${DOEXPLOG}; then echo " ${EXPIREOVER} start `date`" >>${EXPLOG} fi ( cd ${HISTDIR} ; eval ${EXPIREOVER} "${EXPIREOVERFLAGS}" 2>&1 ) | \ grep -v 'No such file or directory' DOEXPIREOVER=false if ${DOEXPLOG}; then echo " ${EXPIREOVER} end `date`" >>${EXPLOG} fi test -n "${LOWMARKFILE}" && { echo "lowmarkrenumber begin `date`: (${LOWMARKFILE})" >>${EXPLOG} ctlinnd -s -t`wc -l <${ACTIVE}` lowmark ${LOWMARKFILE} 2>&1 echo "lowmarkrenumber end `date`" >>${EXPLOG} rm -f ${MOST_LOGS}/expire.lastlowmark mv ${LOWMARKFILE} ${MOST_LOGS}/expire.lastlowmark } fi fi # in case noexpire expireover if ${DOEXPIREOVER}; then if ${DOEXPLOG}; then echo " ${EXPIREOVER} start `date`" >>${EXPLOG} fi ( cd ${HISTDIR} ; eval ${EXPIREOVER} "${EXPIREOVERFLAGS}" 2>&1 ) | \ grep -v 'No such file or directory' if ${DOEXPLOG}; then echo " ${EXPIREOVER} end `date`" >>${EXPLOG} fi test -n "${LOWMARKFILE}" && { echo "lowmarkrenumber begin `date`: (${LOWMARKFILE})" >>${EXPLOG} ctlinnd -s -t`wc -l <${ACTIVE}` lowmark ${LOWMARKFILE} 2>&1 echo "lowmarkrenumber end `date`" >>${EXPLOG} rm -f ${MOST_LOGS}/expire.lastlowmark mv ${LOWMARKFILE} ${MOST_LOGS}/expire.lastlowmark } fi ## Renumber the active file. if ${DORENUMBER} ; then echo '' echo 'Renumbering active file.' if [ -z "${RENUMBER}" ] ;then ctlinnd -s -t`wc -l <${ACTIVE}` renumber '' 2>&1 else while read GROUP hi lo flag ; do ctlinnd -s renumber ${GROUP} 2>&1 sleep ${RENUMBER} done <${ACTIVE} fi fi ## Display expire log messages if ${DOMAIL} ; then if [ -s ${EXPLOG} ] ; then echo Expire messages: cat ${EXPLOG} echo --------- echo '' fi fi ## Show the status of the news system after expiration. ${DOSTAT} && { echo 'Post expiration status:' ; echo '' ${INNSTAT} echo '' } ## Mail the report. if ${DOMAIL} ; then # Stop using the temp file, and mail captured output. exec 1>&3 2>&1 3>&- MAIL="${MAILCMD} -s \"${MAILSUBJ}\" ${NEWSMASTER}" test -s ${TEMP} && cat ${TEMP} | ${SED} -e 's/^~/~~/' | eval ${MAIL} rm -f ${TEMP} fi ## Run any user programs. if [ -n "${POSTPROGRAMS}" ] ; then for P in ${POSTPROGRAMS} ; do echo '' echo "${P}:" eval ${P} done fi ## All done if ${DAILY} ; then date >${PATHDB}/.news.daily fi ${RNEWS} -U exit 0