3 ## Daily news maintenance.
5 ## expdir=xxx Directory in which to build new history file
6 ## tmpdir=xxx Working directory for `sort' and such
7 ## expirectl=xxx Use xxx as expire.ctl file
8 ## flags=xxx Pass xxx flags to expire
9 ## lowmark Create and use a lowmark file
10 ## noexpire Do not expire
11 ## noexplog Do not log expire output
12 ## nologs Do not scan logfiles
13 ## nomail Do not capture and mail output
14 ## norenumber Do not renumber the active file
15 ## norm Do not remove certain old files
16 ## norotate Do not rotate logfiles
17 ## nostat Do not run innstat
18 ## notdaily Not a daily run, and therefore implies nologs.
19 ## delayrm Delay unlink files, then do it quicker (expire -z)
20 ## /full/path Path to a program to run before expiring
22 . @LIBDIR@/innshellvars
24 EXPLOG=${MOST_LOGS}/expire.log
25 INNSTAT=${PATHBIN}/innstat
28 TAGGEDHASH=@DO_DBZ_TAGGED_HASH@
31 ## If your expire does not pause or throttle innd, enable this next line:
32 #MESSAGE="Expiration script $$"
33 ## Renumber all at once, or in steps? Set to the delay if steps (that
34 ## may take a long time!).
38 LOCK=${LOCKS}/LOCK.${PROGNAME}
57 HISTDIR="`dirname ${HISTORY}`"
58 TOUT=600 # timeout value for ctlinnd commands
59 if [ -z "${HISTDIR}" -o X"." = X"${HISTDIR}" -o ! -d "${HISTDIR}" ]; then
60 if [ -d "${PATHETC}/hist" ]; then
61 HISTDIR="${PATHETC}/hist"
66 if [ "${ENABLEOVERVIEW}" = "true" ]; then
68 RMFILE=${MOST_LOGS}/expire.rm
76 DOGROUPBASEEXPIRY=false
78 if [ "${GROUPBASEEXPIRY}" = "true" ]; then
79 if [ "${ENABLEOVERVIEW}" = "true" ]; then
80 DOGROUPBASEEXPIRY=true
92 RMFILE=${MOST_LOGS}/expire.rm
95 EXPIRECTL=`expr "${I}" : 'expctl=\(.*\)'`
100 EXPIRECTL=`/bin/pwd`/${EXPIRECTL}
105 EXPDIR=`expr "${I}" : 'expdir=\(.*\)'`
108 TMPDIR=`expr "${I}" : 'tmpdir=\(.*\)'`
112 RMFILE=${MOST_LOGS}/expire.rm
115 EXPIREOVERFLAGS=`expr "${I}" : 'expireoverflags=\(.*\)'`
118 EXPIREFLAGS=`expr "${I}" : 'flags=\(.*\)'`
121 LOWMARKFILE=${MOST_LOGS}/expire.lowmark
143 MAIL="cut -c 1-1022 | ${SED} -e 's/^~/~~/'"
155 SCANARG="${SCANARG} norotate"
161 PROGRAMS="${PROGRAMS} ${I}"
164 POSTEXEC=`expr "${I}" : 'postexec=\(.*\)'`
165 POSTPROGRAMS="${POSTPROGRAMS} ${POSTEXEC}"
168 echo "Unknown flag ${I}" 1>&2
175 ## Setup mail subject and command
178 MAILSUBJ="${HOSTNAME} Daily Usenet report for ${DATE}"
180 MAILSUBJ="${HOSTNAME} intermediate usenet report for ${DATE}"
182 MAIL="cut -c 1-1022 | ${SED} -e 's/^~/~~/' | \
183 ${MAILCMD} -s '$MAILSUBJ' ${NEWSMASTER}"
186 # Sanity check. Shouldn't we just bail out here with an error
187 # instead of trying to patch things up?
194 test -n "${EXPDIR}" && {
195 test -z "${REASON}" && REASON="Expiring $$ on ${EXPDIR}"
196 EXPIREFLAGS="${EXPIREFLAGS} '-d${EXPDIR}' '-r${REASON}'"
199 test -n "${RMFILE}" && {
200 if ${DOGROUPBASEEXPIRY} ; then
201 EXPIREOVERFLAGS="${EXPIREOVERFLAGS} -z${RMFILE}"
203 EXPIREFLAGS="${EXPIREFLAGS} -z${RMFILE}"
207 test -n "${LOWMARKFILE}" && {
208 EXPIREOVERFLAGS="${EXPIREOVERFLAGS} -Z${LOWMARKFILE}"
213 ## Try to get a temporary file.
214 TEMP=${TMPDIR}/doex$$
216 echo "Temporary file ${TEMP} exists" | eval ${MAIL}
221 exec 3>&1 >${TEMP} 2>&1
226 ## Show the status of the news system.
233 trap 'rm -f ${LOCK} ; exit 1' 1 2 3 15
234 shlock -p $$ -f ${LOCK} || {
235 ( echo "$0: Locked by `cat ${LOCK}`"; ${INNSTAT} ) | eval ${MAIL}
239 ## Run any user programs.
240 if [ -n "${PROGRAMS}" ] ; then
241 for P in ${PROGRAMS} ; do
253 # group-based expiry (delete expired overview first)
254 if [ ${DOGROUPBASEEXPIRY} = true -a ${DOEXPIREOVER} = true ] ; then
256 echo "${EXPIREOVER} start `date`: (${EXPIREOVERFLAGS})" >>${EXPLOG}
258 ( cd ${HISTDIR} ; exec 2>&1 ; eval ${EXPIREOVER} "${EXPIREOVERFLAGS}" ) \
261 echo "${EXPIREOVER} end `date`" >>${EXPLOG}
263 test -n "${LOWMARKFILE}" && {
264 echo "lowmarkrenumber begin `date`: (${LOWMARKFILE})" >>${EXPLOG}
265 ctlinnd -s -t`wc -l <${ACTIVE}` lowmark ${LOWMARKFILE} 2>&1
266 echo "lowmarkrenumber end `date`" >>${EXPLOG}
267 rm -f ${MOST_LOGS}/expire.lastlowmark
268 mv ${LOWMARKFILE} ${MOST_LOGS}/expire.lastlowmark
270 test -n "${RMFILE}" -a -s "${RMFILE}" && {
271 mv ${RMFILE} ${RMFILE}.$$ && RMFILE=${RMFILE}.$$
273 test -n "${TMPDIR}" && SORT="${SORT} -T ${TMPDIR}"
274 ${SORT} -u -o ${RMFILE} ${RMFILE}
276 echo " expirerm start `date`" >>${EXPLOG}
280 echo " expirerm end `date`" >>${EXPLOG}
286 ## The heart of the matter: prologs, expire, epilogs.
287 if ${DOEXPIRE} ; then
289 ## Wait to be fairly certain innwatch is not in the middle of a pass
290 ## Since we're locked, innwatch will pause now till we're done
293 ## See if we're throttled for lack of space.
294 SERVERMODE=`ctlinnd -t $TOUT mode 2>/dev/null | ${SED} 1q`
295 case "${SERVERMODE}" in
296 'Server paused'*'[innwatch:'*)
297 ## If paused, by innwatch, then turn pause into throttle
298 ## as we're going to stay that way for a while now
299 ctlinnd -t $TOUT -s throttle \
300 "`expr \"${SERVERMODE}\" : 'Server paused \(.*\)'`" || {
301 ( echo "$0: Cannot throttle while innwatch paused";
302 ${INNSTAT} ) | eval ${MAIL}
306 case "${SERVERMODE}" in
307 *space*" -- throttling")
308 echo "${SERVERMODE} -- trying to recover"
310 EXPIREFLAGS="${EXPIREFLAGS} -n"
314 echo "${SERVERMODE} -- pressing on"
316 EXPIREFLAGS="${EXPIREFLAGS} -n"
325 ## Throttle server if we need to.
326 if [ -n "${MESSAGE}" ] ; then
327 ctlinnd -t $TOUT -s -t120 throttle "${MESSAGE}" 2>&1 || {
328 ( echo "$0: Cannot throttle news"; ${INNSTAT} ) | eval ${MAIL}
334 # Get rid of an old expire RMFILE since news.daily locks itself and
335 # we would not get here if another instance were still running.
337 if [ -n "${RMFILE}" ] ; then
341 ## Actual expire the articles (finally!).
342 test -n "${EXPIRECTL}" && EXPIREFLAGS="${EXPIREFLAGS} ${EXPIRECTL}"
344 echo "expire begin `date`: (${EXPIREFLAGS})" >>${EXPLOG}
345 ( cd ${HISTDIR}; exec 2>&1 ; eval expire "${EXPIREFLAGS}" ) \
346 | ${SED} -e '/No such file or directory/d' \
347 -e 's/^/ /' >>${EXPLOG}
348 echo "expire end `date`" >>${EXPLOG}
350 eval expire "${EXPIREFLAGS}" 2>&1 | grep -v 'No such file or directory'
353 ## If built on another filesystem, move history files.
354 if [ -n "${EXPDIR}" ] ; then
355 if [ ! -f ${EXPDIR}/history.n -o ! -f ${EXPDIR}/history.n.done ] ; then
356 ( echo "$0: No new history files"; ${INNSTAT} ) | eval ${MAIL}
359 cp /dev/null ${HISTORY}
360 mv -f ${EXPDIR}/history.n ${HISTORY}
361 mv -f ${EXPDIR}/history.n.dir ${HISTORY}.dir
362 if [ X${TAGGEDHASH} = XDO ] ; then
363 mv -f ${EXPDIR}/history.n.pag ${HISTORY}.pag
365 mv -f ${EXPDIR}/history.n.index ${HISTORY}.index
366 mv -f ${EXPDIR}/history.n.hash ${HISTORY}.hash
368 rm -f ${EXPDIR}/history.n.done
370 case "${EXPIREFLAGS}" in
379 ## Restart the server if we need to.
380 if ${THROTTLED} || test -n "${MESSAGE}" ; then
381 ctlinnd -t "$TOUT" -s go "${MESSAGE}" 2>&1 || {
382 ( echo "$0: Cannot unthrottle news"; ${INNSTAT} ) | eval ${MAIL}
387 echo " all done `date`" >>${EXPLOG}
391 ## Remove old sockets.
393 find ${TEMPSOCKDIR} -name "${TEMPSOCK}" -mtime +2 -exec rm -f '{}' ';'
395 ## Did we became throttled during the run?
396 SERVERMODE=`ctlinnd mode 2>/dev/null | ${SED} 1q`
397 case "${SERVERMODE}" in
398 *space*" -- throttling")
399 ## We did, try to unthrottle the server.
400 echo "${SERVERMODE} -- trying to recover"
405 ## Release the lock now, everything below this must be able to withstand
406 ## simultaneous news.daily's running. We do this so innwatch can start
407 ## monitoring again asap after the expire is done -- removing the
408 ## articles isn't critical, nor is the renumber.
411 ## Remove the articles that are supposed to go
412 if [ ${DOEXPIRE} = true -a ${DOGROUPBASEEXPIRY} != true ] ; then
413 test -n "${RMFILE}" -a -s "${RMFILE}" && {
414 mv ${RMFILE} ${RMFILE}.$$ && RMFILE=${RMFILE}.$$
416 test -n "${TMPDIR}" && SORT="${SORT} -T ${TMPDIR}"
417 ${SORT} -u -o ${RMFILE} ${RMFILE}
419 echo " expirerm start `date`" >>${EXPLOG}
423 echo " expirerm end `date`" >>${EXPLOG}
427 echo " ${EXPIREOVER} start `date`" >>${EXPLOG}
429 ( cd ${HISTDIR} ; eval ${EXPIREOVER} "${EXPIREOVERFLAGS}" 2>&1 ) | \
430 grep -v 'No such file or directory'
433 echo " ${EXPIREOVER} end `date`" >>${EXPLOG}
436 test -n "${LOWMARKFILE}" && {
437 echo "lowmarkrenumber begin `date`: (${LOWMARKFILE})" >>${EXPLOG}
438 ctlinnd -s -t`wc -l <${ACTIVE}` lowmark ${LOWMARKFILE} 2>&1
439 echo "lowmarkrenumber end `date`" >>${EXPLOG}
440 rm -f ${MOST_LOGS}/expire.lastlowmark
441 mv ${LOWMARKFILE} ${MOST_LOGS}/expire.lastlowmark
444 # expire overview lines for files we just removed
445 if ${DOEXPIREOVER}; then
447 echo " ${EXPIREOVER} start `date`" >>${EXPLOG}
449 ( cd ${HISTDIR} ; eval ${EXPIREOVER} "${EXPIREOVERFLAGS}" 2>&1 ) | \
450 grep -v 'No such file or directory'
453 echo " ${EXPIREOVER} end `date`" >>${EXPLOG}
455 test -n "${LOWMARKFILE}" && {
456 echo "lowmarkrenumber begin `date`: (${LOWMARKFILE})" >>${EXPLOG}
457 ctlinnd -s -t`wc -l <${ACTIVE}` lowmark ${LOWMARKFILE} 2>&1
458 echo "lowmarkrenumber end `date`" >>${EXPLOG}
459 rm -f ${MOST_LOGS}/expire.lastlowmark
460 mv ${LOWMARKFILE} ${MOST_LOGS}/expire.lastlowmark
464 # in case noexpire expireover
465 if ${DOEXPIREOVER}; then
467 echo " ${EXPIREOVER} start `date`" >>${EXPLOG}
469 ( cd ${HISTDIR} ; eval ${EXPIREOVER} "${EXPIREOVERFLAGS}" 2>&1 ) | \
470 grep -v 'No such file or directory'
472 echo " ${EXPIREOVER} end `date`" >>${EXPLOG}
474 test -n "${LOWMARKFILE}" && {
475 echo "lowmarkrenumber begin `date`: (${LOWMARKFILE})" >>${EXPLOG}
476 ctlinnd -s -t`wc -l <${ACTIVE}` lowmark ${LOWMARKFILE} 2>&1
477 echo "lowmarkrenumber end `date`" >>${EXPLOG}
478 rm -f ${MOST_LOGS}/expire.lastlowmark
479 mv ${LOWMARKFILE} ${MOST_LOGS}/expire.lastlowmark
483 ## Renumber the active file.
484 if ${DORENUMBER} ; then
486 echo 'Renumbering active file.'
487 if [ -z "${RENUMBER}" ] ;then
488 ctlinnd -s -t`wc -l <${ACTIVE}` renumber '' 2>&1
490 while read GROUP hi lo flag ; do
491 ctlinnd -s renumber ${GROUP} 2>&1
497 ## Display expire log messages
499 if [ -s ${EXPLOG} ] ; then
500 echo Expire messages:
507 ## Show the status of the news system after expiration.
509 echo 'Post expiration status:' ; echo ''
516 # Stop using the temp file, and mail captured output.
518 MAIL="${MAILCMD} -s \"${MAILSUBJ}\" ${NEWSMASTER}"
519 test -s ${TEMP} && cat ${TEMP} | ${SED} -e 's/^~/~~/' | eval ${MAIL}
523 ## Run any user programs.
524 if [ -n "${POSTPROGRAMS}" ] ; then
525 for P in ${POSTPROGRAMS} ; do
534 date >${PATHDB}/.news.daily