I've added a dbgflush() function to debug.c. Calling this will cause the
[nivanova/samba-autobuild/.git] / source3 / client / client.c
index 9b7ce7ecb58225cc4bbc6e86661ae0c252b20078..d23bdb579667846b41a4cd03344f2565ab1dd83d 100644 (file)
@@ -2,7 +2,7 @@
    Unix SMB/Netbios implementation.
    Version 1.9.
    SMB client
-   Copyright (C) Andrew Tridgell 1994-1997
+   Copyright (C) Andrew Tridgell 1994-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"
 
@@ -33,13 +31,14 @@ pstring cur_dir = "\\";
 pstring cd_path = "";
 extern pstring service;
 extern pstring desthost;
-extern pstring myname;
+extern pstring global_myname;
 extern pstring myhostname;
 extern pstring password;
 extern pstring username;
 extern pstring workgroup;
 char *cmdstr="";
 extern BOOL got_pass;
+extern BOOL no_pass;
 extern BOOL connect_as_printer;
 extern BOOL connect_as_ipc;
 extern struct in_addr ipzero;
@@ -79,7 +78,7 @@ extern BOOL have_ip;
 extern int max_xmit;
 
 static int interpret_long_filename(int level,char *p,file_info *finfo);
-static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(),BOOL longdir);
+static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(file_info *),BOOL longdir, BOOL dirstoo);
 static int interpret_short_filename(char *p,file_info *finfo);
 static BOOL do_this_one(file_info *finfo);
 
@@ -129,13 +128,8 @@ extern int Client;
 
 #define USENMB
 
-static BOOL setup_term_code(char *code)
-{
-       interpret_coding_system(code);
-       return True;
-}
-#define CNV_LANG(s) dos2unix_format(s,False)
-#define CNV_INPUT(s) unix2dos_format(s,True)
+#define CNV_LANG(s) dos_to_unix(s,False)
+#define CNV_INPUT(s) unix_to_dos(s,True)
 
 /****************************************************************************
 send an SMBclose on an SMB file handle
@@ -152,7 +146,7 @@ void cli_smb_close(char *inbuf, char *outbuf, int clnt_fd, int c_num, int f_num)
   SIVALS(outbuf,smb_vwv1, -1);
   
   send_smb(clnt_fd, outbuf);
-  receive_smb(clnt_fd,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(clnt_fd,inbuf,CLIENT_TIMEOUT);
 }
 
 /****************************************************************************
@@ -244,7 +238,7 @@ static BOOL chkpath(char *path,BOOL report)
   pstring inbuf,outbuf;
   char *p;
 
-  strcpy(path2,path);
+  fstrcpy(path2,path);
   trim_string(path2,NULL,"\\");
   if (!*path2) *path2 = '\\';
 
@@ -256,7 +250,7 @@ static BOOL chkpath(char *path,BOOL report)
 
   p = smb_buf(outbuf);
   *p++ = 4;
-  strcpy(p,path2);
+  fstrcpy(p,path2);
 
 #if 0
   {
@@ -271,7 +265,7 @@ static BOOL chkpath(char *path,BOOL report)
 #endif
 
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
 
   if (report && CVAL(inbuf,smb_rcls) != 0)
     DEBUG(2,("chkpath: %s\n",smb_errstr(inbuf)));
@@ -298,10 +292,10 @@ static void send_message(char *inbuf,char *outbuf)
 
   p = smb_buf(outbuf);
   *p++ = 4;
-  strcpy(p,username);
+  pstrcpy(p,username);
   p = skip_string(p,1);
   *p++ = 4;
-  strcpy(p,desthost);
+  pstrcpy(p,desthost);
   p = skip_string(p,1);
 
   set_message(outbuf,0,PTR_DIFF(p,smb_buf(outbuf)),False);
@@ -309,7 +303,7 @@ static void send_message(char *inbuf,char *outbuf)
   send_smb(Client,outbuf);
   
 
-  if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
+  if (!client_receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
     {
       printf("SMBsendstrt failed. (%s)\n",smb_errstr(inbuf));
       return;
@@ -349,7 +343,7 @@ static void send_message(char *inbuf,char *outbuf)
       send_smb(Client,outbuf);
       
 
-      if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
+      if (!client_receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
        {
          printf("SMBsendtxt failed (%s)\n",smb_errstr(inbuf));
          return;
@@ -372,7 +366,7 @@ static void send_message(char *inbuf,char *outbuf)
   send_smb(Client,outbuf);
   
 
-  if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
+  if (!client_receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
     {
       printf("SMBsendend failed (%s)\n",smb_errstr(inbuf));
       return;
@@ -395,7 +389,7 @@ static void do_dskattr(void)
   cli_setup_pkt(outbuf);
 
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
 
   if (CVAL(inbuf,smb_rcls) != 0) 
     DEBUG(0,("Error in dskattr: %s\n",smb_errstr(inbuf)));      
@@ -409,7 +403,7 @@ static void do_dskattr(void)
 /****************************************************************************
 show cd/pwd
 ****************************************************************************/
-static void cmd_pwd(void)
+static void cmd_pwd(char *dum_in, char *dum_out)
 {
   DEBUG(0,("Current directory is %s",CNV_LANG(service)));
   DEBUG(0,("%s\n",CNV_LANG(cur_dir)));
@@ -427,24 +421,24 @@ static void do_cd(char *newdir)
       
   /* Save the current directory in case the
      new directory is invalid */
-  strcpy(saved_dir, cur_dir);
+  pstrcpy(saved_dir, cur_dir);
   if (*p == '\\')
-    strcpy(cur_dir,p);
+    pstrcpy(cur_dir,p);
   else
-    strcat(cur_dir,p);
+    pstrcat(cur_dir,p);
   if (*(cur_dir+strlen(cur_dir)-1) != '\\') {
-    strcat(cur_dir, "\\");
+    pstrcat(cur_dir, "\\");
   }
   dos_clean_name(cur_dir);
-  strcpy(dname,cur_dir);
-  strcat(cur_dir,"\\");
+  pstrcpy(dname,cur_dir);
+  pstrcat(cur_dir,"\\");
   dos_clean_name(cur_dir);
 
   if (!strequal(cur_dir,"\\"))
     if (!chkpath(dname,True))
-      strcpy(cur_dir,saved_dir);
+      pstrcpy(cur_dir,saved_dir);
 
-  strcpy(cd_path,cur_dir);
+  pstrcpy(cd_path,cur_dir);
 }
 
 /****************************************************************************
@@ -482,7 +476,7 @@ static void display_finfo(file_info *finfo)
   do a directory listing, calling fn on each file found. Use the TRANSACT2
   call for long filenames
   ****************************************************************************/
-static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
+static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(file_info *),BOOL recurse_dir, BOOL dirstoo)
 {
   int max_matches = 512;
   int info_level = Protocol<PROTOCOL_NT1?1:260; /* NT uses 260, OS/2 uses 2. Both accept 1. */
@@ -509,7 +503,7 @@ static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*
   uint16 setup;
   pstring param;
 
-  strcpy(mask,Mask);
+  pstrcpy(mask,Mask);
 
   while (ff_eos == 0)
     {
@@ -528,7 +522,7 @@ static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*
          SSVAL(param,4,8+4+2); /* resume required + close on end + continue */
          SSVAL(param,6,info_level); 
          SIVAL(param,8,0);
-         strcpy(param+12,mask);
+         pstrcpy(param+12,mask);
        }
       else
        {
@@ -538,7 +532,7 @@ static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*
          SSVAL(param,4,info_level); 
          SIVAL(param,6,ff_resume_key); /* ff_resume_key */
          SSVAL(param,10,8+4+2);        /* resume required + close on end + continue */
-         strcpy(param+12,mask);
+         pstrcpy(param+12,mask);
 
          DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
                   ff_dir_handle,ff_resume_key,ff_lastname,mask));
@@ -588,16 +582,16 @@ static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*
            case 260:
              ff_resume_key =0;
              StrnCpy(mask,p+ff_lastname,resp_data_len-ff_lastname);
-             /* strcpy(mask,p+ff_lastname+94); */
+             /* pstrcpy(mask,p+ff_lastname+94); */
              break;
            case 1:
-             strcpy(mask,p + ff_lastname + 1);
+             pstrcpy(mask,p + ff_lastname + 1);
              ff_resume_key = 0;
              break;
            }
        }
       else
-       strcpy(mask,"");
+       pstrcpy(mask,"");
   
       /* and add them to the dirlist pool */
       dirlist = Realloc(dirlist,dirlist_len + resp_data_len);
@@ -642,7 +636,7 @@ static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*
   for (p=dirlist,i=0;i<total_received;i++)
     {
       p += interpret_long_filename(info_level,p,&finfo);
-      dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,True);
+      dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,True, dirstoo);
     }
 
   /* free up the dirlist buffer */
@@ -654,7 +648,7 @@ static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*
 /****************************************************************************
   do a directory listing, calling fn on each file found
   ****************************************************************************/
