r14173: change smb interface structures to always use
[jelmer/samba4-debian.git] / source / torture / basic / delaywrite.c
index 51fe2814e2e2c691a6b5dc8108b7071db84f074b..2a41508bcc39da5d5a17bc15f995ed59ac851982 100644 (file)
 */
 
 #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 BASEDIR "\\delaywrite"
 
@@ -51,7 +54,7 @@ static BOOL test_delayed_write_update(struct smbcli_state *cli, TALLOC_CTX *mem_
        }
 
        finfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO;
-       finfo1.basic_info.in.fnum = fnum1;
+       finfo1.basic_info.file.fnum = fnum1;
        finfo2 = finfo1;
 
        status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo1);
@@ -71,7 +74,8 @@ static BOOL test_delayed_write_update(struct smbcli_state *cli, TALLOC_CTX *mem_
        written =  smbcli_write(cli->tree, fnum1, 0, "x", 0, 1);
 
        if (written != 1) {
-               printf("write failed - wrote %d bytes (%s)\n", written, __location__);
+               printf("write failed - wrote %d bytes (%s)\n", 
+                      (int)written, __location__);
                return False;
        }
 
@@ -121,10 +125,11 @@ static BOOL test_delayed_write_update2(struct smbcli_state *cli, TALLOC_CTX *mem
        const char *fname = BASEDIR "\\torture_file.txt";
        NTSTATUS status;
        int fnum1 = -1;
+       int fnum2 = -1;
        BOOL ret = True;
        ssize_t written;
        time_t t;
-       struct smb_flush flsh;
+       union smb_flush flsh;
 
        printf("Testing delayed update of write time using 2 connections\n");
 
@@ -143,7 +148,7 @@ static BOOL test_delayed_write_update2(struct smbcli_state *cli, TALLOC_CTX *mem
        }
 
        finfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO;
-       finfo1.basic_info.in.fnum = fnum1;
+       finfo1.basic_info.file.fnum = fnum1;
        finfo2 = finfo1;
 
        status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo1);
@@ -190,7 +195,7 @@ static BOOL test_delayed_write_update2(struct smbcli_state *cli, TALLOC_CTX *mem
        t = time(NULL);
 
        while (time(NULL) < t+120) {
-               finfo2.basic_info.in.fname = fname;
+               finfo2.basic_info.file.path = fname;
        
                status = smb_raw_pathinfo(cli2->tree, mem_ctx, &finfo2);
 
@@ -218,7 +223,7 @@ static BOOL test_delayed_write_update2(struct smbcli_state *cli, TALLOC_CTX *mem
        /* Now try a write to see if the write time gets reset. */
 
        finfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO;
-       finfo1.basic_info.in.fnum = fnum1;
+       finfo1.basic_info.file.fnum = fnum1;
        finfo2 = finfo1;
 
        status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo1);
@@ -237,7 +242,8 @@ static BOOL test_delayed_write_update2(struct smbcli_state *cli, TALLOC_CTX *mem
        written =  smbcli_write(cli->tree, fnum1, 0, "0123456789", 1, 10);
 
        if (written != 10) {
-               printf("write failed - wrote %d bytes (%s)\n", written, __location__);
+               printf("write failed - wrote %d bytes (%s)\n", 
+                      (int)written, __location__);
                return False;
        }
 
@@ -246,7 +252,7 @@ static BOOL test_delayed_write_update2(struct smbcli_state *cli, TALLOC_CTX *mem
 
        printf("Doing flush after write\n");
 
-       flsh.in.fnum = fnum1;
+       flsh.flush.file.fnum = fnum1;
        status = smb_raw_flush(cli->tree, &flsh);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("smbflush failed: %s\n", nt_errstr(status)));
@@ -258,7 +264,7 @@ static BOOL test_delayed_write_update2(struct smbcli_state *cli, TALLOC_CTX *mem
        /* Once the time was set using setfileinfo then it stays set - writes
           don't have any effect. But make sure. */
 
-       while (time(NULL) < t+40) {
+       while (time(NULL) < t+15) {
                status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo2);
 
                if (!NT_STATUS_IS_OK(status)) {
@@ -278,9 +284,174 @@ static BOOL test_delayed_write_update2(struct smbcli_state *cli, TALLOC_CTX *mem
        }
        
        if (finfo1.basic_info.out.write_time == finfo2.basic_info.out.write_time) {
-               printf("Server did not update write time?!\n");
+               printf("Server did not update write time\n");
+       }
+
+       fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
+       if (fnum2 == -1) {
+               printf("Failed to open %s\n", fname);
+               return False;
+       }
+       
+       printf("Doing a 10 byte write to extend the file via second fd and see if this changes the last write time.\n");
+
+       written =  smbcli_write(cli->tree, fnum2, 0, "0123456789", 11, 10);
+
+       if (written != 10) {
+               printf("write failed - wrote %d bytes (%s)\n", 
+                      (int)written, __location__);
+               return False;
+       }
+
+       status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo2);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
+               return False;
+       }
+       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\n");
+       }
+
+       printf("Closing the first fd to see if write time updated.\n");
+       smbcli_close(cli->tree, fnum1);
+       fnum1 = -1;
+
+       printf("Doing a 10 byte write to extend the file via second fd and see if this changes the last write time.\n");
+
+       written =  smbcli_write(cli->tree, fnum2, 0, "0123456789", 21, 10);
+
+       if (written != 10) {
+               printf("write failed - wrote %d bytes (%s)\n", 
+                      (int)written, __location__);
+               return False;
+       }
+
+       finfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO;
+       finfo1.basic_info.file.fnum = fnum2;
+       finfo2 = finfo1;
+       status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo2);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
+               return False;
+       }
+       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\n");
        }
 
+       t = time(NULL);
+
+       /* Once the time was set using setfileinfo then it stays set - writes
+          don't have any effect. But make sure. */
+
+       while (time(NULL) < t+15) {
+               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");
+       }
+
+       printf("Closing both fd's to see if write time updated.\n");
+
+       smbcli_close(cli->tree, fnum2);
+       fnum2 = -1;
+
+       fnum1 = smbcli_open(cli->tree, fname, O_RDWR, 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.file.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("Second open initial write time %s\n", 
+              nt_time_string(mem_ctx, finfo1.basic_info.out.write_time));
+
+       sleep(10);
+       printf("Doing a 10 byte write to extend the file to see if this changes the last write time.\n");
+
+       written =  smbcli_write(cli->tree, fnum1, 0, "0123456789", 31, 10);
+
+       if (written != 10) {
+               printf("write failed - wrote %d bytes (%s)\n", 
+                      (int)written, __location__);
+               return False;
+       }
+
+       finfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO;
+       finfo1.basic_info.file.fnum = fnum1;
+       finfo2 = finfo1;
+       status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo2);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
+               return False;
+       }
+       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\n");
+       }
+
+       t = time(NULL);
+
+       /* Once the time was set using setfileinfo then it stays set - writes
+          don't have any effect. But make sure. */
+
+       while (time(NULL) < t+15) {
+               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");
+       }
+
+
        /* One more test to do. We should read the filetime via findfirst on the
           second connection to ensure it's the same. This is very easy for a Windows
           server but a bastard to get right on a POSIX server. JRA. */
@@ -331,7 +502,7 @@ static BOOL test_finfo_after_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx
        }
 
        finfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO;
-       finfo1.basic_info.in.fnum = fnum1;
+       finfo1.basic_info.file.fnum = fnum1;
 
        status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo1);
 
@@ -347,7 +518,7 @@ static BOOL test_finfo_after_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx
 
        if (written != 1) {
                printf("(%s) written gave %d - should have been 1\n", 
-                      __location__, written);
+                      __location__, (int)written);
                ret = False;
                goto done;
        }
@@ -368,13 +539,13 @@ static BOOL test_finfo_after_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx
        
        if (written != 1) {
                printf("(%s) written gave %d - should have been 1\n", 
-                      __location__, written);
+                      __location__, (int)written);
                ret = False;
                goto done;
        }
        
        finfo2.basic_info.level = RAW_FILEINFO_BASIC_INFO;
-       finfo2.basic_info.in.fname = fname;
+       finfo2.basic_info.file.path = fname;
        
        status = smb_raw_pathinfo(cli2->tree, mem_ctx, &finfo2);
        
@@ -402,6 +573,9 @@ static BOOL test_finfo_after_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx
        if (finfo1.basic_info.out.write_time !=
            finfo2.basic_info.out.write_time) {
                printf("(%s) write_time changed\n", __location__);
+               printf("write time conn 1 = %s, conn 2 = %s\n", 
+                      nt_time_string(mem_ctx, finfo1.basic_info.out.write_time),
+                      nt_time_string(mem_ctx, finfo2.basic_info.out.write_time));
                ret = False;
                goto done;
        }
@@ -424,7 +598,7 @@ static BOOL test_finfo_after_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx
 
        /* This call is only for the people looking at ethereal :-) */
        finfo2.basic_info.level = RAW_FILEINFO_BASIC_INFO;
-       finfo2.basic_info.in.fname = fname;
+       finfo2.basic_info.file.path = fname;
 
        status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo2);
 
@@ -467,6 +641,6 @@ BOOL torture_delay_write(void)
        ret &= test_delayed_write_update2(cli, mem_ctx);
 
        torture_close_connection(cli);
-       talloc_destroy(mem_ctx);
+       talloc_free(mem_ctx);
        return ret;
 }