Author: bapt
Date: Mon Oct 31 18:20:12 2016
New Revision: 308139
URL: https://svnweb.freebsd.org/changeset/base/308139

Log:
  cron(8): add support for /etc/cron.d and /usr/local/etc/cron.d
  
  For automation tools it is way easier to maintain files in directories rather
  than modifying /etc/crontab.
  
  The files in those directories are in the same format as /etc/crontab
  
  Reviewed by:  adrian
  MFC after:    2 weeks
  Relnotes:     yes
  Sponsored by: Gandi.net
  Differential Revision:        https://reviews.freebsd.org/D8400

Modified:
  head/etc/mtree/BSD.root.dist
  head/usr.sbin/cron/cron/cron.8
  head/usr.sbin/cron/cron/cron.h
  head/usr.sbin/cron/cron/database.c
  head/usr.sbin/cron/cron/pathnames.h
  head/usr.sbin/cron/lib/misc.c

Modified: head/etc/mtree/BSD.root.dist
==============================================================================
--- head/etc/mtree/BSD.root.dist        Mon Oct 31 18:12:07 2016        
(r308138)
+++ head/etc/mtree/BSD.root.dist        Mon Oct 31 18:20:12 2016        
(r308139)
@@ -32,6 +32,8 @@
         ..
         casper
         ..
+        cron.d
+        ..
         defaults
         ..
         devd

Modified: head/usr.sbin/cron/cron/cron.8
==============================================================================
--- head/usr.sbin/cron/cron/cron.8      Mon Oct 31 18:12:07 2016        
(r308138)
+++ head/usr.sbin/cron/cron/cron.8      Mon Oct 31 18:20:12 2016        
(r308139)
@@ -17,7 +17,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd August 21, 2016
+.Dd Octobre 31, 2016
 .Dt CRON 8
 .Os
 .Sh NAME
@@ -53,7 +53,11 @@ The
 .Nm
 utility also searches for
 .Pa /etc/crontab
