diff options
Diffstat (limited to 'usr.sbin/periodic/periodic.sh')
| -rw-r--r-- | usr.sbin/periodic/periodic.sh | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/usr.sbin/periodic/periodic.sh b/usr.sbin/periodic/periodic.sh new file mode 100644 index 000000000000..a310f04864da --- /dev/null +++ b/usr.sbin/periodic/periodic.sh @@ -0,0 +1,160 @@ +#!/bin/sh - +# +# +# Run nightly periodic scripts +# +# usage: periodic { daily | weekly | monthly | security } - run standard scripts +# periodic /absolute/path/to/directory - run periodic scripts in dir +# + +usage () { + echo "usage: $0 <directory of files to execute>" 1>&2 + echo "or $0 { daily | weekly | monthly | security }" 1>&2 + exit 1 +} + +output_pipe() +{ + # Where's our output going ? + eval output=\$${1##*/}_output + case "$output" in + /*) pipe="cat >>$output";; + "") pipe=cat;; + *) pipe="mail -E -s '$host ${2}${2:+ }${1##*/} run output' $output";; + esac + eval $pipe +} + +if [ $# -lt 1 ] ; then + usage +fi + +# If possible, check the global system configuration file, +# to see if there are additional dirs to check +if [ -r /etc/defaults/periodic.conf ]; then + . /etc/defaults/periodic.conf + source_periodic_confs +fi + +# Use a deterministic path to match the preset from /etc/crontab in case +# periodic is run interactively. +export PATH=/sbin:/bin:/usr/sbin:/usr/bin:${_localbase}/sbin:${_localbase}/bin + +host=`hostname` +export host + +# If we were called normally, then create a lock file for each argument +# in turn and reinvoke ourselves with the LOCKED argument. This prevents +# very long running jobs from being overlapped by another run as this is +# will lead the system running progressively slower and more and more jobs +# are run at once. +if [ $1 != "LOCKED" ]; then + ret=0 + for arg; do + lockfile=/var/run/periodic.${arg##*/}.lock + lockf -s -t 0 "${lockfile}" /bin/sh $0 LOCKED "$arg" + case $? in + 0) ;; + 73) #EX_CANTCREATE + echo "can't create ${lockfile}" | \ + output_pipe $arg "$PERIODIC" + ret=1 + ;; + 75) #EX_TEMPFAIL + echo "$host ${arg##*/} prior run still in progress" | \ + output_pipe $arg "$PERIODIC" + ret=1 + ;; + *) + ret=1 + ;; + esac + done + exit $ret +fi + +if [ $# -ne 2 ]; then + usage +fi +shift +arg=$1 + +if [ -z "$PERIODIC_ANTICONGESTION_FILE" ] ; then + export PERIODIC_ANTICONGESTION_FILE=`mktemp ${TMPDIR:-/tmp}/periodic.anticongestion.XXXXXXXXXX` + remove_periodic_anticongestion_file=yes +else + # We might be in a recursive invocation; let the top-level invocation + # remove the file. + remove_periodic_anticongestion_file=no +fi +if [ -t 0 ]; then + export PERIODIC_IS_INTERACTIVE=1 +fi +tmp_output=`mktemp ${TMPDIR:-/tmp}/periodic.XXXXXXXXXX` +context="$PERIODIC" +export PERIODIC="$arg${PERIODIC:+ }${PERIODIC}" + +# Execute each executable file in the directory list. If the x bit is not +# set, assume the user didn't really want us to muck with it (it's a +# README file or has been disabled). + +success=YES info=YES badconfig=NO empty_output=YES # Defaults when ${run}_* aren't YES/NO +for var in success info badconfig empty_output; do + case $(eval echo "\$${arg##*/}_show_$var") in + [Yy][Ee][Ss]) eval $var=YES;; + [Nn][Oo]) eval $var=NO;; + esac +done + +case $arg in +/*) if [ -d "$arg" ]; then + dirlist="$arg" + else + echo "$0: $arg not found" >&2 + exit 1 + fi + ;; +*) dirlist= + for top in /etc/periodic ${local_periodic}; do + [ -d $top/$arg ] && dirlist="$dirlist $top/$arg" + done + ;; +esac + +{ + empty=TRUE + processed=0 + for dir in $dirlist; do + for file in $dir/*; do + if [ -x $file -a ! -d $file ]; then + output=TRUE + processed=$(($processed + 1)) + $file </dev/null >$tmp_output 2>&1 + rc=$? + if [ -s $tmp_output ]; then + case $rc in + 0) [ $success = NO ] && output=FALSE;; + 1) [ $info = NO ] && output=FALSE;; + 2) [ $badconfig = NO ] && output=FALSE;; + esac + [ $output = TRUE ] && { cat $tmp_output; empty=FALSE; } + fi + cp /dev/null $tmp_output + fi + done + done + if [ $empty = TRUE ]; then + if [ $empty_output = TRUE ]; then + [ $processed = 1 ] && plural= || plural=s + echo "No output from the $processed file$plural processed" + fi + else + echo "" + echo "-- End of $arg output --" + fi +} | output_pipe $arg "$context" + +rm -f $tmp_output +if [ $remove_periodic_anticongestion_file = "yes" ] ; then + rm -f $PERIODIC_ANTICONGESTION_FILE +fi |
