View | Details | Raw Unified | Return to bug 140621
Collapse All | Expand All

(-)isc-cron/Makefile (-1 / +10 lines)
Lines 25-30 Link Here
25
MAN5=		crontab.5
25
MAN5=		crontab.5
26
MAN8=		cron.8
26
MAN8=		cron.8
27
27
28
OPTIONS= \
29
	CROND "Enable cron.d support" Off
30
31
.include <bsd.port.pre.mk>
32
33
.if defined(WITH_CROND)
34
EXTRA_PATCHES+=	${FILESDIR}/opt-patch-cron.d
35
.endif
36
28
do-extract:
37
do-extract:
29
	${MKDIR} ${WRKSRC}
38
	${MKDIR} ${WRKSRC}
30
	cd ${WRKSRC} && ${SH} ${DISTDIR}/${DISTNAME}
39
	cd ${WRKSRC} && ${SH} ${DISTDIR}/${DISTNAME}
Lines 41-44 Link Here
41
post-install:
50
post-install:
42
	${CAT} ${PKGMESSAGE}
51
	${CAT} ${PKGMESSAGE}
43
52
44
.include <bsd.port.mk>
53
.include <bsd.port.post.mk>
(-)isc-cron/files/opt-patch-cron.d (+153 lines)
Line 0 Link Here
1
diff -ru isc-cron-4.1.orig/FEATURES isc-cron-4.1/FEATURES
2
--- FEATURES	2009-10-01 17:40:45.000000000 -0700
3
+++ FEATURES	2009-10-08 17:22:22.000000000 -0700
4
@@ -82,3 +82,8 @@
5
 	act this way and do the more reasonable thing, which is (IMHO) to "or"
6
 	the various field-matches together.  In that sense this cron may not
7
 	be completely similar to some AT&T crons.
8
+
9
+--	If they exist, the /etc/cron.d/ and /usr/local/etc/cron.d/ directories
10
+	are parsed like the cron spool directory, except that the files in it
11
+	are not user-specific and are therefore read with /etc/crontab syntax
12
+	(the user is specified explicitly in the 6th column).
13
diff -ru isc-cron-4.1.orig/cron.8 isc-cron-4.1/cron.8
14
--- cron.8	2009-10-01 17:40:45.000000000 -0700
15
+++ cron.8	2009-10-08 17:08:21.000000000 -0700
16
@@ -39,7 +39,8 @@
17
 searches /var/cron/tabs for crontab files which are named after accounts in
18
 /etc/passwd; crontabs found are loaded into memory.
19
 .I Cron
