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).