]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/periodic/periodic.sh
adlink: Remove unused devclass argument to DRIVER_MODULE.
[FreeBSD/FreeBSD.git] / usr.sbin / periodic / periodic.sh
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
11 usage () {
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
17 output_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
29 if [ $# -lt 1 ] ; then
30     usage
31 fi
32
33 # Use a deterministic path to match the preset from /etc/crontab in case
34 # periodic is run interactively.
35 export 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
39 if [ -r /etc/defaults/periodic.conf ]; then
40     . /etc/defaults/periodic.conf
41     source_periodic_confs
42 fi
43
44 host=`hostname`
45 export 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.
52 if [ $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
75 fi
76
77 if [ $# -ne 2 ]; then
78     usage
79 fi
80 shift
81 arg=$1
82
83 if [ -z "$PERIODIC_ANTICONGESTION_FILE" ] ; then
84         export PERIODIC_ANTICONGESTION_FILE=`mktemp ${TMPDIR:-/tmp}/periodic.anticongestion.XXXXXXXXXX`
85         remove_periodic_anticongestion_file=yes
86 else
87         # We might be in a recursive invocation; let the top-level invocation
88         # remove the file.
89         remove_periodic_anticongestion_file=no
90 fi
91 if [ -t 0 ]; then
92         export PERIODIC_IS_INTERACTIVE=1
93 fi
94 tmp_output=`mktemp ${TMPDIR:-/tmp}/periodic.XXXXXXXXXX`
95 context="$PERIODIC"
96 export 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
102 success=YES info=YES badconfig=NO empty_output=YES      # Defaults when ${run}_* aren't YES/NO
103 for 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
108 done
109
110 case $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     ;;
123 esac
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
158 rm -f $tmp_output
159 if [ $remove_periodic_anticongestion_file = "yes" ] ; then
160         rm -f $PERIODIC_ANTICONGESTION_FILE
161 fi