Date: Tue, 17 Nov 2009 02:53:04 GMT From: Benjamin Lee <ben@b1c1l1.com> To: freebsd-gnats-submit@FreeBSD.org Subject: ports/140621: Add support for /etc/cron.d and /usr/local/etc/cron.d in sysutils/isc-cron port Message-ID: <200911170253.nAH2r4Qn029255@www.freebsd.org> Resent-Message-ID: <200911170300.nAH30Cjt032497@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 140621 >Category: ports >Synopsis: Add support for /etc/cron.d and /usr/local/etc/cron.d in sysutils/isc-cron port >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Tue Nov 17 03:00:12 UTC 2009 >Closed-Date: >Last-Modified: >Originator: Benjamin Lee >Release: 7.2-RELEASE >Organization: >Environment: FreeBSD eclipse.b1c1l1.com 7.2-RELEASE-p4 FreeBSD 7.2-RELEASE-p4 #0: Fri Oct 2 12:21:39 UTC 2009 root@i386-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC i386 >Description: The attached patch is an enhancement for the sysutils/isc-cron port. It enables searching and parsing the /etc/cron.d and /usr/local/etc/cron.d directories for additional crontab files. >How-To-Repeat: >Fix: Patch attached with submission follows: diff -ruN isc-cron.orig/Makefile isc-cron/Makefile --- isc-cron.orig/Makefile 2009-10-19 16:07:29.320158000 -0700 +++ isc-cron/Makefile 2009-11-16 18:43:53.000000000 -0800 @@ -25,6 +25,15 @@ MAN5= crontab.5 MAN8= cron.8 +OPTIONS= \ + CROND "Enable cron.d support" Off + +.include <bsd.port.pre.mk> + +.if defined(WITH_CROND) +EXTRA_PATCHES+= ${FILESDIR}/opt-patch-cron.d +.endif + do-extract: ${MKDIR} ${WRKSRC} cd ${WRKSRC} && ${SH} ${DISTDIR}/${DISTNAME} @@ -41,4 +50,4 @@ post-install: ${CAT} ${PKGMESSAGE} -.include <bsd.port.mk> +.include <bsd.port.post.mk> diff -ruN isc-cron.orig/files/opt-patch-cron.d isc-cron/files/opt-patch-cron.d --- isc-cron.orig/files/opt-patch-cron.d 1969-12-31 16:00:00.000000000 -0800 +++ isc-cron/files/opt-patch-cron.d 2009-11-16 18:43:53.000000000 -0800 @@ -0,0 +1,153 @@ +diff -ru isc-cron-4.1.orig/FEATURES isc-cron-4.1/FEATURES +--- FEATURES 2009-10-01 17:40:45.000000000 -0700 ++++ FEATURES 2009-10-08 17:22:22.000000000 -0700 +@@ -82,3 +82,8 @@ + act this way and do the more reasonable thing, which is (IMHO) to "or" + the various field-matches together. In that sense this cron may not + be completely similar to some AT&T crons. ++ ++-- If they exist, the /etc/cron.d/ and /usr/local/etc/cron.d/ directories ++ are parsed like the cron spool directory, except that the files in it ++ are not user-specific and are therefore read with /etc/crontab syntax ++ (the user is specified explicitly in the 6th column). +diff -ru isc-cron-4.1.orig/cron.8 isc-cron-4.1/cron.8 +--- cron.8 2009-10-01 17:40:45.000000000 -0700 ++++ cron.8 2009-10-08 17:08:21.000000000 -0700 +@@ -39,7 +39,8 @@ + searches /var/cron/tabs for crontab files which are named after accounts in + /etc/passwd; crontabs found are loaded into memory. + .I Cron +-also searches for /etc/crontab which is in a different format (see ++also searches for /etc/crontab and the files in the /etc/cron.d/ and ++/usr/local/etc/cron.d/ directories, which are in a different format (see + .IR crontab (5)). + .I Cron + then wakes up every minute, examining all stored crontabs, checking each +diff -ru isc-cron-4.1.orig/database.c isc-cron-4.1/database.c +--- database.c 2009-10-01 17:40:45.000000000 -0700 ++++ database.c 2009-10-08 17:20:53.000000000 -0700 +@@ -36,7 +36,7 @@ + + void + load_database(cron_db *old_db) { +- struct stat statbuf, syscron_stat; ++ struct stat statbuf, syscron_stat, crond_stat, usrcrond_stat; + cron_db new_db; + DIR_T *dp; + DIR *dir; +@@ -53,6 +53,16 @@ + (void) exit(ERROR_EXIT); + } + ++ if (stat(CROND_DIR, &crond_stat) < OK) { ++ log_it("CRON", getpid(), "STAT FAILED", CROND_DIR); ++ (void) exit(ERROR_EXIT); ++ } ++ ++ if (stat(USRCROND_DIR, &usrcrond_stat) < OK) { ++ log_it("CRON", getpid(), "STAT FAILED", USRCROND_DIR); ++ (void) exit(ERROR_EXIT); ++ } ++ + /* track system crontab file + */ + if (stat(SYSCRONTAB, &syscron_stat) < OK) +@@ -65,7 +75,9 @@ + * 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 == TMAX(usrcrond_stat.st_mtime, ++ TMAX(crond_stat.st_mtime, ++ TMAX(statbuf.st_mtime, syscron_stat.st_mtime)))) { + Debug(DLOAD, ("[%ld] spool dir mtime unch, no load needed.\n", + (long)getpid())) + return; +@@ -76,13 +88,73 @@ + * 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 = TMAX(usrcrond_stat.st_mtime, ++ TMAX(crond_stat.st_mtime, ++ TMAX(statbuf.st_mtime, syscron_stat.st_mtime))); + new_db.head = new_db.tail = NULL; + + if (syscron_stat.st_mtime) + process_crontab("root", NULL, SYSCRONTAB, &syscron_stat, + &new_db, old_db); + ++ if (!(dir = opendir(CROND_DIR))) { ++ log_it("CRON", getpid(), "OPENDIR FAILED", CROND_DIR); ++ (void) exit(ERROR_EXIT); ++ } ++ ++ while (NULL != (dp = readdir(dir))) { ++ char fname[MAXNAMLEN+1], ++ tabname[MAXNAMLEN+1]; ++ ++ /* avoid file names beginning with ".". this is good ++ * because we would otherwise waste two guaranteed calls ++ * to getpwnam() for . and .., and there shouldn't be ++ * hidden files in here anyway. Also ignore files beginning ++ * with '#' and ending with '~'. ++ */ ++ if (dp->d_name[0] == '.' || ++ dp->d_name[0] == '#' || ++ dp->d_name[strlen(dp->d_name) - 1] == '~') ++ continue; ++ ++ (void) strncpy(fname, dp->d_name, MAXNAMLEN); ++ snprintf(tabname, MAXNAMLEN+1, "%s/%s", CROND_DIR, fname); ++ ++ process_crontab("root", NULL, tabname, ++ &crond_stat, &new_db, old_db); ++ } ++ closedir(dir); ++ ++ ++ if (!(dir = opendir(USRCROND_DIR))) { ++ log_it("CRON", getpid(), "OPENDIR FAILED", USRCROND_DIR); ++ (void) exit(ERROR_EXIT); ++ } ++ ++ while (NULL != (dp = readdir(dir))) { ++ char fname[MAXNAMLEN+1], ++ tabname[MAXNAMLEN+1]; ++ ++ /* avoid file names beginning with ".". this is good ++ * because we would otherwise waste two guaranteed calls ++ * to getpwnam() for . and .., and there shouldn't be ++ * hidden files in here anyway. Also ignore files beginning ++ * with '#' and ending with '~'. ++ */ ++ if (dp->d_name[0] == '.' || ++ dp->d_name[0] == '#' || ++ dp->d_name[strlen(dp->d_name) - 1] == '~') ++ continue; ++ ++ (void) strncpy(fname, dp->d_name, MAXNAMLEN); ++ snprintf(tabname, MAXNAMLEN+1, "%s/%s", USRCROND_DIR, fname); ++ ++ process_crontab("root", NULL, tabname, ++ &usrcrond_stat, &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. +diff -ru isc-cron-4.1.orig/pathnames.h isc-cron-4.1/pathnames.h +--- pathnames.h 2009-10-01 17:40:45.000000000 -0700 ++++ pathnames.h 2009-10-08 17:45:34.000000000 -0700 +@@ -48,6 +48,9 @@ + */ + #define SPOOL_DIR "tabs" + ++#define CROND_DIR "/etc/cron.d" ++#define USRCROND_DIR "/usr/local/etc/cron.d" ++ + /* cron allow/deny file. At least cron.deny must + * exist for ordinary users to run crontab. + */ >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911170253.nAH2r4Qn029255>