#!/bin/sh -
#
# $FreeBSD: src/usr.sbin/periodic/periodic.sh,v 1.21 2007/06/22 10:04:05 dwmalone Exp $
#
# Run nightly periodic scripts
#
# usage: periodic { daily | weekly | monthly } - run standard periodic 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 }"    1>&2
    exit 1
}

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

host=`hostname`
export host
tmp_output=`mktemp ${TMPDIR:-/tmp}/periodic.XXXXXXXXXX`

# 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).

for arg
do
    skippedlist=()

    # Where's our output going ?
    eval output=\$${arg##*/}_output
    case "$output" in
    /*) pipe="cat >>$output";;
    "") pipe=cat;;
    *)  pipe="mail -E -s '$host ${arg##*/} run output' $output";;
    esac

    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 
            continue
        fi;;
    *)  dirlist=
        for top in /etc/periodic ${local_periodic}
        do
            [ -d $top/$arg ] && dirlist="$dirlist $top/$arg"
        done;;
    esac

    {
        # Print the date at the beginning of all logs (3086063).
        echo
        /bin/date
        
        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))
                    result=(`/usr/bin/stat -f '%Su %Ul' $file`)
                    user=${result[0]}
                    hardlinks=${result[1]}
                    if [ $hardlinks -ne 1 ] ; then
                        skippedlist+=("$file")
                        continue
                    fi
                    /usr/bin/su $user -c $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 ] && { /bin/cat $tmp_output; empty=FALSE; }
                    fi
                    /bin/cp /dev/null $tmp_output
                fi
            done
        done
        
        if [ ! -z $skippedlist ] ; then
            echo ""
            echo "Skipped running files with too many links: ${skippedlist[@]}"
        fi
        
        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
    } | eval $pipe
done
/bin/rm -f $tmp_output
