Author: bapt
Date: Wed Nov 16 07:03:24 2016
New Revision: 308720
URL: https://svnweb.freebsd.org/changeset/base/308720

Log:
  MFC r308139, r308157-r308158
  
  r308139:
  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
  
  r308157:
  Fix typo in cron(8) date
  
  Reported by:  jilles
  
  r308158:
  Allow symlinks to be followed in cron.d directories and fix detection of
  regular files on NFS
  
  Reported by:  jilles

Modified:
  stable/11/etc/mtree/BSD.root.dist
  stable/11/usr.sbin/cron/cron/cron.8
  stable/11/usr.sbin/cron/cron/cron.h
  stable/11/usr.sbin/cron/cron/database.c
  stable/11/usr.sbin/cron/cron/pathnames.h
  stable/11/usr.sbin/cron/lib/misc.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/etc/mtree/BSD.root.dist
==============================================================================
--- stable/11/etc/mtree/BSD.root.dist   Wed Nov 16 07:01:52 2016        
(r308719)
+++ stable/11/etc/mtree/BSD.root.dist   Wed Nov 16 07:03:24 2016        
(r308720)
@@ -32,6 +32,8 @@
         ..
         casper
         ..
+        cron.d
+        ..
         defaults
         ..
         devd

Modified: stable/11/usr.sbin/cron/cron/cron.8
==============================================================================
--- stable/11/usr.sbin/cron/cron/cron.8 Wed Nov 16 07:01:52 2016        
(r308719)
+++ stable/11/usr.sbin/cron/cron/cron.8 Wed Nov 16 07:03:24 2016        
(r308720)
@@ -17,7 +17,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd August 21, 2016
+.Dd October 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: stable/11/usr.sbin/cron/cron/cron.h
==============================================================================
--- stable/11/usr.sbin/cron/cron/cron.h Wed Nov 16 07:01:52 2016        
(r308719)
+++ stable/11/usr.sbin/cron/cron/cron.h Wed Nov 16 07:03:24 2016        
(r308720)
@@ -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: stable/11/usr.sbin/cron/cron/database.c
==============================================================================
--- stable/11/usr.sbin/cron/cron/database.c     Wed Nov 16 07:01:52 2016        
(r308719)
+++ stable/11/usr.sbin/cron/cron/database.c     Wed Nov 16 07:03:24 2016        
(r308720)
@@ -44,10 +44,19 @@ load_database(old_db)
 {
        DIR             *dir;
        struct stat     statbuf;
-       struct stat     syscron_stat;
+       struct stat     syscron_stat, st;
+       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,30 @@ 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 (fstatat(dirfd(dir), dp->d_name, &st, 0) == 0 &&
+                           !S_ISREG(st.st_mode))
+                               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: stable/11/usr.sbin/cron/cron/pathnames.h
==============================================================================
--- stable/11/usr.sbin/cron/cron/pathnames.h    Wed Nov 16 07:01:52 2016        
(r308719)
+++ stable/11/usr.sbin/cron/cron/pathnames.h    Wed Nov 16 07:03:24 2016        
(r308720)
@@ -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: stable/11/usr.sbin/cron/lib/misc.c
==============================================================================
--- stable/11/usr.sbin/cron/lib/misc.c  Wed Nov 16 07:01:52 2016        
(r308719)
+++ stable/11/usr.sbin/cron/lib/misc.c  Wed Nov 16 07:03:24 2016        
(r308720)
@@ -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-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to