1#!/bin/sh - 2# 3# $FreeBSD$ 4# 5# Run nightly periodic scripts 6# 7# usage: periodic { daily | weekly | monthly } - run standard periodic scripts 8# periodic /absolute/path/to/directory - run periodic scripts in dir 9# 10 11usage () { 12 echo "usage: $0 <directory of files to execute>" 1>&2 13 echo "or $0 { daily | weekly | monthly }" 1>&2 14 exit 1 15} 16 17output_pipe() 18{ 19 # Where's our output going ? 20 eval output=\$${1##*/}_output 21 case "$output" in 22 /*) pipe="cat >>$output";; 23 "") pipe=cat;; 24 *) pipe="mail -E -s '$host ${2}${2:+ }${1##*/} run output' $output";; 25 esac 26 eval $pipe 27} 28 29if [ $# -lt 1 ] ; then 30 usage 31fi 32 33# If possible, check the global system configuration file, 34# to see if there are additional dirs to check 35if [ -r /etc/defaults/periodic.conf ]; then 36 . /etc/defaults/periodic.conf 37 source_periodic_confs 38fi 39 40host=`hostname` 41export host 42 43# If we were called normally, then create a lock file for each argument 44# in turn and reinvoke ourselves with the LOCKED argument. This prevents 45# very long running jobs from being overlapped by another run as this is 46# will lead the system running progressivly slower and more and more jobs 47# are run at once. 48if [ $1 != "LOCKED" ]; then 49 ret=0 50 for arg; do 51 lockfile=/var/run/periodic.${arg##*/}.lock 52 lockf -t 0 "${lockfile}" /bin/sh $0 LOCKED "$arg" 53 case $? in 54 0) ;; 55 73) #EX_CANTCREATE 56 echo "can't create ${lockfile}" | \ 57 output_pipe $arg "$PERIODIC" 58 ret=1 59 ;; 60 75) #EX_TEMPFAIL 61 echo "$host ${arg##*/} prior run still in progress" | \ 62 output_pipe $arg "$PERIODIC" 63 ret=1 64 ;; 65 *) 66 ret=1 67 ;; 68 esac 69 done 70 exit $ret 71fi 72 73if [ $# -ne 2 ]; then 74 usage 75fi 76shift 77arg=$1 78 79tmp_output=`mktemp ${TMPDIR:-/tmp}/periodic.XXXXXXXXXX` 80context="$PERIODIC" 81export PERIODIC="$arg${PERIODIC:+ }${PERIODIC}" 82 83# Execute each executable file in the directory list. If the x bit is not 84# set, assume the user didn't really want us to muck with it (it's a 85# README file or has been disabled). 86 87success=YES info=YES badconfig=NO empty_output=YES # Defaults when ${run}_* aren't YES/NO 88for var in success info badconfig empty_output; do 89 case $(eval echo "\$${arg##*/}_show_$var") in 90 [Yy][Ee][Ss]) eval $var=YES;; 91 [Nn][Oo]) eval $var=NO;; 92 esac 93done 94 95case $arg in 96/*) if [ -d "$arg" ]; then 97 dirlist="$arg" 98 else 99 echo "$0: $arg not found" >&2 100 continue 101 fi 102 ;; 103*) dirlist= 104 for top in /etc/periodic ${local_periodic}; do 105 [ -d $top/$arg ] && dirlist="$dirlist $top/$arg" 106 done 107 ;; 108esac 109 110{ 111 empty=TRUE 112 processed=0 113 for dir in $dirlist; do 114 for file in $dir/*; do 115 if [ -x $file -a ! -d $file ]; then 116 output=TRUE 117 processed=$(($processed + 1)) 118 $file </dev/null >$tmp_output 2>&1 119 rc=$? 120 if [ -s $tmp_output ]; then 121 case $rc in 122 0) [ $success = NO ] && output=FALSE;; 123 1) [ $info = NO ] && output=FALSE;; 124 2) [ $badconfig = NO ] && output=FALSE;; 125 esac 126 [ $output = TRUE ] && { cat $tmp_output; empty=FALSE; } 127 fi 128 cp /dev/null $tmp_output 129 fi 130 done 131 done 132 if [ $empty = TRUE ]; then 133 if [ $empty_output = TRUE ]; then 134 [ $processed = 1 ] && plural= || plural=s 135 echo "No output from the $processed file$plural processed" 136 fi 137 else 138 echo "" 139 echo "-- End of $arg output --" 140 fi 141} | output_pipe $arg "$context" 142 143rm -f $tmp_output 144