s3-vfs: include smbd/smbd.h in vfs modules.
[samba.git] / source3 / torture / cmd_vfs.c
index ee71b83471ee4eb4eb5071cf190718e5ebd7b38f..2c3a41600243a30cd617acf34ee2a58e9d67e8da 100644 (file)
@@ -7,7 +7,7 @@
 
    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
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
+#include "smbd/smbd.h"
+#include "system/passwd.h"
+#include "system/filesys.h"
 #include "vfstest.h"
+#include "../lib/util/util_pw.h"
 
 static const char *null_string = "";
 
@@ -54,7 +57,7 @@ static NTSTATUS cmd_populate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
        }
        c = argv[1][0];
        size = atoi(argv[2]);
-       vfs->data = (char *)talloc(mem_ctx, size);
+       vfs->data = TALLOC_ARRAY(mem_ctx, char, size);
        if (vfs->data == NULL) {
                printf("populate: error=-1 (not enough memory)");
                return NT_STATUS_UNSUCCESSFUL;
@@ -88,31 +91,31 @@ static NTSTATUS cmd_show_data(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar
                printf("show_data: error=-1 (not enough data in buffer)\n");
                return NT_STATUS_UNSUCCESSFUL;
        }
-       dump_data(0, (char *)(vfs->data) + offset, len);
+       dump_data(0, (uint8 *)(vfs->data) + offset, len);
        return NT_STATUS_OK;
 }
 
 static NTSTATUS cmd_connect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
-       VFS_CONNECT(vfs->conn, lp_servicename(vfs->conn->service), "vfstest");
+       SMB_VFS_CONNECT(vfs->conn, lp_servicename(SNUM(vfs->conn)), "vfstest");
        return NT_STATUS_OK;
 }
 
 static NTSTATUS cmd_disconnect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
-       VFS_DISCONNECT(vfs->conn);
+       SMB_VFS_DISCONNECT(vfs->conn);
        return NT_STATUS_OK;
 }
 
 static NTSTATUS cmd_disk_free(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
-       SMB_BIG_UINT diskfree, bsize, dfree, dsize;
+       uint64_t diskfree, bsize, dfree, dsize;
        if (argc != 2) {
                printf("Usage: disk_free <path>\n");
                return NT_STATUS_OK;
        }
 
-       diskfree = VFS_DISK_FREE(vfs->conn, argv[1], False, &bsize, &dfree, &dsize);
+       diskfree = SMB_VFS_DISK_FREE(vfs->conn, argv[1], False, &bsize, &dfree, &dsize);
        printf("disk_free: %lu, bsize = %lu, dfree = %lu, dsize = %lu\n",
                        (unsigned long)diskfree,
                        (unsigned long)bsize,
@@ -129,7 +132,7 @@ static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc
                return NT_STATUS_OK;
        }
 
-       vfs->currentdir = VFS_OPENDIR(vfs->conn, argv[1]);
+       vfs->currentdir = SMB_VFS_OPENDIR(vfs->conn, argv[1], NULL, 0);
        if (vfs->currentdir == NULL) {
                printf("opendir error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
@@ -142,20 +145,53 @@ static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc
 
 static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
-       struct dirent *dent;
+       SMB_STRUCT_STAT st;
+       SMB_STRUCT_DIRENT *dent = NULL;
 
        if (vfs->currentdir == NULL) {
                printf("readdir: error=-1 (no open directory)\n");
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       dent = VFS_READDIR(vfs->conn, vfs->currentdir);
+       dent = SMB_VFS_READDIR(vfs->conn, vfs->currentdir, &st);
        if (dent == NULL) {
                printf("readdir: NULL\n");
                return NT_STATUS_OK;
        }
 
        printf("readdir: %s\n", dent->d_name);
+       if (VALID_STAT(st)) {
+               time_t tmp_time;
+               printf("  stat available");
+               if (S_ISREG(st.st_ex_mode)) printf("  Regular File\n");
+               else if (S_ISDIR(st.st_ex_mode)) printf("  Directory\n");
+               else if (S_ISCHR(st.st_ex_mode)) printf("  Character Device\n");
+               else if (S_ISBLK(st.st_ex_mode)) printf("  Block Device\n");
+               else if (S_ISFIFO(st.st_ex_mode)) printf("  Fifo\n");
+               else if (S_ISLNK(st.st_ex_mode)) printf("  Symbolic Link\n");
+               else if (S_ISSOCK(st.st_ex_mode)) printf("  Socket\n");
+               printf("  Size: %10u", (unsigned int)st.st_ex_size);
+#ifdef HAVE_STAT_ST_BLOCKS
+               printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks);
+#endif
+#ifdef HAVE_STAT_ST_BLKSIZE
+               printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize);
+#endif
+               printf("  Device: 0x%10x", (unsigned int)st.st_ex_dev);
+               printf(" Inode: %10u", (unsigned int)st.st_ex_ino);
+               printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink);
+               printf("  Access: %05o", (int)((st.st_ex_mode) & 007777));
+               printf(" Uid: %5lu Gid: %5lu\n",
+                      (unsigned long)st.st_ex_uid,
+                      (unsigned long)st.st_ex_gid);
+               tmp_time = convert_timespec_to_time_t(st.st_ex_atime);
+               printf("  Access: %s", ctime(&tmp_time));
+               tmp_time = convert_timespec_to_time_t(st.st_ex_mtime);
+               printf("  Modify: %s", ctime(&tmp_time));
+               tmp_time = convert_timespec_to_time_t(st.st_ex_ctime);
+               printf("  Change: %s", ctime(&tmp_time));
+       }
+
        return NT_STATUS_OK;
 }
 
