]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:libsmb: Return a 'struct stat' buffer for SMBC_getatr()
authorAndreas Schneider <asn@samba.org>
Mon, 25 Nov 2019 10:09:52 +0000 (11:09 +0100)
committerKarolin Seeger <kseeger@samba.org>
Tue, 14 Jan 2020 08:30:24 +0000 (08:30 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14101

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 0fe9dc5219beaf605da9c7922053f7324507b50e)

source3/include/libsmb_internal.h
source3/libsmb/libsmb_dir.c
source3/libsmb/libsmb_file.c
source3/libsmb/libsmb_stat.c
source3/libsmb/libsmb_xattr.c

index 5627b0c867eb63688faac206e49397ad8b8f4c57..2c139404c37167516214e89e4a617e17b25c9f76 100644 (file)
@@ -402,13 +402,7 @@ bool
 SMBC_getatr(SMBCCTX * context,
             SMBCSRV *srv,
             const char *path,
-            uint16_t *mode,
-            off_t *size,
-            struct timespec *create_time_ts,
-            struct timespec *access_time_ts,
-            struct timespec *write_time_ts,
-            struct timespec *change_time_ts,
-            SMB_INO_T *ino);
+           struct stat *sbuf);
 
 bool
 SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
index 14bfcdec6a7643a9489192b666f2ad4ab601138b..fd42c71b2b89c6e26ee5840aeb25902db27b5c72 100644 (file)
@@ -474,7 +474,6 @@ SMBC_opendir_ctx(SMBCCTX *context,
        char *workgroup = NULL;
        char *path = NULL;
        size_t path_len = 0;
-        uint16_t mode;
        uint16_t port = 0;
        SMBCSRV *srv  = NULL;
        SMBCFILE *dir = NULL;
@@ -961,6 +960,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                saved_errno = SMBC_errno(context, targetcli);
 
                                 if (saved_errno == EINVAL) {
+                                       struct stat sb = {0};
                                         /*
                                          * See if they asked to opendir
                                          * something other than a directory.
@@ -970,11 +970,11 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                          */
                                         path[path_len] = '\0'; /* restore original path */
 
-                                        if (SMBC_getatr(context, srv, path,
-                                                        &mode, NULL,
-                                                        NULL, NULL, NULL, NULL,
-                                                        NULL) &&
-                                            ! IS_DOS_DIR(mode)) {
+                                        if (SMBC_getatr(context,
+                                                       srv,
+                                                       path,
+                                                       &sb) &&
+                                            !S_ISDIR(sb.st_mode)) {
 
                                                 /* It is.  Correct the error value */
                                                 saved_errno = ENOTDIR;
@@ -2098,20 +2098,11 @@ SMBC_unlink_ctx(SMBCCTX *context,
                if (errno == EACCES) { /* Check if the file is a directory */
 
                        int saverr = errno;
-                       off_t size = 0;
-                       uint16_t mode = 0;
-                       struct timespec write_time_ts;
-                        struct timespec access_time_ts;
-                        struct timespec change_time_ts;
-                       SMB_INO_T ino = 0;
-
-                       if (!SMBC_getatr(context, srv, path, &mode, &size,
-                                        NULL,
-                                         &access_time_ts,
-                                         &write_time_ts,
-                                         &change_time_ts,
-                                         &ino)) {
+                       struct stat sb = {0};
+                       bool ok;
 
+                       ok = SMBC_getatr(context, srv, path, &sb);
+                       if (!ok) {
                                /* Hmmm, bad error ... What? */
 
                                errno = SMBC_errno(context, targetcli);
@@ -2121,7 +2112,7 @@ SMBC_unlink_ctx(SMBCCTX *context,
                        }
                        else {
 
-                               if (IS_DOS_DIR(mode))
+                               if (S_ISDIR(sb.st_mode))
                                        errno = EISDIR;
                                else
                                        errno = saverr;  /* Restore this */
index ebd0bfe422af3348f0061461ad1650bbac4a9b04..d73b0b68c07647d9c9c95234331da31217ac154a 100644 (file)
@@ -452,18 +452,19 @@ bool
 SMBC_getatr(SMBCCTX * context,
             SMBCSRV *srv,
             const char *path,
-            uint16_t *mode,
-            off_t *size,
-            struct timespec *create_time_ts,
-            struct timespec *access_time_ts,
-            struct timespec *write_time_ts,
-            struct timespec *change_time_ts,
-            SMB_INO_T *ino)
+           struct stat *sb)
 {
        char *fixedpath = NULL;
        char *targetpath = NULL;
        struct cli_state *targetcli = NULL;
-       time_t write_time;
+       uint16_t mode = 0;
+       off_t size = 0;
+       struct timespec create_time_ts = {0};
+       struct timespec access_time_ts = {0};
+       struct timespec write_time_ts = {0};
+       struct timespec change_time_ts = {0};
+       time_t write_time = 0;
+       SMB_INO_T ino = 0;
        TALLOC_CTX *frame = talloc_stackframe();
        NTSTATUS status;
 
@@ -503,28 +504,36 @@ SMBC_getatr(SMBCCTX * context,
                return False;
        }
 
-       if (!srv->no_pathinfo2 &&
-            NT_STATUS_IS_OK(cli_qpathinfo2(targetcli, targetpath,
-                           create_time_ts,
-                           access_time_ts,
-                           write_time_ts,
-                           change_time_ts,
-                          size, mode, ino))) {
-               TALLOC_FREE(frame);
-               return True;
+       if (!srv->no_pathinfo2) {
+               status = cli_qpathinfo2(targetcli,
+                                       targetpath,
+                                       &create_time_ts,
+                                       &access_time_ts,
+                                       &write_time_ts,
+                                       &change_time_ts,
+                                       &size,
+                                       &mode,
+                                       &ino);
+               if (NT_STATUS_IS_OK(status)) {
+                       goto setup_stat;
+               }
         }
 
        srv->no_pathinfo2 = True;
 
-       if (!srv->no_pathinfo3 &&
-            NT_STATUS_IS_OK(cli_qpathinfo3(targetcli, targetpath,
-                           create_time_ts,
-                           access_time_ts,
-                           write_time_ts,
-                           change_time_ts,
-                          size, mode, ino))) {
-               TALLOC_FREE(frame);
-               return True;
+       if (!srv->no_pathinfo3) {
+               status = cli_qpathinfo3(targetcli,
+                                       targetpath,
+                                       &create_time_ts,
+                                       &access_time_ts,
+                                       &write_time_ts,
+                                       &change_time_ts,
+                                       &size,
+                                       &mode,
+                                       &ino);
+               if (NT_STATUS_IS_OK(status)) {
+                       goto setup_stat;
+               }
         }
 
        srv->no_pathinfo3 = True;
@@ -534,29 +543,30 @@ SMBC_getatr(SMBCCTX * context,
                goto all_failed;
         }
 
-       if (NT_STATUS_IS_OK(cli_getatr(targetcli, targetpath, mode, size, &write_time))) {
-                struct timespec w_time_ts;
+       status = cli_getatr(targetcli, targetpath, &mode, &size, &write_time);
+       if (NT_STATUS_IS_OK(status)) {
+               struct timespec w_time_ts =
+                       convert_time_t_to_timespec(write_time);
 
-                w_time_ts = convert_time_t_to_timespec(write_time);
-                if (write_time_ts != NULL) {
-                       *write_time_ts = w_time_ts;
-                }
-                if (create_time_ts != NULL) {
-                        *create_time_ts = w_time_ts;
-                }
-                if (access_time_ts != NULL) {
-                        *access_time_ts = w_time_ts;
-                }
-                if (change_time_ts != NULL) {
-                        *change_time_ts = w_time_ts;
-                }
-               if (ino) {
-                       *ino = 0;
-               }
-               TALLOC_FREE(frame);
-               return True;
+               access_time_ts = change_time_ts = write_time_ts = w_time_ts;
+
+               goto setup_stat;
        }
 
+setup_stat:
+       setup_stat(sb,
+                  path,
+                  size,
+                  mode,
+                  ino,
+                  srv->dev,
+                  access_time_ts,
+                  change_time_ts,
+                  write_time_ts);
+
+       TALLOC_FREE(frame);
+       return true;
+
 all_failed:
        srv->no_pathinfo2 = False;
        srv->no_pathinfo3 = False;
index 7145c94c21cb36142d32ee333dca7e0ab8d9787d..c2e646e317d65f4fde4347d980b296c044859d21 100644 (file)
@@ -123,13 +123,7 @@ SMBC_stat_ctx(SMBCCTX *context,
        char *password = NULL;
        char *workgroup = NULL;
        char *path = NULL;
-       struct timespec write_time_ts;
-        struct timespec access_time_ts;
-        struct timespec change_time_ts;
-       off_t size = 0;
-       uint16_t mode = 0;
        uint16_t port = 0;
-       SMB_INO_T ino = 0;
        TALLOC_CTX *frame = talloc_stackframe();
 
        if (!context || !context->internal->initialized) {
@@ -178,27 +172,12 @@ SMBC_stat_ctx(SMBCCTX *context,
                return -1;  /* errno set by SMBC_server */
        }
 
-       if (!SMBC_getatr(context, srv, path, &mode, &size,
-                        NULL,
-                         &access_time_ts,
-                         &write_time_ts,
-                         &change_time_ts,
-                         &ino)) {
+       if (!SMBC_getatr(context, srv, path, st)) {
                errno = SMBC_errno(context, srv->cli);
                TALLOC_FREE(frame);
                return -1;
        }
 
-       setup_stat(st,
-               path,
-               size,
-               mode,
-               ino,
-               srv->dev,
-               access_time_ts,
-               change_time_ts,
-               write_time_ts);
-
        TALLOC_FREE(frame);
        return 0;
 }
index 442b45f24357e3158d2a31b9f02884379d7008a1..06a1d0c601dd4f828bd7b2e893d595ca466a7860 100644 (file)
@@ -552,13 +552,7 @@ dos_attr_query(SMBCCTX *context,
                const char *filename,
                SMBCSRV *srv)
 {
-        struct timespec create_time_ts;
-        struct timespec write_time_ts;
-        struct timespec access_time_ts;
-        struct timespec change_time_ts;
-        off_t size = 0;
-        uint16_t mode = 0;
-       SMB_INO_T inode = 0;
+       struct stat sb = {0};
         DOS_ATTR_DESC *ret;
 
         ret = talloc(ctx, DOS_ATTR_DESC);
@@ -568,26 +562,20 @@ dos_attr_query(SMBCCTX *context,
         }
 
         /* Obtain the DOS attributes */
-        if (!SMBC_getatr(context, srv, filename,
-                         &mode, &size,
-                         &create_time_ts,
-                         &access_time_ts,
-                         &write_time_ts,
-                         &change_time_ts,
-                         &inode)) {
+        if (!SMBC_getatr(context, srv, filename, &sb)) {
                 errno = SMBC_errno(context, srv->cli);
                 DEBUG(5, ("dos_attr_query Failed to query old attributes\n"));
                TALLOC_FREE(ret);
                 return NULL;
         }
 
-        ret->mode = mode;
-        ret->size = size;
-        ret->create_time = convert_timespec_to_time_t(create_time_ts);
-        ret->access_time = convert_timespec_to_time_t(access_time_ts);
-        ret->write_time = convert_timespec_to_time_t(write_time_ts);
-        ret->change_time = convert_timespec_to_time_t(change_time_ts);
-        ret->inode = inode;
+        ret->mode = sb.st_mode;
+        ret->size = sb.st_size;
+        ret->create_time = sb.st_ctime;
+        ret->access_time = sb.st_atime;
+        ret->write_time = sb.st_mtime;
+        ret->change_time = sb.st_mtime;
+        ret->inode = sb.st_ino;
 
         return ret;
 }
@@ -736,17 +724,6 @@ cacl_get(SMBCCTX *context,
         char *name;
         char *pExclude;
         char *p;
-        struct timespec create_time_ts;
-       struct timespec write_time_ts;
-        struct timespec access_time_ts;
-        struct timespec change_time_ts;
-       time_t create_time = (time_t)0;
-       time_t write_time = (time_t)0;
-        time_t access_time = (time_t)0;
-        time_t change_time = (time_t)0;
-       off_t size = 0;
-       uint16_t mode = 0;
-       SMB_INO_T ino = 0;
        struct cli_state *cli = srv->cli;
         struct {
                 const char * create_time_attr;
@@ -1155,25 +1132,31 @@ cacl_get(SMBCCTX *context,
         }
 
         if (all || some_dos) {
+               struct stat sb = {0};
+               time_t create_time = (time_t)0;
+               time_t write_time = (time_t)0;
+               time_t access_time = (time_t)0;
+               time_t change_time = (time_t)0;
+               off_t size = 0;
+               uint16_t mode = 0;
+               SMB_INO_T ino = 0;
+
                 /* Point to the portion after "system.dos_attr." */
                 name += 16;     /* if (all) this will be invalid but unused */
 
                 /* Obtain the DOS attributes */
-                if (!SMBC_getatr(context, srv, filename, &mode, &size, 
-                                 &create_time_ts,
-                                 &access_time_ts,
-                                 &write_time_ts,
-                                 &change_time_ts,
-                                 &ino)) {
-
+                if (!SMBC_getatr(context, srv, filename, &sb)) {
                         errno = SMBC_errno(context, srv->cli);
                         return -1;
                 }
 
-                create_time = convert_timespec_to_time_t(create_time_ts);
-                access_time = convert_timespec_to_time_t(access_time_ts);
-                write_time = convert_timespec_to_time_t(write_time_ts);
-                change_time = convert_timespec_to_time_t(change_time_ts);
+               create_time = sb.st_ctime;
+               access_time = sb.st_atime;
+               write_time  = sb.st_mtime;
+               change_time = sb.st_mtime;
+               size        = sb.st_size;
+               mode        = sb.st_mode;
+               ino         = sb.st_ino;
 
                 if (! exclude_dos_mode) {
                         if (all || all_dos) {