r21714: Change the VFS interface to use struct timespec
authorJeremy Allison <jra@samba.org>
Mon, 5 Mar 2007 23:40:03 +0000 (23:40 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:18:24 +0000 (12:18 -0500)
for utimes - change the call to ntimes. This preserves
nsec timestamps we get from stat (if the system supports
it) and only maps back down to usec or sec resolution
on time set. Looks bigger than it is as I had to move
lots of internal code from using time_t and struct utimebuf
to struct timespec.
Jeremy.
(This used to be commit 8f3d530c5a748ea90f42ed8fbe68ae92178d4875)

27 files changed:
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/client/client.c
source3/client/clitar.c
source3/client/smbctool.c
source3/include/smb.h
source3/include/smbprofile.h
source3/include/vfs.h
source3/include/vfs_macros.h
source3/lib/time.c
source3/modules/vfs_cap.c
source3/modules/vfs_catia.c
source3/modules/vfs_default.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_recycle.c
source3/profile/profile.c
source3/smbd/close.c
source3/smbd/dosmode.c
source3/smbd/fileio.c
source3/smbd/files.c
source3/smbd/nttrans.c
source3/smbd/reply.c
source3/smbd/trans2.c
source3/utils/net_status.c
source3/utils/status.c
source3/utils/status_profile.c
source3/web/statuspage.c

index 096068da147bf6b3c60564906d7d9dff1b0c1119..18ad5eb5172e2eff2532dee69feb6ea8e8969d79 100644 (file)
@@ -211,9 +211,9 @@ static char *skel_getwd(vfs_handle_struct *handle,  char *buf)
        return vfswrap_getwd(NULL,  buf);
 }
 
-static int skel_utime(vfs_handle_struct *handle,  const char *path, struct utimbuf *times)
+static int skel_ntimes(vfs_handle_struct *handle,  const char *path, const struct timespec ts[2])
 {
-       return vfswrap_utime(NULL,  path, times);
+       return vfswrap_ntimes(NULL,  path, ts);
 }
 
 static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T offset)
@@ -578,7 +578,7 @@ static vfs_op_tuple skel_op_tuples[] = {
        {SMB_VFS_OP(skel_fchown),                       SMB_VFS_OP_FCHOWN,              SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_chdir),                        SMB_VFS_OP_CHDIR,               SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_getwd),                        SMB_VFS_OP_GETWD,               SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(skel_utime),                        SMB_VFS_OP_UTIME,               SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(skel_ntimes),                       SMB_VFS_OP_NTIMES,              SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_ftruncate),                    SMB_VFS_OP_FTRUNCATE,           SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_lock),                         SMB_VFS_OP_LOCK,                SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(skel_getlock),                      SMB_VFS_OP_GETLOCK,             SMB_VFS_LAYER_OPAQUE},
index 2a379cd6d894896e1d75f87d99c5802fffaf0aae..b967a337ebca26ce47aaaf1c77294c5d73efde5d 100644 (file)
@@ -210,9 +210,9 @@ static char *skel_getwd(vfs_handle_struct *handle,  char *buf)
        return SMB_VFS_NEXT_GETWD(handle, buf);
 }
 
-static int skel_utime(vfs_handle_struct *handle,  const char *path, struct utimbuf *times)
+static int skel_ntimes(vfs_handle_struct *handle,  const char *path, const struct timespec ts[2])
 {
-       return SMB_VFS_NEXT_UTIME(handle, path, times);
+       return SMB_VFS_NEXT_NTIMES(handle, path, ts[2]);
 }
 
 static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T offset)
@@ -545,7 +545,7 @@ static vfs_op_tuple skel_op_tuples[] = {
        {SMB_VFS_OP(skel_fchown),                       SMB_VFS_OP_FCHOWN,              SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(skel_chdir),                        SMB_VFS_OP_CHDIR,               SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(skel_getwd),                        SMB_VFS_OP_GETWD,               SMB_VFS_LAYER_TRANSPARENT},
-       {SMB_VFS_OP(skel_utime),                        SMB_VFS_OP_UTIME,               SMB_VFS_LAYER_TRANSPARENT},
+       {SMB_VFS_OP(skel_ntimes),                       SMB_VFS_OP_NTIMES,              SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(skel_ftruncate),                    SMB_VFS_OP_FTRUNCATE,           SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(skel_lock),                         SMB_VFS_OP_LOCK,                SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(skel_getlock),                      SMB_VFS_OP_GETLOCK,             SMB_VFS_LAYER_TRANSPARENT},
index a7bb56ba88c924049b2070bd435171c1486b64df..605beb2e06c93708718659286f47c33ac5e177fd 100644 (file)
@@ -387,7 +387,7 @@ static void display_finfo(file_info *finfo)
                                 finfo->name,
                                 attrib_string(finfo->mode),
                                (double)finfo->size,
-                               time_to_asc(&t));
+                               time_to_asc(t));
                        dir_total += finfo->size;
                } else {
                        pstring afname;
@@ -404,7 +404,7 @@ static void display_finfo(file_info *finfo)
                        d_printf( "FILENAME:%s\n", afname);
                        d_printf( "MODE:%s\n", attrib_string(finfo->mode));
                        d_printf( "SIZE:%.0f\n", (double)finfo->size);
-                       d_printf( "MTIME:%s", time_to_asc(&t));
+                       d_printf( "MTIME:%s", time_to_asc(t));
                        fnum = cli_nt_create(cli, afname, CREATE_ACCESS_READ);
                        if (fnum == -1) {
                                DEBUG( 0, ("display_finfo() Failed to open %s: %s\n",
@@ -2713,7 +2713,7 @@ static int cmd_newer(void)
        if (ok && (sys_stat(buf,&sbuf) == 0)) {
                newer_than = sbuf.st_mtime;
                DEBUG(1,("Getting files newer than %s",
-                        time_to_asc(&newer_than)));
+                        time_to_asc(newer_than)));
        } else {
                newer_than = 0;
        }
index f228db119981f62b7cb981b39759d8f47a8a9130..c0748799b20163e75a9acb0fb5171a5bf795b289 100644 (file)
@@ -1650,7 +1650,7 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
                                        if (sys_stat(argv[Optind], &stbuf) == 0) {
                                                newer_than = stbuf.st_mtime;
                                                DEBUG(1,("Getting files newer than %s",
-                                                       time_to_asc(&newer_than)));
+                                                       time_to_asc(newer_than)));
                                                newOptind++;
                                                Optind++;
                                        } else {
index b7042f99cb2a5a8dc6389addeb133548a06397fc..29466108c072f2100ed1b720cae43ac82be2101a 100644 (file)
@@ -445,7 +445,7 @@ static void display_finfo(file_info *finfo)
                         finfo->name,
                         attrib_string(finfo->mode),
                         (double)finfo->size,
-                        time_to_asc(&t));
+                        time_to_asc(t));
                dir_total += finfo->size;
        }
 }
@@ -458,7 +458,7 @@ static void display_stat(char *name, struct stat *st)
 {
        time_t t = st->st_mtime;
        pstring time_str;
-       pstrcpy(time_str, time_to_asc(&t));
+       pstrcpy(time_str, time_to_asc(t));
        time_str[strlen(time_str)-1] = 0;
        d_printf("> %-30s", name);
        d_printf("%10.10s %8.0f  %s\n", *mode_t_string(st->st_mode), (double)st->st_size, time_str);
@@ -2561,7 +2561,7 @@ static int cmd_newer(void)
        if (ok && (sys_stat(buf,&sbuf) == 0)) {
                newer_than = sbuf.st_mtime;
                DEBUG(1,("Getting files newer than %s",
-                        time_to_asc(&newer_than)));
+                        time_to_asc(newer_than)));
        } else {
                newer_than = 0;
        }
