[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-1811-g49ca690

Volker Lendecke vlendec at samba.org
Tue May 26 15:49:07 GMT 2009


The branch, master has been updated
       via  49ca690b4b22ee6e597179059c9442e94c5bd423 (commit)
      from  52f2f9449f8d53aa9181d656a4b54a007c80fa81 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 49ca690b4b22ee6e597179059c9442e94c5bd423
Author: Volker Lendecke <vl at samba.org>
Date:   Thu May 14 15:34:42 2009 +0200

    Introduce "struct stat_ex" as a replacement for SMB_STRUCT_STAT
    
    This patch introduces
    
    struct stat_ex {
            dev_t           st_ex_dev;
            ino_t           st_ex_ino;
            mode_t          st_ex_mode;
            nlink_t         st_ex_nlink;
            uid_t           st_ex_uid;
            gid_t           st_ex_gid;
            dev_t           st_ex_rdev;
            off_t           st_ex_size;
            struct timespec st_ex_atime;
            struct timespec st_ex_mtime;
            struct timespec st_ex_ctime;
            struct timespec st_ex_btime; /* birthtime */
            blksize_t       st_ex_blksize;
            blkcnt_t        st_ex_blocks;
    };
    typedef struct stat_ex SMB_STRUCT_STAT;
    
    It is really large because due to the friendly libc headers playing macro
    tricks with fields like st_ino, so I renamed them to st_ex_xxx.
    
    Why this change? To support birthtime, we already have quite a few #ifdef's at
    places where it does not really belong. With a stat struct that we control, we
    can consolidate the nanosecond timestamps and the birthtime deep in the VFS
    stat calls.
    
    At this moment it is triggered by a request to support the birthtime field for
    GPFS. GPFS does not extend the system level struct stat, but instead has a
    separate call that gets us the additional information beyond posix. Without
    being able to do that within the VFS stat calls, that support would have to be
    scattered around the main smbd code.
    
    It will very likely break all the onefs modules, but I think the changes will
    be reasonably easy to do.

-----------------------------------------------------------------------

Summary of changes:
 source3/client/client.c             |   42 ++++---
 source3/client/clitar.c             |    5 +-
 source3/include/includes.h          |   33 ++++-
 source3/include/proto.h             |   11 +--
 source3/include/smb_macros.h        |    6 +-
 source3/lib/debug.c                 |    2 +-
 source3/lib/system.c                |  225 ++++++++++++++++++++++++++++++--
 source3/lib/time.c                  |  245 -----------------------------------
 source3/lib/util.c                  |   10 +-
 source3/libsmb/clifile.c            |   28 ++--
 source3/libsmb/clirap.c             |    6 +-
 source3/libsmb/libsmb_stat.c        |   12 +-
 source3/modules/nfs4_acls.c         |   11 +-
 source3/modules/vfs_acl_tdb.c       |    4 +-
 source3/modules/vfs_acl_xattr.c     |    4 +-
 source3/modules/vfs_afsacl.c        |    6 +-
 source3/modules/vfs_commit.c        |    2 +-
 source3/modules/vfs_default.c       |   44 +++---
 source3/modules/vfs_fake_perms.c    |   20 ++--
 source3/modules/vfs_fileid.c        |    4 +-
 source3/modules/vfs_gpfs.c          |    4 +-
 source3/modules/vfs_hpuxacl.c       |    2 +-
 source3/modules/vfs_netatalk.c      |   12 +-
 source3/modules/vfs_recycle.c       |    8 +-
 source3/modules/vfs_shadow_copy2.c  |    2 +-
 source3/modules/vfs_streams_depot.c |   10 +-
 source3/modules/vfs_streams_xattr.c |   54 ++++----
 source3/modules/vfs_tsmsm.c         |   15 ++-
 source3/param/loadparm.c            |   64 +++++-----
 source3/passdb/pdb_smbpasswd.c      |    2 +-
 source3/printing/nt_printing.c      |    4 +-
 source3/printing/printfsp.c         |    2 +-
 source3/printing/printing.c         |    2 +-
 source3/registry/regfio.c           |    4 +-
 source3/smbd/close.c                |    2 +-
 source3/smbd/dir.c                  |   12 +-
 source3/smbd/dosmode.c              |   42 +++---
 source3/smbd/file_access.c          |   14 +-
 source3/smbd/fileio.c               |    2 +-
 source3/smbd/filename.c             |    2 +-
 source3/smbd/msdfs.c                |    2 +-
 source3/smbd/nttrans.c              |   28 ++--
 source3/smbd/open.c                 |   56 ++++----
 source3/smbd/posix_acls.c           |   58 ++++----
 source3/smbd/reply.c                |   67 +++++-----
 source3/smbd/service.c              |    4 +-
 source3/smbd/trans2.c               |  104 ++++++++--------
 source3/smbd/vfs.c                  |   28 ++--
 source3/torture/cmd_vfs.c           |  180 ++++++++++++++------------
 source3/utils/net_conf.c            |    2 +-
 source3/utils/net_usershare.c       |   14 +-
 source3/utils/testparm.c            |    6 +-
 source3/web/cgi.c                   |    8 +-
 53 files changed, 768 insertions(+), 768 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/client/client.c b/source3/client/client.c
index 59e5c1a..13dee60 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -3022,7 +3022,7 @@ static int cmd_getfacl(void)
 	}
 
 	d_printf("# file: %s\n", src);
