tridge the destroyer returns!
[samba.git] / source3 / utils / torture.c
index d5258d2d6ab35eee8ba1a6b1d4d548976c99e382..2bee5f3769059fe3a2eb2ab21d6f79ef4f553a3e 100644 (file)
@@ -2,7 +2,7 @@
    Unix SMB/Netbios implementation.
    Version 1.9.
    SMB torture tester
-   Copyright (C) Andrew Tridgell 1997
+   Copyright (C) Andrew Tridgell 1997-1998
    
    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
@@ -19,9 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#ifdef SYSLOG
-#undef SYSLOG
-#endif
+#define NO_SYSLOG
 
 #include "includes.h"
 
@@ -32,12 +30,12 @@ static char *sockops="";
 
 static struct timeval tp1,tp2;
 
-static void start_timer()
+static void start_timer(void)
 {
        gettimeofday(&tp1,NULL);
 }
 
-static double end_timer()
+static double end_timer(void)
 {
        gettimeofday(&tp2,NULL);
        return((tp2.tv_sec - tp1.tv_sec) + 
@@ -73,7 +71,9 @@ static BOOL open_connection(struct cli_state *c)
                return False;
        }
 
-       if (!cli_send_tconX(c, share, "A:", password, strlen(password)+1)) {
+       if (!cli_send_tconX(c, share, 
+                           strstr(share,"IPC$")?"IPC":"A:", 
+                           password, strlen(password)+1)) {
                printf("%s refused tree connect (%s)\n", host, cli_errstr(c));
                cli_shutdown(c);
                return False;
@@ -116,7 +116,8 @@ static BOOL rw_torture(struct cli_state *c, int numops)
        int fnum;
        int fnum2;
        int pid2, pid = getpid();
-       int i;
+       int i, j;
+       char buf[1024];
 
        fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
                         DENY_NONE);
@@ -133,7 +134,7 @@ static BOOL rw_torture(struct cli_state *c, int numops)
                if (i % 10 == 0) {
                        printf("%d\r", i); fflush(stdout);
                }
-               sprintf(fname,"\\torture.%u", n);
+               slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
 
                if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
                        return False;
@@ -149,6 +150,14 @@ static BOOL rw_torture(struct cli_state *c, int numops)
                        printf("write failed (%s)\n", cli_errstr(c));
                }
 
+               for (j=0;j<50;j++) {
+                       if (cli_write(c, fnum, (char *)buf, 
+                                     sizeof(pid)+(j*sizeof(buf)), 
+                                     sizeof(buf)) != sizeof(buf)) {
+                               printf("write failed (%s)\n", cli_errstr(c));
+                       }
+               }
+
                pid2 = 0;
 
                if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
@@ -172,6 +181,9 @@ static BOOL rw_torture(struct cli_state *c, int numops)
                }
        }
 
+       cli_close(c, fnum2);
+       cli_unlink(c, lockfname);
+
        printf("%d\n", i);
 
        return True;