-which is in a different format (see
+and files in
+.Pa /etc/cron.d
+and
+.Pa /usr/local/etc/cron.d
+which are in a different format (see
 .Xr crontab 5 ) .
 .Pp
 The

Modified: head/usr.sbin/cron/cron/cron.h
==============================================================================
--- head/usr.sbin/cron/cron/cron.h      Mon Oct 31 18:12:07 2016        
(r308138)
+++ head/usr.sbin/cron/cron/cron.h      Mon Oct 31 18:20:12 2016        
(r308139)
@@ -218,7 +218,7 @@ void                set_cron_uid(void),
                unget_char(int, FILE *),
                free_entry(entry *),
                skip_comments(FILE *),
-               log_it(char *, int, char *, char *),
+               log_it(char *, int, char *, const char *),
                log_close(void);
 
 int            job_runqueue(void),

Modified: head/usr.sbin/cron/cron/database.c
==============================================================================
--- head/usr.sbin/cron/cron/database.c  Mon Oct 31 18:12:07 2016        
(r308138)
+++ head/usr.sbin/cron/cron/database.c  Mon Oct 31 18:20:12 2016        
(r308139)
@@ -45,9 +45,18 @@ load_database(old_db)
        DIR             *dir;
        struct stat     statbuf;
        struct stat     syscron_stat;
+       time_t          maxmtime;
        DIR_T           *dp;
        cron_db         new_db;
        user            *u, *nu;
+       struct {
+               const char *name;
+               struct stat st;
+       } syscrontabs [] = {
+               { SYSCRONTABS },
+               { LOCALSYSCRONTABS }
+       };
+       int i;
 
        Debug(DLOAD, ("[%d] load_database()\n", getpid()))
 
@@ -65,6 +74,16 @@ load_database(old_db)
        if (stat(SYSCRONTAB, &syscron_stat) < OK)
                syscron_stat.st_mtime = 0;
 
+       maxmtime = TMAX(statbuf.st_mtime, syscron_stat.st_mtime);
+
+       for (i = 0; i < nitems(syscrontabs); i++) {
+               if (stat(syscrontabs[i].name, &syscrontabs[i].st) != -1) {
+                       maxmtime = TMAX(syscrontabs[i].st.st_mtime, maxmtime);
+               } else {
+                       syscrontabs[i].st.st_mtime = 0;
+               }
+       }
+
        /* if spooldir's mtime has not changed, we don't need to fiddle with
         * the database.
         *
@@ -72,7 +91,7 @@ load_database(old_db)
         * so is guaranteed to be different than the stat() mtime the first
         * time this function is called.
         */
-       if (old_db->mtime == TMAX(statbuf.st_mtime, syscron_stat.st_mtime)) {
+       if (old_db->mtime == maxmtime) {
                Debug(DLOAD, ("[%d] spool dir mtime unch, no load needed.\n",
                              getpid()))
                return;
@@ -83,7 +102,7 @@ load_database(old_db)
         * actually changed.  Whatever is left in the old database when
         * we're done is chaff -- crontabs that disappeared.
         */
-       new_db.mtime = TMAX(statbuf.st_mtime, syscron_stat.st_mtime);
+       new_db.mtime = maxmtime;
        new_db.head = new_db.tail = NULL;
 
        if (syscron_stat.st_mtime) {
@@ -92,6 +111,29 @@ load_database(old_db)
                                &new_db, old_db);
        }
 
+       for (i = 0; i < nitems(syscrontabs); i++) {
+               char tabname[MAXPATHLEN];
+               if (syscrontabs[i].st.st_mtime == 0)
+                       continue;
+               if (!(dir = opendir(syscrontabs[i].name))) {
+                       log_it("CRON", getpid(), "OPENDIR FAILED",
+                           syscrontabs[i].name);
+                       (void) exit(ERROR_EXIT);
+               }
+
+               while (NULL != (dp = readdir(dir))) {
+                       if (dp->d_name[0] == '.')
+                               continue;
+                       if (dp->d_type != DT_REG)
+                               continue;
+                       snprintf(tabname, sizeof(tabname), "%s/%s",
+                           syscrontabs[i].name, dp->d_name);
+                       process_crontab("root", SYS_NAME, tabname,
+                           &syscrontabs[i].st, &new_db, old_db);
+               }
+               closedir(dir);
+       }
+
        /* we used to keep this dir open all the time, for the sake of
         * efficiency.  however, we need to close it in every fork, and
         * we fork a lot more often than the mtime of the dir changes.

Modified: head/usr.sbin/cron/cron/pathnames.h
==============================================================================
--- head/usr.sbin/cron/cron/pathnames.h Mon Oct 31 18:12:07 2016        
(r308138)
+++ head/usr.sbin/cron/cron/pathnames.h Mon Oct 31 18:20:12 2016        
(r308139)
@@ -62,6 +62,8 @@
 
                        /* 4.3BSD-style crontab */
 #define SYSCRONTAB     "/etc/crontab"
+#define SYSCRONTABS    "/etc/cron.d"
+#define LOCALSYSCRONTABS       "/usr/local/etc/cron.d"
 
                        /* what editor to use if no EDITOR or VISUAL
                         * environment variable specified.

Modified: head/usr.sbin/cron/lib/misc.c
==============================================================================
--- head/usr.sbin/cron/lib/misc.c       Mon Oct 31 18:12:07 2016        
(r308138)
+++ head/usr.sbin/cron/lib/misc.c       Mon Oct 31 18:20:12 2016        
(r308139)
@@ -385,11 +385,7 @@ out:       if (allow)
 
 
 void
-log_it(username, xpid, event, detail)
-       char    *username;
-       int     xpid;
-       char    *event;
-       char    *detail;
+log_it(char *username, int xpid, char *event, const char *detail)
 {
 #if defined(LOG_FILE) || DEBUGGING
        PID_T                   pid = xpid;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to