|
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 |
*/ |