Finish removal of iconv_convenience in public API's.
[bbaumbach/samba-autobuild/.git] / source4 / client / client.c
index f63315a05bb853e75bfe041938a69ae6236f9de3..cf834b9e1fa6b5c74fe7cc819343d574df649a24 100644 (file)
 #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"
-#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 "libcli/raw/raw_proto.h"
 
-static int io_bufsize = 64512;
+/* 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;
        struct smbcli_state *cli;
        char *fileselection;
        time_t newer_than;
-       BOOL prompt;
-       BOOL recurse;
+       bool prompt;
+       bool recurse;
        int archive_level;
-       BOOL lowercase;
+       bool lowercase;
        int printmode;
-       BOOL translation;
+       bool translation;
+       int io_bufsize;
 };
 
 /* 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; 
@@ -105,7 +109,7 @@ static void dos_clean_name(char *s)
 write to a local file with CR/LF->LF translation if appropriate. return the 
 number taken from the buffer. This may not equal the number written.
 ****************************************************************************/
-static int writefile(int f, const void *_b, int n, BOOL translation)
+static int writefile(int f, const void *_b, int n, bool translation)
 {
        const uint8_t *b = (const uint8_t *)_b;
        int i;
@@ -133,7 +137,7 @@ static int writefile(int f, const void *_b, int n, BOOL translation)
   read from a file with LF->CR/LF translation if appropriate. return the 
   number read. read approx n bytes.
 ****************************************************************************/
-static int readfile(void *_b, int n, XFILE *f, BOOL translation)
+static int readfile(void *_b, int n, XFILE *f, bool translation)
 {
        uint8_t *b = (uint8_t *)_b;
        int i;
@@ -213,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;
 }
@@ -253,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);
 
@@ -299,7 +306,7 @@ static bool mask_match(struct smbcli_state *c, const char *string,
        if (ISDOTDOT(string))
                string = ".";
        if (ISDOT(pattern))
-               return False;
+               return false;
        
        if (is_case_sensitive)
                return ms_fnmatch(pattern, string, 
@@ -319,27 +326,27 @@ static bool mask_match(struct smbcli_state *c, const char *string,
 /*******************************************************************
   decide if a file should be operated on
   ********************************************************************/
-static BOOL do_this_one(struct smbclient_context *ctx, struct clilist_file_info *finfo)
+static bool do_this_one(struct smbclient_context *ctx, struct clilist_file_info *finfo)
 {
-       if (finfo->attrib & FILE_ATTRIBUTE_DIRECTORY) return(True);
+       if (finfo->attrib & FILE_ATTRIBUTE_DIRECTORY) return(true);
 
        if (ctx->fileselection && 
-           !mask_match(ctx->cli, finfo->name,ctx->fileselection,False)) {
+           !mask_match(ctx->cli, finfo->name,ctx->fileselection,false)) {
                DEBUG(3,("mask_match %s failed\n", finfo->name));
-               return False;
+               return false;
        }
 
        if (ctx->newer_than && finfo->mtime < ctx->newer_than) {
                DEBUG(3,("newer_than %s failed\n", finfo->name));
-               return(False);
+               return(false);
        }
 
        if ((ctx->archive_level==1 || ctx->archive_level==2) && !(finfo->attrib & FILE_ATTRIBUTE_ARCHIVE)) {
                DEBUG(3,("archive %s failed\n", finfo->name));
-               return(False);
+               return(false);
        }
        
-       return(True);
+       return(true);
 }
 
 /****************************************************************************
@@ -371,8 +378,8 @@ static void do_du(struct smbclient_context *ctx, struct clilist_file_info *finfo
        }
 }
 
-static BOOL do_list_recurse;
-static BOOL do_list_dirs;
+static bool do_list_recurse;
+static bool do_list_dirs;
 static char *do_list_queue = 0;
 static long do_list_queue_size = 0;
 static long do_list_queue_start = 0;
@@ -532,7 +539,7 @@ static void do_list_helper(struct clilist_file_info *f, const char *mask, void *
 a wrapper around smbcli_list that adds recursion
   ****************************************************************************/
 static void do_list(struct smbclient_context *ctx, const char *mask,uint16_t attribute,
-            void (*fn)(struct smbclient_context *, struct clilist_file_info *),BOOL rec, BOOL dirs)
+            void (*fn)(struct smbclient_context *, struct clilist_file_info *),bool rec, bool dirs)
 {
        static int in_do_list = 0;
 
@@ -628,7 +635,7 @@ static int cmd_dir(struct smbclient_context *ctx, const char **args)
                }
        }
 
-       do_list(ctx, mask, attribute, display_finfo, ctx->recurse, True);
+       do_list(ctx, mask, attribute, display_finfo, ctx->recurse, true);
 
        rc = do_dskattr(ctx);
 
@@ -659,7 +666,7 @@ static int cmd_du(struct smbclient_context *ctx, const char **args)
                mask = talloc_asprintf(ctx, "%s\\*", ctx->remote_cur_dir);
        }
 
