]> granicus.if.org Git - sudo/commitdiff
Add checks for st_mtim and st_mtimespec and add macros for pulling
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 7 Sep 2004 19:57:00 +0000 (19:57 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 7 Sep 2004 19:57:00 +0000 (19:57 +0000)
the mtime sec and nsec out of struct stat.  These are used in sudo_edit()
to better tell whether or not the file has changed.

config.h.in
configure
configure.in
sudo_edit.c

index 6c6a49e968e4b4ff50ee38f0f35ecf7ac3e880ca..1f1b1fcae15b0d8e0d6ddab23c6919864220692a 100644 (file)
 /* Define if you use Kerberos V. */
 #undef HAVE_KERB5
 
-/* Define if your LDAP needs <lber.h>. (OpenLDAP does not) */
+/* Define to 1 if your LDAP needs <lber.h>. (OpenLDAP does not) */
 #undef HAVE_LBER_H
 
 /* Define if you use LDAP. */
 /* Define to 1 if you have the `strrchr' function. */
 #undef HAVE_STRRCHR
 
+/* Define if your struct stat has an st_mtim member */
+#undef HAVE_ST_MTIM
+
+/* Define if your struct stat has an st_mtimespec member */
+#undef HAVE_ST_MTIMESPEC
+
 /* Define to 1 if you have the `sysconf' function. */
 #undef HAVE_SYSCONF
 
 /* Define if you want the hostname to be entered into the log file. */
 #undef HOST_IN_LOG
 
-/* Define if you want to ignore '.' and empty $PATH elements */
+/* Define if you want to ignore '.' and empty PATH elements */
 #undef IGNORE_DOT_PATH
 
 /* The message given when a bad password is entered. */
    code using `volatile' can become incorrect without. Disable with care. */
 #undef volatile
 
+/*
+ * Macros to pull sec and nsec parts of mtime from struct stat.
+ */
+#ifdef HAVE_ST_MTIM
+# define mtim_getsec(_x)       ((_x).st_mtim.tv_sec)
+# define mtim_getnsec(_x)      ((_x).st_mtim.tv_nsec)
+#else
+# ifdef HAVE_ST_MTIMESPEC
+#  define mtim_getsec(_x)      ((_x).st_mtimespec.tv_sec)
+#  define mtim_getnsec(_x)     ((_x).st_mtimespec.tv_nsec)
+# else
+#  define mtim_getsec(_x)      ((_x).st_mtime)
+#  define mtim_getnsec(_x)     (0)
+# endif /* HAVE_ST_MTIMESPEC */
+#endif /* HAVE_ST_MTIM */
+
 /*
  * Emulate a subset of waitpid() if we don't have it.
  */
index 9cfad54ae0b889dc6c11c2637086f791abda1a2c..72cef7c78537ae01747be0a4ee5820b2c802329c 100755 (executable)
--- a/configure
+++ b/configure
@@ -26441,6 +26441,191 @@ else
 fi
 done
 
+
+
+
+
+echo "$as_me:$LINENO: checking for struct stat.st_mtim" >&5
+echo $ECHO_N "checking for struct stat.st_mtim... $ECHO_C" >&6
+if test "${ac_cv_member_struct_stat_st_mtim+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static struct stat ac_aggr;
+if (ac_aggr.st_mtim)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_mtim=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static struct stat ac_aggr;
+if (sizeof ac_aggr.st_mtim)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_mtim=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_stat_st_mtim=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_mtim" >&5
+echo "${ECHO_T}$ac_cv_member_struct_stat_st_mtim" >&6
+if test $ac_cv_member_struct_stat_st_mtim = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_ST_MTIM 1
+_ACEOF
+
+else
+  echo "$as_me:$LINENO: checking for struct stat.st_mtimespec" >&5
+echo $ECHO_N "checking for struct stat.st_mtimespec... $ECHO_C" >&6
+if test "${ac_cv_member_struct_stat_st_mtimespec+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static struct stat ac_aggr;
+if (ac_aggr.st_mtimespec)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_mtimespec=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static struct stat ac_aggr;
+if (sizeof ac_aggr.st_mtimespec)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_mtimespec=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_stat_st_mtimespec=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_mtimespec" >&5
+echo "${ECHO_T}$ac_cv_member_struct_stat_st_mtimespec" >&6
+if test $ac_cv_member_struct_stat_st_mtimespec = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_ST_MTIMESPEC 1
+_ACEOF
+
+fi
+
+fi
+
 cat >conftest.$ac_ext <<_ACEOF
 #line $LINENO "configure"
 /* confdefs.h.  */
index 77fa87c13f3a5a9435c285e116a595317bba5dd3..a373197174a33d631178106b69561f84d782e35c 100644 (file)
@@ -1709,6 +1709,9 @@ SUDO_FUNC_FNMATCH(AC_DEFINE(HAVE_FNMATCH, 1, [Define if you have the `fnmatch' f
 SUDO_FUNC_ISBLANK
 AC_REPLACE_FUNCS(strerror strcasecmp sigaction strlcpy strlcat closefrom)
 AC_CHECK_FUNCS(snprintf vsnprintf asprintf vasprintf, , [NEED_SNPRINTF=1])
+AH_TEMPLATE(HAVE_ST_MTIM, [Define if your struct stat has an st_mtim member])
+AH_TEMPLATE(HAVE_ST_MTIMESPEC, [Define if your struct stat has an st_mtimespec member])
+AC_CHECK_MEMBER([struct stat.st_mtim], AC_DEFINE(HAVE_ST_MTIM), [AC_CHECK_MEMBER([struct stat.st_mtimespec], AC_DEFINE([HAVE_ST_MTIMESPEC]))])
 dnl
 dnl Check for the dirfd function/macro.  If not found, look for dd_fd in DIR.
 dnl
@@ -2240,6 +2243,22 @@ AH_TOP([#ifndef _SUDO_CONFIG_H
 #define _SUDO_CONFIG_H])
 
 AH_BOTTOM([/*
+ * Macros to pull sec and nsec parts of mtime from struct stat.
+ */
+#ifdef HAVE_ST_MTIM
+# define mtim_getsec(_x)       ((_x).st_mtim.tv_sec)
+# define mtim_getnsec(_x)      ((_x).st_mtim.tv_nsec)
+#else
+# ifdef HAVE_ST_MTIMESPEC
+#  define mtim_getsec(_x)      ((_x).st_mtimespec.tv_sec)
+#  define mtim_getnsec(_x)     ((_x).st_mtimespec.tv_nsec)
+# else
+#  define mtim_getsec(_x)      ((_x).st_mtime)
+#  define mtim_getnsec(_x)     (0)
+# endif /* HAVE_ST_MTIMESPEC */
+#endif /* HAVE_ST_MTIM */
+
+/*
  * Emulate a subset of waitpid() if we don't have it.
  */
 #ifdef HAVE_WAITPID
index c5a638b41a48e87d71892847f672687f912e77a0..a1893565e49238eef76ebaa164924e99b86139b4 100644 (file)
@@ -17,7 +17,9 @@
 #include "config.h"
 
 #include <sys/types.h>
+#include <sys/param.h>
 #include <sys/stat.h>
+#include <sys/time.h>
 #include <sys/wait.h>
 #include <sys/socket.h>
 #include <stdio.h>
@@ -49,6 +51,7 @@
 #include <signal.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <time.h>
 
 #include "sudo.h"
 
@@ -76,9 +79,9 @@ int sudo_edit(argc, argv)
     struct tempfile {
        char *tfile;
        char *ofile;
-       int tfd;
-       time_t omtime;          /* XXX - use st_mtimespec / st_mtim? */
+       struct timespec ots;
        off_t osize;
+       int tfd;
     } *tf;
 
     /*
@@ -122,11 +125,11 @@ int sudo_edit(argc, argv)
                i--;
                continue;
            }
-           sb.st_mtime = 0;
-           sb.st_size = 0;
+           memset(&sb, 0, sizeof(sb));
        }
        tf[i].ofile = *ap;
-       tf[i].omtime = sb.st_mtime;
+       tf[i].ots.tv_sec = mtim_getsec(sb);
+       tf[i].ots.tv_nsec = mtim_getnsec(sb);
        tf[i].osize = sb.st_size;
        if ((cp = strrchr(tf[i].ofile, '/')) != NULL)
            cp++;
@@ -159,9 +162,11 @@ int sudo_edit(argc, argv)
         * file's mtime.  It is better than nothing and we only use the info
         * to determine whether or not a file has been modified.
         */
-       if (touch(tf[i].tfd, NULL, tf[i].omtime, 0) == -1) {
-           if (fstat(tf[i].tfd, &sb) == 0)
-               tf[i].omtime = sb.st_mtime;
+       if (touch(tf[i].tfd, NULL, tf[i].ots.tv_sec, tf[i].ots.tv_nsec) == -1) {
+           if (fstat(tf[i].tfd, &sb) == 0) {
+               tf[i].ots.tv_sec = mtim_getsec(sb);
+               tf[i].ots.tv_nsec = mtim_getnsec(sb);
+           }
        }
 #endif
     }
@@ -262,7 +267,9 @@ int sudo_edit(argc, argv)
        }
 #ifdef HAVE_FSTAT
        if (fstat(tf[i].tfd, &sb) == 0) {
-           if (tf[i].osize == sb.st_size && tf[i].omtime == sb.st_mtime) {
+           if (tf[i].osize == sb.st_size &&
+               tf[i].ots.tv_sec == mtim_getsec(sb) &&
+               tf[i].ots.tv_nsec == mtim_getnsec(sb)) {
                warnx("%s unchanged", tf[i].ofile);
                unlink(tf[i].tfile);
                close(tf[i].tfd);