use utimensat(2) and correct and centralize file times handling.
This commit is contained in:
parent
7639cf466f
commit
0a00da6dcc
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -137,6 +137,48 @@ main(int argc, char *argv[]) {
|
|||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
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).
|
||||
|
|
Loading…
Reference in New Issue