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