svn commit: r308139 - in head: etc/mtree usr.sbin/cron/cron usr.sbin/cron/lib

Baptiste Daroussin bapt at FreeBSD.org
Mon Oct 31 18:20:14 UTC 2016


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;


More information about the svn-src-all mailing list