-	d_printf("# owner: %u\n# group: %u\n", (unsigned int)sbuf.st_uid, (unsigned int)sbuf.st_gid);
+	d_printf("# owner: %u\n# group: %u\n", (unsigned int)sbuf.st_ex_uid, (unsigned int)sbuf.st_ex_gid);
 
 	if (num_file_acls == 0 && num_dir_acls == 0) {
 		d_printf("No acls found.\n");
@@ -3120,6 +3120,7 @@ static int cmd_stat(void)
 	fstring mode_str;
 	SMB_STRUCT_STAT sbuf;
 	struct tm *lt;
+	time_t tmp_time;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&name,NULL)) {
 		d_printf("stat file\n");
@@ -3152,30 +3153,31 @@ static int cmd_stat(void)
 	/* Print out the stat values. */
 	d_printf("File: %s\n", src);
 	d_printf("Size: %-12.0f\tBlocks: %u\t%s\n",
-		(double)sbuf.st_size,
-		(unsigned int)sbuf.st_blocks,
-		filetype_to_str(sbuf.st_mode));
+		(double)sbuf.st_ex_size,
+		(unsigned int)sbuf.st_ex_blocks,
+		filetype_to_str(sbuf.st_ex_mode));
 
 #if defined(S_ISCHR) && defined(S_ISBLK)
-	if (S_ISCHR(sbuf.st_mode) || S_ISBLK(sbuf.st_mode)) {
+	if (S_ISCHR(sbuf.st_ex_mode) || S_ISBLK(sbuf.st_ex_mode)) {
 		d_printf("Inode: %.0f\tLinks: %u\tDevice type: %u,%u\n",
-			(double)sbuf.st_ino,
-			(unsigned int)sbuf.st_nlink,
-			unix_dev_major(sbuf.st_rdev),
-			unix_dev_minor(sbuf.st_rdev));
+			(double)sbuf.st_ex_ino,
+			(unsigned int)sbuf.st_ex_nlink,
+			unix_dev_major(sbuf.st_ex_rdev),
+			unix_dev_minor(sbuf.st_ex_rdev));
 	} else
 #endif
 		d_printf("Inode: %.0f\tLinks: %u\n",
-			(double)sbuf.st_ino,
-			(unsigned int)sbuf.st_nlink);
+			(double)sbuf.st_ex_ino,
+			(unsigned int)sbuf.st_ex_nlink);
 
 	d_printf("Access: (0%03o/%s)\tUid: %u\tGid: %u\n",
-		((int)sbuf.st_mode & 0777),
-		unix_mode_to_str(mode_str, sbuf.st_mode),
-		(unsigned int)sbuf.st_uid,
-		(unsigned int)sbuf.st_gid);
+		((int)sbuf.st_ex_mode & 0777),
+		unix_mode_to_str(mode_str, sbuf.st_ex_mode),
+		(unsigned int)sbuf.st_ex_uid,
+		(unsigned int)sbuf.st_ex_gid);
 
