wscript: Add check for --wrap linker flag
[vlendec/samba-autobuild/.git] / source3 / torture / vfstest.c
index 76025eef1fc3c8ed7345a6364af1b4406106b61b..f156def46471dfd2760056d61a7af480e1f71640 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    VFS module tester
 
    it under the terms of the GNU General Public License as published by
    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,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    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, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
+#include "smbd/smbd.h"
+#include "smbd/globals.h"
 #include "popt_common.h"
 #include "vfstest.h"
 #include "../libcli/smbreadline/smbreadline.h"
+#include "auth.h"
+#include "serverid.h"
+#include "messages.h"
+#include "libcli/security/security.h"
+#include "lib/smbd_shim.h"
+#include "system/filesys.h"
 
 /* List to hold groups of commands */
 static struct cmd_list {
@@ -34,6 +42,9 @@ static struct cmd_list {
        struct cmd_set *cmd_set;
 } *cmd_list;
 
+/* shall we do talloc_report after each command? */
+static int memreports = 0;
+
 /****************************************************************************
 handle completion of commands for readline
 ****************************************************************************/
@@ -44,11 +55,11 @@ static char **completion_fn(const char *text, int start, int end)
        int i, count=0;
        struct cmd_list *commands = cmd_list;
 
-       if (start) 
+       if (start)
                return NULL;
 
        /* make sure we have a list of valid commands */
-       if (!commands) 
+       if (!commands)
                return NULL;
 
        matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
@@ -57,25 +68,24 @@ static char **completion_fn(const char *text, int start, int end)
        matches[count++] = SMB_STRDUP(text);
        if (!matches[0]) return NULL;
 
-       while (commands && count < MAX_COMPLETIONS-1) 
+       while (commands && count < MAX_COMPLETIONS-1)
        {
                if (!commands->cmd_set)
                        break;
-               
+
                for (i=0; commands->cmd_set[i].name; i++)
                {
                        if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
-                               commands->cmd_set[i].fn) 
+                               commands->cmd_set[i].fn)
                        {
                                matches[count] = SMB_STRDUP(commands->cmd_set[i].name);
-                               if (!matches[count]) 
+                               if (!matches[count])
                                        return NULL;
                                count++;
                        }
                }
-               
+
                commands = commands->next;
-               
        }
 
        if (count == 2) {
@@ -98,7 +108,12 @@ static char *next_command(TALLOC_CTX *ctx, char **cmdstr)
        if (p)
                *p = '\0';
        command = talloc_strdup(ctx, *cmdstr);
-       *cmdstr = p;
+
+       /* Pass back the remaining cmdstring 
+          (a trailing delimiter ";" does also work),
+          or NULL at last cmdstring.
+       */
+       *cmdstr = p ? p + 1 : p;
 
        return command;
 }
@@ -112,7 +127,7 @@ static NTSTATUS cmd_conf(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
                return NT_STATUS_OK;
        }
 
