rpms/fcron/devel fcron_config_modified.c, NONE, 1.1 fcron.LISEZMOI, 1.3, 1.4 fcron.README, 1.3, 1.4 fcron.spec, 1.17, 1.18 fcron_watch_config, 1.2, 1.3

Patrice Dumas pertusus at fedoraproject.org
Fri Dec 5 19:37:28 UTC 2008


Author: pertusus

Update of /cvs/extras/rpms/fcron/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv13244

Modified Files:
	fcron.LISEZMOI fcron.README fcron.spec fcron_watch_config 
Added Files:
	fcron_config_modified.c 
Log Message:
* Fri Dec  5 2008 Patrice Dumas <pertusus[AT]free[DOT]fr> 3.0.4-4
  - instead of using inotifywait use a specific C program to watch config
  - don't try to run anything in the default case and merge the 
    fcron-watch-config subpackage



--- NEW FILE fcron_config_modified.c ---
/*	--*- c -*--
 * 
 * placed in the public domain by Patrice Dumas, Dec 2008.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/inotify.h>
#include <libgen.h>
#include <sys/types.h>
#include <dirent.h>

typedef struct fcron_watched_file {
   char * filename;
   int already_here;
} fcron_watched_file;

#ifndef SYSCONFDIR
# define SYSCONFDIR "/etc"
#endif

fcron_watched_file watched_config_files [] = {
 { SYSCONFDIR "/crontab", 0 },
 { SYSCONFDIR "/fcrontab", 0 },
 {NULL, 0}
};

#ifndef CRONDIR
#define CRONDIR SYSCONFDIR "/cron.d" 
#endif

/* size of the event structure, not counting name */
#define EVENT_SIZE  (sizeof (struct inotify_event))
/* 1024 events with filenames of length 1024 */
#define BUF_LEN        (1024 * (EVENT_SIZE + 1024))
char events_buffer[BUF_LEN];