@@ -179,7 +191,7 @@ static BOOL rw_torture(struct cli_state *c, int numops)
 
 static void usage(void)
 {
-       printf("Usage: smbtorture \\\\server\\share <options>\n");
+       printf("Usage: smbtorture //server/share <options>\n");
 
        printf("\t-U user%%pass\n");
        printf("\t-N numprocs\n");
@@ -220,7 +232,7 @@ static void run_torture(int numops)
 static void run_locktest1(void)
 {
        static struct cli_state cli1, cli2;
-       char *fname = "\\locktest.lck";
+       char *fname = "\\lockt1.lck";
        int fnum1, fnum2, fnum3;
        time_t t1, t2;
 
@@ -345,7 +357,7 @@ static void run_locktest1(void)
 static void run_locktest2(void)
 {
        static struct cli_state cli;
-       char *fname = "\\locktest.lck";
+       char *fname = "\\lockt2.lck";
        int fnum1, fnum2, fnum3;
 
        if (!open_connection(&cli)) {
@@ -448,7 +460,7 @@ static void run_locktest2(void)
 static void run_locktest3(int numops)
 {
        static struct cli_state cli1, cli2;
-       char *fname = "\\locktest.lck";
+       char *fname = "\\lockt3.lck";
        int fnum1, fnum2, i;
        uint32 offset;
 
@@ -587,11 +599,65 @@ static void run_unlinktest(void)
                printf("error: server allowed unlink on an open file\n");
        }
 
+       cli_close(&cli, fnum);
+       cli_unlink(&cli, fname);
+
        close_connection(&cli);
 
        printf("unlink test finished\n");
 }
 
+/* generate a random buffer */
+static void rand_buf(char *buf, int len)
+{
+       while (len--) {
+               *buf = random();
+               buf++;
+       }
+}
+
+/* send random IPC commands */
+static void run_randomipc(void)
+{
+       char *rparam = NULL;
+       char *rdata = NULL;
+       int rdrcnt,rprcnt;
+       pstring param;
+       int api, param_len, i;
+       static struct cli_state cli;
+       struct {
+               int api, level;
+               char *format;
+               char *subformat;
+               int len;
+       } foo;
+
+       printf("starting random ipc test\n");
+
+       if (!open_connection(&cli)) {
+               return;
+       }
+
+       for (i=0;i<1000;i++) {
+               api = random() % 500;
+               param_len = random() % 64;
+
+               rand_buf(param, param_len);
+  
+               SSVAL(param,0,api); 
+
+               cli_api(&cli, 
+                       param, param_len, 8,  
+                       NULL, 0, BUFFER_SIZE, 
+                       &rparam, &rprcnt,     
+                       &rdata, &rdrcnt);
+       }
+
+       close_connection(&cli);
+
+       printf("finished random ipc test\n");
+}
+
 
 
 static void browse_callback(char *sname, uint32 stype, char *comment)
@@ -600,6 +666,7 @@ static void browse_callback(char *sname, uint32 stype, char *comment)
 }
 
 
+
 /*
   This test checks the browse list code
 
@@ -608,7 +675,7 @@ static void run_browsetest(void)
 {
        static struct cli_state cli;
 
-       printf("staring browse test\n");
+       printf("starting browse test\n");
 
        if (!open_connection(&cli)) {
                return;
@@ -640,7 +707,7 @@ static void run_attrtest(void)
        time_t t, t2;
        char *fname = "\\attrib.tst";
 
-       printf("staring attrib test\n");
+       printf("starting attrib test\n");
 
        if (!open_connection(&cli)) {
                return;
@@ -676,12 +743,116 @@ static void run_attrtest(void)
                printf("%s", ctime(&t2));
        }
 
+       cli_unlink(&cli, fname);
+
        close_connection(&cli);
 
        printf("attrib test finished\n");
 }
 
 
+/*
+  This checks a couple of trans2 calls
+*/
+static void run_trans2test(void)
+{
+       static struct cli_state cli;
+       int fnum;
+       uint32 size;
+       time_t c_time, a_time, m_time, w_time, m_time2;
+       char *fname = "\\trans2.tst";
+       char *dname = "\\trans2";
+       char *fname2 = "\\trans2\\trans2.tst";
+
+       printf("starting trans2 test\n");
+
+       if (!open_connection(&cli)) {
+               return;
+       }
+
+       cli_unlink(&cli, fname);
+       fnum = cli_open(&cli, fname, 
+                       O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+       if (!cli_qfileinfo(&cli, fnum, &c_time, &a_time, &m_time, &size)) {
+               printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
+       }
+       cli_close(&cli, fnum);
+
+       sleep(2);
+
+       cli_unlink(&cli, fname);
+       fnum = cli_open(&cli, fname, 
+                       O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+       cli_close(&cli, fnum);
+
+       if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size)) {
+               printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
+       } else {
+               if (c_time != m_time) {
+                       printf("create time=%s", ctime(&c_time));
+                       printf("modify time=%s", ctime(&m_time));
+                       printf("This system appears to have sticky create times\n");
+               }
+               if (a_time % (60*60) == 0) {
+                       printf("access time=%s", ctime(&a_time));
+                       printf("This system appears to set a midnight access time\n");
+               }
+
+               if (abs(m_time - time(NULL)) > 60*60*24*7) {
+                       printf("ERROR: totally incorrect times - maybe word reversed?\n");
+               }
+       }
+
+
+       cli_unlink(&cli, fname);
+       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)) {
+               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+       } else {
+               if (w_time < 60*60*24*2) {
+                       printf("write time=%s", ctime(&w_time));
+                       printf("This system appears to set a initial 0 write time\n");
+               }
+       }
+
+       cli_unlink(&cli, fname);
+
+
+       /* check if the server updates the directory modification time
+           when creating a new file */
+       if (!cli_mkdir(&cli, dname)) {
+               printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
+       }
+       sleep(3);
+       if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time, 
+                           &w_time, &size)) {
+               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+       }
+
+       fnum = cli_open(&cli, fname2, 
+                       O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+       cli_write(&cli, fnum,  (char *)&fnum, 0, sizeof(fnum));
+       cli_close(&cli, fnum);
+       if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2, 
+                           &w_time, &size)) {
+               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+       } else {
+               if (m_time2 == m_time)
+                       printf("This system does not update directory modification times\n");
+       }
+       cli_unlink(&cli, fname2);
+       cli_rmdir(&cli, dname);
+
+
+       close_connection(&cli);
+
+       printf("trans2 test finished\n");
+}
+
+
 static void create_procs(int nprocs, int numops)
 {
        int i, status;
@@ -722,12 +893,16 @@ static void create_procs(int nprocs, int numops)
                usage();
        }
 
