]> granicus.if.org Git - sudo/commitdiff
Use timeval directly instead of converting to timespec when dealing
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 2 Jun 2010 22:54:33 +0000 (18:54 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 2 Jun 2010 22:54:33 +0000 (18:54 -0400)
with file times and time of day.

--HG--
branch : 1.7

check.c
compat.h
config.h.in
configure
configure.in
fileops.c
gettime.c
sudo.h
sudo_edit.c
visudo.c

diff --git a/check.c b/check.c
index f989bfd4867ddbd23967a45106600c4599deff86..568b9aac33dbbe8a6bae074ffc4cda4a108b1861 100644 (file)
--- a/check.c
+++ b/check.c
@@ -23,6 +23,7 @@
 
 #include <sys/types.h>
 #include <sys/param.h>
+#include <sys/time.h>
 #include <sys/stat.h>
 #ifndef __TANDEM
 # include <sys/file.h>
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif /* HAVE_UNISTD_H */
+#if TIME_WITH_SYS_TIME
+# include <time.h>
+#endif
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
-#include <time.h>
 #include <pwd.h>
 #include <grp.h>
-#ifndef HAVE_TIMESPEC
-# include <emul/timespec.h>
-#endif
 
 #include "sudo.h"
 
@@ -534,7 +534,7 @@ timestamp_status(timestampdir, timestampfile, user, flags)
        if (def_timestamp_timeout < 0 && sb.st_mtime != 0)
            status = TS_CURRENT;
        else {
-           /* XXX - should use timespec here */
+           /* XXX - should use timeval here */
            now = time(NULL);
            boottime = get_boottime();
            if (def_timestamp_timeout &&
@@ -574,7 +574,7 @@ void
 remove_timestamp(remove)
     int remove;
 {
-    struct timespec ts;
+    struct timeval tv;
     char *timestampdir, *timestampfile, *path;
     int status;
 
@@ -594,8 +594,8 @@ remove_timestamp(remove)
                remove = FALSE;
            }
        } else {
-           timespecclear(&ts);
-           if (touch(-1, path, &ts) == -1)
+           timerclear(&tv);
+           if (touch(-1, path, &tv) == -1)
                error(1, "can't reset %s to Epoch", path);
        }
     }
index 808ada3674734ccb6b7b39778ae6f5efd51fa3a7..b5da2639c4d61dabc3c7e618b7cca3e9d1f24c4b 100644 (file)
--- a/compat.h
+++ b/compat.h
@@ -260,24 +260,12 @@ const char *getprogname __P((void));
 #endif /* HAVE___PROGNAME */
 #endif /* !HAVE_GETPROGNAME */
 
-#ifndef timespecclear
-# define timespecclear(ts)     (ts)->tv_sec = (ts)->tv_nsec = 0
+#ifndef timerclear
+# define timerclear(ts)        (ts)->tv_sec = (ts)->tv_nsec = 0
 #endif
-#ifndef timespecisset
-# define timespecisset(ts)     ((ts)->tv_sec || (ts)->tv_nsec)
+#ifndef timerisset
+# define timerisset(ts)        ((ts)->tv_sec || (ts)->tv_nsec)
 #endif
-#ifndef timespecsub
-# define timespecsub(minuend, subrahend, difference)                          \
-    do {                                                                      \
-           (difference)->tv_sec = (minuend)->tv_sec - (subrahend)->tv_sec;    \
-           (difference)->tv_nsec = (minuend)->tv_nsec - (subrahend)->tv_nsec; \
-           if ((difference)->tv_nsec < 0) {                                   \
-                   (difference)->tv_nsec += 1000000000L;                      \
-                   (difference)->tv_sec--;                                    \
-           }                                                                  \
-    } while (0)
-#endif
-
 #ifndef timeradd
 # define timeradd(tv1, tv2, total)                                            \
     do {                                                                      \
@@ -289,7 +277,6 @@ const char *getprogname __P((void));
        }                                                                      \
     } while (0)
 #endif