int main(int argc, char *argv[])
{
 int fd;
 int watch_desc;
 int watch_desc_sysconfdir;
 int watch_sysconfdir = 0;
 fcron_watched_file *watched_file;
 struct stat st;
 DIR *crondir_dir;
 struct dirent *cron_dir_entry;
 char *file_in_crondir_filename;
 int file_in_crondir_size = 1024;

 if ((file_in_crondir_filename = malloc(sizeof(char) * (file_in_crondir_size+1))) == NULL)
  return EXIT_FAILURE;
 
 fd = inotify_init();
 if (fd < 0) {
  perror("inotify_init()");
  return EXIT_FAILURE;
 }

 watch_desc = inotify_add_watch(fd, CRONDIR, IN_CREATE | IN_MOVE | IN_DELETE);
 if (watch_desc < 0) {
  perror("inotify_add_watch("CRONDIR")");
  close(fd);
  return EXIT_FAILURE;
 }

 /* add watches to files in CRONDIR */
 if ((crondir_dir = opendir(CRONDIR)) == NULL ) {
  perror("opendir("CRONDIR")");
  close(fd);
  return EXIT_FAILURE;
 }
 while ((cron_dir_entry = readdir(crondir_dir))) {
  if (!strncmp(".", cron_dir_entry->d_name, 1) || !strncmp("..", cron_dir_entry->d_name, 2))
   continue;
  /* allocate enough storage for CRONDIR files. This should never been 
   * needed, since there are already 1024 char */
  while (file_in_crondir_size < (strlen(cron_dir_entry->d_name) + strlen(CRONDIR"/")+1)) {
   file_in_crondir_size = file_in_crondir_size * 2;
   if ((file_in_crondir_filename = realloc(file_in_crondir_filename, file_in_crondir_size)) == NULL) {
    close(fd);
    return EXIT_FAILURE;
   }
  }
  strcpy(file_in_crondir_filename, CRONDIR"/");
  strcat(file_in_crondir_filename, cron_dir_entry->d_name);
  watch_desc = inotify_add_watch(fd, file_in_crondir_filename, IN_DELETE_SELF | IN_MOVE_SELF | IN_CLOSE_WRITE);
  if (watch_desc < 0) {
   if (lstat(file_in_crondir_filename, &st) == 0)
   {
    fprintf(stderr, "inotify_add_watch(%s): %s\n", file_in_crondir_filename, strerror(errno));
    close(fd);
    return EXIT_FAILURE;
   }
   else { /* the file was removed before the inotify_add_watch */
    return EXIT_SUCCESS;
   }
  }
 }
 closedir(crondir_dir);

 /* now turn to crontab and fcrontab.
 * if file exist, add a watch, otherwise set a watch on the up directory 
 * to watch file appear */
 for (watched_file = watched_config_files; watched_file->filename != NULL; watched_file++) {
  if (lstat(watched_file->filename, &st) == 0) {
   watch_desc = inotify_add_watch(fd, watched_file->filename, IN_DELETE_SELF | IN_MOVE_SELF | IN_CLOSE_WRITE);
   if (watch_desc < 0) {
    if (lstat(watched_file->filename, &st) == 0) {
     fprintf(stderr, "inotify_add_watch(%s): %s\n", watched_file->filename, strerror(errno));
     close(fd);
     return EXIT_FAILURE;
    }
    else { /* file was removed between the first stat and inotify_add_watch */
     return EXIT_SUCCESS;
    }
   }
   watched_file->already_here = 1;
  }
  else if (! watch_sysconfdir) {
   watch_desc_sysconfdir = inotify_add_watch(fd, SYSCONFDIR, IN_CREATE | IN_MOVED_TO);
   if (watch_desc_sysconfdir < 0) {
    perror("inotify_add_watch("SYSCONFDIR")");
    close(fd);
    return EXIT_FAILURE;
   }
   watch_sysconfdir = 1;
  }
 }

 /* the loop is needed in case crontab or fcrontab file is missing
 * since in that case we don't exit if another file is added in 
 * SYSCONFDIR */
 while (1)
 {
  fd_set fds;
  int rc;
  int len;
  int i = 0;

  FD_ZERO(&fds);
  FD_SET(fd, &fds);
  rc = select(fd+1, &fds, NULL, NULL, NULL);
  if (rc < 0) {
   perror("select()");
   close(fd);
   return EXIT_FAILURE;
  }

  len = read (fd, events_buffer, BUF_LEN);
  if (len < 0) {
   perror ("read");
   close(fd);
   return EXIT_FAILURE;
  }
  else if (!len) {/* what does it mean ?*/
   /* in doubt it is as if something changed */
   return EXIT_SUCCESS;
  }
  
  while (i < len)
  {
   struct inotify_event *event;
   event = (struct inotify_event *) &events_buffer[i];
   /* printf ("wd=%d mask=%u cookie=%u len=%u\n",
                event->wd, event->mask,
                event->cookie, event->len);

        if (event->len)
                printf ("name=%s\n", event->name); */
   if (watch_sysconfdir && (event->wd == watch_desc_sysconfdir) && event->len) {
    for (watched_file = watched_config_files; watched_file->filename != NULL; watched_file++) {
     if ((strcmp(event->name, basename(watched_file->filename)) == 0) && (!watched_file->already_here)) {
      return EXIT_SUCCESS;
     }
    }
    i += EVENT_SIZE + event->len;
   }
   else {
    return EXIT_SUCCESS;
   }
  }
 }
}


Index: fcron.LISEZMOI
===================================================================
RCS file: /cvs/extras/rpms/fcron/devel/fcron.LISEZMOI,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- fcron.LISEZMOI	18 Sep 2008 11:53:33 -0000	1.3
+++ fcron.LISEZMOI	5 Dec 2008 19:36:58 -0000	1.4
@@ -9,7 +9,12 @@
 
   fcrontab /etc/crontab
 
-et de recommencer chaque fois que vous modifiez ce fichier.
+Le service fcron_watch_config permet de faire en sorte que les fichiers
+de contrôle de fcron soient régénérés automatiquement quand /etc/fcrontab
+/etc/crontab ou un fichier de /etc/cron.d est modifié. Pour activer ce 
+service par défaut, il faut faire :
+
+  chkconfig --level 2345 fcron_watch_config on
 
 Enfin, si l'administrateur souhaite désintaller définitivement ce paquet,
 il devra supprimer à la main l'utilisateur fcron et le répertoire


