The branch, master has been updated
       via  8aaa73e5e90 vfs_fruit: Call fruit_fstatat() from fruit_[l]stat()
       via  720193220bc vfs_fruit: Implement fstatat
       via  01a3c14a083 lib: Add adouble_buf_parse()
       via  91a75272058 vfs_fruit: Use all_zero() to check for an all-0 buffer
       via  b8ce454a69e vfs_fruit: Fix signed/unsigned comparison warnings
       via  edf7009f0d5 vfs_fruit: Modernize a DEBUG
       via  572e5372da8 lib: Simplify data definitions
       via  9f1dd0bbfa6 lib: Avoid a talloc_zero in afpinfo_new()
       via  c4d60b712bf vfs_fruit: Make struct allocation in 
fruit_freaddir_attr() more common
       via  c45b78d5849 lib: Fix typos
       via  e1059e7baa5 lib: Slightly simplify ad_read_rsrc_adouble()
       via  c5a070a9b06 vfs_fruit: Slightly simplify 
readdir_attr_meta_finderi_stream()
      from  708ae38a76a mdssvc: call mangle_reset_cache()

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


- Log -----------------------------------------------------------------
commit 8aaa73e5e90ce8ae82d6c88a1ac4d8b77df44d31
Author: Volker Lendecke <[email protected]>
Date:   Thu Oct 2 21:56:59 2025 +0200

    vfs_fruit: Call fruit_fstatat() from fruit_[l]stat()
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    
    Autobuild-User(master): Volker Lendecke <[email protected]>
    Autobuild-Date(master): Wed Oct  8 09:02:25 UTC 2025 on atb-devel-224

commit 720193220bc2bb48ae40ea0a19a4dab63d87ac19
Author: Volker Lendecke <[email protected]>
Date:   Thu Oct 2 12:45:18 2025 +0200

    vfs_fruit: Implement fstatat
    
    This violates the abstraction in adouble.[ch], but passing "dirfsp"
    and "relname" through ad_get() & friends would have been a more churn,
    and with this violation of abstraction we only do fgetxattr once where
    with a separate update_btime we do it twice. So in theory it should be
    more efficient.
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 01a3c14a0837d3f45ad5603740c26ddf8265a292
Author: Volker Lendecke <[email protected]>
Date:   Thu Oct 2 10:38:24 2025 +0200

    lib: Add adouble_buf_parse()
    
    Simplified version of ad_get that takes a buffer and does basic parsing of 
an
    AppleDouble file format. The entries are represented as DATA_BLOBs directly
    pointing at "buf" to avoid offset calculations in users of this.
    
    Yes, this is a duplication of logic, but it makes the next patch
    possible. Future patches could use this in ad_unpack()
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 91a75272058186f81896f2ecf508500094115db6
Author: Volker Lendecke <[email protected]>
Date:   Wed Oct 1 17:23:16 2025 +0200

    vfs_fruit: Use all_zero() to check for an all-0 buffer
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit b8ce454a69e0ace72d77dc1a1ecc690c08c7debb
Author: Volker Lendecke <[email protected]>
Date:   Tue Sep 30 12:24:51 2025 +0200

    vfs_fruit: Fix signed/unsigned comparison warnings
    
    It also factors out the tevent_req_post() in pread/pwrite_send()
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit edf7009f0d591b132e7ac5eca878c8cc6077cb56
Author: Volker Lendecke <[email protected]>
Date:   Tue Sep 30 11:35:56 2025 +0200

    vfs_fruit: Modernize a DEBUG
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 572e5372da8181cdb35bfbd8c56bad2b67d0da2f
Author: Volker Lendecke <[email protected]>
Date:   Mon Sep 29 21:40:58 2025 +0200

    lib: Simplify data definitions
    
    C calculates the array size itself
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 9f1dd0bbfa685e7c8376fba9ecab6cf0880efd4b
Author: Volker Lendecke <[email protected]>
Date:   Mon Sep 29 19:25:41 2025 +0200

    lib: Avoid a talloc_zero in afpinfo_new()
    
    Use a struct assignment.
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit c4d60b712bfa32f9cdad3cf570a4862461342e12
Author: Volker Lendecke <[email protected]>
Date:   Mon Sep 29 14:33:18 2025 +0200

    vfs_fruit: Make struct allocation in fruit_freaddir_attr() more common
    
    Just assign the output buffer on success
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit c45b78d58497dd5dec38eb5aee3e3d2727c899ce
Author: Volker Lendecke <[email protected]>
Date:   Sat Sep 27 09:59:33 2025 +0200

    lib: Fix typos
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit e1059e7baa569952a4de68b0d6b5ae48b8d82f52
Author: Volker Lendecke <[email protected]>
Date:   Thu Oct 2 11:46:40 2025 +0200

    lib: Slightly simplify ad_read_rsrc_adouble()
    
    We have the MIN() macro for this
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit c5a070a9b064370f78cb91a2f422da1feefef215
Author: Volker Lendecke <[email protected]>
Date:   Mon Sep 29 13:38:55 2025 +0200

    vfs_fruit: Slightly simplify readdir_attr_meta_finderi_stream()
    
    "&buf[0]" is equivalent to just "buf" in this case
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

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