-	lt = localtime(&sbuf.st_atime);
+	tmp_time = convert_timespec_to_time_t(sbuf.st_ex_atime);
+	lt = localtime(&tmp_time);
 	if (lt) {
 		strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
 	} else {
@@ -3183,7 +3185,8 @@ static int cmd_stat(void)
 	}
 	d_printf("Access: %s\n", mode_str);
 
-	lt = localtime(&sbuf.st_mtime);
+	tmp_time = convert_timespec_to_time_t(sbuf.st_ex_mtime);
+	lt = localtime(&tmp_time);
 	if (lt) {
 		strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
 	} else {
@@ -3191,7 +3194,8 @@ static int cmd_stat(void)
 	}
 	d_printf("Modify: %s\n", mode_str);
 
-	lt = localtime(&sbuf.st_ctime);
+	tmp_time = convert_timespec_to_time_t(sbuf.st_ex_ctime);
+	lt = localtime(&tmp_time);
 	if (lt) {
 		strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
 	} else {
@@ -3400,7 +3404,7 @@ static int cmd_newer(void)
 
 	ok = next_token_talloc(ctx, &cmd_ptr,&buf,NULL);
 	if (ok && (sys_stat(buf,&sbuf) == 0)) {
-		newer_than = sbuf.st_mtime;
+		newer_than = convert_timespec_to_time_t(sbuf.st_ex_mtime);
 		DEBUG(1,("Getting files newer than %s",
 			 time_to_asc(newer_than)));
 	} else {
diff --git a/source3/client/clitar.c b/source3/client/clitar.c
index ff71924..d973329 100644
--- a/source3/client/clitar.c
+++ b/source3/client/clitar.c
@@ -412,7 +412,7 @@ static void dotareof(int f)
 	/* Could be a pipe, in which case S_ISREG should fail,
 		* and we should write out at full size */
 	if (tp > 0) {
-		size_t towrite = S_ISREG(stbuf.st_mode) ? tp : tbufsiz;
+		size_t towrite = S_ISREG(stbuf.st_ex_mode) ? tp : tbufsiz;
 		if (sys_write(f, tarbuf, towrite) != towrite) {
 			DEBUG(0,("dotareof: sys_write fail\n"));
 		}
@@ -1793,7 +1793,8 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
 					SMB_STRUCT_STAT stbuf;
 
 					if (sys_stat(argv[Optind], &stbuf) == 0) {
-						newer_than = stbuf.st_mtime;
+						newer_than = convert_timespec_to_time_t(
+							stbuf.st_ex_mtime);
 						DEBUG(1,("Getting files newer than %s",
 							time_to_asc(newer_than)));
 						newOptind++;
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 596c772..a2f6048 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -435,13 +435,32 @@ typedef uint64_t br_off;
  * Type for stat structure.
  */
 
-#ifndef SMB_STRUCT_STAT
-#  if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STAT64) && defined(HAVE_OFF64_T)
-#    define SMB_STRUCT_STAT struct stat64
-#  else
-#    define SMB_STRUCT_STAT struct stat
-#  endif
-#endif
+struct stat_ex {
+	dev_t		st_ex_dev;
+	ino_t		st_ex_ino;
+	mode_t		st_ex_mode;
+	nlink_t		st_ex_nlink;
+	uid_t		st_ex_uid;
+	gid_t		st_ex_gid;
+	dev_t		st_ex_rdev;
+	off_t		st_ex_size;
+	struct timespec st_ex_atime;
+	struct timespec st_ex_mtime;
+	struct timespec st_ex_ctime;
+	struct timespec st_ex_btime; /* birthtime */
+	blksize_t	st_ex_blksize;
+	blkcnt_t	st_ex_blocks;
+
+	/*
+	 * Add space for VFS internal extensions. The initial user of this
+	 * would be the onefs modules, passing the snapid from the stat calls
+	 * to the file_id_create call. Maybe we'll have to expand this later,
+	 * but the core of Samba should never look at this field.
+	 */
+	uint64_t vfs_private;
+};
+
+typedef struct stat_ex SMB_STRUCT_STAT;
 
 /*
  * Type for dirent structure.
diff --git a/source3/include/proto.h b/source3/include/proto.h
index e0b0e59..c78d2c8 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1010,13 +1010,6 @@ void srv_put_dos_date2(char *buf,int offset, time_t unixdate);
 void srv_put_dos_date3(char *buf,int offset,time_t unixdate);
 void put_long_date_timespec(char *p, struct timespec ts);
 void put_long_date(char *p, time_t t);
-struct timespec get_create_timespec(const SMB_STRUCT_STAT *st,bool fake_dirs);
-struct timespec get_atimespec(const SMB_STRUCT_STAT *pst);
-void set_atimespec(SMB_STRUCT_STAT *pst, struct timespec ts);
-struct timespec get_mtimespec(const SMB_STRUCT_STAT *pst);
-void set_mtimespec(SMB_STRUCT_STAT *pst, struct timespec ts);
-struct timespec get_ctimespec(const SMB_STRUCT_STAT *pst);
-void set_ctimespec(SMB_STRUCT_STAT *pst, struct timespec ts);
 void dos_filetime_timespec(struct timespec *tsp);
 time_t make_unix_date2(const void *date_ptr, int zone_offset);
 time_t make_unix_date3(const void *date_ptr, int zone_offset);
@@ -4087,7 +4080,7 @@ bool lp_recursive_veto_delete(int );
 bool lp_dos_filemode(int );
 bool lp_dos_filetimes(int );
 bool lp_dos_filetime_resolution(int );
-bool lp_fake_dir_create_times(int );
+bool lp_fake_dir_create_times(void);
 bool lp_blocking_locks(int );
 bool lp_inherit_perms(int );
 bool lp_inherit_acls(int );
@@ -6174,7 +6167,7 @@ bool get_dir_entry(TALLOC_CTX *ctx,
 		char **pp_fname_out,
 		SMB_OFF_T *size,
 		uint32 *mode,
-		time_t *date,
+		struct timespec *date,
 		bool check_descend,
 		bool ask_sharemode);
 bool is_visible_file(connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, bool use_veto);
diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h
index 22cfaaf..7528883 100644
--- a/source3/include/smb_macros.h
+++ b/source3/include/smb_macros.h
@@ -88,9 +88,9 @@
  * stat structure is valid.
  */
 
-#define VALID_STAT(st) ((st).st_nlink != 0)  
-#define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR((st).st_mode))
-#define SET_STAT_INVALID(st) ((st).st_nlink = 0)
+#define VALID_STAT(st) ((st).st_ex_nlink != 0)
+#define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR((st).st_ex_mode))
+#define SET_STAT_INVALID(st) ((st).st_ex_nlink = 0)
 
 /* Macros to get at offsets within smb_lkrng and smb_unlkrng
    structures. We cannot define these as actual structures
diff --git a/source3/lib/debug.c b/source3/lib/debug.c
index 14aca3a..419af61 100644
--- a/source3/lib/debug.c
+++ b/source3/lib/debug.c
@@ -739,7 +739,7 @@ void check_log_size( void )
 
 	maxlog = lp_max_log_size() * 1024;
 
-	if( sys_fstat( x_fileno( dbf ), &st ) == 0 && st.st_size > maxlog ) {
+	if( sys_fstat( x_fileno( dbf ), &st ) == 0 && st.st_ex_size > maxlog ) {
 		(void)reopen_logs();
 		if( dbf && get_file_size( debugf ) > maxlog ) {
 			char *name = NULL;
diff --git a/source3/lib/system.c b/source3/lib/system.c
index 517e347..5158750 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -290,6 +290,195 @@ int sys_fcntl_long(int fd, int cmd, long arg)
 	return ret;
 }
 
+/****************************************************************************
+ Return the best approximation to a 'create time' under UNIX from a stat
+ structure.
+****************************************************************************/
+
+static time_t calc_create_time(const struct stat *st)
+{
+	time_t ret, ret1;
+
+	ret = MIN(st->st_ctime, st->st_mtime);
+	ret1 = MIN(ret, st->st_atime);
+
+	if(ret1 != (time_t)0) {
+		return ret1;
+	}
+
+	/*
+	 * One of ctime, mtime or atime was zero (probably atime).
+	 * Just return MIN(ctime, mtime).
+	 */
+	return ret;
+}
+
+/****************************************************************************
+ Return the 'create time' from a stat struct if it exists (birthtime) or else
+ use the best approximation.
+****************************************************************************/
+
+static struct timespec get_create_timespec(const struct stat *pst)
+{
+	struct timespec ret;
+
+	if (S_ISDIR(pst->st_mode) && lp_fake_dir_create_times()) {
+		ret.tv_sec = 315493200L;          /* 1/1/1980 */
+		ret.tv_nsec = 0;
+		return ret;
+	}
+
+#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC)
+	ret = pst->st_birthtimespec;
+#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC)
+	ret.tv_sec = pst->st_birthtime;
+	ret.tv_nsec = pst->st_birthtimenspec;
+#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
+	ret.tv_sec = pst->st_birthtime;
+	ret.tv_nsec = 0;
+#else
+	ret.tv_sec = calc_create_time(pst);
+	ret.tv_nsec = 0;
+#endif
+
+	/* Deal with systems that don't initialize birthtime correctly.
+	 * Pointed out by SATOH Fumiyasu <fumiyas at osstech.jp>.
+	 */
+	if (null_timespec(ret)) {
+		ret.tv_sec = calc_create_time(pst);
+		ret.tv_nsec = 0;
+	}
+	return ret;
+}
+
+/****************************************************************************
+ Get/Set all the possible time fields from a stat struct as a timespec.
+****************************************************************************/
+
+static struct timespec get_atimespec(const struct stat *pst)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+	struct timespec ret;
+
+	/* Old system - no ns timestamp. */
+	ret.tv_sec = pst->st_atime;
+	ret.tv_nsec = 0;
+	return ret;
+#else
+#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+	return pst->st_atim;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
+	struct timespec ret;
+	ret.tv_sec = pst->st_atime;
+	ret.tv_nsec = pst->st_atimensec;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
+	struct timespec ret;
+	ret.tv_sec = pst->st_atime;
+	ret.tv_nsec = pst->st_atime_n;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
+	struct timespec ret;
+	ret.tv_sec = pst->st_atime;
+	ret.tv_nsec = pst->st_uatime * 1000;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
+	return pst->st_atimespec;
+#else
+#error	CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
+#endif
+#endif
+}
+
+static struct timespec get_mtimespec(const struct stat *pst)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+	struct timespec ret;
+
+	/* Old system - no ns timestamp. */
+	ret.tv_sec = pst->st_mtime;
+	ret.tv_nsec = 0;
+	return ret;
+#else
+#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+	return pst->st_mtim;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
+	struct timespec ret;
+	ret.tv_sec = pst->st_mtime;
+	ret.tv_nsec = pst->st_mtimensec;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
+	struct timespec ret;
+	ret.tv_sec = pst->st_mtime;
+	ret.tv_nsec = pst->st_mtime_n;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
+	struct timespec ret;
+	ret.tv_sec = pst->st_mtime;
+	ret.tv_nsec = pst->st_umtime * 1000;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
+	return pst->st_mtimespec;
+#else
+#error	CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
+#endif
+#endif
+}
+
+static struct timespec get_ctimespec(const struct stat *pst)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+	struct timespec ret;
+
+	/* Old system - no ns timestamp. */
+	ret.tv_sec = pst->st_ctime;
+	ret.tv_nsec = 0;
+	return ret;
+#else
+#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+	return pst->st_ctim;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
+	struct timespec ret;
+	ret.tv_sec = pst->st_ctime;
+	ret.tv_nsec = pst->st_ctimensec;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
+	struct timespec ret;
+	ret.tv_sec = pst->st_ctime;
+	ret.tv_nsec = pst->st_ctime_n;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
+	struct timespec ret;
+	ret.tv_sec = pst->st_ctime;
+	ret.tv_nsec = pst->st_uctime * 1000;
+	return ret;
+#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
+	return pst->st_ctimespec;
+#else
+#error	CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
+#endif
+#endif
+}
+
+static void init_stat_ex_from_stat (struct stat_ex *dst,
+				    const struct stat *src)
+{
+	dst->st_ex_dev = src->st_dev;
+	dst->st_ex_ino = src->st_ino;
+	dst->st_ex_mode = src->st_mode;
+	dst->st_ex_nlink = src->st_nlink;
+	dst->st_ex_uid = src->st_uid;
+	dst->st_ex_gid = src->st_gid;
+	dst->st_ex_rdev = src->st_rdev;
+	dst->st_ex_size = src->st_size;
+	dst->st_ex_atime = get_atimespec(src);
+	dst->st_ex_mtime = get_mtimespec(src);
+	dst->st_ex_ctime = get_ctimespec(src);
+	dst->st_ex_btime = get_create_timespec(src);
+	dst->st_ex_blksize = src->st_blksize;
+	dst->st_ex_blocks = src->st_blocks;
+}
+
 /*******************************************************************
 A stat() wrapper that will deal with 64 bit filesizes.
 ********************************************************************/
@@ -300,10 +489,16 @@ int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
 	ret = stat64(fname, sbuf);
 #else
-	ret = stat(fname, sbuf);
+	struct stat statbuf;
+	ret = stat(fname, &statbuf);
 #endif
-	/* we always want directories to appear zero size */
-	if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+	if (ret == 0) {
+		/* we always want directories to appear zero size */
+		if (S_ISDIR(statbuf.st_mode)) {
+			statbuf.st_size = 0;
+		}
+		init_stat_ex_from_stat(sbuf, &statbuf);
+	}
 	return ret;
 }
 
