diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2001-08-19 18:30:39 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2001-08-19 18:30:39 +0000 |
commit | d0eae1b3c9b6b0068e9e2920f5ab4c32f58af829 (patch) | |
tree | 8f96f8b466cdb8003f15e18c8b785366bf4bee34 | |
parent | 71fd3643a55f28fd036318d785605467bc355b1c (diff) |
Better file change detection:
o when copying to temp file set utimes on temp file equal to original
o use st_mtimespec instead of st_mtime for better granularity
-rw-r--r-- | usr.sbin/cron/crontab.c | 26 | ||||
-rw-r--r-- | usr.sbin/vipw/vipw.c | 15 |
2 files changed, 28 insertions, 13 deletions
diff --git a/usr.sbin/cron/crontab.c b/usr.sbin/cron/crontab.c index 5fb78c5c75e..fee68e0670a 100644 --- a/usr.sbin/cron/crontab.c +++ b/usr.sbin/cron/crontab.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crontab.c,v 1.21 2001/08/11 20:47:14 millert Exp $ */ +/* $OpenBSD: crontab.c,v 1.22 2001/08/19 18:30:38 millert Exp $ */ /* Copyright 1988,1990,1993,1994 by Paul Vixie * All rights reserved */ @@ -21,7 +21,7 @@ */ #if !defined(lint) && !defined(LINT) -static char rcsid[] = "$OpenBSD: crontab.c,v 1.21 2001/08/11 20:47:14 millert Exp $"; +static char rcsid[] = "$OpenBSD: crontab.c,v 1.22 2001/08/19 18:30:38 millert Exp $"; #endif /* crontab - install and manage per-user crontab files @@ -285,7 +285,8 @@ edit_cmd(void) { FILE *f; int ch, t, x; struct stat statbuf; - time_t mtime; + struct timespec mtimespec; + struct timeval tv[2]; off_t size; WAIT_T waiter; PID_T pid, xpid; @@ -308,6 +309,15 @@ edit_cmd(void) { } } + if (fstat(fileno(f), &statbuf) < 0) { + perror("fstat"); + goto fatal; + } + size = statbuf.st_size; + memcpy(&mtimespec, &statbuf.st_mtimespec, sizeof(mtimespec)); + TIMESPEC_TO_TIMEVAL(&tv[0], &statbuf.st_atimespec); + TIMESPEC_TO_TIMEVAL(&tv[1], &statbuf.st_mtimespec); + /* Turn off signals. */ (void)signal(SIGHUP, SIG_IGN); (void)signal(SIGINT, SIG_IGN); @@ -367,6 +377,7 @@ edit_cmd(void) { perror(Filename); exit(ERROR_EXIT); } + (void)futimes(t, tv); again: rewind(NewCrontab); if (ferror(NewCrontab)) { @@ -376,12 +387,6 @@ edit_cmd(void) { unlink(Filename); exit(ERROR_EXIT); } - if (fstat(t, &statbuf) < 0) { - perror("fstat"); - goto fatal; - } - mtime = statbuf.st_mtime; - size = statbuf.st_size; if (((editor = getenv("VISUAL")) == NULL || *editor == '\0') && ((editor = getenv("EDITOR")) == NULL || *editor == '\0')) { @@ -461,7 +466,8 @@ edit_cmd(void) { perror("fstat"); goto fatal; } - if (mtime == statbuf.st_mtime && size == statbuf.st_size) { + if (timespeccmp(&mtimespec, &statbuf.st_mtimespec, -) == 0 && + size == statbuf.st_size) { fprintf(stderr, "%s: no changes made to crontab\n", ProgramName); goto remove; diff --git a/usr.sbin/vipw/vipw.c b/usr.sbin/vipw/vipw.c index 6a2d07b228a..9d32fa659dc 100644 --- a/usr.sbin/vipw/vipw.c +++ b/usr.sbin/vipw/vipw.c @@ -43,7 +43,7 @@ static char copyright[] = static char sccsid[] = "@(#)vipw.c 8.3 (Berkeley) 4/2/94"; #endif /* not lint */ -#include <sys/types.h> +#include <sys/time.h> #include <sys/stat.h> #include <err.h> @@ -96,7 +96,7 @@ main(argc, argv) pw_edit(0, NULL); if (stat(_PATH_MASTERPASSWD_LOCK, &end)) pw_error(_PATH_MASTERPASSWD_LOCK, 1, 1); - if (begin.st_mtime == end.st_mtime && + if (!timespeccmp(&begin.st_mtimespec, &end.st_mtimespec, -) && begin.st_size == end.st_size) { warnx("no changes made"); pw_error((char *)NULL, 0, 0); @@ -114,19 +114,28 @@ copyfile(from, to) { int nr, nw, off; char buf[8*1024]; + struct stat sb; + struct timeval tv[2]; + if (fstat(from, &sb) == -1) + pw_error(_PATH_MASTERPASSWD, 1, 1); while ((nr = read(from, buf, sizeof(buf))) > 0) for (off = 0; off < nr; nr -= nw, off += nw) if ((nw = write(to, buf + off, nr)) < 0) pw_error(_PATH_MASTERPASSWD_LOCK, 1, 1); if (nr < 0) pw_error(_PATH_MASTERPASSWD, 1, 1); + + TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atimespec); + TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec); + (void) futimes(to, tv); } void usage() { + extern char *__progname; - (void)fprintf(stderr, "usage: vipw\n"); + (void)fprintf(stderr, "usage: %s\n", __progname); exit(1); } |