-
 #ifndef timersub
 # define timersub(minuend, subrahend, difference)                             \
     do {                                                                      \
index a00b62371e3e57e0f5b698ef7b00c1b6628a5d91..625f0878fc98333b81490933d66a4971f8409926 100644 (file)
 
 /* Define to 1 if you have a timespecsub macro or function that takes two
    arguments (not three) */
-#undef HAVE_TIMESPECSUB2
+#undef HAVE_TIMERSUB2
 
 /* Define to 1 if you have the `tzset' function. */
 #undef HAVE_TZSET
 #undef volatile
 
 /*
- * Macros to pull sec and nsec parts of mtime from struct stat.
- * We need to be able to convert between timeval and timespec
- * so the last 3 digits of tv_nsec are not significant.
+ * Macros to convert ctime and mtime into timevals.
  */
+#define timespec2timeval(_ts, _tv) do {                                        \
+    (_tv)->tv_sec = (_ts)->tv_sec;                                     \
+    (_tv)->tv_usec = (_ts)->tv_nsec / 1000;                            \
+} while (0)
+
 #ifdef HAVE_ST_MTIM
 # ifdef HAVE_ST__TIM
-#  define mtim_getsec(_x)      ((_x).st_mtim.st__tim.tv_sec)
-#  define mtim_getnsec(_x)     (((_x).st_mtim.st__tim.tv_nsec / 1000) * 1000)
+#  define ctim_get(_x, _y)     timespec2timeval(&(_x)->st_ctim.st__tim, (_y))
+#  define mtim_get(_x, _y)     timespec2timeval(&(_x)->st_mtim.st__tim, (_y))
 # else
-#  define mtim_getsec(_x)      ((_x).st_mtim.tv_sec)
-#  define mtim_getnsec(_x)     (((_x).st_mtim.tv_nsec / 1000) * 1000)
+#  define ctim_get(_x, _y)     timespec2timeval(&(_x)->st_ctim, (_y))
+#  define mtim_get(_x, _y)     timespec2timeval(&(_x)->st_mtim, (_y))
 # endif
 #else
 # ifdef HAVE_ST_MTIMESPEC
-#  define mtim_getsec(_x)      ((_x).st_mtimespec.tv_sec)
-#  define mtim_getnsec(_x)     (((_x).st_mtimespec.tv_nsec / 1000) * 1000)
+#  define ctim_get(_x, _y)     timespec2timeval(&(_x)->st_ctimespec, (_y))
+#  define mtim_get(_x, _y)     timespec2timeval(&(_x)->st_mtimespec, (_y))
 # else
-#  define mtim_getsec(_x)      ((_x).st_mtime)
-#  define mtim_getnsec(_x)     (0)
+#  define ctim_get(_x, _y)     do { (_y)->tv_sec = (_x)->st_ctime; (_y)->tv_usec = 0; } while (0)
+#  define mtim_get(_x, _y)     do { (_y)->tv_sec = (_x)->st_mtime; (_y)->tv_usec = 0; } while (0)
 # endif /* HAVE_ST_MTIMESPEC */
 #endif /* HAVE_ST_MTIM */
 
index 5c72cfdd9f809734111081b40ee7ad7ddd6b3e36..b70d778a41f6ec5c9a46cf321476deaed266fc6d 100755 (executable)
--- a/configure
+++ b/configure
@@ -20244,8 +20244,8 @@ fi
 
 fi
 