-       if (strncmp(argv[1], "\\\\", 2)) {
+        for(p = argv[1]; *p; p++)
+          if(*p == '\\')
+            *p = '/';
+       if (strncmp(argv[1], "//", 2)) {
                usage();
        }
 
        fstrcpy(host, &argv[1][2]);
-       p = strchr(&host[2],'\\');
+       p = strchr(&host[2],'/');
        if (!p) {
                usage();
        }
@@ -737,7 +912,7 @@ static void create_procs(int nprocs, int numops)
        get_myname(myname,NULL);
 
        if (*username == 0 && getenv("LOGNAME")) {
-         strcpy(username,getenv("LOGNAME"));
+         pstrcpy(username,getenv("LOGNAME"));
        }
 
        argc--;
@@ -765,11 +940,11 @@ static void create_procs(int nprocs, int numops)
                        fstrcpy(myname, optarg);
                        break;
                case 'U':
-                       strcpy(username,optarg);
+                       pstrcpy(username,optarg);
                        p = strchr(username,'%');
                        if (p) {
                                *p = 0;
-                               strcpy(password, p+1);
+                               pstrcpy(password, p+1);
                                gotpass = 1;
                        }
                        break;
@@ -783,7 +958,7 @@ static void create_procs(int nprocs, int numops)
        while (!gotpass) {
                p = getpass("Password:");
                if (p) {
-                       strcpy(password, p);
+                       pstrcpy(password, p);
                        gotpass = 1;
                }
        }
@@ -791,6 +966,8 @@ static void create_procs(int nprocs, int numops)
        printf("host=%s share=%s user=%s myname=%s\n", 
               host, share, username, myname);
 
+       run_randomipc();
+
        start_timer();
        create_procs(nprocs, numops);
        printf("rw_torture: %g secs\n", end_timer());
@@ -801,6 +978,7 @@ static void create_procs(int nprocs, int numops)
        run_unlinktest();
        run_browsetest();
        run_attrtest();
+       run_trans2test();
 
        return(0);
 }