@@ -317,10 +512,16 @@ int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
 	ret = fstat64(fd, sbuf);
 #else
-	ret = fstat(fd, sbuf);
+	struct stat statbuf;
+	ret = fstat(fd, &statbuf);
 #endif
-	/* we always want directories to appear zero size */
-	if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+	if (ret == 0) {
+		/* we always want directories to appear zero size */
+		if (S_ISDIR(statbuf.st_mode)) {
+			statbuf.st_size = 0;
+		}
+		init_stat_ex_from_stat(sbuf, &statbuf);
+	}
 	return ret;
 }
 
@@ -334,10 +535,16 @@ int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
 	ret = lstat64(fname, sbuf);
 #else
-	ret = lstat(fname, sbuf);
+	struct stat statbuf;
+	ret = lstat(fname, &statbuf);
 #endif
-	/* we always want directories to appear zero size */
-	if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+	if (ret == 0) {
+		/* we always want directories to appear zero size */
+		if (S_ISDIR(statbuf.st_mode)) {
+			statbuf.st_size = 0;
+		}
+		init_stat_ex_from_stat(sbuf, &statbuf);
+	}
 	return ret;
 }
 
diff --git a/source3/lib/time.c b/source3/lib/time.c
index 611debe..a2e615a 100644
--- a/source3/lib/time.c
+++ b/source3/lib/time.c
@@ -322,251 +322,6 @@ void put_long_date(char *p, time_t t)
 	put_long_date_timespec(p, ts);
 }
 
-/****************************************************************************
- Return the best approximation to a 'create time' under UNIX from a stat


-- 
Samba Shared Repository


More information about the samba-cvs mailing list