Module Name:    src
Committed By:   christos
Date:           Sat Nov  3 15:39:24 UTC 2012

Modified Files:
        src/external/bsd/cron/dist: config.h crontab.c

Log Message:
use utimensat(2) and correct and centralize file times handling.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/external/bsd/cron/dist/config.h
cvs rdiff -u -r1.5 -r1.6 src/external/bsd/cron/dist/crontab.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/cron/dist/config.h
diff -u src/external/bsd/cron/dist/config.h:1.3 src/external/bsd/cron/dist/config.h:1.4
--- src/external/bsd/cron/dist/config.h:1.3	Fri May  7 16:43:27 2010
+++ src/external/bsd/cron/dist/config.h	Sat Nov  3 11:39:23 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: config.h,v 1.3 2010/05/07 20:43:27 christos Exp $	*/
+/*	$NetBSD: config.h,v 1.4 2012/11/03 15:39:23 christos Exp $	*/
 
 /* Copyright 1988,1990,1993,1994 by Paul Vixie
  * All rights reserved
@@ -93,6 +93,8 @@
 #define HAVE_TM_GMTOFF		/*-*/
 #define HAVE_FCHOWN		/*-*/
 #define HAVE_UTIMES		/*-*/
+#define HAVE_UTIMENSAT
+#define _INCOMPLETE_XOPEN_C063
 
 			/* if your OS supports a BSD-style login.conf file */
 /* #define LOGIN_CAP			*/

Index: src/external/bsd/cron/dist/crontab.c
diff -u src/external/bsd/cron/dist/crontab.c:1.5 src/external/bsd/cron/dist/crontab.c:1.6
--- src/external/bsd/cron/dist/crontab.c:1.5	Sun Mar  4 13:38:31 2012
+++ src/external/bsd/cron/dist/crontab.c	Sat Nov  3 11:39:23 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: crontab.c,v 1.5 2012/03/04 18:38:31 tron Exp $	*/
+/*	$NetBSD: crontab.c,v 1.6 2012/11/03 15:39:23 christos Exp $	*/
 
 /* Copyright 1988,1990,1993,1994 by Paul Vixie
  * All rights reserved
@@ -25,7 +25,7 @@
 #if 0
 static char rcsid[] = "Id: crontab.c,v 1.12 2004/01/23 18:56:42 vixie Exp";
 #else
-__RCSID("$NetBSD: crontab.c,v 1.5 2012/03/04 18:38:31 tron Exp $");
+__RCSID("$NetBSD: crontab.c,v 1.6 2012/11/03 15:39:23 christos Exp $");
 #endif
 #endif
 
@@ -138,6 +138,48 @@ main(int argc, char *argv[]) {
 }
 
 static void
+get_time(const struct stat *st, struct timespec *ts)
+{
+	ts[0].tv_sec = st->st_atime;
+	ts[0].tv_nsec = st->st_atimensec;
+	ts[1].tv_sec = st->st_mtime;
+	ts[1].tv_nsec = st->st_mtimensec;
+}
+
+static int
+change_time(const char *name, const struct timespec *ts)
+{
+#if defined(HAVE_UTIMENSAT)
+	return utimensat(AT_FDCWD, name, ts, 0);
+#elif defined(HAVE_UTIMES)
+	struct timeval tv[2];
+	TIMESPEC_TO_TIMEVAL(&tv[0], &ts[0]);
+	TIMESPEC_TO_TIMEVAL(&tv[1], &ts[1]);
+	return utimes(name, tvs);
+#else
+	struct utimebuf ut;
+	ut.actime = tv[0].tv_sec;
+	ut.modtime = tv[1].tv_sec;
+	return utime(name, &ut);
+#endif
+}
+
+static int
+compare_time(const struct stat *st, const struct timespec *ts2)
+{
+	struct timespec ts1[2];
+	get_time(st, ts1);
+	
+	return ts1[1].tv_sec == ts2[1].tv_sec
+#if defined(HAVE_UTIMENSAT)
+	    && ts1[1].tv_nsec == ts2[1].tv_nsec
+#elif defined(HAVE_UTIMES)
+	    && ts1[1].tv_nsec / 1000 = ts2[1].tv_nsec / 1000
+#endif
+	;
+}
+
+static void
 parse_args(int argc, char *argv[]) {
 	int argch;
 
@@ -322,10 +364,9 @@ edit_cmd(void) {
 	int ch, t, x;
 	sig_t oint, oabrt, oquit, ohup;
 	struct stat statbuf;
-	struct utimbuf utimebuf;
-	long mtimensec;
 	WAIT_T waiter;
 	PID_T pid, xpid;
+	struct timespec ts[2];
 
 	log_it(RealUser, Pid, "BEGIN EDIT", User);
 	if (!glue_strings(n, sizeof n, SPOOL_DIR, User, '/')) {
@@ -345,9 +386,7 @@ edit_cmd(void) {
 		warn("cannot stat crontab file");
 		goto fatal;
 	}
-	utimebuf.actime = statbuf.st_atime;
-	utimebuf.modtime = statbuf.st_mtime;
-	mtimensec = statbuf.st_mtimensec;
+	get_time(&statbuf, ts);
 
 	/* Turn off signals. */
 	ohup = signal(SIGHUP, SIG_IGN);
