Finish removal of iconv_convenience in public API's.
[bbaumbach/samba-autobuild/.git] / source4 / client / client.c
index ef88913c4d27c68a470b4dcf14760135b17fd153..cf834b9e1fa6b5c74fe7cc819343d574df649a24 100644 (file)
 #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"
-#include "librpc/gen_ndr/ndr_security.h"
-#include "libcli/raw/libcliraw.h"
 #include "libcli/util/clilsa.h"
 #include "system/dir.h"
 #include "system/filesys.h"
-#include "lib/util/dlinklist.h"
+#include "../lib/util/dlinklist.h"
 #include "system/readline.h"
 #include "auth/credentials/credentials.h"
 #include "auth/gensec/gensec.h"
 #include "lib/smbreadline/smbreadline.h"
 #include "librpc/gen_ndr/ndr_nbt.h"
 #include "param/param.h"
-#include "librpc/rpc/dcerpc.h"
+#include "libcli/raw/raw_proto.h"
+
+/* the default pager to use for the client "more" command. Users can
+ *    override this with the PAGER environment variable */
+#ifndef DEFAULT_PAGER
+#define DEFAULT_PAGER "more"
+#endif
 
 struct smbclient_context {
        char *remote_cur_dir;
@@ -69,9 +72,9 @@ struct smbclient_context {
 
 /* timing globals */
 static uint64_t get_total_size = 0;
-static uint_t get_total_time_ms = 0;
+static unsigned int get_total_time_ms = 0;
 static uint64_t put_total_size = 0;
-static uint_t put_total_time_ms = 0;
+static unsigned int put_total_time_ms = 0;
 
 /* Unfortunately, there is no way to pass the a context to the completion function as an argument */
 static struct smbclient_context *rl_ctx; 
@@ -214,15 +217,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;
 }
@@ -254,9 +260,9 @@ static int do_cd(struct smbclient_context *ctx, const char *newdir)
        /* Save the current directory in case the
           new directory is invalid */
        if (newdir[0] == '\\')
-               dname = talloc_strdup(NULL, newdir);
+               dname = talloc_strdup(ctx, newdir);
        else
-               dname = talloc_asprintf(NULL, "%s\\%s", ctx->remote_cur_dir, newdir);
+               dname = talloc_asprintf(ctx, "%s\\%s", ctx->remote_cur_dir, newdir);
 
        dos_format(dname);
 
@@ -675,7 +681,7 @@ static int cmd_du(struct smbclient_context *ctx, const char **args)
 /****************************************************************************
   get a file from rname to lname
   ****************************************************************************/
-static int do_get(struct smbclient_context *ctx, char *rname, const char *lname, bool reget)
+static int do_get(struct smbclient_context *ctx, char *rname, const char *p_lname, bool reget)
 {  
        int handle = 0, fnum;
        bool newhandle = false;
@@ -687,11 +693,14 @@ static int do_get(struct smbclient_context *ctx, char *rname, const char *lname,
        off_t start = 0;
        off_t nread = 0;
        int rc = 0;
+       char *lname;
 
+
+       lname = talloc_strdup(ctx, p_lname);
        GetTimeOfDay(&tp_start);
 
        if (ctx->lowercase) {
-               strlower(discard_const_p(char, lname));
+               strlower(lname);
        }
 
        fnum = smbcli_open(ctx->cli->tree, rname, O_RDONLY, DENY_NONE);
@@ -848,6 +857,7 @@ static void do_mget(struct smbclient_context *ctx, struct clilist_file_info *fin
        char *quest;
        char *mget_mask;
        char *saved_curdir;
+       char *l_fname;
 
        if (ISDOT(finfo->name) || ISDOTDOT(finfo->name))
                return;
@@ -869,27 +879,29 @@ static void do_mget(struct smbclient_context *ctx, struct clilist_file_info *fin
        }
 
        /* handle directories */
-       saved_curdir = talloc_strdup(NULL, ctx->remote_cur_dir);
+       saved_curdir = talloc_strdup(ctx, ctx->remote_cur_dir);
 
        ctx->remote_cur_dir = talloc_asprintf_append_buffer(NULL, "%s\\", finfo->name);
 
-       string_replace(discard_const_p(char, finfo->name), '\\', '/');
+       l_fname = talloc_strdup(ctx, finfo->name);
+
+       string_replace(l_fname, '\\', '/');
        if (ctx->lowercase) {
-               strlower(discard_const_p(char, finfo->name));
+               strlower(l_fname);
        }
        
-       if (!directory_exist(finfo->name) && 
-           mkdir(finfo->name,0777) != 0) {
-               d_printf("failed to create directory %s\n",finfo->name);
+       if (!directory_exist(l_fname) &&
+           mkdir(l_fname, 0777) != 0) {
+               d_printf("failed to create directory %s\n", l_fname);
                return;
        }
        
-       if (chdir(finfo->name) != 0) {
-               d_printf("failed to chdir to directory %s\n",finfo->name);
+       if (chdir(l_fname) != 0) {
+               d_printf("failed to chdir to directory %s\n", l_fname);
                return;
        }
 
-       mget_mask = talloc_asprintf(NULL, "%s*", ctx->remote_cur_dir);
+       mget_mask = talloc_asprintf(ctx, "%s*", ctx->remote_cur_dir);
        
        do_list(ctx, mget_mask, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY,do_mget,false, true);
        chdir("..");
@@ -931,7 +943,7 @@ static int cmd_more(struct smbclient_context *ctx, const char **args)
 
        pager=getenv("PAGER");
 
-       pager_cmd = talloc_asprintf(ctx, "%s %s",(pager? pager:PAGER), lname);
+       pager_cmd = talloc_asprintf(ctx, "%s %s",(pager? pager:DEFAULT_PAGER), lname);
        system(pager_cmd);
        unlink(lname);
        
@@ -953,7 +965,7 @@ static int cmd_mget(struct smbclient_context *ctx, const char **args)
                attribute |= FILE_ATTRIBUTE_DIRECTORY;
        
        for (i = 1; args[i]; i++) {
-               mget_mask = talloc_strdup(ctx,ctx->remote_cur_dir);
+               mget_mask = talloc_strdup(ctx, ctx->remote_cur_dir);
                if(mget_mask[strlen(mget_mask)-1]!='\\')
                        mget_mask = talloc_append_string(ctx, mget_mask, "\\");
                
@@ -1211,10 +1223,14 @@ static int cmd_put(struct smbclient_context *ctx, const char **args)
 
        lname = talloc_strdup(ctx, args[1]);
   
-       if (args[2])
-               rname = talloc_strdup(ctx, args[2]);
-       else
+       if (args[2]) {
+               if (args[2][0]=='\\')
+                       rname = talloc_strdup(ctx, args[2]);
+               else
+                       rname = talloc_asprintf(ctx, "%s\\%s", ctx->remote_cur_dir, args[2]);
+       } else {
                rname = talloc_asprintf(ctx, "%s\\%s", ctx->remote_cur_dir, lname);
+       }
        
        dos_clean_name(rname);
 
@@ -1278,7 +1294,7 @@ static bool seek_list(struct file_list *list, char *name)
 static int cmd_select(struct smbclient_context *ctx, const char **args)
 {
        talloc_free(ctx->fileselection);
-       ctx->fileselection = talloc_strdup(NULL, args[1]);
+       ctx->fileselection = talloc_strdup(ctx, args[1]);
 
        return 0;
 }
@@ -1519,7 +1535,7 @@ static int cmd_del(struct smbclient_context *ctx, const char **args)
                d_printf("del <filename>\n");
                return 1;
        }
-       mask = talloc_asprintf(ctx,"%s%s", ctx->remote_cur_dir, args[1]);
+       mask = talloc_asprintf(ctx, "%s%s", ctx->remote_cur_dir, args[1]);
 
        if (NT_STATUS_IS_ERR(smbcli_unlink(ctx->cli->tree, mask))) {
                d_printf("%s deleting remote file %s\n",smbcli_errstr(ctx->cli->tree),mask);
@@ -2546,21 +2562,25 @@ static void display_share_result(struct srvsvc_NetShareCtr1 *ctr1)
 /****************************************************************************
 try and browse available shares on a host
 ****************************************************************************/
-static bool browse_host(struct loadparm_context *lp_ctx, const char *query_host)
+static bool browse_host(struct loadparm_context *lp_ctx,
+                       struct tevent_context *ev_ctx,
+                       const char *query_host)
 {
        struct dcerpc_pipe *p;
        char *binding;
        NTSTATUS status;
        struct srvsvc_NetShareEnumAll r;
+       struct srvsvc_NetShareInfoCtr info_ctr;
        uint32_t resume_handle = 0;
        TALLOC_CTX *mem_ctx = talloc_init("browse_host");
        struct srvsvc_NetShareCtr1 ctr1;
+       uint32_t totalentries = 0;
 
        binding = talloc_asprintf(mem_ctx, "ncacn_np:%s", 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", 
@@ -2569,25 +2589,30 @@ static bool browse_host(struct loadparm_context *lp_ctx, const char *query_host)
                return false;
        }
 
+       info_ctr.level = 1;
+       info_ctr.ctr.ctr1 = &ctr1;
+
        r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
-       r.in.level = 1;
-       r.in.ctr.ctr1 = &ctr1;
+       r.in.info_ctr = &info_ctr;
        r.in.max_buffer = ~0;
        r.in.resume_handle = &resume_handle;
+       r.out.resume_handle = &resume_handle;
+       r.out.totalentries = &totalentries;
+       r.out.info_ctr = &info_ctr;
 
        d_printf("\n\tSharename       Type       Comment\n");
        d_printf("\t---------       ----       -------\n");
 
        do {
                ZERO_STRUCT(ctr1);
-               status = dcerpc_srvsvc_NetShareEnumAll(p, mem_ctx, &r);
+               status = dcerpc_srvsvc_NetShareEnumAll_r(p->binding_handle, mem_ctx, &r);
 
                if (NT_STATUS_IS_OK(status) && 
                    (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA) ||
                     W_ERROR_IS_OK(r.out.result)) &&
-                   r.out.ctr.ctr1) {
-                       display_share_result(r.out.ctr.ctr1);
-                       resume_handle += r.out.ctr.ctr1->count;
+                   r.out.info_ctr->ctr.ctr1) {
+                       display_share_result(r.out.info_ctr->ctr.ctr1);
+                       resume_handle += r.out.info_ctr->ctr.ctr1->count;
                }
        } while (NT_STATUS_IS_OK(status) && W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
 
@@ -2749,7 +2774,7 @@ process a -c command string
 ****************************************************************************/
 static int process_command_string(struct smbclient_context *ctx, const char *cmd)
 {
-       const char **lines;
+       char **lines;
        int i, rc = 0;
 
        lines = str_list_make(NULL, cmd, ";");
@@ -2971,7 +2996,7 @@ static int process_line(struct smbclient_context *ctx, const char *cline)
        int i;
 
        /* and get the first part of the command */
-       args = str_list_make_shell(ctx, cline, NULL);
+       args = (const char **) str_list_make_shell(ctx, cline, NULL);
        if (!args || !args[0])
                return 0;
 
@@ -3022,11 +3047,15 @@ static int process_stdin(struct smbclient_context *ctx)
 return a connection to a server
 *******************************************************/
 static bool do_connect(struct smbclient_context *ctx, 
+                      struct tevent_context *ev_ctx,
                       struct resolve_context *resolve_ctx,
                       const char *specified_server, const char **ports, 
                       const char *specified_share, 
+                          const char *socket_options,
                       struct cli_credentials *cred, 
-                      struct smbcli_options *options)
+                      struct smbcli_options *options,
+                      struct smbcli_session_options *session_options,
+                          struct gensec_settings *gensec_settings)
 {
        NTSTATUS status;
        char *server, *share;
@@ -3044,9 +3073,11 @@ static bool do_connect(struct smbclient_context *ctx,
        ctx->remote_cur_dir = talloc_strdup(ctx, "\\");
        
        status = smbcli_full_connection(ctx, &ctx->cli, server, ports,
-                                       share, NULL, cred, resolve_ctx, 
-                                       event_context_init(NULL),
-                                       options);
+                                       share, NULL, 
+                                       socket_options,
+                                       cred, resolve_ctx, 
+                                       ev_ctx, options, session_options,
+                                       gensec_settings);
        if (!NT_STATUS_IS_OK(status)) {
                d_printf("Connection to \\\\%s\\%s failed - %s\n", 
                         server, share, nt_errstr(status));
@@ -3060,9 +3091,12 @@ static bool do_connect(struct smbclient_context *ctx,
 /****************************************************************************
 handle a -L query
 ****************************************************************************/
-static int do_host_query(struct loadparm_context *lp_ctx, const char *query_host, const char *workgroup)
+static int do_host_query(struct loadparm_context *lp_ctx,
+                        struct tevent_context *ev_ctx,
+                        const char *query_host,
+                        const char *workgroup)
 {
-       browse_host(lp_ctx, query_host);
+       browse_host(lp_ctx, ev_ctx, query_host);
        list_servers(workgroup);
        return(0);
 }
@@ -3071,7 +3105,13 @@ static int do_host_query(struct loadparm_context *lp_ctx, const char *query_host
 /****************************************************************************
 handle a message operation
 ****************************************************************************/
-static int do_message_op(const char *netbios_name, const char *desthost, const char **destports, const char *destip, int name_type, struct resolve_context *resolve_ctx, struct smbcli_options *options)
+static int do_message_op(const char *netbios_name, const char *desthost,
+                        const char **destports, const char *destip,
+                        int name_type,
+                        struct tevent_context *ev_ctx,
+                        struct resolve_context *resolve_ctx,
+                        struct smbcli_options *options,
+             const char *socket_options)
 {
        struct nbt_name called, calling;
        const char *server_name;
@@ -3083,7 +3123,10 @@ static int do_message_op(const char *netbios_name, const char *desthost, const c
 
        server_name = destip ? destip : desthost;
 
-       if (!(cli=smbcli_state_init(NULL)) || !smbcli_socket_connect(cli, server_name, destports, resolve_ctx, options)) {
+       if (!(cli = smbcli_state_init(NULL)) ||
+           !smbcli_socket_connect(cli, server_name, destports,
+                                  ev_ctx, resolve_ctx, options,
+                   socket_options)) {
                d_printf("Connection to %s failed\n", server_name);
                return 1;
        }
@@ -3106,17 +3149,12 @@ static int do_message_op(const char *netbios_name, const char *desthost, const c
 ****************************************************************************/
  int main(int argc,char *argv[])
 {
-       const char *base_directory = NULL;
+       char *base_directory = NULL;
        const char *dest_ip = NULL;
        int opt;
        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 */
+       char *desthost = NULL;
        poptContext pc;
        const char *service = NULL;
        int port = 0;
@@ -3124,9 +3162,11 @@ static int do_message_op(const char *netbios_name, const char *desthost, const c
        int rc = 0;
        int name_type = 0x20;
        TALLOC_CTX *mem_ctx;
+       struct tevent_context *ev_ctx;
        struct smbclient_context *ctx;
        const char *cmdstr = NULL;
        struct smbcli_options smb_options;
+       struct smbcli_session_options smb_session_options;
 
        struct poptOption long_options[] = {
                POPT_AUTOHELP
@@ -3135,7 +3175,6 @@ static int do_message_op(const char *netbios_name, const char *desthost, const c
                { "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" },
@@ -3153,7 +3192,7 @@ static int do_message_op(const char *netbios_name, const char *desthost, const c
                exit(1);
        }
 
-       ctx = talloc(mem_ctx, struct smbclient_context);
+       ctx = talloc_zero(mem_ctx, struct smbclient_context);
        ctx->io_bufsize = 64512;
 
        pc = poptGetContext("smbclient", argc, (const char **) argv, long_options, 0);
@@ -3177,9 +3216,6 @@ static int do_message_op(const char *netbios_name, const char *desthost, const c
                case 'L':
                        query_host = strdup(poptGetOptArg(pc));
                        break;
-               case 't':
-                       term_code = strdup(poptGetOptArg(pc));
-                       break;
                case 'D':
                        base_directory = strdup(poptGetOptArg(pc));
                        break;
@@ -3220,6 +3256,9 @@ static int do_message_op(const char *netbios_name, const char *desthost, const c
        poptFreeContext(pc);
 
        lp_smbcli_options(cmdline_lp_ctx, &smb_options);
+       lp_smbcli_session_options(cmdline_lp_ctx, &smb_session_options);
+
+       ev_ctx = s4_event_context_init(talloc_autofree_context());
 
        DEBUG( 3, ( "Client started (version %s).\n", SAMBA_VERSION_STRING ) );
 
@@ -3230,25 +3269,40 @@ static int do_message_op(const char *netbios_name, const char *desthost, const c
        }
   
        if (query_host) {
-               return do_host_query(cmdline_lp_ctx, query_host, lp_workgroup(cmdline_lp_ctx));
+               rc = do_host_query(cmdline_lp_ctx, ev_ctx, query_host,
+                                  lp_workgroup(cmdline_lp_ctx));
+               return rc;
        }
 
        if (message) {
-               return do_message_op(lp_netbios_name(cmdline_lp_ctx), desthost, lp_smb_ports(cmdline_lp_ctx), dest_ip, name_type, lp_resolve_context(cmdline_lp_ctx), &smb_options);
+               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, 
+                   lp_socket_options(cmdline_lp_ctx));
+               return rc;
        }
        
-       if (!do_connect(ctx, lp_resolve_context(cmdline_lp_ctx), desthost, lp_smb_ports(cmdline_lp_ctx), service, cmdline_credentials, &smb_options))
+       if (!do_connect(ctx, ev_ctx, lp_resolve_context(cmdline_lp_ctx),
+                       desthost, lp_smb_ports(cmdline_lp_ctx), service,
+                       lp_socket_options(cmdline_lp_ctx),
+                       cmdline_credentials, &smb_options, &smb_session_options,
+                       lp_gensec_settings(ctx, cmdline_lp_ctx)))
                return 1;
 
-       if (base_directory) 
+       if (base_directory) {
                do_cd(ctx, base_directory);
+               free(base_directory);
+       }
        
        if (cmdstr) {
                rc = process_command_string(ctx, cmdstr);
        } else {
                rc = process_stdin(ctx);
        }
-  
+
+       free(desthost);
        talloc_free(mem_ctx);
 
        return rc;