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