1#!/bin/sh - 2# 3# $FreeBSD$ 4# 5# Run nightly periodic scripts 6# 7# usage: periodic { daily | weekly | monthly | security } - run standard 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 | security }" 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 79if [ -z "$PERIODIC_ANTICONGESTION_FILE" ] ; then 80 export PERIODIC_ANTICONGESTION_FILE=`mktemp ${TMPDIR:-/tmp}/periodic.anticongestion.XXXXXXXXXX` 81fi 82if tty > /dev/null 2>&1; then 83 export PERIODIC_IS_INTERACTIVE=1 84fi 85tmp_output=`mktemp ${TMPDIR:-/tmp}/periodic.XXXXXXXXXX` 86context="$PERIODIC" 87export PERIODIC="$arg${PERIODIC:+ }${PERIODIC}" 88 89# Execute each executable file in the directory list. If the x bit is not 90# set, assume the user didn't really want us to muck with it (it's a 91# README file or has been disabled). 92 93success=YES info=YES badconfig=NO empty_output=YES # Defaults when ${run}_* aren't YES/NO 94for var in success info badconfig empty_output; do 95 case $(eval echo "\$${arg##*/}_show_$var") in 96 [Yy][Ee][Ss]) eval $var=YES;; 97 [Nn][Oo]) eval $var=NO;; 98 esac 99done 100 101case $arg in 102/*) if [ -d "$arg" ]; then 103 dirlist="$arg" 104 else 105 echo "$0: $arg not found" >&2 106 exit 1 107 fi 108 ;; 109*) dirlist= 110 for top in /etc/periodic ${local_periodic}; do 111 [ -d $top/$arg ] && dirlist="$dirlist $top/$arg" 112 done 113 ;; 114esac 115 116{ 117 empty=TRUE 118 processed=0 119 for dir in $dirlist; do 120 for file in $dir/*; do 121 if [ -x $file -a ! -d $file ]; then 122 output=TRUE 123 processed=$(($processed + 1)) 124 $file </dev/null >$tmp_output 2>&1 125 rc=$? 126 if [ -s $tmp_output ]; then 127 case $rc in 128 0) [ $success = NO ] && output=FALSE;; 129 1) [ $info = NO ] && output=FALSE;; 130 2) [ $badconfig = NO ] && output=FALSE;; 131 esac 132 [ $output = TRUE ] && { cat $tmp_output; empty=FALSE; } 133 fi 134 cp /dev/null $tmp_output 135 fi 136 done 137 done 138 if [ $empty = TRUE ]; then 139 if [ $empty_output = TRUE ]; then 140 [ $processed = 1 ] && plural= || plural=s 141 echo "No output from the $processed file$plural processed" 142 fi 143 else 144 echo "" 145 echo "-- End of $arg output --" 146 fi 147} | output_pipe $arg "$context" 148 149rm -f $tmp_output 150rm -f $PERIODIC_ANTICONGESTION_FILE 151