-static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
+static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(file_info *),BOOL recurse_dir, BOOL dirstoo)
 {
   char *p;
   int received = 0;
@@ -671,7 +665,7 @@ static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (
 
   bzero(status,21);
 
-  strcpy(mask,Mask);
+  pstrcpy(mask,Mask);
   
   while (1)
     {
@@ -698,9 +692,9 @@ static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (
       *p++ = 4;
       
       if (first)
-       strcpy(p,mask);
+       pstrcpy(p,mask);
       else
-       strcpy(p,"");
+       pstrcpy(p,"");
       p += strlen(p) + 1;
       
       *p++ = 5;
@@ -714,7 +708,7 @@ static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (
        }
 
       send_smb(Client,outbuf);
-      receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+      client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
 
       received = SVAL(inbuf,smb_vwv0);
 
@@ -755,7 +749,7 @@ static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (
       p = smb_buf(outbuf);
       *p++ = 4;
       
-      strcpy(p,"");
+      pstrcpy(p,"");
       p += strlen(p) + 1;
       
       *p++ = 5;
@@ -764,7 +758,7 @@ static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (
       memcpy(p,status,21);
 
       send_smb(Client,outbuf);
-      receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+      client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
 
       if (CVAL(inbuf,smb_rcls) != 0) 
        DEBUG(0,("Error closing search: %s\n",smb_errstr(inbuf)));      
@@ -781,7 +775,7 @@ static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (
   for (p=dirlist,i=0;i<num_received;i++)
     {
       p += interpret_short_filename(p,&finfo);
-      dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,False);
+      dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,False,dirstoo);
     }
 
   if (dirlist) free(dirlist);
@@ -793,17 +787,17 @@ static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (
 /****************************************************************************
   do a directory listing, calling fn on each file found
   ****************************************************************************/
-void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
+void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(file_info *),BOOL recurse_dir, BOOL dirstoo)
 {
   DEBUG(5,("do_dir(%s,%x,%s)\n",Mask,attribute,BOOLSTR(recurse_dir)));
   if (Protocol >= PROTOCOL_LANMAN2)
     {
-      if (do_long_dir(inbuf,outbuf,Mask,attribute,fn,recurse_dir) > 0)
+      if (do_long_dir(inbuf,outbuf,Mask,attribute,fn,recurse_dir,dirstoo) > 0)
        return;
     }
 
   expand_mask(Mask,False);
-  do_short_dir(inbuf,outbuf,Mask,attribute,fn,recurse_dir);
+  do_short_dir(inbuf,outbuf,Mask,attribute,fn,recurse_dir,dirstoo);
   return;
 }
 
@@ -863,7 +857,7 @@ static int interpret_short_filename(char *p,file_info *finfo)
   finfo->ctime = make_unix_date(p+22);
   finfo->mtime = finfo->atime = finfo->ctime;
   finfo->size = IVAL(p,26);
-  strcpy(finfo->name,p+30);
+  pstrcpy(finfo->name,p+30);
   
   return(DIR_STRUCT_SIZE);
 }
@@ -890,7 +884,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
          finfo->mtime = make_unix_date2(p+12);
          finfo->size = IVAL(p,16);
          finfo->mode = CVAL(p,24);
-         strcpy(finfo->name,p+27);
+         pstrcpy(finfo->name,p+27);
        }
       return(28 + CVAL(p,26));
 
@@ -903,7 +897,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
          finfo->mtime = make_unix_date2(p+12);
          finfo->size = IVAL(p,16);
          finfo->mode = CVAL(p,24);
-         strcpy(finfo->name,p+31);
+         pstrcpy(finfo->name,p+31);
        }
       return(32 + CVAL(p,30));
 
@@ -917,7 +911,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
          finfo->mtime = make_unix_date2(p+16);
          finfo->size = IVAL(p,20);
          finfo->mode = CVAL(p,28);
-         strcpy(finfo->name,p+33);
+         pstrcpy(finfo->name,p+33);
        }
       return(SVAL(p,4)+4);
 
@@ -930,7 +924,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
          finfo->mtime = make_unix_date2(p+16);
          finfo->size = IVAL(p,20);
          finfo->mode = CVAL(p,28);
-         strcpy(finfo->name,p+37);
+         pstrcpy(finfo->name,p+37);
        }
       return(SVAL(p,4)+4);
 
@@ -977,8 +971,11 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
 
 /****************************************************************************
   act on the files in a dir listing
+
+  RJS, 4-Apr-1998, dirstoo added to allow caller to indicate that directories
+                   should be processed as well.
   ****************************************************************************/
-static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(),BOOL longdir)
+static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(file_info *),BOOL longdir, BOOL dirstoo)
 {
 
   if (!((finfo->mode & aDIR) == 0 && *fileselection && 
@@ -990,22 +987,27 @@ static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,B
        {
          pstring mask2;
          pstring sav_dir;
-         strcpy(sav_dir,cur_dir);
-         strcat(cur_dir,finfo->name);
-         strcat(cur_dir,"\\");
-         strcpy(mask2,cur_dir);
+
+          if (fn && dirstoo && do_this_one(finfo)) { /* Do dirs, RJS */
+           fn(finfo);
+         }
+
+         pstrcpy(sav_dir,cur_dir);
+         pstrcat(cur_dir,finfo->name);
+         pstrcat(cur_dir,"\\");
+         pstrcpy(mask2,cur_dir);
 
          if (!fn)
            DEBUG(0,("\n%s\n",CNV_LANG(cur_dir)));
 
-         strcat(mask2,"*");
+         pstrcat(mask2,"*");
 
          if (longdir)
-           do_long_dir(inbuf,outbuf,mask2,attribute,fn,True);      
+           do_long_dir(inbuf,outbuf,mask2,attribute,fn,True, dirstoo);      
          else
-           do_dir(inbuf,outbuf,mask2,attribute,fn,True);
+           do_dir(inbuf,outbuf,mask2,attribute,fn,True, dirstoo);
 
-         strcpy(cur_dir,sav_dir);
+         pstrcpy(cur_dir,sav_dir);
        }
       else
        {
@@ -1027,22 +1029,22 @@ static void cmd_dir(char *inbuf,char *outbuf)
   char *p=buf;
 
   dir_total = 0;
-  strcpy(mask,cur_dir);
+  pstrcpy(mask,cur_dir);
   if(mask[strlen(mask)-1]!='\\')
-    strcat(mask,"\\");
+    pstrcat(mask,"\\");
 
   if (next_token(NULL,buf,NULL))
     {
       if (*p == '\\')
-       strcpy(mask,p);
+       pstrcpy(mask,p);
       else
-       strcat(mask,p);
+       pstrcat(mask,p);
     }
   else {
-    strcat(mask,"*");
+    pstrcat(mask,"*");
   }
 
-  do_dir(inbuf,outbuf,mask,attribute,NULL,recurse);
+  do_dir(inbuf,outbuf,mask,attribute,NULL,recurse,False);
 
   do_dskattr();
 
@@ -1105,7 +1107,7 @@ static void do_get(char *rname,char *lname,file_info *finfo1)
   SSVAL(outbuf,smb_vwv12,0xffff);
   
   p = smb_buf(outbuf);
-  strcpy(p,rname);
+  pstrcpy(p,rname);
   p = skip_string(p,1);
 
   /* do a chained openX with a readX? */
@@ -1140,7 +1142,7 @@ static void do_get(char *rname,char *lname,file_info *finfo1)
     }
 
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
 
   if (CVAL(inbuf,smb_rcls) != 0)
     {
@@ -1158,7 +1160,7 @@ static void do_get(char *rname,char *lname,file_info *finfo1)
       return;
     }
 
-  strcpy(finfo.name,rname);
+  pstrcpy(finfo.name,rname);
 
   if (!finfo1)
     {
@@ -1267,7 +1269,7 @@ static void do_get(char *rname,char *lname,file_info *finfo1)
            }
          
          send_smb(Client,outbuf);
-         receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+         client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
          
          if (CVAL(inbuf,smb_rcls) != 0)
            {
@@ -1360,7 +1362,7 @@ static void do_get(char *rname,char *lname,file_info *finfo1)
          SSVAL(outbuf,smb_vwv4,finfo.size - nread);
 
          send_smb(Client,outbuf);
-         receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+         client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
 
          if (CVAL(inbuf,smb_rcls) != 0)
            {
@@ -1419,12 +1421,12 @@ static void do_get(char *rname,char *lname,file_info *finfo1)
     SIVALS(outbuf,smb_vwv1,0);
     p = smb_buf(outbuf);
     *p++ = 4;
-    strcpy(p,rname);
+    pstrcpy(p,rname);
     p += strlen(p)+1;
     *p++ = 4;
     *p = 0;
     send_smb(Client,outbuf);
-    receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+    client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
   }
 
   {
@@ -1450,14 +1452,14 @@ static void do_get(char *rname,char *lname,file_info *finfo1)
 /****************************************************************************
   get a file
   ****************************************************************************/
-static void cmd_get(void)
+static void cmd_get(char *dum_in, char *dum_out)
 {
   pstring lname;
   pstring rname;
   char *p;
 
-  strcpy(rname,cur_dir);
-  strcat(rname,"\\");
+  pstrcpy(rname,cur_dir);
+  pstrcat(rname,"\\");
 
   p = rname + strlen(rname);
 
@@ -1465,7 +1467,7 @@ static void cmd_get(void)
     DEBUG(0,("get <filename>\n"));
     return;
   }
-  strcpy(lname,p);
+  pstrcpy(lname,p);
   dos_clean_name(rname);
     
   next_token(NULL,lname,NULL);
@@ -1492,9 +1494,11 @@ static void do_mget(file_info *finfo)
     }
 
   if (finfo->mode & aDIR)
-    sprintf(quest,"Get directory %s? ",CNV_LANG(finfo->name));
+    slprintf(quest,sizeof(pstring)-1,
+            "Get directory %s? ",CNV_LANG(finfo->name));
   else
-    sprintf(quest,"Get file %s? ",CNV_LANG(finfo->name));
+    slprintf(quest,sizeof(pstring)-1,
+            "Get file %s? ",CNV_LANG(finfo->name));
 
   if (prompt && !yesno(quest)) return;
 
@@ -1513,10 +1517,10 @@ static void do_mget(file_info *finfo)
          return;
        }
 
-      strcpy(saved_curdir,cur_dir);
+      pstrcpy(saved_curdir,cur_dir);
 
-      strcat(cur_dir,finfo->name);
-      strcat(cur_dir,"\\");
+      pstrcat(cur_dir,finfo->name);
+      pstrcat(cur_dir,"\\");
 
       unix_format(finfo->name);
       {
@@ -1527,7 +1531,7 @@ static void do_mget(file_info *finfo)
            sys_mkdir(finfo->name,0777) != 0) 
          {
            DEBUG(0,("failed to create directory %s\n",CNV_LANG(finfo->name)));
-           strcpy(cur_dir,saved_curdir);
+           pstrcpy(cur_dir,saved_curdir);
            free(inbuf);free(outbuf);
            return;
          }
@@ -1535,25 +1539,25 @@ static void do_mget(file_info *finfo)
        if (sys_chdir(finfo->name) != 0)
          {
            DEBUG(0,("failed to chdir to directory %s\n",CNV_LANG(finfo->name)));
-           strcpy(cur_dir,saved_curdir);
+           pstrcpy(cur_dir,saved_curdir);
            free(inbuf);free(outbuf);
            return;
          }
       }       
 
-      strcpy(mget_mask,cur_dir);
-      strcat(mget_mask,"*");
+      pstrcpy(mget_mask,cur_dir);
+      pstrcat(mget_mask,"*");
       
       do_dir((char *)inbuf,(char *)outbuf,
-            mget_mask,aSYSTEM | aHIDDEN | aDIR,do_mget,False);
+            mget_mask,aSYSTEM | aHIDDEN | aDIR,do_mget,False, False);
       chdir("..");
-      strcpy(cur_dir,saved_curdir);
+      pstrcpy(cur_dir,saved_curdir);
       free(inbuf);free(outbuf);
     }
   else
     {
-      strcpy(rname,cur_dir);
-      strcat(rname,finfo->name);
+      pstrcpy(rname,cur_dir);
+      pstrcat(rname,finfo->name);
       do_get(rname,finfo->name,finfo);
     }
 }