index cea7638d79be0a46a90a6b9cccaeb080d6eb1eb1..1e31d8545d4c602dff30988a1c09e1e6c94a2fba 100644 (file)
@@ -495,8 +495,8 @@ typedef struct files_struct {
        uint32 access_mask;             /* NTCreateX access bits (FILE_READ_DATA etc.) */
        uint32 share_access;            /* NTCreateX share constants (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE). */
        BOOL pending_modtime_owner;
-       time_t pending_modtime;
-       time_t last_write_time;
+       struct timespec pending_modtime;
+       struct timespec last_write_time;
        int oplock_type;
        int sent_oplock_break;
        struct timed_event *oplock_timeout;
index fa7c6e4a5aec18a1d9bc5c7e1f4c3e83fa1683be..cc501739c163ea54ee99f39bbb93063f26a7f657 100644 (file)
@@ -152,9 +152,9 @@ enum profile_stats_values
 #define syscall_getwd_count __profile_stats_value(PR_VALUE_SYSCALL_GETWD, count)
 #define syscall_getwd_time __profile_stats_value(PR_VALUE_SYSCALL_GETWD, time)
 
-       PR_VALUE_SYSCALL_UTIME,
-#define syscall_utime_count __profile_stats_value(PR_VALUE_SYSCALL_UTIME, count)
-#define syscall_utime_time __profile_stats_value(PR_VALUE_SYSCALL_UTIME, time)
+       PR_VALUE_SYSCALL_NTIMES,
+#define syscall_ntimes_count __profile_stats_value(PR_VALUE_SYSCALL_NTIMES, count)
+#define syscall_ntimes_time __profile_stats_value(PR_VALUE_SYSCALL_NTIMES, time)
 
        PR_VALUE_SYSCALL_FTRUNCATE,
 #define syscall_ftruncate_count __profile_stats_value(PR_VALUE_SYSCALL_FTRUNCATE, count)
index 4c2b559bea31bbdc59bf63078328fe16c36f344b..7bcd6cdf2c40edf58bd0529300b6d1c559c69024 100644 (file)
@@ -67,7 +67,9 @@
    Also include kernel_flock call - jmcd */
 /* Changed to version 19, kernel change notify has been merged 
    Also included linux setlease call - jmcd */
-#define SMB_VFS_INTERFACE_VERSION 19
+/* Changed to version 20, use ntimes call instead of utime (greater
+ * timestamp resolition. JRA. */
+#define SMB_VFS_INTERFACE_VERSION 20
 
 
 /* to bug old modules which are trying to compile with the old functions */
@@ -144,7 +146,7 @@ typedef enum _vfs_op_type {
        SMB_VFS_OP_FCHOWN,
        SMB_VFS_OP_CHDIR,
        SMB_VFS_OP_GETWD,
-       SMB_VFS_OP_UTIME,
+       SMB_VFS_OP_NTIMES,
        SMB_VFS_OP_FTRUNCATE,
        SMB_VFS_OP_LOCK,
        SMB_VFS_OP_KERNEL_FLOCK,
@@ -269,7 +271,7 @@ struct vfs_ops {
                int (*fchown)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uid_t uid, gid_t gid);
                int (*chdir)(struct vfs_handle_struct *handle, const char *path);
                char *(*getwd)(struct vfs_handle_struct *handle, char *buf);
-               int (*utime)(struct vfs_handle_struct *handle, const char *path, struct utimbuf *times);
+               int (*ntimes)(struct vfs_handle_struct *handle, const char *path, const struct timespec ts[2]);
                int (*ftruncate)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset);
                BOOL (*lock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
                int (*kernel_flock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 share_mode);
@@ -392,7 +394,7 @@ struct vfs_ops {
                struct vfs_handle_struct *fchown;
                struct vfs_handle_struct *chdir;
                struct vfs_handle_struct *getwd;
-               struct vfs_handle_struct *utime;
+               struct vfs_handle_struct *ntimes;
                struct vfs_handle_struct *ftruncate;
                struct vfs_handle_struct *lock;
                struct vfs_handle_struct *kernel_flock;
index f50da3a02b566a1d1e3adecfff1b1e8c47c731f7..f4a289716bb21bf3bba11d0361cf9ac4742ab9d9 100644 (file)
@@ -67,7 +67,7 @@
 #define SMB_VFS_FCHOWN(fsp, fd, uid, gid) ((fsp)->conn->vfs.ops.fchown((fsp)->conn->vfs.handles.fchown, (fsp), (fd), (uid), (gid)))
 #define SMB_VFS_CHDIR(conn, path) ((conn)->vfs.ops.chdir((conn)->vfs.handles.chdir, (path)))
 #define SMB_VFS_GETWD(conn, buf) ((conn)->vfs.ops.getwd((conn)->vfs.handles.getwd, (buf)))
-#define SMB_VFS_UTIME(conn, path, times) ((conn)->vfs.ops.utime((conn)->vfs.handles.utime, (path), (times)))
+#define SMB_VFS_NTIMES(conn, path, ts) ((conn)->vfs.ops.ntimes((conn)->vfs.handles.ntimes, (path), (ts)))
 #define SMB_VFS_FTRUNCATE(fsp, fd, offset) ((fsp)->conn->vfs.ops.ftruncate((fsp)->conn->vfs.handles.ftruncate, (fsp), (fd), (offset)))
 #define SMB_VFS_LOCK(fsp, fd, op, offset, count, type) ((fsp)->conn->vfs.ops.lock((fsp)->conn->vfs.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
 #define SMB_VFS_KERNEL_FLOCK(fsp, fd, share_mode) ((fsp)->conn->vfs.ops.kernel_flock((fsp)->conn->vfs.handles.kernel_flock, (fsp), (fd), (share_mode)))
 #define SMB_VFS_OPAQUE_FCHOWN(fsp, fd, uid, gid) ((fsp)->conn->vfs_opaque.ops.fchown((fsp)->conn->vfs_opaque.handles.fchown, (fsp), (fd), (uid), (gid)))
 #define SMB_VFS_OPAQUE_CHDIR(conn, path) ((conn)->vfs_opaque.ops.chdir((conn)->vfs_opaque.handles.chdir, (path)))
 #define SMB_VFS_OPAQUE_GETWD(conn, buf) ((conn)->vfs_opaque.ops.getwd((conn)->vfs_opaque.handles.getwd, (buf)))
-#define SMB_VFS_OPAQUE_UTIME(conn, path, times) ((conn)->vfs_opaque.ops.utime((conn)->vfs_opaque.handles.utime, (path), (times)))
+#define SMB_VFS_OPAQUE_NTIMES(conn, path, ts) ((conn)->vfs_opaque.ops.ntimes((conn)->vfs_opaque.handles.ntimes, (path), (ts)))
 #define SMB_VFS_OPAQUE_FTRUNCATE(fsp, fd, offset) ((fsp)->conn->vfs_opaque.ops.ftruncate((fsp)->conn->vfs_opaque.handles.ftruncate, (fsp), (fd), (offset)))
 #define SMB_VFS_OPAQUE_LOCK(fsp, fd, op, offset, count, type) ((fsp)->conn->vfs_opaque.ops.lock((fsp)->conn->vfs_opaque.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
 #define SMB_VFS_OPAQUE_FLOCK(fsp, fd, share_mode) ((fsp)->conn->vfs_opaque.ops.lock((fsp)->conn->vfs_opaque.handles.kernel_flock, (fsp), (fd), (share_mode)))
 #define SMB_VFS_NEXT_FCHOWN(handle, fsp, fd, uid, gid) ((handle)->vfs_next.ops.fchown((handle)->vfs_next.handles.fchown, (fsp), (fd), (uid), (gid)))
 #define SMB_VFS_NEXT_CHDIR(handle, path) ((handle)->vfs_next.ops.chdir((handle)->vfs_next.handles.chdir, (path)))
 #define SMB_VFS_NEXT_GETWD(handle, buf) ((handle)->vfs_next.ops.getwd((handle)->vfs_next.handles.getwd, (buf)))
-#define SMB_VFS_NEXT_UTIME(handle, path, times) ((handle)->vfs_next.ops.utime((handle)->vfs_next.handles.utime, (path), (times)))
+#define SMB_VFS_NEXT_NTIMES(handle, path, ts) ((handle)->vfs_next.ops.ntimes((handle)->vfs_next.handles.ntimes, (path), (ts)))
 #define SMB_VFS_NEXT_FTRUNCATE(handle, fsp, fd, offset) ((handle)->vfs_next.ops.ftruncate((handle)->vfs_next.handles.ftruncate, (fsp), (fd), (offset)))
 #define SMB_VFS_NEXT_LOCK(handle, fsp, fd, op, offset, count, type) ((handle)->vfs_next.ops.lock((handle)->vfs_next.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
 #define SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, fd, share_mode)((handle)->vfs_next.ops.kernel_flock((handle)->vfs_next.handles.kernel_flock, (fsp), (fd), (share_mode)))
index 3abe233c4ffcdbac9648f4d43b4e0435635c7ec9..e98f8232abc58fa2beb3c552f40ccf21843cb7cb 100644 (file)
@@ -4,6 +4,7 @@
 
    Copyright (C) Andrew Tridgell               1992-2004
    Copyright (C) Stefan (metze) Metzmacher     2002   
+   Copyright (C) Jeremy Allison                        2007
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
 #define NTTIME_INFINITY (NTTIME)0x8000000000000000LL
 
-/**
+/***************************************************************************
  External access to time_t_min and time_t_max.
-**/
+****************************************************************************/
+
 time_t get_time_t_max(void)
 {
        return TIME_T_MAX;
 }
 
-/**
-a gettimeofday wrapper
-**/
+/***************************************************************************
+ A gettimeofday wrapper.
+****************************************************************************/
+
 void GetTimeOfDay(struct timeval *tval)
 {
 #ifdef HAVE_GETTIMEOFDAY_TZ
@@ -58,14 +61,6 @@ void GetTimeOfDay(struct timeval *tval)
 #endif
 }
 
-struct timespec convert_time_t_to_timespec(time_t t)
-{
-       struct timespec ts;
-       ts.tv_sec = t;
-       ts.tv_nsec = 0;
-       return ts;
-}
-
 #if (SIZEOF_LONG == 8)
 #define TIME_FIXUP_CONSTANT_INT 11644473600L
 #elif (SIZEOF_LONG_LONG == 8)
@@ -113,10 +108,10 @@ void unix_to_nt_time(NTTIME *nt, time_t t)
        *nt = t2;
 }
 
+/****************************************************************************
+ Check if it's a null unix time.
+****************************************************************************/
 
-/**
-check if it's a null unix time
-**/
 BOOL null_time(time_t t)
 {
        return t == 0 || 
@@ -124,15 +119,26 @@ BOOL null_time(time_t t)
                t == (time_t)-1;
 }
 
+/****************************************************************************
+ Check if it's a null NTTIME.
+****************************************************************************/
 
-/**
-check if it's a null NTTIME
-**/
 BOOL null_nttime(NTTIME t)
 {
        return t == 0 || t == (NTTIME)-1;
 }
 
+/****************************************************************************
+ Check if it's a null timespec.
+****************************************************************************/
+
+BOOL null_timespec(struct timespec ts)
+{
+       return ts.tv_sec == 0 || 
+               ts.tv_sec == (time_t)0xFFFFFFFF || 
+               ts.tv_sec == (time_t)-1;
+}
+
 /*******************************************************************
   create a 16 bit dos packed date
 ********************************************************************/
@@ -549,8 +555,9 @@ NTTIME timeval_to_nttime(const struct timeval *tv)
 }
 
 /*******************************************************************
-yield the difference between *A and *B, in seconds, ignoring leap seconds
+ Yield the difference between *A and *B, in seconds, ignoring leap seconds.
 ********************************************************************/
+
 static int tm_diff(struct tm *a, struct tm *b)
 {
        int ay = a->tm_year + (1900 - 1);
@@ -568,9 +575,10 @@ static int tm_diff(struct tm *a, struct tm *b)
 
 int extra_time_offset=0;
 
-/**
-  return the UTC offset in seconds west of UTC, or 0 if it cannot be determined
- */
+/*******************************************************************
+ Return the UTC offset in seconds west of UTC, or 0 if it cannot be determined.
+********************************************************************/
+
 int get_time_zone(time_t t)
 {
        struct tm *tm = gmtime(&t);
@@ -780,7 +788,7 @@ void put_long_date(char *p, time_t t)
  structure.
 ****************************************************************************/
 
-time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs)
+time_t get_create_time(const SMB_STRUCT_STAT *st,BOOL fake_dirs)
 {
        time_t ret, ret1;
 
@@ -802,7 +810,7 @@ time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs)
        return ret;
 }
 
-struct timespec get_create_timespec(SMB_STRUCT_STAT *st,BOOL fake_dirs)
+struct timespec get_create_timespec(const SMB_STRUCT_STAT *st,BOOL fake_dirs)
 {
        struct timespec ts;
        ts.tv_sec = get_create_time(st, fake_dirs);
@@ -814,7 +822,7 @@ struct timespec get_create_timespec(SMB_STRUCT_STAT *st,BOOL fake_dirs)
  Get/Set all the possible time fields from a stat struct as a timespec.
 ****************************************************************************/
 
-struct timespec get_atimespec(SMB_STRUCT_STAT *pst)
+struct timespec get_atimespec(const SMB_STRUCT_STAT *pst)
 {
 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
        struct timespec ret;
@@ -854,7 +862,7 @@ void set_atimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
 #endif
 }
 
-struct timespec get_mtimespec(SMB_STRUCT_STAT *pst)
+struct timespec get_mtimespec(const SMB_STRUCT_STAT *pst)
 {
 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
        struct timespec ret;
@@ -894,7 +902,7 @@ void set_mtimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
 #endif
 }
 
-struct timespec get_ctimespec(SMB_STRUCT_STAT *pst)
+struct timespec get_ctimespec(const SMB_STRUCT_STAT *pst)
 {
 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
        struct timespec ret;
@@ -1022,6 +1030,81 @@ time_t convert_timespec_to_time_t(struct timespec ts)
        return ts.tv_sec;
 }
 
+struct timespec convert_time_t_to_timespec(time_t t)
+{
+       struct timespec ts;
+       ts.tv_sec = t;
+       ts.tv_nsec = 0;
+       return ts;
+}
+
+/****************************************************************************
+ Convert a normalized timeval to a timespec.
+****************************************************************************/
+
+struct timespec convert_timeval_to_timespec(const struct timeval tv)
+{
+       struct timespec ts;
+       ts.tv_sec = tv.tv_sec;
+       ts.tv_nsec = tv.tv_usec * 1000;
+       return ts;
+}
+
+/****************************************************************************
+ Convert a normalized timespec to a timeval.
+****************************************************************************/
+
+struct timeval convert_timespec_to_timeval(const struct timespec ts)
+{
+       struct timeval tv;
+       tv.tv_sec = ts.tv_sec;
+       tv.tv_usec = ts.tv_nsec / 1000;
+       return tv;
+}
+
+/****************************************************************************
+ Return a timespec for the current time
+****************************************************************************/
+
+struct timespec timespec_current(void)
+{
+       struct timeval tv;
+       struct timespec ts;
+       GetTimeOfDay(&tv);
+       ts.tv_sec = tv.tv_sec;
+       ts.tv_nsec = tv.tv_sec * 1000;
+       return ts;
+}
+
+/****************************************************************************
+ Return the lesser of two timespecs.
+****************************************************************************/
+
+struct timespec timespec_min(const struct timespec *ts1,
+                          const struct timespec *ts2)
+{
+       if (ts1->tv_sec < ts2->tv_sec) return *ts1;
+       if (ts1->tv_sec > ts2->tv_sec) return *ts2;
+       if (ts1->tv_nsec < ts2->tv_nsec) return *ts1;
+       return *ts2;
+}
+
+/****************************************************************************
+  compare two timespec structures. 
+  Return -1 if ts1 < ts2
+  Return 0 if ts1 == ts2
+  Return 1 if ts1 > ts2
+****************************************************************************/
+
+int timespec_compare(const struct timespec *ts1, const struct timespec *ts2)
+{
+       if (ts1->tv_sec  > ts2->tv_sec)  return 1;
+       if (ts1->tv_sec  < ts2->tv_sec)  return -1;
+       if (ts1->tv_nsec > ts2->tv_nsec) return 1;
+       if (ts1->tv_nsec < ts2->tv_nsec) return -1;
+       return 0;
+}
+
 /****************************************************************************
  Interprets an nt time into a unix struct timespec.
  Differs from nt_time_to_unix in that an 8 byte value of 0xffffffffffffffff
@@ -1284,10 +1367,10 @@ BOOL null_mtime(time_t mtime)
  and asctime fail.
 ****************************************************************************/
 
-const char *time_to_asc(const time_t *t)
+const char *time_to_asc(const time_t t)
 {
        const char *asct;
-       struct tm *lt = localtime(t);
+       struct tm *lt = localtime(&t);
 
        if (!lt) {
                return "unknown time";
@@ -1347,4 +1430,3 @@ BOOL nt_time_is_set(const NTTIME *nt)
 
        return True;
 }
-
index c254ba0ed97ebc76d0058a0608157d0b54dfbbac..d495ed5d1464da900af14bd536f8ebdf1d0e1741 100644 (file)
@@ -131,11 +131,11 @@ static int cap_chdir(vfs_handle_struct *handle, const char *path)
        return SMB_VFS_NEXT_CHDIR(handle, cappath);
 }
 
-static int cap_utime(vfs_handle_struct *handle, const char *path, struct utimbuf *times)
+static int cap_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2])
 {
         pstring cappath;
        capencode(cappath, path);
-       return SMB_VFS_NEXT_UTIME(handle, cappath, times);
+       return SMB_VFS_NEXT_NTIMES(handle, cappath, ts);
 }
 
 