-    { echo "$as_me:$LINENO: checking for two-parameter timespecsub" >&5
-echo $ECHO_N "checking for two-parameter timespecsub... $ECHO_C" >&6; }
+    { echo "$as_me:$LINENO: checking for two-parameter timersub" >&5
+echo $ECHO_N "checking for two-parameter timersub... $ECHO_C" >&6; }
     cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -20257,12 +20257,12 @@ cat >>conftest.$ac_ext <<_ACEOF
 int
 main ()
 {
-struct timespec ts1, ts2;
-ts1.tv_sec = 1; ts1.tv_nsec = 0; ts2.tv_sec = 0; ts2.tv_nsec = 0;
-#ifndef timespecsub
-#error missing timespecsub
+struct timeval ts1, ts2;
+ts1.tv_sec = 1; ts1.tv_usec = 0; ts2.tv_sec = 0; ts2.tv_usec = 0;
+#ifndef timersub
+#error missing timersub
 #endif
-timespecsub(&ts1, &ts2);
+timersub(&ts1, &ts2);
   ;
   return 0;
 }
@@ -20285,7 +20285,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest.$ac_objext; then
   cat >>confdefs.h <<\_ACEOF
-#define HAVE_TIMESPECSUB2 1
+#define HAVE_TIMERSUB2 1
 _ACEOF
 
     { echo "$as_me:$LINENO: result: yes" >&5
index 99366165f503c6019d0510c7fde9edd3143a01ec..b41af6b19cf117bf4a4b54e55ad006c958eb78b8 100644 (file)
@@ -1922,14 +1922,14 @@ if test X"$ac_cv_type_struct_timespec" != X"no"; then
     AC_CHECK_MEMBER([struct stat.st_mtim], [AC_DEFINE(HAVE_ST_MTIM)]
        [AC_CHECK_MEMBER([struct stat.st_mtim.st__tim], AC_DEFINE(HAVE_ST__TIM))],
        [AC_CHECK_MEMBER([struct stat.st_mtimespec], AC_DEFINE([HAVE_ST_MTIMESPEC]))])
-    AC_MSG_CHECKING([for two-parameter timespecsub])
+    AC_MSG_CHECKING([for two-parameter timersub])
     AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
-#include <sys/time.h>]], [[struct timespec ts1, ts2;
-ts1.tv_sec = 1; ts1.tv_nsec = 0; ts2.tv_sec = 0; ts2.tv_nsec = 0;
-#ifndef timespecsub
-#error missing timespecsub
+#include <sys/time.h>]], [[struct timeval ts1, ts2;
+ts1.tv_sec = 1; ts1.tv_usec = 0; ts2.tv_sec = 0; ts2.tv_usec = 0;
+#ifndef timersub
+#error missing timersub
 #endif
-timespecsub(&ts1, &ts2);]])], [AC_DEFINE(HAVE_TIMESPECSUB2)
+timersub(&ts1, &ts2);]])], [AC_DEFINE(HAVE_TIMERSUB2)
     AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)])
 fi
 dnl
