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