@@ -327,7 +327,7 @@ static vfs_op_tuple cap_op_tuples[] = {
        {SMB_VFS_OP(cap_chmod),                 SMB_VFS_OP_CHMOD,               SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(cap_chown),                 SMB_VFS_OP_CHOWN,               SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(cap_chdir),                 SMB_VFS_OP_CHDIR,               SMB_VFS_LAYER_TRANSPARENT},
-       {SMB_VFS_OP(cap_utime),                 SMB_VFS_OP_UTIME,               SMB_VFS_LAYER_TRANSPARENT},
+       {SMB_VFS_OP(cap_ntimes),                        SMB_VFS_OP_NTIMES,              SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(cap_symlink),                       SMB_VFS_OP_SYMLINK,             SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(cap_readlink),                      SMB_VFS_OP_READLINK,            SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(cap_link),                          SMB_VFS_OP_LINK,                SMB_VFS_LAYER_TRANSPARENT},
index 478dab6cbedc896cc37a8e256e766c546fd2d8be..fe1ce830f7b7a5bba31476f89a3e1efb8b5fbd0d 100644 (file)
@@ -184,10 +184,10 @@ static char *catia_getwd(vfs_handle_struct *handle, char *buf)
         return SMB_VFS_NEXT_GETWD(handle, buf);
 }
 