@@ -390,7 +429,8 @@ edit_cmd(void) {
 	if (fflush(NewCrontab) < OK) {
 		err(ERROR_EXIT, "cannot flush output for `%s'", Filename);
 	}
-	(void)utime(Filename, &utimebuf);
+	if (change_time(Filename, ts) == -1)
+		err(ERROR_EXIT, "cannot set time info for `%s'", Filename);
  again:
 	rewind(NewCrontab);
 	if (ferror(NewCrontab)) {
@@ -473,8 +513,7 @@ edit_cmd(void) {
 		warn("cannot stat `%s'", Filename);
 		goto fatal;
 	}
-	if (utimebuf.modtime == statbuf.st_mtime &&
-	    mtimensec == statbuf.st_mtimensec) {
+	if (compare_time(&statbuf, ts)) {
 		warnx("no changes made to crontab");
 		goto remove;
 	}
@@ -599,7 +638,7 @@ replace_cmd(void) {
 	 */
 	(void)fprintf(tmp, "# DO NOT EDIT THIS FILE - edit the master and reinstall.\n");
 	(void)fprintf(tmp, "# (%s installed on %-24.24s)\n", Filename, ctime(&now));
-	(void)fprintf(tmp, "# (Cron version %s -- %s)\n", CRON_VERSION, "$NetBSD: crontab.c,v 1.5 2012/03/04 18:38:31 tron Exp $");
+	(void)fprintf(tmp, "# (Cron version %s -- %s)\n", CRON_VERSION, "$NetBSD: crontab.c,v 1.6 2012/11/03 15:39:23 christos Exp $");
 
 	/* copy the crontab to the tmp
 	 */
@@ -717,18 +756,13 @@ done:
 
 static void
 poke_daemon(void) {
-#ifdef HAVE_UTIMES
-	struct timeval tvs[2];
-	struct timezone tz;
-
-	(void) gettimeofday(&tvs[0], &tz);
-	tvs[1] = tvs[0];
-	if (utimes(SPOOL_DIR, tvs) < OK)
-#else
-	if (utime(SPOOL_DIR, NULL) < OK)
-#endif /* HAVE_UTIMES */
-		warn("can't update mtime on spooldir %s", SPOOL_DIR);
+	struct timespec ts[2];
+	(void) clock_gettime(CLOCK_REALTIME, ts);
+	ts[1] = ts[0];
+	if (change_time(SPOOL_DIR, ts) == -1)
+		warn("can't update times on spooldir %s", SPOOL_DIR);
 }
+
 /* int allowed(const char *username, const char *allow_file, const char *deny_file)
  *	returns TRUE if (allow_file exists and user is listed)
  *	or (deny_file exists and user is NOT listed).

Reply via email to