20
-also searches for /etc/crontab which is in a different format (see
21
+also searches for /etc/crontab and the files in the /etc/cron.d/ and
22
+/usr/local/etc/cron.d/ directories, which are in a different format (see
23
 .IR crontab (5)).
24
 .I Cron
25
 then wakes up every minute, examining all stored crontabs, checking each
26
diff -ru isc-cron-4.1.orig/database.c isc-cron-4.1/database.c
27
--- database.c	2009-10-01 17:40:45.000000000 -0700
28
+++ database.c	2009-10-08 17:20:53.000000000 -0700
29
@@ -36,7 +36,7 @@
30
 
31
 void
32
 load_database(cron_db *old_db) {
33
-	struct stat statbuf, syscron_stat;
34
+	struct stat statbuf, syscron_stat, crond_stat, usrcrond_stat;
35
 	cron_db new_db;
36
 	DIR_T *dp;
37
 	DIR *dir;
38
@@ -53,6 +53,16 @@
39
 		(void) exit(ERROR_EXIT);
40
 	}
41
 
42
+	if (stat(CROND_DIR, &crond_stat) < OK) {
43
+		log_it("CRON", getpid(), "STAT FAILED", CROND_DIR);
44
+		(void) exit(ERROR_EXIT);
45
+	}
46
+
47
+	if (stat(USRCROND_DIR, &usrcrond_stat) < OK) {
48
+		log_it("CRON", getpid(), "STAT FAILED", USRCROND_DIR);
49
+		(void) exit(ERROR_EXIT);
50
+	}
51
+
52
 	/* track system crontab file
53
 	 */
54
 	if (stat(SYSCRONTAB, &syscron_stat) < OK)
55
@@ -65,7 +75,9 @@
56
 	 * so is guaranteed to be different than the stat() mtime the first
57
 	 * time this function is called.
58
 	 */
59
-	if (old_db->mtime == TMAX(statbuf.st_mtime, syscron_stat.st_mtime)) {
60
+	if (old_db->mtime == TMAX(usrcrond_stat.st_mtime,
61
+			      TMAX(crond_stat.st_mtime,
62
+			      TMAX(statbuf.st_mtime, syscron_stat.st_mtime)))) {
63
 		Debug(DLOAD, ("[%ld] spool dir mtime unch, no load needed.\n",
64
 			      (long)getpid()))
65
 		return;
66
@@ -76,13 +88,73 @@
67
 	 * actually changed.  Whatever is left in the old database when
68
 	 * we're done is chaff -- crontabs that disappeared.
69
 	 */
70
-	new_db.mtime = TMAX(statbuf.st_mtime, syscron_stat.st_mtime);
71
+	new_db.mtime = TMAX(usrcrond_stat.st_mtime,
72
+			    TMAX(crond_stat.st_mtime,
73
+			    TMAX(statbuf.st_mtime, syscron_stat.st_mtime)));
74
 	new_db.head = new_db.tail = NULL;
75
 
76
 	if (syscron_stat.st_mtime)
77
 		process_crontab("root", NULL, SYSCRONTAB, &syscron_stat,
78
 				&new_db, old_db);
79
 
80
+	if (!(dir = opendir(CROND_DIR))) {
81
+		log_it("CRON", getpid(), "OPENDIR FAILED", CROND_DIR);
82
+		(void) exit(ERROR_EXIT);
83
+	}
84
+
85
+	while (NULL != (dp = readdir(dir))) {
86
+		char	fname[MAXNAMLEN+1],
87
+			tabname[MAXNAMLEN+1];
88
+
89
+		/* avoid file names beginning with ".".  this is good
90
+		 * because we would otherwise waste two guaranteed calls
91
+		 * to getpwnam() for . and .., and there shouldn't be 
92
+		 * hidden files in here anyway. Also ignore files beginning
93
+		 * with '#' and ending with '~'.
94
+		 */
95
+		if (dp->d_name[0] == '.' ||
96
+		    dp->d_name[0] == '#' ||
97
+		    dp->d_name[strlen(dp->d_name) - 1] == '~')
98
+			continue;
99
+
100
+		(void) strncpy(fname, dp->d_name, MAXNAMLEN);
101
+		snprintf(tabname, MAXNAMLEN+1, "%s/%s", CROND_DIR, fname);
102
+
103
+		process_crontab("root", NULL, tabname,
104
+				&crond_stat, &new_db, old_db);
105
+	}
106
+	closedir(dir);
107
+
108
+
109
+	if (!(dir = opendir(USRCROND_DIR))) {
110
+		log_it("CRON", getpid(), "OPENDIR FAILED", USRCROND_DIR);
111
+		(void) exit(ERROR_EXIT);
112
+	}
113
+
114
+	while (NULL != (dp = readdir(dir))) {
115
+		char	fname[MAXNAMLEN+1],
116
+			tabname[MAXNAMLEN+1];
117
+
118
+		/* avoid file names beginning with ".".  this is good
119
+		 * because we would otherwise waste two guaranteed calls
120
+		 * to getpwnam() for . and .., and there shouldn't be 
121
+		 * hidden files in here anyway. Also ignore files beginning
122
+		 * with '#' and ending with '~'.
123
+		 */
124
+		if (dp->d_name[0] == '.' ||
125
+		    dp->d_name[0] == '#' ||
126
+		    dp->d_name[strlen(dp->d_name) - 1] == '~')
127
+			continue;
128
+
129
+		(void) strncpy(fname, dp->d_name, MAXNAMLEN);
130
+		snprintf(tabname, MAXNAMLEN+1, "%s/%s", USRCROND_DIR, fname);
131
+
132
+		process_crontab("root", NULL, tabname,
133
+				&usrcrond_stat, &new_db, old_db);
134
+	}
135
+	closedir(dir);
136
+
137
+
138
 	/* we used to keep this dir open all the time, for the sake of
139
 	 * efficiency.  however, we need to close it in every fork, and
140
 	 * we fork a lot more often than the mtime of the dir changes.
141
diff -ru isc-cron-4.1.orig/pathnames.h isc-cron-4.1/pathnames.h
142
--- pathnames.h	2009-10-01 17:40:45.000000000 -0700
143
+++ pathnames.h	2009-10-08 17:45:34.000000000 -0700
144
@@ -48,6 +48,9 @@
145
 			 */
146
 #define SPOOL_DIR	"tabs"
147
 
148
+#define CROND_DIR      "/etc/cron.d"
149
+#define USRCROND_DIR   "/usr/local/etc/cron.d"
150
+
151
 			/* cron allow/deny file.  At least cron.deny must
152
 			 * exist for ordinary users to run crontab.
153
 			 */

Return to bug 140621