-static int catia_utime(vfs_handle_struct *handle,
-                      const char *path, struct utimbuf *times)
+static int catia_ntimes(vfs_handle_struct *handle,
+                      const char *path, const struct timespec ts[2])
 {
-        return SMB_VFS_NEXT_UTIME(handle, path, times);
+        return SMB_VFS_NEXT_NTIMES(handle, path, ts);
 }
 
 static BOOL catia_symlink(vfs_handle_struct *handle,
@@ -278,7 +278,7 @@ SMB_VFS_LAYER_TRANSPARENT},
 SMB_VFS_LAYER_TRANSPARENT},
         {SMB_VFS_OP(catia_getwd),                       SMB_VFS_OP_GETWD,  
 SMB_VFS_LAYER_TRANSPARENT},
-        {SMB_VFS_OP(catia_utime),                       SMB_VFS_OP_UTIME,  
+        {SMB_VFS_OP(catia_ntimes),                       SMB_VFS_OP_NTIMES,  
 SMB_VFS_LAYER_TRANSPARENT},
         {SMB_VFS_OP(catia_symlink), SMB_VFS_OP_SYMLINK, 
 SMB_VFS_LAYER_TRANSPARENT},
index c0b80e17754a61d9f93203b883d54c4dc9170101..f482a3b1f3d06df9dbe7a19b6c4648b904383403 100644 (file)
@@ -2,6 +2,7 @@
    Unix SMB/CIFS implementation.
    Wrap disk only vfs functions to sidestep dodgy compilers.
    Copyright (C) Tim Potter 1998
+   Copyright (C) Jeremy Allison 2007
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -612,13 +613,35 @@ static char *vfswrap_getwd(vfs_handle_struct *handle,  char *path)
        return result;
 }
 
-static int vfswrap_utime(vfs_handle_struct *handle,  const char *path, struct utimbuf *times)
+/*********************************************************************
+ nsec timestamp resolution call. Convert down to whatever the underlying
+ system will support.
+**********************************************************************/
+
+static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2])
 {
        int result;
 
-       START_PROFILE(syscall_utime);
-       result = utime(path, times);
-       END_PROFILE(syscall_utime);
+       START_PROFILE(syscall_ntimes);
+#if defined(HAVE_UTIMES)
+       {
+               struct timeval tv[2];
+               tv[0] = convert_timespec_to_timeval(ts[0]);
+               tv[1] = convert_timespec_to_timeval(ts[1]);
+               result = utimes(path, tv);
+       }
+#elif defined(HAVE_UTIME)
+       {
+               struct utimebuf times;
+               times.actime = convert_timespec_to_time_t(ts[0]);
+               times.modtime = convert_timespec_to_time_t(ts[1]);
+               result = utime(path, times);
+       }
+#else
+       errno = ENOSYS;
+       result = -1;
+#endif
+       END_PROFILE(syscall_ntimes);
        return result;
 }
 
@@ -1239,7 +1262,7 @@ static vfs_op_tuple vfs_default_ops[] = {
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_getwd),     SMB_VFS_OP_GETWD,
         SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_utime),     SMB_VFS_OP_UTIME,