@@ -1561,15 +1565,17 @@ static void do_mget(file_info *finfo)
 /****************************************************************************
 view the file using the pager
 ****************************************************************************/
-static void cmd_more(void)
+static void cmd_more(char *dum_in, char *dum_out)
 {
   fstring rname,lname,tmpname,pager_cmd;
   char *pager;
 
-  strcpy(rname,cur_dir);
-  strcat(rname,"\\");
-  sprintf(tmpname,"%s/smbmore.%d",tmpdir(),(int)getpid());
-  strcpy(lname,tmpname);
+  fstrcpy(rname,cur_dir);
+  fstrcat(rname,"\\");
+  slprintf(tmpname,
+          sizeof(fstring)-1,
+          "%s/smbmore.%d",tmpdir(),(int)getpid());
+  fstrcpy(lname,tmpname);
 
   if (!next_token(NULL,rname+strlen(rname),NULL)) {
     DEBUG(0,("more <filename>\n"));
@@ -1580,7 +1586,9 @@ static void cmd_more(void)
   do_get(rname,lname,NULL);
 
   pager=getenv("PAGER");
-  sprintf(pager_cmd,"%s %s",(pager? pager:PAGER), tmpname);
+
+  slprintf(pager_cmd,sizeof(pager_cmd)-1,
+          "%s %s",(pager? pager:PAGER), tmpname);
   system(pager_cmd);
   unlink(tmpname);
 }
@@ -1606,24 +1614,24 @@ static void cmd_mget(char *inbuf,char *outbuf)
 
   while (next_token(NULL,p,NULL))
     {
-      strcpy(mget_mask,cur_dir);
+      pstrcpy(mget_mask,cur_dir);
       if(mget_mask[strlen(mget_mask)-1]!='\\')
-       strcat(mget_mask,"\\");
+       pstrcat(mget_mask,"\\");
 
       if (*p == '\\')
-       strcpy(mget_mask,p);
+       pstrcpy(mget_mask,p);
       else
-       strcat(mget_mask,p);
-      do_dir((char *)inbuf,(char *)outbuf,mget_mask,attribute,do_mget,False);
+       pstrcat(mget_mask,p);
+      do_dir((char *)inbuf,(char *)outbuf,mget_mask,attribute,do_mget,False,False);
     }
 
   if (! *mget_mask)
     {
-      strcpy(mget_mask,cur_dir);
+      pstrcpy(mget_mask,cur_dir);
       if(mget_mask[strlen(mget_mask)-1]!='\\')
-       strcat(mget_mask,"\\");
-      strcat(mget_mask,"*");
-      do_dir((char *)inbuf,(char *)outbuf,mget_mask,attribute,do_mget,False);
+       pstrcat(mget_mask,"\\");
+      pstrcat(mget_mask,"*");
+      do_dir((char *)inbuf,(char *)outbuf,mget_mask,attribute,do_mget,False,False);
     }
 }
 
@@ -1654,10 +1662,10 @@ static BOOL do_mkdir(char *name)
   
   p = smb_buf(outbuf);
   *p++ = 4;      