Summary of changes:
 source3/lib/adouble.c       |  83 ++++++-
 source3/lib/adouble.h       |  10 +
 source3/modules/vfs_fruit.c | 572 ++++++++++++++++++++++----------------------
 3 files changed, 366 insertions(+), 299 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c
index bc48c9d8e2e..0cea2ba23fe 100644
--- a/source3/lib/adouble.c
+++ b/source3/lib/adouble.c
@@ -183,7 +183,7 @@ struct ad_entry_order {
 
 /* Netatalk AppleDouble metadata xattr */
 static const
-struct ad_entry_order entry_order_meta_xattr[ADEID_NUM_XATTR + 1] = {
+struct ad_entry_order entry_order_meta_xattr[] = {
        {ADEID_FINDERI,    ADEDOFF_FINDERI_XATTR,    ADEDLEN_FINDERI},
        {ADEID_COMMENT,    ADEDOFF_COMMENT_XATTR,    0},
        {ADEID_FILEDATESI, ADEDOFF_FILEDATESI_XATTR, ADEDLEN_FILEDATESI},
@@ -197,7 +197,7 @@ struct ad_entry_order 
entry_order_meta_xattr[ADEID_NUM_XATTR + 1] = {
 
 /* AppleDouble resource fork file (the ones prefixed by "._") */
 static const
-struct ad_entry_order entry_order_dot_und[ADEID_NUM_DOT_UND + 1] = {
+struct ad_entry_order entry_order_dot_und[] = {
        {ADEID_FINDERI,    ADEDOFF_FINDERI_DOT_UND,  ADEDLEN_FINDERI},
        {ADEID_RFORK,      ADEDOFF_RFORK_DOT_UND,    0},
        {0, 0, 0}
@@ -271,8 +271,8 @@ size_t ad_setentryoff(struct adouble *ad, int eid, size_t 
off)
 
 /*
  * All entries besides FinderInfo and resource fork must fit into the
- * buffer. FinderInfo is special as it may be larger then the default 32 bytes
- * if it contains marshalled xattrs, which we will fixup that in
+ * buffer. FinderInfo is special as it may be larger than the default 32 bytes
+ * if it contains marshalled xattrs, which we will fix up in
  * ad_convert(). The first 32 bytes however must also be part of the buffer.
  *
  * The resource fork is never accessed directly by the ad_data buf.
@@ -2369,9 +2369,7 @@ static ssize_t ad_read_rsrc_adouble(vfs_handle_struct 
*handle,
        }
 
        to_read = ad->ad_fsp->fsp_name->st.st_ex_size;
-       if (to_read > AD_XATTR_MAX_HDR_SIZE) {
-               to_read = AD_XATTR_MAX_HDR_SIZE;
-       }
+       to_read = MIN(to_read, AD_XATTR_MAX_HDR_SIZE);
 
        len = SMB_VFS_NEXT_PREAD(handle,
                                 ad->ad_fsp,
@@ -2808,13 +2806,15 @@ struct smb_filename *adouble_name(TALLOC_CTX *mem_ctx,
  **/
 AfpInfo *afpinfo_new(TALLOC_CTX *ctx)
 {
-       AfpInfo *ai = talloc_zero(ctx, AfpInfo);
+       AfpInfo *ai = talloc(ctx, AfpInfo);
        if (ai == NULL) {
                return NULL;
        }
-       ai->afpi_Signature = AFP_Signature;
-       ai->afpi_Version = AFP_Version;
-       ai->afpi_BackupTime = AD_DATE_START;
+       *ai = (AfpInfo){
+               .afpi_Signature = AFP_Signature,
+               .afpi_Version = AFP_Version,
+               .afpi_BackupTime = AD_DATE_START,
+       };
        return ai;
 }
 
@@ -2869,3 +2869,64 @@ AfpInfo *afpinfo_unpack(TALLOC_CTX *ctx, const void 
*data, bool validate)
 
        return ai;
 }
+
+bool adouble_buf_parse(const uint8_t *buf,
+                      size_t buflen,
+                      struct adouble_buf *ad)
+{
+       size_t i, nentries;
+
+       if (buflen < AD_HEADER_LEN) {
+               return false;
+       }
+
+       *ad = (struct adouble_buf){
+               .magic = PULL_BE_U32(buf, ADEDOFF_MAGIC),
+               .version = PULL_BE_U32(buf, ADEDOFF_VERSION),
+       };
+
+       if ((ad->magic != AD_MAGIC) || (ad->version != AD_VERSION)) {
+               return false;
+       }
+
+       nentries = PULL_BE_U16(buf, ADEDOFF_NENTRIES);
+
+       /*
+        * no overflow, nentries is just 16 bits
+        */
+
+       if ((AD_HEADER_LEN + (AD_ENTRY_LEN * (size_t)nentries)) > buflen) {
+               return false;
+       }
+
+       for (i = 0; i < nentries; i++) {
+               size_t eoff = AD_HEADER_LEN + i * AD_ENTRY_LEN;
+               uint32_t id = get_eid(PULL_BE_U32(buf, eoff));
+               uint32_t off = PULL_BE_U32(buf, eoff + 4);
+               uint32_t len = PULL_BE_U32(buf, eoff + 8);
+               bool ok;
+
+               if ((id == 0) || (id >= ADEID_MAX)) {
+                       return false;
+               }
+
+               ok = ad_entry_check_size(id, buflen, off, len);
+               if (!ok) {
+                       return false;
+               }
+
+               if (ad->entries[id].data != NULL) {
+                       /*
+                        * Duplicate id
+                        */
+                       return false;
+               }
+
+               ad->entries[i] = (DATA_BLOB){
+                       .data = discard_const_p(uint8_t, buf) + off,
+                       .length = len,
+               };
+       }
+
+       return true;
+}
diff --git a/source3/lib/adouble.h b/source3/lib/adouble.h
index 3879b79fed1..8fd4b7e69b6 100644
--- a/source3/lib/adouble.h
+++ b/source3/lib/adouble.h
@@ -191,4 +191,14 @@ AfpInfo *afpinfo_new(TALLOC_CTX *ctx);
 ssize_t afpinfo_pack(const AfpInfo *ai, char *buf);
 AfpInfo *afpinfo_unpack(TALLOC_CTX *ctx, const void *data, bool validate);
 
+struct adouble_buf {
+       uint32_t magic;
+       uint32_t version;
+       DATA_BLOB entries[ADEID_MAX];
+};
+
+bool adouble_buf_parse(const uint8_t *buf,
+                      size_t buflen,
+                      struct adouble_buf *dst);
+
 #endif
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index b274274d46c..4ef7a68a30f 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -470,8 +470,6 @@ static bool del_fruit_stream(TALLOC_CTX *mem_ctx, unsigned 
int *num_streams,
 
 static bool ad_empty_finderinfo(const struct adouble *ad)
 {
-       int cmp;
-       char emptybuf[ADEDLEN_FINDERI] = {0};
        char *fi = NULL;
 
        fi = ad_get_entry(ad, ADEID_FINDERI);
@@ -479,59 +477,12 @@ static bool ad_empty_finderinfo(const struct adouble *ad)
                DBG_ERR("Missing FinderInfo in struct adouble [%p]\n", ad);
                return false;
        }
-
-       cmp = memcmp(emptybuf, fi, ADEDLEN_FINDERI);
-       return (cmp == 0);
+       return all_zero((const uint8_t *)fi, ADEDLEN_FINDERI);
 }
 
 static bool ai_empty_finderinfo(const AfpInfo *ai)
 {
-       int cmp;
-       char emptybuf[ADEDLEN_FINDERI] = {0};
-
-       cmp = memcmp(emptybuf, &ai->afpi_FinderInfo[0], ADEDLEN_FINDERI);
-       return (cmp == 0);
-}
-
-/**
- * Update btime with btime from Netatalk
- **/
-static void update_btime(vfs_handle_struct *handle,
-                        struct smb_filename *smb_fname)
-{
-       uint32_t t;
-       struct timespec creation_time = {0};
-       struct adouble *ad;
-       struct fruit_config_data *config = NULL;
-
-       SMB_VFS_HANDLE_GET_DATA(handle, config, struct fruit_config_data,
-                               return);
-
-       switch (config->meta) {
-       case FRUIT_META_STREAM:
-               return;
-       case FRUIT_META_NETATALK:
-               /* Handled below */
-               break;
-       default:
-               DBG_ERR("Unexpected meta config [%d]\n", config->meta);
-               return;
-       }
-
-       ad = ad_get_meta_fsp(talloc_tos(), handle, smb_fname);
-       if (ad == NULL) {
-               return;
-       }
-       if (ad_getdate(ad, AD_DATE_UNIX | AD_DATE_CREATE, &t) != 0) {
-               TALLOC_FREE(ad);
-               return;
-       }
-       TALLOC_FREE(ad);
-
-       creation_time.tv_sec = convert_uint32_t_to_time_t(t);
-       update_stat_ex_create_time(&smb_fname->st, creation_time);
-
-       return;
+       return all_zero(&ai->afpi_FinderInfo[0], ADEDLEN_FINDERI);
 }
 
 /**
@@ -1001,7 +952,7 @@ static bool readdir_attr_meta_finderi_stream(
                return false;
        }
 
-       nread = SMB_VFS_PREAD(fsp, &buf[0], AFP_INFO_SIZE, 0);
+       nread = SMB_VFS_PREAD(fsp, buf, sizeof(buf), 0);
        if (nread != AFP_INFO_SIZE) {
                DBG_ERR("short read [%s] [%zd/%d]\n",
                        smb_fname_str_dbg(stream_name), nread, AFP_INFO_SIZE);
@@ -2371,7 +2322,7 @@ static ssize_t fruit_pread_meta_stream(vfs_handle_struct 
*handle,
        }
 
        nread = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
-       if (nread == -1 || nread == n) {
+       if (nread == -1 || ((size_t)nread == n)) {
                return nread;
        }
 
@@ -2646,14 +2597,13 @@ static struct tevent_req *fruit_pread_send(
 
        if (fruit_must_handle_aio_stream(fio)) {
                state->nread = SMB_VFS_PREAD(fsp, data, n, offset);
-               if (state->nread != n) {
-                       if (state->nread != -1) {
-                               errno = EIO;
-                       }
+               if (state->nread == -1) {
                        tevent_req_error(req, errno);
-                       return tevent_req_post(req, ev);
+               } else if ((size_t)state->nread != n) {
+                       tevent_req_error(req, EIO);
+               } else {
+                       tevent_req_done(req);
                }
-               tevent_req_done(req);
                return tevent_req_post(req, ev);
        }
 
@@ -2946,7 +2896,7 @@ static ssize_t fruit_pwrite_meta(vfs_handle_struct 
*handle,
                return -1;
        }
 
-       if (nwritten != to_write) {
+       if ((size_t)nwritten != to_write) {
                return -1;
        }
 
@@ -2994,7 +2944,7 @@ static ssize_t 
fruit_pwrite_rsrc_adouble(vfs_handle_struct *handle,
 
        nwritten = SMB_VFS_NEXT_PWRITE(handle, fio->ad_fsp, data, n,
                                       offset + ad_getentryoff(ad, 
ADEID_RFORK));
-       if (nwritten != n) {
+       if ((nwritten == -1) || ((size_t)nwritten != n)) {
                DBG_ERR("Short write on [%s] [%zd/%zd]\n",
                        fsp_str_dbg(fio->ad_fsp), nwritten, n);
                TALLOC_FREE(ad);
@@ -3100,14 +3050,13 @@ static struct tevent_req *fruit_pwrite_send(
 
        if (fruit_must_handle_aio_stream(fio)) {
                state->nwritten = SMB_VFS_PWRITE(fsp, data, n, offset);
-               if (state->nwritten != n) {
-                       if (state->nwritten != -1) {
-                               errno = EIO;
-                       }
+               if (state->nwritten == -1) {
                        tevent_req_error(req, errno);
-                       return tevent_req_post(req, ev);
+               } else if ((size_t)state->nwritten != n) {
+                       tevent_req_error(req, EIO);
+               } else {
+                       tevent_req_done(req);
                }
-               tevent_req_done(req);
                return tevent_req_post(req, ev);
        }
 
@@ -3254,300 +3203,346 @@ static int fruit_fsync_recv(struct tevent_req *req,
        return retval;
 }
 
-/**
- * Helper to stat/lstat the base file of an smb_fname.
- */
-static int fruit_stat_base(vfs_handle_struct *handle,
-                          struct smb_filename *smb_fname,
-                          bool follow_links)
+static int fruit_fstatat_meta(struct vfs_handle_struct *handle,
+                             const struct fruit_config_data *config,
+                             const struct files_struct *dirfsp,
+                             const struct smb_filename *_smb_relname,
+                             SMB_STRUCT_STAT *sbuf,
+                             int flags)
 {
-       char *tmp_stream_name;
-       int rc;
+       struct adouble_buf ad = {};
+       struct smb_filename *smb_relname = NULL;
+       uint8_t ad_data[402];
+       NTSTATUS status;
+       int ret = -1;
+       ssize_t ealen;
+       ino_t ino;
+       bool ok;
 
-       tmp_stream_name = smb_fname->stream_name;
-       smb_fname->stream_name = NULL;
-       if (follow_links) {
-               rc = SMB_VFS_NEXT_STAT(handle, smb_fname);
-       } else {
-               rc = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
-       }
-       smb_fname->stream_name = tmp_stream_name;
+       {
+               /* Populate the stat struct with info from the base file. */
 
-       DBG_DEBUG("[%s] dev [%ju] ino [%ju]\n",
-                 smb_fname->base_name,
-                 (uintmax_t)smb_fname->st.st_ex_dev,
-                 (uintmax_t)smb_fname->st.st_ex_ino);
-       return rc;
-}
+               struct smb_filename base_name = *smb_relname;
+               base_name.stream_name = NULL;
 
-static int fruit_stat_meta_stream(vfs_handle_struct *handle,
-                                 struct smb_filename *smb_fname,
-                                 bool follow_links)
-{
-       int ret;
-       ino_t ino;
+               ret = SMB_VFS_NEXT_FSTATAT(
+                       handle, dirfsp, &base_name, sbuf, flags);
+       }
 
-       ret = fruit_stat_base(handle, smb_fname, false);
-       if (ret != 0) {
-               return -1;
+       if (ret == -1) {
+               goto fail;
        }
 
-       ino = hash_inode(&smb_fname->st, smb_fname->stream_name);
+       ino = hash_inode(sbuf, smb_relname->stream_name);
 
-       if (follow_links) {
-               ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
-       } else {
-               ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
+       if (config->meta == FRUIT_META_STREAM) {
+               ret = SMB_VFS_NEXT_FSTATAT(
+                       handle, dirfsp, smb_relname, sbuf, flags);
+               if (ret == -1) {
+                       goto fail;
+               }
+               sbuf->st_ex_ino = ino;
+               goto done;
        }
 
-       smb_fname->st.st_ex_ino = ino;
+       if (config->meta != FRUIT_META_NETATALK) {
+               DBG_ERR("Unexpected meta config [%d]\n", config->meta);
+               errno = EINVAL;
+               goto fail;
+       }
 
-       return ret;
-}
+       sbuf->st_ex_ino = ino;
+       sbuf->st_ex_size = AFP_INFO_SIZE;
 
-static int fruit_stat_meta_netatalk(vfs_handle_struct *handle,
-                                   struct smb_filename *smb_fname,
-                                   bool follow_links)
-{
-       struct adouble *ad = NULL;
+       /*
+        * FRUIT_META_NETATALK
+        */
 
-       /* Populate the stat struct with info from the base file. */
-       if (fruit_stat_base(handle, smb_fname, follow_links) == -1) {
-               return -1;
+       smb_relname = cp_smb_filename_nostream(talloc_tos(), _smb_relname);
+       if (smb_relname == NULL) {
+               errno = ENOMEM;
+               goto fail;
        }
 
-       ad = ad_get_meta_fsp(talloc_tos(), handle, smb_fname);
-       if (ad == NULL) {
-               DBG_INFO("fruit_stat_meta %s: %s\n",
-                        smb_fname_str_dbg(smb_fname), strerror(errno));
+       if (flags & AT_SYMLINK_NOFOLLOW) {
+               status = openat_pathref_fsp_lcomp(
+                       discard_const_p(struct files_struct, dirfsp),
+                       smb_relname,
+                       0);
+       } else {
+               status = openat_pathref_fsp(dirfsp, smb_relname);
+       }
+       if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
                errno = ENOENT;
-               return -1;
+               goto fail;
        }
-       TALLOC_FREE(ad);
 
-       smb_fname->st.st_ex_size = AFP_INFO_SIZE;
-       smb_fname->st.st_ex_ino = hash_inode(&smb_fname->st,
-                                             smb_fname->stream_name);
-       return 0;
-}
+       ealen = SMB_VFS_FGETXATTR(
+               smb_relname->fsp, AFPINFO_EA_NETATALK, ad_data,
+               sizeof(ad_data));
+       if (ealen == -1) {
+               if (errno == ENOATTR) {
+                       errno = ENOENT;
+               }
+               goto fail;
+       }
 
-static int fruit_stat_meta(vfs_handle_struct *handle,
-                          struct smb_filename *smb_fname,
-                          bool follow_links)
-{
-       struct fruit_config_data *config = NULL;
-       int ret;
+       ok = adouble_buf_parse(ad_data, ealen, &ad);
+       if (!ok) {
+               errno = EIO;
+               goto fail;
+       }
 
-       SMB_VFS_HANDLE_GET_DATA(handle, config,
-                               struct fruit_config_data, return -1);
+       if (ad.entries[ADEID_FILEDATESI].data != NULL) {
+               /*
+                * Update btime
+                */
+               struct timespec btime = {};
+               uint32_t ad_btime;
 
-       switch (config->meta) {
-       case FRUIT_META_STREAM:
-               ret = fruit_stat_meta_stream(handle, smb_fname, follow_links);
-               break;
+               memcpy(&ad_btime,
+                      ad.entries[ADEID_FILEDATESI].data,
+                      sizeof(ad_btime));
+               ad_btime = AD_DATE_TO_UNIX(ad_btime);
+               btime.tv_sec = convert_uint32_t_to_time_t(ad_btime);
+               update_stat_ex_create_time(sbuf, btime);
+       }
 
-       case FRUIT_META_NETATALK:
-               ret = fruit_stat_meta_netatalk(handle, smb_fname, follow_links);
-               break;
+done:
+       TALLOC_FREE(smb_relname);
+       return 0;
 
-       default:
-               DBG_ERR("Unexpected meta config [%d]\n", config->meta);
-               return -1;
+fail:
+       {
+               int err = errno;
+               TALLOC_FREE(smb_relname);
+               errno = err;
        }
-
-       return ret;
+       return -1;
 }
 
-static int fruit_stat_rsrc_netatalk(vfs_handle_struct *handle,


-- 
Samba Shared Repository

Reply via email to