-       if (!lp_load(argv[1], False, True, False, True)) {
+       if (!lp_load_with_shares(argv[1])) {
                printf("Error loading \"%s\"\n", argv[1]);
                return NT_STATUS_OK;
        }
@@ -120,7 +135,7 @@ static NTSTATUS cmd_conf(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
        printf("\"%s\" successfully loaded\n", argv[1]);
        return NT_STATUS_OK;
 }
-       
+
 /* Display help on commands */
 static NTSTATUS cmd_help(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
                         int argc, const char **argv)
@@ -138,7 +153,7 @@ static NTSTATUS cmd_help(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
 
        if (argc == 2) {
                for (tmp = cmd_list; tmp; tmp = tmp->next) {
-                       
+
                        tmp_set = tmp->cmd_set;
 
                        while(tmp_set->name) {
@@ -188,7 +203,7 @@ static NTSTATUS cmd_debuglevel(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int a
        }
 
        if (argc == 2) {
-               DEBUGLEVEL = atoi(argv[1]);
+               lp_set_cmdline("log level", argv[1]);
        }
 
        printf("debuglevel is %d\n", DEBUGLEVEL);
@@ -261,11 +276,11 @@ static void add_command_set(struct cmd_set *cmd_set)
 static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *cmd)
 {
        const char *p = cmd;
-       char **argv = NULL;
+       const char **argv = NULL;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        char *buf;
        TALLOC_CTX *mem_ctx = talloc_stackframe();
-       int argc = 0, i;
+       int argc = 0;
 
        /* Count number of arguments first time through the loop then
           allocate memory and strdup them. */
@@ -273,7 +288,7 @@ static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *c
  again:
        while(next_token_talloc(mem_ctx, &p, &buf, " ")) {
                if (argv) {
-                       argv[argc] = SMB_STRDUP(buf);
+                       argv[argc] = talloc_strdup(argv, buf);
                }
                argc++;
        }
@@ -281,10 +296,8 @@ static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *c
        if (!argv) {
                /* Create argument list */
 
-               argv = SMB_MALLOC_ARRAY(char *, argc);
-               memset(argv, 0, sizeof(char *) * argc);
-
-               if (!argv) {
+               argv = talloc_zero_array(mem_ctx, const char *, argc);
+               if (argv == NULL) {
                        fprintf(stderr, "out of memory\n");
                        result = NT_STATUS_NO_MEMORY;
                        goto done;
@@ -311,12 +324,14 @@ static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *c
        /* Cleanup */
 
        if (argv) {
-               for (i = 0; i < argc; i++)
-                       SAFE_FREE(argv[i]);
-
-               SAFE_FREE(argv);
+               char **_argv = discard_const_p(char *, argv);
+               TALLOC_FREE(_argv);
+               argv = NULL;
        }
 
+       if (memreports != 0) {
+               talloc_report_full(mem_ctx, stdout);
+       }
        TALLOC_FREE(mem_ctx);
        return result;
 }
@@ -400,39 +415,59 @@ static void process_file(struct vfs_state *pvfs, char *filename) {
        }
 }
 
-void exit_server(const char *reason)
+static void vfstest_exit_server(const char * const reason) _NORETURN_;
+static void vfstest_exit_server(const char * const reason)
 {
        DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
        exit(0);
 }
 
-void exit_server_cleanly(const char *const reason)
+static void vfstest_exit_server_cleanly(const char * const reason) _NORETURN_;
+static void vfstest_exit_server_cleanly(const char * const reason)
 {
-       exit_server("normal exit");
+       vfstest_exit_server("normal exit");
 }
 
-int last_message = -1;
-
-struct event_context *smbd_event_context(void)
+struct smb_request *vfstest_get_smbreq(TALLOC_CTX *mem_ctx,
+                                      struct vfs_state *vfs)
 {
-       static struct event_context *ctx;
+       struct smb_request *result;
+       uint8_t *inbuf;
 
-       if (!ctx && !(ctx = event_context_init(NULL))) {
-               smb_panic("Could not init smbd event context\n");
+       result = talloc_zero(mem_ctx, struct smb_request);
+       if (result == NULL) {
+               return NULL;
+       }
+       result->sconn = vfs->conn->sconn;
+       result->mid = ++vfs->mid;
+
+       inbuf = talloc_array(result, uint8_t, smb_size);
+       if (inbuf == NULL) {
+               goto fail;
        }
-       return ctx;
+       SSVAL(inbuf, smb_mid, result->mid);
+       smb_setlen(inbuf, smb_size-4);
+       result->inbuf = inbuf;
+       return result;
+fail:
+       TALLOC_FREE(result);
+       return NULL;
 }
 
 /* Main function */
 
-int main(int argc, char *argv[])
+int main(int argc, const char *argv[])
 {
-       static char             *cmdstr = NULL;
-       struct cmd_set          **cmd_set;
-       static struct vfs_state vfs;
+       char *cmdstr = NULL;
+       struct cmd_set  **cmd_set;
+       struct vfs_state *vfs;
        int i;
-       static char             *filename = NULL;
+       char *filename = NULL;
+       char cwd[MAXPATHLEN];
        TALLOC_CTX *frame = talloc_stackframe();
+       struct tevent_context *ev;
+       struct auth_session_info *session_info = NULL;
+       NTSTATUS status = NT_STATUS_OK;
 
        /* make sure the vars that get altered (4th field) are in
           a fixed location or certain compilers complain */
@@ -441,29 +476,43 @@ int main(int argc, char *argv[])
                POPT_AUTOHELP
                {"file",        'f', POPT_ARG_STRING,   &filename, 0, },
                {"command",     'c', POPT_ARG_STRING,   &cmdstr, 0, "Execute specified list of commands" },
+               {"memreport",   'm', POPT_ARG_INT,      &memreports, 0,
+                "Report memory left on talloc stackframe after each command" },
                POPT_COMMON_SAMBA
                POPT_TABLEEND
        };
+       static const struct smbd_shim vfstest_shim_fns =
+       {
+               .exit_server = vfstest_exit_server,
+               .exit_server_cleanly = vfstest_exit_server_cleanly,
+       };
 
-       load_case_tables();
+       smb_init_locale();
 
        setlinebuf(stdout);
 
-       pc = poptGetContext("vfstest", argc, (const char **) argv,
-                           long_options, 0);
-       
+       pc = poptGetContext("vfstest", argc, argv, long_options, 0);
+
        while(poptGetNextOpt(pc) != -1);
 
 
        poptFreeContext(pc);
 
+       /* we want total control over the permissions on created files,
+          so set our umask to 0 */
+       umask(0);
+
+       lp_load_initial_only(get_dyn_CONFIGFILE());
+
        /* TODO: check output */
-       reload_services(smbd_messaging_context(), -1, False);
+       reload_services(NULL, NULL, false);
 
        /* the following functions are part of the Samba debugging
           facilities.  See lib/debug.c */
-       setup_logging("vfstest", True);
-       
+       setup_logging("vfstest", DEBUG_STDOUT);
+
+       set_smbd_shim(&vfstest_shim_fns);
+
        /* Load command lists */
 
        cmd_set = vfstest_command_list;
@@ -476,17 +525,44 @@ int main(int argc, char *argv[])
 
        /* some basic initialization stuff */
        sec_init();
-       vfs.conn = TALLOC_ZERO_P(NULL, connection_struct);
-       vfs.conn->params = TALLOC_P(vfs.conn, struct share_params);
+       init_guest_info();
+       locking_init();
+       vfs = talloc_zero(NULL, struct vfs_state);
+       if (vfs == NULL) {
+               return 1;
+       }
+       status = make_session_info_guest(vfs, &session_info);
+       if (!NT_STATUS_IS_OK(status)) {
+               return 1;
+       }
+
+       ev = server_event_context();
+
+       status = create_conn_struct(vfs,
+                               ev,
+                               server_messaging_context(),
+                                &vfs->conn,
+                                -1,
+                                getcwd(cwd, sizeof(cwd)),
+                                session_info);
+       if (!NT_STATUS_IS_OK(status)) {
+               return 1;
+       }
+
+       vfs->conn->share_access = FILE_GENERIC_ALL;
+       vfs->conn->read_only = false;
+
+       file_init(vfs->conn->sconn);
        for (i=0; i < 1024; i++)
-               vfs.files[i] = NULL;
+               vfs->files[i] = NULL;
 
-       /* some advanced initiliazation stuff */
-       smbd_vfs_init(vfs.conn);
+       if (!posix_locking_init(false)) {
+               return 1;
+       }
 
        /* Do we have a file input? */
        if (filename && filename[0]) {
-               process_file(&vfs, filename);
+               process_file(vfs, filename);
                return 0;
        }
 
@@ -496,11 +572,11 @@ int main(int argc, char *argv[])
                char    *p = cmdstr;
 
                while((cmd=next_command(frame, &p)) != NULL) {
-                       process_cmd(&vfs, cmd);
+                       status = process_cmd(vfs, cmd);
                }
 
                TALLOC_FREE(cmd);
-               return 0;
+               return NT_STATUS_IS_OK(status) ? 0 : 1;
        }
 
        /* Loop around accepting commands */
@@ -515,12 +591,12 @@ int main(int argc, char *argv[])
                }
 
                if (line[0] != '\n') {
-                       process_cmd(&vfs, line);
+                       status = process_cmd(vfs, line);
                }
                SAFE_FREE(line);
        }
 
-       TALLOC_FREE(vfs.conn);
+       TALLOC_FREE(vfs);
        TALLOC_FREE(frame);
-       return 0;
+       return NT_STATUS_IS_OK(status) ? 0 : 1;
 }