-  strcpy(p,name);
+  pstrcpy(p,name);
   
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
   
   if (CVAL(inbuf,smb_rcls) != 0)
     {
@@ -1682,7 +1690,7 @@ static void cmd_mkdir(char *inbuf,char *outbuf)
   fstring buf;
   char *p=buf;
   
-  strcpy(mask,cur_dir);
+  pstrcpy(mask,cur_dir);
 
   if (!next_token(NULL,p,NULL))
     {
@@ -1690,7 +1698,7 @@ static void cmd_mkdir(char *inbuf,char *outbuf)
        DEBUG(0,("mkdir <dirname>\n"));
       return;
     }
-  strcat(mask,p);
+  pstrcat(mask,p);
 
   if (recurse)
     {
@@ -1698,17 +1706,17 @@ static void cmd_mkdir(char *inbuf,char *outbuf)
       pstring ddir2;
       *ddir2 = 0;
 
-      strcpy(ddir,mask);
+      pstrcpy(ddir,mask);
       trim_string(ddir,".",NULL);
       p = strtok(ddir,"/\\");
       while (p)
        {
-         strcat(ddir2,p);
+         pstrcat(ddir2,p);
          if (!chkpath(ddir2,False))
            {             
              do_mkdir(ddir2);
            }
-         strcat(ddir2,"\\");
+         pstrcat(ddir2,"\\");
          p = strtok(NULL,"/\\");
        }        
     }
@@ -1740,7 +1748,7 @@ static int smb_writeraw(char *outbuf,int fnum,int pos,char *buf,int n)
 
   send_smb(Client,outbuf);
   
-  if (!receive_smb(Client,inbuf,CLIENT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
+  if (!client_receive_smb(Client,inbuf,CLIENT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
     return(0);
 
   _smb_setlen(buf-4,n);                /* HACK! XXXX */
@@ -1748,7 +1756,7 @@ static int smb_writeraw(char *outbuf,int fnum,int pos,char *buf,int n)
   if (write_socket(Client,buf-4,n+4) != n+4)
     return(0);
 
-  if (!receive_smb(Client,inbuf,CLIENT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0) {
+  if (!client_receive_smb(Client,inbuf,CLIENT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0) {
     DEBUG(0,("Error writing remote file (2)\n"));
     return(0);
   }
@@ -1785,7 +1793,7 @@ static int smb_writefile(char *outbuf,int fnum,int pos,char *buf,int n)
   memcpy(smb_buf(outbuf)+3,buf,n);
 
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
 
   if (CVAL(inbuf,smb_rcls) != 0) {
     DEBUG(0,("%s writing remote file\n",smb_errstr(inbuf)));
@@ -1837,10 +1845,10 @@ static void do_put(char *rname,char *lname,file_info *finfo)
   
   p = smb_buf(outbuf);
   *p++ = 4;      
-  strcpy(p,rname);
+  pstrcpy(p,rname);
   
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
   
   if (CVAL(inbuf,smb_rcls) != 0)
     {
@@ -1850,7 +1858,15 @@ static void do_put(char *rname,char *lname,file_info *finfo)
       return;
     }
 
-  f = fopen(lname,"r");
+  /* allow files to be piped into smbclient
+     jdblair 24.jun.98 */
+  if (!strcmp(lname, "-")) {
+    f = stdin;
+    /* size of file is not known */
+    finfo->size = 0;
+  } else {
+    f = fopen(lname,"r");
+  }
 
   if (!f)
     {
@@ -1869,15 +1885,21 @@ static void do_put(char *rname,char *lname,file_info *finfo)
   if (!maxwrite)
     maxwrite = writebraw_supported?MAX(max_xmit,BUFFER_SIZE):(max_xmit-200);
 
-  while (nread < finfo->size)
+  /* This is a rewrite of the read/write loop that doesn't require the input
+     file to be of a known length.  This allows the stream pointer 'f' to
+     refer to stdin.
+
+     Rather than reallocing the read buffer every loop to keep it the min
+     necessary length this look uses a fixed length buffer and just tests
+     for eof on the file stream at the top of each loop.
+     jdblair, 24.jun.98 */
+
+  buf = (char *)malloc(maxwrite+4);
+  while (! feof(f) )
     {
       int n = maxwrite;
       int ret;
 
-      n = MIN(n,finfo->size - nread);
-
-      buf = (char *)Realloc(buf,n+4);
-  
       fseek(f,nread,SEEK_SET);
       if ((n = readfile(buf+4,1,n,f)) < 1)
        {
@@ -1900,8 +1922,6 @@ static void do_put(char *rname,char *lname,file_info *finfo)
       nread += n;
     }
 
-
-
   bzero(outbuf,smb_size);
   set_message(outbuf,3,0,True);
   CVAL(outbuf,smb_com) = SMBclose;
@@ -1912,7 +1932,7 @@ static void do_put(char *rname,char *lname,file_info *finfo)
   put_dos_date3(outbuf,smb_vwv1,close_time);
 
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
   
   if (CVAL(inbuf,smb_rcls) != 0)
     {
@@ -1943,14 +1963,14 @@ static void do_put(char *rname,char *lname,file_info *finfo)
             finfo->size / (1.024*this_time + 1.0e-4),
             put_total_size / (1.024*put_total_time_ms)));
   }
-} 
+}
 
  
 
 /****************************************************************************
   put a file
   ****************************************************************************/
-static void cmd_put(void)
+static void cmd_put(char *dum_in, char *dum_out)
 {
   pstring lname;
   pstring rname;
@@ -1959,8 +1979,8 @@ static void cmd_put(void)
   file_info finfo;
   finfo = def_finfo;
   
-  strcpy(rname,cur_dir);
-  strcat(rname,"\\");
+  pstrcpy(rname,cur_dir);
+  pstrcat(rname,"\\");
   
   
   if (!next_token(NULL,p,NULL))
@@ -1968,18 +1988,21 @@ static void cmd_put(void)
       DEBUG(0,("put <filename>\n"));
       return;
     }
-  strcpy(lname,p);
+  pstrcpy(lname,p);
   
   if (next_token(NULL,p,NULL))
-    strcat(rname,p);      
+    pstrcat(rname,p);      
   else
-    strcat(rname,lname);
+    pstrcat(rname,lname);
 
   dos_clean_name(rname);
 
   {
     struct stat st;
-    if (!file_exist(lname,&st)) {
+    /* allow '-' to represent stdin
+       jdblair, 24.jun.98 */
+    if (!file_exist(lname,&st) &&
+      (strcmp(lname,"-"))) {
       DEBUG(0,("%s does not exist\n",lname));
       return;
     }
@@ -2002,7 +2025,7 @@ static BOOL seek_list(FILE *f,char *name)
       trim_string(s,"./",NULL);
       if (strncmp(s,name,strlen(name)) != 0)
        {
-         strcpy(name,s);
+         pstrcpy(name,s);
          return(True);
        }
     }
@@ -2014,9 +2037,9 @@ static BOOL seek_list(FILE *f,char *name)
 /****************************************************************************
   set the file selection mask
   ****************************************************************************/
-static void cmd_select(void)
+static void cmd_select(char *dum_in, char *dum_out)
 {
-  strcpy(fileselection,"");
+  pstrcpy(fileselection,"");
   next_token(NULL,fileselection,NULL);
 }
 
@@ -2024,7 +2047,7 @@ static void cmd_select(void)
 /****************************************************************************
   mput some files
   ****************************************************************************/
-static void cmd_mput(void)
+static void cmd_mput(char *dum_in, char *dum_out)
 {
   pstring lname;
   pstring rname;
@@ -2042,11 +2065,14 @@ static void cmd_mput(void)
       pstring tmpname;
       FILE *f;
       
-      sprintf(tmpname,"%s/ls.smb.%d",tmpdir(),(int)getpid());
+      slprintf(tmpname,sizeof(pstring)-1,
+              "%s/ls.smb.%d",tmpdir(),(int)getpid());
       if (recurse)
-       sprintf(cmd,"find . -name \"%s\" -print > %s",p,tmpname);
+       slprintf(cmd,sizeof(pstring)-1,
+               "find . -name \"%s\" -print > %s",p,tmpname);
       else
-       sprintf(cmd,"/bin/ls %s > %s",p,tmpname);
+       slprintf(cmd,sizeof(pstring)-1,
+                "/bin/ls %s > %s",p,tmpname);
       system(cmd);
 
       f = fopen(tmpname,"r");
@@ -2065,19 +2091,20 @@ static void cmd_mput(void)
          if (directory_exist(lname,&st))
            {
              if (!recurse) continue;
-             sprintf(quest,"Put directory %s? ",lname);
+             slprintf(quest,sizeof(pstring)-1,
+                      "Put directory %s? ",lname);
              if (prompt && !yesno(quest)) 
                {
-                 strcat(lname,"/");
+                 pstrcat(lname,"/");
                  if (!seek_list(f,lname))
                    break;
                  goto again1;              
                }
              
-             strcpy(rname,cur_dir);
-             strcat(rname,lname);
+             pstrcpy(rname,cur_dir);
+             pstrcat(rname,lname);
              if (!chkpath(rname,False) && !do_mkdir(rname)) {
-               strcat(lname,"/");
+               pstrcat(lname,"/");
                if (!seek_list(f,lname))
                  break;
                goto again1;                              
@@ -2087,11 +2114,12 @@ static void cmd_mput(void)
            }
          else
            {
-             sprintf(quest,"Put file %s? ",lname);
+             slprintf(quest,sizeof(quest)-1,
+                      "Put file %s? ",lname);
              if (prompt && !yesno(quest)) continue;
 
-             strcpy(rname,cur_dir);
-             strcat(rname,lname);
+             pstrcpy(rname,cur_dir);
+             pstrcat(rname,lname);
            }
          dos_format(rname);
 
@@ -2124,9 +2152,9 @@ static void do_cancel(int job)
   p = param;
   SSVAL(p,0,81);               /* DosPrintJobDel() */
   p += 2;
-  strcpy(p,"W");
+  pstrcpy(p,"W");
   p = skip_string(p,1);
-  strcpy(p,"");
+  pstrcpy(p,"");
   p = skip_string(p,1);
   SSVAL(p,0,job);     
   p += 2;
@@ -2206,13 +2234,13 @@ static void cmd_print(char *inbuf,char *outbuf )
       return;
     }
 
-  strcpy(rname,lname);
+  pstrcpy(rname,lname);
   p = strrchr(rname,'/');
   if (p)
     {
       pstring tname;
-      strcpy(tname,p+1);
-      strcpy(rname,tname);
+      pstrcpy(tname,p+1);
+      pstrcpy(rname,tname);
     }
 
   if ((int)strlen(rname) > 14)
@@ -2221,7 +2249,7 @@ static void cmd_print(char *inbuf,char *outbuf )
   if (strequal(lname,"-"))
     {
       f = stdin;
-      strcpy(rname,"stdin");
+      pstrcpy(rname,"stdin");
     }
   
   dos_clean_name(rname);
@@ -2238,10 +2266,10 @@ static void cmd_print(char *inbuf,char *outbuf )
   
   p = smb_buf(outbuf);
   *p++ = 4;      
-  strcpy(p,rname);
+  pstrcpy(p,rname);
   
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
   
   if (CVAL(inbuf,smb_rcls) != 0)
     {
@@ -2295,7 +2323,7 @@ static void cmd_print(char *inbuf,char *outbuf )
       SSVAL(smb_buf(outbuf),1,n);
 
       send_smb(Client,outbuf);
-      receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+      client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
 
       if (CVAL(inbuf,smb_rcls) != 0)
        {
@@ -2317,7 +2345,7 @@ static void cmd_print(char *inbuf,char *outbuf )
   SSVAL(outbuf,smb_vwv0,fnum);
 
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
   
   if (CVAL(inbuf,smb_rcls) != 0)
     {
@@ -2351,7 +2379,7 @@ static void cmd_queue(char *inbuf,char *outbuf )
   SSVAL(outbuf,smb_vwv1,0); /* the index into the queue */
   
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
   
   if (CVAL(inbuf,smb_rcls) != 0)
     {
@@ -2376,13 +2404,13 @@ static void cmd_queue(char *inbuf,char *outbuf )
       {
        switch (CVAL(p,4))
          {
-         case 0x01: sprintf(status,"held or stopped"); break;
-         case 0x02: sprintf(status,"printing"); break;
-         case 0x03: sprintf(status,"awaiting print"); break;
-         case 0x04: sprintf(status,"in intercept"); break;
-         case 0x05: sprintf(status,"file had error"); break;
-         case 0x06: sprintf(status,"printer error"); break;
-         default: sprintf(status,"unknown"); break;
+         case 0x01: safe_strcpy(status,"held or stopped", sizeof(status)-1); break;
+         case 0x02: safe_strcpy(status,"printing",sizeof(status)-1); break;
+         case 0x03: safe_strcpy(status,"awaiting print", sizeof(status)-1); break;
+         case 0x04: safe_strcpy(status,"in intercept",sizeof(status)-1); break;
+         case 0x05: safe_strcpy(status,"file had error",sizeof(status)-1); break;
+         case 0x06: safe_strcpy(status,"printer error",sizeof(status)-1); break;
+         default: safe_strcpy(status,"unknown",sizeof(status)-1); break;
          }
 
        DEBUG(0,("%-6d   %-16.16s  %-9d    %s\n",
@@ -2417,21 +2445,21 @@ static void cmd_p_queue_4(char *inbuf,char *outbuf )
   p = param;
   SSVAL(p,0,76);                        /* API function number 76 (DosPrintJobEnum) */
   p += 2;
-  strcpy(p,"zWrLeh");                   /* parameter description? */
+  pstrcpy(p,"zWrLeh");                   /* parameter description? */
   p = skip_string(p,1);
-  strcpy(p,"WWzWWDDzz");                /* returned data format */
+  pstrcpy(p,"WWzWWDDzz");                /* returned data format */
   p = skip_string(p,1);
-  strcpy(p,strrchr(service,'\\')+1);    /* name of queue */
+  pstrcpy(p,strrchr(service,'\\')+1);    /* name of queue */
   p = skip_string(p,1);
   SSVAL(p,0,2);                 /* API function level 2, PRJINFO_2 data structure */
   SSVAL(p,2,1000);                      /* size of bytes of returned data buffer */
   p += 4;
-  strcpy(p,"");                         /* subformat */
+  pstrcpy(p,"");                         /* subformat */
   p = skip_string(p,1);
 
   DEBUG(1,("Calling DosPrintJobEnum()...\n"));
-  if( cli_call_api(PIPE_LANMAN, 0,PTR_DIFF(p,param), 0,
-               10, 0, 4096,
+  if( cli_call_api(PIPE_LANMAN, 0,PTR_DIFF(p,param), 0, 0,
+               10, 4096,
                &rprcnt, &rdrcnt,
                param, NULL, NULL,
                &rparam, &rdata) )
@@ -2452,9 +2480,9 @@ static void cmd_p_queue_4(char *inbuf,char *outbuf )
           char *JobName;
           char *JobTimeStr;
           time_t JobTime;
-          char PrinterName[20];
+          fstring PrinterName;
              
-          strcpy(PrinterName,strrchr(service,'\\')+1);       /* name of queue */
+          fstrcpy(PrinterName,strrchr(service,'\\')+1);       /* name of queue */
           strlower(PrinterName);                             /* in lower case */
 
           p = rdata;                          /* received data */
@@ -2524,16 +2552,16 @@ static void cmd_qinfo(char *inbuf,char *outbuf )
   p = param;
   SSVAL(p,0,70);                       /* API function number 70 (DosPrintQGetInfo) */
   p += 2;
-  strcpy(p,"zWrLh");                   /* parameter description? */
+  pstrcpy(p,"zWrLh");                  /* parameter description? */
   p = skip_string(p,1);
-  strcpy(p,"zWWWWzzzzWWzzl");          /* returned data format */
+  pstrcpy(p,"zWWWWzzzzWWzzl");         /* returned data format */
   p = skip_string(p,1);
-  strcpy(p,strrchr(service,'\\')+1);   /* name of queue */
+  pstrcpy(p,strrchr(service,'\\')+1);  /* name of queue */
   p = skip_string(p,1);
   SSVAL(p,0,3);                                /* API function level 3, just queue info, no job info */
   SSVAL(p,2,1000);                     /* size of bytes of returned data buffer */
   p += 4;
-  strcpy(p,"");                                /* subformat */
+  pstrcpy(p,"");                               /* subformat */
   p = skip_string(p,1);
 
   DEBUG(1,("Calling DosPrintQueueGetInfo()...\n"));
@@ -2619,8 +2647,8 @@ static void do_del(file_info *finfo)
   char *inbuf,*outbuf;
   pstring mask;
 
-  strcpy(mask,cur_dir);
-  strcat(mask,finfo->name);
+  pstrcpy(mask,cur_dir);
+  pstrcat(mask,finfo->name);
 
   if (finfo->mode & aDIR) 
     return;
@@ -2645,10 +2673,10 @@ static void do_del(file_info *finfo)
   
   p = smb_buf(outbuf);
   *p++ = 4;      
-  strcpy(p,mask);
+  pstrcpy(p,mask);
   
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
   
   if (CVAL(inbuf,smb_rcls) != 0)
     DEBUG(0,("%s deleting remote file %s\n",smb_errstr(inbuf),CNV_LANG(mask)));
@@ -2669,16 +2697,16 @@ static void cmd_del(char *inbuf,char *outbuf )
   if (recurse)
     attribute |= aDIR;
   
-  strcpy(mask,cur_dir);
+  pstrcpy(mask,cur_dir);
     
   if (!next_token(NULL,buf,NULL))
     {
       DEBUG(0,("del <filename>\n"));
       return;
     }
-  strcat(mask,buf);
+  pstrcat(mask,buf);
 
-  do_dir((char *)inbuf,(char *)outbuf,mask,attribute,do_del,False);
+  do_dir((char *)inbuf,(char *)outbuf,mask,attribute,do_del,False,False);
 }
 
 
@@ -2691,14 +2719,14 @@ static void cmd_rmdir(char *inbuf,char *outbuf )
   fstring buf;
   char *p;
   
-  strcpy(mask,cur_dir);
+  pstrcpy(mask,cur_dir);
   
   if (!next_token(NULL,buf,NULL))
     {
       DEBUG(0,("rmdir <dirname>\n"));
       return;
     }
-  strcat(mask,buf);
+  pstrcat(mask,buf);
 
   bzero(outbuf,smb_size);
   set_message(outbuf,0,2 + strlen(mask),True);
@@ -2710,10 +2738,10 @@ static void cmd_rmdir(char *inbuf,char *outbuf )
   
   p = smb_buf(outbuf);
   *p++ = 4;      
-  strcpy(p,mask);
+  pstrcpy(p,mask);
   
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
   
   if (CVAL(inbuf,smb_rcls) != 0)
     {
@@ -2732,16 +2760,16 @@ static void cmd_rename(char *inbuf,char *outbuf )
   fstring buf,buf2;
   char *p;
   
-  strcpy(src,cur_dir);
-  strcpy(dest,cur_dir);
+  pstrcpy(src,cur_dir);
+  pstrcpy(dest,cur_dir);
   
   if (!next_token(NULL,buf,NULL) || !next_token(NULL,buf2,NULL))
     {
       DEBUG(0,("rename <src> <dest>\n"));
       return;
     }
-  strcat(src,buf);
-  strcat(dest,buf2);
+  pstrcat(src,buf);
+  pstrcat(dest,buf2);
 
   bzero(outbuf,smb_size);
   set_message(outbuf,1,4 + strlen(src) + strlen(dest),True);
@@ -2753,13 +2781,13 @@ static void cmd_rename(char *inbuf,char *outbuf )
   
   p = smb_buf(outbuf);
   *p++ = 4;      
-  strcpy(p,src);
+  pstrcpy(p,src);
   p = skip_string(p,1);
   *p++ = 4;      
-  strcpy(p,dest);
+  pstrcpy(p,dest);
   
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
   
   if (CVAL(inbuf,smb_rcls) != 0)
     {
@@ -2773,7 +2801,7 @@ static void cmd_rename(char *inbuf,char *outbuf )
 /****************************************************************************
 toggle the prompt flag
 ****************************************************************************/
-static void cmd_prompt(void)
+static void cmd_prompt(char *dum_in, char *dum_out)
 {
   prompt = !prompt;
   DEBUG(2,("prompting is now %s\n",prompt?"on":"off"));
@@ -2783,7 +2811,7 @@ static void cmd_prompt(void)
 /****************************************************************************
 set the newer than time
 ****************************************************************************/
-static void cmd_newer(void)
+static void cmd_newer(char *dum_in, char *dum_out)
 {
   fstring buf;
   BOOL ok;
@@ -2806,7 +2834,7 @@ static void cmd_newer(void)
 /****************************************************************************
 set the archive level
 ****************************************************************************/
-static void cmd_archive(void)
+static void cmd_archive(char *dum_in, char *dum_out)
 {
   fstring buf;
 
@@ -2819,7 +2847,7 @@ static void cmd_archive(void)
 /****************************************************************************
 toggle the lowercaseflag
 ****************************************************************************/
-static void cmd_lowercase(void)
+static void cmd_lowercase(char *dum_in, char *dum_out)
 {
   lowercase = !lowercase;
   DEBUG(2,("filename lowercasing is now %s\n",lowercase?"on":"off"));
@@ -2831,7 +2859,7 @@ static void cmd_lowercase(void)
 /****************************************************************************
 toggle the recurse flag
 ****************************************************************************/
-static void cmd_recurse(void)
+static void cmd_recurse(char *dum_in, char *dum_out)
 {
   recurse = !recurse;
   DEBUG(2,("directory recursion is now %s\n",recurse?"on":"off"));
@@ -2840,7 +2868,7 @@ static void cmd_recurse(void)
 /****************************************************************************
 toggle the translate flag
 ****************************************************************************/
-static void cmd_translate(void)
+static void cmd_translate(char *dum_in, char *dum_out)
 {
   translation = !translation;
   DEBUG(2,("CR/LF<->LF and print text translation now %s\n",
@@ -2851,7 +2879,7 @@ static void cmd_translate(void)
 /****************************************************************************
 do a printmode command
 ****************************************************************************/
-static void cmd_printmode(void)
+static void cmd_printmode(char *dum_in, char *dum_out)
 {
   fstring buf;
   fstring mode;
@@ -2872,13 +2900,13 @@ static void cmd_printmode(void)
   switch(printmode)
     {
     case 0: 
-      strcpy(mode,"text");
+      fstrcpy(mode,"text");
       break;
     case 1: 
-      strcpy(mode,"graphics");
+      fstrcpy(mode,"graphics");
       break;
     default: 
-      sprintf(mode,"%d",printmode);
+      slprintf(mode,sizeof(mode)-1,"%d",printmode);
       break;
     }
 
@@ -2888,7 +2916,7 @@ static void cmd_printmode(void)
 /****************************************************************************
 do the lcd command
 ****************************************************************************/
-static void cmd_lcd(void)
+static void cmd_lcd(char *dum_in, char *dum_out)
 {
   fstring buf;
   pstring d;
@@ -2904,16 +2932,6 @@ try and browse available connections on a host
 ****************************************************************************/
 static BOOL browse_host(BOOL sort)
 {
-#ifdef NOSTRCASECMP
-/* If strcasecmp is already defined, remove it. */
-#ifdef strcasecmp
-#undef strcasecmp
-#endif /* strcasecmp */
-#define strcasecmp StrCaseCmp
-#endif /* NOSTRCASECMP */
-
-  extern int strcasecmp();
-
   char *rparam = NULL;
   char *rdata = NULL;
   char *p;
@@ -2925,9 +2943,9 @@ static BOOL browse_host(BOOL sort)
   p = param;
   SSVAL(p,0,0); /* api number */
   p += 2;
-  strcpy(p,"WrLeh");
+  pstrcpy(p,"WrLeh");
   p = skip_string(p,1);
-  strcpy(p,"B13BWz");
+  pstrcpy(p,"B13BWz");
   p = skip_string(p,1);
   SSVAL(p,0,1);
   SSVAL(p,2,BUFFER_SIZE);
@@ -2935,64 +2953,67 @@ static BOOL browse_host(BOOL sort)
 
   if (cli_call_api(PIPE_LANMAN, 0,PTR_DIFF(p,param),0, 0,
              1024, BUFFER_SIZE,
-               &rprcnt,&rdrcnt,
-              param,NULL, NULL,
-              &rparam,&rdata))
-    {
-      int res = SVAL(rparam,0);
-      int converter=SVAL(rparam,2);
-      int i;
-      BOOL long_share_name=False;
+             &rprcnt,&rdrcnt,
+             param,NULL, NULL,
+             &rparam,&rdata))
+  {
+    int res = SVAL(rparam,0);
+    int converter=SVAL(rparam,2);
+    int i;
+    BOOL long_share_name=False;
       
-      if (res == 0)
-       {
-         count=SVAL(rparam,4);
-         p = rdata;
+    if (res == 0 || res == ERRmoredata)
+    {
+      count=SVAL(rparam,4);
+      p = rdata;
 
-         if (count > 0)
-           {
-             printf("\n\tSharename      Type      Comment\n");
-             printf("\t---------      ----      -------\n");
-           }
+      if (count > 0)
+      {
+        printf("\n\tSharename      Type      Comment\n");
+        printf("\t---------      ----      -------\n");
+      }
 
-         if (sort)
-           qsort(p,count,20,QSORT_CAST strcasecmp);
+      if (sort)
+        qsort(p,count,20,QSORT_CAST StrCaseCmp);
 
-         for (i=0;i<count;i++)
-           {
-             char *sname = p;
-             int type = SVAL(p,14);
-             int comment_offset = IVAL(p,16) & 0xFFFF;
-             fstring typestr;
-             *typestr=0;
+      for (i=0;i<count;i++)
+      {
+        char *sname = p;
+        int type = SVAL(p,14);
+        int comment_offset = IVAL(p,16) & 0xFFFF;
+        fstring typestr;
+        *typestr=0;
 
-             switch (type)
-               {
-               case STYPE_DISKTREE:
-                 strcpy(typestr,"Disk"); break;
-               case STYPE_PRINTQ:
-                 strcpy(typestr,"Printer"); break;           
-               case STYPE_DEVICE:
-                 strcpy(typestr,"Device"); break;
-               case STYPE_IPC:
-                 strcpy(typestr,"IPC"); break;      
-               }
+        switch (type)
+        {
+          case STYPE_DISKTREE:
+            fstrcpy(typestr,"Disk"); break;
+          case STYPE_PRINTQ:
+            fstrcpy(typestr,"Printer"); break;       
+          case STYPE_DEVICE:
+            fstrcpy(typestr,"Device"); break;
+          case STYPE_IPC:
+            fstrcpy(typestr,"IPC"); break;      
+        }
 
-             printf("\t%-15.15s%-10.10s%s\n",
-                    sname,
-                    typestr,
-                    comment_offset?rdata+comment_offset-converter:"");
+        printf("\t%-15.15s%-10.10s%s\n",
+               sname, typestr,
+               comment_offset?rdata+comment_offset-converter:"");
          
-             if (strlen(sname)>8) long_share_name=True;
+        if (strlen(sname)>8) long_share_name=True;
          
-             p += 20;
-           }
+        p += 20;
+      }
 
-         if (long_share_name) {
-           printf("\nNOTE: There were share names longer than 8 chars.\nOn older clients these may not be accessible or may give browsing errors\n");
-         }
-       }
+      if (long_share_name) {
+        printf("\nNOTE: There were share names longer than 8 chars.\n\
+On older clients these may not be accessible or may give browsing errors\n");
+      }
+
+      if(res == ERRmoredata)
+        printf("\nNOTE: More data was available, the list was truncated.\n");
     }
+  }
   
   if (rparam) free(rparam);
   if (rdata) free(rdata);
@@ -3004,7 +3025,7 @@ static BOOL browse_host(BOOL sort)
 /****************************************************************************
 get some server info
 ****************************************************************************/
-static void server_info()
+static void server_info(void)
 {
   char *rparam = NULL;
   char *rdata = NULL;
@@ -3017,9 +3038,9 @@ static void server_info()
   p = param;
   SSVAL(p,0,63);               /* NetServerGetInfo()? */
   p += 2;
-  strcpy(p,"WrLh");
+  pstrcpy(p,"WrLh");
   p = skip_string(p,1);
-  strcpy(p,"zzzBBzz");
+  pstrcpy(p,"zzzBBzz");
   p = skip_string(p,1);
   SSVAL(p,0,10); /* level 10 */
   SSVAL(p,2,1000);
@@ -3079,10 +3100,10 @@ static BOOL list_servers(char *wk_grp)
   SSVAL(p,0,0x68); /* api number */
   p += 2;
 
-  strcpy(p,generic_request?"WrLehDO":"WrLehDz");
+  pstrcpy(p,generic_request?"WrLehDO":"WrLehDz");
   p = skip_string(p,1);
 
-  strcpy(p,"B16BBDz");
+  pstrcpy(p,"B16BBDz");
 
   p = skip_string(p,1);
   SSVAL(p,0,uLevel);
@@ -3093,7 +3114,7 @@ static BOOL list_servers(char *wk_grp)
   p += 4;
 
   if (!generic_request) {
-    strcpy(p, wk_grp);
+    pstrcpy(p, wk_grp);
     p = skip_string(p,1);
   }
 
@@ -3102,36 +3123,38 @@ static BOOL list_servers(char *wk_grp)
 
   if (cli_call_api(PIPE_LANMAN, 0,PTR_DIFF(p+4,param),0, 0,
            8, BUFFER_SIZE - SAFETY_MARGIN,
-              &rprcnt,&rdrcnt,
-              param,NULL, NULL,
-              &rparam,&rdata))
-    {
-      int res = SVAL(rparam,0);
-      int converter=SVAL(rparam,2);
-      int i;
-
-      if (res == 0) {  
-       char *p2 = rdata;
-       count=SVAL(rparam,4);
-
-       if (count > 0) {
-         printf("\n\nThis machine has a browse list:\n");
-         printf("\n\tServer               Comment\n");
-         printf("\t---------            -------\n");
-       }
+           &rprcnt,&rdrcnt,
+           param,NULL, NULL,
+           &rparam,&rdata))
+  {
+    int res = SVAL(rparam,0);
+    int converter=SVAL(rparam,2);
+    int i;
+
+    if (res == 0 || res == ERRmoredata) {      
+      char *p2 = rdata;
+      count=SVAL(rparam,4);
+
+      if (count > 0) {
+        printf("\n\nThis machine has a browse list:\n");
+        printf("\n\tServer               Comment\n");
+        printf("\t---------            -------\n");
+      }
        
-       for (i=0;i<count;i++) {
-         char *sname = p2;
-         int comment_offset = IVAL(p2,22) & 0xFFFF;
-         printf("\t%-16.16s     %s\n",
-                sname,
-                comment_offset?rdata+comment_offset-converter:"");
-
-         ok=True;
-         p2 += 26;
-       }
+      for (i=0;i<count;i++) {
+        char *sname = p2;
+        int comment_offset = IVAL(p2,22) & 0xFFFF;
+        printf("\t%-16.16s     %s\n", sname,
+               comment_offset?rdata+comment_offset-converter:"");
+
+        ok=True;
+        p2 += 26;
       }
+
+      if(res == ERRmoredata)
+        printf("\nNOTE: More data was available, the list was truncated.\n");
     }
+  }
 
   if (rparam) {free(rparam); rparam = NULL;}
   if (rdata) {free(rdata); rdata = NULL;}
@@ -3141,36 +3164,38 @@ static BOOL list_servers(char *wk_grp)
 
   if (cli_call_api(PIPE_LANMAN, 0,PTR_DIFF(p+4,param),0, 0,
            8, BUFFER_SIZE - SAFETY_MARGIN,
-              &rprcnt,&rdrcnt,
-              param,NULL, NULL,
-              &rparam,&rdata))
-    {
-      int res = SVAL(rparam,0);
-      int converter=SVAL(rparam,2);
-      int i;
-
-      if (res == 0) {
-       char *p2 = rdata;
-       count=SVAL(rparam,4);
-
-       if (count > 0) {
-         printf("\n\nThis machine has a workgroup list:\n");
-         printf("\n\tWorkgroup            Master\n");
-         printf("\t---------            -------\n");
-       }
+           &rprcnt,&rdrcnt,
+           param,NULL, NULL,
+           &rparam,&rdata))
+  {
+    int res = SVAL(rparam,0);
+    int converter=SVAL(rparam,2);
+    int i;
+
+    if (res == 0 || res == ERRmoredata) {
+      char *p2 = rdata;
+      count=SVAL(rparam,4);
+
+      if (count > 0) {
+        printf("\n\nThis machine has a workgroup list:\n");
+        printf("\n\tWorkgroup            Master\n");
+        printf("\t---------            -------\n");
+      }
        
-       for (i=0;i<count;i++) {
-         char *sname = p2;
-         int comment_offset = IVAL(p2,22) & 0xFFFF;
-         printf("\t%-16.16s     %s\n",
-                sname,
-                comment_offset?rdata+comment_offset-converter:"");
+      for (i=0;i<count;i++) {
+        char *sname = p2;
+        int comment_offset = IVAL(p2,22) & 0xFFFF;
+        printf("\t%-16.16s     %s\n", sname,
+               comment_offset?rdata+comment_offset-converter:"");
          
-         ok=True;
-         p2 += 26;
-       }
+        ok=True;
+        p2 += 26;
       }
+
+      if(res == ERRmoredata)
+        printf("\nNOTE: More data was available, the list was truncated.\n");
     }
+  }
 
   if (rparam) free(rparam);
   if (rdata) free(rdata);
@@ -3183,7 +3208,7 @@ static BOOL list_servers(char *wk_grp)
 struct
 {
   char *name;
-  void (*fn)();
+  void (*fn)(char *, char *);
   char *description;
 } commands[] = 
 {
@@ -3250,7 +3275,7 @@ static int process_tok(fstring tok)
          cmd = i;
          break;
        }
-      else if (strnequal(commands[i].name, tok, tok_len+1))
+      else if (strnequal(commands[i].name, tok, tok_len))
        {
          matches++;
          cmd = i;
@@ -3269,7 +3294,7 @@ static int process_tok(fstring tok)
 /****************************************************************************
 help
 ****************************************************************************/
-void cmd_help(void)
+void cmd_help(char *dum_in, char *dum_out)
 {
   int i=0,j;
   fstring buf;
@@ -3293,74 +3318,34 @@ void cmd_help(void)
 /****************************************************************************
 wait for keyboard activity, swallowing network packets
 ****************************************************************************/
-#ifdef CLIX
-static char wait_keyboard(char *buffer)
-#else
 static void wait_keyboard(char *buffer)
-#endif
 {
   fd_set fds;
   int selrtn;
   struct timeval timeout;
   
-#ifdef CLIX
-  int delay = 0;
-#endif
-  
   while (1) 
     {
       extern int Client;
       FD_ZERO(&fds);
       FD_SET(Client,&fds);
-#ifndef CLIX
       FD_SET(fileno(stdin),&fds);
-#endif
 
       timeout.tv_sec = 20;
       timeout.tv_usec = 0;
-#ifdef CLIX
-      timeout.tv_sec = 0;
-#endif
       selrtn = sys_select(&fds,&timeout);
       
-#ifndef CLIX
       if (FD_ISSET(fileno(stdin),&fds))
        return;
-#else
-      {
-       char ch;
-       int readret;
 
-    set_blocking(fileno(stdin), False);        
-       readret = read_data( fileno(stdin), &ch, 1);
-       set_blocking(fileno(stdin), True);
-       if (readret == -1)
-         {
-           if (errno != EAGAIN)
-             {
-               /* should crash here */
-               DEBUG(1,("readchar stdin failed\n"));
-             }
-         }
-       else if (readret != 0)
-         {
-           return ch;
-         }
-      }
-#endif
+      /* We deliberately use receive_smb instead of
+         client_receive_smb as we want to receive
+         session keepalives and then drop them here.
+       */
       if (FD_ISSET(Client,&fds))
        receive_smb(Client,buffer,0);
       
-#ifdef CLIX
-      delay++;
-      if (delay > 100000)
-       {
-         delay = 0;
-         chkpath("\\",False);
-       }
-#else
       chkpath("\\",False);
-#endif
     }  
 }
 
@@ -3382,7 +3367,7 @@ static BOOL process(char *base_directory)
   
   bzero(OutBuffer,smb_size);
 
-  if (!cli_send_login(InBuffer,OutBuffer,True,True))
+  if (!cli_send_login(InBuffer,OutBuffer,True,True,NULL))
     return(False);
 
   if (*base_directory) do_cd(base_directory);
@@ -3433,24 +3418,13 @@ static BOOL process(char *base_directory)
 
       /* display a prompt */
       DEBUG(0,("smb: %s> ", CNV_LANG(cur_dir)));
-      fflush(dbf);
+      dbgflush( );
 
-#ifdef CLIX
-      line[0] = wait_keyboard(InBuffer);
-      /* this might not be such a good idea... */
-      if ( line[0] == EOF)
-       break;
-#else
       wait_keyboard(InBuffer);
-#endif
   
       /* and get a response */
-#ifdef CLIX
-      fgets( &line[1],999, stdin);
-#else
       if (!fgets(line,1000,stdin))
        break;
-#endif
 
       /* input language code to internal one */
       CNV_INPUT (line);
@@ -3476,7 +3450,7 @@ static BOOL process(char *base_directory)
        DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
     }
   
-  cli_send_logout();
+  cli_send_logout(InBuffer,OutBuffer);
   return(True);
 }
 
@@ -3489,7 +3463,7 @@ static void usage(char *pname)
           pname));
 
   DEBUG(0,("\nVersion %s\n",VERSION));
-  DEBUG(0,("\t-p port               listen on the specified port\n"));
+  DEBUG(0,("\t-p port               connect to the specified port\n"));
   DEBUG(0,("\t-d debuglevel         set the debuglevel\n"));
   DEBUG(0,("\t-l log basename.      Basename for log/debug files\n"));
   DEBUG(0,("\t-n netbios name.      Use this name as my netbios name\n"));
@@ -3499,6 +3473,7 @@ static void usage(char *pname)
   DEBUG(0,("\t-m max protocol       set the max protocol level\n"));
   DEBUG(0,("\t-L host               get a list of shares available on a host\n"));
   DEBUG(0,("\t-I dest IP            use this IP to connect to\n"));
+  DEBUG(0,("\t-R name resolve order use these name resolution services only\n"));
   DEBUG(0,("\t-E                    write messages to stderr instead of stdout\n"));
   DEBUG(0,("\t-U username           set the network username\n"));
   DEBUG(0,("\t-W workgroup          set the workgroup name\n"));
@@ -3524,13 +3499,15 @@ static void usage(char *pname)
   pstring query_host;
   BOOL message = False;
   BOOL nt_domain_logon = False;
+  BOOL explicit_user = False;
   extern char tar_type;
   static pstring servicesf = CONFIGFILE;
   pstring term_code;
+  pstring new_name_resolve_order;
   char *p;
 
 #ifdef KANJI
-  strcpy(term_code, KANJI);
+  pstrcpy(term_code, KANJI);
 #else /* KANJI */
   *term_code = 0;
 #endif /* KANJI */
@@ -3538,6 +3515,8 @@ static void usage(char *pname)
   *query_host = 0;
   *base_directory = 0;
 
+  *new_name_resolve_order = 0;
+
   DEBUGLEVEL = 2;
 
   setup_logging(pname,True);
@@ -3545,6 +3524,26 @@ static void usage(char *pname)
   TimeInit();
   charset_initialise();
 
+  if(!get_myname(myhostname,NULL))
+  {
+    DEBUG(0,("Failed to get my hostname.\n"));
+  }
+
+  if (!lp_load(servicesf,True,False,False)) {
+    fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
+  }
+
+  codepage_initialise(lp_client_code_page());
+
+  interpret_coding_system(term_code);
+
+#ifdef WITH_SSL
+  sslutil_init(0);
+#endif
+
+  pstrcpy(workgroup,lp_workgroup());
+
+  load_interfaces();
   pid = getpid();
   uid = getuid();
   gid = getgid();
@@ -3554,7 +3553,7 @@ static void usage(char *pname)
 
   if (getenv("USER"))
   {
-    strcpy(username,getenv("USER"));
+    pstrcpy(username,getenv("USER"));
 
     /* modification to support userid%passwd syntax in the USER var
        25.Aug.97, jdblair@uab.edu */
@@ -3562,7 +3561,7 @@ static void usage(char *pname)
     if ((p=strchr(username,'%')))
     {
       *p = 0;
-      strcpy(password,p+1);
+      pstrcpy(password,p+1);
       got_pass = True;
       memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
     }
@@ -3572,12 +3571,14 @@ static void usage(char *pname)
  /* modification to support PASSWD environmental var
   25.Aug.97, jdblair@uab.edu */
 
-  if (getenv("PASSWD"))
-    strcpy(password,getenv("PASSWD"));
+  if (getenv("PASSWD")) {
+    pstrcpy(password,getenv("PASSWD"));
+    got_pass = True;
+  }
 
   if (*username == 0 && getenv("LOGNAME"))
     {
-      strcpy(username,getenv("LOGNAME"));
+      pstrcpy(username,getenv("LOGNAME"));
       strupper(username);
     }
 
@@ -3590,7 +3591,7 @@ static void usage(char *pname)
   if (*argv[1] != '-')
     {
 
-      strcpy(service,argv[1]);  
+      pstrcpy(service,argv[1]);  
       /* Convert any '/' characters in the service name to '\' characters */
       string_replace( service, '/','\\');
       argc--;
@@ -3615,7 +3616,7 @@ static void usage(char *pname)
       if (argc > 1 && (*argv[1] != '-'))
        {
          got_pass = True;
-         strcpy(password,argv[1]);  
+         pstrcpy(password,argv[1]);  
          memset(argv[1],'X',strlen(argv[1]));
          argc--;
          argv++;
@@ -3623,23 +3624,26 @@ static void usage(char *pname)
     }
 
   while ((opt = 
-         getopt(argc, argv,"s:B:O:M:S:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
+         getopt(argc, argv,"s:B:O:R:M:S:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
     switch (opt)
       {
       case 'm':
        max_protocol = interpret_protocol(optarg,max_protocol);
        break;
       case 'O':
-       strcpy(user_socket_options,optarg);
+       pstrcpy(user_socket_options,optarg);
        break;  
+      case 'R':
+        pstrcpy(new_name_resolve_order, optarg);
+        break;
       case 'S':
-       strcpy(desthost,optarg);
+       pstrcpy(desthost,optarg);
        strupper(desthost);
        nt_domain_logon = True;
        break;
       case 'M':
        name_type = 0x03; /* messages are sent to NetBIOS name type 0x3 */
-       strcpy(desthost,optarg);
+       pstrcpy(desthost,optarg);
        strupper(desthost);
        message = True;
        break;
@@ -3647,7 +3651,7 @@ static void usage(char *pname)
        iface_set_default(NULL,optarg,NULL);
        break;
       case 'D':
-       strcpy(base_directory,optarg);
+       pstrcpy(base_directory,optarg);
        break;
       case 'T':
        if (!tar_parseargs(argc, argv, optarg, optind)) {
@@ -3656,20 +3660,23 @@ static void usage(char *pname)
        }
        break;
       case 'i':
-       strcpy(scope,optarg);
+       pstrcpy(scope,optarg);
        break;
       case 'L':
        got_pass = True;
-       strcpy(query_host,optarg);
+       pstrcpy(query_host,optarg);
+    if(!explicit_user)
+      *username = '\0';
        break;
       case 'U':
        {
          char *lp;
-       strcpy(username,optarg);
-       if ((lp=strchr(username,'%')))
+      explicit_user = True;
+      pstrcpy(username,optarg);
+      if ((lp=strchr(username,'%')))
          {
            *lp = 0;
-           strcpy(password,lp+1);
+           pstrcpy(password,lp+1);
            got_pass = True;
            memset(strchr(optarg,'%')+1,'X',strlen(password));
          }
@@ -3677,7 +3684,7 @@ static void usage(char *pname)
            
        break;
       case 'W':
-       strcpy(workgroup,optarg);
+       pstrcpy(workgroup,optarg);
        break;
       case 'E':
        dbf = stderr;
@@ -3690,10 +3697,11 @@ static void usage(char *pname)
        }
        break;
       case 'n':
-       strcpy(myname,optarg);
+       pstrcpy(global_myname,optarg);
        break;
       case 'N':
        got_pass = True;
+       no_pass = True;
        break;
       case 'P':
        connect_as_printer = True;
@@ -3705,7 +3713,7 @@ static void usage(char *pname)
          DEBUGLEVEL = atoi(optarg);
        break;
       case 'l':
-       sprintf(debugf,"%s.client",optarg);
+       slprintf(debugf,sizeof(debugf)-1, "%s.client",optarg);
        break;
       case 'p':
        port = atoi(optarg);
@@ -3719,16 +3727,22 @@ static void usage(char *pname)
        exit(0);
        break;
       case 's':
-       strcpy(servicesf, optarg);
+       pstrcpy(servicesf, optarg);
        break;
       case 't':
-        strcpy(term_code, optarg);
+        pstrcpy(term_code, optarg);
        break;
       default:
        usage(pname);
        exit(1);
       }
 
+  get_myname((*global_myname)?NULL:global_myname,NULL);  
+  strupper(global_myname);
+
+  if(*new_name_resolve_order)
+    lp_set_name_resolve_order(new_name_resolve_order);
+
   if (!tar_type && !*query_host && !*service && !message)
     {
       usage(pname);
@@ -3736,35 +3750,7 @@ static void usage(char *pname)
     }
 
 
-  DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION));
-
-  if(!get_myname(myhostname,NULL))
-  {
-    DEBUG(0,("Failed to get my hostname.\n"));
-  }
-
-  if (!lp_load(servicesf,True)) {
-    fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
-  }
-
-  codepage_initialise(lp_client_code_page());
-
-  if(lp_client_code_page() == KANJI_CODEPAGE)
-  {
-        if (!setup_term_code (term_code))
-    {
-            DEBUG(0, ("%s: unknown terminal code name\n", optarg));
-            usage (pname);
-            exit (1);
-        }
-  }
-
-  if (*workgroup == 0)
-    strcpy(workgroup,lp_workgroup());
-
-  load_interfaces();
-  get_myname((*myname)?NULL:myname,NULL);  
-  strupper(myname);
+  DEBUG( 3, ( "Client started (version %s).\n", VERSION ) );
 
   if (tar_type) {
     recurse=True;
@@ -3778,14 +3764,14 @@ static void usage(char *pname)
          return(1);
 
        bzero(OutBuffer,smb_size);
-       if (!cli_send_login(InBuffer,OutBuffer,True,True))
+       if (!cli_send_login(InBuffer,OutBuffer,True,True,NULL))
          return(False);
 
        if (*base_directory) do_cd(base_directory);
 
        ret=process_tar(InBuffer, OutBuffer);
 
-       cli_send_logout();
+       cli_send_logout(InBuffer, OutBuffer);
        close_sockets();
        return(ret);
     } else
@@ -3795,7 +3781,8 @@ static void usage(char *pname)
   if (*query_host && !nt_domain_logon)
     {
       int ret = 0;
-      sprintf(service,"\\\\%s\\IPC$",query_host);
+      slprintf(service,sizeof(service)-1,
+              "\\\\%s\\IPC$",query_host);
       strupper(service);
       connect_as_ipc = True;
       if (cli_open_sockets(port))
@@ -3803,7 +3790,7 @@ static void usage(char *pname)
 #if 0
          *username = 0;
 #endif
-         if (!cli_send_login(NULL,NULL,True,True))
+         if (!cli_send_login(NULL,NULL,True,True,NULL))
            return(1);
 
          server_info();
@@ -3816,7 +3803,7 @@ static void usage(char *pname)
            list_servers(workgroup);
          }
 
-         cli_send_logout();
+         cli_send_logout(NULL,NULL);
          close_sockets();
        }
 
@@ -3841,31 +3828,6 @@ static void usage(char *pname)
       return(ret);
     }
 
-#ifdef NTDOMAIN
-
-       if (nt_domain_logon)
-       {
-               int ret = 0;
-               sprintf(service,"\\\\%s\\IPC$",query_host);
-               strupper(service);
-               connect_as_ipc = True;
-
-               DEBUG(5,("NT Domain Logon.  Service: %s\n", service));
-
-               if (cli_open_sockets(port))
-               {
-                       if (!cli_send_login(NULL,NULL,True,True)) return(1);
-
-                       do_nt_login(desthost, myhostname, Client, cnum);
-
-                       cli_send_logout();
-                       close_sockets();
-               }
-
-               return(ret);
-       }
-#endif 
-
   if (cli_open_sockets(port))
     {
       if (!process(base_directory))