+       {SMB_VFS_OP(vfswrap_ntimes),    SMB_VFS_OP_NTIMES,
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_ftruncate), SMB_VFS_OP_FTRUNCATE,
         SMB_VFS_LAYER_OPAQUE},
index 6036e49fc15702097d57e7fce2c63d87f9dbec9a..e609ae1cd1fa757139c066ab862e07ee69456552 100644 (file)
@@ -151,8 +151,8 @@ static int smb_full_audit_chdir(vfs_handle_struct *handle,
                       const char *path);
 static char *smb_full_audit_getwd(vfs_handle_struct *handle,
                         char *path);
-static int smb_full_audit_utime(vfs_handle_struct *handle,
-                      const char *path, struct utimbuf *times);
+static int smb_full_audit_ntimes(vfs_handle_struct *handle,
+                      const char *path, const struct timespec ts[2]);
 static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp,
                           int fd, SMB_OFF_T len);
 static BOOL smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp, int fd,
@@ -375,7 +375,7 @@ static vfs_op_tuple audit_op_tuples[] = {
         SMB_VFS_LAYER_LOGGER},
        {SMB_VFS_OP(smb_full_audit_getwd),      SMB_VFS_OP_GETWD,
         SMB_VFS_LAYER_LOGGER},
-       {SMB_VFS_OP(smb_full_audit_utime),      SMB_VFS_OP_UTIME,
+       {SMB_VFS_OP(smb_full_audit_ntimes),     SMB_VFS_OP_NTIMES,
         SMB_VFS_LAYER_LOGGER},
        {SMB_VFS_OP(smb_full_audit_ftruncate),  SMB_VFS_OP_FTRUNCATE,
         SMB_VFS_LAYER_LOGGER},
@@ -549,7 +549,7 @@ static struct {
        { SMB_VFS_OP_FCHOWN,    "fchown" },
        { SMB_VFS_OP_CHDIR,     "chdir" },
        { SMB_VFS_OP_GETWD,     "getwd" },
-       { SMB_VFS_OP_UTIME,     "utime" },
+       { SMB_VFS_OP_NTIMES,    "ntimes" },
        { SMB_VFS_OP_FTRUNCATE, "ftruncate" },
        { SMB_VFS_OP_LOCK,      "lock" },
        { SMB_VFS_OP_KERNEL_FLOCK,      "kernel_flock" },
@@ -1267,14 +1267,14 @@ static char *smb_full_audit_getwd(vfs_handle_struct *handle,
        return result;
 }
 
-static int smb_full_audit_utime(vfs_handle_struct *handle,
-                      const char *path, struct utimbuf *times)
+static int smb_full_audit_ntimes(vfs_handle_struct *handle,
+                      const char *path, const struct timespec ts[2])
 {
        int result;
 
-       result = SMB_VFS_NEXT_UTIME(handle, path, times);
+       result = SMB_VFS_NEXT_NTIMES(handle, path, ts);
 
-       do_log(SMB_VFS_OP_UTIME, (result >= 0), handle, "%s", path);
+       do_log(SMB_VFS_OP_NTIMES, (result >= 0), handle, "%s", path);
 
        return result;
 }
index b417b9cbff830f968397d9390dc14ef0051a8d4e..240931fa7814a6cd206b6f13a67d4248793ec4eb 100644 (file)
@@ -364,18 +364,16 @@ static BOOL matchparam(const char **haystack_list, const char *needle)
 static void recycle_do_touch(vfs_handle_struct *handle, const char *fname, BOOL touch_mtime)
 {
        SMB_STRUCT_STAT st;
-       struct utimbuf tb;
-       time_t currtime;
+       struct timespec ts[2];
        
        if (SMB_VFS_NEXT_STAT(handle, fname, &st) != 0) {
                DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno)));
                return;
        }
-       currtime = time(&currtime);
-       tb.actime = currtime;
-       tb.modtime = touch_mtime ? currtime : st.st_mtime;
+       ts[0] = timespec_current(); /* atime */
+       ts[1] = touch_mtime ? ts[0] : get_mtimespec(&st); /* mtime */
 
-       if (SMB_VFS_NEXT_UTIME(handle, fname, &tb) == -1 ) {
+       if (SMB_VFS_NEXT_NTIMES(handle, fname, ts) == -1 ) {
                DEBUG(0, ("recycle: touching %s failed, reason = %s\n", fname, strerror(errno)));
        }
 }
index 30b06492545beed883d1d70ff9dce3e87126c76d..686d130b567f20554842292dd1ee9765ad649bef 100644 (file)
@@ -285,7 +285,7 @@ BOOL profile_setup(BOOL rdonly)
            "syscall_fchown",           /* PR_VALUE_SYSCALL_FCHOWN */
            "syscall_chdir",            /* PR_VALUE_SYSCALL_CHDIR */
            "syscall_getwd",            /* PR_VALUE_SYSCALL_GETWD */
-           "syscall_utime",            /* PR_VALUE_SYSCALL_UTIME */
+           "syscall_ntimes",           /* PR_VALUE_SYSCALL_NTIMES */
            "syscall_ftruncate",        /* PR_VALUE_SYSCALL_FTRUNCATE */
            "syscall_fcntl_lock",       /* PR_VALUE_SYSCALL_FCNTL_LOCK */
            "syscall_kernel_flock",     /* PR_VALUE_SYSCALL_KERNEL_FLOCK */
index 50111f62bbf2f74adb7f983fad0d2438e87d256e..1c9f6ea8c42deb9313b44f0390ac6174f850d015 100644 (file)
@@ -361,9 +361,9 @@ static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_
         * Ensure pending modtime is set after close.
         */
 
-       if(fsp->pending_modtime && fsp->pending_modtime_owner) {
+       if (fsp->pending_modtime_owner && !null_timespec(fsp->pending_modtime)) {
                set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
-       } else if (fsp->last_write_time) {
+       } else if (!null_timespec(fsp->last_write_time)) {
                set_filetime(conn, fsp->fsp_name, fsp->last_write_time);
        }
 
index ad79bbacddf31382fa70e4331f6929ff1fbace8d..71d4fa179d4949fc72028c7fea89207994bc93af 100644 (file)
@@ -282,7 +282,7 @@ static BOOL set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_
                }
 
                /* We want DOS semantics, ie allow non owner with write permission to change the
-                       bits on a file. Just like file_utime below.
+                       bits on a file. Just like file_ntimes below.
                */
 
                /* Check if we have write access. */
@@ -504,7 +504,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
                return -1;
 
        /* We want DOS semantics, ie allow non owner with write permission to change the
-               bits on a file. Just like file_utime below.
+               bits on a file. Just like file_ntimes below.
        */
 
        /* Check if we have write access. */
@@ -532,11 +532,11 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
 }
 
 /*******************************************************************
- Wrapper around dos_utime that possibly allows DOS semantics rather
+ Wrapper around the VFS ntimes that possibly allows DOS semantics rather
  than POSIX.
 *******************************************************************/
 
-int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times)
+int file_ntimes(connection_struct *conn, const char *fname, const struct timespec ts[2])
 {
        SMB_STRUCT_STAT sbuf;
        int ret = -1;
@@ -555,14 +555,17 @@ int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times
                return 0;
        }
 
-       if(SMB_VFS_UTIME(conn,fname, times) == 0)
+       if(SMB_VFS_NTIMES(conn, fname, ts) == 0) {
                return 0;
+       }
 
-       if((errno != EPERM) && (errno != EACCES))
+       if((errno != EPERM) && (errno != EACCES)) {
                return -1;
+       }
 