Index: fcron.README
===================================================================
RCS file: /cvs/extras/rpms/fcron/devel/fcron.README,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- fcron.README	18 Sep 2008 11:53:33 -0000	1.3
+++ fcron.README	5 Dec 2008 19:36:58 -0000	1.4
@@ -7,7 +7,11 @@
 
   fcrontab /etc/crontab
 
-This should be done everytime the file is modified.
+The fcron_watch_config service synchronizes automatically fcron control files
+with /etc/fcrontab, /etc/crontab and files in /etc/cron.d whenever they
+are modified. To activate this service in the default case, one should run: 
+
+  chkconfig --level 2345 fcron_watch_config on
 
 To remove definitively the fcron package, you'll have to remove the fcron
 user by hand, and the /var/spool/fcron directory which contains the


Index: fcron.spec
===================================================================
RCS file: /cvs/extras/rpms/fcron/devel/fcron.spec,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- fcron.spec	2 Dec 2008 23:21:35 -0000	1.17
+++ fcron.spec	5 Dec 2008 19:36:58 -0000	1.18
@@ -1,6 +1,6 @@
 Name:		fcron
 Version:	3.0.4
-Release:	3%{?dist}
+Release:	4%{?dist}
 Summary:	A task scheduler
 Summary(fr):	Un ordonnanceur de tâches
 Summary(it):	Uno schedulatore di processi
@@ -14,6 +14,7 @@
 Source3:	fcron_watch_config
 Source4:	fcron_watch_config.init
 Source5:	daemon_fcron_watch_config
+Source6:	fcron_config_modified.c
 Patch0:		fcron-3.0.4-dist_install.patch
 Patch1:		fcron-3.0.4-LSB.patch
 Patch3:		fcron-3.0.2-accept_readable_fcron.conf.patch
@@ -22,6 +23,7 @@
 Requires:	syslog
 Requires:	/usr/sbin/sendmail
 Requires:	vim-minimal
+Requires:       %{_bindir}/setsid
 
 BuildRequires:	pam-devel
 BuildRequires:	libselinux-devel
@@ -76,24 +78,6 @@
 automatica di fcron al boot, oppure puo iusare chkconfig come illustrato nel
 file %{_docdir}/%{name}-%{version}/README.Package file.
 
-%package watch-config
-Summary:	Set up fcron to watch config files like Vixie cron does
-Group:		Applications/System
-Requires:       %{name} = %{version}-%{release}
-Requires:       inotify-tools, %{_bindir}/setsid
-
-Requires(post):		chkconfig
-Requires(preun):	chkconfig, initscripts
-Requires(postun):	initscripts
-
-%description watch-config
-Starts a shell script that watch over configuration files like Vixie cron 
-does, together with fcron fcrontab. Instead of checking every second, 
-inotify is used to watch files and directories. The service should be 
-restarted if an /etc/crontab or /etc/fcrontab file that did not exist before
-is created.
-
-
 %prep
 
 %setup -q
@@ -116,6 +100,8 @@
 %configure --with-boot-install=no
 make %{?_smp_mflags}
 
+%{__cc} %{SOURCE6} %{optflags} -D SYSCONFDIR='"%{_sysconfdir}"' -o fcron_config_modified
+
 %install
 %{__rm} -rf %{buildroot}
 
@@ -160,6 +146,8 @@
 
 %{__install} -m755 -p %{SOURCE5} %{buildroot}%{_sbindir}/
 
+%{__install} -m755 fcron_config_modified %{buildroot}%{_bindir}
+
 mkdir -p %{buildroot}%{_sysconfdir}/cron.d
 
 # remove a page that is hold in cron
@@ -194,30 +182,22 @@
 
 %post
 /sbin/chkconfig --add %{name}
+/sbin/chkconfig --add %{name}_watch_config
 
 %postun
 if [ "$1" -ge "1" ] ; then
     /sbin/service %{name} condrestart >/dev/null 2>&1 || :
 fi
+if [ "$1" -ge "1" ] ; then
+    /sbin/service %{name}_watch_config condrestart >/dev/null 2>&1 || :
+fi
 
 %preun
 if [ "$1" = "0" ]
 then
   /sbin/service %{name} stop >/dev/null 2>&1
   /sbin/chkconfig --del %{name}
