diff options
-rw-r--r-- | examples/VFS/skel_opaque.c | 6 | ||||
-rw-r--r-- | examples/VFS/skel_transparent.c | 6 | ||||
-rw-r--r-- | source3/client/client.c | 6 | ||||
-rw-r--r-- | source3/client/clitar.c | 2 | ||||
-rw-r--r-- | source3/client/smbctool.c | 6 | ||||
-rw-r--r-- | source3/include/smb.h | 4 | ||||
-rw-r--r-- | source3/include/smbprofile.h | 6 | ||||
-rw-r--r-- | source3/include/vfs.h | 10 | ||||
-rw-r--r-- | source3/include/vfs_macros.h | 6 | ||||
-rw-r--r-- | source3/lib/time.c | 144 | ||||
-rw-r--r-- | source3/modules/vfs_cap.c | 6 | ||||
-rw-r--r-- | source3/modules/vfs_catia.c | 8 | ||||
-rw-r--r-- | source3/modules/vfs_default.c | 33 | ||||
-rw-r--r-- | source3/modules/vfs_full_audit.c | 16 | ||||
-rw-r--r-- | source3/modules/vfs_recycle.c | 10 | ||||
-rw-r--r-- | source3/profile/profile.c | 2 | ||||
-rw-r--r-- | source3/smbd/close.c | 4 | ||||
-rw-r--r-- | source3/smbd/dosmode.c | 36 | ||||
-rw-r--r-- | source3/smbd/fileio.c | 4 | ||||
-rw-r--r-- | source3/smbd/files.c | 6 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 2 | ||||
-rw-r--r-- | source3/smbd/reply.c | 43 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 91 | ||||
-rw-r--r-- | source3/utils/net_status.c | 4 | ||||
-rw-r--r-- | source3/utils/status.c | 4 | ||||
-rw-r--r-- | source3/utils/status_profile.c | 4 | ||||
-rw-r--r-- | source3/web/statuspage.c | 2 |
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, ×)) { + 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, ×); + 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," "," ",sizeof(buf)); return buf; } |