aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/periodic/periodic.sh
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/periodic/periodic.sh')
-rw-r--r--usr.sbin/periodic/periodic.sh160
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