-fi
-
-%post watch-config
-/sbin/chkconfig --add %{name}_watch_config
-
-%postun watch-config
-if [ "$1" -ge "1" ] ; then
-    /sbin/service %{name}_watch_config condrestart >/dev/null 2>&1 || :
-fi
 
-%preun watch-config
-if [ "$1" = "0" ]
-then
   /sbin/service %{name}_watch_config stop >/dev/null 2>&1
   /sbin/chkconfig --del %{name}_watch_config
 fi
@@ -230,6 +210,7 @@
 %doc doc/en/HTML/ doc/fr/HTML-fr/ doc/en/txt/*
 %doc README.Package LISEZMOI.Package
 %{_initrddir}/fcron
+%{_initrddir}/fcron_watch_config
 %config(noreplace) %{_sysconfdir}/fcron.conf
 %config(noreplace) %{_sysconfdir}/fcron.allow
 %config(noreplace) %{_sysconfdir}/fcron.deny
@@ -243,21 +224,23 @@
 %lang(fr) %{_mandir}/fr/man8/*
 %attr(04754,root,fcron) %{_bindir}/fcronsighup
 %{_bindir}/fcrondyn
+%{_bindir}/fcron_config_modified
 %attr(06755,fcron,fcron) %{_bindir}/fcrontab
 %{_sbindir}/fcron
 %{_sbindir}/fcron-update-crontabs
 %{_sbindir}/check_system_crontabs
+%{_sbindir}/fcron_watch_config
+%{_sbindir}/daemon_fcron_watch_config
 %dir %attr(770,fcron,fcron) %{_localstatedir}/spool/fcron
 %ghost %{_localstatedir}/run/fcron.pid
-
-%files watch-config
-%defattr(-,root,root,-)
 %dir %{_sysconfdir}/cron.d
-%{_initrddir}/fcron_watch_config
-%{_sbindir}/fcron_watch_config
-%{_sbindir}/daemon_fcron_watch_config
 
 %changelog
+* Fri Dec  5 2008 Patrice Dumas <pertusus[AT]free[DOT]fr> 3.0.4-4
+  - instead of using inotifywait use a specific C program to watch config
+  - don't try to run anything in the default case and merge the 
+    fcron-watch-config subpackage
+
 * Sun Nov 30 2008 Patrice Dumas <pertusus[AT]free[DOT]fr> 3.0.4-3
   - fcron_watch_config really kill its children
   - remove crontabs requires, to be like cronie


Index: fcron_watch_config
===================================================================
RCS file: /cvs/extras/rpms/fcron/devel/fcron_watch_config,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- fcron_watch_config	2 Dec 2008 23:21:35 -0000	1.2
+++ fcron_watch_config	5 Dec 2008 19:36:58 -0000	1.3
@@ -7,36 +7,20 @@
 
 trap ':' TERM
 
-fcron_config_files="/etc/crontab /etc/fcrontab"
-fcron_present_files=
-
 while true; do
- fcron_present_files=
- for file in $fcron_config_files; do
-  [ -f $file ] && fcron_present_files="$fcron_present_files $file"
- done
- inotifywait -q $fcron_present_files /etc/cron.d &
- inotifypid=$!
- wait $inotifypid
- inotifyres=$?
-
- if [ z"$inotifyres" = 'z0' ]; then :
-  # some change on the file status, or file removal
- elif [ z"$inotifyres" = 'z1' ]; then
-  # inotifywait exits with status 0 if a file was removed... So we should
-  # never go here (doc implies an exit status of 1 upon file removal?)
-  file_removed=no
-  for file in $fcron_present_files; do
-   if [ ! -f $file ]; then
-    file_removed=yes
-    break
-   fi
-  done
+ fcron_config_modified &
+ notifypid=$!
+ wait $notifypid
+ notifyres=$?
+ 
+ if [ z"$notifyres" = 'z0' ]; then :
+  # some change in th econfig files
+ elif [ z"$notifyres" = 'z1' ]; then
   # some error happened
-  [ "$file_removed" = "no" ] && exit 1
+  exit 1
  else
-  # a signal was received, kill inotifywait. Could verify that $inotifyres > 128.
-  kill -TERM $inotifypid
+  # a signal was received, kill notification. Could verify that $notifyres > 128.
+  kill -TERM $notifypid
   exit 0
  fi
 




More information about the fedora-extras-commits mailing list