@@ -2786,7 +2786,7 @@ AH_TEMPLATE(HAVE_ST_MTIM, [Define to 1 if your struct stat has an st_mtim member
 AH_TEMPLATE(HAVE_ST_MTIMESPEC, [Define to 1 if your struct stat has an st_mtimespec member])
 AH_TEMPLATE(HAVE_TERMIOS_H, [Define to 1 if you have the <termios.h> header file and the `tcgetattr' function.])
 AH_TEMPLATE(HAVE_TIMESPEC, [Define to 1 if you have struct timespec in sys/time.h])
-AH_TEMPLATE(HAVE_TIMESPECSUB2, [Define to 1 if you have a timespecsub macro or function that takes two arguments (not three)])
+AH_TEMPLATE(HAVE_TIMERSUB2, [Define to 1 if you have a timersub macro or function that takes two arguments (not three)])
 AH_TEMPLATE(HAVE___PROGNAME, [Define to 1 if your crt0.o defines the __progname symbol for you.])
 AH_TEMPLATE(HOST_IN_LOG, [Define to 1 if you want the hostname to be entered into the log file.])
 AH_TEMPLATE(IGNORE_DOT_PATH, [Define to 1 if you want to ignore '.' and empty PATH elements])
@@ -2820,25 +2820,28 @@ AH_TOP([#ifndef _SUDO_CONFIG_H
 #define _SUDO_CONFIG_H])
 
 AH_BOTTOM([/*
- * Macros to pull sec and nsec parts of mtime from struct stat.
- * We need to be able to convert between timeval and timespec
- * so the last 3 digits of tv_nsec are not significant.
+ * Macros to convert ctime and mtime into timevals.
  */
+#define timespec2timeval(_ts, _tv) do {                                        \
+    (_tv)->tv_sec = (_ts)->tv_sec;                                     \
+    (_tv)->tv_usec = (_ts)->tv_nsec / 1000;                            \
+} while (0)
+
 #ifdef HAVE_ST_MTIM
 # ifdef HAVE_ST__TIM
-#  define mtim_getsec(_x)      ((_x).st_mtim.st__tim.tv_sec)
-#  define mtim_getnsec(_x)     (((_x).st_mtim.st__tim.tv_nsec / 1000) * 1000)
+#  define ctim_get(_x, _y)     timespec2timeval(&(_x)->st_ctim.st__tim, (_y))
+#  define mtim_get(_x, _y)     timespec2timeval(&(_x)->st_mtim.st__tim, (_y))
 # else
-#  define mtim_getsec(_x)      ((_x).st_mtim.tv_sec)
-#  define mtim_getnsec(_x)     (((_x).st_mtim.tv_nsec / 1000) * 1000)
+#  define ctim_get(_x, _y)     timespec2timeval(&(_x)->st_ctim, (_y))
+#  define mtim_get(_x, _y)     timespec2timeval(&(_x)->st_mtim, (_y))
 # endif
 #else
 # ifdef HAVE_ST_MTIMESPEC
-#  define mtim_getsec(_x)      ((_x).st_mtimespec.tv_sec)
-#  define mtim_getnsec(_x)     (((_x).st_mtimespec.tv_nsec / 1000) * 1000)
+#  define ctim_get(_x, _y)     timespec2timeval(&(_x)->st_ctimespec, (_y))
+#  define mtim_get(_x, _y)     timespec2timeval(&(_x)->st_mtimespec, (_y))
 # else
-#  define mtim_getsec(_x)      ((_x).st_mtime)
-#  define mtim_getnsec(_x)     (0)
+#  define ctim_get(_x, _y)     do { (_y)->tv_sec = (_x)->st_ctime; (_y)->tv_usec = 0; } while (0)
+#  define mtim_get(_x, _y)     do { (_y)->tv_sec = (_x)->st_mtime; (_y)->tv_usec = 0; } while (0)
 # endif /* HAVE_ST_MTIMESPEC */
 #endif /* HAVE_ST_MTIM */
 
index 5e9d31dd67c6323c5a7ebf5da58f40735f7929fb..c2dc152fb2dc33e2820a68e7bdc4830bc090f0ea 100644 (file)
--- a/fileops.c
+++ b/fileops.c
  * Update the access and modify times on an fd or file.
  */
 int
-touch(fd, path, tsp)
+touch(fd, path, tvp)
     int fd;
     char *path;
-    struct timespec *tsp;
+    struct timeval *tvp;
 {
     struct timeval times[2];
 
-    if (tsp != NULL) {
-       times[0].tv_sec = times[1].tv_sec = tsp->tv_sec;
-       times[0].tv_usec = times[1].tv_usec = tsp->tv_nsec / 1000;
+    if (tvp != NULL) {
+       times[0].tv_sec = times[1].tv_sec = tvp->tv_sec;
+       times[0].tv_usec = times[1].tv_usec = tvp->tv_usec;
     }
 
 #if defined(HAVE_FUTIME) || defined(HAVE_FUTIMES)
     if (fd != -1)
-       return(futimes(fd, tsp ? times : NULL));
+       return(futimes(fd, tvp ? times : NULL));
     else
 #endif
     if (path != NULL)
-       return(utimes(path, tsp ? times : NULL));
+       return(utimes(path, tvp ? times : NULL));
     else
        return(-1);
 }
index f6de4753269cc79ea3ea67c56ab33c8255a6df34..1f498dbc44b1dc780883a9b4baf0bf58d3de3f9d 100644 (file)
--- a/gettime.c
+++ b/gettime.c
@@ -22,9 +22,6 @@
 #if TIME_WITH_SYS_TIME
 # include <time.h>
 #endif
-#ifndef HAVE_TIMESPEC
-# include <emul/timespec.h>
-#endif
 
 #include <compat.h>
 
  * timespecs in struct stat or, otherwise, using time().
  */
 int
-gettime(ts)
-    struct timespec *ts;
+gettime(tv)
+    struct timeval *tv;
 {
     int rval;
 #if defined(HAVE_GETTIMEOFDAY) && (defined(HAVE_ST_MTIM) || defined(HAVE_ST_MTIMESPEC))
-    struct timeval tv;
-
-    rval = gettimeofday(&tv, NULL);
-    ts->tv_sec = tv.tv_sec;
-    ts->tv_nsec = tv.tv_usec * 1000;
+    rval = gettimeofday(tv, NULL);
 #else
-    rval = (int)time(&ts->tv_sec);
-    ts->tv_nsec = 0;
+    rval = (int)time(&tv->tv_sec);
+    tv->tv_usec = 0;
 #endif
     return (rval);
 }
diff --git a/sudo.h b/sudo.h
index a181c3cd58a69bc674ff730e64d2d5cff0ea29a1..4db6d1adf0d88627f6e00cc7698eff7052c9feab 100644 (file)
--- a/sudo.h
+++ b/sudo.h
@@ -241,13 +241,13 @@ void dump_auth_methods    __P((void));
 void init_envtables    __P((void));
 void read_env_file     __P((const char *, int));
 int lock_file          __P((int, int));
-int touch              __P((int, char *, struct timespec *));
+int touch              __P((int, char *, struct timeval *));
 int user_is_exempt     __P((void));
 void set_fqdn          __P((void));
 char *sudo_getepw      __P((const struct passwd *));
 int pam_prep_user      __P((struct passwd *));
 void zero_bytes                __P((volatile void *, size_t));
-int gettime            __P((struct timespec *));
+int gettime            __P((struct timeval *));
 FILE *open_sudoers     __P((const char *, int, int *));
 void display_privs     __P((struct sudo_nss_list *, struct passwd *));
 int display_cmnd       __P((struct sudo_nss_list *, struct passwd *));
index 04d5d7434e4743af140dec6ee55713b531d5137a..44989d452125a2d10a8056cba5d25b5b63e8edbc 100644 (file)
@@ -49,9 +49,6 @@
 #if TIME_WITH_SYS_TIME
 # include <time.h>
 #endif
-#ifndef HAVE_TIMESPEC
-# include <emul/timespec.h>
-#endif
 
 #include "sudo.h"
 
@@ -74,13 +71,13 @@ sudo_edit(argc, argv, envp)
     const char *tmpdir;
     char **nargv, **ap, *editor, *cp;
     char buf[BUFSIZ];
-    int error, i, ac, ofd, tfd, nargc, rval, tmplen, wasblank;
+    int rc, i, ac, ofd, tfd, nargc, rval, tmplen, wasblank;
     struct stat sb;
-    struct timespec ts1, ts2;
+    struct timeval tv, tv1, tv2;
     struct tempfile {
        char *tfile;
        char *ofile;
-       struct timespec omtim;
+       struct timeval omtim;
        off_t osize;
     } *tf;
 
@@ -113,23 +110,23 @@ sudo_edit(argc, argv, envp)
     tf = emalloc2(argc - 1, sizeof(*tf));
     zero_bytes(tf, (argc - 1) * sizeof(*tf));
     for (i = 0, ap = argv + 1; i < argc - 1 && *ap != NULL; i++, ap++) {
-       error = -1;
+       rc = -1;
        set_perms(PERM_RUNAS);
        if ((ofd = open(*ap, O_RDONLY, 0644)) != -1 || errno == ENOENT) {
            if (ofd == -1) {
                zero_bytes(&sb, sizeof(sb));            /* new file */
-               error = 0;
+               rc = 0;
            } else {
 #ifdef HAVE_FSTAT
-               error = fstat(ofd, &sb);
+               rc = fstat(ofd, &sb);
 #else
-               error = stat(tf[i].ofile, &sb);
+               rc = stat(tf[i].ofile, &sb);
 #endif
            }
        }
        set_perms(PERM_ROOT);
-       if (error || (ofd != -1 && !S_ISREG(sb.st_mode))) {
-           if (error)
+       if (rc || (ofd != -1 && !S_ISREG(sb.st_mode))) {
+           if (rc)
                warning("%s", *ap);
            else
                warningx("%s: not a regular file", *ap);
@@ -140,8 +137,7 @@ sudo_edit(argc, argv, envp)
            continue;
        }
        tf[i].ofile = *ap;
-       tf[i].omtim.tv_sec = mtim_getsec(sb);
-       tf[i].omtim.tv_nsec = mtim_getnsec(sb);
+       mtim_get(&sb, &tf[i].omtim);
        tf[i].osize = sb.st_size;
        if ((cp = strrchr(tf[i].ofile, '/')) != NULL)
            cp++;
@@ -176,14 +172,12 @@ sudo_edit(argc, argv, envp)
         */
        (void) touch(tfd, NULL, &tf[i].omtim);
 #ifdef HAVE_FSTAT
-       error = fstat(tfd, &sb);
+       rc = fstat(tfd, &sb);
 #else
-       error = stat(tf[i].tfile, &sb);
+       rc = stat(tf[i].tfile, &sb);
 #endif
-       if (!error) {
-           tf[i].omtim.tv_sec = mtim_getsec(sb);
-           tf[i].omtim.tv_nsec = mtim_getnsec(sb);
-       }
+       if (!rc)
+           mtim_get(&sb, &tf[i].omtim);
        close(tfd);
     }
     if (argc == 1)
@@ -221,7 +215,7 @@ sudo_edit(argc, argv, envp)
      * Fork and exec the editor with the invoking user's creds,
      * keeping track of the time spent in the editor.
      */
-    gettime(&ts1);
+    gettime(&tv1);
     kidpid = fork();
     if (kidpid == -1) {
        warning("fork");
@@ -257,7 +251,7 @@ sudo_edit(argc, argv, envp)
                break;
        }
     } while (pid != -1 || errno == EINTR);
-    gettime(&ts2);
+    gettime(&tv2);
     if (pid == -1 || !WIFEXITED(i))
        rval = 1;
     else
@@ -265,18 +259,18 @@ sudo_edit(argc, argv, envp)
 
     /* Copy contents of temp files to real ones */
     for (i = 0; i < argc - 1; i++) {
-       error = -1;
+       rc = -1;
        set_perms(PERM_USER);
        if ((tfd = open(tf[i].tfile, O_RDONLY, 0644)) != -1) {
 #ifdef HAVE_FSTAT
-           error = fstat(tfd, &sb);
+           rc = fstat(tfd, &sb);
 #else
-           error = stat(tf[i].tfile, &sb);
+           rc = stat(tf[i].tfile, &sb);
 #endif
        }
        set_perms(PERM_ROOT);
-       if (error || !S_ISREG(sb.st_mode)) {
-           if (error)
+       if (rc || !S_ISREG(sb.st_mode)) {
+           if (rc)
                warning("%s", tf[i].tfile);
            else
                warningx("%s: not a regular file", tf[i].tfile);
@@ -285,18 +279,18 @@ sudo_edit(argc, argv, envp)
                close(tfd);
            continue;
        }
-       if (tf[i].osize == sb.st_size && tf[i].omtim.tv_sec == mtim_getsec(sb)
-           && tf[i].omtim.tv_nsec == mtim_getnsec(sb)) {
+       mtim_get(&sb, &tv);
+       if (tf[i].osize == sb.st_size && timercmp(&tf[i].omtim, &tv, ==)) {
            /*
             * If mtime and size match but the user spent no measurable
             * time in the editor we can't tell if the file was changed.
             */
-#ifdef HAVE_TIMESPECSUB2
-           timespecsub(&ts1, &ts2);
+#ifdef HAVE_TIMERSUB2
+           timersub(&tv1, &tv2);
 #else
-           timespecsub(&ts1, &ts2, &ts2);
+           timersub(&tv1, &tv2, &tv2);
 #endif
-           if (timespecisset(&ts2)) {
+           if (timerisset(&tv2)) {
                warningx("%s unchanged", tf[i].ofile);
                unlink(tf[i].tfile);
                close(tfd);
index c6a0838bf7f274a2d563d218882eb950871c19f4..c93b817b8446bee2aa7bb0b047c3029ec8823e57 100644 (file)
--- a/visudo.c
+++ b/visudo.c
@@ -76,9 +76,6 @@
 #else
 # include <varargs.h>
 #endif
-#ifndef HAVE_TIMESPEC
-# include <emul/timespec.h>
-#endif
 
 #include "sudo.h"
 #include "interfaces.h"
@@ -267,8 +264,8 @@ edit_sudoers(sp, editor, args, lineno)
     char *cp;                          /* scratch char pointer */
     char buf[PATH_MAX*2];              /* buffer used for copying files */
     char linestr[64];                  /* string version of lineno */
-    struct timespec ts1, ts2;          /* time before and after edit */
-    struct timespec orig_mtim;         /* starting mtime of sudoers file */
+    struct timeval tv, tv1, tv2;       /* time before and after edit */
+    struct timeval orig_mtim;          /* starting mtime of sudoers file */
     off_t orig_size;                   /* starting size of sudoers file */
     ssize_t nread;                     /* number of bytes read */
     struct stat sb;                    /* stat buffer */
@@ -280,8 +277,7 @@ edit_sudoers(sp, editor, args, lineno)
 #endif
        error(1, "can't stat %s", sp->path);
     orig_size = sb.st_size;
-    orig_mtim.tv_sec = mtim_getsec(sb);
-    orig_mtim.tv_nsec = mtim_getnsec(sb);
+    mtim_get(&sb, &orig_mtim);
 
     /* Create the temp file if needed and set timestamp. */
     if (sp->tpath == NULL) {
@@ -347,9 +343,9 @@ edit_sudoers(sp, editor, args, lineno)
      *  XPG4 specifies that vi's exit value is a function of the
      *  number of errors during editing (?!?!).
      */
-    gettime(&ts1);
+    gettime(&tv1);
     if (run_command(editor, av) != -1) {
-       gettime(&ts2);
+       gettime(&tv2);
        /*
         * Sanity checks.
         */
@@ -371,19 +367,20 @@ edit_sudoers(sp, editor, args, lineno)
 
     /* Set modified bit if use changed the file. */
     modified = TRUE;
+    mtim_get(&sb, &tv);
     if (orig_size == sb.st_size &&
-       orig_mtim.tv_sec == mtim_getsec(sb) &&
-       orig_mtim.tv_nsec == mtim_getnsec(sb)) {
+       orig_mtim.tv_sec == tv.tv_sec &&
+       orig_mtim.tv_usec == tv.tv_usec) {
        /*
         * If mtime and size match but the user spent no measurable
         * time in the editor we can't tell if the file was changed.
         */
-#ifdef HAVE_TIMESPECSUB2
-       timespecsub(&ts1, &ts2);
+#ifdef HAVE_TIMERSUB2
+       timersub(&tv1, &tv2);
 #else
-       timespecsub(&ts1, &ts2, &ts2);
+       timersub(&tv1, &tv2, &tv2);
 #endif
-       if (timespecisset(&ts2))
+       if (timerisset(&tv2))
            modified = FALSE;
     }