-       if(!lp_dos_filetimes(SNUM(conn)))
+       if(!lp_dos_filetimes(SNUM(conn))) {
                return -1;
+       }
 
        /* We have permission (given by the Samba admin) to
           break POSIX semantics and allow a user to change
@@ -574,7 +577,7 @@ int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times
        if (can_write_to_file(conn, fname, &sbuf)) {
                /* We are allowed to become root and change the filetime. */
                become_root();
-               ret = SMB_VFS_UTIME(conn,fname, times);
+               ret = SMB_VFS_NTIMES(conn, fname, ts);
                unbecome_root();
        }
 
@@ -585,16 +588,19 @@ int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times
  Change a filetime - possibly allowing DOS semantics.
 *******************************************************************/
 
-BOOL set_filetime(connection_struct *conn, const char *fname, time_t mtime)
+BOOL set_filetime(connection_struct *conn, const char *fname,
+               const struct timespec mtime)
 {
-       struct utimbuf times;
+       struct timespec ts[2];
 
-       if (null_mtime(mtime))
+       if (null_timespec(mtime)) {
                return(True);
+       }
 
-       times.modtime = times.actime = mtime;
+       ts[1] = mtime; /* mtime. */
+       ts[0] = ts[1]; /* atime. */
 
-       if (file_utime(conn, fname, &times)) {
+       if (file_ntimes(conn, fname, ts)) {
                DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
                return False;
        }
@@ -602,5 +608,5 @@ BOOL set_filetime(connection_struct *conn, const char *fname, time_t mtime)
        notify_fname(conn, NOTIFY_ACTION_MODIFIED,
                     FILE_NOTIFY_CHANGE_LAST_WRITE, fname);
   
-       return(True);
-} 
+       return True;
+}
index e0945be8893e220031b13ce91899929ecf478aff..65238c0e9ee60bb0e7c47767e2182caaa2363319 100644 (file)
@@ -149,13 +149,13 @@ static ssize_t real_write_file(files_struct *fsp,const char *data, SMB_OFF_T pos
                 * The 99% solution will hopefully be good enough in this case. JRA.
                 */
 
-               if (fsp->pending_modtime) {
+               if (!null_timespec(fsp->pending_modtime)) {
                        set_filetime(fsp->conn, fsp->fsp_name, fsp->pending_modtime);
 
                        /* If we didn't get the "set modtime" call ourselves, we must
                           store the last write time to restore on close. JRA. */
                        if (!fsp->pending_modtime_owner) {
-                               fsp->last_write_time = time(NULL);
+                               fsp->last_write_time = timespec_current();
                        }
                }
 
index 0706548334494113b80d7e9b2cf949d8c5065c38..062bebd58e66886627a472c0e293b83b158fa066 100644 (file)
@@ -383,11 +383,11 @@ files_struct *file_find_print(void)
  Record the owner of that modtime.
 ****************************************************************************/
 
-void fsp_set_pending_modtime(files_struct *tfsp, time_t pmod)
+void fsp_set_pending_modtime(files_struct *tfsp, const struct timespec mod)
 {
        files_struct *fsp;
 
-       if (null_mtime(pmod)) {
+       if (null_timespec(mod)) {
                return;
        }
 
@@ -395,7 +395,7 @@ void fsp_set_pending_modtime(files_struct *tfsp, time_t pmod)
                if ( fsp->fh->fd != -1 &&
                                fsp->dev == tfsp->dev &&
                                fsp->inode == tfsp->inode ) {
-                       fsp->pending_modtime = pmod;
+                       fsp->pending_modtime = mod;
                        fsp->pending_modtime_owner = False;
                }
        }
index 968c536cafd7152923b1e694a8b17800b8e8d8ed..eedc3cfba4479d2a93de8abc23f33f29ab33ca6b 100644 (file)
@@ -1675,7 +1675,7 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
        close_file(fsp1,NORMAL_CLOSE);
 
        /* Ensure the modtime is set correctly on the destination file. */
-       fsp_set_pending_modtime(fsp2, sbuf1.st_mtime);
+       fsp_set_pending_modtime(fsp2, get_mtimespec(&sbuf1));
 
        status = close_file(fsp2,NORMAL_CLOSE);
 
index 25c2aaa4dcb730054382ec9d0283d64f1e910983..df560390c949fd2f39ad93b5c09b8d2f19c33a7b 100644 (file)
@@ -828,7 +828,7 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                }
        }
 
-       if (!set_filetime(conn,fname,mtime)) {
+       if (!set_filetime(conn,fname,convert_time_t_to_timespec(mtime))) {
                END_PROFILE(SMBsetatr);
                return UNIXERROR(ERRDOS, ERRnoaccess);
        }
@@ -1483,7 +1483,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
        int com;
        int outsize = 0;
        uint32 fattr = SVAL(inbuf,smb_vwv0);
-       struct utimbuf times;
+       struct timespec ts[2];
        files_struct *fsp;
        int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
        SMB_STRUCT_STAT sbuf;
@@ -1497,7 +1497,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
  
        com = SVAL(inbuf,smb_com);
 
-       times.modtime = srv_make_unix_date3(inbuf + smb_vwv1);
+       ts[1] = convert_time_t_to_timespec(srv_make_unix_date3(inbuf + smb_vwv1)); /* mtime. */
 
        srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), 0, STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
@@ -1550,8 +1550,8 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                return ERROR_NT(status);
        }
  
-       times.actime = sbuf.st_atime;
-       file_utime(conn, fname, &times);
+       ts[0] = get_atimespec(&sbuf); /* atime. */
+       file_ntimes(conn, fname, ts);
 
        outsize = set_message(outbuf,1,0,True);
        SSVAL(outbuf,smb_vwv0,fsp->fnum);