-       do_list(ctx, mask, attribute, do_du, ctx->recurse, True);
+       do_list(ctx, mask, attribute, do_du, ctx->recurse, true);
 
        talloc_free(mask);
 
@@ -674,23 +681,26 @@ 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;
+       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;
        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);
@@ -715,7 +725,7 @@ static int do_get(struct smbclient_context *ctx, char *rname, const char *lname,
                } else {
                        handle = open(lname, O_WRONLY|O_CREAT|O_TRUNC, 0644);
                }
-               newhandle = True;
+               newhandle = true;
        }
        if (handle < 0) {
                d_printf("Error opening local file %s\n",lname);
@@ -818,24 +828,24 @@ static int cmd_get(struct smbclient_context *ctx, const char **args)
        
        dos_clean_name(rname);
        
-       return do_get(ctx, rname, lname, False);
+       return do_get(ctx, rname, lname, false);
 }
 
 /****************************************************************************
  Put up a yes/no prompt.
 ****************************************************************************/
-static BOOL yesno(char *p)
+static bool yesno(char *p)
 {
        char ans[4];
        printf("%s",p);
 
        if (!fgets(ans,sizeof(ans)-1,stdin))
-               return(False);
+               return(false);
 
        if (*ans == 'y' || *ans == 'Y')
-               return(True);
+               return(true);
 
-       return(False);
+       return(false);
 }
 
 /****************************************************************************
@@ -847,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;
@@ -862,35 +873,37 @@ static void do_mget(struct smbclient_context *ctx, struct clilist_file_info *fin
 
        if (!(finfo->attrib & FILE_ATTRIBUTE_DIRECTORY)) {
                asprintf(&rname, "%s%s",ctx->remote_cur_dir,finfo->name);
-               do_get(ctx, rname, finfo->name, False);
+               do_get(ctx, rname, finfo->name, false);
                SAFE_FREE(rname);
                return;
        }
 
        /* 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);
+       do_list(ctx, mget_mask, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY,do_mget,false, true);
        chdir("..");
        talloc_free(ctx->remote_cur_dir);
 
@@ -926,11 +939,11 @@ static int cmd_more(struct smbclient_context *ctx, const char **args)
        rname = talloc_asprintf(ctx, "%s%s", ctx->remote_cur_dir, args[1]);
        dos_clean_name(rname);
 
-       rc = do_get(ctx, rname, lname, False);
+       rc = do_get(ctx, rname, lname, false);
 
        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);
        
@@ -952,21 +965,21 @@ 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, "\\");
                
                mget_mask = talloc_strdup(ctx, args[i]);
                if (mget_mask[0] != '\\')
                        mget_mask = talloc_append_string(ctx, mget_mask, "\\");
-               do_list(ctx, mget_mask, attribute,do_mget,False,True);
+               do_list(ctx, mget_mask, attribute,do_mget,false,true);
 
                talloc_free(mget_mask);
        }
 
        if (mget_mask == NULL) {
                mget_mask = talloc_asprintf(ctx, "%s\\*", ctx->remote_cur_dir);
-               do_list(ctx, mget_mask, attribute,do_mget,False,True);
+               do_list(ctx, mget_mask, attribute,do_mget,false,true);
                talloc_free(mget_mask);
        }
        
@@ -1056,7 +1069,7 @@ static int cmd_altname(struct smbclient_context *ctx, const char **args)
        if (!NT_STATUS_IS_OK(smbcli_qpathinfo_alt_name(ctx->cli->tree, name, &altname))) {
                d_printf("%s getting alt name for %s\n",
                         smbcli_errstr(ctx->cli->tree),name);
-               return(False);
+               return(false);
        }
        d_printf("%s\n", altname);
 
@@ -1067,14 +1080,14 @@ static int cmd_altname(struct smbclient_context *ctx, const char **args)
 /****************************************************************************
   put a single file
   ****************************************************************************/
