]> granicus.if.org Git - fcron/commitdiff
Initial revision
authorthib <thib>
Sat, 26 Feb 2005 15:15:31 +0000 (15:15 +0000)
committerthib <thib>
Sat, 26 Feb 2005 15:15:31 +0000 (15:15 +0000)
script/check_system_crontabs [new file with mode: 0755]

diff --git a/script/check_system_crontabs b/script/check_system_crontabs
new file mode 100755 (executable)
index 0000000..ef499a3
--- /dev/null
@@ -0,0 +1,145 @@
+#!/bin/sh
+#
+# check_system_crontabs
+#
+# Script to check and see if any system (f)crontabs have changed, and if so 
+# build a fcrontab file from /etc/crontab, /etc/fcrontab and files from
+# /etc/cron.d/ and notify fcron about the change.
+#
+# WARNING : - if you run this script, your system fcrontab will be overridden
+#             by the content of /etc/crontab, /etc/fcrontab, /etc/cron.d :
+#             save the content of your system fcrontab first if necessary.
+#
+#           - you should not have the same lines in /etc/crontab
+#             and /etc/fcrontab, in which case the jobs would get run twice.
+#             (/etc/crontab may for example be used for Vixie-cron compatible
+#              lines, and /etc/fcrontab for the other ones)
+#
+#           - you must understand that the contents of all the mentionned
+#             files will go to a single file : the system fcrontab.
+#             This means that you should pay attention to the global option
+#             settings and environment variable assignments, which may
+#             affect the other files too while you thought it wouldn't.
+#             
+# This script was originally created for a Debian server. A number of
+# Debian packages like to drop files in /etc/cron.d/ and it would be nice
+# to have something automatically create a system fcrontab file and notify
+# fcron when those files change, so the system administrator doesn't have
+# to try and keep up with it all manually.
+#
+# It is planned that such feature is integreated directly in fcron
+# in the future (in a cleaner and more efficient way). Until then,
+# this script should be useful.
+#
+# I recommend running this script using dnotify or a similar program
+# (dnotify wait for a change in a file or a directory, and run a command
+# when it happens), with a something like that:
+# dnotify -b -p 1 -q 0 -MCDR /etc /etc/cron.d -e /usr/local/sbin/check_system_crontabs
+# in your boot scripts.
+#
+# If you can't use dnotify, you should run this script from the system fcrontab
+# with a line like this:
+#
+# @ 1 /usr/local/sbin/check_system_crontabs
+#
+# and set SLEEP_TIME_BEFORE_REBUILD to 0.
+#
+# Changelog
+# =========
+# Date        Author             Description
+# ----        ------             -----------
+# 2004/11/12  maasj@dm.org       Original version
+# 2005/02/24  Thibault Godouet   Modified to be used with dnotify 
+#                                + bug fixes and enhancement.
+#
+
+CROND_DIR=/etc/cron.d
+FCRONTAB_PROG=/usr/bin/fcrontab
+CRONTAB_FILE=/etc/crontab
+FCRONTAB_FILE=/etc/fcrontab
+FCRONTAB_FILE_GEN=/etc/fcrontab-script-gen
+FCRONTAB_FILE_TMP=/etc/fcrontab.tmp
+SLEEP_TIME_BEFORE_REBUILD=30
+
+# Function to build up a system crontab and tell fcron it's changed
+rebuild_and_notify()
+{
+  logger -s -t "[check_system_crontabs]" "Rebuilding the system fcrontab ..."
+
+  # put a warning message at the top of the file
+  echo -e "########################################" > $FCRONTAB_FILE_GEN
+  echo -e "# WARNING!!!  DO NOT EDIT THIS FILE!!! #" >> $FCRONTAB_FILE_GEN
+  echo -e "########################################" >> $FCRONTAB_FILE_GEN
+  echo -e "# Do not edit this file!  It is automatically generated from" >> $FCRONTAB_FILE_GEN
+  echo -e "# the $CRONTAB_FILE, the $FCRONTAB_FILE and $CROND_DIR/* files whenever one of" >> $FCRONTAB_FILE_GEN
+  echo -e "# those files is changed.\n#\n\n" >> $FCRONTAB_FILE_GEN
+
+  # include the standard system crontab file
+  echo -e "\n\n########################################\n# $CRONTAB_FILE\n########################################\n" >> $FCRONTAB_FILE_GEN
+  cat $CRONTAB_FILE >> $FCRONTAB_FILE_GEN
+
+  # print a nice filename header for each file in /etc/cron.d/
+  # and include its contents into the new fcron system crontab
+  for i in $CROND_DIR/* ; do
+    if [ $i != "RCS" ] ; then
+      echo -e "\n\n########################################\n# $CROND_DIR/$i\n########################################\n" >> $FCRONTAB_FILE_GEN
+      cat $i >> $FCRONTAB_FILE_GEN
+    fi
+  done
+
+  # include the system fcrontab file
+  echo -e "\n\n########################################\n# $FCRONTAB_FILE\n########################################\n" >> $FCRONTAB_FILE_GEN
+  cat $FCRONTAB_FILE >> $FCRONTAB_FILE_GEN
+
+  # Replace "@hourly" style Vixie cron extensions which fcron doesn't parse
+  cat $FCRONTAB_FILE_GEN | sed -e "s/@yearly/0 0 1 1 */g" -e "s/@annually/0 0 1 1 */g" -e "s/@monthly/0 0 1 * */g" -e "s/@weekly/0 0 * * 0/g" -e "s/@daily/0 0 * * */g" -e "s/@midnight/0 0 * * */g" -e "s/@hourly/0 * * * */g" > $FCRONTAB_FILE_TMP
+  mv -f $FCRONTAB_FILE_TMP $FCRONTAB_FILE_GEN
+
+  # notify fcron about the updated file
+  $FCRONTAB_PROG $FCRONTAB_FILE_GEN -u systab
+}
+
+NEED_REBUILD=0
+
+# change to the directory of cron files
+cd $CROND_DIR
+
+# We don't want the system fcrontab to be generated every few seconds
+# if the sys admin is working in /etc/ (we have probably been called
+# because of a change in /etc, but it may be a file not related to fcron),
+# so we sleep so as to avoid this script be run too often.
+sleep $SLEEP_TIME_BEFORE_REBUILD
+
+# This test works for file creation/deletion (deletion is not detected
+# by the next test)
+if [ $CROND_DIR -nt $FCRONTAB_FILE_GEN ]; then
+
+  NEED_REBUILD=1
+
+else
+
+  # Test each one and see if it's newer than our timestamp file
+  for i in $CROND_DIR/* ; do
+    if [ $i != "RCS" ]; then
+      if [ $i -nt $FCRONTAB_FILE_GEN ]; then
+
+        NEED_REBUILD=1
+
+      fi
+    fi
+  done
+
+fi
+
+# Test the standard /etc/crontab file and see if it has changed
+if [ $NEED_REBUILD -eq 0 -a \( $CRONTAB_FILE -nt $FCRONTAB_FILE_GEN -o $FCRONTAB_FILE -nt $FCRONTAB_FILE_GEN \) ]; then
+
+  NEED_REBUILD=1
+
+fi
+
+if [ $NEED_REBUILD -eq 1 ]; then
+
+  rebuild_and_notify
+
+fi