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