]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/periodic/periodic.sh
pmap: move the smp_targeted_tlb_shutdown pointer stuff to amd64 pmap.h
[FreeBSD/FreeBSD.git] / usr.sbin / periodic / periodic.sh
1 #!/bin/sh -
2 #
3 #
4 # Run nightly periodic scripts
5 #
6 # usage: periodic { daily | weekly | monthly | security } - run standard scripts
7 #        periodic /absolute/path/to/directory  - run periodic scripts in dir
8 #
9
10 usage () {
11     echo "usage: $0 <directory of files to execute>" 1>&2
12     echo "or     $0 { daily | weekly | monthly | security }"    1>&2
13     exit 1
14 }
15
16 output_pipe()
17 {
18     # Where's our output going ?
19     eval output=\$${1##*/}_output
20     case "$output" in
21     /*) pipe="cat >>$output";;
22     "") pipe=cat;;
23     *)  pipe="mail -E -s '$host ${2}${2:+ }${1##*/} run output' $output";;
24     esac
25     eval $pipe
26 }
27
28 if [ $# -lt 1 ] ; then
29     usage
30 fi
31
32 _localbase=`/sbin/sysctl -n user.localbase 2> /dev/null`
33 # Set default value of _localbase if not previously set
34 : ${_localbase:="/usr/local"}
35
36 # Use a deterministic path to match the preset from /etc/crontab in case
37 # periodic is run interactively.
38 export PATH=/sbin:/bin:/usr/sbin:/usr/bin:${_localbase}/sbin:${_localbase}/bin
39
40 # If possible, check the global system configuration file,
41 # to see if there are additional dirs to check
42 if [ -r /etc/defaults/periodic.conf ]; then
43     . /etc/defaults/periodic.conf
44     source_periodic_confs
45 fi
46
47 host=`hostname`
48 export host
49
50 # If we were called normally, then create a lock file for each argument
51 # in turn and reinvoke ourselves with the LOCKED argument.  This prevents
52 # very long running jobs from being overlapped by another run as this is
53 # will lead the system running progressively slower and more and more jobs
54 # are run at once.
55 if [ $1 != "LOCKED" ]; then
56     ret=0
57     for arg; do
58         lockfile=/var/run/periodic.${arg##*/}.lock
59         lockf -s -t 0 "${lockfile}" /bin/sh $0 LOCKED "$arg"
60         case $? in
61         0) ;;
62         73) #EX_CANTCREATE
63             echo "can't create ${lockfile}" | \
64                 output_pipe $arg "$PERIODIC"
65             ret=1
66             ;;
67         75) #EX_TEMPFAIL
68             echo "$host ${arg##*/} prior run still in progress" | \
69                 output_pipe $arg "$PERIODIC"
70             ret=1
71             ;;
72         *)
73             ret=1
74             ;;
75         esac
76     done
77     exit $ret
78 fi
79
80 if [ $# -ne 2 ]; then
81     usage
82 fi
83 shift
84 arg=$1
85
86 if [ -z "$PERIODIC_ANTICONGESTION_FILE" ] ; then
87         export PERIODIC_ANTICONGESTION_FILE=`mktemp ${TMPDIR:-/tmp}/periodic.anticongestion.XXXXXXXXXX`
88         remove_periodic_anticongestion_file=yes
89 else
90         # We might be in a recursive invocation; let the top-level invocation
91         # remove the file.
92         remove_periodic_anticongestion_file=no
93 fi
94 if [ -t 0 ]; then
95         export PERIODIC_IS_INTERACTIVE=1
96 fi
97 tmp_output=`mktemp ${TMPDIR:-/tmp}/periodic.XXXXXXXXXX`
98 context="$PERIODIC"
99 export PERIODIC="$arg${PERIODIC:+ }${PERIODIC}"
100
101 # Execute each executable file in the directory list.  If the x bit is not
102 # set, assume the user didn't really want us to muck with it (it's a
103 # README file or has been disabled).
104
105 success=YES info=YES badconfig=NO empty_output=YES      # Defaults when ${run}_* aren't YES/NO
106 for var in success info badconfig empty_output; do
107     case $(eval echo "\$${arg##*/}_show_$var") in
108     [Yy][Ee][Ss]) eval $var=YES;;
109     [Nn][Oo])     eval $var=NO;;
110     esac
111 done
112
113 case $arg in
114 /*) if [ -d "$arg" ]; then
115         dirlist="$arg"
116     else
117         echo "$0: $arg not found" >&2
118         exit 1
119     fi
120     ;;
121 *)  dirlist=
122     for top in /etc/periodic ${local_periodic}; do
123         [ -d $top/$arg ] && dirlist="$dirlist $top/$arg"
124     done
125     ;;
126 esac
127
128 {
129     empty=TRUE
130     processed=0
131     for dir in $dirlist; do
132         for file in $dir/*; do
133             if [ -x $file -a ! -d $file ]; then
134                 output=TRUE
135                 processed=$(($processed + 1))
136                 $file </dev/null >$tmp_output 2>&1
137                 rc=$?
138                 if [ -s $tmp_output ]; then
139                     case $rc in
140                     0)  [ $success = NO ] && output=FALSE;;
141                     1)  [ $info = NO ] && output=FALSE;;
142                     2)  [ $badconfig = NO ] && output=FALSE;;
143                     esac
144                     [ $output = TRUE ] && { cat $tmp_output; empty=FALSE; }
145                 fi
146                 cp /dev/null $tmp_output
147             fi
148         done
149     done
150     if [ $empty = TRUE ]; then
151         if [ $empty_output = TRUE ]; then
152             [ $processed = 1 ] && plural= || plural=s
153             echo "No output from the $processed file$plural processed"
154         fi
155     else
156         echo ""
157         echo "-- End of $arg output --"
158     fi
159 } | output_pipe $arg "$context"
160
161 rm -f $tmp_output
162 if [ $remove_periodic_anticongestion_file = "yes" ] ; then
163         rm -f $PERIODIC_ANTICONGESTION_FILE
164 fi