diff --git a/usr.sbin/periodic/periodic.8 b/usr.sbin/periodic/periodic.8 index 2fda1db157f5..fd09fbf1b368 100644 --- a/usr.sbin/periodic/periodic.8 +++ b/usr.sbin/periodic/periodic.8 @@ -1,262 +1,267 @@ .\" Copyright (c) 1997 FreeBSD, Inc. .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .\" .Dd June 18, 2020 .Dt PERIODIC 8 .Os .Sh NAME .Nm periodic .Nd run periodic system functions .Sh SYNOPSIS .Nm .Sm off .Cm daily | weekly | monthly | security | Ar directory .Sm on .Ar ... .Sh DESCRIPTION The .Nm utility is intended to be called by .Xr cron 8 to execute shell scripts located in the specified directory. .Pp One or more of the following arguments must be specified: .Bl -tag -width "directory" .It Cm daily Perform the standard daily periodic executable run. This usually occurs early in the morning (local time). .It Cm weekly Perform the standard weekly periodic executable run. This usually occurs very early on Saturday mornings. .It Cm monthly Perform the standard monthly periodic executable run. This usually occurs on the first day of the month. .It Cm security Perform the standard daily security checks. This is usually spawned by the .Cm daily run. .It Ar directory An arbitrary directory containing a set of executables to be run. .El .Pp If an argument is an absolute directory name it is used as is, otherwise it is searched for under .Pa /etc/periodic and any other directories specified by the .Va local_periodic setting in .Xr periodic.conf 5 (see below). .Pp The .Nm utility will run each executable file in the directory or directories specified. If a file does not have the executable bit set, it is silently ignored. .Pp Each script is required to exit with one of the following values: .Bl -tag -width 4n .It 0 The script has produced nothing notable in its output. The .Ao Ar basedir Ac Ns Va _show_success variable controls the masking of this output. .It 1 The script has produced some notable information in its output. The .Ao Ar basedir Ac Ns Va _show_info variable controls the masking of this output. .It 2 The script has produced some warnings due to invalid configuration settings. The .Ao Ar basedir Ac Ns Va _show_badconfig variable controls the masking of this output. .It >2 The script has produced output that must not be masked. .El .Pp If the relevant variable (where .Aq Ar basedir is the base directory in which the script resides) is set to .Dq Li NO in .Pa periodic.conf , .Nm will mask the script output. If the variable is not set to either .Dq Li YES or .Dq Li NO , it will be given a default value as described in .Xr periodic.conf 5 . .Pp All remaining script output is delivered based on the value of the .Ao Ar basedir Ac Ns Va _output setting. .Pp If this is set to a path name (beginning with a .Ql / character), output is simply logged to that file. .Xr newsyslog 8 knows about the files .Pa /var/log/daily.log , /var/log/weekly.log and .Pa /var/log/monthly.log , and if they exist, it will rotate them at the appropriate times. These are therefore good values if you wish to log .Nm output. .Pp If the .Ao Ar basedir Ac Ns Va _output value does not begin with a .Ql / and is not empty, it is assumed to contain a list of email addresses, and the output is mailed to them. If .Ao Ar basedir Ac Ns Va _show_empty_output is set to .Dq Li NO , then no mail will be sent if the output was empty. .Pp If .Ao Ar basedir Ac Ns Va _output is not set or is empty, output is sent to standard output. .Sh ENVIRONMENT The .Nm utility sets the .Ev PATH environment to include all standard system directories, but no additional directories, such as .Pa /usr/local/bin . If executables are added which depend upon other path components, each executable must be responsible for configuring its own appropriate environment. .Sh FILES .Bl -tag -width ".Pa /etc/defaults/periodic.conf" .It Pa /etc/crontab the .Nm utility is typically called via entries in the system default .Xr cron 8 table .It Pa /etc/periodic the top level directory containing .Pa daily , .Pa weekly , .Pa monthly , and .Pa security subdirectories which contain standard system periodic executables .It Pa /etc/defaults/periodic.conf the .Pa periodic.conf system registry contains variables that control the behaviour of .Nm and the standard .Pa daily , weekly , monthly , and .Pa security scripts -.It Pa /etc/periodic.conf +.It Pa /etc/periodic.conf , ${LOCALBASE}/etc/periodic.conf this file contains local overrides for the default .Nm configuration .El .Sh EXIT STATUS Exit status is 0 on success and 1 if the command fails. .Sh EXAMPLES The system crontab should have entries for .Nm similar to the following example: .Bd -literal -offset indent # do daily/weekly/monthly maintenance 0 2 * * * root periodic daily 0 3 * * 6 root periodic weekly 0 5 1 * * root periodic monthly .Ed .Pp The .Pa /etc/defaults/periodic.conf system registry will typically have a .Va local_periodic variable reading: .Pp -.Dl local_periodic="/usr/local/etc/periodic" +.Dl local_periodic="${_localbase}/etc/periodic" +.Pp +where +.Pa ${_localbase} +is being set from within +.Pa /usr/sbin/periodic . .Pp To log .Nm output instead of receiving it as email, add the following lines to .Pa /etc/periodic.conf : .Bd -literal -offset indent daily_output=/var/log/daily.log weekly_output=/var/log/weekly.log monthly_output=/var/log/monthly.log .Ed .Pp To only see important information from daily periodic jobs, add the following lines to .Pa /etc/periodic.conf : .Bd -literal -offset indent daily_show_success=NO daily_show_info=NO daily_show_badconfig=NO .Ed .Sh DIAGNOSTICS The command may fail for one of the following reasons: .Bl -diag .It usage: periodic No directory path argument was passed to .Nm to specify where the script fragments reside. .It not found Self explanatory. .El .Sh SEE ALSO .Xr sh 1 , .Xr crontab 5 , .Xr periodic.conf 5 , .Xr cron 8 , .Xr newsyslog 8 .Sh HISTORY The .Nm utility first appeared in .Fx 3.0 . .Sh AUTHORS .An Paul Traina Aq Mt pst@FreeBSD.org .An Brian Somers Aq Mt brian@Awfulhak.org .Sh BUGS Since one specifies information about a directory using shell variables containing the string, .Aq Ar basedir , .Aq Ar basedir must only contain characters that are valid within a .Xr sh 1 variable name, alphanumerics and underscores, and the first character may not be numeric. diff --git a/usr.sbin/periodic/periodic.conf b/usr.sbin/periodic/periodic.conf index 61cebe858372..c22ff6fe652d 100644 --- a/usr.sbin/periodic/periodic.conf +++ b/usr.sbin/periodic/periodic.conf @@ -1,428 +1,428 @@ #!/bin/sh # # This is defaults/periodic.conf - a file full of useful variables that # you can set to change the default behaviour of periodic jobs on your # system. You should not edit this file! Put any overrides into one of the # $periodic_conf_files instead and you will be able to update these defaults # later without spamming your local configuration information. # # The $periodic_conf_files files should only contain values which override # values set in this file. This eases the upgrade path when defaults # are changed and new features are added. # # For a more detailed explanation of all the periodic.conf variables, please # refer to the periodic.conf(5) manual page. # # $FreeBSD$ # # What files override these defaults ? -periodic_conf_files="/etc/periodic.conf /etc/periodic.conf.local" +periodic_conf_files="/etc/periodic.conf /etc/periodic.conf.local ${_localbase}/etc/periodic.conf" -# periodic script dirs -local_periodic="/usr/local/etc/periodic" +# periodic script dirs. _localbase is being set in /usr/sbin/periodic +local_periodic="${_localbase}/etc/periodic" # Max time to sleep to avoid causing congestion on download servers anticongestion_sleeptime=3600 # Daily options # These options are used by periodic(8) itself to determine what to do # with the output of the sub-programs that are run, and where to send # that output. $daily_output might be set to /var/log/daily.log if you # wish to log the daily output and have the files rotated by newsyslog(8) # daily_output="root" # user or /file daily_show_success="YES" # scripts returning 0 daily_show_info="YES" # scripts returning 1 daily_show_badconfig="NO" # scripts returning 2 # 100.clean-disks daily_clean_disks_enable="NO" # Delete files daily daily_clean_disks_files="[#,]* .#* a.out *.core *.CKP .emacs_[0-9]*" daily_clean_disks_days=3 # If older than this daily_clean_disks_verbose="YES" # Mention files deleted # 110.clean-tmps daily_clean_tmps_enable="NO" # Delete stuff daily daily_clean_tmps_dirs="/tmp" # Delete under here daily_clean_tmps_days="3" # If not accessed for daily_clean_tmps_ignore=".X*-lock .X11-unix .ICE-unix .font-unix .XIM-unix" daily_clean_tmps_ignore="$daily_clean_tmps_ignore quota.user quota.group .snap" daily_clean_tmps_ignore="$daily_clean_tmps_ignore .sujournal" # Don't delete these daily_clean_tmps_verbose="YES" # Mention files deleted # 120.clean-preserve daily_clean_preserve_enable="YES" # Delete files daily daily_clean_preserve_days=7 # If not modified for daily_clean_preserve_verbose="YES" # Mention files deleted # 130.clean-msgs daily_clean_msgs_enable="YES" # Delete msgs daily daily_clean_msgs_days= # If not modified for # 140.clean-rwho daily_clean_rwho_enable="YES" # Delete rwho daily daily_clean_rwho_days=7 # If not modified for daily_clean_rwho_verbose="YES" # Mention files deleted # 150.clean-hoststat daily_clean_hoststat_enable="YES" # Purge sendmail host # status cache daily # 200.backup-passwd daily_backup_passwd_enable="YES" # Backup passwd & group # 210.backup-aliases daily_backup_aliases_enable="YES" # Backup mail aliases # 221.backup-gpart if [ $(sysctl -n security.jail.jailed) = 0 ]; then # Backup partition table/boot partition/MBR daily_backup_gpart_enable="YES" else daily_backup_gpart_enable="NO" fi daily_backup_gpart_verbose="NO" # Be verbose if new backup differs from the old one daily_backup_efi_enable="NO" # Backup EFI system partition (ESP) # 222.backup-gmirror daily_backup_gmirror_enable="NO" # Backup of gmirror info (i.e., output of `gmirror list`) daily_backup_gmirror_verbose="NO" # Log diff if new backup differs from the old one # 223.backup-zfs daily_backup_zfs_enable="NO" # Backup output from zpool/zfs list daily_backup_zfs_props_enable="NO" # Backup zpool/zfs filesystem properties daily_backup_zfs_get_flags="all" # flags passed to `zfs get` daily_backup_zfs_list_flags="" # flags passed to `zfs list` daily_backup_zpool_get_flags="all" # flags passed to `zpool get` daily_backup_zpool_list_flags="-v" # flags passed to `zpool list` daily_backup_zfs_verbose="NO" # Report diff between the old and new backups. # 300.calendar daily_calendar_enable="NO" # Run calendar -a # 310.accounting daily_accounting_enable="YES" # Rotate acct files daily_accounting_compress="NO" # Gzip rotated files daily_accounting_flags=-q # Flags to /usr/sbin/sa daily_accounting_save=3 # How many files to save # 400.status-disks daily_status_disks_enable="YES" # Check disk status daily_status_disks_df_flags="-l -h" # df(1) flags for check # 401.status-graid daily_status_graid_enable="NO" # Check graid(8) # 404.status-zfs daily_status_zfs_enable="NO" # Check ZFS daily_status_zfs_zpool_list_enable="YES" # List ZFS pools # 406.status-gmirror daily_status_gmirror_enable="NO" # Check gmirror(8) # 407.status-graid3 daily_status_graid3_enable="NO" # Check graid3(8) # 408.status-gstripe daily_status_gstripe_enable="NO" # Check gstripe(8) # 409.status-gconcat daily_status_gconcat_enable="NO" # Check gconcat(8) # 410.status-mfi daily_status_mfi_enable="NO" # Check mfiutil(8) # 420.status-network daily_status_network_enable="YES" # Check network status daily_status_network_usedns="YES" # DNS lookups are ok daily_status_network_netstat_flags="-d -W" # netstat(1) flags # 430.status-uptime daily_status_uptime_enable="YES" # Check system uptime # 440.status-mailq daily_status_mailq_enable="YES" # Check mail status daily_status_mailq_shorten="NO" # Shorten output daily_status_include_submit_mailq="YES" # Also submit queue # 450.status-security daily_status_security_enable="YES" # Security check # See also "Security options" below for more options daily_status_security_inline="NO" # Run inline ? daily_status_security_output="root" # user or /file # 460.status-mail-rejects daily_status_mail_rejects_enable="YES" # Check mail rejects daily_status_mail_rejects_logs=3 # How many logs to check daily_status_mail_rejects_shorten="NO" # Shorten output # 480.leapfile-ntpd daily_ntpd_leapfile_enable="YES" # Fetch NTP leapfile # 480.status-ntpd daily_status_ntpd_enable="NO" # Check NTP status # 500.queuerun daily_queuerun_enable="YES" # Run mail queue daily_submit_queuerun="YES" # Also submit queue # 510.status-world-kernel daily_status_world_kernel="YES" # Check the running # userland/kernel version # 800.scrub-zfs daily_scrub_zfs_enable="NO" daily_scrub_zfs_pools="" # empty string selects all pools daily_scrub_zfs_default_threshold="35" # days between scrubs #daily_scrub_zfs_${poolname}_threshold="35" # pool specific threshold # 999.local daily_local="/etc/daily.local" # Local scripts # Weekly options # These options are used by periodic(8) itself to determine what to do # with the output of the sub-programs that are run, and where to send # that output. $weekly_output might be set to /var/log/weekly.log if you # wish to log the weekly output and have the files rotated by newsyslog(8) # weekly_output="root" # user or /file weekly_show_success="YES" # scripts returning 0 weekly_show_info="YES" # scripts returning 1 weekly_show_badconfig="NO" # scripts returning 2 # 310.locate weekly_locate_enable="YES" # Update locate weekly # 320.whatis weekly_whatis_enable="YES" # Update whatis weekly # 340.noid weekly_noid_enable="NO" # Find unowned files weekly_noid_dirs="/" # Look here # 450.status-security weekly_status_security_enable="YES" # Security check # See also "Security options" above for more options weekly_status_security_inline="NO" # Run inline ? weekly_status_security_output="root" # user or /file # 999.local weekly_local="/etc/weekly.local" # Local scripts # Monthly options # These options are used by periodic(8) itself to determine what to do # with the output of the sub-programs that are run, and where to send # that output. $monthly_output might be set to /var/log/monthly.log if you # wish to log the monthly output and have the files rotated by newsyslog(8) # monthly_output="root" # user or /file monthly_show_success="YES" # scripts returning 0 monthly_show_info="YES" # scripts returning 1 monthly_show_badconfig="NO" # scripts returning 2 # 200.accounting monthly_accounting_enable="YES" # Login accounting # 450.status-security monthly_status_security_enable="YES" # Security check # See also "Security options" above for more options monthly_status_security_inline="NO" # Run inline ? monthly_status_security_output="root" # user or /file # 999.local monthly_local="/etc/monthly.local" # Local scripts # Security options security_show_success="YES" # scripts returning 0 security_show_info="YES" # scripts returning 1 security_show_badconfig="NO" # scripts returning 2 # These options are used by the security periodic(8) scripts spawned in # daily and weekly 450.status-security. security_status_logdir="/var/log" # Directory for logs security_status_diff_flags="-b -u" # flags for diff output # Each of the security_status_*_period options below can have one of the # following values: # - NO: do not run at all # - daily: only run during the daily security status # - weekly: only run during the weekly security status # - monthly: only run during the monthly security status # Note that if periodic security scripts are run from crontab(5) directly, # they will be run unless _enable or _period is set to "NO". # 100.chksetuid security_status_chksetuid_enable="YES" security_status_chksetuid_period="daily" # 110.neggrpperm security_status_neggrpperm_enable="YES" security_status_neggrpperm_period="daily" # 200.chkmounts security_status_chkmounts_enable="YES" security_status_chkmounts_period="daily" #security_status_chkmounts_ignore="^amd:" # Don't check matching # FS types security_status_noamd="NO" # Don't check amd mounts # 300.chkuid0 security_status_chkuid0_enable="YES" security_status_chkuid0_period="daily" # 400.passwdless security_status_passwdless_enable="YES" security_status_passwdless_period="daily" # 410.logincheck security_status_logincheck_enable="YES" security_status_logincheck_period="daily" # 500.ipfwdenied security_status_ipfwdenied_enable="YES" security_status_ipfwdenied_period="daily" # 510.ipfdenied security_status_ipfdenied_enable="YES" security_status_ipfdenied_period="daily" # 520.pfdenied security_status_pfdenied_enable="YES" security_status_pfdenied_period="daily" security_status_pfdenied_additionalanchors="" # 550.ipfwlimit security_status_ipfwlimit_enable="YES" security_status_ipfwlimit_period="daily" # 610.ipf6denied security_status_ipf6denied_enable="YES" security_status_ipf6denied_period="daily" # 700.kernelmsg security_status_kernelmsg_enable="YES" security_status_kernelmsg_period="daily" # 800.loginfail security_status_loginfail_enable="YES" security_status_loginfail_period="daily" # 900.tcpwrap security_status_tcpwrap_enable="YES" security_status_tcpwrap_period="daily" # Define source_periodic_confs, the mechanism used by /etc/periodic/*/* # scripts to source defaults/periodic.conf overrides safely. if [ -z "${source_periodic_confs_defined}" ]; then source_periodic_confs_defined=yes # Sleep for a random amount of time in order to mitigate the thundering # herd problem of multiple hosts running periodic simultaneously. # Will not sleep when used interactively. # Will sleep at most once per invocation of periodic anticongestion() { [ -n "$PERIODIC_IS_INTERACTIVE" ] && return if [ -f "$PERIODIC_ANTICONGESTION_FILE" ]; then rm -f $PERIODIC_ANTICONGESTION_FILE sleep `jot -r 1 0 ${anticongestion_sleeptime}` fi } # Compatibility with old daily variable names. # They can be removed in stable/11. security_daily_compat_var() { local var=$1 dailyvar value dailyvar=daily_status_security${var#security_status} periodvar=${var%enable}period eval value=\"\$$dailyvar\" [ -z "$value" ] && return echo "Warning: Variable \$$dailyvar is deprecated," \ "use \$$var instead." >&2 case "$value" in [Yy][Ee][Ss]) eval $var=YES eval $periodvar=daily ;; *) eval $var=\"$value\" ;; esac } check_yesno_period() { local var="$1" periodvar value period eval value=\"\$$var\" case "$value" in [Yy][Ee][Ss]) ;; *) return 1 ;; esac periodvar=${var%enable}period eval period=\"\$$periodvar\" case "$PERIODIC" in "security daily") case "$period" in [Dd][Aa][Ii][Ll][Yy]) return 0 ;; *) return 1 ;; esac ;; "security weekly") case "$period" in [Ww][Ee][Ee][Kk][Ll][Yy]) return 0 ;; *) return 1 ;; esac ;; "security monthly") case "$period" in [Mm][Oo][Nn][Tt][Hh][Ll][Yy]) return 0 ;; *) return 1 ;; esac ;; security) # Run directly from crontab(5). case "$period" in [Nn][Oo]) return 1 ;; *) return 0 ;; esac ;; '') # Script run manually. return 0 ;; *) echo "ASSERTION FAILED: Unexpected value for" \ "\$PERIODIC: '$PERIODIC'" >&2 exit 127 ;; esac } source_periodic_confs() { local i sourced_files for i in ${periodic_conf_files}; do case ${sourced_files} in *:$i:*) ;; *) sourced_files="${sourced_files}:$i:" [ -r $i ] && . $i ;; esac done } fi diff --git a/usr.sbin/periodic/periodic.sh b/usr.sbin/periodic/periodic.sh index cdbd1b3b57fb..bec13bc4fe89 100644 --- a/usr.sbin/periodic/periodic.sh +++ b/usr.sbin/periodic/periodic.sh @@ -1,161 +1,165 @@ #!/bin/sh - # # $FreeBSD$ # # 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 " 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 +_localbase=`/sbin/sysctl -n user.localbase 2> /dev/null` +# Set default value of _localbase if not previously set +: ${_localbase:="/usr/local"} + # 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:/usr/local/sbin:/usr/local/bin +export PATH=/sbin:/bin:/usr/sbin:/usr/bin:${_localbase}/sbin:${_localbase}/bin # 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 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 progressivly 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 $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