@@ -167,7 +203,7 @@ static NTSTATUS cmd_mkdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
                return NT_STATUS_OK;
        }
 
-       if (VFS_MKDIR(vfs->conn, argv[1], 00755) == -1) {
+       if (SMB_VFS_MKDIR(vfs->conn, argv[1], 00755) == -1) {
                printf("mkdir error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -186,7 +222,7 @@ static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       ret = VFS_CLOSEDIR(vfs->conn, vfs->currentdir);
+       ret = SMB_VFS_CLOSEDIR(vfs->conn, vfs->currentdir);
        if (ret == -1) {
                printf("closedir failure: %s\n", strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
@@ -200,9 +236,12 @@ static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
 
 static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
-       int flags, fd;
+       int flags;
        mode_t mode;
        const char *flagstr;
+       files_struct *fsp;
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
 
        mode = 00400;
 
@@ -272,23 +311,44 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
                flagstr++;
        }
        if ((flags & O_CREAT) && argc == 4) {
-               if (sscanf(argv[3], "%o", &mode) == 0) {
+               if (sscanf(argv[3], "%ho", (unsigned short *)&mode) == 0) {
                        printf("open: error=-1 (invalid mode!)\n");
                        return NT_STATUS_UNSUCCESSFUL;
                }
        }
 
-       fd = VFS_OPEN(vfs->conn, argv[1], flags, mode);
-       if (fd == -1) {
+       fsp = SMB_MALLOC_P(struct files_struct);
+       if (fsp == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       fsp->fh = SMB_MALLOC_P(struct fd_handle);
+       if (fsp->fh == NULL) {
+               SAFE_FREE(fsp->fsp_name);
+               SAFE_FREE(fsp);
+               return NT_STATUS_NO_MEMORY;
+       }
+       fsp->conn = vfs->conn;
+
+       status = create_synthetic_smb_fname_split(mem_ctx, argv[1], NULL,
+                                                 &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               SAFE_FREE(fsp);
+               return status;
+       }
+
+       fsp->fsp_name = smb_fname;
+
+       fsp->fh->fd = SMB_VFS_OPEN(vfs->conn, smb_fname, fsp, flags, mode);
+       if (fsp->fh->fd == -1) {
                printf("open: error=%d (%s)\n", errno, strerror(errno));
+               SAFE_FREE(fsp->fh);
+               SAFE_FREE(fsp);
+               TALLOC_FREE(smb_fname);
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       vfs->files[fd] = (struct files_struct *)malloc(sizeof(struct files_struct));
-       vfs->files[fd]->fsp_name = strdup(argv[1]);
-       vfs->files[fd]->fd = fd;
-       vfs->files[fd]->conn = vfs->conn;
-       printf("open: fd=%d\n", fd);
+       vfs->files[fsp->fh->fd] = fsp;
+       printf("open: fd=%d\n", fsp->fh->fd);
        return NT_STATUS_OK;
 }
 
@@ -303,11 +363,21 @@ static NTSTATUS cmd_pathfunc(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
        }
 
        if (strcmp("rmdir", argv[0]) == 0 ) {
-               ret = VFS_RMDIR(vfs->conn, argv[1]);
+               ret = SMB_VFS_RMDIR(vfs->conn, argv[1]);
        } else if (strcmp("unlink", argv[0]) == 0 ) {
-               ret = VFS_UNLINK(vfs->conn, argv[1]);
+               struct smb_filename *smb_fname = NULL;
+               NTSTATUS status;
+
+               status = create_synthetic_smb_fname_split(mem_ctx, argv[1],
+                                                         NULL, &smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+
+               ret = SMB_VFS_UNLINK(vfs->conn, smb_fname);
+               TALLOC_FREE(smb_fname);
        } else if (strcmp("chdir", argv[0]) == 0 ) {
-               ret = VFS_CHDIR(vfs->conn, argv[1]);
+               ret = SMB_VFS_CHDIR(vfs->conn, argv[1]);
        } else {
                printf("%s: error=%d (invalid function name!)\n", argv[0], errno);
                return NT_STATUS_UNSUCCESSFUL;
@@ -338,13 +408,14 @@ static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
                return NT_STATUS_OK;
        }
 
-       ret = VFS_CLOSE(vfs->files[fd], fd);
+       ret = SMB_VFS_CLOSE(vfs->files[fd]);
        if (ret == -1 )
                printf("close: error=%d (%s)\n", errno, strerror(errno));
        else
                printf("close: ok\n");
 
-       SAFE_FREE(vfs->files[fd]->fsp_name);
+       TALLOC_FREE(vfs->files[fd]->fsp_name);
+       SAFE_FREE(vfs->files[fd]->fh);
        SAFE_FREE(vfs->files[fd]);
        vfs->files[fd] = NULL;
        return NT_STATUS_OK;
@@ -364,14 +435,14 @@ static NTSTATUS cmd_read(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
        /* do some error checking on these */
        fd = atoi(argv[1]);
        size = atoi(argv[2]);
-       vfs->data = (char *)talloc(mem_ctx, size);
+       vfs->data = TALLOC_ARRAY(mem_ctx, char, size);
        if (vfs->data == NULL) {
                printf("read: error=-1 (not enough memory)");
                return NT_STATUS_UNSUCCESSFUL;
        }
        vfs->data_size = size;
        
-       rsize = VFS_READ(vfs->files[fd], fd, vfs->data, size);
+       rsize = SMB_VFS_READ(vfs->files[fd], vfs->data, size);
        if (rsize == -1) {
                printf("read: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
@@ -404,7 +475,7 @@ static NTSTATUS cmd_write(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       wsize = VFS_WRITE(vfs->files[fd], fd, vfs->data, size);
+       wsize = SMB_VFS_WRITE(vfs->files[fd], vfs->data, size);
 
        if (wsize == -1) {
                printf("write: error=%d (%s)\n", errno, strerror(errno));
@@ -435,7 +506,7 @@ static NTSTATUS cmd_lseek(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
                default:        whence = SEEK_END;
        }
 
-       pos = VFS_LSEEK(vfs->files[fd], fd, offset, whence);
+       pos = SMB_VFS_LSEEK(vfs->files[fd], offset, whence);
        if (pos == (SMB_OFF_T)-1) {
                printf("lseek: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
@@ -449,12 +520,31 @@ static NTSTATUS cmd_lseek(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
 static NTSTATUS cmd_rename(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
        int ret;
+       struct smb_filename *smb_fname_src = NULL;
+       struct smb_filename *smb_fname_dst = NULL;
+       NTSTATUS status;
+
        if (argc != 3) {
                printf("Usage: rename <old> <new>\n");
                return NT_STATUS_OK;
        }
 
-       ret = VFS_RENAME(vfs->conn, argv[1], argv[2]);
+       status = create_synthetic_smb_fname_split(mem_ctx, argv[1], NULL,
+                                                 &smb_fname_src);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = create_synthetic_smb_fname_split(mem_ctx, argv[2], NULL,
+                                                 &smb_fname_dst);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(smb_fname_src);
+               return status;
+       }
+
+       ret = SMB_VFS_RENAME(vfs->conn, smb_fname_src, smb_fname_dst);
+       TALLOC_FREE(smb_fname_src);
+       TALLOC_FREE(smb_fname_dst);
        if (ret == -1) {
                printf("rename: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
@@ -474,7 +564,7 @@ static NTSTATUS cmd_fsync(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
        }
 
        fd = atoi(argv[1]);
-       ret = VFS_FSYNC(vfs->files[fd], fd);
+       ret = SMB_VFS_FSYNC(vfs->files[fd]);
        if (ret == -1) {
                printf("fsync: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
@@ -490,50 +580,69 @@ static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
        int ret;
        const char *user;
        const char *group;
-       struct passwd *pwd;
-       struct group *grp;
+       struct passwd *pwd = NULL;
+       struct group *grp = NULL;
+       struct smb_filename *smb_fname = NULL;
        SMB_STRUCT_STAT st;
+       time_t tmp_time;
+       NTSTATUS status;
 
        if (argc != 2) {
                printf("Usage: stat <fname>\n");
                return NT_STATUS_OK;
        }
 
-       ret = VFS_STAT(vfs->conn, argv[1], &st);
+       status = create_synthetic_smb_fname_split(mem_ctx, argv[1], NULL,
+                                                 &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       ret = SMB_VFS_STAT(vfs->conn, smb_fname);
        if (ret == -1) {
                printf("stat: error=%d (%s)\n", errno, strerror(errno));
+               TALLOC_FREE(smb_fname);
                return NT_STATUS_UNSUCCESSFUL;
        }
+       st = smb_fname->st;
+       TALLOC_FREE(smb_fname);
 
-       pwd = sys_getpwuid(st.st_uid);
+       pwd = sys_getpwuid(st.st_ex_uid);
        if (pwd != NULL) user = pwd->pw_name;
        else user = null_string;
-       grp = sys_getgrgid(st.st_gid);
+       grp = sys_getgrgid(st.st_ex_gid);
        if (grp != NULL) group = grp->gr_name;
        else group = null_string;
 
        printf("stat: ok\n");
        printf("  File: %s", argv[1]);
-       if (S_ISREG(st.st_mode)) printf("  Regular File\n");
-       else if (S_ISDIR(st.st_mode)) printf("  Directory\n");
-       else if (S_ISCHR(st.st_mode)) printf("  Character Device\n");
-       else if (S_ISBLK(st.st_mode)) printf("  Block Device\n");
-       else if (S_ISFIFO(st.st_mode)) printf("  Fifo\n");
-       else if (S_ISLNK(st.st_mode)) printf("  Symbolic Link\n");
-       else if (S_ISSOCK(st.st_mode)) printf("  Socket\n");
-       printf("  Size: %10u", (unsigned int)st.st_size);
-       printf(" Blocks: %9u", (unsigned int)st.st_blocks);
-       printf(" IO Block: %u\n", (unsigned int)st.st_blksize);
-       printf("  Device: 0x%10x", (unsigned int)st.st_dev);
-       printf(" Inode: %10u", (unsigned int)st.st_ino);
-       printf(" Links: %10u\n", (unsigned int)st.st_nlink);
-       printf("  Access: %05o", (st.st_mode) & 007777);
-       printf(" Uid: %5d/%.16s Gid: %5d/%.16s\n", st.st_uid, user, st.st_gid, group);
-       printf("  Access: %s", ctime(&(st.st_atime)));
-       printf("  Modify: %s", ctime(&(st.st_mtime)));
-       printf("  Change: %s", ctime(&(st.st_ctime)));
-       SAFE_FREE(pwd);
-       SAFE_FREE(grp);
+       if (S_ISREG(st.st_ex_mode)) printf("  Regular File\n");
+       else if (S_ISDIR(st.st_ex_mode)) printf("  Directory\n");
+       else if (S_ISCHR(st.st_ex_mode)) printf("  Character Device\n");
+       else if (S_ISBLK(st.st_ex_mode)) printf("  Block Device\n");
+       else if (S_ISFIFO(st.st_ex_mode)) printf("  Fifo\n");
+       else if (S_ISLNK(st.st_ex_mode)) printf("  Symbolic Link\n");
+       else if (S_ISSOCK(st.st_ex_mode)) printf("  Socket\n");
+       printf("  Size: %10u", (unsigned int)st.st_ex_size);
+#ifdef HAVE_STAT_ST_BLOCKS
+       printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks);
+#endif
+#ifdef HAVE_STAT_ST_BLKSIZE
+       printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize);
+#endif
+       printf("  Device: 0x%10x", (unsigned int)st.st_ex_dev);
+       printf(" Inode: %10u", (unsigned int)st.st_ex_ino);
+       printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink);
+       printf("  Access: %05o", (int)((st.st_ex_mode) & 007777));
+       printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_ex_uid, user,
+              (unsigned long)st.st_ex_gid, group);
+       tmp_time = convert_timespec_to_time_t(st.st_ex_atime);
+       printf("  Access: %s", ctime(&tmp_time));
+       tmp_time = convert_timespec_to_time_t(st.st_ex_mtime);
+       printf("  Modify: %s", ctime(&tmp_time));
+       tmp_time = convert_timespec_to_time_t(st.st_ex_ctime);
+       printf("  Change: %s", ctime(&tmp_time));
+
        return NT_STATUS_OK;
 }
 
@@ -543,9 +652,10 @@ static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
        int fd;
        const char *user;
        const char *group;
-       struct passwd *pwd;
-       struct group *grp;
+       struct passwd *pwd = NULL;
+       struct group *grp = NULL;
        SMB_STRUCT_STAT st;
+       time_t tmp_time;
 
        if (argc != 2) {
                printf("Usage: fstat <fd>\n");
@@ -553,7 +663,7 @@ static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
        }
 
        fd = atoi(argv[1]);
-       if (fd < 0 || fd > 1024) {
+       if (fd < 0 || fd >= 1024) {
                printf("fstat: error=%d (file descriptor out of range)\n", EBADF);
                return NT_STATUS_OK;
        }
@@ -563,39 +673,46 @@ static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
                return NT_STATUS_OK;
        }
 
-       if (VFS_FSTAT(vfs->files[fd], fd, &st) == -1) {
+       if (SMB_VFS_FSTAT(vfs->files[fd], &st) == -1) {
                printf("fstat: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       pwd = sys_getpwuid(st.st_uid);
+       pwd = sys_getpwuid(st.st_ex_uid);
        if (pwd != NULL) user = pwd->pw_name;
        else user = null_string;
-       grp = sys_getgrgid(st.st_gid);
+       grp = sys_getgrgid(st.st_ex_gid);
        if (grp != NULL) group = grp->gr_name;
        else group = null_string;
 
        printf("fstat: ok\n");
-       if (S_ISREG(st.st_mode)) printf("  Regular File\n");
-       else if (S_ISDIR(st.st_mode)) printf("  Directory\n");
-       else if (S_ISCHR(st.st_mode)) printf("  Character Device\n");
-       else if (S_ISBLK(st.st_mode)) printf("  Block Device\n");
-       else if (S_ISFIFO(st.st_mode)) printf("  Fifo\n");
-       else if (S_ISLNK(st.st_mode)) printf("  Symbolic Link\n");
-       else if (S_ISSOCK(st.st_mode)) printf("  Socket\n");
-       printf("  Size: %10u", (unsigned int)st.st_size);
-       printf(" Blocks: %9u", (unsigned int)st.st_blocks);
-       printf(" IO Block: %u\n", (unsigned int)st.st_blksize);
-       printf("  Device: 0x%10x", (unsigned int)st.st_dev);
-       printf(" Inode: %10u", (unsigned int)st.st_ino);
-       printf(" Links: %10u\n", (unsigned int)st.st_nlink);
-       printf("  Access: %05o", (st.st_mode) & 007777);
-       printf(" Uid: %5d/%.16s Gid: %5d/%.16s\n", st.st_uid, user, st.st_gid, group);
-       printf("  Access: %s", ctime(&(st.st_atime)));
-       printf("  Modify: %s", ctime(&(st.st_mtime)));
-       printf("  Change: %s", ctime(&(st.st_ctime)));
-       SAFE_FREE(pwd);
-       SAFE_FREE(grp);
+       if (S_ISREG(st.st_ex_mode)) printf("  Regular File\n");
+       else if (S_ISDIR(st.st_ex_mode)) printf("  Directory\n");
+       else if (S_ISCHR(st.st_ex_mode)) printf("  Character Device\n");
+       else if (S_ISBLK(st.st_ex_mode)) printf("  Block Device\n");
+       else if (S_ISFIFO(st.st_ex_mode)) printf("  Fifo\n");
+       else if (S_ISLNK(st.st_ex_mode)) printf("  Symbolic Link\n");
+       else if (S_ISSOCK(st.st_ex_mode)) printf("  Socket\n");
+       printf("  Size: %10u", (unsigned int)st.st_ex_size);
+#ifdef HAVE_STAT_ST_BLOCKS
+       printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks);
+#endif
+#ifdef HAVE_STAT_ST_BLKSIZE
+       printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize);
+#endif
+       printf("  Device: 0x%10x", (unsigned int)st.st_ex_dev);
+       printf(" Inode: %10u", (unsigned int)st.st_ex_ino);
+       printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink);
+       printf("  Access: %05o", (int)((st.st_ex_mode) & 007777));
+       printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_ex_uid, user,
+              (unsigned long)st.st_ex_gid, group);
+       tmp_time = convert_timespec_to_time_t(st.st_ex_atime);
+       printf("  Access: %s", ctime(&tmp_time));
+       tmp_time = convert_timespec_to_time_t(st.st_ex_mtime);
+       printf("  Modify: %s", ctime(&tmp_time));
+       tmp_time = convert_timespec_to_time_t(st.st_ex_ctime);
+       printf("  Change: %s", ctime(&tmp_time));
+
        return NT_STATUS_OK;
 }
 
@@ -604,48 +721,67 @@ static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
 {
        const char *user;
        const char *group;
-       struct passwd *pwd;
-       struct group *grp;
+       struct passwd *pwd = NULL;
+       struct group *grp = NULL;
+       struct smb_filename *smb_fname = NULL;
        SMB_STRUCT_STAT st;
+       time_t tmp_time;
+       NTSTATUS status;
 
        if (argc != 2) {
                printf("Usage: lstat <path>\n");
                return NT_STATUS_OK;
        }
 
-       if (VFS_LSTAT(vfs->conn, argv[1], &st) == -1) {
+       status = create_synthetic_smb_fname_split(mem_ctx, argv[1], NULL,
+                                                 &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       if (SMB_VFS_LSTAT(vfs->conn, smb_fname) == -1) {
                printf("lstat: error=%d (%s)\n", errno, strerror(errno));
+               TALLOC_FREE(smb_fname);
                return NT_STATUS_UNSUCCESSFUL;
        }
+       st = smb_fname->st;
+       TALLOC_FREE(smb_fname);
 
-       pwd = sys_getpwuid(st.st_uid);
+       pwd = sys_getpwuid(st.st_ex_uid);
        if (pwd != NULL) user = pwd->pw_name;
        else user = null_string;
-       grp = sys_getgrgid(st.st_gid);
+       grp = sys_getgrgid(st.st_ex_gid);
        if (grp != NULL) group = grp->gr_name;
        else group = null_string;
 
        printf("lstat: ok\n");
-       if (S_ISREG(st.st_mode)) printf("  Regular File\n");
-       else if (S_ISDIR(st.st_mode)) printf("  Directory\n");
-       else if (S_ISCHR(st.st_mode)) printf("  Character Device\n");
-       else if (S_ISBLK(st.st_mode)) printf("  Block Device\n");
-       else if (S_ISFIFO(st.st_mode)) printf("  Fifo\n");
-       else if (S_ISLNK(st.st_mode)) printf("  Symbolic Link\n");
-       else if (S_ISSOCK(st.st_mode)) printf("  Socket\n");
-       printf("  Size: %10u", (unsigned int)st.st_size);
-       printf(" Blocks: %9u", (unsigned int)st.st_blocks);
-       printf(" IO Block: %u\n", (unsigned int)st.st_blksize);
-       printf("  Device: 0x%10x", (unsigned int)st.st_dev);
-       printf(" Inode: %10u", (unsigned int)st.st_ino);
-       printf(" Links: %10u\n", (unsigned int)st.st_nlink);
-       printf("  Access: %05o", (st.st_mode) & 007777);
-       printf(" Uid: %5d/%.16s Gid: %5d/%.16s\n", st.st_uid, user, st.st_gid, group);
-       printf("  Access: %s", ctime(&(st.st_atime)));
-       printf("  Modify: %s", ctime(&(st.st_mtime)));
-       printf("  Change: %s", ctime(&(st.st_ctime)));
-       SAFE_FREE(pwd);
-       SAFE_FREE(grp);
+       if (S_ISREG(st.st_ex_mode)) printf("  Regular File\n");
+       else if (S_ISDIR(st.st_ex_mode)) printf("  Directory\n");
+       else if (S_ISCHR(st.st_ex_mode)) printf("  Character Device\n");
+       else if (S_ISBLK(st.st_ex_mode)) printf("  Block Device\n");
+       else if (S_ISFIFO(st.st_ex_mode)) printf("  Fifo\n");
+       else if (S_ISLNK(st.st_ex_mode)) printf("  Symbolic Link\n");
+       else if (S_ISSOCK(st.st_ex_mode)) printf("  Socket\n");
+       printf("  Size: %10u", (unsigned int)st.st_ex_size);
+#ifdef HAVE_STAT_ST_BLOCKS
+       printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks);
+#endif
+#ifdef HAVE_STAT_ST_BLKSIZE
+       printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize);
+#endif
+       printf("  Device: 0x%10x", (unsigned int)st.st_ex_dev);
+       printf(" Inode: %10u", (unsigned int)st.st_ex_ino);
+       printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink);
+       printf("  Access: %05o", (int)((st.st_ex_mode) & 007777));
+       printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_ex_uid, user,
+              (unsigned long)st.st_ex_gid, group);
+       tmp_time = convert_timespec_to_time_t(st.st_ex_atime);
+       printf("  Access: %s", ctime(&tmp_time));
+       tmp_time = convert_timespec_to_time_t(st.st_ex_mtime);
+       printf("  Modify: %s", ctime(&tmp_time));
+       tmp_time = convert_timespec_to_time_t(st.st_ex_ctime);
+       printf("  Change: %s", ctime(&tmp_time));
+       
        return NT_STATUS_OK;
 }
 
@@ -659,7 +795,7 @@ static NTSTATUS cmd_chmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
        }
 
        mode = atoi(argv[2]);
-       if (VFS_CHMOD(vfs->conn, argv[1], mode) == -1) {
+       if (SMB_VFS_CHMOD(vfs->conn, argv[1], mode) == -1) {
                printf("chmod: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -680,7 +816,7 @@ static NTSTATUS cmd_fchmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
 
        fd = atoi(argv[1]);
        mode = atoi(argv[2]);
-       if (fd < 0 || fd > 1024) {
+       if (fd < 0 || fd >= 1024) {
                printf("fchmod: error=%d (file descriptor out of range)\n", EBADF);
                return NT_STATUS_OK;
        }
@@ -689,7 +825,7 @@ static NTSTATUS cmd_fchmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
                return NT_STATUS_OK;
        }
 
-       if (VFS_FCHMOD(vfs->files[fd], fd, mode) == -1) {
+       if (SMB_VFS_FCHMOD(vfs->files[fd], mode) == -1) {
                printf("fchmod: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -710,7 +846,7 @@ static NTSTATUS cmd_chown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
 
        uid = atoi(argv[2]);
        gid = atoi(argv[3]);
-       if (VFS_CHOWN(vfs->conn, argv[1], uid, gid) == -1) {
+       if (SMB_VFS_CHOWN(vfs->conn, argv[1], uid, gid) == -1) {
                printf("chown: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -733,7 +869,7 @@ static NTSTATUS cmd_fchown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
        uid = atoi(argv[2]);
        gid = atoi(argv[3]);
        fd = atoi(argv[1]);
-       if (fd < 0 || fd > 1024) {
+       if (fd < 0 || fd >= 1024) {
                printf("fchown: faliure=%d (file descriptor out of range)\n", EBADF);
                return NT_STATUS_OK;
        }
@@ -741,7 +877,7 @@ static NTSTATUS cmd_fchown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
                printf("fchown: error=%d (invalid file descriptor)\n", EBADF);
                return NT_STATUS_OK;
        }
-       if (VFS_FCHOWN(vfs->files[fd], fd, uid, gid) == -1) {
+       if (SMB_VFS_FCHOWN(vfs->files[fd], uid, gid) == -1) {
                printf("fchown error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -754,7 +890,7 @@ static NTSTATUS cmd_fchown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
 static NTSTATUS cmd_getwd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
        char buf[PATH_MAX];
-       if (VFS_GETWD(vfs->conn, buf) == NULL) {
+       if (SMB_VFS_GETWD(vfs->conn, buf) == NULL) {
                printf("getwd: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -765,18 +901,33 @@ static NTSTATUS cmd_getwd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
 
 static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
-       struct utimbuf times;
+       struct smb_file_time ft;
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
+
        if (argc != 4) {
                printf("Usage: utime <path> <access> <modify>\n");
                return NT_STATUS_OK;
        }
-       times.actime = atoi(argv[2]);
-       times.modtime = atoi(argv[3]);
-       if (VFS_UTIME(vfs->conn, argv[1], &times) != 0) {
+
+       ZERO_STRUCT(ft);
+
+       ft.atime = convert_time_t_to_timespec(atoi(argv[2]));
+       ft.mtime = convert_time_t_to_timespec(atoi(argv[3]));
+
+       status = create_synthetic_smb_fname_split(mem_ctx, argv[1],
+                                                 NULL, &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       if (SMB_VFS_NTIMES(vfs->conn, smb_fname, &ft) != 0) {
                printf("utime: error=%d (%s)\n", errno, strerror(errno));
+               TALLOC_FREE(smb_fname);
                return NT_STATUS_UNSUCCESSFUL;
        }
 
+       TALLOC_FREE(smb_fname);
        printf("utime: ok\n");
        return NT_STATUS_OK;
 }
@@ -792,7 +943,7 @@ static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar
 
        fd = atoi(argv[1]);
        off = atoi(argv[2]);
-       if (fd < 0 || fd > 1024) {
+       if (fd < 0 || fd >= 1024) {
                printf("ftruncate: error=%d (file descriptor out of range)\n", EBADF);
                return NT_STATUS_OK;
        }
@@ -801,7 +952,7 @@ static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar
                return NT_STATUS_OK;
        }
 
-       if (VFS_FTRUNCATE(vfs->files[fd], fd, off) == -1) {
+       if (SMB_VFS_FTRUNCATE(vfs->files[fd], off) == -1) {
                printf("ftruncate: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -812,7 +963,6 @@ static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar
 
 static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
-       BOOL ret;
        int fd;
        int op;
        long offset;
@@ -884,7 +1034,7 @@ static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
 
        printf("lock: debug lock(fd=%d, op=%d, offset=%ld, count=%ld, type=%d))\n", fd, op, offset, count, type);
 
-       if ((ret = VFS_LOCK(vfs->files[fd], fd, op, offset, count, type)) == False) {
+       if (SMB_VFS_LOCK(vfs->files[fd], op, offset, count, type) == False) {
                printf("lock: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -900,7 +1050,7 @@ static NTSTATUS cmd_symlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc
                return NT_STATUS_OK;
        }
 
-       if (VFS_SYMLINK(vfs->conn, argv[1], argv[2]) == -1) {
+       if (SMB_VFS_SYMLINK(vfs->conn, argv[1], argv[2]) == -1) {
                printf("symlink: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -920,7 +1070,7 @@ static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
                return NT_STATUS_OK;
        }
 
-       if ((size = VFS_READLINK(vfs->conn, argv[1], buffer, PATH_MAX)) == -1) {
+       if ((size = SMB_VFS_READLINK(vfs->conn, argv[1], buffer, PATH_MAX)) == -1) {
                printf("readlink: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -938,7 +1088,7 @@ static NTSTATUS cmd_link(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
                return NT_STATUS_OK;
        }
 
-       if (VFS_LINK(vfs->conn, argv[1], argv[2]) == -1) {
+       if (SMB_VFS_LINK(vfs->conn, argv[1], argv[2]) == -1) {
                printf("link: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -960,7 +1110,7 @@ static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
                return NT_STATUS_OK;
        }
 
-       if (sscanf(argv[2], "%o", &mode) == 0) {
+       if (sscanf(argv[2], "%ho", (unsigned short *)&mode) == 0) {
                printf("open: error=-1 (invalid mode!)\n");
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -971,7 +1121,7 @@ static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
        }
        dev = (SMB_DEV_T)dev_val;
 
-       if (VFS_MKNOD(vfs->conn, argv[1], mode, dev) == -1) {
+       if (SMB_VFS_MKNOD(vfs->conn, argv[1], mode, dev) == -1) {
                printf("mknod: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -982,14 +1132,12 @@ static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
 
 static NTSTATUS cmd_realpath(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
-       char respath[PATH_MAX];
-       
        if (argc != 2) {
                printf("Usage: realpath <path>\n");
                return NT_STATUS_OK;
        }
 
-       if (VFS_REALPATH(vfs->conn, argv[1], respath) == NULL) {
+       if (SMB_VFS_REALPATH(vfs->conn, argv[1]) == NULL) {
                printf("realpath: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }