RIP BOOL. Convert BOOL -> bool. I found a few interesting
[nivanova/samba-autobuild/.git] / source3 / torture / torture.c
index 840b6ad2947a26e77da71cd3a48829e57d638888..d68421623294780d15c8907af1ff7eab722e0474 100644 (file)
@@ -5,7 +5,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/>.
 */
 
-#define NO_SYSLOG
-
 #include "includes.h"
 
+extern char *optarg;
+extern int optind;
+
 static fstring host, workgroup, share, password, username, myname;
 static int max_protocol = PROTOCOL_NT1;
 static const char *sockops="TCP_NODELAY";
@@ -31,26 +31,29 @@ int torture_numops=100;
 static int procnum; /* records process count number when forking */
 static struct cli_state *current_cli;
 static fstring randomfname;
-static BOOL use_oplocks;
-static BOOL use_level_II_oplocks;
+static bool use_oplocks;
+static bool use_level_II_oplocks;
 static const char *client_txt = "client_oplocks.txt";
-static BOOL use_kerberos;
+static bool use_kerberos;
+static fstring multishare_conn_fname;
+static bool use_multishare_conn = False;
 
-BOOL torture_showall = False;
+bool torture_showall = False;
 
-static double create_procs(BOOL (*fn)(int), BOOL *result);
+static double create_procs(bool (*fn)(int), bool *result);
 
 
 static struct timeval tp1,tp2;
 
+
 void start_timer(void)
 {
-       gettimeofday(&tp1,NULL);
+       GetTimeOfDay(&tp1);
 }
 
 double end_timer(void)
 {
-       gettimeofday(&tp2,NULL);
+       GetTimeOfDay(&tp2);
        return((tp2.tv_sec - tp1.tv_sec) + 
               (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
 }
@@ -70,7 +73,7 @@ void *shm_setup(int size)
        int shmid;
        void *ret;
 
-       shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
+       shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
        if (shmid == -1) {
                printf("can't get shared memory\n");
                exit(1);
@@ -93,28 +96,29 @@ void *shm_setup(int size)
 }
 
 
-static BOOL open_nbt_connection(struct cli_state *c)
+static struct cli_state *open_nbt_connection(void)
 {
        struct nmb_name called, calling;
        struct in_addr ip;
-
-       ZERO_STRUCTP(c);
+       struct cli_state *c;
+       NTSTATUS status;
 
        make_nmb_name(&calling, myname, 0x0);
        make_nmb_name(&called , host, 0x20);
 
-        zero_ip(&ip);
+        zero_ip_v4(&ip);
 
-       if (!cli_initialise(c)) {
+       if (!(c = cli_initialise())) {
                printf("Failed initialize cli_struct to connect with %s\n", host);
-               return False;
+               return NULL;
        }
 
        c->port = port_to_use;
 
-       if (!cli_connect(c, host, &ip)) {
-               printf("Failed to connect with %s\n", host);
-               return False;
+       status = cli_connect(c, host, &ip);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
+               return NULL;
        }
 
        c->use_kerberos = use_kerberos;
@@ -128,9 +132,10 @@ static BOOL open_nbt_connection(struct cli_state *c)
                 * Well, that failed, try *SMBSERVER ... 
                 * However, we must reconnect as well ...
                 */
-               if (!cli_connect(c, host, &ip)) {
-                       printf("Failed to connect with %s\n", host);
-                       return False;
+               status = cli_connect(c, host, &ip);
+               if (!NT_STATUS_IS_OK(status)) {
+                       printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
+                       return NULL;
                }
 
                make_nmb_name(&called, "*SMBSERVER", 0x20);
@@ -139,28 +144,90 @@ static BOOL open_nbt_connection(struct cli_state *c)
                        printf("We tried with a called name of %s & %s\n",
                                host, "*SMBSERVER");
                        cli_shutdown(c);
-                       return False;
+                       return NULL;
                }
        }
 
-       return True;
+       return c;
+}
+
+/* Insert a NULL at the first separator of the given path and return a pointer
+ * to the remainder of the string.
+ */
+static char *
+terminate_path_at_separator(char * path)
+{
+       char * p;
+
+       if (!path) {
+               return NULL;
+       }
+
+       if ((p = strchr_m(path, '/'))) {
+               *p = '\0';
+               return p + 1;
+       }
+
+       if ((p = strchr_m(path, '\\'))) {
+               *p = '\0';
+               return p + 1;
+       }
+       
+       /* No separator. */
+       return NULL;
 }
 
-BOOL torture_open_connection(struct cli_state **c)
+/*
+  parse a //server/share type UNC name
+*/
+bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
+                     char **hostname, char **sharename)
 {
-       BOOL retry;
+       char *p;
+
+       *hostname = *sharename = NULL;
+
+       if (strncmp(unc_name, "\\\\", 2) &&
+           strncmp(unc_name, "//", 2)) {
+               return False;
+       }
+
+       *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
+       p = terminate_path_at_separator(*hostname);
+
+       if (p && *p) {
+               *sharename = talloc_strdup(mem_ctx, p);
+               terminate_path_at_separator(*sharename);
+       }
+
+       if (*hostname && *sharename) {
+               return True;
+       }
+
+       TALLOC_FREE(*hostname);
+       TALLOC_FREE(*sharename);
+       return False;
+}
+
+static bool torture_open_connection_share(struct cli_state **c,
+                                  const char *hostname, 
+                                  const char *sharename)
+{
+       bool retry;
        int flags = 0;
        NTSTATUS status;
 
        if (use_kerberos)
                flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
-       
+
        status = cli_full_connection(c, myname,
-                                    host, NULL, port_to_use, 
-                                    share, "?????", 
+                                    hostname, NULL, port_to_use, 
+                                    sharename, "?????", 
                                     username, workgroup, 
-                                    password, flags, &retry);
+                                    password, flags, Undefined, &retry);
        if (!NT_STATUS_IS_OK(status)) {
+               printf("failed to open share connection: //%s/%s port:%d - %s\n",
+                       hostname, sharename, port_to_use, nt_errstr(status));
                return False;
        }
 
@@ -171,16 +238,60 @@ BOOL torture_open_connection(struct cli_state **c)
        return True;
 }
 
-BOOL torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
+void torture_open_connection_free_unclist(char **unc_list)
+{
+       if (unc_list!=NULL)
+       {
+               SAFE_FREE(unc_list[0]);
+               SAFE_FREE(unc_list);
+       }
+}
+
+bool torture_open_connection(struct cli_state **c, int conn_index)
+{
+       char **unc_list = NULL;
+       int num_unc_names = 0;
+       bool result;
+
+       if (use_multishare_conn==True) {
+               char *h, *s;
+               unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0);
+               if (!unc_list || num_unc_names <= 0) {
+                       printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
+                       exit(1);
+               }
+
+               if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
+                                     NULL, &h, &s)) {
+                       printf("Failed to parse UNC name %s\n",
+                              unc_list[conn_index % num_unc_names]);
+                       torture_open_connection_free_unclist(unc_list);
+                       exit(1);
+               }
+
+               result = torture_open_connection_share(c, h, s);
+
+               /* h, s were copied earlier */
+               torture_open_connection_free_unclist(unc_list);
+               return result;
+       }
+
+       return torture_open_connection_share(c, host, share);
+}
+
+bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
 {
        uint16 old_vuid = cli->vuid;
        fstring old_user_name;
        size_t passlen = strlen(password);
-       BOOL ret;
+       bool ret;
 
        fstrcpy(old_user_name, cli->user_name);
        cli->vuid = 0;
-       ret = cli_session_setup(cli, username, password, passlen, password, passlen, workgroup);
+       ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
+                                               password, passlen,
+                                               password, passlen,
+                                               workgroup));
        *new_vuid = cli->vuid;
        cli->vuid = old_vuid;
        fstrcpy(cli->user_name, old_user_name);
@@ -188,9 +299,9 @@ BOOL torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
 }
 
 
-BOOL torture_close_connection(struct cli_state *c)
+bool torture_close_connection(struct cli_state *c)
 {
-       BOOL ret = True;
+       bool ret = True;
        if (!cli_tdis(c)) {
                printf("tdis failed (%s)\n", cli_errstr(c));
                ret = False;
@@ -203,20 +314,20 @@ BOOL torture_close_connection(struct cli_state *c)
 
 
 /* check if the server produced the expected error code */
-static BOOL check_error(int line, struct cli_state *c, 
+static bool check_error(int line, struct cli_state *c, 
                        uint8 eclass, uint32 ecode, NTSTATUS nterr)
 {
         if (cli_is_dos_error(c)) {
-                uint8 class;
+                uint8 cclass;
                 uint32 num;
 
                 /* Check DOS error */
 
-                cli_dos_error(c, &class, &num);
+                cli_dos_error(c, &cclass, &num);
 
-                if (eclass != class || ecode != num) {
+                if (eclass != cclass || ecode != num) {
                         printf("unexpected error code class=%d code=%d\n", 
-                               (int)class, (int)num);
+                               (int)cclass, (int)num);
                         printf(" expected %d/%d %s (line=%d)\n", 
                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
                         return False;
@@ -240,7 +351,7 @@ static BOOL check_error(int line, struct cli_state *c,
 }
 
 
-static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
+static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
 {
        while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
                if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
@@ -249,7 +360,7 @@ static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
 }
 
 
-static BOOL rw_torture(struct cli_state *c)
+static bool rw_torture(struct cli_state *c)
 {
        const char *lockfname = "\\torture.lck";
        fstring fname;
@@ -258,7 +369,9 @@ static BOOL rw_torture(struct cli_state *c)
        pid_t pid2, pid = getpid();
        int i, j;
        char buf[1024];
-       BOOL correct = True;
+       bool correct = True;
+
+       memset(buf, '\0', sizeof(buf));
 
        fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
                         DENY_NONE);
@@ -338,10 +451,10 @@ static BOOL rw_torture(struct cli_state *c)
        return correct;
 }
 
-static BOOL run_torture(int dummy)
+static bool run_torture(int dummy)
 {
        struct cli_state *cli;
-        BOOL ret;
+        bool ret;
 
        cli = current_cli;
 
@@ -356,7 +469,7 @@ static BOOL run_torture(int dummy)
        return ret;
 }
 
-static BOOL rw_torture3(struct cli_state *c, char *lockfname)
+static bool rw_torture3(struct cli_state *c, char *lockfname)
 {
        int fnum = -1;
        unsigned int i = 0;
@@ -365,7 +478,7 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname)
        unsigned count;
        unsigned countprev = 0;
        ssize_t sent = 0;
-       BOOL correct = True;
+       bool correct = True;
 
        srandom(1);
        for (i = 0; i < sizeof(buf); i += sizeof(uint32))
@@ -389,7 +502,7 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname)
                {
                        fnum = cli_open(c, lockfname, O_RDONLY, 
                                         DENY_NONE);
-                       msleep(10);
+                       smb_msleep(10);
                }
                if (fnum == -1) {
                        printf("second open read-only of %s failed (%s)\n",
@@ -427,9 +540,9 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname)
                                                  sizeof(buf)-count);
                        if (sent < 0)
                        {
-                               printf("read failed offset:%d size:%d (%s)\n",
-                                               count, sizeof(buf)-count,
-                                               cli_errstr(c));
+                               printf("read failed offset:%d size:%ld (%s)\n",
+                                      count, (unsigned long)sizeof(buf)-count,
+                                      cli_errstr(c));
                                correct = False;
                                sent = 0;
                        }
@@ -438,8 +551,7 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname)
                                if (memcmp(buf_rd+count, buf+count, sent) != 0)
                                {
                                        printf("read/write compare failed\n");
-                                       printf("offset: %d req %d recvd %d\n",
-                                               count, sizeof(buf)-count, sent);
+                                       printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
                                        correct = False;
                                        break;
                                }
@@ -456,15 +568,15 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname)
        return correct;
 }
 
-static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
+static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
 {
        const char *lockfname = "\\torture2.lck";
        int fnum1;
        int fnum2;
        int i;
-       uchar buf[131072];
-       uchar buf_rd[131072];
-       BOOL correct = True;
+       char buf[131072];
+       char buf_rd[131072];
+       bool correct = True;
        ssize_t bytes_read;
 
        if (!cli_unlink(c1, lockfname)) {
@@ -494,7 +606,7 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
                        printf("%d\r", i); fflush(stdout);
                }
 
-               generate_random_buffer(buf, buf_size, False);
+               generate_random_buffer((unsigned char *)buf, buf_size);
 
                if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
                        printf("write failed (%s)\n", cli_errstr(c1));
@@ -504,7 +616,8 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
 
                if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
                        printf("read failed (%s)\n", cli_errstr(c2));
-                       printf("read %d, expected %d\n", bytes_read, buf_size); 
+                       printf("read %d, expected %ld\n", (int)bytes_read, 
+                              (unsigned long)buf_size); 
                        correct = False;
                        break;
                }
@@ -534,12 +647,12 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
        return correct;
 }
 
-static BOOL run_readwritetest(int dummy)
+static bool run_readwritetest(int dummy)
 {
        static struct cli_state *cli1, *cli2;
-       BOOL test1, test2;
+       bool test1, test2 = False;
 
-       if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
                return False;
        }
        cli_sockopt(cli1, sockops);
@@ -566,10 +679,10 @@ static BOOL run_readwritetest(int dummy)
        return (test1 && test2);
 }
 
-static BOOL run_readwritemulti(int dummy)
+static bool run_readwritemulti(int dummy)
 {
        struct cli_state *cli;
-       BOOL test;
+       bool test;
 
        cli = current_cli;
 
@@ -585,16 +698,16 @@ static BOOL run_readwritemulti(int dummy)
        return test;
 }
 
-static BOOL run_readwritelarge(int dummy)
+static bool run_readwritelarge(int dummy)
 {
        static struct cli_state *cli1;
        int fnum1;
        const char *lockfname = "\\large.dat";
-       size_t fsize;
+       SMB_OFF_T fsize;
        char buf[126*1024];
-       BOOL correct = True;
+       bool correct = True;
  
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
        cli_sockopt(cli1, sockops);
@@ -620,9 +733,11 @@ static BOOL run_readwritelarge(int dummy)
        }
 
        if (fsize == sizeof(buf))
-               printf("readwritelarge test 1 succeeded (size = %x)\n", fsize);
+               printf("readwritelarge test 1 succeeded (size = %lx)\n", 
+                      (unsigned long)fsize);
        else {
-               printf("readwritelarge test 1 failed (size = %x)\n", fsize);
+               printf("readwritelarge test 1 failed (size = %lx)\n", 
+                      (unsigned long)fsize);
                correct = False;
        }
 
@@ -652,9 +767,11 @@ static BOOL run_readwritelarge(int dummy)
        }
 
        if (fsize == sizeof(buf))
-               printf("readwritelarge test 2 succeeded (size = %x)\n", fsize);
+               printf("readwritelarge test 2 succeeded (size = %lx)\n", 
+                      (unsigned long)fsize);
        else {
-               printf("readwritelarge test 2 failed (size = %x)\n", fsize);
+               printf("readwritelarge test 2 failed (size = %lx)\n", 
+                      (unsigned long)fsize);
                correct = False;
        }
 
@@ -689,16 +806,15 @@ int nbio_id;
 #define ival(s) strtol(s, NULL, 0)
 
 /* run a test that simulates an approximate netbench client load */
-static BOOL run_netbench(int client)
+static bool run_netbench(int client)
 {
        struct cli_state *cli;
        int i;
-       fstring fname;
        pstring line;
        char cname[20];
        FILE *f;
        const char *params[20];
-       BOOL correct = True;
+       bool correct = True;
 
        cli = current_cli;
 
@@ -708,7 +824,7 @@ static BOOL run_netbench(int client)
 
        nb_setup(cli);
 
-       slprintf(cname,sizeof(fname), "client%d", client);
+       slprintf(cname,sizeof(cname)-1, "client%d", client);
 
        f = fopen(client_txt, "r");
 
@@ -787,10 +903,10 @@ static BOOL run_netbench(int client)
 
 
 /* run a test that simulates an approximate netbench client load */
-static BOOL run_nbench(int dummy)
+static bool run_nbench(int dummy)
 {
        double t;
-       BOOL correct = True;
+       bool correct = True;
 
        nbio_shmem(nprocs);
 
@@ -814,7 +930,7 @@ static BOOL run_nbench(int dummy)
      must not use posix semantics)
   2) support for lock timeouts
  */
-static BOOL run_locktest1(int dummy)
+static bool run_locktest1(int dummy)
 {
        struct cli_state *cli1, *cli2;
        const char *fname = "\\lockt1.lck";
@@ -822,7 +938,7 @@ static BOOL run_locktest1(int dummy)
        time_t t1, t2;
        unsigned lock_timeout;
 
-       if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
                return False;
        }
        cli_sockopt(cli1, sockops);
@@ -875,9 +991,10 @@ static BOOL run_locktest1(int dummy)
        }
        t2 = time(NULL);
 
-       if (t2 - t1 < 5) {
+       if (ABS(t2 - t1) < lock_timeout-1) {
                printf("error: This server appears not to support timed lock requests\n");
        }
+
        printf("server slept for %u seconds for a %u second timeout\n",
               (unsigned int)(t2-t1), lock_timeout);
 
@@ -926,7 +1043,7 @@ static BOOL run_locktest1(int dummy)
   this checks to see if a secondary tconx can use open files from an
   earlier tconx
  */
-static BOOL run_tcon_test(int dummy)
+static bool run_tcon_test(int dummy)
 {
        static struct cli_state *cli;
        const char *fname = "\\tcontest.tmp";
@@ -934,9 +1051,11 @@ static BOOL run_tcon_test(int dummy)
        uint16 cnum1, cnum2, cnum3;
        uint16 vuid1, vuid2;
        char buf[4];
-       BOOL ret = True;
+       bool ret = True;
 
-       if (!torture_open_connection(&cli)) {
+       memset(buf, '\0', sizeof(buf));
+
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
        cli_sockopt(cli, sockops);
@@ -1031,14 +1150,14 @@ static BOOL run_tcon_test(int dummy)
 /*
  checks for old style tcon support
  */
-static BOOL run_tcon2_test(int dummy)
+static bool run_tcon2_test(int dummy)
 {
        static struct cli_state *cli;
        uint16 cnum, max_xmit;
        char *service;
        NTSTATUS status;
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
        cli_sockopt(cli, sockops);
@@ -1064,13 +1183,13 @@ static BOOL run_tcon2_test(int dummy)
        return True;
 }
 
-static BOOL tcon_devtest(struct cli_state *cli,
+static bool tcon_devtest(struct cli_state *cli,
                         const char *myshare, const char *devtype,
                         const char *return_devtype,
                         NTSTATUS expected_error)
 {
-       BOOL status;
-       BOOL ret;
+       bool status;
+       bool ret;
 
        status = cli_send_tconX(cli, myshare, devtype,
                                password, strlen(password)+1);
@@ -1115,19 +1234,19 @@ static BOOL tcon_devtest(struct cli_state *cli,
 /*
  checks for correct tconX support
  */
-static BOOL run_tcon_devtype_test(int dummy)
+static bool run_tcon_devtype_test(int dummy)
 {
        static struct cli_state *cli1 = NULL;
-       BOOL retry;
+       bool retry;
        int flags = 0;
        NTSTATUS status;
-       BOOL ret;
+       bool ret = True;
 
        status = cli_full_connection(&cli1, myname,
                                     host, NULL, port_to_use,
                                     NULL, NULL,
                                     username, workgroup,
-                                    password, flags, &retry);
+                                    password, flags, Undefined, &retry);
 
        if (!NT_STATUS_IS_OK(status)) {
                printf("could not open connection\n");
@@ -1184,14 +1303,14 @@ static BOOL run_tcon_devtype_test(int dummy)
 
   3) the server denies unlock requests by an incorrect client PID
 */
-static BOOL run_locktest2(int dummy)
+static bool run_locktest2(int dummy)
 {
        static struct cli_state *cli;
        const char *fname = "\\lockt2.lck";
        int fnum1, fnum2, fnum3;
-       BOOL correct = True;
+       bool correct = True;
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
@@ -1320,17 +1439,17 @@ static BOOL run_locktest2(int dummy)
 
   1) the server supports the full offset range in lock requests
 */
-static BOOL run_locktest3(int dummy)
+static bool run_locktest3(int dummy)
 {
        static struct cli_state *cli1, *cli2;
        const char *fname = "\\lockt3.lck";
        int fnum1, fnum2, i;
        uint32 offset;
-       BOOL correct = True;
+       bool correct = True;
 
 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
 
-       if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
                return False;
        }
        cli_sockopt(cli1, sockops);
@@ -1445,16 +1564,16 @@ static BOOL run_locktest3(int dummy)
 /*
   looks at overlapping locks
 */
-static BOOL run_locktest4(int dummy)
+static bool run_locktest4(int dummy)
 {
        static struct cli_state *cli1, *cli2;
        const char *fname = "\\lockt4.lck";
        int fnum1, fnum2, f;
-       BOOL ret;
+       bool ret;
        char buf[1000];
-       BOOL correct = True;
+       bool correct = True;
 
-       if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
                return False;
        }
 
@@ -1616,16 +1735,16 @@ static BOOL run_locktest4(int dummy)
 /*
   looks at lock upgrade/downgrade.
 */
-static BOOL run_locktest5(int dummy)
+static bool run_locktest5(int dummy)
 {
        static struct cli_state *cli1, *cli2;
        const char *fname = "\\lockt5.lck";
        int fnum1, fnum2, fnum3;
-       BOOL ret;
+       bool ret;
        char buf[1000];
-       BOOL correct = True;
+       bool correct = True;
 
-       if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
                return False;
        }
 
@@ -1740,7 +1859,7 @@ static BOOL run_locktest5(int dummy)
 /*
   tries the unusual lockingX locktype bits
 */
-static BOOL run_locktest6(int dummy)
+static bool run_locktest6(int dummy)
 {
        static struct cli_state *cli;
        const char *fname[1] = { "\\lock6.txt" };
@@ -1748,7 +1867,7 @@ static BOOL run_locktest6(int dummy)
        int fnum;
        NTSTATUS status;
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
@@ -1780,15 +1899,15 @@ static BOOL run_locktest6(int dummy)
        return True;
 }
 
-static BOOL run_locktest7(int dummy)
+static bool run_locktest7(int dummy)
 {
        struct cli_state *cli1;
        const char *fname = "\\lockt7.lck";
        int fnum1;
        char buf[200];
-       BOOL correct = False;
+       bool correct = False;
 
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
 
@@ -1917,14 +2036,14 @@ fail:
 test whether fnums and tids open on one VC are available on another (a major
 security hole)
 */
-static BOOL run_fdpasstest(int dummy)
+static bool run_fdpasstest(int dummy)
 {
        struct cli_state *cli1, *cli2;
        const char *fname = "\\fdpass.tst";
        int fnum1;
        pstring buf;
 
-       if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
                return False;
        }
        cli_sockopt(cli1, sockops);
@@ -1965,7 +2084,7 @@ static BOOL run_fdpasstest(int dummy)
        return True;
 }
 
-static BOOL run_fdsesstest(int dummy)
+static bool run_fdsesstest(int dummy)
 {
        struct cli_state *cli;
        uint16 new_vuid;
@@ -1977,9 +2096,9 @@ static BOOL run_fdsesstest(int dummy)
        int fnum1;
        int fnum2;
        pstring buf;
-       BOOL ret = True;
+       bool ret = True;
 
-       if (!torture_open_connection(&cli))
+       if (!torture_open_connection(&cli, 0))
                return False;
        cli_sockopt(cli, sockops);
 
@@ -2054,14 +2173,14 @@ static BOOL run_fdsesstest(int dummy)
 
   1) the server does not allow an unlink on a file that is open
 */
-static BOOL run_unlinktest(int dummy)
+static bool run_unlinktest(int dummy)
 {
        struct cli_state *cli;
        const char *fname = "\\unlink.tst";
        int fnum;
-       BOOL correct = True;
+       bool correct = True;
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
@@ -2103,14 +2222,14 @@ static BOOL run_unlinktest(int dummy)
 /*
 test how many open files this server supports on the one socket
 */
-static BOOL run_maxfidtest(int dummy)
+static bool run_maxfidtest(int dummy)
 {
        struct cli_state *cli;
-       const char *template = "\\maxfid.%d.%d";
+       const char *ftemplate = "\\maxfid.%d.%d";
        fstring fname;
        int fnums[0x11000], i;
        int retries=4;
-       BOOL correct = True;
+       bool correct = True;
 
        cli = current_cli;
 
@@ -2122,7 +2241,7 @@ static BOOL run_maxfidtest(int dummy)
        cli_sockopt(cli, sockops);
 
        for (i=0; i<0x11000; i++) {
-               slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
+               slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
                if ((fnums[i] = cli_open(cli, fname, 
                                        O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
                    -1) {
@@ -2138,7 +2257,7 @@ static BOOL run_maxfidtest(int dummy)
 
        printf("cleaning up\n");
        for (;i>=0;i--) {
-               slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
+               slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
                cli_close(cli, fnums[i]);
                if (!cli_unlink(cli, fname)) {
                        printf("unlink of %s failed (%s)\n", 
@@ -2166,23 +2285,23 @@ static void rand_buf(char *buf, int len)
 }
 
 /* send smb negprot commands, not reading the response */
-static BOOL run_negprot_nowait(int dummy)
+static bool run_negprot_nowait(int dummy)
 {
        int i;
-       static struct cli_state cli;
-       BOOL correct = True;
+       static struct cli_state *cli;
+       bool correct = True;
 
        printf("starting negprot nowait test\n");
 
-       if (!open_nbt_connection(&cli)) {
+       if (!(cli = open_nbt_connection())) {
                return False;
        }
 
        for (i=0;i<50000;i++) {
-               cli_negprot_send(&cli);
+               cli_negprot_send(cli);
        }
 
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                correct = False;
        }
 
@@ -2193,20 +2312,20 @@ static BOOL run_negprot_nowait(int dummy)
 
 
 /* send random IPC commands */
-static BOOL run_randomipc(int dummy)
+static bool run_randomipc(int dummy)
 {
        char *rparam = NULL;
        char *rdata = NULL;
-       int rdrcnt,rprcnt;
+       unsigned int rdrcnt,rprcnt;
        pstring param;
        int api, param_len, i;
        struct cli_state *cli;
-       BOOL correct = True;
+       bool correct = True;
        int count = 50000;
 
        printf("starting random ipc test\n");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
@@ -2252,14 +2371,14 @@ static void browse_callback(const char *sname, uint32 stype,
   This test checks the browse list code
 
 */
-static BOOL run_browsetest(int dummy)
+static bool run_browsetest(int dummy)
 {
        static struct cli_state *cli;
-       BOOL correct = True;
+       bool correct = True;
 
        printf("starting browse test\n");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
@@ -2287,17 +2406,17 @@ static BOOL run_browsetest(int dummy)
 /*
   This checks how the getatr calls works
 */
-static BOOL run_attrtest(int dummy)
+static bool run_attrtest(int dummy)
 {
        struct cli_state *cli;
        int fnum;
        time_t t, t2;
        const char *fname = "\\attrib123456789.tst";
-       BOOL correct = True;
+       bool correct = True;
 
        printf("starting attrib test\n");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
@@ -2351,29 +2470,30 @@ static BOOL run_attrtest(int dummy)
 /*
   This checks a couple of trans2 calls
 */
-static BOOL run_trans2test(int dummy)
+static bool run_trans2test(int dummy)
 {
        struct cli_state *cli;
        int fnum;
-       size_t size;
-       time_t c_time, a_time, m_time, w_time, m_time2;
+       SMB_OFF_T size;
+       time_t c_time, a_time, m_time;
+       struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
        const char *fname = "\\trans2.tst";
        const char *dname = "\\trans2";
        const char *fname2 = "\\trans2\\trans2.tst";
        pstring pname;
-       BOOL correct = True;
+       bool correct = True;
 
        printf("starting trans2 test\n");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
        cli_unlink(cli, fname);
        fnum = cli_open(cli, fname, 
                        O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
-       if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
-                          NULL, NULL)) {
+       if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
+                          &m_time_ts, NULL)) {
                printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
                correct = False;
        }
@@ -2428,13 +2548,13 @@ static BOOL run_trans2test(int dummy)
        fnum = cli_open(cli, fname, 
                        O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
        cli_close(cli, fnum);
-       if (!cli_qpathinfo2(cli, fname, &c_time, &a_time, &m_time
-                           &w_time, &size, NULL, NULL)) {
+       if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts
+                           &m_time_ts, &size, NULL, NULL)) {
                printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
                correct = False;
        } else {
-               if (w_time < 60*60*24*2) {
-                       printf("write time=%s", ctime(&w_time));
+               if (w_time_ts.tv_sec < 60*60*24*2) {
+                       printf("write time=%s", ctime(&w_time_ts.tv_sec));
                        printf("This system appears to set a initial 0 write time\n");
                        correct = False;
                }
@@ -2450,8 +2570,8 @@ static BOOL run_trans2test(int dummy)
                correct = False;
        }
        sleep(3);
-       if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &m_time
-                           &w_time, &size, NULL, NULL)) {
+       if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts
+                           &m_time_ts, &size, NULL, NULL)) {
                printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
                correct = False;
        }
@@ -2460,12 +2580,13 @@ static BOOL run_trans2test(int dummy)
                        O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
        cli_write(cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
        cli_close(cli, fnum);
-       if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &m_time2
-                           &w_time, &size, NULL, NULL)) {
+       if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts
+                           &m_time2_ts, &size, NULL, NULL)) {
                printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
                correct = False;
        } else {
-               if (m_time2 == m_time) {
+               if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
+                   == 0) {
                        printf("This system does not update directory modification times\n");
                        correct = False;
                }
@@ -2486,35 +2607,35 @@ static BOOL run_trans2test(int dummy)
   This checks new W2K calls.
 */
 
-static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
+static bool new_trans(struct cli_state *pcli, int fnum, int level)
 {
-       char buf[4096];
-       BOOL correct = True;
-
-       memset(buf, 0xff, sizeof(buf));
+       char *buf = NULL;
+       uint32 len;
+       bool correct = True;
 
-       if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
+       if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
                printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
                correct = False;
        } else {
-               printf("qfileinfo: level %d\n", level);
-               dump_data(0, buf, 256);
+               printf("qfileinfo: level %d, len = %u\n", level, len);
+               dump_data(0, (uint8 *)buf, len);
                printf("\n");
        }
+       SAFE_FREE(buf);
        return correct;
 }
 
-static BOOL run_w2ktest(int dummy)
+static bool run_w2ktest(int dummy)
 {
        struct cli_state *cli;
        int fnum;
        const char *fname = "\\w2ktest\\w2k.tst";
        int level;
-       BOOL correct = True;
+       bool correct = True;
 
        printf("starting w2k test\n");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
@@ -2540,16 +2661,16 @@ static BOOL run_w2ktest(int dummy)
 /*
   this is a harness for some oplock tests
  */
-static BOOL run_oplock1(int dummy)
+static bool run_oplock1(int dummy)
 {
        struct cli_state *cli1;
        const char *fname = "\\lockt1.lck";
        int fnum1;
-       BOOL correct = True;
+       bool correct = True;
 
        printf("starting oplock test 1\n");
 
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
 
@@ -2589,17 +2710,17 @@ static BOOL run_oplock1(int dummy)
        return correct;
 }
 
-static BOOL run_oplock2(int dummy)
+static bool run_oplock2(int dummy)
 {
        struct cli_state *cli1, *cli2;
        const char *fname = "\\lockt2.lck";
        int fnum1, fnum2;
        int saved_use_oplocks = use_oplocks;
        char buf[4];
-       BOOL correct = True;
-       volatile BOOL *shared_correct;
+       bool correct = True;
+       volatile bool *shared_correct;
 
-       shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
+       shared_correct = (volatile bool *)shm_setup(sizeof(bool));
        *shared_correct = True;
 
        use_level_II_oplocks = True;
@@ -2607,7 +2728,7 @@ static BOOL run_oplock2(int dummy)
 
        printf("starting oplock test 2\n");
 
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                use_level_II_oplocks = False;
                use_oplocks = saved_use_oplocks;
                return False;
@@ -2616,7 +2737,7 @@ static BOOL run_oplock2(int dummy)
        cli1->use_oplocks = True;
        cli1->use_level_II_oplocks = True;
 
-       if (!torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli2, 1)) {
                use_level_II_oplocks = False;
                use_oplocks = saved_use_oplocks;
                return False;
@@ -2661,9 +2782,10 @@ static BOOL run_oplock2(int dummy)
 
        sleep(2);
 
-       /* Ensure cli1 processes the break. */
+       /* Ensure cli1 processes the break. Empty file should always return 0
+        * bytes.  */
 
-       if (cli_read(cli1, fnum1, buf, 0, 4) != 4) {
+       if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
                printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
@@ -2724,23 +2846,23 @@ static BOOL run_oplock2(int dummy)
 }
 
 /* handler for oplock 3 tests */
-static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
+static bool oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
 {
        printf("got oplock break fnum=%d level=%d\n",
               fnum, level);
        return cli_oplock_ack(cli, fnum, level);
 }
 
-static BOOL run_oplock3(int dummy)
+static bool run_oplock3(int dummy)
 {
        struct cli_state *cli;
        const char *fname = "\\oplockt3.dat";
        int fnum;
        char buf[4] = "abcd";
-       BOOL correct = True;
-       volatile BOOL *shared_correct;
+       bool correct = True;
+       volatile bool *shared_correct;
 
-       shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
+       shared_correct = (volatile bool *)shm_setup(sizeof(bool));
        *shared_correct = True;
 
        printf("starting oplock test 3\n");
@@ -2749,7 +2871,7 @@ static BOOL run_oplock3(int dummy)
                /* Child code */
                use_oplocks = True;
                use_level_II_oplocks = True;
-               if (!torture_open_connection(&cli)) {
+               if (!torture_open_connection(&cli, 0)) {
                        *shared_correct = False;
                        exit(0);
                } 
@@ -2763,7 +2885,7 @@ static BOOL run_oplock3(int dummy)
        /* parent code */
        use_oplocks = True;
        use_level_II_oplocks = True;
-       if (!torture_open_connection(&cli)) { 
+       if (!torture_open_connection(&cli, 1)) { /* other is forked */
                return False;
        }
        cli_oplock_handler(cli, oplock3_handler);
@@ -2785,18 +2907,18 @@ static BOOL run_oplock3(int dummy)
 /*
   Test delete on close semantics.
  */
-static BOOL run_deletetest(int dummy)
+static bool run_deletetest(int dummy)
 {
-       struct cli_state *cli1;
-       struct cli_state *cli2;
+       struct cli_state *cli1 = NULL;
+       struct cli_state *cli2 = NULL;
        const char *fname = "\\delete.file";
        int fnum1 = -1;
        int fnum2 = -1;
-       BOOL correct = True;
+       bool correct = True;
        
        printf("starting delete test\n");
        
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
        
@@ -2807,8 +2929,8 @@ static BOOL run_deletetest(int dummy)
        cli_setatr(cli1, fname, 0, 0);
        cli_unlink(cli1, fname);
        
-       fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 
+       fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                                  0, FILE_OVERWRITE_IF, 
                                   FILE_DELETE_ON_CLOSE, 0);
        
        if (fnum1 == -1) {
@@ -2816,7 +2938,18 @@ static BOOL run_deletetest(int dummy)
                correct = False;
                goto fail;
        }
-       
+
+#if 0 /* JRATEST */
+        {
+                uint32 *accinfo = NULL;
+                uint32 len;
+                cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
+               if (accinfo)
+                       printf("access mode = 0x%lx\n", *accinfo);
+                SAFE_FREE(accinfo);
+        }
+#endif
+
        if (!cli_close(cli1, fnum1)) {
                printf("[1] close failed (%s)\n", cli_errstr(cli1));
                correct = False;
@@ -3099,7 +3232,7 @@ static BOOL run_deletetest(int dummy)
        cli_setatr(cli1, fname, 0, 0);
        cli_unlink(cli1, fname);
        
-       if (!torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli2, 1)) {
                printf("[8] failed to open second connection.\n");
                correct = False;
                goto fail;
@@ -3112,7 +3245,7 @@ static BOOL run_deletetest(int dummy)
                                   FILE_OVERWRITE_IF, 0, 0);
        
        if (fnum1 == -1) {
-               printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
+               printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
                correct = False;
                goto fail;
        }
@@ -3122,7 +3255,7 @@ static BOOL run_deletetest(int dummy)
                                   FILE_OPEN, 0, 0);
        
        if (fnum2 == -1) {
-               printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
+               printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
                correct = False;
                goto fail;
        }
@@ -3189,6 +3322,49 @@ static BOOL run_deletetest(int dummy)
                correct = False;
        } else
                printf("tenth delete on close test succeeded.\n");
+
+       cli_setatr(cli1, fname, 0, 0);
+       cli_unlink(cli1, fname);
+
+       /* What error do we get when attempting to open a read-only file with
+          delete access ? */
+
+       /* Create a readonly file. */
+       fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
+                                  FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
+       if (fnum1 == -1) {
+               printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
+               correct = False;
+               goto fail;
+       }
+
+       if (!cli_close(cli1, fnum1)) {
+               printf("[11] close failed (%s)\n", cli_errstr(cli1));
+               correct = False;
+               goto fail;
+       }
+
+       /* Now try open for delete access. */
+       fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
+                                  0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+                                  FILE_OVERWRITE_IF, 0, 0);
+       
+       if (fnum1 != -1) {
+               printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
+               cli_close(cli1, fnum1);
+               goto fail;
+               correct = False;
+       } else {
+               NTSTATUS nterr = cli_nt_error(cli1);
+               if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
+                       printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
+                       goto fail;
+                       correct = False;
+               } else {
+                       printf("eleventh delete on close test succeeded.\n");
+               }
+       }
+       
        printf("finished delete test\n");
 
   fail:
@@ -3196,15 +3372,15 @@ static BOOL run_deletetest(int dummy)
         * intialized, because these functions don't handle
         * uninitialized connections. */
                
-       cli_close(cli1, fnum1);
-       cli_close(cli1, fnum2);
+       if (fnum1 != -1) cli_close(cli1, fnum1);
+       if (fnum2 != -1) cli_close(cli1, fnum2);
        cli_setatr(cli1, fname, 0, 0);
        cli_unlink(cli1, fname);
 
-       if (!torture_close_connection(cli1)) {
+       if (cli1 && !torture_close_connection(cli1)) {
                correct = False;
        }
-       if (!torture_close_connection(cli2)) {
+       if (cli2 && !torture_close_connection(cli2)) {
                correct = False;
        }
        return correct;
@@ -3214,16 +3390,16 @@ static BOOL run_deletetest(int dummy)
 /*
   print out server properties
  */
-static BOOL run_properties(int dummy)
+static bool run_properties(int dummy)
 {
        static struct cli_state *cli;
-       BOOL correct = True;
+       bool correct = True;
        
        printf("starting properties test\n");
        
        ZERO_STRUCT(cli);
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
        
@@ -3262,16 +3438,16 @@ static BOOL run_properties(int dummy)
 /*
   Test ntcreate calls made by xcopy
  */
-static BOOL run_xcopy(int dummy)
+static bool run_xcopy(int dummy)
 {
        static struct cli_state *cli1;
        const char *fname = "\\test.txt";
-       BOOL correct = True;
+       bool correct = True;
        int fnum1, fnum2;
 
        printf("starting xcopy test\n");
        
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
        
@@ -3304,17 +3480,17 @@ static BOOL run_xcopy(int dummy)
 /*
   Test rename on files open with share delete and no share delete.
  */
-static BOOL run_rename(int dummy)
+static bool run_rename(int dummy)
 {
        static struct cli_state *cli1;
        const char *fname = "\\test.txt";
        const char *fname1 = "\\test1.txt";
-       BOOL correct = True;
+       bool correct = True;
        int fnum1;
 
        printf("starting rename test\n");
        
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
        
@@ -3329,9 +3505,9 @@ static BOOL run_rename(int dummy)
        }
 
        if (!cli_rename(cli1, fname, fname1)) {
-               printf("First rename failed (this is correct) - %s\n", cli_errstr(cli1));
+               printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
        } else {
-               printf("First rename succeeded - this should have failed !\n");
+               printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
                correct = False;
        }
 
@@ -3355,10 +3531,10 @@ static BOOL run_rename(int dummy)
        }
 
        if (!cli_rename(cli1, fname, fname1)) {
-               printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(cli1));
+               printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
                correct = False;
        } else {
-               printf("Second rename succeeded\n");
+               printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
        }
 
        if (!cli_close(cli1, fnum1)) {
@@ -3402,10 +3578,10 @@ static BOOL run_rename(int dummy)
 #endif
 
        if (!cli_rename(cli1, fname, fname1)) {
-               printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(cli1));
+               printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
                correct = False;
        } else {
-               printf("Third rename succeeded\n");
+               printf("Third rename succeeded (SHARE_NONE)\n");
        }
 
        if (!cli_close(cli1, fnum1)) {
@@ -3416,6 +3592,75 @@ static BOOL run_rename(int dummy)
        cli_unlink(cli1, fname);
        cli_unlink(cli1, fname1);
 
+        /*----*/
+
+       fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
+
+       if (fnum1 == -1) {
+               printf("Fourth open failed - %s\n", cli_errstr(cli1));
+               return False;
+       }
+
+       if (!cli_rename(cli1, fname, fname1)) {
+               printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
+       } else {
+               printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
+               correct = False;
+       }
+
+       if (!cli_close(cli1, fnum1)) {
+               printf("close - 4 failed (%s)\n", cli_errstr(cli1));
+               return False;
+       }
+
+       cli_unlink(cli1, fname);
+       cli_unlink(cli1, fname1);
+
+        /*--*/
+
+       fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
+
+       if (fnum1 == -1) {
+               printf("Fifth open failed - %s\n", cli_errstr(cli1));
+               return False;
+       }
+
+       if (!cli_rename(cli1, fname, fname1)) {
+               printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have failed ! \n");
+               correct = False;
+       } else {
+               printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
+       }
+
+        /*
+         * Now check if the first name still exists ...
+         */
+
+        /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
+
+        if (fnum2 == -1) {
+          printf("Opening original file after rename of open file fails: %s\n",
+              cli_errstr(cli1));
+        }
+        else {
+          printf("Opening original file after rename of open file works ...\n");
+          (void)cli_close(cli1, fnum2);
+          } */
+
+        /*--*/
+
+
+       if (!cli_close(cli1, fnum1)) {
+               printf("close - 5 failed (%s)\n", cli_errstr(cli1));
+               return False;
+       }
+
+       cli_unlink(cli1, fname);
+       cli_unlink(cli1, fname1);
+        
        if (!torture_close_connection(cli1)) {
                correct = False;
        }
@@ -3423,7 +3668,7 @@ static BOOL run_rename(int dummy)
        return correct;
 }
 
-static BOOL run_pipe_number(int dummy)
+static bool run_pipe_number(int dummy)
 {
        struct cli_state *cli1;
        const char *pipe_name = "\\SPOOLSS";
@@ -3431,7 +3676,7 @@ static BOOL run_pipe_number(int dummy)
        int num_pipes = 0;
 
        printf("starting pipenumber test\n");
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
 
@@ -3445,6 +3690,7 @@ static BOOL run_pipe_number(int dummy)
                        break;
                }
                num_pipes++;
+               printf("\r%6d", num_pipes);
        }
 
        printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
@@ -3455,20 +3701,20 @@ static BOOL run_pipe_number(int dummy)
 /*
   Test open mode returns on read-only files.
  */
-static BOOL run_opentest(int dummy)
+static bool run_opentest(int dummy)
 {
        static struct cli_state *cli1;
        static struct cli_state *cli2;
        const char *fname = "\\readonly.file";
        int fnum1, fnum2;
        char buf[20];
-       size_t fsize;
-       BOOL correct = True;
+       SMB_OFF_T fsize;
+       bool correct = True;
        char *tmp_path;
 
        printf("starting open test\n");
        
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
        
@@ -3615,7 +3861,7 @@ static BOOL run_opentest(int dummy)
        
        /* Test the non-io opens... */
 
-       if (!torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli2, 1)) {
                return False;
        }
        
@@ -3905,18 +4151,18 @@ static struct trunc_open_results attr_results[] = {
        { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
 };
 
-static BOOL run_openattrtest(int dummy)
+static bool run_openattrtest(int dummy)
 {
        static struct cli_state *cli1;
        const char *fname = "\\openattr.file";
        int fnum1;
-       BOOL correct = True;
+       bool correct = True;
        uint16 attr;
        unsigned int i, j, k, l;
 
        printf("starting open attr test\n");
        
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
        
@@ -4010,7 +4256,7 @@ static BOOL run_openattrtest(int dummy)
        return correct;
 }
 
-static void list_fn(file_info *finfo, const char *name, void *state)
+static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
 {
        
 }
@@ -4018,17 +4264,17 @@ static void list_fn(file_info *finfo, const char *name, void *state)
 /*
   test directory listing speed
  */
-static BOOL run_dirtest(int dummy)
+static bool run_dirtest(int dummy)
 {
        int i;
        static struct cli_state *cli;
        int fnum;
        double t1;
-       BOOL correct = True;
+       bool correct = True;
 
        printf("starting directory test\n");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
@@ -4070,7 +4316,7 @@ static BOOL run_dirtest(int dummy)
        return correct;
 }
 
-static void del_fn(file_info *finfo, const char *mask, void *state)
+static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
 {
        struct cli_state *pcli = (struct cli_state *)state;
        fstring fname;
@@ -4092,7 +4338,7 @@ static void del_fn(file_info *finfo, const char *mask, void *state)
 /*
   sees what IOCTLs are supported
  */
-BOOL torture_ioctl_test(int dummy)
+bool torture_ioctl_test(int dummy)
 {
        static struct cli_state *cli;
        uint16 device, function;
@@ -4101,7 +4347,7 @@ BOOL torture_ioctl_test(int dummy)
        DATA_BLOB blob;
        NTSTATUS status;
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
@@ -4129,7 +4375,8 @@ BOOL torture_ioctl_test(int dummy)
                        status = cli_raw_ioctl(cli, fnum, code, &blob);
 
                        if (NT_STATUS_IS_OK(status)) {
-                               printf("ioctl 0x%x OK : %d bytes\n", code, blob.length);
+                               printf("ioctl 0x%x OK : %d bytes\n", (int)code,
+                                      (int)blob.length);
                                data_blob_free(&blob);
                        }
                }
@@ -4146,13 +4393,13 @@ BOOL torture_ioctl_test(int dummy)
 /*
   tries varients of chkpath
  */
-BOOL torture_chkpath_test(int dummy)
+bool torture_chkpath_test(int dummy)
 {
        static struct cli_state *cli;
        int fnum;
-       BOOL ret;
+       bool ret;
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
@@ -4225,19 +4472,136 @@ BOOL torture_chkpath_test(int dummy)
        return ret;
 }
 
+static bool run_eatest(int dummy)
+{
+       static struct cli_state *cli;
+       const char *fname = "\\eatest.txt";
+       bool correct = True;
+       int fnum, i;
+       size_t num_eas;
+       struct ea_struct *ea_list = NULL;
+       TALLOC_CTX *mem_ctx = talloc_init("eatest");
+
+       printf("starting eatest\n");
+       
+       if (!torture_open_connection(&cli, 0)) {
+               talloc_destroy(mem_ctx);
+               return False;
+       }
+       
+       cli_unlink(cli, fname);
+       fnum = cli_nt_create_full(cli, fname, 0,
+                                  FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
+                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
+                                  0x4044, 0);
+
+       if (fnum == -1) {
+               printf("open failed - %s\n", cli_errstr(cli));
+               talloc_destroy(mem_ctx);
+               return False;
+       }
+
+       for (i = 0; i < 10; i++) {
+               fstring ea_name, ea_val;
 
+               slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
+               memset(ea_val, (char)i+1, i+1);
+               if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
+                       printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
+                       talloc_destroy(mem_ctx);
+                       return False;
+               }
+       }
+       
+       cli_close(cli, fnum);
+       for (i = 0; i < 10; i++) {
+               fstring ea_name, ea_val;
+
+               slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
+               memset(ea_val, (char)i+1, i+1);
+               if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
+                       printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
+                       talloc_destroy(mem_ctx);
+                       return False;
+               }
+       }
+       
+       if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
+               printf("ea_get list failed - %s\n", cli_errstr(cli));
+               correct = False;
+       }
 
+       printf("num_eas = %d\n", (int)num_eas);
 
-static BOOL run_dirtest1(int dummy)
+       if (num_eas != 20) {
+               printf("Should be 20 EA's stored... failing.\n");
+               correct = False;
+       }
+
+       for (i = 0; i < num_eas; i++) {
+               printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
+               dump_data(0, ea_list[i].value.data,
+                         ea_list[i].value.length);
+       }
+
+       /* Setting EA's to zero length deletes them. Test this */
+       printf("Now deleting all EA's - case indepenent....\n");
+
+#if 1
+       cli_set_ea_path(cli, fname, "", "", 0);
+#else
+       for (i = 0; i < 20; i++) {
+               fstring ea_name;
+               slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
+               if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
+                       printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
+                       talloc_destroy(mem_ctx);
+                       return False;
+               }
+       }
+#endif
+
+       if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
+               printf("ea_get list failed - %s\n", cli_errstr(cli));
+               correct = False;
+       }
+
+       printf("num_eas = %d\n", (int)num_eas);
+       for (i = 0; i < num_eas; i++) {
+               printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
+               dump_data(0, ea_list[i].value.data,
+                         ea_list[i].value.length);
+       }
+
+       if (num_eas != 0) {
+               printf("deleting EA's failed.\n");
+               correct = False;
+       }
+
+       /* Try and delete a non existant EA. */
+       if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
+               printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
+               correct = False;
+       }
+
+       talloc_destroy(mem_ctx);
+       if (!torture_close_connection(cli)) {
+               correct = False;
+       }
+       
+       return correct;
+}
+
+static bool run_dirtest1(int dummy)
 {
        int i;
        static struct cli_state *cli;
        int fnum, num_seen;
-       BOOL correct = True;
+       bool correct = True;
 
        printf("starting directory test\n");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
@@ -4309,10 +4673,10 @@ static BOOL run_dirtest1(int dummy)
        return correct;
 }
 
-static BOOL run_error_map_extract(int dummy) {
+static bool run_error_map_extract(int dummy) {
        
-       static struct cli_state c_dos;
-       static struct cli_state c_nt;
+       static struct cli_state *c_dos;
+       static struct cli_state *c_nt;
 
        uint32 error;
 
@@ -4325,81 +4689,81 @@ static BOOL run_error_map_extract(int dummy) {
 
        /* NT-Error connection */
 
-       if (!open_nbt_connection(&c_nt)) {
+       if (!(c_nt = open_nbt_connection())) {
                return False;
        }
 
-       c_nt.use_spnego = False;
+       c_nt->use_spnego = False;
 
-       if (!cli_negprot(&c_nt)) {
-               printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
-               cli_shutdown(&c_nt);
+       if (!cli_negprot(c_nt)) {
+               printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(c_nt));
+               cli_shutdown(c_nt);
                return False;
        }
 
-       if (!cli_session_setup(&c_nt, "", "", 0, "", 0,
-                              workgroup)) {
-               printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt));
+       if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
+                                              workgroup))) {
+               printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
                return False;
        }
 
        /* DOS-Error connection */
 
-       if (!open_nbt_connection(&c_dos)) {
+       if (!(c_dos = open_nbt_connection())) {
                return False;
        }
 
-       c_dos.use_spnego = False;
-       c_dos.force_dos_errors = True;
+       c_dos->use_spnego = False;
+       c_dos->force_dos_errors = True;
 
-       if (!cli_negprot(&c_dos)) {
-               printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
-               cli_shutdown(&c_dos);
+       if (!cli_negprot(c_dos)) {
+               printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(c_dos));
+               cli_shutdown(c_dos);
                return False;
        }
 
-       if (!cli_session_setup(&c_dos, "", "", 0, "", 0,
-                              workgroup)) {
-               printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos));
+       if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
+                                              workgroup))) {
+               printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
                return False;
        }
 
        for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
-               snprintf(user, sizeof(user), "%X", error);
+               fstr_sprintf(user, "%X", error);
 
-               if (cli_session_setup(&c_nt, user, 
-                                      password, strlen(password),
-                                      password, strlen(password),
-                                     workgroup)) {
+               if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user, 
+                                                     password, strlen(password),
+                                                     password, strlen(password),
+                                                     workgroup))) {
                        printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
                }
                
-               flgs2 = SVAL(c_nt.inbuf,smb_flg2);
+               flgs2 = SVAL(c_nt->inbuf,smb_flg2);
                
                /* Case #1: 32-bit NT errors */
                if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
-                       nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
+                       nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
                } else {
                        printf("/** Dos error on NT connection! (%s) */\n", 
-                              cli_errstr(&c_nt));
+                              cli_errstr(c_nt));
                        nt_status = NT_STATUS(0xc0000000);
                }
 
-               if (cli_session_setup(&c_dos, user, 
-                                      password, strlen(password),
-                                      password, strlen(password),
-                                      workgroup)) {
+               if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user, 
+                                                     password, strlen(password),
+                                                     password, strlen(password),
+                                                     workgroup))) {
                        printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
                }
-               flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
+               flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
                
                /* Case #1: 32-bit NT errors */
                if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
                        printf("/** NT error on DOS connection! (%s) */\n", 
-                              cli_errstr(&c_nt));
+                              cli_errstr(c_nt));
                        errnum = errclass = 0;
                } else {
-                       cli_dos_error(&c_dos, &errclass, &errnum);
+                       cli_dos_error(c_dos, &errclass, &errnum);
                }
 
                if (NT_STATUS_V(nt_status) != error) { 
@@ -4416,11 +4780,151 @@ static BOOL run_error_map_extract(int dummy) {
        return True;
 }
 
-static double create_procs(BOOL (*fn)(int), BOOL *result)
+static bool subst_test(const char *str, const char *user, const char *domain,
+                      uid_t uid, gid_t gid, const char *expected)
+{
+       char *subst;
+       bool result = true;
+
+       subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
+
+       if (strcmp(subst, expected) != 0) {
+               printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
+                      "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
+                      expected);
+               result = false;
+       }
+
+       TALLOC_FREE(subst);
+       return result;
+}
+
+static bool run_local_substitute(int dummy)
+{
+       bool ok = true;
+
+       ok &= subst_test("%U", "bla", "", -1, -1, "bla");
+       ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
+       ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
+       ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
+       ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
+       ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
+       ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
+       ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
+
+       /* Different captialization rules in sub_basic... */
+
+       ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
+                      "blaDOM") == 0);
+
+       return ok;
+}
+
+static bool run_local_gencache(int dummy)
+{
+       char *val;
+       time_t tm;
+       DATA_BLOB blob;
+
+       if (!gencache_init()) {
+               d_printf("%s: gencache_init() failed\n", __location__);
+               return False;
+       }
+
+       if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
+               d_printf("%s: gencache_set() failed\n", __location__);
+               return False;
+       }
+
+       if (!gencache_get("foo", &val, &tm)) {
+               d_printf("%s: gencache_get() failed\n", __location__);
+               return False;
+       }
+
+       if (strcmp(val, "bar") != 0) {
+               d_printf("%s: gencache_get() returned %s, expected %s\n",
+                        __location__, val, "bar");
+               SAFE_FREE(val);
+               return False;
+       }
+
+       SAFE_FREE(val);
+
+       if (!gencache_del("foo")) {
+               d_printf("%s: gencache_del() failed\n", __location__);
+               return False;
+       }
+       if (gencache_del("foo")) {
+               d_printf("%s: second gencache_del() succeeded\n",
+                        __location__);
+               return False;
+       }
+                       
+       if (gencache_get("foo", &val, &tm)) {
+               d_printf("%s: gencache_get() on deleted entry "
+                        "succeeded\n", __location__);
+               return False;
+       }
+
+       blob = data_blob_string_const("bar");
+       tm = time(NULL);
+
+       if (!gencache_set_data_blob("foo", &blob, tm)) {
+               d_printf("%s: gencache_set_data_blob() failed\n", __location__);
+               return False;
+       }
+
+       data_blob_free(&blob);
+
+       if (!gencache_get_data_blob("foo", &blob, NULL)) {
+               d_printf("%s: gencache_get_data_blob() failed\n", __location__);
+               return False;
+       }
+
+       if (strcmp((const char *)blob.data, "bar") != 0) {
+               d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
+                        __location__, (const char *)blob.data, "bar");
+               data_blob_free(&blob);
+               return False;
+       }
+
+       data_blob_free(&blob);
+
+       if (!gencache_del("foo")) {
+               d_printf("%s: gencache_del() failed\n", __location__);
+               return False;
+       }
+       if (gencache_del("foo")) {
+               d_printf("%s: second gencache_del() succeeded\n",
+                        __location__);
+               return False;
+       }
+
+       if (gencache_get_data_blob("foo", &blob, NULL)) {
+               d_printf("%s: gencache_get_data_blob() on deleted entry "
+                        "succeeded\n", __location__);
+               return False;
+       }
+
+       if (!gencache_shutdown()) {
+               d_printf("%s: gencache_shutdown() failed\n", __location__);
+               return False;
+       }
+
+       if (gencache_shutdown()) {
+               d_printf("%s: second gencache_shutdown() succeeded\n",
+                        __location__);
+               return False;
+       }
+
+       return True;
+}
+
+static double create_procs(bool (*fn)(int), bool *result)
 {
        int i, status;
        volatile pid_t *child_status;
-       volatile BOOL *child_status_out;
+       volatile bool *child_status_out;
        int synccount;
        int tries = 8;
 
@@ -4432,7 +4936,7 @@ static double create_procs(BOOL (*fn)(int), BOOL *result)
                return -1;
        }
 
-       child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
+       child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
        if (!child_status_out) {
                printf("Failed to setup result status shared memory\n");
                return -1;
@@ -4454,17 +4958,17 @@ static double create_procs(BOOL (*fn)(int), BOOL *result)
                        slprintf(myname,sizeof(myname),"CLIENT%d", i);
 
                        while (1) {
-                               if (torture_open_connection(&current_cli)) break;
+                               if (torture_open_connection(&current_cli, i)) break;
                                if (tries-- == 0) {
                                        printf("pid %d failed to start\n", (int)getpid());
                                        _exit(1);
                                }
-                               msleep(10);     
+                               smb_msleep(10); 
                        }
 
                        child_status[i] = getpid();
 
-                       while (child_status[i] && end_timer() < 5) msleep(2);
+                       while (child_status[i] && end_timer() < 5) smb_msleep(2);
 
                        child_status_out[i] = fn(i);
                        _exit(0);
@@ -4477,7 +4981,7 @@ static double create_procs(BOOL (*fn)(int), BOOL *result)
                        if (child_status[i]) synccount++;
                }
                if (synccount == nprocs) break;
-               msleep(10);
+               smb_msleep(10);
        } while (end_timer() < 30);
 
        if (synccount != nprocs) {
@@ -4513,7 +5017,7 @@ static double create_procs(BOOL (*fn)(int), BOOL *result)
 
 static struct {
        const char *name;
-       BOOL (*fn)(int);
+       bool (*fn)(int);
        unsigned flags;
 } torture_ops[] = {
        {"FDPASS", run_fdpasstest, 0},
@@ -4565,6 +5069,9 @@ static struct {
        {"IOCTL",  torture_ioctl_test, 0},
        {"CHKPATH",  torture_chkpath_test, 0},
        {"FDSESS", run_fdsesstest, 0},
+       { "EATEST", run_eatest, 0},
+       { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
+       { "LOCAL-GENCACHE", run_local_gencache, 0},
        {NULL, NULL, 0}};
 
 
@@ -4572,23 +5079,26 @@ static struct {
 /****************************************************************************
 run a specified test or "ALL"
 ****************************************************************************/
-static BOOL run_test(const char *name)
+static bool run_test(const char *name)
 {
-       BOOL ret = True;
-       BOOL result = True;
+       bool ret = True;
+       bool result = True;
+       bool found = False;
        int i;
        double t;
        if (strequal(name,"ALL")) {
                for (i=0;torture_ops[i].name;i++) {
                        run_test(torture_ops[i].name);
                }
+               found = True;
        }
        
        for (i=0;torture_ops[i].name;i++) {
-               snprintf(randomfname, sizeof(randomfname), "\\XX%x", 
+               fstr_sprintf(randomfname, "\\XX%x", 
                         (unsigned)random());
 
                if (strequal(name, torture_ops[i].name)) {
+                       found = True;
                        printf("Running %s\n", name);
                        if (torture_ops[i].flags & FLAG_MULTIPROC) {
                                t = create_procs(torture_ops[i].fn, &result);
@@ -4608,6 +5118,12 @@ static BOOL run_test(const char *name)
                        printf("%s took %g secs\n\n", name, t);
                }
        }
+
+       if (!found) {
+               printf("Did not find a test named %s\n", name);
+               ret = False;
+       }
+
        return ret;
 }
 
@@ -4616,6 +5132,9 @@ static void usage(void)
 {
        int i;
 
+       printf("WARNING samba4 test suite is much more complete nowadays.\n");
+       printf("Please use samba4 torture.\n\n");
+
        printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
 
        printf("\t-d debuglevel\n");
@@ -4632,6 +5151,7 @@ static void usage(void)
        printf("\t-A showall\n");
        printf("\t-p port\n");
        printf("\t-s seed\n");
+       printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
        printf("\n\n");
 
        printf("tests are:");
@@ -4654,9 +5174,7 @@ static void usage(void)
        char *p;
        int gotuser = 0;
        int gotpass = 0;
-       extern char *optarg;
-       extern int optind;
-       BOOL correct = True;
+       bool correct = True;
 
        dbf = x_stdout;
 
@@ -4664,7 +5182,9 @@ static void usage(void)
        setbuffer(stdout, NULL, 0);
 #endif
 
-       lp_load(dyn_CONFIGFILE,True,False,False);
+       load_case_tables();
+
+       lp_load(dyn_CONFIGFILE,True,False,False,True);
        load_interfaces();
 
        if (argc < 2) {
@@ -4700,7 +5220,7 @@ static void usage(void)
 
        fstrcpy(workgroup, lp_workgroup());
 
-       while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Ac:ks:")) != EOF) {
+       while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Ac:ks:b:")) != EOF) {
                switch (opt) {
                case 'p':
                        port_to_use = atoi(optarg);
@@ -4756,6 +5276,10 @@ static void usage(void)
                                gotpass = 1;
                        }
                        break;
+               case 'b':
+                       fstrcpy(multishare_conn_fname, optarg);
+                       use_multishare_conn = True;
+                       break;
                default:
                        printf("Unknown option %c (%d)\n", (char)opt, opt);
                        usage();
@@ -4775,10 +5299,10 @@ static void usage(void)
        printf("host=%s share=%s user=%s myname=%s\n", 
               host, share, username, myname);
 
-       if (argc == 1) {
+       if (argc == optind) {
                correct = run_test("ALL");
        } else {
-               for (i=1;i<argc;i++) {
+               for (i=optind;i<argc;i++) {
                        if (!run_test(argv[i])) {
                                correct = False;
                        }