summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/VFS/skel_opaque.c6
-rw-r--r--examples/VFS/skel_transparent.c6
-rw-r--r--source3/client/client.c6
-rw-r--r--source3/client/clitar.c2
-rw-r--r--source3/client/smbctool.c6
-rw-r--r--source3/include/smb.h4
-rw-r--r--source3/include/smbprofile.h6
-rw-r--r--source3/include/vfs.h10
-rw-r--r--source3/include/vfs_macros.h6
-rw-r--r--source3/lib/time.c144
-rw-r--r--source3/modules/vfs_cap.c6
-rw-r--r--source3/modules/vfs_catia.c8
-rw-r--r--source3/modules/vfs_default.c33
-rw-r--r--source3/modules/vfs_full_audit.c16
-rw-r--r--source3/modules/vfs_recycle.c10
-rw-r--r--source3/profile/profile.c2
-rw-r--r--source3/smbd/close.c4
-rw-r--r--source3/smbd/dosmode.c36
-rw-r--r--source3/smbd/fileio.c4
-rw-r--r--source3/smbd/files.c6
-rw-r--r--source3/smbd/nttrans.c2
-rw-r--r--source3/smbd/reply.c43
-rw-r--r--source3/smbd/trans2.c91
-rw-r--r--source3/utils/net_status.c4
-rw-r--r--source3/utils/status.c4
-rw-r--r--source3/utils/status_profile.c4
-rw-r--r--source3/web/statuspage.c2
27 files changed, 294 insertions, 177 deletions
diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 096068da14..18ad5eb517 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -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},
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index 2a379cd6d8..b967a337eb 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -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},
diff --git a/source3/client/client.c b/source3/client/client.c
index a7bb56ba88..605beb2e06 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -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;
}
diff --git a/source3/client/clitar.c b/source3/client/clitar.c
index f228db1199..c0748799b2 100644
--- a/source3/client/clitar.c
+++ b/source3/client/clitar.c
@@ -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 {
diff --git a/source3/client/smbctool.c b/source3/client/smbctool.c
index b7042f99cb..29466108c0 100644
--- a/source3/client/smbctool.c
+++ b/source3/client/smbctool.c
@@ -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;
}
diff --git a/source3/include/smb.h b/source3/include/smb.h
index cea7638d79..1e31d8545d 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -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;
diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h
index fa7c6e4a5a..cc501739c1 100644
--- a/source3/include/smbprofile.h
+++ b/source3/include/smbprofile.h
@@ -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)
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 4c2b559bea..7bcd6cdf2c 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -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;
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index f50da3a02b..f4a289716b 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -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)))
@@ -182,7 +182,7 @@
#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)))
@@ -298,7 +298,7 @@
#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)))
diff --git a/source3/lib/time.c b/source3/lib/time.c
index 3abe233c4f..e98f8232ab 100644
--- a/source3/lib/time.c
+++ b/source3/lib/time.c
@@ -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
@@ -38,17 +39,19 @@
#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;
}
-
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index c254ba0ed9..d495ed5d14 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -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},
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 478dab6cbe..fe1ce830f7 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -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},
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index c0b80e1775..f482a3b1f3 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -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},
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 6036e49fc1..e609ae1cd1 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -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;
}
diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c
index b417b9cbff..240931fa78 100644
--- a/source3/modules/vfs_recycle.c
+++ b/source3/modules/vfs_recycle.c
@@ -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)));
}
}
diff --git a/source3/profile/profile.c b/source3/profile/profile.c
index 30b0649254..686d130b56 100644
--- a/source3/profile/profile.c
+++ b/source3/profile/profile.c
@@ -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 */
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 50111f62bb..1c9f6ea8c4 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -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);
}
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index ad79bbacdd..71d4fa179d 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -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;
+}
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index e0945be889..65238c0e9e 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -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();
}
}
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 0706548334..062bebd58e 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -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;
}
}
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 968c536caf..eedc3cfba4 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -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);
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 25c2aaa4dc..df560390c9 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -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);
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 33618360f1..41fd2c5102 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -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) {
diff --git a/source3/utils/net_status.c b/source3/utils/net_status.c
index c68c9f6e2f..bfc30eac78 100644
--- a/source3/utils/net_status.c
+++ b/source3/utils/net_status.c
@@ -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;
}
diff --git a/source3/utils/status.c b/source3/utils/status.c
index 4f66501511..deba6a9523 100644
--- a/source3/utils/status.c
+++ b/source3/utils/status.c
@@ -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;
}
diff --git a/source3/utils/status_profile.c b/source3/utils/status_profile.c
index 9224fc176c..b4c4940f3f 100644
--- a/source3/utils/status_profile.c
+++ b/source3/utils/status_profile.c
@@ -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);
diff --git a/source3/web/statuspage.c b/source3/web/statuspage.c
index 459b679d81..a88e5debd0 100644
--- a/source3/web/statuspage.c
+++ b/source3/web/statuspage.c
@@ -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;
}