r14173: change smb interface structures to always use
[jelmer/samba4-debian.git] / source / torture / raw / write.c
index 28faf6b22ce033f2934d6e2e9ae0970939e64db2..e9a391a7dc049af04fbb49fff3caff4ac55e91aa 100644 (file)
@@ -1,6 +1,7 @@
 /* 
    Unix SMB/CIFS implementation.
    test suite for various write operations
+
    Copyright (C) Andrew Tridgell 2003
    
    This program is free software; you can redistribute it and/or modify
 */
 
 #include "includes.h"
+#include "torture/torture.h"
 #include "libcli/raw/libcliraw.h"
+#include "system/time.h"
+#include "system/filesys.h"
+#include "libcli/libcli.h"
 
 #define CHECK_STATUS(status, correct) do { \
        if (!NT_STATUS_EQUAL(status, correct)) { \
@@ -45,7 +50,7 @@
 
 #define CHECK_ALL_INFO(v, field) do { \
        finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
-       finfo.all_info.in.fname = fname; \
+       finfo.all_info.file.path = fname; \
        status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); \
        CHECK_STATUS(status, NT_STATUS_OK); \
        if ((v) != finfo.all_info.out.field) { \
 #define BASEDIR "\\testwrite"
 
 
-static BOOL setup_dir(struct smbcli_state *cli, const char *dname)
-{
-       smb_raw_exit(cli->session);
-       if (smbcli_deltree(cli->tree, dname) == -1 ||
-           NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
-               printf("Unable to setup %s - %s\n", dname, smbcli_errstr(cli->tree));
-               return False;
-       }
-       return True;
-}
-
-
 /*
   setup a random buffer based on a seed
 */
-static void setup_buffer(char *buf, uint_t seed, int len)
+static void setup_buffer(uint8_t *buf, uint_t seed, int len)
 {
        int i;
        srandom(seed);
@@ -84,12 +77,12 @@ static void setup_buffer(char *buf, uint_t seed, int len)
 /*
   check a random buffer based on a seed
 */
-static BOOL check_buffer(char *buf, uint_t seed, int len, const char *location)
+static BOOL check_buffer(uint8_t *buf, uint_t seed, int len, const char *location)
 {
        int i;
        srandom(seed);
        for (i=0;i<len;i++) {
-               char v = random();
+               uint8_t v = random();
                if (buf[i] != v) {
                        printf("Buffer incorrect at %s! ofs=%d buf=0x%x correct=0x%x\n", 
                               location, i, buf[i], v);
@@ -108,15 +101,15 @@ static BOOL test_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        NTSTATUS status;
        BOOL ret = True;
        int fnum;
-       char *buf;
+       uint8_t *buf;
        const int maxsize = 90000;
        const char *fname = BASEDIR "\\test.txt";
        uint_t seed = time(NULL);
        union smb_fileinfo finfo;
 
-       buf = talloc_zero(mem_ctx, maxsize);
+       buf = talloc_zero_size(mem_ctx, maxsize);
 
-       if (!setup_dir(cli, BASEDIR)) {
+       if (!torture_setup_dir(cli, BASEDIR)) {
                return False;
        }
 
@@ -131,7 +124,7 @@ static BOOL test_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        }
 
        printf("Trying zero write\n");
-       io.write.in.fnum = fnum;
+       io.write.file.fnum = fnum;
        io.write.in.count = 0;
        io.write.in.offset = 0;
        io.write.in.remaining = 0;
@@ -178,7 +171,7 @@ static BOOL test_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_BUFFER(buf, seed, 4000);
 
        printf("Trying bad fnum\n");
-       io.write.in.fnum = fnum+1;
+       io.write.file.fnum = fnum+1;
        io.write.in.count = 4000;
        io.write.in.offset = 0;
        io.write.in.data = buf;
@@ -191,7 +184,7 @@ static BOOL test_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        
        printf("Trying 2^32 offset\n");
        setup_buffer(buf, seed, maxsize);
-       io.write.in.fnum = fnum;
+       io.write.file.fnum = fnum;
        io.write.in.count = 4000;
        io.write.in.offset = 0xFFFFFFFF - 2000;
        io.write.in.data = buf;
@@ -225,15 +218,15 @@ static BOOL test_writex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        NTSTATUS status;
        BOOL ret = True;
        int fnum, i;
-       char *buf;
+       uint8_t *buf;
        const int maxsize = 90000;
        const char *fname = BASEDIR "\\test.txt";
        uint_t seed = time(NULL);
        union smb_fileinfo finfo;
 
-       buf = talloc_zero(mem_ctx, maxsize);
+       buf = talloc_zero_size(mem_ctx, maxsize);
 
-       if (!setup_dir(cli, BASEDIR)) {
+       if (!torture_setup_dir(cli, BASEDIR)) {
                return False;
        }
 
@@ -248,7 +241,7 @@ static BOOL test_writex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        }
 
        printf("Trying zero write\n");
-       io.writex.in.fnum = fnum;
+       io.writex.file.fnum = fnum;
        io.writex.in.offset = 0;
        io.writex.in.wmode = 0;
        io.writex.in.remaining = 0;
@@ -296,7 +289,7 @@ static BOOL test_writex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_BUFFER(buf, seed, 4000);
 
        printf("Trying bad fnum\n");
-       io.writex.in.fnum = fnum+1;
+       io.writex.file.fnum = fnum+1;
        io.writex.in.count = 4000;
        io.writex.in.offset = 0;
        io.writex.in.data = buf;
@@ -304,7 +297,7 @@ static BOOL test_writex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
        printf("Testing wmode\n");
-       io.writex.in.fnum = fnum;
+       io.writex.file.fnum = fnum;
        io.writex.in.count = 1;
        io.writex.in.offset = 0;
        io.writex.in.wmode = 1;
@@ -339,7 +332,7 @@ static BOOL test_writex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        
        printf("Trying 2^32 offset\n");
        setup_buffer(buf, seed, maxsize);
-       io.writex.in.fnum = fnum;
+       io.writex.file.fnum = fnum;
        io.writex.in.count = 4000;
        io.writex.in.offset = 0xFFFFFFFF - 2000;
        io.writex.in.data = buf;
@@ -359,12 +352,12 @@ static BOOL test_writex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        for (i=33;i<64;i++) {
                printf("Trying 2^%d offset\n", i);
                setup_buffer(buf, seed+1, maxsize);
-               io.writex.in.fnum = fnum;
+               io.writex.file.fnum = fnum;
                io.writex.in.count = 4000;
                io.writex.in.offset = ((uint64_t)1) << i;
                io.writex.in.data = buf;
                status = smb_raw_write(cli->tree, &io);
-               if (i>40 &&
+               if (i>33 &&
                    NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
                        break;
                }
@@ -401,15 +394,15 @@ static BOOL test_writeunlock(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        NTSTATUS status;
        BOOL ret = True;
        int fnum;
-       char *buf;
+       uint8_t *buf;
        const int maxsize = 90000;
        const char *fname = BASEDIR "\\test.txt";
        uint_t seed = time(NULL);
        union smb_fileinfo finfo;
 
-       buf = talloc_zero(mem_ctx, maxsize);
+       buf = talloc_zero_size(mem_ctx, maxsize);
 
-       if (!setup_dir(cli, BASEDIR)) {
+       if (!torture_setup_dir(cli, BASEDIR)) {
                return False;
        }
 
@@ -424,7 +417,7 @@ static BOOL test_writeunlock(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        }
 
        printf("Trying zero write\n");
-       io.writeunlock.in.fnum = fnum;
+       io.writeunlock.file.fnum = fnum;
        io.writeunlock.in.count = 0;
        io.writeunlock.in.offset = 0;
        io.writeunlock.in.remaining = 0;
@@ -489,7 +482,7 @@ static BOOL test_writeunlock(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_BUFFER(buf, seed, 4000);
 
        printf("Trying bad fnum\n");
-       io.writeunlock.in.fnum = fnum+1;
+       io.writeunlock.file.fnum = fnum+1;
        io.writeunlock.in.count = 4000;
        io.writeunlock.in.offset = 0;
        io.writeunlock.in.data = buf;
@@ -502,7 +495,7 @@ static BOOL test_writeunlock(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        
        printf("Trying 2^32 offset\n");
        setup_buffer(buf, seed, maxsize);
-       io.writeunlock.in.fnum = fnum;
+       io.writeunlock.file.fnum = fnum;
        io.writeunlock.in.count = 4000;
        io.writeunlock.in.offset = 0xFFFFFFFF - 2000;
        io.writeunlock.in.data = buf;
@@ -538,15 +531,15 @@ static BOOL test_writeclose(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        NTSTATUS status;
        BOOL ret = True;
        int fnum;
-       char *buf;
+       uint8_t *buf;
        const int maxsize = 90000;
        const char *fname = BASEDIR "\\test.txt";
        uint_t seed = time(NULL);
        union smb_fileinfo finfo;
 
-       buf = talloc_zero(mem_ctx, maxsize);
+       buf = talloc_zero_size(mem_ctx, maxsize);
 
-       if (!setup_dir(cli, BASEDIR)) {
+       if (!torture_setup_dir(cli, BASEDIR)) {
                return False;
        }
 
@@ -561,7 +554,7 @@ static BOOL test_writeclose(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        }
 
        printf("Trying zero write\n");
-       io.writeclose.in.fnum = fnum;
+       io.writeclose.file.fnum = fnum;
        io.writeclose.in.count = 0;
        io.writeclose.in.offset = 0;
        io.writeclose.in.mtime = 0;
@@ -587,7 +580,7 @@ static BOOL test_writeclose(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
        fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
-       io.writeclose.in.fnum = fnum;
+       io.writeclose.file.fnum = fnum;
 
        if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
                printf("read failed at %s\n", __location__);
@@ -603,7 +596,7 @@ static BOOL test_writeclose(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_VALUE(io.writeclose.out.nwritten, io.writeclose.in.count);
 
        fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
-       io.writeclose.in.fnum = fnum;
+       io.writeclose.file.fnum = fnum;
 
        memset(buf, 0, maxsize);
        if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
@@ -628,7 +621,7 @@ static BOOL test_writeclose(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
        fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
-       io.writeclose.in.fnum = fnum;
+       io.writeclose.file.fnum = fnum;
 
        memset(buf, 0, maxsize);
        if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
@@ -639,7 +632,7 @@ static BOOL test_writeclose(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_BUFFER(buf, seed, 4000);
 
        printf("Trying bad fnum\n");
-       io.writeclose.in.fnum = fnum+1;
+       io.writeclose.file.fnum = fnum+1;
        io.writeclose.in.count = 4000;
        io.writeclose.in.offset = 0;
        io.writeclose.in.data = buf;
@@ -652,7 +645,7 @@ static BOOL test_writeclose(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        
        printf("Trying 2^32 offset\n");
        setup_buffer(buf, seed, maxsize);
-       io.writeclose.in.fnum = fnum;
+       io.writeclose.file.fnum = fnum;
        io.writeclose.in.count = 4000;
        io.writeclose.in.offset = 0xFFFFFFFF - 2000;
        io.writeclose.in.data = buf;
@@ -662,7 +655,7 @@ static BOOL test_writeclose(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_ALL_INFO(io.writeclose.in.count + (uint64_t)io.writeclose.in.offset, size);
 
        fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
-       io.writeclose.in.fnum = fnum;
+       io.writeclose.file.fnum = fnum;
 
        memset(buf, 0, maxsize);
        if (smbcli_read(cli->tree, fnum, buf, io.writeclose.in.offset, 4000) != 4000) {
@@ -679,238 +672,6 @@ done:
        return ret;
 }
 
-static BOOL test_delayed_write_update(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
-{
-       union smb_fileinfo finfo1, finfo2;
-       const char *fname = BASEDIR "\\torture_file.txt";
-       NTSTATUS status;
-       int fnum1 = -1;
-       BOOL ret = True;
-       ssize_t written;
-       time_t t;
-
-       printf("Testing delayed update of write time\n");
-
-       if (!setup_dir(cli, BASEDIR)) {
-               return False;
-       }
-
-       fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
-       if (fnum1 == -1) {
-               printf("Failed to open %s\n", fname);
-               return False;
-       }
-
-       finfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO;
-       finfo1.basic_info.in.fnum = fnum1;
-       finfo2 = finfo1;
-
-       status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo1);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
-               return False;
-       }
-       
-       printf("Initial write time %s\n", 
-              nt_time_string(mem_ctx, finfo1.basic_info.out.write_time));
-
-       /* 3 second delay to ensure we get past any 2 second time
-          granularity (older systems may have that) */
-       sleep(3);
-
-       written =  smbcli_write(cli->tree, fnum1, 0, "x", 0, 1);
-
-       if (written != 1) {
-               printf("write failed - wrote %d bytes (%s)\n", written, __location__);
-               return False;
-       }
-
-       t = time(NULL);
-
-       while (time(NULL) < t+120) {
-               status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo2);
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
-                       ret = False;
-                       break;
-               }
-               printf("write time %s\n", 
-                      nt_time_string(mem_ctx, finfo2.basic_info.out.write_time));
-               if (finfo1.basic_info.out.write_time != finfo2.basic_info.out.write_time) {
-                       printf("Server updated write_time after %d seconds\n",
-                              (int)(time(NULL) - t));
-                       break;
-               }
-               sleep(1);
-               fflush(stdout);
-       }
-       
-       if (finfo1.basic_info.out.write_time == finfo2.basic_info.out.write_time) {
-               printf("Server did not update write time?!\n");
-               ret = False;
-       }
-
-
-       if (fnum1 != -1)
-               smbcli_close(cli->tree, fnum1);
-       smbcli_unlink(cli->tree, fname);
-       smbcli_deltree(cli->tree, BASEDIR);
-
-       return ret;
-}
-
-
-/* Windows does obviously not update the stat info during a write call. I
- * *think* this is the problem causing a spurious Excel 2003 on XP error
- * message when saving a file. Excel does a setfileinfo, writes, and then does
- * a getpath(!)info. Or so... For Samba sometimes it displays an error message
- * that the file might have been changed in between. What i've been able to
- * trace down is that this happens if the getpathinfo after the write shows a
- * different last write time than the setfileinfo showed. This is really
- * nasty....
- */
-
-static BOOL test_finfo_after_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
-{
-       union smb_fileinfo finfo1, finfo2;
-       const char *fname = BASEDIR "\\torture_file.txt";
-       NTSTATUS status;
-       int fnum1 = -1;
-       int fnum2;
-       BOOL ret = True;
-       ssize_t written;
-       struct smbcli_state *cli2=NULL;
-
-       printf("Testing finfo update on close\n");
-
-       if (!setup_dir(cli, BASEDIR)) {
-               return False;
-       }
-
-       fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
-       if (fnum1 == -1) {
-               ret = False;
-               goto done;
-       }
-
-       finfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO;
-       finfo1.basic_info.in.fnum = fnum1;
-
-       status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo1);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
-               ret = False;
-               goto done;
-       }
-
-       msleep(1000);
-
-       written =  smbcli_write(cli->tree, fnum1, 0, "x", 0, 1);
-
-       if (written != 1) {
-               printf("(%s) written gave %d - should have been 1\n", 
-                      __location__, written);
-               ret = False;
-               goto done;
-       }
-
-       if (!torture_open_connection(&cli2)) {
-               return False;
-       }
-
-       fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
-       if (fnum2 == -1) {
-               printf("(%s) failed to open 2nd time - %s\n", 
-                      __location__, smbcli_errstr(cli2->tree));
-               ret = False;
-               goto done;
-       }
-       
-       written =  smbcli_write(cli2->tree, fnum2, 0, "x", 0, 1);
-       
-       if (written != 1) {
-               printf("(%s) written gave %d - should have been 1\n", 
-                      __location__, written);
-               ret = False;
-               goto done;
-       }
-       
-       finfo2.basic_info.level = RAW_FILEINFO_BASIC_INFO;
-       finfo2.basic_info.in.fname = fname;
-       
-       status = smb_raw_pathinfo(cli2->tree, mem_ctx, &finfo2);
-       
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("(%s) fileinfo failed: %s\n", 
-                         __location__, nt_errstr(status)));
-               ret = False;
-               goto done;
-       }
-       
-       if (finfo1.basic_info.out.create_time !=
-           finfo2.basic_info.out.create_time) {
-               printf("(%s) create_time changed\n", __location__);
-               ret = False;
-               goto done;
-       }
-       
-       if (finfo1.basic_info.out.access_time !=
-           finfo2.basic_info.out.access_time) {
-               printf("(%s) access_time changed\n", __location__);
-               ret = False;
-               goto done;
-       }
-       
-       if (finfo1.basic_info.out.write_time !=
-           finfo2.basic_info.out.write_time) {
-               printf("(%s) write_time changed\n", __location__);
-               ret = False;
-               goto done;
-       }
-       
-       if (finfo1.basic_info.out.change_time !=
-           finfo2.basic_info.out.change_time) {
-               printf("(%s) change_time changed\n", __location__);
-               ret = False;
-               goto done;
-       }
-       
-       /* One of the two following calls updates the qpathinfo. */
-       
-       /* If you had skipped the smbcli_write on fnum2, it would
-        * *not* have updated the stat on disk */
-       
-       smbcli_close(cli2->tree, fnum2);
-       torture_close_connection(cli2);
-       cli2 = NULL;
-
-       /* This call is only for the people looking at ethereal :-) */
-       finfo2.basic_info.level = RAW_FILEINFO_BASIC_INFO;
-       finfo2.basic_info.in.fname = fname;
-
-       status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo2);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
-               ret = False;
-               goto done;
-       }
-
- done:
-       if (fnum1 != -1)
-               smbcli_close(cli->tree, fnum1);
-       smbcli_unlink(cli->tree, fname);
-       smbcli_deltree(cli->tree, BASEDIR);
-       if (cli2 != NULL) {
-               torture_close_connection(cli2);
-       }
-
-       return ret;
-}
-
 /* 
    basic testing of write calls
 */
@@ -926,14 +687,12 @@ BOOL torture_raw_write(void)
 
        mem_ctx = talloc_init("torture_raw_write");
 
-       ret &= test_finfo_after_write(cli, mem_ctx);
-       ret &= test_delayed_write_update(cli, mem_ctx);
        ret &= test_write(cli, mem_ctx);
        ret &= test_writeunlock(cli, mem_ctx);
        ret &= test_writeclose(cli, mem_ctx);
        ret &= test_writex(cli, mem_ctx);
 
        torture_close_connection(cli);
-       talloc_destroy(mem_ctx);
+       talloc_free(mem_ctx);
        return ret;
 }