-static int do_put(struct smbclient_context *ctx, char *rname, char *lname, BOOL reput)
+static int do_put(struct smbclient_context *ctx, char *rname, char *lname, bool reput)
 {
        int fnum;
        XFILE *f;
        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;
@@ -1210,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);
 
@@ -1224,7 +1241,7 @@ static int cmd_put(struct smbclient_context *ctx, const char **args)
                return 1;
        }
 
-       return do_put(ctx, rname, lname, False);
+       return do_put(ctx, rname, lname, false);
 }
 
 /*************************************
@@ -1234,7 +1251,7 @@ static int cmd_put(struct smbclient_context *ctx, const char **args)
 static struct file_list {
        struct file_list *prev, *next;
        char *file_path;
-       BOOL isdir;
+       bool isdir;
 } *file_list;
 
 /****************************************************************************
@@ -1258,17 +1275,17 @@ static void free_file_list (struct file_list * list)
   seek in a directory/file list until you get something that doesn't start with
   the specified name
   ****************************************************************************/
-static BOOL seek_list(struct file_list *list, char *name)
+static bool seek_list(struct file_list *list, char *name)
 {
        while (list) {
                trim_string(list->file_path,"./","\n");
                if (strncmp(list->file_path, name, strlen(name)) != 0) {
-                       return(True);
+                       return(true);
                }
                list = list->next;
        }
       
-       return(False);
+       return(false);
 }
 
 /****************************************************************************
@@ -1277,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;
 }
@@ -1321,17 +1338,17 @@ static const char *readdirname(DIR *p)
 
 /****************************************************************************
   Recursive file matching function act as find
-  match must be always set to True when calling this function
+  match must be always set to true when calling this function
 ****************************************************************************/
 static int file_find(struct smbclient_context *ctx, struct file_list **list, const char *directory, 
-                     const char *expression, BOOL match)
+                     const char *expression, bool match)
 {
        DIR *dir;
        struct file_list *entry;
         struct stat statbuf;
         int ret;
         char *path;
-       BOOL isdir;
+       bool isdir;
        const char *dname;
 
         dir = opendir(directory);
@@ -1346,14 +1363,14 @@ static int file_find(struct smbclient_context *ctx, struct file_list **list, con
                        continue;
                }
 
-               isdir = False;
+               isdir = false;
                if (!match || !gen_fnmatch(expression, dname)) {
                        if (ctx->recurse) {
                                ret = stat(path, &statbuf);
                                if (ret == 0) {
                                        if (S_ISDIR(statbuf.st_mode)) {
-                                               isdir = True;
-                                               ret = file_find(ctx, list, path, expression, False);
+                                               isdir = true;
+                                               ret = file_find(ctx, list, path, expression, false);
                                        }
                                } else {
                                        d_printf("file_find: cannot stat file %s\n", path);
@@ -1399,7 +1416,7 @@ static int cmd_mput(struct smbclient_context *ctx, const char **args)
        
                file_list = NULL;
 
-               ret = file_find(ctx, &file_list, ".", args[i], True);
+               ret = file_find(ctx, &file_list, ".", args[i], true);
                if (ret) {
                        free_file_list(file_list);
                        continue;
@@ -1455,7 +1472,7 @@ static int cmd_mput(struct smbclient_context *ctx, const char **args)
 
                        dos_format(rname);
 
-                       do_put(ctx, rname, lname, False);
+                       do_put(ctx, rname, lname, false);
                }
                free_file_list(file_list);
                SAFE_FREE(quest);
@@ -1492,7 +1509,7 @@ static int cmd_print(struct smbclient_context *ctx, const char **args)
                slprintf(rname, sizeof(rname)-1, "stdin-%d", (int)getpid());
        }
 
-       return do_put(ctx, rname, lname, False);
+       return do_put(ctx, rname, lname, false);
 }
 
 
@@ -1518,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);
@@ -2470,7 +2487,7 @@ static int cmd_reget(struct smbclient_context *ctx, const char **args)
        else
                local_name = talloc_strdup(ctx, args[1]);
        
-       return do_get(ctx, remote_name, local_name, True);
+       return do_get(ctx, remote_name, local_name, true);
 }
 
 /****************************************************************************
@@ -2499,7 +2516,7 @@ static int cmd_reput(struct smbclient_context *ctx, const char **args)
        
        dos_clean_name(remote_name);
 
-       return do_put(ctx, remote_name, local_name, True);
+       return do_put(ctx, remote_name, local_name, true);
 }
 
 
@@ -2545,47 +2562,57 @@ 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 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", 
                         binding, nt_errstr(status));
                talloc_free(mem_ctx);
-               return False;
+               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));
 
@@ -2594,19 +2621,19 @@ static BOOL browse_host(const char *query_host)
        if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
                d_printf("Failed NetShareEnumAll %s - %s/%s\n", 
                         binding, nt_errstr(status), win_errstr(r.out.result));
-               return False;
+               return false;
        }
 
-       return False;
+       return false;
 }
 
 /****************************************************************************
 try and browse available connections on a host
 ****************************************************************************/
