#!/bin/sh # Copyright 1999-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # # this script looks into /etc/cron.[hourly|daily|weekly|monthly] # for scripts to be executed. The info about last run is stored in # /var/spool/cron/lastrun LOCKDIR=/var/spool/cron/lastrun LOCKFILE=${LOCKDIR}/lock # Usage: log # Log a message via syslog. log() { local level="$1" shift logger -i -p "cron.${level}" -t run-crons "$@" } mkdir -p ${LOCKDIR} # Make sure we're not running multiple instances at once. # Try twice to lock, otherwise give up. i=0 while [ $(( i += 1 )) -le 2 ] ; do ln -sn $$ ${LOCKFILE} 2>/dev/null && break # lock failed, check for a running process. # handle both old- and new-style locking. cronpid=$(readlink ${LOCKFILE} 2>/dev/null) || cronpid=$(cat ${LOCKFILE} 2>/dev/null) || continue # lockfile disappeared? try again # better than kill -0 because we can verify that it's really # another run-crons process cmdline1=$(cat /proc/${cronpid}/cmdline 2>/dev/null) || : cmdline2=$(cat /proc/$$/cmdline) if [ "${cmdline1}" = "${cmdline2}" ] ; then # whoa, another process is really running exit 0 else rm -f ${LOCKFILE} fi done # Check to make sure locking was successful if [ ! -L "${LOCKFILE}" ] ; then echo "Can't create or read existing ${LOCKFILE}, giving up" exit 1 fi # Set a trap to remove the lockfile when we're finished trap "rm -f ${LOCKFILE}" EXIT HUP INT QUIT TERM EXIT_STATUS=0 for BASE in hourly daily weekly monthly ; do CRONDIR=/etc/cron.${BASE} test -d $CRONDIR || continue if [ -e ${LOCKDIR}/cron.$BASE ] ; then case $BASE in hourly) #>= 1 hour, 5 min -=> +65 min TIME="-cmin +65" ;; daily) #>= 1 day, 5 min -=> +1445 min TIME="-cmin +1445" ;; weekly) #>= 1 week, 5 min -=> +10085 min TIME="-cmin +10085" ;; monthly) #>= 31 days, 5 min -=> +44645 min TIME="-cmin +44645" ;; esac find ${LOCKDIR} -name cron.$BASE $TIME -exec rm {} \; 2>/dev/null || : fi # if there is no touch file, make one then run the scripts if [ ! -e ${LOCKDIR}/cron.$BASE ] ; then touch ${LOCKDIR}/cron.$BASE set +e for SCRIPT in $CRONDIR/* ; do if [ -x "${SCRIPT}" ] && [ ! -d "${SCRIPT}" ] ; then # Filter out files people do not expect to be executed. case ${SCRIPT} in .*|*~) continue ;; esac log info "($(whoami)) CMD (${SCRIPT})" $SCRIPT ret=$? if [ ${ret} -ne 0 ] ; then log err "CMD (${SCRIPT}) failed with exit status ${ret}" EXIT_STATUS=1 fi fi done fi done # Clean out bogus cron.$BASE files with future times touch ${LOCKDIR} find ${LOCKDIR} -newer ${LOCKDIR} -exec /bin/rm -f {} \; 2>/dev/null || : exit ${EXIT_STATUS}