@@ -3146,7 +3146,6 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
 {
        NTSTATUS status = NT_STATUS_OK;
        int outsize = 0;
-       time_t mtime;
        files_struct *fsp = NULL;
        START_PROFILE(SMBclose);
 
@@ -3188,8 +3187,8 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
                 * Take care of any time sent in the close.
                 */
 
-               mtime = srv_make_unix_date3(inbuf+smb_vwv1);
-               fsp_set_pending_modtime(fsp, mtime);
+               fsp_set_pending_modtime(fsp,
+                               convert_time_t_to_timespec(srv_make_unix_date3(inbuf+smb_vwv1)));
 
                /*
                 * close_file() returns the unix errno if an error
@@ -3222,7 +3221,7 @@ int reply_writeclose(connection_struct *conn,
        NTSTATUS close_status = NT_STATUS_OK;
        SMB_OFF_T startpos;
        char *data;
-       time_t mtime;
+       struct timespec mtime;
        files_struct *fsp = file_fsp(inbuf,smb_vwv0);
        START_PROFILE(SMBwriteclose);
 
@@ -3233,7 +3232,7 @@ int reply_writeclose(connection_struct *conn,
 
        numtowrite = SVAL(inbuf,smb_vwv1);
        startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
-       mtime = srv_make_unix_date3(inbuf+smb_vwv4);
+       mtime = convert_time_t_to_timespec(srv_make_unix_date3(inbuf+smb_vwv4));
        data = smb_buf(inbuf) + 1;
   
        if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
@@ -3243,7 +3242,7 @@ int reply_writeclose(connection_struct *conn,
   
        nwritten = write_file(fsp,data,startpos,numtowrite);
 
-       set_filetime(conn, fsp->fsp_name,mtime);
+       set_filetime(conn, fsp->fsp_name, mtime);
   
        /*
         * More insanity. W2K only closes the file if writelen > 0.
@@ -4724,7 +4723,7 @@ NTSTATUS copy_file(connection_struct *conn,
        close_file(fsp1,NORMAL_CLOSE);
 
        /* Ensure the modtime is set correctly on the destination file. */
-       fsp_set_pending_modtime( fsp2, src_sbuf.st_mtime);
+       fsp_set_pending_modtime( fsp2, get_mtimespec(&src_sbuf));
 
        /*
         * As we are opening fsp1 read-only we only expect
@@ -5536,7 +5535,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
 
 int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
 {
-       struct utimbuf unix_times;
+       struct timespec ts[2];
        int outsize = 0;
        files_struct *fsp = file_fsp(inbuf,smb_vwv0);
        START_PROFILE(SMBsetattrE);
@@ -5553,15 +5552,15 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
         * time as UNIX can't set this.
         */
 
-       unix_times.actime = srv_make_unix_date2(inbuf+smb_vwv3);
-       unix_times.modtime = srv_make_unix_date2(inbuf+smb_vwv5);
+       ts[0] = convert_time_t_to_timespec(srv_make_unix_date2(inbuf+smb_vwv3)); /* atime. */
+       ts[1] = convert_time_t_to_timespec(srv_make_unix_date2(inbuf+smb_vwv5)); /* mtime. */
   
        /* 
         * Patch from Ray Frush <frush@engr.colostate.edu>
         * Sometimes times are sent as zero - ignore them.
         */
 
-       if (null_mtime(unix_times.actime) && null_mtime(unix_times.modtime)) {
+       if (null_timespec(ts[0]) && null_timespec(ts[1])) {
                /* Ignore request */
                if( DEBUGLVL( 3 ) ) {
                        dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
@@ -5569,20 +5568,22 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
                }
                END_PROFILE(SMBsetattrE);
                return(outsize);
-       } else if (!null_mtime(unix_times.actime) && null_mtime(unix_times.modtime)) {
+       } else if (!null_timespec(ts[0]) && null_timespec(ts[1])) {
                /* set modify time = to access time if modify time was unset */
-               unix_times.modtime = unix_times.actime;
+               ts[1] = ts[0];
        }
 
        /* Set the date on this file */
        /* Should we set pending modtime here ? JRA */
-       if(file_utime(conn, fsp->fsp_name, &unix_times)) {
+       if(file_ntimes(conn, fsp->fsp_name, ts)) {
                END_PROFILE(SMBsetattrE);
                return ERROR_DOS(ERRDOS,ERRnoaccess);
        }
   
-       DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
-               fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
+       DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n",
+               fsp->fnum,
+               (unsigned int)ts[0].tv_sec,
+               (unsigned int)ts[1].tv_sec));
 
        END_PROFILE(SMBsetattrE);
        return(outsize);
index 33618360f1944cdd61c5e9c773b7be690b5304cf..41fd2c5102e6a694db24e0cdaeb2bc92642b3632 100644 (file)
@@ -3175,18 +3175,16 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
        allocation_size = get_allocation_size(conn,fsp,&sbuf);
 
        if (fsp) {
-               if (fsp->pending_modtime) {
+               if (!null_timespec(fsp->pending_modtime)) {
                        /* the pending modtime overrides the current modtime */
-                       mtime_ts.tv_sec = fsp->pending_modtime;
-                       mtime_ts.tv_nsec = 0;
+                       mtime_ts = fsp->pending_modtime;
                }
        } else {
                /* Do we have this path open ? */
                files_struct *fsp1 = file_find_di_first(sbuf.st_dev, sbuf.st_ino);
-               if (fsp1 && fsp1->pending_modtime) {
+               if (fsp1 && !null_timespec(fsp1->pending_modtime)) {
                        /* the pending modtime overrides the current modtime */
-                       mtime_ts.tv_sec = fsp1->pending_modtime;
-                       mtime_ts.tv_nsec = 0;
+                       mtime_ts = fsp->pending_modtime;
                }
                if (fsp1 && fsp1->initial_allocation_size) {
                        allocation_size = get_allocation_size(conn, fsp1, &sbuf);
@@ -3798,7 +3796,7 @@ static NTSTATUS smb_set_file_time(connection_struct *conn,
                                files_struct *fsp,
                                const char *fname,
                                const SMB_STRUCT_STAT *psbuf,
-                               struct utimbuf tvs)
+                               struct timespec ts[2])
 {
        uint32 action =
                FILE_NOTIFY_CHANGE_LAST_ACCESS
@@ -3810,26 +3808,30 @@ static NTSTATUS smb_set_file_time(connection_struct *conn,
        }
 
        /* get some defaults (no modifications) if any info is zero or -1. */
-       if (null_mtime(tvs.actime)) {
-               tvs.actime = psbuf->st_atime;
+       if (null_timespec(ts[0])) {
+               ts[0] = get_atimespec(psbuf);
                action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
        }
 
-       if (null_mtime(tvs.modtime)) {
-               tvs.modtime = psbuf->st_mtime;
+       if (null_timespec(ts[1])) {
+               ts[1] = get_mtimespec(psbuf);
                action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
        }
 
-       DEBUG(6,("smb_set_file_time: actime: %s " , ctime(&tvs.actime)));
-       DEBUG(6,("smb_set_file_time: modtime: %s ", ctime(&tvs.modtime)));
+       DEBUG(6,("smb_set_file_time: actime: %s " , time_to_asc(convert_timespec_to_time_t(ts[0])) ));
+       DEBUG(6,("smb_set_file_time: modtime: %s ", time_to_asc(convert_timespec_to_time_t(ts[1])) ));
 
        /*
         * Try and set the times of this file if
         * they are different from the current values.
         */
 
-       if (psbuf->st_mtime == tvs.modtime && psbuf->st_atime == tvs.actime) {
-               return NT_STATUS_OK;
+       {
+               struct timespec mts = get_mtimespec(psbuf);
+               struct timespec ats = get_atimespec(psbuf);
+               if ((timespec_compare(&ts[0], &ats) == 0) && (timespec_compare(&ts[1], &mts) == 0)) {
+                       return NT_STATUS_OK;
+               }
        }
 
        if(fsp != NULL) {
@@ -3843,15 +3845,16 @@ static NTSTATUS smb_set_file_time(connection_struct *conn,
                 * away and will set it on file close and after a write. JRA.
                 */
 
-               if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
-                       DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
-                       fsp_set_pending_modtime(fsp, tvs.modtime);
+               if (!null_timespec(ts[1])) {
+                       DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
+                               time_to_asc(convert_timespec_to_time_t(ts[1])) ));
+                       fsp_set_pending_modtime(fsp, ts[1]);
                }
 
        }
        DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
 
-       if(file_utime(conn, fname, &tvs)!=0) {
+       if(file_ntimes(conn, fname, ts)!=0) {
                return map_nt_error_from_unix(errno);
        }
        if (action != 0) {
@@ -4459,16 +4462,16 @@ static NTSTATUS smb_set_info_standard(connection_struct *conn,
                                        const char *fname,
                                        const SMB_STRUCT_STAT *psbuf)
 {
-       struct utimbuf tvs;
+       struct timespec ts[2];
 
        if (total_data < 12) {
                return NT_STATUS_INVALID_PARAMETER;
        }
 
        /* access time */
-       tvs.actime = srv_make_unix_date2(pdata+l1_fdateLastAccess);
+       ts[0] = convert_time_t_to_timespec(srv_make_unix_date2(pdata+l1_fdateLastAccess));
        /* write time */
-       tvs.modtime = srv_make_unix_date2(pdata+l1_fdateLastWrite);
+       ts[1] = convert_time_t_to_timespec(srv_make_unix_date2(pdata+l1_fdateLastWrite));
 
        DEBUG(10,("smb_set_info_standard: file %s\n",
                fname ? fname : fsp->fsp_name ));
@@ -4477,7 +4480,7 @@ static NTSTATUS smb_set_info_standard(connection_struct *conn,
                                fsp,
                                fname,
                                psbuf,
-                               tvs);
+                               ts);
 }
 
 /****************************************************************************
@@ -4492,10 +4495,10 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
                                        SMB_STRUCT_STAT *psbuf)
 {
        /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
-       time_t write_time;
-       time_t changed_time;
+       struct timespec write_time;
+       struct timespec changed_time;
        uint32 dosmode = 0;
-       struct utimbuf tvs;
+       struct timespec ts[2];
        NTSTATUS status = NT_STATUS_OK;
 
        if (total_data < 36) {
@@ -4515,19 +4518,21 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
        /* Ignore create time at offset pdata. */
 
        /* access time */
-       tvs.actime = convert_timespec_to_time_t(interpret_long_date(pdata+8));
+       ts[0] = interpret_long_date(pdata+8);
 
-       write_time = convert_timespec_to_time_t(interpret_long_date(pdata+16));
-       changed_time = convert_timespec_to_time_t(interpret_long_date(pdata+24));
+       write_time = interpret_long_date(pdata+16);
+       changed_time = interpret_long_date(pdata+24);
 
-       tvs.modtime = MIN(write_time, changed_time);
+       /* mtime */
+       ts[1] = timespec_min(&write_time, &changed_time);
 
-       if (write_time > tvs.modtime && write_time != (time_t)-1) {
-               tvs.modtime = write_time;
+       if ((timespec_compare(&write_time, &ts[1]) == 1) && !null_timespec(write_time)) {
+               ts[1] = write_time;
        }
+
        /* Prefer a defined time to an undefined one. */
-       if (null_mtime(tvs.modtime)) {
-               tvs.modtime = null_mtime(write_time) ? changed_time : write_time;
+       if (null_timespec(ts[1])) {
+               ts[1] = null_timespec(write_time) ? changed_time : write_time;
        }
 
        DEBUG(10,("smb_set_file_basic_info: file %s\n",
@@ -4537,7 +4542,7 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
                                fsp,
                                fname,
                                psbuf,
-                               tvs);
+                               ts);
 }
 
 /****************************************************************************
@@ -4751,7 +4756,7 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
                                        const char *fname,
                                        SMB_STRUCT_STAT *psbuf)
 {
-       struct utimbuf tvs;
+       struct timespec ts[2];
        uint32 raw_unixmode;
        mode_t unixmode;
        SMB_OFF_T size = 0;
@@ -4778,8 +4783,8 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
 #endif /* LARGE_SMB_OFF_T */
        }
 
-       tvs.actime = convert_timespec_to_time_t(interpret_long_date(pdata+24)); /* access_time */
-       tvs.modtime = convert_timespec_to_time_t(interpret_long_date(pdata+32)); /* modification_time */
+       ts[0] = interpret_long_date(pdata+24); /* access_time */
+       ts[1] = interpret_long_date(pdata+32); /* modification_time */
        set_owner = (uid_t)IVAL(pdata,40);
        set_grp = (gid_t)IVAL(pdata,48);
        raw_unixmode = IVAL(pdata,84);
@@ -4822,8 +4827,8 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
                /* Ensure we don't try and change anything else. */
                raw_unixmode = SMB_MODE_NO_CHANGE;
                size = get_file_size(*psbuf);
-               tvs.modtime = psbuf->st_mtime;
-               tvs.actime = psbuf->st_atime;
+               ts[0] = get_atimespec(psbuf);
+               ts[1] = get_mtimespec(psbuf);
                /* 
                 * We continue here as we might want to change the 
                 * owner uid/gid.
@@ -4902,7 +4907,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
                                fsp,
                                fname,
                                psbuf,
-                               tvs);
+                               ts);
 }
 
 /****************************************************************************
@@ -5360,9 +5365,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
 
        SSVAL(params,0,0);
 
-       if (fsp && fsp->pending_modtime) {
+       if (fsp && !null_timespec(fsp->pending_modtime)) {
                /* the pending modtime overrides the current modtime */
-               sbuf.st_mtime = fsp->pending_modtime;
+               set_mtimespec(&sbuf, fsp->pending_modtime);
        }
 
        switch (info_level) {
index c68c9f6e2fb365a0790b779c929d69ec2b2ae573..bfc30eac78a4dd96b07db3bdd66d40d99222eb14 100644 (file)
@@ -104,7 +104,7 @@ static int show_share(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
        d_printf("%-10.10s   %s   %-12s  %s",
               crec.name,procid_str_static(&crec.pid),
               crec.machine,
-              time_to_asc(&crec.start));
+              time_to_asc(crec.start));
 
        return 0;
 }
@@ -173,7 +173,7 @@ static int show_share_parseable(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
                 guest ? "" : gidtoname(ids->entries[i].gid),
                 crec.machine, 
                 guest ? "" : ids->entries[i].hostname,
-                time_to_asc(&crec.start));
+                time_to_asc(crec.start));
 
        return 0;
 }
index 4f66501511b6ab8954ac875bfe06bb2aa7ce7cfb..deba6a9523bad0aa61cefea67fbeb475baa04ce4 100644 (file)
@@ -162,7 +162,7 @@ static void print_share_mode(const struct share_mode_entry *e,
                        d_printf("NONE            ");
                }
 
-               d_printf(" %s   %s   %s",sharepath, fname, time_to_asc((time_t *)&e->time.tv_sec));
+               d_printf(" %s   %s   %s",sharepath, fname, time_to_asc((time_t)e->time.tv_sec));
        }
 }
 
@@ -207,7 +207,7 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st
        d_printf("%-10s   %s   %-12s  %s",
               crec.name,procid_str_static(&crec.pid),
               crec.machine,
-              time_to_asc(&crec.start));
+              time_to_asc(crec.start));
 
        return 0;
 }
index 9224fc176cb1362242168feb3697f00c85c6fd88..b4c4940f3fd5b817d5e7c328b0fd44ab12f543e6 100644 (file)
@@ -113,8 +113,8 @@ BOOL status_profile_dump(BOOL verbose)
        d_printf("chdir_time:                     %u\n", profile_p->syscall_chdir_time);
        d_printf("getwd_count:                    %u\n", profile_p->syscall_getwd_count);
        d_printf("getwd_time:                     %u\n", profile_p->syscall_getwd_time);
-       d_printf("utime_count:                    %u\n", profile_p->syscall_utime_count);
-       d_printf("utime_time:                     %u\n", profile_p->syscall_utime_time);
+       d_printf("ntimes_count:                   %u\n", profile_p->syscall_ntimes_count);
+       d_printf("ntimes_time:                    %u\n", profile_p->syscall_ntimes_time);
        d_printf("ftruncate_count:                %u\n", profile_p->syscall_ftruncate_count);
        d_printf("ftruncate_time:                 %u\n", profile_p->syscall_ftruncate_time);
        d_printf("fcntl_lock_count:               %u\n", profile_p->syscall_fcntl_lock_count);
index 459b679d8172b249f24429388db2447972713e23..a88e5debd0e3a9c636b4d87764d5ba409401dd15 100644 (file)
@@ -101,7 +101,7 @@ static char *mapPid2Machine (struct process_id pid)
 static char *tstring(time_t t)
 {
        static pstring buf;
-       pstrcpy(buf, time_to_asc(&t));
+       pstrcpy(buf, time_to_asc(t));
        all_string_sub(buf," ","&nbsp;",sizeof(buf));
        return buf;
 }