-static BOOL list_servers(const char *wk_grp)
+static bool list_servers(const char *wk_grp)
 {
        d_printf("REWRITE: list servers not implemented\n");
-       return False;
+       return false;
 }
 
 /* Some constants for completing filename arguments */
@@ -2747,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, ";");
@@ -2969,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;
 
@@ -2997,16 +3024,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 +3046,20 @@ 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 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_session_options *session_options,
+                          struct gensec_settings *gensec_settings)
 {
        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 +3072,12 @@ 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, 
+                                       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));
@@ -3055,9 +3091,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 tevent_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 +3105,28 @@ 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 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;
        struct smbcli_state *cli;
 
-       make_nbt_name_client(&calling, lp_netbios_name());
+       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,
+                   socket_options)) {
                d_printf("Connection to %s failed\n", server_name);
                return 1;
        }
@@ -3101,17 +3149,12 @@ static int do_message_op(const char *desthost, const char *destip, int name_type
 ****************************************************************************/
  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 */
+       bool message = false;
+       char *desthost = NULL;
        poptContext pc;
        const char *service = NULL;
        int port = 0;
@@ -3119,8 +3162,11 @@ 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 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
@@ -3129,7 +3175,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 +3192,9 @@ static int do_message_op(const char *desthost, const char *destip, int name_type
                exit(1);
        }
 
+       ctx = talloc_zero(mem_ctx, struct smbclient_context);
+       ctx->io_bufsize = 64512;
+
        pc = poptGetContext("smbclient", argc, (const char **) argv, long_options, 0);
        poptSetOtherOptionHelp(pc, "[OPTIONS] service <password>");
 
@@ -3160,7 +3208,7 @@ static int do_message_op(const char *desthost, const char *destip, int name_type
                        name_type = 0x03; 
                        desthost = strdup(poptGetOptArg(pc));
                        if( 0 == port ) port = 139;
-                       message = True;
+                       message = true;
                        break;
                case 'I':
                        dest_ip = poptGetOptArg(pc);
@@ -3168,19 +3216,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 +3255,11 @@ static int do_message_op(const char *desthost, const char *destip, int name_type
 
        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 ) );
 
        if (query_host && (p=strchr_m(query_host,'#'))) {
@@ -3219,27 +3269,40 @@ 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());
+               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, 
+                   lp_socket_options(cmdline_lp_ctx));
+               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,
+                       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;