Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-wsgi
[samba.git] / source4 / client / client.c
index 44153616028c300a05bf54d0b0aed0e8d2883389..01197e8a9ee8cc2abffaf9ade19a01c00ed5eb18 100644 (file)
@@ -32,6 +32,7 @@
 #include "includes.h"
 #include "version.h"
 #include "libcli/libcli.h"
+#include "lib/events/events.h"
 #include "lib/cmdline/popt_common.h"
 #include "librpc/gen_ndr/ndr_srvsvc_c.h"
 #include "librpc/gen_ndr/ndr_lsa.h"
@@ -50,8 +51,7 @@
 #include "lib/smbreadline/smbreadline.h"
 #include "librpc/gen_ndr/ndr_nbt.h"
 #include "param/param.h"
-
-static int io_bufsize = 64512;
+#include "librpc/rpc/dcerpc.h"
 
 struct smbclient_context {
        char *remote_cur_dir;
@@ -64,6 +64,7 @@ struct smbclient_context {
        bool lowercase;
        int printmode;
        bool translation;
+       int io_bufsize;
 };
 
 /* timing globals */
@@ -213,15 +214,18 @@ check the space on a device
 ****************************************************************************/
 static int do_dskattr(struct smbclient_context *ctx)
 {
-       int total, bsize, avail;
+       uint32_t bsize;
+       uint64_t total, avail;
 
        if (NT_STATUS_IS_ERR(smbcli_dskattr(ctx->cli->tree, &bsize, &total, &avail))) {
                d_printf("Error in dskattr: %s\n",smbcli_errstr(ctx->cli->tree)); 
                return 1;
        }
 
-       d_printf("\n\t\t%d blocks of size %d. %d blocks available\n",
-                total, bsize, avail);
+       d_printf("\n\t\t%llu blocks of size %u. %llu blocks available\n",
+                (unsigned long long)total, 
+                (unsigned)bsize, 
+                (unsigned long long)avail);
 
        return 0;
 }
@@ -680,7 +684,7 @@ static int do_get(struct smbclient_context *ctx, char *rname, const char *lname,
        bool newhandle = false;
        uint8_t *data;
        struct timeval tp_start;
-       int read_size = io_bufsize;
+       int read_size = ctx->io_bufsize;
        uint16_t attr;
        size_t size;
        off_t start = 0;
@@ -1074,7 +1078,7 @@ static int do_put(struct smbclient_context *ctx, char *rname, char *lname, bool
        size_t start = 0;
        off_t nread = 0;
        uint8_t *buf = NULL;
-       int maxwrite = io_bufsize;
+       int maxwrite = ctx->io_bufsize;
        int rc = 0;
        
        struct timeval tp_start;
@@ -2545,7 +2549,9 @@ static void display_share_result(struct srvsvc_NetShareCtr1 *ctr1)
 /****************************************************************************
 try and browse available shares on a host
 ****************************************************************************/
-static bool browse_host(const char *query_host)
+static bool browse_host(struct loadparm_context *lp_ctx,
+                       struct event_context *ev_ctx,
+                       const char *query_host)
 {
        struct dcerpc_pipe *p;
        char *binding;
@@ -2559,7 +2565,8 @@ static bool browse_host(const char *query_host)
 
        status = dcerpc_pipe_connect(mem_ctx, &p, binding, 
                                         &ndr_table_srvsvc,
-                                    cmdline_credentials, NULL);
+                                    cmdline_credentials, ev_ctx,
+                                    lp_ctx);
        if (!NT_STATUS_IS_OK(status)) {
                d_printf("Failed to connect to %s - %s\n", 
                         binding, nt_errstr(status));
@@ -2997,16 +3004,19 @@ static int process_stdin(struct smbclient_context *ctx)
                char *the_prompt = talloc_asprintf(ctx, "smb: %s> ", ctx->remote_cur_dir);
                char *cline = smb_readline(the_prompt, readline_callback, completion_fn);
                talloc_free(the_prompt);
-                       
+
                if (!cline) break;
-               
+
                /* special case - first char is ! */
                if (*cline == '!') {
                        system(cline + 1);
+                       free(cline);
                        continue;
                }
 
-               rc |= process_command_string(ctx, cline); 
+               rc |= process_command_string(ctx, cline);
+               free(cline);
+
        }
 
        return rc;
@@ -3016,17 +3026,17 @@ static int process_stdin(struct smbclient_context *ctx)
 /***************************************************** 
 return a connection to a server
 *******************************************************/
-static struct smbclient_context *do_connect(TALLOC_CTX *mem_ctx, 
-                                      const char *specified_server, const char *specified_share, struct cli_credentials *cred)
+static bool do_connect(struct smbclient_context *ctx, 
+                      struct event_context *ev_ctx,
+                      struct resolve_context *resolve_ctx,
+                      const char *specified_server, const char **ports, 
+                      const char *specified_share, 
+                      struct cli_credentials *cred, 
+                      struct smbcli_options *options)
 {
        NTSTATUS status;
-       struct smbclient_context *ctx = talloc_zero(mem_ctx, struct smbclient_context);
        char *server, *share;
 
-       if (!ctx) {
-               return NULL;
-       }
-
        rl_ctx = ctx; /* Ugly hack */
 
        if (strncmp(specified_share, "\\\\", 2) == 0 ||
@@ -3039,9 +3049,9 @@ static struct smbclient_context *do_connect(TALLOC_CTX *mem_ctx,
 
        ctx->remote_cur_dir = talloc_strdup(ctx, "\\");
        
-       status = smbcli_full_connection(ctx, &ctx->cli, server,
-                                       share, NULL, cred, 
-                                       cli_credentials_get_event_context(cred));
+       status = smbcli_full_connection(ctx, &ctx->cli, server, ports,
+                                       share, NULL, cred, resolve_ctx, 
+                                       ev_ctx, options);
        if (!NT_STATUS_IS_OK(status)) {
                d_printf("Connection to \\\\%s\\%s failed - %s\n", 
                         server, share, nt_errstr(status));
@@ -3055,9 +3065,12 @@ static struct smbclient_context *do_connect(TALLOC_CTX *mem_ctx,
 /****************************************************************************
 handle a -L query
 ****************************************************************************/
-static int do_host_query(const char *query_host, const char *workgroup)
+static int do_host_query(struct loadparm_context *lp_ctx,
+                        struct event_context *ev_ctx,
+                        const char *query_host,
+                        const char *workgroup)
 {
-       browse_host(query_host);
+       browse_host(lp_ctx, ev_ctx, query_host);
        list_servers(workgroup);
        return(0);
 }
@@ -3066,19 +3079,26 @@ static int do_host_query(const char *query_host, const char *workgroup)
 /****************************************************************************
 handle a message operation
 ****************************************************************************/
-static int do_message_op(const char *desthost, const char *destip, int name_type)
+static int do_message_op(const char *netbios_name, const char *desthost,
+                        const char **destports, const char *destip,
+                        int name_type,
+                        struct event_context *ev_ctx,
+                        struct resolve_context *resolve_ctx,
+                        struct smbcli_options *options)
 {
        struct nbt_name called, calling;
        const char *server_name;
        struct smbcli_state *cli;
 
-       make_nbt_name_client(&calling, lp_netbios_name(global_loadparm));
+       make_nbt_name_client(&calling, netbios_name);
 
        nbt_choose_called_name(NULL, &called, desthost, name_type);
 
        server_name = destip ? destip : desthost;
 
-       if (!(cli=smbcli_state_init(NULL)) || !smbcli_socket_connect(cli, server_name)) {
+       if (!(cli = smbcli_state_init(NULL)) ||
+           !smbcli_socket_connect(cli, server_name, destports,
+                                  ev_ctx, resolve_ctx, options)) {
                d_printf("Connection to %s failed\n", server_name);
                return 1;
        }
@@ -3107,11 +3127,6 @@ static int do_message_op(const char *desthost, const char *destip, int name_type
        const char *query_host = NULL;
        bool message = false;
        const char *desthost = NULL;
-#ifdef KANJI
-       const char *term_code = KANJI;
-#else
-       const char *term_code = "";
-#endif /* KANJI */
        poptContext pc;
        const char *service = NULL;
        int port = 0;
@@ -3119,8 +3134,10 @@ static int do_message_op(const char *desthost, const char *destip, int name_type
        int rc = 0;
        int name_type = 0x20;
        TALLOC_CTX *mem_ctx;
+       struct event_context *ev_ctx;
        struct smbclient_context *ctx;
        const char *cmdstr = NULL;
+       struct smbcli_options smb_options;
 
        struct poptOption long_options[] = {
                POPT_AUTOHELP
@@ -3129,7 +3146,6 @@ static int do_message_op(const char *desthost, const char *destip, int name_type
                { "ip-address", 'I', POPT_ARG_STRING, NULL, 'I', "Use this IP to connect to", "IP" },
                { "stderr", 'E', POPT_ARG_NONE, NULL, 'E', "Write messages to stderr instead of stdout" },
                { "list", 'L', POPT_ARG_STRING, NULL, 'L', "Get a list of shares available on a host", "HOST" },
-               { "terminal", 't', POPT_ARG_STRING, NULL, 't', "Terminal I/O code {sjis|euc|jis7|jis8|junet|hex}", "CODE" },
                { "directory", 'D', POPT_ARG_STRING, NULL, 'D', "Start from directory", "DIR" },
                { "command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated commands" }, 
                { "send-buffer", 'b', POPT_ARG_INT, NULL, 'b', "Changes the transmit/send buffer", "BYTES" },
@@ -3147,6 +3163,9 @@ static int do_message_op(const char *desthost, const char *destip, int name_type
                exit(1);
        }
 
+       ctx = talloc(mem_ctx, struct smbclient_context);
+       ctx->io_bufsize = 64512;
+
        pc = poptGetContext("smbclient", argc, (const char **) argv, long_options, 0);
        poptSetOtherOptionHelp(pc, "[OPTIONS] service <password>");
 
@@ -3168,19 +3187,16 @@ static int do_message_op(const char *desthost, const char *destip, int name_type
                case 'L':
                        query_host = strdup(poptGetOptArg(pc));
                        break;
-               case 't':
-                       term_code = strdup(poptGetOptArg(pc));
-                       break;
                case 'D':
                        base_directory = strdup(poptGetOptArg(pc));
                        break;
                case 'b':
-                       io_bufsize = MAX(1, atoi(poptGetOptArg(pc)));
+                       ctx->io_bufsize = MAX(1, atoi(poptGetOptArg(pc)));
                        break;
                }
        }
 
-       gensec_init();
+       gensec_init(cmdline_lp_ctx);
 
        if(poptPeekArg(pc)) {
                char *s = strdup(poptGetArg(pc)); 
@@ -3210,6 +3226,10 @@ static int do_message_op(const char *desthost, const char *destip, int name_type
 
        poptFreeContext(pc);
 
+       lp_smbcli_options(cmdline_lp_ctx, &smb_options);
+
+       ev_ctx = event_context_init(talloc_autofree_context());
+
        DEBUG( 3, ( "Client started (version %s).\n", SAMBA_VERSION_STRING ) );
 
        if (query_host && (p=strchr_m(query_host,'#'))) {
@@ -3219,16 +3239,23 @@ static int do_message_op(const char *desthost, const char *destip, int name_type
        }
   
        if (query_host) {
-               return do_host_query(query_host, lp_workgroup(global_loadparm));
+               rc = do_host_query(cmdline_lp_ctx, ev_ctx, query_host,
+                                  lp_workgroup(cmdline_lp_ctx));
+               return rc;
        }
 
        if (message) {
-               return do_message_op(desthost, dest_ip, name_type);
+               rc = do_message_op(lp_netbios_name(cmdline_lp_ctx), desthost,
+                                  lp_smb_ports(cmdline_lp_ctx), dest_ip,
+                                  name_type, ev_ctx,
+                                  lp_resolve_context(cmdline_lp_ctx),
+                                  &smb_options);
+               return rc;
        }
        
-
-       ctx = do_connect(mem_ctx, desthost, service, cmdline_credentials);
-       if (!ctx)
+       if (!do_connect(ctx, ev_ctx, lp_resolve_context(cmdline_lp_ctx),
+                       desthost, lp_smb_ports(cmdline_lp_ctx), service,
+                       cmdline_credentials, &smb_options))
                return 1;
 
        if (base_directory)