converted smbclient to use clientgen.c rather than clientutil.c
authorAndrew Tridgell <tridge@samba.org>
Mon, 9 Nov 1998 03:45:49 +0000 (03:45 +0000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 9 Nov 1998 03:45:49 +0000 (03:45 +0000)
I did this when I saw yet another bug report complaining about
smbclient intermittently missing files. Rather than applying more
patches to smbclient it was better to move to the more robust
clientgen.c code.

The conversion wasn't perfect, I probably lost some features of
smbclient while doing it, but at least smbclient should be consistent
now. It if fails it should _always_ fail rather than giving people the
false impression of a reliable utility.

the tar stuff seems to work, but hasn't had much testing as I never
use it myself. I'm sure someone will find bugs in my conversion of
smbtar.c. It was quite tricky as it did a lot of its own SMB calls. It
now uses clientgen.c exclusively.

smbclient is still quite messy, but at least it doesn't build its own
SMB packets.

I haven't touched smbmount as I never use it. Mike, do you want to
convert smbmount to use clientgen.c?
(This used to be commit e14ca7765ace1b721dad8eca4a527a4e4a8f1ab8)

source3/Makefile.in
source3/client/client.c
source3/client/clitar.c
source3/include/proto.h
source3/libsmb/clientgen.c
source3/smbd/dfree.c
source3/smbd/password.c
source3/smbwrapper/shared.c
source3/smbwrapper/smbw_dir.c
source3/utils/smbpasswd.c

index 8d194ffaa4cd2da7556942244c6179a0e20a730a..a4a234ba3555d5298168fa0f2b41bd8775700039 100644 (file)
@@ -204,7 +204,7 @@ SMBWRAPPER_OBJ = smbwrapper/smbw.o smbwrapper/wrapped.o \
                $(LIBSMB_OBJ) $(PARAM_OBJ) \
                 $(UBIQX_OBJ) $(LIB_OBJ)
 
-CLIENT_OBJ = client/client.o client/clientutil.o client/clitar.o \
+CLIENT_OBJ = client/client.o client/clitar.o \
              $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
 
 MOUNT_OBJ = client/smbmount.o client/clientutil.o \
index eceadbe09cd40088f5075668d30b599b92bab24d..13f5adec05c2395cf3865d01e06937fee63e173e 100644 (file)
 #define REGISTER 0
 #endif
 
+struct cli_state *cli;
 extern BOOL in_client;
 pstring cur_dir = "\\";
 pstring cd_path = "";
-extern pstring service;
-extern pstring desthost;
+static pstring service;
+static pstring desthost;
 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;
+static pstring password;
+static pstring username;
+static pstring workgroup;
+static char *cmdstr;
+static BOOL got_pass;
+static BOOL no_pass;
 extern struct in_addr ipzero;
+extern pstring scope;
 
-extern BOOL doencrypt;
+static int name_type = 0x20;
 
 extern pstring user_socket_options;
 
 static int process_tok(fstring tok);
-static void cmd_help(char *dum_in, char *dum_out);
+static void cmd_help(void);
 
 /* 30 second timeout on most commands */
 #define CLIENT_TIMEOUT (30*1000)
@@ -58,11 +58,6 @@ static void cmd_help(char *dum_in, char *dum_out);
 /* value for unused fid field in trans2 secondary request */
 #define FID_UNUSED (0xFFFF)
 
-extern int name_type;
-
-extern int max_protocol;
-
-
 time_t newer_than = 0;
 int archive_level = 0;
 
@@ -71,18 +66,7 @@ extern int DEBUGLEVEL;
 
 BOOL translation = False;
 
-extern uint16 cnum;
-extern uint16 mid;
-extern uint16 pid;
-extern uint16 vuid;
-
-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)(file_info *),BOOL longdir, BOOL dirstoo);
-static int interpret_short_filename(char *p,file_info *finfo);
-static BOOL do_this_one(file_info *finfo);
+static BOOL have_ip;
 
 /* clitar bits insert */
 extern int blocksize;
@@ -93,13 +77,11 @@ extern BOOL tar_reset;
 
 mode_t myumask = 0755;
 
-extern pstring scope;
-
 BOOL prompt = True;
 
 int printmode = 1;
 
-BOOL recurse = False;
+static BOOL recurse = False;
 BOOL lowercase = False;
 
 struct in_addr dest_ip;
@@ -108,11 +90,6 @@ struct in_addr dest_ip;
 
 BOOL abort_mget = True;
 
-extern int Protocol;
-
-extern BOOL readbraw_supported ;
-extern BOOL writebraw_supported;
-
 pstring fileselection = "";
 
 extern file_info def_finfo;
@@ -126,31 +103,11 @@ int put_total_time_ms = 0;
 /* totals globals */
 int dir_total = 0;
 
-extern int Client;
-
 #define USENMB
 
 #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
-****************************************************************************/
-static void cli_smb_close(char *inbuf, char *outbuf, int clnt_fd, int c_num, int f_num)
-{
-  bzero(outbuf,smb_size);
-  set_message(outbuf,3,0,True);
-
-  CVAL (outbuf,smb_com) = SMBclose;
-  SSVAL(outbuf,smb_tid,c_num);
-  cli_setup_pkt(outbuf);
-  SSVAL (outbuf,smb_vwv0, f_num);
-  SIVALS(outbuf,smb_vwv1, -1);
-  
-  send_smb(clnt_fd, outbuf);
-  client_receive_smb(clnt_fd,inbuf,CLIENT_TIMEOUT);
-}
-
 
 /****************************************************************************
 write to a local file with CR/LF->LF translation if appropriate. return the 
@@ -158,27 +115,25 @@ number taken from the buffer. This may not equal the number written.
 ****************************************************************************/
 static int writefile(int f, char *b, int n)
 {
-  int i;
+       int i;
 
-  if (!translation)
-    return(write(f,b,n));
-  
-  i = 0;
-  while (i < n)
-    {
-      if (*b == '\r' && (i<(n-1)) && *(b+1) == '\n')
-       {
-         b++;i++;
+       if (!translation) {
+               return write(f,b,n);
        }
-      if (write(f, b, 1) != 1)
-       {
-         break;
+
+       i = 0;
+       while (i < n) {
+               if (*b == '\r' && (i<(n-1)) && *(b+1) == '\n') {
+                       b++;i++;
+               }
+               if (write(f, b, 1) != 1) {
+                       break;
+               }
+               b++;
+               i++;
        }
-      b++;
-      i++;
-    }
   
-  return(i);
+       return(i);
 }
 
 /****************************************************************************
@@ -187,193 +142,78 @@ static int writefile(int f, char *b, int n)
 ****************************************************************************/
 static int readfile(char *b, int size, int n, FILE *f)
 {
-  int i;
-  int c;
+       int i;
+       int c;
 
-  if (!translation || (size != 1))
-    return(fread(b,size,n,f));
+       if (!translation || (size != 1))
+               return(fread(b,size,n,f));
   
-  i = 0;
-  while (i < n)
-    {
-      if ((c = getc(f)) == EOF)
-       {
-         break;
-       }
+       i = 0;
+       while (i < n) {
+               if ((c = getc(f)) == EOF) {
+                       break;
+               }
       
-      if (c == '\n') /* change all LFs to CR/LF */
-       {
-         b[i++] = '\r';
-         n++;
-       }
+               if (c == '\n') { /* change all LFs to CR/LF */
+                       b[i++] = '\r';
+                       n++;
+               }
       
-      if(i < n)
-        b[i++] = c;
-    }
+               if(i < n)
+                       b[i++] = c;
+       }
   
-  return(i);
+       return(i);
 }
  
 
-/****************************************************************************
-read from a file with print translation. return the number read. read approx n
-bytes.
-****************************************************************************/
-static int printread(FILE *f,char *b,int n)
-{
-  int i;
-
-  i = readfile(b,1, n-1,f);
-#if FORMFEED
-  if (feof(f) && i>0)
-    b[i++] = '\014';
-#endif
-
-  return(i);
-}
-
-/****************************************************************************
-check for existance of a dir
-****************************************************************************/
-static BOOL chkpath(char *path,BOOL report)
-{
-  fstring path2;
-  pstring inbuf,outbuf;
-  char *p;
-
-  fstrcpy(path2,path);
-  trim_string(path2,NULL,"\\");
-  if (!*path2) *path2 = '\\';
-
-  bzero(outbuf,smb_size);
-  set_message(outbuf,0,4 + strlen(path2),True);
-  SCVAL(outbuf,smb_com,SMBchkpth);
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-
-  p = smb_buf(outbuf);
-  *p++ = 4;
-  fstrcpy(p,path2);
-
-#if 0
-  {
-         /* this little bit of code can be used to extract NT error codes.
-            Just feed a bunch of "cd foo" commands to smbclient then watch
-            in netmon (tridge) */
-         static int code=0;
-         SIVAL(outbuf, smb_rcls, code | 0xC0000000);
-         SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | (1<<14));
-         code++;
-  }
-#endif
-
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
-  if (report && CVAL(inbuf,smb_rcls) != 0)
-    DEBUG(2,("chkpath: %s\n",smb_errstr(inbuf)));
-
-  return(CVAL(inbuf,smb_rcls) == 0);
-}
-
-
 /****************************************************************************
 send a message
 ****************************************************************************/
-static void send_message(char *inbuf,char *outbuf)
+static void send_message(void)
 {
-  int total_len = 0;
+       int total_len = 0;
+       int grp_id;
 
-  char *p;
-  int grp_id;
-
-  /* send a SMBsendstrt command */
-  bzero(outbuf,smb_size);
-  set_message(outbuf,0,0,True);
-  CVAL(outbuf,smb_com) = SMBsendstrt;
-  SSVAL(outbuf,smb_tid,cnum);
-
-  p = smb_buf(outbuf);
-  *p++ = 4;
-  pstrcpy(p,username);
-  p = skip_string(p,1);
-  *p++ = 4;
-  pstrcpy(p,desthost);
-  p = skip_string(p,1);
-
-  set_message(outbuf,0,PTR_DIFF(p,smb_buf(outbuf)),False);
-
-  send_smb(Client,outbuf);
-  
+       if (!cli_message_start(cli, desthost, username, &grp_id)) {
+               DEBUG(0,("message start: %s\n", cli_errstr(cli)));
+               return;
+       }
 
-  if (!client_receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
-    {
-      printf("SMBsendstrt failed. (%s)\n",smb_errstr(inbuf));
-      return;
-    }
 
-  grp_id = SVAL(inbuf,smb_vwv0);
+       printf("Connected. Type your message, ending it with a Control-D\n");
 
-  printf("Connected. Type your message, ending it with a Control-D\n");
+       while (!feof(stdin) && total_len < 1600) {
+               int maxlen = MIN(1600 - total_len,127);
+               pstring msg;
+               int l=0;
+               int c;
 
-  while (!feof(stdin) && total_len < 1600)
-    {
-      int maxlen = MIN(1600 - total_len,127);
-      pstring msg;
-      int l=0;
-      int c;
+               ZERO_STRUCT(msg);
 
-      bzero(msg,smb_size);
+               for (l=0;l<maxlen && (c=fgetc(stdin))!=EOF;l++) {
+                       if (c == '\n')
+                               msg[l++] = '\r';
+                       msg[l] = c;   
+               }
 
-      for (l=0;l<maxlen && (c=fgetc(stdin))!=EOF;l++)
-       {
-         if (c == '\n')
-           msg[l++] = '\r';
-         msg[l] = c;   
+               if (!cli_message_text(cli, msg, l, grp_id)) {
+                       printf("SMBsendtxt failed (%s)\n",cli_errstr(cli));
+                       return;
+               }      
+               
+               total_len += l;
        }
 
-      CVAL(outbuf,smb_com) = SMBsendtxt;
-
-      set_message(outbuf,1,l+3,True);
-
-      SSVAL(outbuf,smb_vwv0,grp_id);
-
-      p = smb_buf(outbuf);
-      *p = 1;
-      SSVAL(p,1,l);
-      memcpy(p+3,msg,l);
+       if (total_len >= 1600)
+               printf("the message was truncated to 1600 bytes\n");
+       else
+               printf("sent %d bytes\n",total_len);
 
-      send_smb(Client,outbuf);
-      
-
-      if (!client_receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
-       {
-         printf("SMBsendtxt failed (%s)\n",smb_errstr(inbuf));
-         return;
+       if (!cli_message_end(cli, grp_id)) {
+               printf("SMBsendend failed (%s)\n",cli_errstr(cli));
+               return;
        }      
-
-      total_len += l;
-    }
-
-  if (total_len >= 1600)
-    printf("the message was truncated to 1600 bytes ");
-  else
-    printf("sent %d bytes ",total_len);
-
-  printf("(status was %d-%d)\n",CVAL(inbuf,smb_rcls),SVAL(inbuf,smb_err));
-
-  CVAL(outbuf,smb_com) = SMBsendend;
-  set_message(outbuf,1,0,False);
-  SSVAL(outbuf,smb_vwv0,grp_id);
-
-  send_smb(Client,outbuf);
-  
-
-  if (!client_receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
-    {
-      printf("SMBsendend failed (%s)\n",smb_errstr(inbuf));
-      return;
-    }      
 }
 
 
@@ -383,33 +223,24 @@ check the space on a device
 ****************************************************************************/
 static void do_dskattr(void)
 {
-  pstring inbuf,outbuf;
-
-  bzero(outbuf,smb_size);
-  set_message(outbuf,0,0,True);
-  CVAL(outbuf,smb_com) = SMBdskattr;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+       int total, bsize, avail;
 
-  if (CVAL(inbuf,smb_rcls) != 0) 
-    DEBUG(0,("Error in dskattr: %s\n",smb_errstr(inbuf)));      
+       if (!cli_dskattr(cli, &bsize, &total, &avail)) {
+               DEBUG(0,("Error in dskattr: %s\n",cli_errstr(cli))); 
+               return;
+       }
 
-  DEBUG(0,("\n\t\t%d blocks of size %d. %d blocks available\n",
-       SVAL(inbuf,smb_vwv0),
-       SVAL(inbuf,smb_vwv1)*SVAL(inbuf,smb_vwv2),
-       SVAL(inbuf,smb_vwv3)));
+       DEBUG(0,("\n\t\t%d blocks of size %d. %d blocks available\n",
+                total, bsize, avail));
 }
 
 /****************************************************************************
 show cd/pwd
 ****************************************************************************/
-static void cmd_pwd(char *dum_in, char *dum_out)
+static void cmd_pwd(void)
 {
-  DEBUG(0,("Current directory is %s",CNV_LANG(service)));
-  DEBUG(0,("%s\n",CNV_LANG(cur_dir)));
+       DEBUG(0,("Current directory is %s",CNV_LANG(service)));
+       DEBUG(0,("%s\n",CNV_LANG(cur_dir)));
 }
 
 
@@ -418,1652 +249,684 @@ change directory - inner section
 ****************************************************************************/
 static void do_cd(char *newdir)
 {
-  char *p = newdir;
-  pstring saved_dir;
-  pstring dname;
+       char *p = newdir;
+       pstring saved_dir;
+       pstring dname;
       
-  dos_format(newdir);
-
-  /* Save the current directory in case the
-     new directory is invalid */
-  pstrcpy(saved_dir, cur_dir);
-  if (*p == '\\')
-    pstrcpy(cur_dir,p);
-  else
-    pstrcat(cur_dir,p);
-  if (*(cur_dir+strlen(cur_dir)-1) != '\\') {
-    pstrcat(cur_dir, "\\");
-  }
-  dos_clean_name(cur_dir);
-  pstrcpy(dname,cur_dir);
-  pstrcat(cur_dir,"\\");
-  dos_clean_name(cur_dir);
-
-  if (!strequal(cur_dir,"\\"))
-    if (!chkpath(dname,True))
-      pstrcpy(cur_dir,saved_dir);
-
-  pstrcpy(cd_path,cur_dir);
+       dos_format(newdir);
+
+       /* Save the current directory in case the
+          new directory is invalid */
+       pstrcpy(saved_dir, cur_dir);
+       if (*p == '\\')
+               pstrcpy(cur_dir,p);
+       else
+               pstrcat(cur_dir,p);
+       if (*(cur_dir+strlen(cur_dir)-1) != '\\') {
+               pstrcat(cur_dir, "\\");
+       }
+       dos_clean_name(cur_dir);
+       pstrcpy(dname,cur_dir);
+       pstrcat(cur_dir,"\\");
+       dos_clean_name(cur_dir);
+       
+       if (!strequal(cur_dir,"\\")) {
+               if (!cli_chkpath(cli, dname)) {
+                       DEBUG(0,("cd %s: %s\n", dname, cli_errstr(cli)));
+                       pstrcpy(cur_dir,saved_dir);
+               }
+       }
+       
+       pstrcpy(cd_path,cur_dir);
 }
 
 /****************************************************************************
 change directory
 ****************************************************************************/
-static void cmd_cd(char *inbuf,char *outbuf)
+static void cmd_cd(void)
 {
-  fstring buf;
+       fstring buf;
 
-  if (next_token(NULL,buf,NULL,sizeof(buf)))
-    do_cd(buf);
-  else
-    DEBUG(0,("Current directory is %s\n",CNV_LANG(cur_dir)));
+       if (next_token(NULL,buf,NULL,sizeof(buf)))
+               do_cd(buf);
+       else
+               DEBUG(0,("Current directory is %s\n",CNV_LANG(cur_dir)));
 }
 
 
+/*******************************************************************
+  decide if a file should be operated on
+  ********************************************************************/
+static BOOL do_this_one(file_info *finfo)
+{
+       if (finfo->mode & aDIR) return(True);
+
+       if (*fileselection && 
+           !mask_match(finfo->name,fileselection,False,False)) {
+               DEBUG(3,("match_match %s failed\n", finfo->name));
+               return False;
+       }
+
+       if (newer_than && finfo->mtime < newer_than) {
+               DEBUG(3,("newer_than %s failed\n", finfo->name));
+               return(False);
+       }
+
+       if ((archive_level==1 || archive_level==2) && !(finfo->mode & aARCH)) {
+               DEBUG(3,("archive %s failed\n", finfo->name));
+               return(False);
+       }
+       
+       return(True);
+}
+
 /****************************************************************************
   display info about a file
   ****************************************************************************/
 static void display_finfo(file_info *finfo)
 {
-  if (do_this_one(finfo)) {
-    time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */
-    DEBUG(0,("  %-30s%7.7s%8.0f  %s",
-       CNV_LANG(finfo->name),
-          attrib_string(finfo->mode),
-          (double)finfo->size,
-          asctime(LocalTime(&t))));
-    dir_total += finfo->size;
-  }
+       if (do_this_one(finfo)) {
+               time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */
+               DEBUG(0,("  %-30s%7.7s%8.0f  %s",
+                        CNV_LANG(finfo->name),
+                        attrib_string(finfo->mode),
+                        (double)finfo->size,
+                        asctime(LocalTime(&t))));
+               dir_total += finfo->size;
+       }
 }
 
 
 /****************************************************************************
-  calculate size of a file
+   accumulate size of a file
   ****************************************************************************/
 static void do_du(file_info *finfo)
 {
-  if (do_this_one(finfo)) {
-    dir_total += finfo->size;
-  }
+       if (do_this_one(finfo)) {
+               dir_total += finfo->size;
+       }
 }
 
+static BOOL do_list_recurse;
+static BOOL do_list_dirs;
+static int do_list_attr;
+static void (*do_list_fn)(file_info *);
 
 /****************************************************************************
-  do a directory listing, calling fn on each file found. Use the TRANSACT2
-  call for long filenames
+a helper for do_list
   ****************************************************************************/
-static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(file_info *),BOOL recurse_dir, BOOL dirstoo)
+static void do_list_helper(file_info *f, const char *mask)
 {
-  int max_matches = 512;
-  int info_level = Protocol<PROTOCOL_NT1?1:260; /* NT uses 260, OS/2 uses 2. Both accept 1. */
-  char *p;
-  pstring mask;
-  file_info finfo;
-  int i;
-  char *dirlist = NULL;
-  int dirlist_len = 0;
-  int total_received = 0;
-  BOOL First = True;
-  char *resp_data=NULL;
-  char *resp_param=NULL;
-  int resp_data_len = 0;
-  int resp_param_len=0;
-
-  int ff_resume_key = 0;
-  int ff_searchcount=0;
-  int ff_eos=0;
-  int ff_lastname=0;
-  int ff_dir_handle=0;
-  int loop_count = 0;
-
-  uint16 setup;
-  pstring param;
-
-  pstrcpy(mask,Mask);
-
-  while (ff_eos == 0)
-    {
-      loop_count++;
-      if (loop_count > 200)
-       {
-         DEBUG(0,("Error: Looping in FIND_NEXT??\n"));
-         break;
+       if (f->mode & aDIR) {
+               if (do_list_dirs && do_this_one(f)) {
+                       do_list_fn(f);
+               }
+               if (do_list_recurse && 
+                   !strequal(f->name,".") && 
+                   !strequal(f->name,"..")) {
+                       pstring mask2;
+                       char *p;
+
+                       pstrcpy(mask2, mask);
+                       p = strrchr(mask2,'\\');
+                       if (!p) return;
+                       p[1] = 0;
+                       pstrcat(mask2, f->name);
+                       if (do_list_fn == display_finfo) {
+                               DEBUG(0,("\n%s\n",CNV_LANG(mask2)));
+                       }
+                       pstrcat(mask2,"\\*.*");
+                       do_list(mask2, do_list_attr, do_list_fn, True, True);
+               }
+               return;
        }
 
-      if (First)
-       {
-         setup = TRANSACT2_FINDFIRST;
-         SSVAL(param,0,attribute); /* attribute */
-         SSVAL(param,2,max_matches); /* max count */
-         SSVAL(param,4,8+4+2); /* resume required + close on end + continue */
-         SSVAL(param,6,info_level); 
-         SIVAL(param,8,0);
-         pstrcpy(param+12,mask);
-       }
-      else
-       {
-         setup = TRANSACT2_FINDNEXT;
-         SSVAL(param,0,ff_dir_handle);
-         SSVAL(param,2,max_matches); /* max count */
-         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 */
-         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));
+       if (do_this_one(f)) {
+               do_list_fn(f);
        }
-      /* ??? original code added 1 pad byte after param */
+}
 
-      cli_send_trans_request(outbuf,SMBtrans2,NULL,0,FID_UNUSED,0,
-                        NULL,param,&setup,
-                        0,12+strlen(mask)+1,1,
-                        BUFFER_SIZE,10,0);
 
-      if (!cli_receive_trans_response(inbuf,SMBtrans2,
-                             &resp_data_len,&resp_param_len,
-                                 &resp_data,&resp_param))
-       {
-         DEBUG(3,("FIND%s gave %s\n",First?"FIRST":"NEXT",smb_errstr(inbuf)));
-         break;
-       }
+/****************************************************************************
+a wrapper around cli_list that adds recursion
+  ****************************************************************************/
+void do_list(const char *mask,int attribute,void (*fn)(file_info *),BOOL rec, BOOL dirs)
+{
+       do_list_recurse = rec;
+       do_list_dirs = dirs;
+       do_list_fn = fn;
+       do_list_attr = attribute;
 
-      /* parse out some important return info */
-      p = resp_param;
-      if (First)
-       {
-         ff_dir_handle = SVAL(p,0);
-         ff_searchcount = SVAL(p,2);
-         ff_eos = SVAL(p,4);
-         ff_lastname = SVAL(p,8);
+       cli_list(cli, mask, attribute, do_list_helper);
+}
+
+/****************************************************************************
+  get a directory listing
+  ****************************************************************************/
+static void cmd_dir(void)
+{
+       int attribute = aDIR | aSYSTEM | aHIDDEN;
+       pstring mask;
+       fstring buf;
+       char *p=buf;
+       
+       dir_total = 0;
+       pstrcpy(mask,cur_dir);
+       if(mask[strlen(mask)-1]!='\\')
+               pstrcat(mask,"\\");
+       
+       if (next_token(NULL,buf,NULL,sizeof(buf))) {
+               dos_format(p);
+               if (*p == '\\')
+                       pstrcpy(mask,p);
+               else
+                       pstrcat(mask,p);
        }
-      else
-       {
-         ff_searchcount = SVAL(p,0);
-         ff_eos = SVAL(p,2);
-         ff_lastname = SVAL(p,6);
+       else {
+               pstrcat(mask,"*.*");
        }
 
-      if (ff_searchcount == 0) 
-       break;
-
-      /* point to the data bytes */
-      p = resp_data;
-
-      /* we might need the lastname for continuations */
-      if (ff_lastname > 0)
-       {
-         switch(info_level)
-           {
-           case 260:
-             ff_resume_key =0;
-             StrnCpy(mask,p+ff_lastname,resp_data_len-ff_lastname);
-             /* pstrcpy(mask,p+ff_lastname+94); */
-             break;
-           case 1:
-             pstrcpy(mask,p + ff_lastname + 1);
-             ff_resume_key = 0;
-             break;
-           }
-       }
-      else
-       pstrcpy(mask,"");
-  
-      /* and add them to the dirlist pool */
-      dirlist = Realloc(dirlist,dirlist_len + resp_data_len);
+       do_list(mask, attribute, display_finfo, recurse, True);
 
-      if (!dirlist)
-       {
-         DEBUG(0,("Failed to expand dirlist\n"));
-         break;
-       }
+       do_dskattr();
 
-      /* put in a length for the last entry, to ensure we can chain entries 
-        into the next packet */
-      {
-       char *p2;
-       for (p2=p,i=0;i<(ff_searchcount-1);i++)
-         p2 += interpret_long_filename(info_level,p2,NULL);
-       SSVAL(p2,0,resp_data_len - PTR_DIFF(p2,p));
-      }
-
-      /* grab the data for later use */
-      memcpy(dirlist+dirlist_len,p,resp_data_len);
-      dirlist_len += resp_data_len;
-
-      total_received += ff_searchcount;
-
-      if (resp_data) free(resp_data); resp_data = NULL;
-      if (resp_param) free(resp_param); resp_param = NULL;
-
-      DEBUG(3,("received %d entries (eos=%d resume=%d)\n",
-              ff_searchcount,ff_eos,ff_resume_key));
-
-      First = False;
-    }
-
-  if (!fn)
-    for (p=dirlist,i=0;i<total_received;i++)
-      {
-       p += interpret_long_filename(info_level,p,&finfo);
-       display_finfo(&finfo);
-      }
-
-  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, dirstoo);
-    }
-
-  /* free up the dirlist buffer */
-  if (dirlist) free(dirlist);
-  return(total_received);
+       DEBUG(3, ("Total bytes listed: %d\n", dir_total));
 }
 
 
 /****************************************************************************
-  do a directory listing, calling fn on each file found
+  get a directory listing
   ****************************************************************************/
-static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(file_info *),BOOL recurse_dir, BOOL dirstoo)
+static void cmd_du(void)
 {
-  char *p;
-  int received = 0;
-  BOOL first = True;
-  char status[21];
-  int num_asked = (max_xmit - 100)/DIR_STRUCT_SIZE;
-  int num_received = 0;
-  int i;
-  char *dirlist = NULL;
-  pstring mask;
-  file_info finfo;
-
-  finfo = def_finfo;
-
-  bzero(status,21);
-
-  pstrcpy(mask,Mask);
-  
-  while (1)
-    {
-      bzero(outbuf,smb_size);
-      if (first)       
-       set_message(outbuf,2,5 + strlen(mask),True);
-      else
-       set_message(outbuf,2,5 + 21,True);
-
-#if FFIRST
-      if (Protocol >= PROTOCOL_LANMAN1)
-       CVAL(outbuf,smb_com) = SMBffirst;
-      else
-#endif
-       CVAL(outbuf,smb_com) = SMBsearch;
-
-      SSVAL(outbuf,smb_tid,cnum);
-      cli_setup_pkt(outbuf);
-
-      SSVAL(outbuf,smb_vwv0,num_asked);
-      SSVAL(outbuf,smb_vwv1,attribute);
-  
-      p = smb_buf(outbuf);
-      *p++ = 4;
-      
-      if (first)
-       pstrcpy(p,mask);
-      else
-       pstrcpy(p,"");
-      p += strlen(p) + 1;
-      
-      *p++ = 5;
-      if (first)
-       SSVAL(p,0,0);
-      else
-       {
-         SSVAL(p,0,21);
-         p += 2;
-         memcpy(p,status,21);
+       int attribute = aDIR | aSYSTEM | aHIDDEN;
+       pstring mask;
+       fstring buf;
+       char *p=buf;
+       
+       dir_total = 0;
+       pstrcpy(mask,cur_dir);
+       if(mask[strlen(mask)-1]!='\\')
+               pstrcat(mask,"\\");
+       
+       if (next_token(NULL,buf,NULL,sizeof(buf))) {
+               dos_format(p);
+               if (*p == '\\')
+                       pstrcpy(mask,p);
+               else
+                       pstrcat(mask,p);
+       } else {
+               pstrcat(mask,"*.*");
        }
 
-      send_smb(Client,outbuf);
-      client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+       do_list(mask, attribute, do_du, recurse, True);
 
-      received = SVAL(inbuf,smb_vwv0);
+       do_dskattr();
 
-      DEBUG(5,("dir received %d\n",received));
-
-      DEBUG(6,("errstr=%s\n",smb_errstr(inbuf)));
+       DEBUG(0, ("Total number of bytes: %d\n", dir_total));
+}
 
-      if (received <= 0) break;
 
-      first = False;
+/****************************************************************************
+  get a file from rname to lname
+  ****************************************************************************/
+static void do_get(char *rname,char *lname)
+{  
+       int handle=0,fnum;
+       BOOL newhandle = False;
+       char *data;
+       struct timeval tp_start;
+       int read_size = 65520;
+       uint32 attr;
+       size_t size;
+       off_t nread = 0;
+
+       GetTimeOfDay(&tp_start);
+
+       if (lowercase) {
+               strlower(lname);
+       }
 
-      dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE);
+       fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
 
-      if (!dirlist) 
-       return 0;
+       if (fnum == -1) {
+               DEBUG(0,("%s opening remote file %s\n",cli_errstr(cli),CNV_LANG(rname)));
+               return;
+       }
 
-      p = smb_buf(inbuf) + 3;
+       if(!strcmp(lname,"-")) {
+               handle = fileno(stdout);
+       } else {
+               handle = open(lname,O_WRONLY|O_CREAT|O_TRUNC,0644);
+               newhandle = True;
+       }
+       if (handle < 0) {
+               DEBUG(0,("Error opening local file %s\n",lname));
+               return;
+       }
 
-      memcpy(dirlist+num_received*DIR_STRUCT_SIZE,
-            p,received*DIR_STRUCT_SIZE);
 
-      memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21);
+       if (!cli_getattrE(cli, fnum, &attr, &size, NULL, NULL, NULL)) {
+               DEBUG(0,("getattrE: %s\n",cli_errstr(cli)));
+               return;
+       }
 
-      num_received += received;
 
-      if (CVAL(inbuf,smb_rcls) != 0) break;
-    }
+       DEBUG(2,("getting file %s of size %.0f as %s ", 
+                lname, (double)size, lname));
 
-#if FFIRST
-  if (!first && Protocol >= PROTOCOL_LANMAN1)
-    {
-      bzero(outbuf,smb_size);
-      CVAL(outbuf,smb_com) = SMBfclose;
+       data = (char *)malloc(read_size);
 
-      SSVAL(outbuf,smb_tid,cnum);
-      cli_setup_pkt(outbuf);
+       while (1) {
+               int n = cli_read(cli, fnum, data, nread, read_size);
 
-      p = smb_buf(outbuf);
-      *p++ = 4;
-      
-      pstrcpy(p,"");
-      p += strlen(p) + 1;
+               if (n <= 0) break;
+               if (writefile(handle,data, n) != n) {
+                       DEBUG(0,("Error writing local file\n"));
+                       break;
+               }
       
-      *p++ = 5;
-      SSVAL(p,0,21);
-      p += 2;
-      memcpy(p,status,21);
+               nread += n;
+       }
+       
+       if (!cli_close(cli, fnum)) {
+               DEBUG(0,("Error %s closing remote file\n",cli_errstr(cli)));
+       }
 
-      send_smb(Client,outbuf);
-      client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+       if (newhandle) {
+               close(handle);
+       }
 
-      if (CVAL(inbuf,smb_rcls) != 0) 
-       DEBUG(0,("Error closing search: %s\n",smb_errstr(inbuf)));      
-    }
-#endif
+       if (archive_level >= 2 && (attr & aARCH)) {
+               cli_setatr(cli, rname, attr & ~aARCH, 0);
+       }
 
-  if (!fn)
-    for (p=dirlist,i=0;i<num_received;i++)
-      {
-       p += interpret_short_filename(p,&finfo);
-       display_finfo(&finfo);
-      }
-
-  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,dirstoo);
-    }
-
-  if (dirlist) free(dirlist);
-  return(num_received);
+       {
+               struct timeval tp_end;
+               int this_time;
+               
+               GetTimeOfDay(&tp_end);
+               this_time = 
+                       (tp_end.tv_sec - tp_start.tv_sec)*1000 +
+                       (tp_end.tv_usec - tp_start.tv_usec)/1000;
+               get_total_time_ms += this_time;
+               get_total_size += nread;
+               
+               DEBUG(2,("(%g kb/s) (average %g kb/s)\n",
+                        nread / (1.024*this_time + 1.0e-4),
+                        get_total_size / (1.024*get_total_time_ms)));
+       }
 }
 
 
-
 /****************************************************************************
-  do a directory listing, calling fn on each file found
+  get a file
   ****************************************************************************/
-void do_dir(char *inbuf,char *outbuf,char *mask,int attribute,void (*fn)(file_info *),BOOL recurse_dir, BOOL dirstoo)
-{
-  dos_format(mask);
-  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,dirstoo) > 0)
-       return;
-    }
-
-  expand_mask(mask,False);
-  do_short_dir(inbuf,outbuf,mask,attribute,fn,recurse_dir,dirstoo);
-  return;
-}
-
-/*******************************************************************
-  decide if a file should be operated on
-  ********************************************************************/
-static BOOL do_this_one(file_info *finfo)
+static void cmd_get(void)
 {
-  if (finfo->mode & aDIR) return(True);
-
-  if (newer_than && finfo->mtime < newer_than)
-    return(False);
+       pstring lname;
+       pstring rname;
+       char *p;
 
-  if ((archive_level==1 || archive_level==2) && !(finfo->mode & aARCH))
-    return(False);
-
-  return(True);
+       pstrcpy(rname,cur_dir);
+       pstrcat(rname,"\\");
+       
+       p = rname + strlen(rname);
+       
+       if (!next_token(NULL,p,NULL,sizeof(rname)-strlen(rname))) {
+               DEBUG(0,("get <filename>\n"));
+               return;
+       }
+       pstrcpy(lname,p);
+       dos_clean_name(rname);
+       
+       next_token(NULL,lname,NULL,sizeof(lname));
+       
+       do_get(rname, lname);
 }
 
 
-/*****************************************************************************
- Convert a character pointer in a cli_call_api() response to a form we can use.
- This function contains code to prevent core dumps if the server returns 
- invalid data.
-*****************************************************************************/
-static char *fix_char_ptr(unsigned int datap, unsigned int converter, char *rdata, int rdrcnt)
-{
-  if( datap == 0 )             /* turn NULL pointers */
-  {                            /* into zero length strings */
-    return "";
-  }
-  else
-  {
-    unsigned int offset = datap - converter;
-
-    if( offset >= rdrcnt )
-    {
-      DEBUG(1,("bad char ptr: datap=%u, converter=%u, rdata=%lu, rdrcnt=%d>", datap, converter, (unsigned long)rdata, rdrcnt));
-      return "<ERROR>";
-    }
-    else
-    {
-      return &rdata[offset];
-    }
-  }
-}
-
 /****************************************************************************
-interpret a short filename structure
-The length of the structure is returned
-****************************************************************************/
-static int interpret_short_filename(char *p,file_info *finfo)
+  do a mget operation on one file
+  ****************************************************************************/
+static void do_mget(file_info *finfo)
 {
-  finfo->mode = CVAL(p,21);
-
-  /* this date is converted to GMT by make_unix_date */
-  finfo->ctime = make_unix_date(p+22);
-  finfo->mtime = finfo->atime = finfo->ctime;
-  finfo->size = IVAL(p,26);
-  pstrcpy(finfo->name,p+30);
-  
-  return(DIR_STRUCT_SIZE);
-}
+       pstring rname;
+       pstring quest;
+       pstring saved_curdir;
+       pstring mget_mask;
 
-/****************************************************************************
-interpret a long filename structure - this is mostly guesses at the moment
-The length of the structure is returned
-The structure of a long filename depends on the info level. 260 is used
-by NT and 2 is used by OS/2
-****************************************************************************/
-static int interpret_long_filename(int level,char *p,file_info *finfo)
-{
-  if (finfo)
-    memcpy(finfo,&def_finfo,sizeof(*finfo));
+       if (strequal(finfo->name,".") || strequal(finfo->name,".."))
+               return;
 
-  switch (level)
-    {
-    case 1: /* OS/2 understands this */
-      if (finfo)
-       {
-         /* these dates are converted to GMT by make_unix_date */
-         finfo->ctime = make_unix_date2(p+4);
-         finfo->atime = make_unix_date2(p+8);
-         finfo->mtime = make_unix_date2(p+12);
-         finfo->size = IVAL(p,16);
-         finfo->mode = CVAL(p,24);
-         pstrcpy(finfo->name,p+27);
+       if (abort_mget) {
+               DEBUG(0,("mget aborted\n"));
+               return;
        }
-      return(28 + CVAL(p,26));
 
-    case 2: /* this is what OS/2 uses mostly */
-      if (finfo)
-       {
-         /* these dates are converted to GMT by make_unix_date */
-         finfo->ctime = make_unix_date2(p+4);
-         finfo->atime = make_unix_date2(p+8);
-         finfo->mtime = make_unix_date2(p+12);
-         finfo->size = IVAL(p,16);
-         finfo->mode = CVAL(p,24);
-         pstrcpy(finfo->name,p+31);
-       }
-      return(32 + CVAL(p,30));
+       if (finfo->mode & aDIR)
+               slprintf(quest,sizeof(pstring)-1,
+                        "Get directory %s? ",CNV_LANG(finfo->name));
+       else
+               slprintf(quest,sizeof(pstring)-1,
+                        "Get file %s? ",CNV_LANG(finfo->name));
 
-      /* levels 3 and 4 are untested */
-    case 3:
-      if (finfo)
-       {
-         /* these dates are probably like the other ones */
-         finfo->ctime = make_unix_date2(p+8);
-         finfo->atime = make_unix_date2(p+12);
-         finfo->mtime = make_unix_date2(p+16);
-         finfo->size = IVAL(p,20);
-         finfo->mode = CVAL(p,28);
-         pstrcpy(finfo->name,p+33);
-       }
-      return(SVAL(p,4)+4);
+       if (prompt && !yesno(quest)) return;
 
-    case 4:
-      if (finfo)
-       {
-         /* these dates are probably like the other ones */
-         finfo->ctime = make_unix_date2(p+8);
-         finfo->atime = make_unix_date2(p+12);
-         finfo->mtime = make_unix_date2(p+16);
-         finfo->size = IVAL(p,20);
-         finfo->mode = CVAL(p,28);
-         pstrcpy(finfo->name,p+37);
+       if (!(finfo->mode & aDIR)) {
+               pstrcpy(rname,cur_dir);
+               pstrcat(rname,finfo->name);
+               do_get(rname,finfo->name);
+               return;
        }
-      return(SVAL(p,4)+4);
 
-    case 260: /* NT uses this, but also accepts 2 */
-      if (finfo)
-       {
-         int ret = SVAL(p,0);
-         int namelen;
-         p += 4; /* next entry offset */
-         p += 4; /* fileindex */
-
-         /* these dates appear to arrive in a weird way. It seems to
-            be localtime plus the serverzone given in the initial
-            connect. This is GMT when DST is not in effect and one
-            hour from GMT otherwise. Can this really be right??
-
-            I suppose this could be called kludge-GMT. Is is the GMT
-            you get by using the current DST setting on a different
-            localtime. It will be cheap to calculate, I suppose, as
-            no DST tables will be needed */
-
-         finfo->ctime = interpret_long_date(p); p += 8;
-         finfo->atime = interpret_long_date(p); p += 8;
-         finfo->mtime = interpret_long_date(p); p += 8; p += 8;
-         finfo->size = IVAL(p,0); p += 8;
-         p += 8; /* alloc size */
-         finfo->mode = CVAL(p,0); p += 4;
-         namelen = IVAL(p,0); p += 4;
-         p += 4; /* EA size */
-         p += 2; /* short name len? */
-         p += 24; /* short name? */      
-         StrnCpy(finfo->name,p,namelen);
-         return(ret);
+       /* handle directories */
+       pstrcpy(saved_curdir,cur_dir);
+
+       pstrcat(cur_dir,finfo->name);
+       pstrcat(cur_dir,"\\");
+
+       unix_format(finfo->name);
+       if (lowercase)
+               strlower(finfo->name);
+       
+       if (!directory_exist(finfo->name,NULL) && 
+           dos_mkdir(finfo->name,0777) != 0) {
+               DEBUG(0,("failed to create directory %s\n",CNV_LANG(finfo->name)));
+               pstrcpy(cur_dir,saved_curdir);
+               return;
+       }
+       
+       if (dos_chdir(finfo->name) != 0) {
+               DEBUG(0,("failed to chdir to directory %s\n",CNV_LANG(finfo->name)));
+               pstrcpy(cur_dir,saved_curdir);
+               return;
        }
-      return(SVAL(p,0));
-    }
 
-  DEBUG(1,("Unknown long filename format %d\n",level));
-  return(SVAL(p,0));
+       pstrcpy(mget_mask,cur_dir);
+       pstrcat(mget_mask,"*.*");
+       
+       do_list(mget_mask, aSYSTEM | aHIDDEN | aDIR,do_mget,False, True);
+       chdir("..");
+       pstrcpy(cur_dir,saved_curdir);
 }
 
 
+/****************************************************************************
+view the file using the pager
+****************************************************************************/
+static void cmd_more(void)
+{
+       fstring rname,lname,tmpname,pager_cmd;
+       char *pager;
 
+       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,sizeof(rname)-strlen(rname))) {
+               DEBUG(0,("more <filename>\n"));
+               return;
+       }
+       dos_clean_name(rname);
 
-/****************************************************************************
-  act on the files in a dir listing
+       do_get(rname,lname);
 
-  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)(file_info *),BOOL longdir, BOOL dirstoo)
-{
+       pager=getenv("PAGER");
 
-  if (!((finfo->mode & aDIR) == 0 && *fileselection && 
-       !mask_match(finfo->name,fileselection,False,False)) &&
-      !(recurse_dir && (strequal(finfo->name,".") || 
-                       strequal(finfo->name,".."))))
-    {
-      if (recurse_dir && (finfo->mode & aDIR))
-       {
-         pstring mask2;
-         pstring sav_dir;
+       slprintf(pager_cmd,sizeof(pager_cmd)-1,
+                "%s %s",(pager? pager:PAGER), tmpname);
+       system(pager_cmd);
+       unlink(tmpname);
+}
 
-          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)));
+/****************************************************************************
+do a mget command
+****************************************************************************/
+static void cmd_mget(void)
+{
+       int attribute = aSYSTEM | aHIDDEN;
+       pstring mget_mask;
+       fstring buf;
+       char *p=buf;
 
-         pstrcat(mask2,"*");
+       *mget_mask = 0;
 
-         if (longdir)
-           do_long_dir(inbuf,outbuf,mask2,attribute,fn,True, dirstoo);      
-         else
-           do_dir(inbuf,outbuf,mask2,attribute,fn,True, dirstoo);
+       if (recurse)
+               attribute |= aDIR;
+       
+       abort_mget = False;
 
-         pstrcpy(cur_dir,sav_dir);
+       while (next_token(NULL,p,NULL,sizeof(buf))) {
+               pstrcpy(mget_mask,cur_dir);
+               if(mget_mask[strlen(mget_mask)-1]!='\\')
+                       pstrcat(mget_mask,"\\");
+               
+               if (*p == '\\')
+                       pstrcpy(mget_mask,p);
+               else
+                       pstrcat(mget_mask,p);
+               do_list(mget_mask, attribute,do_mget,False,True);
        }
-      else
-       {
-         if (fn && do_this_one(finfo))
-           fn(finfo);
+
+       if (!*mget_mask) {
+               pstrcpy(mget_mask,cur_dir);
+               if(mget_mask[strlen(mget_mask)-1]!='\\')
+                       pstrcat(mget_mask,"\\");
+               pstrcat(mget_mask,"*.*");
+               do_list(mget_mask, attribute,do_mget,False,True);
        }
-    }
 }
 
 
 /****************************************************************************
-  get a directory listing
-  ****************************************************************************/
-static void cmd_dir(char *inbuf,char *outbuf)
+make a directory of name "name"
+****************************************************************************/
+static BOOL do_mkdir(char *name)
 {
-  int attribute = aDIR | aSYSTEM | aHIDDEN;
-  pstring mask;
-  fstring buf;
-  char *p=buf;
-
-  dir_total = 0;
-  pstrcpy(mask,cur_dir);
-  if(mask[strlen(mask)-1]!='\\')
-    pstrcat(mask,"\\");
-
-  if (next_token(NULL,buf,NULL,sizeof(buf))) {
-    dos_format(p);
-    if (*p == '\\')
-      pstrcpy(mask,p);
-    else
-      pstrcat(mask,p);
-  }
-  else {
-    pstrcat(mask,"*");
-  }
-
-  do_dir(inbuf,outbuf,mask,attribute,NULL,recurse,False);
-
-  do_dskattr();
-
-  DEBUG(3, ("Total bytes listed: %d\n", dir_total));
+       if (!cli_mkdir(cli, name)) {
+               DEBUG(0,("%s making remote directory %s\n",
+                        cli_errstr(cli),CNV_LANG(name)));
+               return(False);
+       }
+
+       return(True);
 }
 
 
 /****************************************************************************
-  get a directory listing
-  ****************************************************************************/
-static void cmd_du(char *inbuf,char *outbuf)
+make a directory of name "name"
+****************************************************************************/
+static void cmd_quit(void)
 {
-  int attribute = aDIR | aSYSTEM | aHIDDEN;
-  pstring mask;
-  fstring buf;
-  char *p=buf;
-
-  dir_total = 0;
-  pstrcpy(mask,cur_dir);
-  if(mask[strlen(mask)-1]!='\\')
-    pstrcat(mask,"\\");
-
-  if (next_token(NULL,buf,NULL,sizeof(buf)))
-  {
-    dos_format(p);
-    if (*p == '\\')
-      pstrcpy(mask,p);
-    else
-      pstrcat(mask,p);
-  }
-  else {
-    pstrcat(mask,"*");
-  }
-
-  do_dir(inbuf,outbuf,mask,attribute,do_du,recurse,False);
-
-  do_dskattr();
-
-  DEBUG(0, ("Total number of bytes: %d\n", dir_total));
+       cli_shutdown(cli);
+       exit(0);
 }
 
+
 /****************************************************************************
-  get a file from rname to lname
+  make a directory
   ****************************************************************************/
-static void do_get(char *rname,char *lname,file_info *finfo1)
-{  
-  int handle=0,fnum;
-  uint32 nread=0;
-  char *p;
-  BOOL newhandle = False;
-  char *inbuf,*outbuf;
-  file_info finfo;
-  BOOL close_done = False;
-  BOOL ignore_close_error = False;
-  char *dataptr=NULL;
-  int datalen=0;
-
-  struct timeval tp_start;
-  GetTimeOfDay(&tp_start);
-
-  if (finfo1) 
-    finfo = *finfo1;
-  else
-    finfo = def_finfo;
-
-  if (lowercase)
-    strlower(lname);
-
-
-  inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
-  if (!inbuf || !outbuf)
-  {
-    DEBUG(0,("out of memory\n"));
-    return;
-  }
-
-  bzero(outbuf,smb_size);
-  set_message(outbuf,15,1 + strlen(rname),True);
-
-  CVAL(outbuf,smb_com) = SMBopenX;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-
-  SSVAL(outbuf,smb_vwv0,0xFF);
-  SSVAL(outbuf,smb_vwv2,1); /* return additional info */
-  SSVAL(outbuf,smb_vwv3,(DENY_NONE<<4));
-  SSVAL(outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
-  SSVAL(outbuf,smb_vwv5,aSYSTEM | aHIDDEN);
-  SSVAL(outbuf,smb_vwv8,1);
-  SSVAL(outbuf,smb_vwv11,0xffff);
-  SSVAL(outbuf,smb_vwv12,0xffff);
+static void cmd_mkdir(void)
+{
+       pstring mask;
+       fstring buf;
+       char *p=buf;
   
-  p = smb_buf(outbuf);
-  pstrcpy(p,rname);
-  p = skip_string(p,1);
-
-  /* do a chained openX with a readX? */
-#if 1
-  if (finfo.size > 0)
-    {
-      DEBUG(3,("Chaining readX wth openX\n"));
-      SSVAL(outbuf,smb_vwv0,SMBreadX);
-      SSVAL(outbuf,smb_vwv1,smb_offset(p,outbuf));
-      bzero(p,200);
-      p -= smb_wct;
-      SCVAL(p,smb_wct,10);
-      SSVAL(p,smb_vwv0,0xFF);
-      SSVAL(p,smb_vwv5,MIN(max_xmit-500,finfo.size));
-      SSVAL(p,smb_vwv9,MIN(BUFFER_SIZE,finfo.size));
-      smb_setlen(outbuf,smb_len(outbuf)+11*2+1);  
-    }
-#endif
+       pstrcpy(mask,cur_dir);
 
-  if(!strcmp(lname,"-"))
-    handle = fileno(stdout);
-  else 
-    {
-      handle = creat(lname,0644);
-      newhandle = True;
-    }
-  if (handle < 0)
-    {
-      DEBUG(0,("Error opening local file %s\n",lname));
-      free(inbuf);free(outbuf);
-      return;
-    }
-
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      if (CVAL(inbuf,smb_rcls) == ERRSRV &&
-         SVAL(inbuf,smb_err) == ERRnoresource &&
-         cli_reopen_connection(inbuf,outbuf))
-       {
-         do_get(rname,lname,finfo1);
-         return;
-       }
-      DEBUG(0,("%s opening remote file %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
-      if(newhandle)
-       {
-         close(handle);
-         unlink(lname);
+       if (!next_token(NULL,p,NULL,sizeof(buf))) {
+               if (!recurse)
+                       DEBUG(0,("mkdir <dirname>\n"));
+               return;
        }
-      free(inbuf);free(outbuf);
-      return;
-    }
-
-  pstrcpy(finfo.name,rname);
-
-  if (!finfo1)
-    {
-      finfo.mode = SVAL(inbuf,smb_vwv3);
-      /* these times arrive as LOCAL time, using the DST offset 
-        corresponding to that time, we convert them to GMT */
-      finfo.mtime = make_unix_date3(inbuf+smb_vwv4);
-      finfo.atime = finfo.ctime = finfo.mtime;
-      finfo.size = IVAL(inbuf,smb_vwv6);
-    }
-
-  DEBUG(3,("file %s attrib 0x%X\n",CNV_LANG(finfo.name),finfo.mode));
-
-  fnum = SVAL(inbuf,smb_vwv2);
-
-  /* we might have got some data from a chained readX */
-  if (SVAL(inbuf,smb_vwv0) == SMBreadX)
-    {
-      p = (smb_base(inbuf)+SVAL(inbuf,smb_vwv1)) - smb_wct;
-      datalen = SVAL(p,smb_vwv5);
-      dataptr = smb_base(inbuf) + SVAL(p,smb_vwv6);
-    }
-  else
-    {
-      dataptr = NULL;
-      datalen = 0;
-    }
-
-
-  DEBUG(2,("getting file %s of size %.0f bytes as %s ",
-          CNV_LANG(finfo.name),
-          (double)finfo.size,
-          lname));
-
-  while (nread < finfo.size && !close_done)
-    {
-      int method = -1;
-      static BOOL can_chain_close = True;
-
-      p=NULL;
-      
-      DEBUG(3,("nread=%d max_xmit=%d fsize=%.0f\n",nread,max_xmit,(double)finfo.size));
-
-      /* 3 possible read types. readbraw if a large block is required.
-        readX + close if not much left and read if neither is supported */
+       pstrcat(mask,p);
 
-      /* we might have already read some data from a chained readX */
-      if (dataptr && datalen>0)
-       method=3;
-
-      /* if we can finish now then readX+close */
-      if (method<0 && can_chain_close && (Protocol >= PROTOCOL_LANMAN1) && 
-         ((finfo.size - nread) < 
-          (max_xmit - (2*smb_size + 13*SIZEOFWORD + 300))))
-       method = 0;
-
-      /* if we support readraw then use that */
-      if (method<0 && readbraw_supported)
-       method = 1;
-
-      /* if we can then use readX */
-      if (method<0 && (Protocol >= PROTOCOL_LANMAN1))
-       method = 2;
-
-      switch (method)
-       {
-         /* use readX */
-       case 0:
-       case 2:
-         if (method == 0)
-           close_done = True;
-           
-         /* use readX + close */
-         bzero(outbuf,smb_size);
-         set_message(outbuf,10,0,True);
-         CVAL(outbuf,smb_com) = SMBreadX;
-         SSVAL(outbuf,smb_tid,cnum);
-         cli_setup_pkt(outbuf);
-         
-         if (close_done)
-           {
-             CVAL(outbuf,smb_vwv0) = SMBclose;
-             SSVAL(outbuf,smb_vwv1,smb_offset(smb_buf(outbuf),outbuf));
-           }
-         else
-           CVAL(outbuf,smb_vwv0) = 0xFF;             
-         
-         SSVAL(outbuf,smb_vwv2,fnum);
-         SIVAL(outbuf,smb_vwv3,nread);
-         SSVAL(outbuf,smb_vwv5,MIN(max_xmit-200,finfo.size - nread));
-         SSVAL(outbuf,smb_vwv6,0);
-         SIVAL(outbuf,smb_vwv7,0);
-         SSVAL(outbuf,smb_vwv9,MIN(BUFFER_SIZE,finfo.size-nread));
-         
-         if (close_done)
-           {
-             p = smb_buf(outbuf);
-             bzero(p,9);
-             
-             CVAL(p,0) = 3;
-             SSVAL(p,1,fnum);
-             SIVALS(p,3,-1);
-             
-             /* now set the total packet length */
-             smb_setlen(outbuf,smb_len(outbuf)+9);
-           }
-         
-         send_smb(Client,outbuf);
-         client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-         
-         if (CVAL(inbuf,smb_rcls) != 0)
-           {
-             DEBUG(0,("Error %s reading remote file\n",smb_errstr(inbuf)));
-             break;
-           }
-         
-         if (close_done &&
-             SVAL(inbuf,smb_vwv0) != SMBclose)
-           {
-             /* NOTE: WfWg sometimes just ignores the chained
-                command! This seems to break the spec? */
-             DEBUG(3,("Rejected chained close?\n"));
-             close_done = False;
-             can_chain_close = False;
-             ignore_close_error = True;
-           }
-         
-         datalen = SVAL(inbuf,smb_vwv5);
-         dataptr = smb_base(inbuf) + SVAL(inbuf,smb_vwv6);
-         break;
-
-         /* use readbraw */
-       case 1:
-         {
-           static int readbraw_size = BUFFER_SIZE;
-         
-           extern int Client;
-           bzero(outbuf,smb_size);
-           set_message(outbuf,8,0,True);
-           CVAL(outbuf,smb_com) = SMBreadbraw;
-           SSVAL(outbuf,smb_tid,cnum);
-           cli_setup_pkt(outbuf);
-           SSVAL(outbuf,smb_vwv0,fnum);
-           SIVAL(outbuf,smb_vwv1,nread);
-           SSVAL(outbuf,smb_vwv3,MIN(finfo.size-nread,readbraw_size));
-           SSVAL(outbuf,smb_vwv4,0);
-           SIVALS(outbuf,smb_vwv5,-1);
-           send_smb(Client,outbuf);
-
-           /* Now read the raw data into the buffer and write it */      
-           if(read_smb_length(Client,inbuf,0) == -1) {
-             DEBUG(0,("Failed to read length in readbraw\n"));     
-             exit(1);
-           }
-           
-           /* Even though this is not an smb message, smb_len
-              returns the generic length of an smb message */
-           datalen = smb_len(inbuf);
-
-           if (datalen == 0)
-             {
-               /* we got a readbraw error */
-               DEBUG(4,("readbraw error - reducing size\n"));
-               readbraw_size = (readbraw_size * 9) / 10;
-               
-               if (readbraw_size < max_xmit)
-                 {
-                   DEBUG(0,("disabling readbraw\n"));
-                   readbraw_supported = False;
-                 }
-               
-               dataptr=NULL;
-               continue;
-             }
-
-           if(read_data(Client,inbuf,datalen) != datalen) {
-             DEBUG(0,("Failed to read data in readbraw\n"));
-             exit(1);
-           }
-           dataptr = inbuf;
-         }
-         break;
-
-       case 3:
-         /* we've already read some data with a chained readX */
-         break;
-
-       default:
-         /* use plain read */
-         bzero(outbuf,smb_size);
-         set_message(outbuf,5,0,True);
-         CVAL(outbuf,smb_com) = SMBread;
-         SSVAL(outbuf,smb_tid,cnum);
-         cli_setup_pkt(outbuf);
-
-         SSVAL(outbuf,smb_vwv0,fnum);
-         SSVAL(outbuf,smb_vwv1,MIN(max_xmit-200,finfo.size - nread));
-         SIVAL(outbuf,smb_vwv2,nread);
-         SSVAL(outbuf,smb_vwv4,finfo.size - nread);
-
-         send_smb(Client,outbuf);
-         client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
-         if (CVAL(inbuf,smb_rcls) != 0)
-           {
-             DEBUG(0,("Error %s reading remote file\n",smb_errstr(inbuf)));
-             break;
-           }
-
-         datalen = SVAL(inbuf,smb_vwv0);
-         dataptr = smb_buf(inbuf) + 3;
-         break;
-       }
-      if (writefile(handle,dataptr,datalen) != datalen)
-       {
-         DEBUG(0,("Error writing local file\n"));
-         break;
-       }
-      
-      nread += datalen;
-      if (datalen == 0) 
-       {
-         DEBUG(0,("Error reading file %s. Got %d bytes\n",CNV_LANG(rname),nread));
-         break;
-       }
-
-      dataptr=NULL;
-      datalen=0;
-    }
-
-
-
-  if (!close_done)
-    {
-      cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
-      
-      if (!ignore_close_error && CVAL(inbuf,smb_rcls) != 0)
-       {
-         DEBUG(0,("Error %s closing remote file\n",smb_errstr(inbuf)));
-         if(newhandle)
-           close(handle);
-         free(inbuf);free(outbuf);
-         return;
-       }
-    }
-
-  if(newhandle)
-    close(handle);
-
-  if (archive_level >= 2 && (finfo.mode & aARCH)) {
-    bzero(outbuf,smb_size);
-    set_message(outbuf,8,strlen(rname)+4,True);
-    CVAL(outbuf,smb_com) = SMBsetatr;
-    SSVAL(outbuf,smb_tid,cnum);
-    cli_setup_pkt(outbuf);
-    SSVAL(outbuf,smb_vwv0,finfo.mode & ~(aARCH));
-    SIVALS(outbuf,smb_vwv1,0);
-    p = smb_buf(outbuf);
-    *p++ = 4;
-    pstrcpy(p,rname);
-    p += strlen(p)+1;
-    *p++ = 4;
-    *p = 0;
-    send_smb(Client,outbuf);
-    client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-  }
-
-  {
-    struct timeval tp_end;
-    int this_time;
-
-    GetTimeOfDay(&tp_end);
-    this_time = 
-      (tp_end.tv_sec - tp_start.tv_sec)*1000 +
-       (tp_end.tv_usec - tp_start.tv_usec)/1000;
-    get_total_time_ms += this_time;
-    get_total_size += finfo.size;
-
-    DEBUG(1,("(%g kb/s) (average %g kb/s)\n",
-            finfo.size / (1.024*this_time + 1.0e-4),
-            get_total_size / (1.024*get_total_time_ms)));
-  }
-
-  free(inbuf);free(outbuf);
-}
+       if (recurse) {
+               pstring ddir;
+               pstring ddir2;
+               *ddir2 = 0;
+               
+               pstrcpy(ddir,mask);
+               trim_string(ddir,".",NULL);
+               p = strtok(ddir,"/\\");
+               while (p) {
+                       pstrcat(ddir2,p);
+                       if (!cli_chkpath(cli, ddir2)) { 
+                               do_mkdir(ddir2);
+                       }
+                       pstrcat(ddir2,"\\");
+                       p = strtok(NULL,"/\\");
+               }        
+       } else {
+               do_mkdir(mask);
+       }
+}
 
 
 /****************************************************************************
-  get a file
-  ****************************************************************************/
-static void cmd_get(char *dum_in, char *dum_out)
-{
-  pstring lname;
-  pstring rname;
-  char *p;
-
-  pstrcpy(rname,cur_dir);
-  pstrcat(rname,"\\");
-
-  p = rname + strlen(rname);
-
-  if (!next_token(NULL,p,NULL,sizeof(rname)-strlen(rname))) {
-    DEBUG(0,("get <filename>\n"));
-    return;
-  }
-  pstrcpy(lname,p);
-  dos_clean_name(rname);
-    
-  next_token(NULL,lname,NULL,sizeof(lname));
-
-  do_get(rname,lname,NULL);
-}
-
-
-/****************************************************************************
-  do a mget operation on one file
+  put a single file
   ****************************************************************************/
-static void do_mget(file_info *finfo)
-{
-  pstring rname;
-  pstring quest;
-
-  if (strequal(finfo->name,".") || strequal(finfo->name,".."))
-    return;
-
-  if (abort_mget)
-    {
-      DEBUG(0,("mget aborted\n"));
-      return;
-    }
-
-  if (finfo->mode & aDIR)
-    slprintf(quest,sizeof(pstring)-1,
-            "Get directory %s? ",CNV_LANG(finfo->name));
-  else
-    slprintf(quest,sizeof(pstring)-1,
-            "Get file %s? ",CNV_LANG(finfo->name));
-
-  if (prompt && !yesno(quest)) return;
-
-  if (finfo->mode & aDIR)
-    {
-      pstring saved_curdir;
-      pstring mget_mask;
-      char *inbuf,*outbuf;
-
-      inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-      outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
-      if (!inbuf || !outbuf)
-       {
-         DEBUG(0,("out of memory\n"));
-         return;
-       }
-
-      pstrcpy(saved_curdir,cur_dir);
-
-      pstrcat(cur_dir,finfo->name);
-      pstrcat(cur_dir,"\\");
-
-      unix_format(finfo->name);
-      {
-       if (lowercase)
-         strlower(finfo->name);
-
-       if (!directory_exist(finfo->name,NULL) && 
-           dos_mkdir(finfo->name,0777) != 0) 
-         {
-           DEBUG(0,("failed to create directory %s\n",CNV_LANG(finfo->name)));
-           pstrcpy(cur_dir,saved_curdir);
-           free(inbuf);free(outbuf);
-           return;
-         }
-
-       if (dos_chdir(finfo->name) != 0)
-         {
-           DEBUG(0,("failed to chdir to directory %s\n",CNV_LANG(finfo->name)));
-           pstrcpy(cur_dir,saved_curdir);
-           free(inbuf);free(outbuf);
-           return;
-         }
-      }       
-
-      pstrcpy(mget_mask,cur_dir);
-      pstrcat(mget_mask,"*");
-      
-      do_dir((char *)inbuf,(char *)outbuf,
-            mget_mask,aSYSTEM | aHIDDEN | aDIR,do_mget,False, False);
-      chdir("..");
-      pstrcpy(cur_dir,saved_curdir);
-      free(inbuf);free(outbuf);
-    }
-  else
-    {
-      pstrcpy(rname,cur_dir);
-      pstrcat(rname,finfo->name);
-      do_get(rname,finfo->name,finfo);
-    }
-}
-
-/****************************************************************************
-view the file using the pager
-****************************************************************************/
-static void cmd_more(char *dum_in, char *dum_out)
-{
-  fstring rname,lname,tmpname,pager_cmd;
-  char *pager;
-
-  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,sizeof(rname)-strlen(rname))) {
-    DEBUG(0,("more <filename>\n"));
-    return;
-  }
-  dos_clean_name(rname);
-
-  do_get(rname,lname,NULL);
-
-  pager=getenv("PAGER");
-
-  slprintf(pager_cmd,sizeof(pager_cmd)-1,
-          "%s %s",(pager? pager:PAGER), tmpname);
-  system(pager_cmd);
-  unlink(tmpname);
-}
-
-
-
-/****************************************************************************
-do a mget command
-****************************************************************************/
-static void cmd_mget(char *inbuf,char *outbuf)
-{
-  int attribute = aSYSTEM | aHIDDEN;
-  pstring mget_mask;
-  fstring buf;
-  char *p=buf;
-
-  *mget_mask = 0;
-
-  if (recurse)
-    attribute |= aDIR;
-
-  abort_mget = False;
-
-  while (next_token(NULL,p,NULL,sizeof(buf)))
-    {
-      pstrcpy(mget_mask,cur_dir);
-      if(mget_mask[strlen(mget_mask)-1]!='\\')
-       pstrcat(mget_mask,"\\");
-
-      if (*p == '\\')
-       pstrcpy(mget_mask,p);
-      else
-       pstrcat(mget_mask,p);
-      do_dir((char *)inbuf,(char *)outbuf,mget_mask,attribute,do_mget,False,False);
-    }
-
-  if (! *mget_mask)
-    {
-      pstrcpy(mget_mask,cur_dir);
-      if(mget_mask[strlen(mget_mask)-1]!='\\')
-       pstrcat(mget_mask,"\\");
-      pstrcat(mget_mask,"*");
-      do_dir((char *)inbuf,(char *)outbuf,mget_mask,attribute,do_mget,False,False);
-    }
-}
-
-/****************************************************************************
-make a directory of name "name"
-****************************************************************************/
-static BOOL do_mkdir(char *name)
+static void do_put(char *rname,char *lname)
 {
-  char *p;
-  char *inbuf,*outbuf;
-
-  inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
-  if (!inbuf || !outbuf)
-    {
-      DEBUG(0,("out of memory\n"));
-      return False;
-    }
-
-  bzero(outbuf,smb_size);
-  set_message(outbuf,0,2 + strlen(name),True);
-  
-  CVAL(outbuf,smb_com) = SMBmkdir;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
+       int fnum;
+       FILE *f;
+       int nread=0;
+       char *buf=NULL;
+       int maxwrite=65520;
+       
+       struct timeval tp_start;
+       GetTimeOfDay(&tp_start);
 
+       fnum = cli_open(cli, rname, O_WRONLY|O_CREAT|O_TRUNC, DENY_NONE);
   
-  p = smb_buf(outbuf);
-  *p++ = 4;      
-  pstrcpy(p,name);
-  
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-  
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      DEBUG(0,("%s making remote directory %s\n",
-              smb_errstr(inbuf),CNV_LANG(name)));
-
-      free(inbuf);free(outbuf);
-      return(False);
-    }
+       if (fnum == -1) {
+               DEBUG(0,("%s opening remote file %s\n",cli_errstr(cli),CNV_LANG(rname)));
+               return;
+       }
 
-  free(inbuf);free(outbuf);
-  return(True);
-}
+       /* allow files to be piped into smbclient
+          jdblair 24.jun.98 */
+       if (!strcmp(lname, "-")) {
+               f = stdin;
+               /* size of file is not known */
+       } else {
+               f = fopen(lname,"r");
+       }
 
+       if (!f) {
+               DEBUG(0,("Error opening local file %s\n",lname));
+               return;
+       }
 
-/****************************************************************************
-  make a directory
-  ****************************************************************************/
-static void cmd_mkdir(char *inbuf,char *outbuf)
-{
-  pstring mask;
-  fstring buf;
-  char *p=buf;
   
-  pstrcpy(mask,cur_dir);
-
-  if (!next_token(NULL,p,NULL,sizeof(buf)))
-    {
-      if (!recurse)
-       DEBUG(0,("mkdir <dirname>\n"));
-      return;
-    }
-  pstrcat(mask,p);
-
-  if (recurse)
-    {
-      pstring ddir;
-      pstring ddir2;
-      *ddir2 = 0;
-
-      pstrcpy(ddir,mask);
-      trim_string(ddir,".",NULL);
-      p = strtok(ddir,"/\\");
-      while (p)
-       {
-         pstrcat(ddir2,p);
-         if (!chkpath(ddir2,False))
-           {             
-             do_mkdir(ddir2);
-           }
-         pstrcat(ddir2,"\\");
-         p = strtok(NULL,"/\\");
-       }        
-    }
-  else
-    do_mkdir(mask);
-}
-
-
-/*******************************************************************
-  write to a file using writebraw
-  ********************************************************************/
-static int smb_writeraw(char *outbuf,int fnum,int pos,char *buf,int n)
-{
-  extern int Client;
-  pstring inbuf;
-
-  bzero(outbuf,smb_size);
-  bzero(inbuf,smb_size);  
-  set_message(outbuf,Protocol>PROTOCOL_COREPLUS?12:10,0,True);
-
-  CVAL(outbuf,smb_com) = SMBwritebraw;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-
-  SSVAL(outbuf,smb_vwv0,fnum);
-  SSVAL(outbuf,smb_vwv1,n);
-  SIVAL(outbuf,smb_vwv3,pos);
-  SSVAL(outbuf,smb_vwv7,1);
-
-  send_smb(Client,outbuf);
+       DEBUG(1,("putting file %s as %s ",lname,
+                CNV_LANG(rname)));
   
-  if (!client_receive_smb(Client,inbuf,CLIENT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
-    return(0);
-
-  _smb_setlen(buf-4,n);                /* HACK! XXXX */
-
-  if (write_socket(Client,buf-4,n+4) != n+4)
-    return(0);
-
-  if (!client_receive_smb(Client,inbuf,CLIENT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0) {
-    DEBUG(0,("Error writing remote file (2)\n"));
-    return(0);
-  }
-  return(SVAL(inbuf,smb_vwv0));
-}
-      
-
+       buf = (char *)malloc(maxwrite);
+       while (!feof(f)) {
+               int n = maxwrite;
+               int ret;
 
-/*******************************************************************
-  write to a file
-  ********************************************************************/
-static int smb_writefile(char *outbuf,int fnum,int pos,char *buf,int n)
-{
-  pstring inbuf;
+               if ((n = readfile(buf,1,n,f)) < 1) {
+                       DEBUG(0,("Error reading local file\n"));
+                       break;
+               }
 
-  if (writebraw_supported && n > (max_xmit-200)) 
-    return(smb_writeraw(outbuf,fnum,pos,buf,n));
+               ret = cli_write(cli, fnum, 0, buf, nread, n);
 
-  bzero(outbuf,smb_size);
-  bzero(inbuf,smb_size);
-  set_message(outbuf,5,n + 3,True);
+               if (n != ret) {
+                       DEBUG(0,("Error writing file: %s\n", cli_errstr(cli)));
+                       break;
+               } 
 
-  CVAL(outbuf,smb_com) = SMBwrite;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
+               nread += n;
+       }
 
-  SSVAL(outbuf,smb_vwv0,fnum);
-  SSVAL(outbuf,smb_vwv1,n);
-  SIVAL(outbuf,smb_vwv2,pos);
-  SSVAL(outbuf,smb_vwv4,0);
-  CVAL(smb_buf(outbuf),0) = 1;
-  SSVAL(smb_buf(outbuf),1,n);
+       if (!cli_close(cli, fnum)) {
+               DEBUG(0,("%s closing remote file %s\n",cli_errstr(cli),CNV_LANG(rname)));
+               fclose(f);
+               if (buf) free(buf);
+               return;
+       }
 
-  memcpy(smb_buf(outbuf)+3,buf,n);
+       
+       fclose(f);
+       if (buf) free(buf);
 
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+       {
+               struct timeval tp_end;
+               int this_time;
+               
+               GetTimeOfDay(&tp_end);
+               this_time = 
+                       (tp_end.tv_sec - tp_start.tv_sec)*1000 +
+                       (tp_end.tv_usec - tp_start.tv_usec)/1000;
+               put_total_time_ms += this_time;
+               put_total_size += nread;
+               
+               DEBUG(1,("(%g kb/s) (average %g kb/s)\n",
+                        nread / (1.024*this_time + 1.0e-4),
+                        put_total_size / (1.024*put_total_time_ms)));
+       }
 
-  if (CVAL(inbuf,smb_rcls) != 0) {
-    DEBUG(0,("%s writing remote file\n",smb_errstr(inbuf)));
-    return(0);
-  }
-  return(SVAL(inbuf,smb_vwv0));
+       if (f == stdin) {
+               cli_shutdown(cli);
+               exit(0);
+       }
 }
-      
 
 
 /****************************************************************************
-  put a single file
+  put a file
   ****************************************************************************/
-static void do_put(char *rname,char *lname,file_info *finfo)
-{
-  int fnum;
-  FILE *f;
-  int nread=0;
-  char *p;
-  char *inbuf,*outbuf; 
-  time_t close_time = finfo->mtime;
-  char *buf=NULL;
-  static int maxwrite=0;
-
-  struct timeval tp_start;
-  GetTimeOfDay(&tp_start);
-
-  inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
-  if (!inbuf || !outbuf)
-    {
-      DEBUG(0,("out of memory\n"));
-      return;
-    }
-
-  bzero(outbuf,smb_size);
-  set_message(outbuf,3,2 + strlen(rname),True);
-
-  if (finfo->mtime == 0 || finfo->mtime == -1)
-    finfo->mtime = finfo->atime = finfo->ctime = time(NULL);
-
-  CVAL(outbuf,smb_com) = SMBcreate;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-
-  SSVAL(outbuf,smb_vwv0,finfo->mode);
-  put_dos_date3(outbuf,smb_vwv1,finfo->mtime);
-  
-  p = smb_buf(outbuf);
-  *p++ = 4;      
-  pstrcpy(p,rname);
-  
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-  
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      DEBUG(0,("%s opening remote file %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
-
-      free(inbuf);free(outbuf);if (buf) free(buf);
-      return;
-    }
-
-  /* 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)
-    {
-      DEBUG(0,("Error opening local file %s\n",lname));
-      free(inbuf);free(outbuf);
-      return;
-    }
-
-  
-  fnum = SVAL(inbuf,smb_vwv0);
-  if (finfo->size < 0)
-    finfo->size = file_size(lname);
+static void cmd_put(void)
+{
+       pstring lname;
+       pstring rname;
+       fstring buf;
+       char *p=buf;
+       file_info finfo;
+       finfo = def_finfo;
+       
+       pstrcpy(rname,cur_dir);
+       pstrcat(rname,"\\");
   
-  DEBUG(1,("putting file %s of size %.0f bytes as %s ",lname,(double)finfo->size,CNV_LANG(rname)));
+       if (!next_token(NULL,p,NULL,sizeof(buf))) {
+               DEBUG(0,("put <filename>\n"));
+               return;
+       }
+       pstrcpy(lname,p);
   
-  if (!maxwrite)
-    maxwrite = writebraw_supported?MAX(max_xmit,BUFFER_SIZE):(max_xmit-200);
-
-  /* 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;
+       if (next_token(NULL,p,NULL,sizeof(buf)))
+               pstrcat(rname,p);      
+       else
+               pstrcat(rname,lname);
+       
+       dos_clean_name(rname);
 
-      if ((n = readfile(buf+4,1,n,f)) < 1)
        {
-         DEBUG(0,("Error reading local file\n"));
-         break;
-       }         
-
-      ret = smb_writefile(outbuf,fnum,nread,buf+4,n);
-
-      if (n != ret) {
-             if (!maxwrite) {
-                     DEBUG(0,("Error writing file\n"));
-                     break;
-             } else {
-                     fseek(f,nread,SEEK_SET);
-                     maxwrite /= 2;
-                     continue;
-             }
-      }
-
-      nread += n;
-    }
-
-  bzero(outbuf,smb_size);
-  set_message(outbuf,3,0,True);
-  CVAL(outbuf,smb_com) = SMBclose;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-
-  SSVAL(outbuf,smb_vwv0,fnum);  
-  put_dos_date3(outbuf,smb_vwv1,close_time);
-
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-  
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      DEBUG(0,("%s closing remote file %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
-      fclose(f);
-      free(inbuf);free(outbuf);
-      if (buf) free(buf);
-      return;
-    }
+               SMB_STRUCT_STAT 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;
+               }
+               finfo.mtime = st.st_mtime;
+       }
 
-  
-  fclose(f);
-  free(inbuf);free(outbuf);
-  if (buf) free(buf);
-
-  {
-    struct timeval tp_end;
-    int this_time;
-
-    GetTimeOfDay(&tp_end);
-    this_time = 
-      (tp_end.tv_sec - tp_start.tv_sec)*1000 +
-       (tp_end.tv_usec - tp_start.tv_usec)/1000;
-    put_total_time_ms += this_time;
-    put_total_size += finfo->size;
-
-    DEBUG(1,("(%g kb/s) (average %g kb/s)\n",
-            finfo->size / (1.024*this_time + 1.0e-4),
-            put_total_size / (1.024*put_total_time_ms)));
-  }
+       do_put(rname,lname);
 }
 
-
-/****************************************************************************
-  put a file
-  ****************************************************************************/
-static void cmd_put(char *dum_in, char *dum_out)
-{
-  pstring lname;
-  pstring rname;
-  fstring buf;
-  char *p=buf;
-  file_info finfo;
-  finfo = def_finfo;
-  
-  pstrcpy(rname,cur_dir);
-  pstrcat(rname,"\\");
-  
-  
-  if (!next_token(NULL,p,NULL,sizeof(buf)))
-    {
-      DEBUG(0,("put <filename>\n"));
-      return;
-    }
-  pstrcpy(lname,p);
-  
-  if (next_token(NULL,p,NULL,sizeof(buf)))
-    pstrcat(rname,p);      
-  else
-    pstrcat(rname,lname);
-
-  dos_clean_name(rname);
-
-  {
-    SMB_STRUCT_STAT 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;
-    }
-    finfo.mtime = st.st_mtime;
-  }
-
-  do_put(rname,lname,&finfo);
-}
 
 /****************************************************************************
   seek in a directory/file list until you get something that doesn't start with
@@ -2071,624 +934,190 @@ static void cmd_put(char *dum_in, char *dum_out)
   ****************************************************************************/
 static BOOL seek_list(FILE *f,char *name)
 {
-  pstring s;
-  while (!feof(f))
-    {
-      if (fscanf(f,"%s",s) != 1) return(False);
-      trim_string(s,"./",NULL);
-      if (strncmp(s,name,strlen(name)) != 0)
-       {
-         pstrcpy(name,s);
-         return(True);
+       pstring s;
+       while (!feof(f)) {
+               if (fscanf(f,"%s",s) != 1) return(False);
+               trim_string(s,"./",NULL);
+               if (strncmp(s,name,strlen(name)) != 0) {
+                       pstrcpy(name,s);
+                       return(True);
+               }
        }
-    }
       
-  return(False);
+       return(False);
 }
 
 
 /****************************************************************************
   set the file selection mask
   ****************************************************************************/
-static void cmd_select(char *dum_in, char *dum_out)
+static void cmd_select(void)
 {
-  pstrcpy(fileselection,"");
-  next_token(NULL,fileselection,NULL,sizeof(fileselection));
+       pstrcpy(fileselection,"");
+       next_token(NULL,fileselection,NULL,sizeof(fileselection));
 }
 
 
 /****************************************************************************
   mput some files
   ****************************************************************************/
-static void cmd_mput(char *dum_in, char *dum_out)
+static void cmd_mput(void)
 {
-  pstring lname;
-  pstring rname;
-  file_info finfo;
-  fstring buf;
-  char *p=buf;
+       pstring lname;
+       pstring rname;
+       file_info finfo;
+       fstring buf;
+       char *p=buf;
+       
+       finfo = def_finfo;
 
-  finfo = def_finfo;
+       while (next_token(NULL,p,NULL,sizeof(buf))) {
+               SMB_STRUCT_STAT st;
+               pstring cmd;
+               pstring tmpname;
+               FILE *f;
+               
+               slprintf(tmpname,sizeof(pstring)-1,
+                        "%s/ls.smb.%d",tmpdir(),(int)getpid());
+               if (recurse)
+                       slprintf(cmd,sizeof(pstring)-1,
+                                "find . -name \"%s\" -print > %s",p,tmpname);
+               else
+                       slprintf(cmd,sizeof(pstring)-1,
+                                "/bin/ls %s > %s",p,tmpname);
+               system(cmd);
 
-  
-  while (next_token(NULL,p,NULL,sizeof(buf)))
-    {
-      SMB_STRUCT_STAT st;
-      pstring cmd;
-      pstring tmpname;
-      FILE *f;
-      
-      slprintf(tmpname,sizeof(pstring)-1,
-              "%s/ls.smb.%d",tmpdir(),(int)getpid());
-      if (recurse)
-       slprintf(cmd,sizeof(pstring)-1,
-               "find . -name \"%s\" -print > %s",p,tmpname);
-      else
-       slprintf(cmd,sizeof(pstring)-1,
-                "/bin/ls %s > %s",p,tmpname);
-      system(cmd);
-
-      f = fopen(tmpname,"r");
-      if (!f) continue;
-
-      while (!feof(f))
-       {
-         pstring quest;
+               f = fopen(tmpname,"r");
+               if (!f) continue;
+               
+               while (!feof(f)) {
+                       pstring quest;
+
+                       if (fscanf(f,"%s",lname) != 1) break;
+                       trim_string(lname,"./",NULL);
+                       
+               again1:
+                       
+                       /* check if it's a directory */
+                       if (directory_exist(lname,&st)) {
+                               if (!recurse) continue;
+                               slprintf(quest,sizeof(pstring)-1,
+                                        "Put directory %s? ",lname);
+                               if (prompt && !yesno(quest)) {
+                                       pstrcat(lname,"/");
+                                       if (!seek_list(f,lname))
+                                               break;
+                                       goto again1;                
+                               }
+             
+                               pstrcpy(rname,cur_dir);
+                               pstrcat(rname,lname);
+                               if (!cli_chkpath(cli, rname) && !do_mkdir(rname)) {
+                                       pstrcat(lname,"/");
+                                       if (!seek_list(f,lname))
+                                               break;
+                                       goto again1;
+                               }
+                               continue;
+                       } else {
+                               slprintf(quest,sizeof(quest)-1,
+                                        "Put file %s? ",lname);
+                               if (prompt && !yesno(quest)) continue;
+                               
+                               pstrcpy(rname,cur_dir);
+                               pstrcat(rname,lname);
+                       }
 
-         if (fscanf(f,"%s",lname) != 1) break;
-         trim_string(lname,"./",NULL);
+                       dos_format(rname);
 
-       again1:
+                       /* null size so do_put knows to ignore it */
+                       finfo.size = -1;
 
-         /* check if it's a directory */
-         if (directory_exist(lname,&st))
-           {
-             if (!recurse) continue;
-             slprintf(quest,sizeof(pstring)-1,
-                      "Put directory %s? ",lname);
-             if (prompt && !yesno(quest)) 
-               {
-                 pstrcat(lname,"/");
-                 if (!seek_list(f,lname))
-                   break;
-                 goto again1;              
+                       /* set the date on the file */
+                       finfo.mtime = st.st_mtime;
+                       
+                       do_put(rname,lname);
                }
-             
-             pstrcpy(rname,cur_dir);
-             pstrcat(rname,lname);
-             if (!chkpath(rname,False) && !do_mkdir(rname)) {
-               pstrcat(lname,"/");
-               if (!seek_list(f,lname))
-                 break;
-               goto again1;                              
-             }
-
-             continue;
-           }
-         else
-           {
-             slprintf(quest,sizeof(quest)-1,
-                      "Put file %s? ",lname);
-             if (prompt && !yesno(quest)) continue;
-
-             pstrcpy(rname,cur_dir);
-             pstrcat(rname,lname);
-           }
-         dos_format(rname);
-
-         /* null size so do_put knows to ignore it */
-         finfo.size = -1;
-
-         /* set the date on the file */
-         finfo.mtime = st.st_mtime;
-
-         do_put(rname,lname,&finfo);
+               fclose(f);
+               unlink(tmpname);
        }
-      fclose(f);
-      unlink(tmpname);
-    }
 }
 
+
 /****************************************************************************
   cancel a print job
   ****************************************************************************/
 static void do_cancel(int job)
 {
-  char *rparam = NULL;
-  char *rdata = NULL;
-  char *p;
-  int rdrcnt,rprcnt;
-  pstring param;
-
-  bzero(param,sizeof(param));
-
-  p = param;
-  SSVAL(p,0,81);               /* DosPrintJobDel() */
-  p += 2;
-  pstrcpy(p,"W");
-  p = skip_string(p,1);
-  pstrcpy(p,"");
-  p = skip_string(p,1);
-  SSVAL(p,0,job);     
-  p += 2;
-
-  if (cli_call_api(PIPE_LANMAN, 0,PTR_DIFF(p,param),0, 0,
-           6, 1000,
-              &rprcnt,&rdrcnt,
-              param,NULL, NULL,
-              &rparam,&rdata))
-    {
-      int res = SVAL(rparam,0);
-
-      if (!res)
-       printf("Job %d cancelled\n",job);
-      else
-       printf("Error %d calcelling job %d\n",res,job);
-      return;
-    }
-  else
-  printf("Server refused cancel request\n");
-
-  if (rparam) free(rparam);
-  if (rdata) free(rdata);
-
-  return;
+       if (cli_printjob_del(cli, job)) {
+               printf("Job %d cancelled\n",job);
+       } else {
+               printf("Error calcelling job %d : %s\n",job,cli_errstr(cli));
+       }
 }
 
 
 /****************************************************************************
   cancel a print job
   ****************************************************************************/
-static void cmd_cancel(char *inbuf,char *outbuf )
+static void cmd_cancel(void)
 {
-  fstring buf;
-  int job; 
-
-  if (!connect_as_printer)
-    {
-      DEBUG(0,("WARNING: You didn't use the -P option to smbclient.\n"));
-      DEBUG(0,("Trying to cancel print jobs without -P may fail\n"));
-    }
-
-  if (!next_token(NULL,buf,NULL,sizeof(buf))) {
-    printf("cancel <jobid> ...\n");
-    return;
-  }
-  do {
-    job = atoi(buf);
-    do_cancel(job);
-  } while (next_token(NULL,buf,NULL,sizeof(buf)));
-}
-
+       fstring buf;
+       int job; 
 
+       if (!next_token(NULL,buf,NULL,sizeof(buf))) {
+               printf("cancel <jobid> ...\n");
+               return;
+       }
+       do {
+               job = atoi(buf);
+               do_cancel(job);
+       } while (next_token(NULL,buf,NULL,sizeof(buf)));
+}
 
 
 /****************************************************************************
   print a file
   ****************************************************************************/
-static void cmd_print(char *inbuf,char *outbuf )
+static void cmd_print(void)
 {
-  int fnum;
-  FILE *f = NULL;
-  uint32 nread=0;
-  pstring lname;
-  pstring rname;
-  char *p;
-
-  if (!connect_as_printer)
-    {
-      DEBUG(0,("WARNING: You didn't use the -P option to smbclient.\n"));
-      DEBUG(0,("Trying to print without -P may fail\n"));
-    }
-
-  if (!next_token(NULL,lname,NULL, sizeof(lname)))
-    {
-      DEBUG(0,("print <filename>\n"));
-      return;
-    }
-
-  pstrcpy(rname,lname);
-  p = strrchr(rname,'/');
-  if (p)
-    {
-      pstring tname;
-      pstrcpy(tname,p+1);
-      pstrcpy(rname,tname);
-    }
-
-  if ((int)strlen(rname) > 14)
-    rname[14] = 0;
-
-  if (strequal(lname,"-"))
-    {
-      f = stdin;
-      pstrcpy(rname,"stdin");
-    }
-  
-  dos_clean_name(rname);
-
-  bzero(outbuf,smb_size);
-  set_message(outbuf,2,2 + strlen(rname),True);
-  
-  CVAL(outbuf,smb_com) = SMBsplopen;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
+       pstring lname;
+       pstring rname;
+       char *p;
 
-  SSVAL(outbuf,smb_vwv0,0);
-  SSVAL(outbuf,smb_vwv1,printmode);
-  
-  p = smb_buf(outbuf);
-  *p++ = 4;      
-  pstrcpy(p,rname);
-  
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-  
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      DEBUG(0,("%s opening printer for %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
-      return;
-    }
-  
-  if (!f)
-    f = fopen(lname,"r");
-  if (!f)
-    {
-      DEBUG(0,("Error opening local file %s\n",lname));
-      return;
-    }
-
-  
-  fnum = SVAL(inbuf,smb_vwv0);
-  
-  DEBUG(1,("printing file %s as %s\n",lname,CNV_LANG(rname)));
-  
-  while (!feof(f))
-    {
-      int n;
-  
-      bzero(outbuf,smb_size);
-      set_message(outbuf,1,3,True);
-
-      /* for some strange reason the OS/2 print server can't handle large
-        packets when printing. weird */
-      n = MIN(1024,max_xmit-(smb_len(outbuf)+4));
-
-      if (translation)
-       n = printread(f,smb_buf(outbuf)+3,(int)(0.95*n));
-      else
-       n = readfile(smb_buf(outbuf)+3,1,n,f);
-      if (n <= 0) 
-       {
-         DEBUG(0,("read gave %d\n",n));
-         break;
+       if (!next_token(NULL,lname,NULL, sizeof(lname))) {
+               DEBUG(0,("print <filename>\n"));
+               return;
        }
 
-      smb_setlen(outbuf,smb_len(outbuf) + n);
-
-      CVAL(outbuf,smb_com) = SMBsplwr;
-      SSVAL(outbuf,smb_tid,cnum);
-      cli_setup_pkt(outbuf);
-
-      SSVAL(outbuf,smb_vwv0,fnum);
-      SSVAL(outbuf,smb_vwv1,n+3);
-      CVAL(smb_buf(outbuf),0) = 1;
-      SSVAL(smb_buf(outbuf),1,n);
-
-      send_smb(Client,outbuf);
-      client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
-      if (CVAL(inbuf,smb_rcls) != 0)
-       {
-         DEBUG(0,("%s printing remote file\n",smb_errstr(inbuf)));
-         break;
+       pstrcpy(rname,lname);
+       p = strrchr(rname,'/');
+       if (p) {
+               slprintf(rname, sizeof(rname)-1, "%s-%d", p+1, (int)getpid());
        }
 
-      nread += n;
-    }
-
-  DEBUG(2,("%d bytes printed\n",nread));
-
-  bzero(outbuf,smb_size);
-  set_message(outbuf,1,0,True);
-  CVAL(outbuf,smb_com) = SMBsplclose;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-
-  SSVAL(outbuf,smb_vwv0,fnum);
-
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-  
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      DEBUG(0,("%s closing print file\n",smb_errstr(inbuf)));
-      if (f != stdin)
-       fclose(f);
-      return;
-    }
-
-  if (f != stdin)
-    fclose(f);
-}
-
-/****************************************************************************
- show a print queue - this is deprecated as it uses the old smb that
- has limited support - the correct call is the cmd_p_queue_4() after this.
-****************************************************************************/
-static void cmd_queue(char *inbuf,char *outbuf )
-{
-  int count;
-  char *p;
-
-  bzero(outbuf,smb_size);
-  set_message(outbuf,2,0,True);
-  
-  CVAL(outbuf,smb_com) = SMBsplretq;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
+       if (strequal(lname,"-")) {
+               slprintf(rname, sizeof(rname)-1, "stdin-%d", (int)getpid());
+       }
 
-  SSVAL(outbuf,smb_vwv0,32); /* a max of 20 entries is to be shown */
-  SSVAL(outbuf,smb_vwv1,0); /* the index into the queue */
-  
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-  
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      DEBUG(0,("%s obtaining print queue\n",smb_errstr(inbuf)));
-      return;
-    }
-
-  count = SVAL(inbuf,smb_vwv0);
-  p = smb_buf(inbuf) + 3;
-  if (count <= 0)
-    {
-      DEBUG(0,("No entries in the print queue\n"));
-      return;
-    }  
-
-  {
-    char status[20];
-
-    DEBUG(0,("Job      Name              Size         Status\n"));
-
-    while (count--)
-      {
-       switch (CVAL(p,4))
-         {
-         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",
-                SVAL(p,5),p+12,IVAL(p,7),status));
-       p += 28;
-      }
-  }
-  
+       do_put(rname, lname);
 }
 
 
 /****************************************************************************
-show information about a print queue
+ show a print queue entry
 ****************************************************************************/
-static void cmd_p_queue_4(char *inbuf,char *outbuf )
+static void queue_fn(struct print_job_info *p)
 {
-  char *rparam = NULL;
-  char *rdata = NULL;
-  char *p;
-  int rdrcnt, rprcnt;
-  pstring param;
-  int result_code=0;
-
-  if (!connect_as_printer)
-    {
-      DEBUG(0,("WARNING: You didn't use the -P option to smbclient.\n"));
-      DEBUG(0,("Trying to print without -P may fail\n"));
-    }
-  
-  bzero(param,sizeof(param));
-
-  p = param;
-  SSVAL(p,0,76);                        /* API function number 76 (DosPrintJobEnum) */
-  p += 2;
-  pstrcpy(p,"zWrLeh");                   /* parameter description? */
-  p = skip_string(p,1);
-  pstrcpy(p,"WWzWWDDzz");                /* returned data format */
-  p = skip_string(p,1);
-  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;
-  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, 0,
-               10, 4096,
-               &rprcnt, &rdrcnt,
-               param, NULL, NULL,
-               &rparam, &rdata) )
-    {
-      int converter;
-      result_code = SVAL(rparam,0);
-      converter = SVAL(rparam,2);             /* conversion factor */
-
-      DEBUG(2,("returned %d bytes of parameters, %d bytes of data, %d records\n", rprcnt, rdrcnt, SVAL(rparam,4) ));
-
-      if (result_code == 0)                   /* if no error, */
-        {
-          int i;
-          uint16 JobId;
-          uint16 Priority;
-          uint32 Size;
-          char *UserName;
-          char *JobName;
-          char *JobTimeStr;
-          time_t JobTime;
-          fstring PrinterName;
-             
-          fstrcpy(PrinterName,strrchr(service,'\\')+1);       /* name of queue */
-          strlower(PrinterName);                             /* in lower case */
-
-          p = rdata;                          /* received data */
-          for( i = 0; i < SVAL(rparam,4); ++i)
-            {
-              JobId = SVAL(p,0);
-              Priority = SVAL(p,2);
-              UserName = fix_char_ptr(SVAL(p,4), converter, rdata, rdrcnt);
-              strlower(UserName);
-              Priority = SVAL(p,2);
-              JobTime = make_unix_date3( p + 12);
-              JobTimeStr = asctime(LocalTime( &JobTime));
-              Size = IVAL(p,16);
-              JobName = fix_char_ptr(SVAL(p,24), converter, rdata, rdrcnt);
-            
-
-              printf("%s-%u    %s    priority %u   %s    %s   %u bytes\n", 
-               PrinterName, JobId, UserName,
-                Priority, JobTimeStr, JobName, Size);
-   
-#if 0 /* DEBUG code */
-              printf("Job Id: \"%u\"\n", SVAL(p,0));
-              printf("Priority: \"%u\"\n", SVAL(p,2));
-            
-              printf("User Name: \"%s\"\n", fix_char_ptr(SVAL(p,4), converter, rdata, rdrcnt) );
-              printf("Position: \"%u\"\n", SVAL(p,8));
-              printf("Status: \"%u\"\n", SVAL(p,10));
-            
-              JobTime = make_unix_date3( p + 12);
-              printf("Submitted: \"%s\"\n", asctime(LocalTime(&JobTime)));
-              printf("date: \"%u\"\n", SVAL(p,12));
-
-              printf("Size: \"%u\"\n", SVAL(p,16));
-              printf("Comment: \"%s\"\n", fix_char_ptr(SVAL(p,20), converter, rdata, rdrcnt) );
-              printf("Document: \"%s\"\n", fix_char_ptr(SVAL(p,24), converter, rdata, rdrcnt) );
-#endif /* DEBUG CODE */ 
-              p += 28;
-            }
-        }
-    }
-  else                  /* cli_call_api() failed */
-    {
-      printf("Failed, error = %d\n", result_code);
-    }
-
-  /* If any parameters or data were returned, free the storage. */
-  if(rparam) free(rparam);
-  if(rdata) free(rdata);
-
-  return;
+       DEBUG(0,("%-6d   %-9d    %s\n", (int)p->id, (int)p->size, p->name));
 }
 
 /****************************************************************************
-show information about a print queue
+ show a print queue
 ****************************************************************************/
-static void cmd_qinfo(char *inbuf,char *outbuf )
+static void cmd_queue(void)
 {
-  char *rparam = NULL;
-  char *rdata = NULL;
-  char *p;
-  int rdrcnt, rprcnt;
-  pstring param;
-  int result_code=0;
-  
-  bzero(param,sizeof(param));
-
-  p = param;
-  SSVAL(p,0,70);                       /* API function number 70 (DosPrintQGetInfo) */
-  p += 2;
-  pstrcpy(p,"zWrLh");                  /* parameter description? */
-  p = skip_string(p,1);
-  pstrcpy(p,"zWWWWzzzzWWzzl");         /* returned data format */
-  p = skip_string(p,1);
-  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;
-  pstrcpy(p,"");                               /* subformat */
-  p = skip_string(p,1);
-
-  DEBUG(1,("Calling DosPrintQueueGetInfo()...\n"));
-  if( cli_call_api(PIPE_LANMAN, 0,PTR_DIFF(p,param), 0, 0,
-           10, 4096,
-              &rprcnt, &rdrcnt,
-              param, NULL, NULL,
-              &rparam, &rdata) )
-       {
-       int converter;
-       result_code = SVAL(rparam,0);
-       converter = SVAL(rparam,2);             /* conversion factor */
-
-       DEBUG(2,("returned %d bytes of parameters, %d bytes of data, %d records\n", rprcnt, rdrcnt, SVAL(rparam,4) ));
-
-       if (result_code == 0)                   /* if no error, */
-           {
-           p = rdata;                          /* received data */
-
-           printf("Name: \"%s\"\n", fix_char_ptr(SVAL(p,0), converter, rdata, rdrcnt) );
-           printf("Priority: %u\n", SVAL(p,4) );
-           printf("Start time: %u\n", SVAL(p,6) );
-           printf("Until time: %u\n", SVAL(p,8) );
-           printf("Seperator file: \"%s\"\n", fix_char_ptr(SVAL(p,12), converter, rdata, rdrcnt) );
-           printf("Print processor: \"%s\"\n", fix_char_ptr(SVAL(p,16), converter, rdata, rdrcnt) );
-           printf("Parameters: \"%s\"\n", fix_char_ptr(SVAL(p,20), converter, rdata, rdrcnt) );
-           printf("Comment: \"%s\"\n", fix_char_ptr(SVAL(p,24), converter, rdata, rdrcnt) );
-           printf("Status: %u\n", SVAL(p,28) );
-           printf("Jobs: %u\n", SVAL(p,30) );
-           printf("Printers: \"%s\"\n", fix_char_ptr(SVAL(p,32), converter, rdata, rdrcnt) );
-           printf("Drivername: \"%s\"\n", fix_char_ptr(SVAL(p,36), converter, rdata, rdrcnt) );
-
-           /* Dump the driver data */
-           {
-           int count, x, y, c;
-           char *ddptr;
-
-           ddptr = rdata + SVAL(p,40) - converter;
-           if( SVAL(p,40) == 0 ) {count = 0;} else {count = IVAL(ddptr,0);}
-           printf("Driverdata: size=%d, version=%u\n", count, IVAL(ddptr,4) );
-
-           for(x=8; x < count; x+=16)
-               {
-               for(y=0; y < 16; y++)
-                   {
-                   if( (x+y) < count )
-                       printf("%2.2X ", CVAL(ddptr,(x+y)) );
-                   else
-                       fputs("   ", stdout);
-                   }
-               for(y=0; y < 16 && (x+y) < count; y++)
-                   {
-                   c = CVAL(ddptr,(x+y));
-                   if(isprint(c))
-                       fputc(c, stdout);
-                   else
-                       fputc('.', stdout);
-                   }
-               fputc('\n', stdout);
-               }
-           }
-           
-           }
-       }
-  else                 /* cli_call_api() failed */
-       {
-       printf("Failed, error = %d\n", result_code);
-       }
-
-  /* If any parameters or data were returned, free the storage. */
-  if(rparam) free(rparam);
-  if(rdata) free(rdata);
-
-  return;
+       cli_print_queue(cli, queue_fn);  
 }
 
 /****************************************************************************
@@ -2696,215 +1125,144 @@ delete some files
 ****************************************************************************/
 static void do_del(file_info *finfo)
 {
-  char *p;
-  char *inbuf,*outbuf;
-  pstring mask;
+       pstring mask;
 
-  pstrcpy(mask,cur_dir);
-  pstrcat(mask,finfo->name);
+       pstrcpy(mask,cur_dir);
+       pstrcat(mask,finfo->name);
 
-  if (finfo->mode & aDIR) 
-    return;
+       if (finfo->mode & aDIR) 
+               return;
 
-  inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  
-  if (!inbuf || !outbuf)
-    {
-      DEBUG(0,("out of memory\n"));
-      return;
-    }
-
-  bzero(outbuf,smb_size);
-  set_message(outbuf,1,2 + strlen(mask),True);
-  
-  CVAL(outbuf,smb_com) = SMBunlink;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-
-  SSVAL(outbuf,smb_vwv0,0);
-  
-  p = smb_buf(outbuf);
-  *p++ = 4;      
-  pstrcpy(p,mask);
-  
-  send_smb(Client,outbuf);
-  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)));
-
-  free(inbuf);free(outbuf);
-  
+       if (!cli_unlink(cli, mask)) {
+               DEBUG(0,("%s deleting remote file %s\n",cli_errstr(cli),CNV_LANG(mask)));
+       }
 }
 
 /****************************************************************************
 delete some files
 ****************************************************************************/
-static void cmd_del(char *inbuf,char *outbuf )
+static void cmd_del(void)
 {
-  pstring mask;
-  fstring buf;
-  int attribute = aSYSTEM | aHIDDEN;
+       pstring mask;
+       fstring buf;
+       int attribute = aSYSTEM | aHIDDEN;
 
-  if (recurse)
-    attribute |= aDIR;
-  
-  pstrcpy(mask,cur_dir);
-    
-  if (!next_token(NULL,buf,NULL,sizeof(buf)))
-    {
-      DEBUG(0,("del <filename>\n"));
-      return;
-    }
-  pstrcat(mask,buf);
-
-  do_dir((char *)inbuf,(char *)outbuf,mask,attribute,do_del,False,False);
+       if (recurse)
+               attribute |= aDIR;
+       
+       pstrcpy(mask,cur_dir);
+       
+       if (!next_token(NULL,buf,NULL,sizeof(buf))) {
+               DEBUG(0,("del <filename>\n"));
+               return;
+       }
+       pstrcat(mask,buf);
+
+       do_list(mask, attribute,do_del,False,False);
 }
 
 
 /****************************************************************************
 remove a directory
 ****************************************************************************/
-static void cmd_rmdir(char *inbuf,char *outbuf )
+static void cmd_rmdir(void)
 {
-  pstring mask;
-  fstring buf;
-  char *p;
-  
-  pstrcpy(mask,cur_dir);
+       pstring mask;
+       fstring buf;
   
-  if (!next_token(NULL,buf,NULL,sizeof(buf)))
-    {
-      DEBUG(0,("rmdir <dirname>\n"));
-      return;
-    }
-  pstrcat(mask,buf);
-
-  bzero(outbuf,smb_size);
-  set_message(outbuf,0,2 + strlen(mask),True);
-  
-  CVAL(outbuf,smb_com) = SMBrmdir;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
+       pstrcpy(mask,cur_dir);
+       
+       if (!next_token(NULL,buf,NULL,sizeof(buf))) {
+               DEBUG(0,("rmdir <dirname>\n"));
+               return;
+       }
+       pstrcat(mask,buf);
 
-  
-  p = smb_buf(outbuf);
-  *p++ = 4;      
-  pstrcpy(p,mask);
-  
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-  
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      DEBUG(0,("%s removing remote directory file %s\n",smb_errstr(inbuf),CNV_LANG(mask)));
-      return;
-    }
-  
+       if (!cli_rmdir(cli, mask)) {
+               DEBUG(0,("%s removing remote directory file %s\n",
+                        cli_errstr(cli),CNV_LANG(mask)));
+       }  
 }
 
 /****************************************************************************
 rename some files
 ****************************************************************************/
-static void cmd_rename(char *inbuf,char *outbuf )
+static void cmd_rename(void)
 {
-  pstring src,dest;
-  fstring buf,buf2;
-  char *p;
-  
-  pstrcpy(src,cur_dir);
-  pstrcpy(dest,cur_dir);
-  
-  if (!next_token(NULL,buf,NULL,sizeof(buf)) || 
-      !next_token(NULL,buf2,NULL, sizeof(buf2)))
-    {
-      DEBUG(0,("rename <src> <dest>\n"));
-      return;
-    }
-  pstrcat(src,buf);
-  pstrcat(dest,buf2);
-
-  bzero(outbuf,smb_size);
-  set_message(outbuf,1,4 + strlen(src) + strlen(dest),True);
-  
-  CVAL(outbuf,smb_com) = SMBmv;
-  SSVAL(outbuf,smb_tid,cnum);
-  SSVAL(outbuf,smb_vwv0,aHIDDEN | aDIR | aSYSTEM);
-  cli_setup_pkt(outbuf);
-  
-  p = smb_buf(outbuf);
-  *p++ = 4;      
-  pstrcpy(p,src);
-  p = skip_string(p,1);
-  *p++ = 4;      
-  pstrcpy(p,dest);
-  
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-  
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      DEBUG(0,("%s renaming files\n",smb_errstr(inbuf)));
-      return;
-    }
+       pstring src,dest;
+       fstring buf,buf2;
   
+       pstrcpy(src,cur_dir);
+       pstrcpy(dest,cur_dir);
+       
+       if (!next_token(NULL,buf,NULL,sizeof(buf)) || 
+           !next_token(NULL,buf2,NULL, sizeof(buf2))) {
+               DEBUG(0,("rename <src> <dest>\n"));
+               return;
+       }
+
+       pstrcat(src,buf);
+       pstrcat(dest,buf2);
+
+       if (!cli_rename(cli, src, dest)) {
+               DEBUG(0,("%s renaming files\n",cli_errstr(cli)));
+               return;
+       }  
 }
 
 
 /****************************************************************************
 toggle the prompt flag
 ****************************************************************************/
-static void cmd_prompt(char *dum_in, char *dum_out)
+static void cmd_prompt(void)
 {
-  prompt = !prompt;
-  DEBUG(2,("prompting is now %s\n",prompt?"on":"off"));
+       prompt = !prompt;
+       DEBUG(2,("prompting is now %s\n",prompt?"on":"off"));
 }
 
 
 /****************************************************************************
 set the newer than time
 ****************************************************************************/
-static void cmd_newer(char *dum_in, char *dum_out)
+static void cmd_newer(void)
 {
-  fstring buf;
-  BOOL ok;
-  SMB_STRUCT_STAT sbuf;
-
-  ok = next_token(NULL,buf,NULL,sizeof(buf));
-  if (ok && (dos_stat(buf,&sbuf) == 0))
-    {
-      newer_than = sbuf.st_mtime;
-      DEBUG(1,("Getting files newer than %s",
-              asctime(LocalTime(&newer_than))));
-    }
-  else
-    newer_than = 0;
-
-  if (ok && newer_than == 0)
-    DEBUG(0,("Error setting newer-than time\n"));
+       fstring buf;
+       BOOL ok;
+       SMB_STRUCT_STAT sbuf;
+
+       ok = next_token(NULL,buf,NULL,sizeof(buf));
+       if (ok && (dos_stat(buf,&sbuf) == 0)) {
+               newer_than = sbuf.st_mtime;
+               DEBUG(1,("Getting files newer than %s",
+                        asctime(LocalTime(&newer_than))));
+       } else {
+               newer_than = 0;
+       }
+
+       if (ok && newer_than == 0)
+               DEBUG(0,("Error setting newer-than time\n"));
 }
 
 /****************************************************************************
 set the archive level
 ****************************************************************************/
-static void cmd_archive(char *dum_in, char *dum_out)
+static void cmd_archive(void)
 {
-  fstring buf;
+       fstring buf;
 
-  if (next_token(NULL,buf,NULL,sizeof(buf))) {
-    archive_level = atoi(buf);
-  } else
-    DEBUG(0,("Archive level is %d\n",archive_level));
+       if (next_token(NULL,buf,NULL,sizeof(buf))) {
+               archive_level = atoi(buf);
+       } else
+               DEBUG(0,("Archive level is %d\n",archive_level));
 }
 
 /****************************************************************************
 toggle the lowercaseflag
 ****************************************************************************/
-static void cmd_lowercase(char *dum_in, char *dum_out)
+static void cmd_lowercase(void)
 {
-  lowercase = !lowercase;
-  DEBUG(2,("filename lowercasing is now %s\n",lowercase?"on":"off"));
+       lowercase = !lowercase;
+       DEBUG(2,("filename lowercasing is now %s\n",lowercase?"on":"off"));
 }
 
 
@@ -2913,348 +1271,130 @@ static void cmd_lowercase(char *dum_in, char *dum_out)
 /****************************************************************************
 toggle the recurse flag
 ****************************************************************************/
-static void cmd_recurse(char *dum_in, char *dum_out)
+static void cmd_recurse(void)
 {
-  recurse = !recurse;
-  DEBUG(2,("directory recursion is now %s\n",recurse?"on":"off"));
+       recurse = !recurse;
+       DEBUG(2,("directory recursion is now %s\n",recurse?"on":"off"));
 }
 
 /****************************************************************************
 toggle the translate flag
 ****************************************************************************/
-static void cmd_translate(char *dum_in, char *dum_out)
+static void cmd_translate(void)
 {
-  translation = !translation;
-  DEBUG(2,("CR/LF<->LF and print text translation now %s\n",
-       translation?"on":"off"));
+       translation = !translation;
+       DEBUG(2,("CR/LF<->LF and print text translation now %s\n",
+                translation?"on":"off"));
 }
 
 
 /****************************************************************************
 do a printmode command
 ****************************************************************************/
-static void cmd_printmode(char *dum_in, char *dum_out)
-{
-  fstring buf;
-  fstring mode;
-
-  if (next_token(NULL,buf,NULL,sizeof(buf)))
-    {
-      if (strequal(buf,"text"))
-       printmode = 0;      
-      else
-       {
-         if (strequal(buf,"graphics"))
-           printmode = 1;
-         else
-           printmode = atoi(buf);
+static void cmd_printmode(void)
+{
+       fstring buf;
+       fstring mode;
+
+       if (next_token(NULL,buf,NULL,sizeof(buf))) {
+               if (strequal(buf,"text")) {
+                       printmode = 0;      
+               } else {
+                       if (strequal(buf,"graphics"))
+                               printmode = 1;
+                       else
+                               printmode = atoi(buf);
+               }
        }
-    }
-
-  switch(printmode)
-    {
-    case 0: 
-      fstrcpy(mode,"text");
-      break;
-    case 1: 
-      fstrcpy(mode,"graphics");
-      break;
-    default: 
-      slprintf(mode,sizeof(mode)-1,"%d",printmode);
-      break;
-    }
-
-  DEBUG(2,("the printmode is now %s\n",mode));
-}
 
-/****************************************************************************
-do the lcd command
-****************************************************************************/
-static void cmd_lcd(char *dum_in, char *dum_out)
-{
-  fstring buf;
-  pstring d;
-
-  if (next_token(NULL,buf,NULL,sizeof(buf)))
-    dos_chdir(buf);
-  DEBUG(2,("the local directory is now %s\n",GetWd(d)));
+       switch(printmode)
+               {
+               case 0: 
+                       fstrcpy(mode,"text");
+                       break;
+               case 1: 
+                       fstrcpy(mode,"graphics");
+                       break;
+               default: 
+                       slprintf(mode,sizeof(mode)-1,"%d",printmode);
+                       break;
+               }
+       
+       DEBUG(2,("the printmode is now %s\n",mode));
 }
 
-
 /****************************************************************************
-try and browse available connections on a host
+do the lcd command
 ****************************************************************************/
-static BOOL browse_host(BOOL sort)
+static void cmd_lcd(void)
 {
-  char *rparam = NULL;
-  char *rdata = NULL;
-  char *p;
-  int rdrcnt,rprcnt;
-  pstring param;
-  int count = -1;
-
-  /* now send a SMBtrans command with api RNetShareEnum */
-  p = param;
-  SSVAL(p,0,0); /* api number */
-  p += 2;
-  pstrcpy(p,"WrLeh");
-  p = skip_string(p,1);
-  pstrcpy(p,"B13BWz");
-  p = skip_string(p,1);
-  SSVAL(p,0,1);
-  SSVAL(p,2,BUFFER_SIZE);
-  p += 4;
-
-  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;
-      
-    if (res == 0 || res == ERRmoredata)
-    {
-      count=SVAL(rparam,4);
-      p = rdata;
-
-      if (count > 0)
-      {
-        printf("\n\tSharename      Type      Comment\n");
-        printf("\t---------      ----      -------\n");
-      }
-
-      if (sort)
-        qsort(p,count,20,QSORT_CAST StrCaseCmp);
+       fstring buf;
+       pstring d;
+       
+       if (next_token(NULL,buf,NULL,sizeof(buf)))
+               dos_chdir(buf);
+       DEBUG(2,("the local directory is now %s\n",GetWd(d)));
+}
 
-      for (i=0;i<count;i++)
-      {
-        char *sname = p;
-        int type = SVAL(p,14);
-        int comment_offset = IVAL(p,16) & 0xFFFF;
+/****************************************************************************
+list a share name
+****************************************************************************/
+static void browse_fn(const char *name, uint32 m, const char *comment)
+{
         fstring typestr;
         *typestr=0;
 
-        switch (type)
+        switch (m)
         {
           case STYPE_DISKTREE:
             fstrcpy(typestr,"Disk"); break;
           case STYPE_PRINTQ:
-            fstrcpy(typestr,"Printer"); break;       
+            fstrcpy(typestr,"Printer"); break;
           case STYPE_DEVICE:
             fstrcpy(typestr,"Device"); break;
           case STYPE_IPC:
-            fstrcpy(typestr,"IPC"); break;      
+            fstrcpy(typestr,"IPC"); break;
         }
 
         printf("\t%-15.15s%-10.10s%s\n",
-               sname, typestr,
-               comment_offset?rdata+comment_offset-converter:"");
-         
-        if (strlen(sname)>8) long_share_name=True;
-         
-        p += 20;
-      }
-
-      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);
-
-  return(count>0);
+               name, typestr,comment);
 }
 
 
 /****************************************************************************
-get some server info
+try and browse available connections on a host
 ****************************************************************************/
-static void server_info(void)
+static BOOL browse_host(BOOL sort)
 {
-  char *rparam = NULL;
-  char *rdata = NULL;
-  char *p;
-  int rdrcnt,rprcnt;
-  pstring param;
-
-  bzero(param,sizeof(param));
-
-  p = param;
-  SSVAL(p,0,63);               /* NetServerGetInfo()? */
-  p += 2;
-  pstrcpy(p,"WrLh");
-  p = skip_string(p,1);
-  pstrcpy(p,"zzzBBzz");
-  p = skip_string(p,1);
-  SSVAL(p,0,10); /* level 10 */
-  SSVAL(p,2,1000);
-  p += 6;
-
-  if (cli_call_api(PIPE_LANMAN, 0,PTR_DIFF(p,param),0, 0,
-           6, 1000,
-              &rprcnt,&rdrcnt,
-              param,NULL, NULL,
-              &rparam,&rdata))
-    {
-      int res = SVAL(rparam,0);
-      int converter=SVAL(rparam,2);
-
-      if (res == 0)
-       {
-      p = rdata;
-
-      printf("\nServer=[%s] User=[%s] Workgroup=[%s] Domain=[%s]\n",
-            rdata+SVAL(p,0)-converter,
-            rdata+SVAL(p,4)-converter,
-            rdata+SVAL(p,8)-converter,
-            rdata+SVAL(p,14)-converter);
-    }
-    }
-
-  if (rparam) free(rparam);
-  if (rdata) free(rdata);
+        printf("\n\tSharename      Type      Comment\n");
+        printf("\t---------      ----      -------\n");
 
-  return;
+       return cli_RNetShareEnum(cli, browse_fn);
 }
 
+/****************************************************************************
+list a server name
+****************************************************************************/
+static void server_fn(const char *name, uint32 m, const char *comment)
+{
+        printf("\t%-16.16s     %s\n", name, comment);
+}
 
 /****************************************************************************
 try and browse available connections on a host
 ****************************************************************************/
 static BOOL list_servers(char *wk_grp)
 {
-  char *rparam = NULL;
-  char *rdata = NULL;
-  int rdrcnt,rprcnt;
-  char *p,*svtype_p;
-  pstring param;
-  int uLevel = 1;
-  int count = 0;
-  BOOL ok = False;
-  BOOL generic_request = False;
-
-
-  if (strequal(wk_grp,"WORKGROUP")) {
-    /* we won't specify a workgroup */
-    generic_request = True;
-  } 
-
-  /* now send a SMBtrans command with api ServerEnum? */
-  p = param;
-  SSVAL(p,0,0x68); /* api number */
-  p += 2;
-
-  pstrcpy(p,generic_request?"WrLehDO":"WrLehDz");
-  p = skip_string(p,1);
-
-  pstrcpy(p,"B16BBDz");
-
-  p = skip_string(p,1);
-  SSVAL(p,0,uLevel);
-  SSVAL(p,2,BUFFER_SIZE - SAFETY_MARGIN); /* buf length */
-  p += 4;
-
-  svtype_p = p;
-  p += 4;
-
-  if (!generic_request) {
-    pstrcpy(p, wk_grp);
-    p = skip_string(p,1);
-  }
-
-  /* first ask for a list of servers in this workgroup */
-  SIVAL(svtype_p,0,SV_TYPE_ALL);
-
-  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 || 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;
-      }
-
-      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;}
-
-  /* now ask for a list of workgroups */
-  SIVAL(svtype_p,0,SV_TYPE_DOMAIN_ENUM);
-
-  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 || res == ERRmoredata) {
-      char *p2 = rdata;
-      count=SVAL(rparam,4);
-
-      if (count > 0) {
-        printf("\n\nThis machine has a workgroup list:\n");
+
+       cli_NetServerEnum(cli, workgroup, SV_TYPE_ALL, server_fn);
+
         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:"");
-         
-        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);
-
-  return(ok);
+
+       cli_NetServerEnum(cli, workgroup, SV_TYPE_DOMAIN_ENUM, server_fn);
+       return True;
 }
 
 
@@ -3268,7 +1408,7 @@ static BOOL list_servers(char *wk_grp)
 struct
 {
   char *name;
-  void (*fn)(char *, char *);
+  void (*fn)(void);
   char *description;
   char compl_args[2];      /* Completion argument info */
 } commands[] = 
@@ -3292,7 +1432,6 @@ struct
   {"md",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
   {"rmdir",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
   {"rd",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
-  {"pq",cmd_p_queue_4,"enumerate the print queue",{COMPL_NONE,COMPL_NONE}},
   {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput",{COMPL_NONE,COMPL_NONE}},  
   {"recurse",cmd_recurse,"toggle directory recursion for mget and mput",{COMPL_NONE,COMPL_NONE}},  
   {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}},  
@@ -3300,11 +1439,10 @@ struct
   {"print",cmd_print,"<file name> print a file",{COMPL_NONE,COMPL_NONE}},
   {"printmode",cmd_printmode,"<graphics or text> set the print mode",{COMPL_NONE,COMPL_NONE}},
   {"queue",cmd_queue,"show the print queue",{COMPL_NONE,COMPL_NONE}},
-  {"qinfo",cmd_qinfo,"show print queue information",{COMPL_NONE,COMPL_NONE}},
   {"cancel",cmd_cancel,"<jobid> cancel a print queue entry",{COMPL_NONE,COMPL_NONE}},
-  {"quit",cli_send_logout,"logoff the server",{COMPL_NONE,COMPL_NONE}},
-  {"q",cli_send_logout,"logoff the server",{COMPL_NONE,COMPL_NONE}},
-  {"exit",cli_send_logout,"logoff the server",{COMPL_NONE,COMPL_NONE}},
+  {"quit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
+  {"q",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
+  {"exit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
   {"newer",cmd_newer,"<file> only mget files newer than the specified local file",{COMPL_LOCAL,COMPL_NONE}},
   {"archive",cmd_archive,"<level>\n0=ignore archive bit\n1=only get archive files\n2=only get archive files and reset archive bit\n3=get all files and reset archive bit",{COMPL_NONE,COMPL_NONE}},
   {"tar",cmd_tar,"tar <c|x>[IXFqbgNan] current directory to/from <file name>",{COMPL_NONE,COMPL_NONE}},
@@ -3325,398 +1463,277 @@ struct
   ******************************************************************/
 static int process_tok(fstring tok)
 {
-  int i = 0, matches = 0;
-  int cmd=0;
-  int tok_len = strlen(tok);
-  
-  while (commands[i].fn != NULL)
-    {
-      if (strequal(commands[i].name,tok))
-       {
-         matches = 1;
-         cmd = i;
-         break;
-       }
-      else if (strnequal(commands[i].name, tok, tok_len))
-       {
-         matches++;
-         cmd = i;
+       int i = 0, matches = 0;
+       int cmd=0;
+       int tok_len = strlen(tok);
+       
+       while (commands[i].fn != NULL) {
+               if (strequal(commands[i].name,tok)) {
+                       matches = 1;
+                       cmd = i;
+                       break;
+               } else if (strnequal(commands[i].name, tok, tok_len)) {
+                       matches++;
+                       cmd = i;
+               }
+               i++;
        }
-      i++;
-    }
   
-  if (matches == 0)
-    return(-1);
-  else if (matches == 1)
-    return(cmd);
-  else
-    return(-2);
+       if (matches == 0)
+               return(-1);
+       else if (matches == 1)
+               return(cmd);
+       else
+               return(-2);
 }
 
 /****************************************************************************
 help
 ****************************************************************************/
-static void cmd_help(char *dum_in, char *dum_out)
+static void cmd_help(void)
 {
-  int i=0,j;
-  fstring buf;
-
-  if (next_token(NULL,buf,NULL,sizeof(buf)))
-    {
-      if ((i = process_tok(buf)) >= 0)
-       DEBUG(0,("HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description));                   
-    }
-  else
-    while (commands[i].description)
-      {
-       for (j=0; commands[i].description && (j<5); j++) {
-         DEBUG(0,("%-15s",commands[i].name));
-         i++;
+       int i=0,j;
+       fstring buf;
+       
+       if (next_token(NULL,buf,NULL,sizeof(buf))) {
+               if ((i = process_tok(buf)) >= 0)
+                       DEBUG(0,("HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description));                   
+       } else {
+               while (commands[i].description) {
+                       for (j=0; commands[i].description && (j<5); j++) {
+                               DEBUG(0,("%-15s",commands[i].name));
+                               i++;
+                       }
+                       DEBUG(0,("\n"));
+               }
        }
-       DEBUG(0,("\n"));
-      }
 }
 
-#ifndef HAVE_LIBREADLINE
-
 /****************************************************************************
 wait for keyboard activity, swallowing network packets
 ****************************************************************************/
-static void wait_keyboard(char *buffer)
+static void wait_keyboard(void)
 {
-  fd_set fds;
-  struct timeval timeout;
+       fd_set fds;
+       struct timeval timeout;
   
-  while (1) 
-    {
-      extern int Client;
-      FD_ZERO(&fds);
-      FD_SET(Client,&fds);
-      FD_SET(fileno(stdin),&fds);
-
-      timeout.tv_sec = 20;
-      timeout.tv_usec = 0;
-      sys_select(MAX(Client,fileno(stdin))+1,&fds,&timeout);
+       while (1) {
+               FD_ZERO(&fds);
+               FD_SET(cli->fd,&fds);
+               FD_SET(fileno(stdin),&fds);
+
+               timeout.tv_sec = 20;
+               timeout.tv_usec = 0;
+               sys_select(MAX(cli->fd,fileno(stdin))+1,&fds,&timeout);
       
-      if (FD_ISSET(fileno(stdin),&fds))
-       return;
-
-      /* 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);
+               if (FD_ISSET(fileno(stdin),&fds))
+                       return;
+
+               /* 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(cli->fd,&fds))
+                       receive_smb(cli->fd,cli->inbuf,0);
       
-      chkpath("\\",False);
-    }  
+               cli_chkpath(cli, "\\");
+       }  
 }
 
-#else /* if HAVE_LIBREADLINE */
-
 /****************************************************************************
-  completion routines for GNU Readline
+process a -c command string
 ****************************************************************************/
-
-/* To avoid filename completion being activated when no valid
-   completions are found, we assign this stub completion function
-   to the rl_completion_entry_function variable. */
-
-char *complete_cmd_null(char *text, int state)
-{
-  return NULL;
-}
-
-/* Argh.  This is starting to get ugly.  We need to be able to pass data
-   back from the do_dir() iterator function. */
-
-static int compl_state;
-static char *compl_text;
-static pstring result;
-
-/* Iterator function for do_dir() */
-
-void complete_process_file(file_info *f)
-{
-  /* Do we have a partial match? */
-
-  if ((compl_state >= 0) && (strncmp(compl_text, f->name, 
-                                    strlen(compl_text)) == 0)) {
-
-    /* Return filename if we have made enough matches */
-
-    if (compl_state == 0) {
-      pstrcpy(result, f->name);
-      compl_state = -1;
-
-      return;
-    }
-    compl_state--;
-  }
-}
-
-/* Complete a remote file */
-
-char *complete_remote_file(char *text, int state)
+static void process_command_string(char *cmd)
 {
-  char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  int attribute = aDIR | aSYSTEM | aHIDDEN;
-  pstring mask;
-
-  if ((InBuffer == NULL) || (OutBuffer == NULL)) 
-    return(NULL);
-
-  /* Create dir mask */
-
-  pstrcpy(mask, cur_dir);
-  pstrcat(mask, "*");
-
-  /* Initialise static vars for filename match */
-
-  compl_text = text;
-  compl_state = state;
-  result[0] = '\0';
-
-  /* Iterate over all files in directory */
-
-  do_dir(InBuffer, OutBuffer, mask, attribute, complete_process_file, False, 
-        True);
-
-  /* Clean up */
-
-  free(InBuffer);
-  free(OutBuffer);
-
-  /* Return matched filename */
-
-  if (result[0] != '\0') {
-    return strdup(result);      /* Readline will dispose of strings */
-  } else {
-    return NULL;
-  }
-}
+       pstring line;
+       char *ptr;
 
-/* Complete a smbclient command */
+       while (cmd[0] != '\0')    {
+               char *p;
+               fstring tok;
+               int i;
+               
+               if ((p = strchr(cmd, ';')) == 0) {
+                       strncpy(line, cmd, 999);
+                       line[1000] = '\0';
+                       cmd += strlen(cmd);
+               } else {
+                       if (p - cmd > 999) p = cmd + 999;
+                       strncpy(line, cmd, p - cmd);
+                       line[p - cmd] = '\0';
+                       cmd = p + 1;
+               }
+               
+               /* input language code to internal one */
+               CNV_INPUT (line);
+               
+               /* and get the first part of the command */
+               ptr = line;
+               if (!next_token(&ptr,tok,NULL,sizeof(tok))) continue;
+               
+               if ((i = process_tok(tok)) >= 0) {
+                       commands[i].fn();
+               } else if (i == -2) {
+                       DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
+               } else {
+                       DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
+               }
+       }
+}      
 
-char *complete_cmd(char *text, int state)
+/****************************************************************************
+process commands on stdin
+****************************************************************************/
+static void process_stdin(void)
 {
-  static int cmd_index;
-  char *name;
-
-  /* Initialise */
-  
-  if (state == 0) {
-    cmd_index = 0;
-  }
+       pstring line;
+       char *ptr;
 
-  /* Return the next name which partially matches the list of commands */
+       while (!feof(stdin)) {
+               fstring tok;
+               int i;
 
-  while (strlen(name = commands[cmd_index++].name) > 0) {
-    if (strncmp(name, text, strlen(text)) == 0) {
-      return strdup(name);
-    }
-  }
+               /* display a prompt */
+               DEBUG(0,("smb: %s> ", CNV_LANG(cur_dir)));
+               dbgflush( );
+               
+               wait_keyboard();
+               
+               /* and get a response */
+               if (!fgets(line,1000,stdin))
+                       break;
 
-  return NULL;
+               /* input language code to internal one */
+               CNV_INPUT (line);
+               
+               /* special case - first char is ! */
+               if (*line == '!') {
+                       system(line + 1);
+                       continue;
+               }
+      
+               /* and get the first part of the command */
+               ptr = line;
+               if (!next_token(&ptr,tok,NULL,sizeof(tok))) continue;
+
+               if ((i = process_tok(tok)) >= 0) {
+                       commands[i].fn();
+               } else if (i == -2) {
+                       DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
+               } else {
+                       DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
+               }
+       }
 }
 
-/* Main completion function for smbclient.  Work out which word we are
-   trying to complete and call the appropriate function. */
 
-char **completion_fn(char *text, int start, int end)
+/***************************************************** 
+return a connection to a server
+*******************************************************/
+struct cli_state *do_connect(char *server, char *share)
 {
-  int i, num_words, cmd_index;
-  char lastch = ' ';
-
-  /* If we are at the start of a word, we are completing a smbclient
-     command. */
+       struct cli_state *c;
+       struct nmb_name called, calling;
+       char *server_n;
+       struct in_addr ip;
+       extern struct in_addr ipzero;
 
-  if (start == 0) {
-    return completion_matches(text, complete_cmd);
-  }
+       if (*share == '\\') {
+               server = share+2;
+               share = strchr(server,'\\');
+               if (!share) return NULL;
+               *share = 0;
+               share++;
+       }
 
-  /* Count # of words in command */
+       server_n = server;
+       
+       ip = ipzero;
 
-  num_words = 0;
-  for (i = 0; i <= end; i++) {
-    if ((rl_line_buffer[i] != ' ') && (lastch == ' '))
-      num_words++;
-    lastch = rl_line_buffer[i];
-  }
+       strupper(server);
 
-  if (rl_line_buffer[end] == ' ')
-    num_words++;
+       make_nmb_name(&calling, global_myname, 0x0, "");
+       make_nmb_name(&called , server, name_type, "");
 
-  /* Work out which command we are completing for */
+ again:
+       ip = ipzero;
+       if (have_ip) ip = dest_ip;
 
-  for (cmd_index = 0; strcmp(commands[cmd_index].name, "") != 0; 
-       cmd_index++) {
+       /* have to open a new connection */
+       if (!(c=cli_initialise(NULL)) || !cli_connect(c, server_n, &ip)) {
+               DEBUG(0,("Connection to %s failed\n", server_n));
+               return NULL;
+       }
 
-    /* Check each command in array */
+       if (!cli_session_request(c, &calling, &called)) {
+               DEBUG(0,("session request to %s failed\n", called.name));
+               cli_shutdown(c);
+               if (strcmp(called.name, "*SMBSERVER")) {
+                       make_nmb_name(&called , "*SMBSERVER", 0x20, "");
+                       goto again;
+               }
+               return NULL;
+       }
 
-    if (strncmp(rl_line_buffer, commands[cmd_index].name,
-               strlen(commands[cmd_index].name)) == 0) {
+       DEBUG(4,(" session request ok\n"));
 
-      /* Call appropriate completion function */
+       if (!cli_negprot(c)) {
+               DEBUG(0,("protocol negotiation failed\n"));
+               cli_shutdown(c);
+               return NULL;
+       }
 
-      if ((num_words == 2) || (num_words == 3)) {
-       switch (commands[cmd_index].compl_args[num_words - 2]) {
+       if (!got_pass) {
+               char *pass = getpass("Password: ");
+               if (pass) {
+                       pstrcpy(password, pass);
+               }
+       }
 
-       case COMPL_REMOTE:
-         return completion_matches(text, complete_remote_file);
-         break;
+       if (!cli_session_setup(c, username, 
+                              password, strlen(password),
+                              password, strlen(password),
+                              workgroup)) {
+               DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
+               return NULL;
+       }
 
-       case COMPL_LOCAL:
-         return completion_matches(text, filename_completion_function);
-         break;
+       DEBUG(4,(" session setup ok\n"));
 
-       default:
-           /* An invalid completion type */
-           break;
+       if (!cli_send_tconX(c, share, "?????",
+                           password, strlen(password)+1)) {
+               DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
+               cli_shutdown(c);
+               return NULL;
        }
-      }
 
-      /* We're either completing an argument > 3 or found an invalid
-        completion type.  Either way do nothing about it. */
+       DEBUG(4,(" tconx ok\n"));
 
-      break;
-    }
-  }
-  return NULL;
+       return c;
 }
 
-#endif /* HAVE_LIBREADLINE */
 
 /****************************************************************************
   process commands from the client
 ****************************************************************************/
 static BOOL process(char *base_directory)
 {
-  pstring line;
-  char *cmd;
-
-  char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
-  if ((InBuffer == NULL) || (OutBuffer == NULL)) 
-    return(False);
-  
-  bzero(OutBuffer,smb_size);
-
-  if (!cli_send_login(InBuffer,OutBuffer,True,True,NULL))
-    return(False);
-
-  if (*base_directory) do_cd(base_directory);
-
-  cmd = cmdstr;
-  if (cmd[0] != '\0') while (cmd[0] != '\0')
-    {
-      char *p;
-      fstring tok;
-      int i;
-
-      if ((p = strchr(cmd, ';')) == 0)
-       {
-         strncpy(line, cmd, 999);
-         line[1000] = '\0';
-         cmd += strlen(cmd);
-       }
-      else
-       {
-         if (p - cmd > 999) p = cmd + 999;
-         strncpy(line, cmd, p - cmd);
-         line[p - cmd] = '\0';
-         cmd = p + 1;
+       cli = do_connect(desthost, service);
+       
+       if (!cli) {
+               return(False);
        }
-
-      /* input language code to internal one */
-      CNV_INPUT (line);
-      
-      /* and get the first part of the command */
-      {
-       char *ptr = line;
-       if (!next_token(&ptr,tok,NULL,sizeof(tok))) continue;
-      }
-
-      if ((i = process_tok(tok)) >= 0)
-       commands[i].fn(InBuffer,OutBuffer);
-      else if (i == -2)
-       DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
-      else
-       DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
-    }
-  else while (!feof(stdin))
-    {
-      fstring tok;
-      int i;
-
-      bzero(OutBuffer,smb_size);
-
-#ifdef HAVE_LIBREADLINE
-
-      {
-       pstring promptline;
        
-       /* Read input using GNU Readline */
-
-       slprintf(promptline, 
-                sizeof(promptline) - 1, "smb: %s> ", CNV_LANG(cur_dir));
-       if (!readline(promptline))
-         break;
-
-       /* Copy read line to samba buffer */
+       if (*base_directory) do_cd(base_directory);
        
-       pstrcpy(line, rl_line_buffer);
-       pstrcat(line, "\n");
-
-       /* Add line to history */
-
-       if (strlen(line) > 0)
-         add_history(line);
-      }
-
-#else
-
-      /* display a prompt */
-      DEBUG(0,("smb: %s> ", CNV_LANG(cur_dir)));
-      dbgflush( );
-
-      wait_keyboard(InBuffer);
-  
-      /* and get a response */
-      if (!fgets(line,1000,stdin))
-       break;
-
-#endif
-
-      /* input language code to internal one */
-      CNV_INPUT (line);
-
-      /* special case - first char is ! */
-      if (*line == '!')
-       {
-         system(line + 1);
-         continue;
+       if (cmdstr) {
+               process_command_string(cmdstr);
+       } else {
+               process_stdin();
        }
-      
-      /* and get the first part of the command */
-      {
-       char *ptr = line;
-       if (!next_token(&ptr,tok,NULL,sizeof(tok))) continue;
-      }
-
-      if ((i = process_tok(tok)) >= 0)
-       commands[i].fn(InBuffer,OutBuffer);
-      else if (i == -2)
-       DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
-      else
-       DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
-    }
   
-  cli_send_logout(InBuffer,OutBuffer);
-  return(True);
+       cli_shutdown(cli);
+       return(True);
 }
 
 /****************************************************************************
@@ -3753,443 +1770,409 @@ static void usage(char *pname)
   DEBUG(0,("\n"));
 }
 
+
+/****************************************************************************
+get a password from a a file or file descriptor
+exit on failure
+****************************************************************************/
+static void get_password_file(void)
+{
+       int fd = -1;
+       char *p;
+       BOOL close_it = False;
+       pstring spec;
+       char pass[128];
+               
+       if ((p = getenv("PASSWD_FD")) != NULL) {
+               pstrcpy(spec, "descriptor ");
+               pstrcat(spec, p);
+               sscanf(p, "%d", &fd);
+               close_it = False;
+       } else if ((p = getenv("PASSWD_FILE")) != NULL) {
+               fd = open(p, O_RDONLY);
+               pstrcpy(spec, p);
+               if (fd < 0) {
+                       fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n",
+                               spec, strerror(errno));
+                       exit(1);
+               }
+               close_it = True;
+       }
+
+       for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */
+           p && p - pass < sizeof(pass);) {
+               switch (read(fd, p, 1)) {
+               case 1:
+                       if (*p != '\n' && *p != '\0') {
+                               *++p = '\0'; /* advance p, and null-terminate pass */
+                               break;
+                       }
+               case 0:
+                       if (p - pass) {
+                               *p = '\0'; /* null-terminate it, just in case... */
+                               p = NULL; /* then force the loop condition to become false */
+                               break;
+                       } else {
+                               fprintf(stderr, "Error reading password from file %s: %s\n",
+                                       spec, "empty password\n");
+                               exit(1);
+                       }
+                       
+               default:
+                       fprintf(stderr, "Error reading password from file %s: %s\n",
+                               spec, strerror(errno));
+                       exit(1);
+               }
+       }
+       pstrcpy(password, pass);
+       if (close_it)
+               close(fd);
+}      
+
+
+
+/****************************************************************************
+handle a -L query
+****************************************************************************/
+static int do_host_query(char *query_host, int port)
+{
+       cli = do_connect(query_host, "IPC$");
+       if (!cli) return 1;
+
+       browse_host(True);
+       list_servers(workgroup);
+
+       cli_shutdown(cli);
+       
+       return(0);
+}
+
+
+/****************************************************************************
+handle a tar operation
+****************************************************************************/
+static int do_tar_op(int port, char *base_directory)
+{
+       int ret;
+       cli = do_connect(desthost, service);
+
+       recurse=True;
+
+       if (*base_directory) do_cd(base_directory);
+       
+       ret=process_tar();
+
+       cli_shutdown(cli);
+
+       return(ret);
+}
+
+/****************************************************************************
+handle a message operation
+****************************************************************************/
+static int do_message_op(void)
+{
+       struct in_addr ip;
+       struct nmb_name called, calling;
+
+       ip = ipzero;
+
+       strupper(desthost);
+
+       make_nmb_name(&calling, global_myname, 0x0, "");
+       make_nmb_name(&called , desthost, name_type, "");
+
+       ip = ipzero;
+       if (have_ip) ip = dest_ip;
+
+       if (!(cli=cli_initialise(NULL)) || !cli_connect(cli, desthost, &ip)) {
+               DEBUG(0,("Connection to %s failed\n", desthost));
+               return 1;
+       }
+
+       if (!cli_session_request(cli, &calling, &called)) {
+               DEBUG(0,("session request failed\n"));
+               cli_shutdown(cli);
+               return 1;
+       }
+
+       send_message();
+       cli_shutdown(cli);
+
+       return 0;
+}
+
+
 /****************************************************************************
   main program
 ****************************************************************************/
  int main(int argc,char *argv[])
 {
-  fstring base_directory;
-  char *pname = argv[0];
-  int port = SMB_PORT;
-  int opt;
-  extern FILE *dbf;
-  extern char *optarg;
-  extern int optind;
-  pstring query_host;
-  BOOL message = False;
-  BOOL explicit_user = False;
-  extern char tar_type;
-  static pstring servicesf = CONFIGFILE;
-  pstring term_code;
-  pstring new_name_resolve_order;
-  char *p;
+       fstring base_directory;
+       char *pname = argv[0];
+       int port = SMB_PORT;
+       int opt;
+       extern FILE *dbf;
+       extern char *optarg;
+       extern int optind;
+       pstring query_host;
+       BOOL message = 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
-  pstrcpy(term_code, KANJI);
+       pstrcpy(term_code, KANJI);
 #else /* KANJI */
-  *term_code = 0;
+       *term_code = 0;
 #endif /* KANJI */
 
-  *query_host = 0;
-  *base_directory = 0;
+       *query_host = 0;
+       *base_directory = 0;
 
-  *new_name_resolve_order = 0;
+       *new_name_resolve_order = 0;
 
-  DEBUGLEVEL = 2;
+       DEBUGLEVEL = 2;
 
-  setup_logging(pname,True);
+       setup_logging(pname,True);
 
-  TimeInit();
-  charset_initialise();
+       TimeInit();
+       charset_initialise();
 
-  if(!get_myname(myhostname,NULL))
-  {
-    DEBUG(0,("Failed to get my hostname.\n"));
-  }
-
-  in_client = True;   /* Make sure that we tell lp_load we are */
+       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);
-  }
+       in_client = True;   /* Make sure that we tell lp_load we are */
 
-  codepage_initialise(lp_client_code_page());
+       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);
+       interpret_coding_system(term_code);
 
 #ifdef WITH_SSL
-  sslutil_init(0);
+       sslutil_init(0);
 #endif
 
-  pstrcpy(workgroup,lp_workgroup());
-
-  load_interfaces();
-  pid = (uint16)getpid();
-  vuid = (uint16)getuid();
-  mid = pid + 100;
-  myumask = umask(0);
-  umask(myumask);
-
-  if (getenv("USER"))
-  {
-    pstrcpy(username,getenv("USER"));
-
-    /* modification to support userid%passwd syntax in the USER var
-       25.Aug.97, jdblair@uab.edu */
-
-    if ((p=strchr(username,'%')))
-    {
-      *p = 0;
-      pstrcpy(password,p+1);
-      got_pass = True;
-      memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
-    }
-    strupper(username);
-  }
-
- /* modification to support PASSWD environmental var
-  25.Aug.97, jdblair@uab.edu */
-
-  if (getenv("PASSWD")) {
-    pstrcpy(password,getenv("PASSWD"));
-    got_pass = True;
-  }
-
-  if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) {
-    int fd = -1;
-    BOOL close_it = False;
-    pstring spec;
-    char pass[128];
-
-    if ((p = getenv("PASSWD_FD")) != NULL) {
-      pstrcpy(spec, "descriptor ");
-      pstrcat(spec, p);
-      sscanf(p, "%d", &fd);
-      close_it = False;
-    } else if ((p = getenv("PASSWD_FILE")) != NULL) {
-      fd = open(p, O_RDONLY);
-      pstrcpy(spec, p);
-      if (fd < 0) {
-       fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n",
-               spec, strerror(errno));
-       exit(1);
-      }
-      close_it = True;
-    }
-    for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */
-       p && p - pass < sizeof(pass);) {
-      switch (read(fd, p, 1)) {
-      case 1:
-       if (*p != '\n' && *p != '\0') {
-         *++p = '\0'; /* advance p, and null-terminate pass */
-         break;
-       }
-      case 0:
-       if (p - pass) {
-         *p = '\0'; /* null-terminate it, just in case... */
-         p = NULL; /* then force the loop condition to become false */
-         break;
-       } else {
-         fprintf(stderr, "Error reading password from file %s: %s\n",
-                 spec, "empty password\n");
-         exit(1);
-       }
+       pstrcpy(workgroup,lp_workgroup());
 
-      default:
-       fprintf(stderr, "Error reading password from file %s: %s\n",
-               spec, strerror(errno));
-       exit(1);
-      }
-    }
-    pstrcpy(password, pass);
-    got_pass = True;
-    if (close_it)
-      close(fd);
-  }
-
-  if (*username == 0 && getenv("LOGNAME"))
-    {
-      pstrcpy(username,getenv("LOGNAME"));
-      strupper(username);
-    }
-
-  if (*username == 0)
-    {
-      pstrcpy(username,"GUEST");
-    }
-
-  if (argc < 2)
-    {
-      usage(pname);
-      exit(1);
-    }
-  
-  if (*argv[1] != '-')
-    {
+       load_interfaces();
+       myumask = umask(0);
+       umask(myumask);
 
-      pstrcpy(service,argv[1]);  
-      /* Convert any '/' characters in the service name to '\' characters */
-      string_replace( service, '/','\\');
-      argc--;
-      argv++;
+       if (getenv("USER")) {
+               pstrcpy(username,getenv("USER"));
 
-      if (count_chars(service,'\\') < 3)
-       {
-         usage(pname);
-         printf("\n%s: Not enough '\\' characters in service\n",service);
-         exit(1);
-       }
+               /* modification to support userid%passwd syntax in the USER var
+                  25.Aug.97, jdblair@uab.edu */
 
-/*
-      if (count_chars(service,'\\') > 3)
-       {
-         usage(pname);
-         printf("\n%s: Too many '\\' characters in service\n",service);
-         exit(1);
+               if ((p=strchr(username,'%'))) {
+                       *p = 0;
+                       pstrcpy(password,p+1);
+                       got_pass = True;
+                       memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
+               }
+               strupper(username);
        }
-       */
 
-      if (argc > 1 && (*argv[1] != '-'))
-       {
-         got_pass = True;
-         pstrcpy(password,argv[1]);  
-         memset(argv[1],'X',strlen(argv[1]));
-         argc--;
-         argv++;
+       /* modification to support PASSWD environmental var
+          25.Aug.97, jdblair@uab.edu */
+       if (getenv("PASSWD")) {
+               pstrcpy(password,getenv("PASSWD"));
+               got_pass = True;
        }
-    }
 
-  while ((opt = 
-         getopt(argc, argv,"s:B:O:R:M:i:Nn:d:Pp:l:hI:EU:L:t:m:W:T:D:c:")) != EOF)
-       switch (opt)
-       {
-       case 's':
-               pstrcpy(servicesf, optarg);
-               break;
-       case 'B':
-               iface_set_default(NULL,optarg,NULL);
-               break;
-       case 'O':
-               pstrcpy(user_socket_options,optarg);
-               break;  
-       case 'R':
-               pstrcpy(new_name_resolve_order, optarg);
-               break;
-       case 'M':
-               name_type = 0x03; /* messages are sent to NetBIOS name type 0x3 */
-               pstrcpy(desthost,optarg);
-               strupper(desthost);
-               message = True;
-               break;
-#if 0 /* This option doesn't seem to do anything - JRA. */
-       case 'S':
-               pstrcpy(desthost,optarg);
-               strupper(desthost);
-               nt_domain_logon = True;
-               break;
-#endif /* 0 */
-       case 'i':
-               pstrcpy(scope,optarg);
-               break;
-       case 'N':
+       if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) {
+               get_password_file();
                got_pass = True;
-               no_pass = True;
-               break;
-       case 'n':
-               pstrcpy(global_myname,optarg);
-               break;
-       case 'd':
-               if (*optarg == 'A')
-                       DEBUGLEVEL = 10000;
-               else
-                       DEBUGLEVEL = atoi(optarg);
-               break;
-       case 'P':
-               connect_as_printer = True;
-               break;
-       case 'p':
-               port = atoi(optarg);
-               break;
-       case 'l':
-               slprintf(debugf,sizeof(debugf)-1, "%s.client",optarg);
-               break;
-       case 'h':
+       }
+
+       if (*username == 0 && getenv("LOGNAME")) {
+               pstrcpy(username,getenv("LOGNAME"));
+               strupper(username);
+       }
+
+       if (*username == 0) {
+               pstrcpy(username,"GUEST");
+       }
+
+       if (argc < 2) {
                usage(pname);
-               exit(0);
-               break;
-       case 'I':
-               {
-                       dest_ip = *interpret_addr2(optarg);
-                       if (zero_ip(dest_ip))
-                               exit(1);
-                       have_ip = True;
+               exit(1);
+       }
+  
+       if (*argv[1] != '-') {
+               pstrcpy(service,argv[1]);  
+               /* Convert any '/' characters in the service name to '\' characters */
+               string_replace( service, '/','\\');
+               argc--;
+               argv++;
+               
+               if (count_chars(service,'\\') < 3) {
+                       usage(pname);
+                       printf("\n%s: Not enough '\\' characters in service\n",service);
+                       exit(1);
                }
-               break;
-       case 'E':
-               dbf = stderr;
-               break;
-       case 'U':
-               {
-                       char *lp;
-                       explicit_user = True;
-                       pstrcpy(username,optarg);
-                       if ((lp=strchr(username,'%')))
+
+               if (argc > 1 && (*argv[1] != '-')) {
+                       got_pass = True;
+                       pstrcpy(password,argv[1]);  
+                       memset(argv[1],'X',strlen(argv[1]));
+                       argc--;
+                       argv++;
+               }
+       }
+
+       while ((opt = 
+               getopt(argc, argv,"s:B:O:R:M:i:Nn:d:Pp:l:hI:EU:L:t:m:W:T:D:c:")) != EOF) {
+               switch (opt) {
+               case 's':
+                       pstrcpy(servicesf, optarg);
+                       break;
+               case 'B':
+                       iface_set_default(NULL,optarg,NULL);
+                       break;
+               case 'O':
+                       pstrcpy(user_socket_options,optarg);
+                       break;  
+               case 'R':
+                       pstrcpy(new_name_resolve_order, optarg);
+                       break;
+               case 'M':
+                       name_type = 0x03; /* messages are sent to NetBIOS name type 0x3 */
+                       pstrcpy(desthost,optarg);
+                       strupper(desthost);
+                       message = True;
+                       break;
+               case 'i':
+                       pstrcpy(scope,optarg);
+                       break;
+               case 'N':
+                       got_pass = True;
+                       no_pass = True;
+                       break;
+               case 'n':
+                       pstrcpy(global_myname,optarg);
+                       break;
+               case 'd':
+                       if (*optarg == 'A')
+                               DEBUGLEVEL = 10000;
+                       else
+                               DEBUGLEVEL = atoi(optarg);
+                       break;
+               case 'P':
+                       /* not needed anymore */
+                       break;
+               case 'p':
+                       port = atoi(optarg);
+                       break;
+               case 'l':
+                       slprintf(debugf,sizeof(debugf)-1, "%s.client",optarg);
+                       break;
+               case 'h':
+                       usage(pname);
+                       exit(0);
+                       break;
+               case 'I':
                        {
-                               *lp = 0;
-                               pstrcpy(password,lp+1);
-                               got_pass = True;
-                               memset(strchr(optarg,'%')+1,'X',strlen(password));
+                               dest_ip = *interpret_addr2(optarg);
+                               if (zero_ip(dest_ip))
+                                       exit(1);
+                               have_ip = True;
                        }
-               }
-               break;
-       case 'L':
-               got_pass = True;
-               pstrcpy(query_host,optarg);
-               if(!explicit_user)
-                       *username = '\0';
-               break;
-       case 't':
-               pstrcpy(term_code, optarg);
-               break;
-       case 'm':
-               max_protocol = interpret_protocol(optarg,max_protocol);
-               break;
-       case 'W':
-               pstrcpy(workgroup,optarg);
-               break;
-       case 'T':
-               if (!tar_parseargs(argc, argv, optarg, optind)) {
+                       break;
+               case 'E':
+                       dbf = stderr;
+                       break;
+               case 'U':
+                       {
+                               char *lp;
+                               explicit_user = True;
+                               pstrcpy(username,optarg);
+                               if ((lp=strchr(username,'%'))) {
+                                       *lp = 0;
+                                       pstrcpy(password,lp+1);
+                                       got_pass = True;
+                                       memset(strchr(optarg,'%')+1,'X',strlen(password));
+                               }
+                       }
+                       break;
+               case 'L':
+                       got_pass = True;
+                       pstrcpy(query_host,optarg);
+                       if(!explicit_user)
+                               *username = '\0';
+                       break;
+               case 't':
+                       pstrcpy(term_code, optarg);
+                       break;
+               case 'm':
+                       /* no longer supported */
+                       break;
+               case 'W':
+                       pstrcpy(workgroup,optarg);
+                       break;
+               case 'T':
+                       if (!tar_parseargs(argc, argv, optarg, optind)) {
+                               usage(pname);
+                               exit(1);
+                       }
+                       break;
+               case 'D':
+                       pstrcpy(base_directory,optarg);
+                       break;
+               case 'c':
+                       cmdstr = optarg;
+                       got_pass = True;
+                       break;
+               default:
                        usage(pname);
                        exit(1);
                }
-               break;
-       case 'D':
-               pstrcpy(base_directory,optarg);
-               break;
-       case 'c':
-               cmdstr = optarg;
-               got_pass = True;
-               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);
-      exit(1);
-    }
-
-#ifdef HAVE_LIBREADLINE
-
-  /* Initialise GNU Readline */
-  
-  rl_readline_name = "smbclient";
-  rl_attempted_completion_function = completion_fn;
-  rl_completion_entry_function = (Function *)complete_cmd_null;
-
-  /* Initialise history list */
+       get_myname((*global_myname)?NULL:global_myname,NULL);  
+       strupper(global_myname);
 
-  using_history();
+       if(*new_name_resolve_order)
+               lp_set_name_resolve_order(new_name_resolve_order);
 
-#endif /* HAVE_LIBREADLINE */
-
-  DEBUG( 3, ( "Client started (version %s).\n", VERSION ) );
-
-  if (tar_type) {
-    recurse=True;
-
-    if (cli_open_sockets(port)) {
-        char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-       char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-       int ret;
-
-       if ((InBuffer == NULL) || (OutBuffer == NULL)) 
-         return(1);
-
-       bzero(OutBuffer,smb_size);
-       if (!cli_send_login(InBuffer,OutBuffer,True,True,NULL))
-         return(False);
+       if (!tar_type && !*query_host && !*service && !message) {
+               usage(pname);
+               exit(1);
+       }
 
-       if (*base_directory) do_cd(base_directory);
+       DEBUG( 3, ( "Client started (version %s).\n", VERSION ) );
 
-       ret=process_tar(InBuffer, OutBuffer);
+       if (tar_type) {
+               return do_tar_op(port, base_directory);
+       }
 
-       cli_send_logout(InBuffer, OutBuffer);
-       close_sockets();
-       return(ret);
-    } else
-      return(1);
-  }
-
-  if ((p=strchr(query_host,'#'))) {
-         *p = 0;
-         p++;
-         sscanf(p, "%x", &name_type);
-  }
+       if ((p=strchr(query_host,'#'))) {
+               *p = 0;
+               p++;
+               sscanf(p, "%x", &name_type);
+       }
   
-#if 0 /* This seemed to be used with the unknown -S option. JRA */
-  if (*query_host && !nt_domain_logon)
-#else
-  if (*query_host)
-#endif
-    {
-      int ret = 0;
-      slprintf(service,sizeof(service)-1,
-              "\\\\%s\\IPC$",query_host);
-      strupper(service);
-      connect_as_ipc = True;
-      if (cli_open_sockets(port))
-       {
-#if 0
-         *username = 0;
-#endif
-         if (!cli_send_login(NULL,NULL,True,True,NULL))
-           return(1);
-
-         server_info();
-         if (!browse_host(True)) {
-           sleep(1);
-           browse_host(True);
-         }
-         if (!list_servers(workgroup)) {
-           sleep(1);
-           list_servers(workgroup);
-         }
-
-         cli_send_logout(NULL,NULL);
-         close_sockets();
+       if (*query_host) {
+               return do_host_query(query_host, port);
        }
 
-      return(ret);
-    }
-
-  if (message)
-    {
-      int ret = 0;
-      if (cli_open_sockets(port))
-       {
-         pstring inbuf,outbuf;
-         bzero(outbuf,smb_size);
-         if (!cli_send_session_request(inbuf,outbuf))
-           return(1);
-
-         send_message(inbuf,outbuf);
-
-         close_sockets();
+       if (message) {
+               return do_message_op();
        }
 
-      return(ret);
-    }
-
-  if (cli_open_sockets(port))
-    {
-      if (!process(base_directory))
-       {
-         close_sockets();
-         return(1);
+       if (!process(base_directory)) {
+               close_sockets();
+               return(1);
        }
-      close_sockets();
-    }
-  else
-    return(1);
+       close_sockets();
 
-  return(0);
+       return(0);
 }
index e9b79baa71bccac448bea161bce14c71702124ef..8ebe9dc853ca4813dc334e7fcbd197fc4867d260 100644 (file)
@@ -68,11 +68,9 @@ typedef struct
 
 stack dir_stack = {NULL, 0}; /* Want an empty stack */
 
-extern BOOL recurse;
-
 #define SEPARATORS " \t\n\r"
 extern int DEBUGLEVEL;
-extern int Client;
+extern struct cli_state *cli;
 
 /* These defines are for the do_setrattr routine, to indicate
  * setting and reseting of file attributes in the function call */
@@ -136,7 +134,6 @@ static int dotarbuf(int f, char *b, int n);
 static void dozerobuf(int f, int n);
 static void dotareof(int f);
 static void initarbuf(void);
-static int do_setrattr(char *fname, int attr, int setit);
 
 /* restore functions */
 static long readtarheader(union hblock *hb, file_info2 *finfo, char *prefix);
@@ -148,54 +145,6 @@ static void unfixtarname(char *tptr, char *fp, int l, BOOL first);
  * tar specific utitlities
  */
 
-#if 0 /* Removed to get around gcc 'defined but not used' error. */
-
-/*
- * Stack routines, push_dir, pop_dir, top_dir_name
- */
-
-static BOOL push_dir(stack *tar_dir_stack, file_info2 *dir)
-{
-  dir -> next = tar_dir_stack -> top;
-  dir -> prev = NULL;
-  tar_dir_stack -> items++;
-  tar_dir_stack -> top = dir;
-  return(True);
-
-}
-
-static file_info2 *pop_dir(stack *tar_dir_stack)
-{
-  file_info2 *ptr;
-  
-  ptr = tar_dir_stack -> top;
-  if (tar_dir_stack -> top != NULL) {
-
-    tar_dir_stack -> top = tar_dir_stack -> top -> next;
-    tar_dir_stack -> items--;
-
-  }
-
-  return ptr;
-
-}
-
-static char *top_dir_name(stack *tar_dir_stack)
-{
-
-  return(tar_dir_stack -> top != NULL?tar_dir_stack -> top -> name:NULL);
-
-}
-
-static BOOL sub_dir(char *dir1, char *dir2)
-{
-
-  return(True);
-
-}
-
-#endif /* Removed to get around gcc 'defined but not used' error. */
-
 /*******************************************************************
 Create  a string of size size+1 (for the null)
 *******************************************************************/
@@ -570,362 +519,11 @@ static int strslashcmp(char *s1, char *s2)
   return *s1-*s2;
 }
 
-/*
- * general smb utility functions
- */
-/**********************************************************************
-do_setrtime, set time on a file or dir ...
-**********************************************************************/
-
-static int do_setrtime(char *fname, int mtime, BOOL err_silent)
-{
-  char *inbuf, *outbuf, *p;
-  char *name;
-
-  DEBUG(5, ("Setting time on: %s, fnlen=%i.\n", fname, strlen(fname)));
-
-  name = (char *)malloc(strlen(fname) + 1 + 1);
-  if (name == NULL) {
-
-     DEBUG(0, ("Failed to allocate space while setting time on file: %s", fname));
-     return False;
-
-  }
-
-  if (*fname != '\\')
-    safe_strcpy(name, "\\", strlen(fname) + 1);
-  else
-    safe_strcpy(name, "", strlen(fname) + 1);
-  safe_strcat(name, fname, strlen(fname) + 1);
-
-  if (fname[strlen(name) - 1] == '\\')
-    name[strlen(name) - 1] = '\0';
-
-  inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
-  if (!inbuf || !outbuf) {
-
-    DEBUG(0, ("Could not allocate memory for inbuf or outbuf while changing time on: %s\n", fname));
-    free(name);
-    return False;
-
-  }
-
-  memset(outbuf, 0, smb_size);
-  set_message(outbuf, 8, 4 + strlen(name), True);
-  CVAL(outbuf, smb_com) = SMBsetatr;
-  SSVAL(outbuf, smb_tid, cnum);
-  cli_setup_pkt(outbuf);
-
-  SSVAL(outbuf, smb_vwv0, 0);
-  put_dos_date3(outbuf, smb_vwv1, mtime);
-
-  p = smb_buf(outbuf);
-  *p++ = 4;
-  safe_strcpy(p, name, strlen(name));
-  p+= (strlen(fname)+1);
-
-  *p++ = 4;
-  *p++ = 0;
-
-  send_smb(Client, outbuf);
-  client_receive_smb(Client, inbuf, CLIENT_TIMEOUT);
-
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      if (!err_silent) {
-       DEBUG(0,("%s setting attributes on file %s\n",
-                smb_errstr(inbuf), fname));
-      }
-      free(name);free(inbuf);free(outbuf);
-      return(False);
-    }
-
-  free(name);
-  free(inbuf);free(outbuf);
-  return(True);
-
-}
-
-/****************************************************************************
-Set DOS file attributes
-***************************************************************************/
-static int do_setrattr(char *fname, int attr, int setit)
-{
-  /*
-   * First get the existing attribs from existing file
-   */
-  char *inbuf,*outbuf;
-  char *p;
-  char *name;
-  int fattr;
-
-  name = (char *)malloc(strlen(fname) + 1 + 1);
-  if (name == NULL) {
-
-     DEBUG(0, ("Failed to allocate space in do_setrattr while setting time on file: %s", fname));
-     return False;
-
-  }
-
-  safe_strcpy(name, "\\", strlen(fname) + 1);
-  safe_strcat(name, fname, strlen(fname) + 1);
-
-  inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
-  if (!inbuf || !outbuf)
-    {
-      DEBUG(0,("out of memory\n"));
-      free(name);
-      return False;
-    }
-
-  /* send an smb getatr message */
-
-  memset(outbuf,0,smb_size);
-  set_message(outbuf,0,2 + strlen(fname),True);
-  CVAL(outbuf,smb_com) = SMBgetatr;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-
-  p = smb_buf(outbuf);
-  *p++ = 4;
-  safe_strcpy(p,name, strlen(name));
-  p += (strlen(name)+1);
-  
-  *p++ = 4;
-  *p++ = 0;
-
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
-  if (CVAL(inbuf,smb_rcls) != 0)
-    DEBUG(5,("getatr: %s\n",smb_errstr(inbuf)));
-  else
-    {
-      DEBUG(5,("\nattr 0x%X  time %d  size %d\n",
-              (int)CVAL(inbuf,smb_vwv0),
-              SVAL(inbuf,smb_vwv1),
-              SVAL(inbuf,smb_vwv3)));
-    }
-
-  fattr=CVAL(inbuf,smb_vwv0);
-
-  /* combine found attributes with bits to be set or reset */
-
-  attr=setit ? (fattr | attr) : (fattr & ~attr);
-
-  /* now try and set attributes by sending smb reset message */
-
-  /* clear out buffer and start again */
-  memset(outbuf,0,smb_size);
-  set_message(outbuf,8,4 + strlen(name),True);
-  CVAL(outbuf,smb_com) = SMBsetatr;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-
-  SSVAL(outbuf,smb_vwv0,attr);
-  
-  p = smb_buf(outbuf);
-  *p++ = 4;      
-  safe_strcpy(p,name, strlen(name));
-  p += (strlen(name)+1);
-  
-  *p++ = 4;
-  *p++ = 0;
-
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-  
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      DEBUG(0,("%s setting attributes on file %s\n",
-           smb_errstr(inbuf), name));
-      free(name);free(inbuf);free(outbuf);
-      return(False);
-    }
-
-  free(name);
-  free(inbuf);free(outbuf);
-  return(True);
-}
-
-/****************************************************************************
-Create a file on a share
-***************************************************************************/
-static BOOL smbcreat(file_info2 finfo, int *fnum, char *inbuf, char *outbuf)
-{
-  char *p;
-  /* *must* be called with buffer ready malloc'ed */
-  /* open remote file */
-
-  memset(outbuf,0,smb_size);
-  set_message(outbuf,3,2 + strlen(finfo.name),True);
-  CVAL(outbuf,smb_com) = SMBcreate;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-  
-  SSVAL(outbuf,smb_vwv0,finfo.mode);
-  put_dos_date3(outbuf,smb_vwv1,finfo.mtime);
-  
-  p = smb_buf(outbuf);
-  *p++ = 4;      
-  safe_strcpy(p,finfo.name, strlen(finfo.name));
-  
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-  
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      DEBUG(0,("%s opening remote file %s\n",smb_errstr(inbuf),
-              finfo.name));
-      return 0;
-    }
-  
-  *fnum = SVAL(inbuf,smb_vwv0);
-  return True;
-}
-
-/****************************************************************************
-Write a file to a share
-***************************************************************************/
-static BOOL smbwrite(int fnum, int n, int low, int high, int left,
-                    char *bufferp, char *inbuf, char *outbuf)
-{
-  /* *must* be called with buffer ready malloc'ed */
-
-  memset(outbuf,0,smb_size);
-  set_message(outbuf,5,n + 3,True);
-  
-  memcpy(smb_buf(outbuf)+3, bufferp, n);
-  
-  set_message(outbuf,5,n + 3, False);
-  CVAL(outbuf,smb_com) = SMBwrite;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-  
-  SSVAL(outbuf,smb_vwv0,fnum);
-  SSVAL(outbuf,smb_vwv1,n);
-  SIVAL(outbuf,smb_vwv2,low);
-  SSVAL(outbuf,smb_vwv4,left);
-  CVAL(smb_buf(outbuf),0) = 1;
-  SSVAL(smb_buf(outbuf),1,n);
-
-  send_smb(Client,outbuf); 
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-  
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      DEBUG(0,("%s writing remote file\n",smb_errstr(inbuf)));
-      return False;
-    }
-  
-  if (n != SVAL(inbuf,smb_vwv0))
-    {
-      DEBUG(0,("Error: only wrote %d bytes out of %d\n",
-              SVAL(inbuf,smb_vwv0), n));
-      return False;
-    }
-
-  return True;
-}
-
-/****************************************************************************
-Close a file on a share
-***************************************************************************/
-static BOOL smbshut(file_info2 finfo, int fnum, char *inbuf, char *outbuf)
-{
-  /* *must* be called with buffer ready malloc'ed */
-
-  memset(outbuf,0,smb_size);
-  set_message(outbuf,3,0,True);
-  CVAL(outbuf,smb_com) = SMBclose;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-  
-  SSVAL(outbuf,smb_vwv0,fnum);
-  put_dos_date3(outbuf,smb_vwv1,finfo.mtime);
-  
-  DEBUG(3,("Setting date to %s (0x%lX)",
-          asctime(LocalTime(&finfo.mtime)),
-          finfo.mtime));
-  
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-  
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      DEBUG(0,("%s closing remote file %s\n",smb_errstr(inbuf),
-              finfo.name));
-      return False;
-    }
-
-  return True;
-}
-
-/****************************************************************************
-Verify existence of path on share
-***************************************************************************/
-static BOOL smbchkpath(char *fname, char *inbuf, char *outbuf)
-{
-  char *p;
-
-  memset(outbuf,0,smb_size);
-  set_message(outbuf,0,4 + strlen(fname),True);
-  CVAL(outbuf,smb_com) = SMBchkpth;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-
-  p = smb_buf(outbuf);
-  *p++ = 4;
-  safe_strcpy(p,fname, strlen(fname));
-
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
-  DEBUG(5,("smbchkpath: %s\n",smb_errstr(inbuf)));
-
-  return(CVAL(inbuf,smb_rcls) == 0);
-}
-
-/****************************************************************************
-Make a directory on share
-***************************************************************************/
-static BOOL smbmkdir(char *fname, char *inbuf, char *outbuf)
-{
-  /* *must* be called with buffer ready malloc'ed */
-  char *p;
-
-  memset(outbuf,0,smb_size);
-  set_message(outbuf,0,2 + strlen(fname),True);
-  
-  CVAL(outbuf,smb_com) = SMBmkdir;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-  
-  p = smb_buf(outbuf);
-  *p++ = 4;      
-  safe_strcpy(p,fname, strlen(fname));
-  
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-  
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      DEBUG(0,("%s making remote directory %s\n",
-              smb_errstr(inbuf),fname));
-      return(False);
-    }
-
-  return(True);
-}
 
 /****************************************************************************
 Ensure a remote path exists (make if necessary)
 ***************************************************************************/
-static BOOL ensurepath(char *fname, char *inbuf, char *outbuf)
+static BOOL ensurepath(char *fname)
 {
   /* *must* be called with buffer ready malloc'ed */
   /* ensures path exists */
@@ -963,8 +561,8 @@ static BOOL ensurepath(char *fname, char *inbuf, char *outbuf)
     {
       safe_strcat(partpath, p, strlen(fname) + 1);
 
-      if (!smbchkpath(partpath, inbuf, outbuf)) {
-       if (!smbmkdir(partpath, inbuf, outbuf))
+      if (!cli_chkpath(cli, partpath)) {
+       if (!cli_mkdir(cli, partpath))
          {
            DEBUG(0, ("Error mkdirhiering\n"));
            return False;
@@ -983,23 +581,40 @@ static BOOL ensurepath(char *fname, char *inbuf, char *outbuf)
 
 static int padit(char *buf, int bufsize, int padsize)
 {
-  int berr= 0;
-  int bytestowrite;
+       int berr= 0;
+       int bytestowrite;
   
-  DEBUG(5, ("Padding with %d zeros\n", padsize));
-  memset(buf, 0, bufsize);
-  while( !berr && padsize > 0 ) {
-    bytestowrite= MIN(bufsize, padsize);
-    berr = dotarbuf(tarhandle, buf, bytestowrite) != bytestowrite;
-    padsize -= bytestowrite;
-  }
+       DEBUG(5, ("Padding with %d zeros\n", padsize));
+       memset(buf, 0, bufsize);
+       while( !berr && padsize > 0 ) {
+               bytestowrite= MIN(bufsize, padsize);
+               berr = dotarbuf(tarhandle, buf, bytestowrite) != bytestowrite;
+               padsize -= bytestowrite;
+       }
   
-  return berr;
+       return berr;
 }
 
-/*
- * smbclient functions
- */
+
+static void do_setrattr(char *name, int attr, int set)
+{
+       int oldattr;
+       time_t t;
+
+       if (!cli_getatr(cli, name, &oldattr, NULL, &t)) return;
+
+       if (set == ATTRSET) {
+               attr |= oldattr;
+       } else {
+               attr = oldattr & ~attr;
+       }
+
+       if (!cli_setatr(cli, name, attr, t)) {
+               DEBUG(1,("setatr failed: %s\n", cli_errstr(cli)));
+       }
+}
+
+
 /****************************************************************************
 append one remote file to the tar file
 ***************************************************************************/
@@ -1008,12 +623,11 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
   int fnum;
   uint32 nread=0;
   char *p, ftype;
-  char *inbuf,*outbuf;
   file_info2 finfo;
   BOOL close_done = False;
   BOOL shallitime=True;
-  BOOL ignore_close_error = False;
-  char *dataptr=NULL;
+  char data[65520];
+  int read_size = 65520;
   int datalen=0;
 
   struct timeval tp_start;
@@ -1050,91 +664,34 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
       ntarf++;
       return;
     }
-    
-  inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
-  if (!inbuf || !outbuf)
-    {
-      DEBUG(0,("out of memory\n"));
-      return;
-    }
-
-  memset(outbuf,0,smb_size);
-  set_message(outbuf,15,1 + strlen(rname),True);
-
-  CVAL(outbuf,smb_com) = SMBopenX;
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
 
-  SSVAL(outbuf,smb_vwv0,0xFF);
-  SSVAL(outbuf,smb_vwv2,1);
-  SSVAL(outbuf,smb_vwv3,(DENY_NONE<<4));
-  SSVAL(outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
-  SSVAL(outbuf,smb_vwv5,aSYSTEM | aHIDDEN);
-  SSVAL(outbuf,smb_vwv8,1);
-
-  p = smb_buf(outbuf);
-  safe_strcpy(p, rname, strlen(rname));
-  p = skip_string(p,1);
+  fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
 
   dos_clean_name(rname);
 
-  /* do a chained openX with a readX? */  
-  if (finfo.size > 0)
-    {
-      SSVAL(outbuf,smb_vwv0,SMBreadX);
-      SSVAL(outbuf,smb_vwv1,PTR_DIFF(p,outbuf) - 4);
-      memset(p,0,200);
-      p -= smb_wct;
-      SCVAL(p,smb_wct,10);
-      SSVAL(p,smb_vwv0,0xFF);
-      SSVAL(p,smb_vwv5,MIN(max_xmit-500,finfo.size));
-      SSVAL(p,smb_vwv9,MIN(0xFFFF,finfo.size));
-      smb_setlen(outbuf,smb_len(outbuf)+11*2+1);  
-    }
-  
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
-  if (CVAL(inbuf,smb_rcls) != 0)
-    {
-      if (CVAL(inbuf,smb_rcls) == ERRSRV &&
-         SVAL(inbuf,smb_err) == ERRnoresource &&
-         cli_reopen_connection(inbuf,outbuf))
-       {
-         do_atar(rname,lname,finfo1);
-         free(inbuf);free(outbuf);
+  if (fnum == -1) {
+         DEBUG(0,("%s opening remote file %s (%s)\n",
+                  cli_errstr(cli),rname, cur_dir));
          return;
-       }
-
-      DEBUG(0,("%s opening remote file %s\n",smb_errstr(inbuf),rname));
-      free(inbuf);free(outbuf);
-      return;
-    }
+  }
 
   finfo.name = string_create_s(strlen(rname));
   if (finfo.name == NULL) {
-
-    DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n"));
-    free(inbuf); free(outbuf);
-    return;
-
+         DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n"));
+         return;
   }
 
   safe_strcpy(finfo.name,rname, strlen(rname));
-  if (!finfo1)
-    {
-      finfo.mode = SVAL(inbuf,smb_vwv3);
-      finfo.size = IVAL(inbuf,smb_vwv4);
-      finfo.mtime = make_unix_date3(inbuf+smb_vwv6);
-      finfo.atime = finfo.ctime = finfo.mtime;
-    }
+  if (!finfo1) {
+         if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &finfo.atime, &finfo.mtime)) {
+                 DEBUG(0, ("getattrE: %s\n", cli_errstr(cli)));
+                 return;
+         }
+         finfo.ctime = finfo.mtime;
+  }
 
   DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode));
 
-  fnum = SVAL(inbuf,smb_vwv2);
-
   if (tar_inc && !(finfo.mode & aARCH))
     {
       DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name));
@@ -1152,18 +709,6 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
     }
   else
     {
-      if (SVAL(inbuf,smb_vwv0) == SMBreadX)
-       {
-         p = (inbuf+4+SVAL(inbuf,smb_vwv1)) - smb_wct;
-         datalen = SVAL(p,smb_vwv5);
-         dataptr = inbuf + 4 + SVAL(p,smb_vwv6);
-       }
-      else
-       {
-         dataptr = NULL;
-         datalen = 0;
-       }
-
       DEBUG(3,("getting file %s of size %d bytes as a tar file %s",
               finfo.name,
               finfo.size,
@@ -1171,217 +716,41 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
       
       /* write a tar header, don't bother with mode - just set to 100644 */
       writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype);
-      
-      while (nread < finfo.size && !close_done)
-       {
-         int method = -1;
-         static BOOL can_chain_close=True;
-
-         p=NULL;
-         
-         DEBUG(3,("nread=%d\n",nread));
-         
-         /* 3 possible read types. readbraw if a large block is required.
-            readX + close if not much left and read if neither is supported */
 
-         /* we might have already read some data from a chained readX */
-         if (dataptr && datalen>0)
-           method=3;
-         
-         /* if we can finish now then readX+close */
-         if (method<0 && can_chain_close && (Protocol >= PROTOCOL_LANMAN1) && 
-             ((finfo.size - nread) < 
-              (max_xmit - (2*smb_size + 13*SIZEOFWORD + 300))))
-           method = 0;
-         
-         /* if we support readraw then use that */
-         if (method<0 && readbraw_supported)
-           method = 1;
-         
-         /* if we can then use readX */
-         if (method<0 && (Protocol >= PROTOCOL_LANMAN1))
-           method = 2;
-         
-         
-         switch (method)
-           {
-             /* use readX */
-           case 0:
-           case 2:
-             if (method == 0)
-               close_done = True;
-             
-             /* use readX + close */
-             memset(outbuf,0,smb_size);
-             set_message(outbuf,10,0,True);
-             CVAL(outbuf,smb_com) = SMBreadX;
-             SSVAL(outbuf,smb_tid,cnum);
-             cli_setup_pkt(outbuf);
-             
-             if (close_done)
-               {
-                 CVAL(outbuf,smb_vwv0) = SMBclose;
-                 SSVAL(outbuf,smb_vwv1,PTR_DIFF(smb_buf(outbuf),outbuf) - 4);
-               }
-             else
-               CVAL(outbuf,smb_vwv0) = 0xFF;         
-             
-             
-             SSVAL(outbuf,smb_vwv2,fnum);
-             SIVAL(outbuf,smb_vwv3,nread);
-             SSVAL(outbuf,smb_vwv5,MIN(max_xmit-200,finfo.size - nread));
-             SSVAL(outbuf,smb_vwv6,0);
-             SIVAL(outbuf,smb_vwv7,0);
-             SSVAL(outbuf,smb_vwv9,MIN(0xFFFF,finfo.size-nread));
-             
-             if (close_done)
-               {
-                 p = smb_buf(outbuf);
-                 memset(p,0,9);
-                 
-                 CVAL(p,0) = 3;
-                 SSVAL(p,1,fnum);
-                 SIVALS(p,3,-1);
-                 
-                 /* now set the total packet length */
-                 smb_setlen(outbuf,smb_len(outbuf)+9);
-               }
+      while (nread < finfo.size && !close_done)        {
+             p=NULL;
              
-             send_smb(Client,outbuf);
-             client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+             DEBUG(3,("nread=%d\n",nread));
              
-             if (CVAL(inbuf,smb_rcls) != 0)
-               {
-                 DEBUG(0,("Error %s reading remote file\n",smb_errstr(inbuf)));
-                 break;
-               }
+             datalen = cli_read(cli, fnum, data, nread, read_size);
              
-             if (close_done &&
-                 SVAL(inbuf,smb_vwv0) != SMBclose)
-               {
-                 /* NOTE: WfWg sometimes just ignores the chained
-                    command! This seems to break the spec? */
-                 DEBUG(3,("Rejected chained close?\n"));
-                 close_done = False;
-                 can_chain_close = False;
-                 ignore_close_error = True;
-               }
-             
-             datalen = SVAL(inbuf,smb_vwv5);
-             dataptr = inbuf + 4 + SVAL(inbuf,smb_vwv6);
-             break;
+             if (datalen == -1) {
+                     DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli)));
+                     break;
+             }
              
+             /* add received bits of file to buffer - dotarbuf will
+              * write out in 512 byte intervals */
+             if (dotarbuf(tarhandle,data,datalen) != datalen) {
+                     DEBUG(0,("Error writing to tar file - %s\n", strerror(errno)));
+                     break;
+             }
              
-             /* use readbraw */
-           case 1:
-             {
-               static int readbraw_size = 0xFFFF;
-               
-               extern int Client;
-               memset(outbuf,0,smb_size);
-               set_message(outbuf,8,0,True);
-               CVAL(outbuf,smb_com) = SMBreadbraw;
-               SSVAL(outbuf,smb_tid,cnum);
-               cli_setup_pkt(outbuf);
-               SSVAL(outbuf,smb_vwv0,fnum);
-               SIVAL(outbuf,smb_vwv1,nread);
-               SSVAL(outbuf,smb_vwv3,MIN(finfo.size-nread,readbraw_size));
-               SSVAL(outbuf,smb_vwv4,0);
-               SIVALS(outbuf,smb_vwv5,-1);
-               send_smb(Client,outbuf);
-               
-               /* Now read the raw data into the buffer and write it */          
-               if(read_smb_length(Client,inbuf,0) == -1) {
-                 DEBUG(0,("Failed to read length in readbraw\n"));         
-                 exit(1);
-               }
-               
-               /* Even though this is not an smb message, smb_len
-                  returns the generic length of an smb message */
-               datalen = smb_len(inbuf);
-               
-               if (datalen == 0)
-                 {
-                   /* we got a readbraw error */
-                   DEBUG(4,("readbraw error - reducing size\n"));
-                   readbraw_size = (readbraw_size * 9) / 10;
-                   
-                   if (readbraw_size < max_xmit)
-                     {
-                       DEBUG(0,("disabling readbraw\n"));
-                       readbraw_supported = False;
-                     }
-
-                   dataptr=NULL;
-                   continue;
-                 }
-
-               if(read_data(Client,inbuf,datalen) != datalen) {
-                 DEBUG(0,("Failed to read data in readbraw\n"));
-                 exit(1);
-               }
-               dataptr = inbuf;
+             nread += datalen;
+             if (datalen == 0) {
+                     DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname));
+                     break;
              }
-             break;
 
-           case 3:
-             /* we've already read some data with a chained readX */
-             break;
-             
-           default:
-             /* use plain read */
-             memset(outbuf,0,smb_size);
-             set_message(outbuf,5,0,True);
-             CVAL(outbuf,smb_com) = SMBread;
-             SSVAL(outbuf,smb_tid,cnum);
-             cli_setup_pkt(outbuf);
-             
-             SSVAL(outbuf,smb_vwv0,fnum);
-             SSVAL(outbuf,smb_vwv1,MIN(max_xmit-200,finfo.size - nread));
-             SIVAL(outbuf,smb_vwv2,nread);
-             SSVAL(outbuf,smb_vwv4,finfo.size - nread);
-             
-             send_smb(Client,outbuf);
-             client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-             
-             if (CVAL(inbuf,smb_rcls) != 0)
-               {
-                 DEBUG(0,("Error %s reading remote file\n",smb_errstr(inbuf)));
-                 break;
-               }
-             
-             datalen = SVAL(inbuf,smb_vwv0);
-             dataptr = smb_buf(inbuf) + 3;
-             break;
-           }
-         
-         
-         /* add received bits of file to buffer - dotarbuf will
-          * write out in 512 byte intervals */
-         if (dotarbuf(tarhandle,dataptr,datalen) != datalen)
-           {
-             DEBUG(0,("Error writing to tar file - %s\n", strerror(errno)));
-             break;
-           }
-         
-         nread += datalen;
-         if (datalen == 0) 
-           {
-             DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname));
-             break;
-           }
-
-         dataptr=NULL;
-         datalen=0;
-       }
+             datalen=0;
+      }
 
-       /* pad tar file with zero's if we couldn't get entire file */
-       if (nread < finfo.size)
-        {
-          DEBUG(0, ("Didn't get entire file. size=%d, nread=%d\n", finfo.size, nread));
-          if (padit(inbuf, BUFFER_SIZE, finfo.size - nread))
-              DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
-        }
+      /* pad tar file with zero's if we couldn't get entire file */
+      if (nread < finfo.size) {
+             DEBUG(0, ("Didn't get entire file. size=%d, nread=%d\n", finfo.size, nread));
+             if (padit(data, sizeof(data), finfo.size - nread))
+                     DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
+      }
 
       /* round tar file to nearest block */
       if (finfo.size % TBLOCK)
@@ -1391,27 +760,7 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
       ntarf++;
     }
   
-  if (!close_done)
-    {
-      memset(outbuf,0,smb_size);
-      set_message(outbuf,3,0,True);
-      CVAL(outbuf,smb_com) = SMBclose;
-      SSVAL(outbuf,smb_tid,cnum);
-      cli_setup_pkt(outbuf);
-      
-      SSVAL(outbuf,smb_vwv0,fnum);
-      SIVALS(outbuf,smb_vwv1,-1);
-      
-      send_smb(Client,outbuf);
-      client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-      
-      if (!ignore_close_error && CVAL(inbuf,smb_rcls) != 0)
-       {
-         DEBUG(0,("Error %s closing remote file\n",smb_errstr(inbuf)));
-         free(inbuf);free(outbuf);
-         return;
-       }
-    }
+  cli_close(cli, fnum);
 
   if (shallitime)
     {
@@ -1441,8 +790,6 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
               finfo.size / MAX(0.001, (1.024*this_time)),
               get_total_size / MAX(0.001, (1.024*get_total_time_ms))));
     }
-  
-  free(inbuf);free(outbuf);
 }
 
 /****************************************************************************
@@ -1452,7 +799,7 @@ static void do_tar(file_info *finfo)
 {
   pstring rname;
 
-  if (strequal(finfo->name,".."))
+  if (strequal(finfo->name,"..") || strequal(finfo->name,"."))
     return;
 
   /* Is it on the exclude list ? */
@@ -1484,16 +831,6 @@ static void do_tar(file_info *finfo)
     {
       pstring saved_curdir;
       pstring mtar_mask;
-      char *inbuf,*outbuf;
-
-      inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-      outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
-      if (!inbuf || !outbuf)
-       {
-         DEBUG(0,("out of memory\n"));
-         return;
-       }
 
       safe_strcpy(saved_curdir, cur_dir, sizeof(saved_curdir));
 
@@ -1508,16 +845,13 @@ static void do_tar(file_info *finfo)
        * 40755 */
       writetarheader(tarhandle, cur_dir, 0, finfo->mtime, "040755 \0", '5');
       if (tar_noisy) {
-
-          DEBUG(0, ("                directory %s\n", cur_dir));
-
+          DEBUG(0,("                directory %s\n", cur_dir));
       }
       ntarf++;  /* Make sure we have a file on there */
       safe_strcpy(mtar_mask,cur_dir, sizeof(pstring));
-      safe_strcat(mtar_mask,"*", sizeof(pstring));
-      /*      do_dir((char *)inbuf,(char *)outbuf,mtar_mask,attribute,do_tar,recurse,True); */
+      safe_strcat(mtar_mask,"*.*", sizeof(pstring));
+      do_list(mtar_mask, attribute, do_tar, False, True);
       safe_strcpy(cur_dir,saved_curdir, sizeof(pstring));
-      free(inbuf);free(outbuf);
     }
   else
     {
@@ -1571,7 +905,6 @@ static void unfixtarname(char *tptr, char *fp, int l, BOOL first)
   }
 }
 
-#ifndef OLD_DOTARPUT 
 
 /****************************************************************************
 Move to the next block in the buffer, which may mean read in another set of
@@ -1635,15 +968,15 @@ static int skip_file(int skipsize)
 }
 
 /* We get a file from the tar file and store it */
-static int get_file(file_info2 finfo, char * inbuf, char * outbuf)
+static int get_file(file_info2 finfo)
 {
   int fsize = finfo.size;
   int fnum, pos = 0, dsize = 0, rsize = 0, bpos = 0;
 
   DEBUG(5, ("get_file: file: %s, size %i\n", finfo.name, fsize));
 
-  if (ensurepath(finfo.name, inbuf, outbuf) &&
-      !smbcreat(finfo, &fnum, inbuf, outbuf))
+  if (ensurepath(finfo.name) && 
+      (fnum=cli_open(cli, finfo.name, O_WRONLY|O_CREAT|O_TRUNC, DENY_NONE)) == -1)
     {
       DEBUG(0, ("abandoning restore\n"));
       return(False);
@@ -1657,15 +990,13 @@ static int get_file(file_info2 finfo, char * inbuf, char * outbuf)
 
     /* We can only write up to the end of the buffer */
 
-    dsize = MIN(tbufsiz - (buffer_p - tarbuf) - bpos, max_xmit - 50); /* Calculate the size to write */
+    dsize = MIN(tbufsiz - (buffer_p - tarbuf) - bpos, 65520); /* Calculate the size to write */
     dsize = MIN(dsize, rsize);  /* Should be only what is left */
-    DEBUG(5, ("writing %i bytes, max_xmit = %i, bpos = %i ...\n", dsize, max_xmit, bpos));
-
-    if (!smbwrite(fnum, dsize, pos, 0, fsize - pos, buffer_p + bpos, inbuf, outbuf)) {
-
-      DEBUG(0, ("Error writing remote file\n"));
-      return 0;
+    DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize, bpos));
 
+    if (cli_write(cli, fnum, 0, buffer_p + bpos, pos, dsize) != dsize) {
+           DEBUG(0, ("Error writing remote file\n"));
+           return 0;
     }
 
     rsize -= dsize;
@@ -1710,23 +1041,20 @@ static int get_file(file_info2 finfo, char * inbuf, char * outbuf)
 
   /* Now close the file ... */
 
-  if (!smbshut(finfo, fnum, inbuf, outbuf)) {
-
-    DEBUG(0, ("Error closing remote file\n"));
-    return(False);
-
+  if (!cli_close(cli, fnum)) {
+         DEBUG(0, ("Error closing remote file\n"));
+         return(False);
   }
 
   /* Now we update the creation date ... */
 
   DEBUG(5, ("Updating creation date on %s\n", finfo.name));
 
-  if (!do_setrtime(finfo.name, finfo.mtime, True)) {
-
-    if (tar_real_noisy) {
-      DEBUG(0, ("Could not set time on file: %s\n", finfo.name));
-      /*return(False); */ /* Ignore, as Win95 does not allow changes */
-    }
+  if (!cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime)) {
+         if (tar_real_noisy) {
+                 DEBUG(0, ("Could not set time on file: %s\n", finfo.name));
+                 /*return(False); */ /* Ignore, as Win95 does not allow changes */
+         }
   }
 
   ntarf++;
@@ -1734,18 +1062,17 @@ static int get_file(file_info2 finfo, char * inbuf, char * outbuf)
   DEBUG(0, ("restore tar file %s of size %d bytes\n", finfo.name, finfo.size));
   
   return(True);
-
 }
 
 /* Create a directory.  We just ensure that the path exists and return as there
    is no file associated with a directory 
 */
-static int get_dir(file_info2 finfo, char * inbuf, char * outbuf)
+static int get_dir(file_info2 finfo)
 {
 
   DEBUG(5, ("Creating directory: %s\n", finfo.name));
 
-  if (!ensurepath(finfo.name, inbuf, outbuf)) {
+  if (!ensurepath(finfo.name)) {
 
     DEBUG(0, ("Problems creating directory\n"));
     return(False);
@@ -1809,7 +1136,7 @@ static void do_tarput(void)
 {
   file_info2 finfo;
   struct timeval tp_start;
-  char *inbuf, *outbuf, *longfilename = NULL, linkflag;
+  char *longfilename = NULL, linkflag;
   int skip = False;
 
   GetTimeOfDay(&tp_start);
@@ -1818,30 +1145,6 @@ static void do_tarput(void)
 
   buffer_p = tarbuf + tbufsiz;  /* init this to force first read */
 
-#if 0   /* Fix later ... */
-  if (push_dir(&dir_stack, &finfo)) {
-    file_info2 *finfo2;
-
-    finfo2 = pop_dir(&dir_stack);
-    inbuf = top_dir_name(&dir_stack); /* FIXME */
-    if (sub_dir(inbuf, finfo2 -> name)){
-
-      DEBUG(0, (""));
-
-    }
-  }
-#endif
-
-  inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
-  if (!inbuf || !outbuf) {
-
-    DEBUG(0, ("Out of memory during allocate of inbuf and outbuf!\n"));
-    return;
-
-  }
-
   /* Now read through those files ... */
 
   while (True) {
@@ -1866,7 +1169,6 @@ static void do_tarput(void)
           !skip_file(finfo.size)) {
 
        DEBUG(0, ("Short file, bailing out...\n"));
-       free(inbuf); free(outbuf);
        return;
 
       }
@@ -1875,12 +1177,10 @@ static void do_tarput(void)
 
     case -1:
       DEBUG(0, ("abandoning restore, -1 from read tar header\n"));
-      free(inbuf); free(outbuf);
       return;
 
     case 0: /* chksum is zero - looks like an EOF */
       DEBUG(0, ("total of %d tar files restored to share\n", ntarf));
-      free(inbuf); free(outbuf);
       return;        /* Hmmm, bad here ... */
 
     default: 
@@ -1933,12 +1233,9 @@ static void do_tarput(void)
 
       if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
        DEBUG(0, ("Short file, bailing out...\n"));
-       free(inbuf); free(outbuf);
        return;
       }
-      if (!get_file(finfo, inbuf, outbuf)) {
-
-       free(inbuf); free(outbuf);
+      if (!get_file(finfo)) {
        DEBUG(0, ("Abandoning restore\n"));
        return;
 
@@ -1946,8 +1243,7 @@ static void do_tarput(void)
       break;
 
     case '5':
-      if (!get_dir(finfo, inbuf, outbuf)) {
-       free(inbuf); free(outbuf);
+      if (!get_dir(finfo)) {
        DEBUG(0, ("Abandoning restore \n"));
        return;
       }
@@ -1956,7 +1252,6 @@ static void do_tarput(void)
     case 'L':
       longfilename = get_longfilename(finfo);
       if (!longfilename) {
-       free(inbuf); free(outbuf);
        DEBUG(0, ("abandoning restore\n"));
        return;
 
@@ -1975,326 +1270,6 @@ static void do_tarput(void)
 
 }
 
-#else 
-
-static void do_tarput()
-{
-  file_info2 finfo;
-  int nread=0, bufread;
-  char *inbuf,*outbuf, *longname = NULL; 
-  int fsize=0;
-  int fnum;
-  struct timeval tp_start;
-  BOOL tskip=False;       /* We'll take each file as it comes */
-
-  finfo.name = NULL;      /* No name in here ... */
-
-  GetTimeOfDay(&tp_start);
-  
-  inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  
-  if (!inbuf || !outbuf)
-    {
-      DEBUG(0,("out of memory\n"));
-      return;
-    }
-  
-  /*
-   * Must read in tbufsiz dollops
-   */
-
-  /* These should be the only reads in clitar.c */
-  while ((bufread=read(tarhandle, tarbuf, tbufsiz))>0) {
-    char *endofbuffer;
-    int chunk;
-
-    /* Code to handle a short read.
-     * We always need a TBLOCK full of stuff
-     */
-    if (bufread % TBLOCK) {
-      int lchunk=TBLOCK-(bufread % TBLOCK);
-      int lread;
-
-      /* It's a shorty - a short read that is */
-      DEBUG(3, ("Short read, read %d so far (need %d)\n", bufread, lchunk));
-
-      while ((lread=read(tarhandle, tarbuf+bufread, lchunk))>0) {
-       bufread+=lread;
-       if (!(lchunk-=lread)) break;
-      }
-
-      /* If we've reached EOF then that must be a short file */
-      if (lread<=0) break;
-    }
-
-    buffer_p=tarbuf; 
-    endofbuffer=tarbuf+bufread;
-
-    if (tskip) {
-      if (fsize<bufread) {
-       tskip=False;
-       buffer_p+=fsize;
-       fsize=0;
-      } else {
-       if (fsize==bufread) tskip=False;
-       fsize-=bufread;
-       continue;
-      }
-    }
-
-    do {
-      if (!fsize)
-       {
-          int next_header = 1;  /* Want at least one header */
-          while (next_header) 
-            {  
-            if (buffer_p >= endofbuffer) {
-
-              bufread = read(tarhandle, tarbuf, tbufsiz);
-              buffer_p = tarbuf;
-
-            }
-            next_header = 0;    /* Don't want the next one ... */
-
-           if (finfo.name != NULL) { /* Free the space */
-
-             free(finfo.name);
-             finfo.name = NULL;
-
-           }
-           DEBUG(5, ("Tarbuf=%X, buffer=%X, endofbuf=%X\n", 
-                     (int)tarbuf, (int)buffer_p, (int)endofbuffer));
-           switch (readtarheader((union hblock *) buffer_p, &finfo, cur_dir))
-             {
-             case -2:             /* something dodgy but not fatal about this */
-               DEBUG(0, ("skipping %s...\n", finfo.name));
-               buffer_p+=TBLOCK;   /* header - like a link */
-               continue;
-             case -1:
-               DEBUG(0, ("abandoning restore, -1 from readtarheader\n"));
-               free(inbuf); free(outbuf);
-               return;
-             case 0: /* chksum is zero - we assume that one all zero
-                      *header block will do for eof */
-               DEBUG(0,
-                     ("total of %d tar files restored to share\n", ntarf));
-               free(inbuf); free(outbuf);
-               return;
-             default:
-               break;
-             }
-
-            /* If we have a longname left from the last time through, 
-               copy it into finfo.name and free it.
-
-               The size of a pstring is the limiting factor on filenames
-               and directory names now. The total pathname length must be
-               less than sizeof(pstring) - 1, which is currently 1023. */
-
-            if (longname != NULL) {
-
-             free(finfo.name);  /* Free the name in the finfo */
-             finfo.name = string_create_s(strlen(longname) + 2);
-              strncpy(finfo.name, longname, strlen(longname) + 1);
-             DEBUG(5, ("Long name = \"%s\", filename=\"%s\"\n", longname, finfo.name));
-              free(longname);
-              longname = NULL;
-
-            }
-
-            /* Check if a long-link. We do this before the clip checking
-               because clip-checking should clip on real name - RJS */
-
-            if (((union hblock *)buffer_p) -> dbuf.linkflag == 'L') {
-             int file_len, first = 0; char *cp;
-
-              /* Skip this header, but pick up length, get the name and 
-                 fix the name and skip the name. Hmmm, what about end of
-                 buffer??? */
-
-              longname = malloc(finfo.size + strlen(cur_dir) + 1);
-              if (longname == NULL) {
-
-                 DEBUG(0, ("could not allocate buffer of size %d for longname\n",
-                          finfo.size + strlen(cur_dir) + 1)
-                      );
-                 free(inbuf); free(outbuf);
-                 return;
-              }
-
-
-             bzero(longname, finfo.size + strlen(cur_dir) +1);
-
-              buffer_p += TBLOCK;   /* Skip that longlink header */
-
-              /* This needs restructuring ... */
-
-              safe_strcpy(longname, cur_dir, strlen(cur_dir) + 1); 
-             cp = longname + strlen(cur_dir);
-             file_len = finfo.size;
-
-             DEBUG(5, ("longname=%0X, cp=%0X, file_len=%i\n", 
-                       (int)longname, (int)cp, file_len));
-
-             while (file_len > 0) {
-
-               if (buffer_p >= endofbuffer) {
-
-                 bufread = read(tarhandle, tarbuf, tbufsiz);
-
-                 buffer_p = tarbuf;
-
-               }
-
-               unfixtarname(cp, buffer_p, file_len >= TBLOCK?TBLOCK:file_len, first == 0);
-
-               first++;              /* Not the first anymore */
-               cp = cp + strlen(cp); /* Move to end of string */
-               buffer_p += TBLOCK;
-               file_len -= TBLOCK;
-               DEBUG(5, ("cp=%0X, file_len=%i\n", (int)cp, file_len));
-               next_header = 1;  /* Force read of next header */
-
-             }
-            }
-          }
-         tskip=clipn
-           && ((!tar_re_search && clipfind(cliplist, clipn, finfo.name) ^ tar_excl)
-#ifdef HAVE_REGEX_H
-               || (tar_re_search && !regexec(preg, finfo.name, 0, NULL, 0)));
-#else
-               || (tar_re_search && mask_match(finfo.name, cliplist[0], True, False)));
-#endif
-         if (tskip) {
-           buffer_p+=TBLOCK;
-           if (finfo.mode & aDIR)
-             continue;
-           else if ((fsize=finfo.size) % TBLOCK) {
-             fsize+=TBLOCK-(fsize%TBLOCK);
-           }
-           if (fsize<endofbuffer-buffer_p) {
-             buffer_p+=fsize;
-             fsize=0;
-             continue;
-           } else {
-             fsize-=endofbuffer-buffer_p;
-             break;
-           }
-         }
-
-         DEBUG(5, ("do_tarput: File is: %s\n", finfo.name));
-
-         if (finfo.mode & aDIR)
-           {
-
-             DEBUG(5, ("Creating directory: %s\n", finfo.name));
-             DEBUG(0, ("restore tar dir  %s of size %d bytes\n",
-                       finfo.name, finfo.size));
-
-             if (!ensurepath(finfo.name, inbuf, outbuf))
-               {
-                 DEBUG(0, ("abandoning restore, problems ensuring path\n"));
-                 free(inbuf); free(outbuf);
-                 return;
-             }
-             else
-               {
-                 /* Now we update the creation date ... */
-
-                 DEBUG(5, ("Updating creation date on %s\n", finfo.name));
-
-                 if (!do_setrtime(finfo.name, finfo.mtime, True)) {
-
-                   if (tar_real_noisy) {
-                     DEBUG(0, ("Could not set time on file: %s\n", finfo.name));
-                   }
-                    /*return;  - Win 95 does not like setting time on dirs */
-
-                  }
-
-                 ntarf++;
-                 buffer_p+=TBLOCK;
-                 continue;
-               }
-           }
-         
-         fsize=finfo.size;
-
-         if (ensurepath(finfo.name, inbuf, outbuf)
-             && !smbcreat(finfo, &fnum, inbuf, outbuf))
-           {
-             DEBUG(0, ("abandoning restore\n"));
-             free(inbuf);free(outbuf);
-             return;
-           }
-
-         DEBUG(0 ,("restore tar file %s of size %d bytes\n",
-                  finfo.name, finfo.size));
-
-         /*          if (!finfo.size) {
-           if (!smbshut(finfo, fnum, inbuf, outbuf)){
-              DEBUG(0, ("Error closing remote file of length 0: %s\n", finfo.name));
-             free(inbuf);free(outbuf);
-              return;
-            }
-           } */
-
-         nread=0;
-         if ((buffer_p+=TBLOCK) >= endofbuffer) break;   
-       } /* if (!fsize) */
-       
-      /* write out the file in chunk sized chunks - don't
-       * go past end of buffer though */
-      chunk=(fsize-nread < endofbuffer - buffer_p)
-       ? fsize - nread : endofbuffer - buffer_p;
-      
-      while (chunk > 0) {
-       int minichunk=MIN(chunk, max_xmit-200);
-       
-       if (!smbwrite(fnum, /* file descriptor */
-                     minichunk, /* n */
-                     nread, /* offset low */
-                     0, /* offset high - not implemented */
-                     fsize-nread, /* left - only hint to server */
-                     buffer_p,
-                     inbuf,
-                     outbuf))
-         {
-           DEBUG(0, ("Error writing remote file\n"));
-           free(inbuf); free(outbuf);
-           return;
-         }
-       DEBUG(5, ("chunk writing fname=%s fnum=%d nread=%d minichunk=%d chunk=%d size=%d\n", finfo.name, fnum, nread, minichunk, chunk, fsize));
-       
-       buffer_p+=minichunk; nread+=minichunk;
-       chunk-=minichunk;
-      }
-
-      if (nread>=fsize)
-       {
-         if (!smbshut(finfo, fnum, inbuf, outbuf))
-           {
-             DEBUG(0, ("Error closing remote file\n"));
-             free(inbuf);free(outbuf);
-             return;
-           }
-         if (fsize % TBLOCK) buffer_p+=TBLOCK - (fsize % TBLOCK);
-         DEBUG(5, ("buffer_p is now %d (psn=%d)\n",
-                   (int) buffer_p, (int)(buffer_p - tarbuf)));
-         ntarf++;
-         fsize=0;
-
-       }
-    } while (buffer_p < endofbuffer);
-  }
-
-  DEBUG(0, ("premature eof on tar file ?\n"));
-  DEBUG(0,("total of %d tar files restored to share\n", ntarf));
-
-  free(inbuf); free(outbuf);
-}
-#endif
 
 /*
  * samba interactive commands
@@ -2303,7 +1278,7 @@ static void do_tarput()
 /****************************************************************************
 Blocksize command
 ***************************************************************************/
-void cmd_block(char *dum_in, char *dum_out)
+void cmd_block(void)
 {
   fstring buf;
   int block;
@@ -2328,7 +1303,7 @@ void cmd_block(char *dum_in, char *dum_out)
 /****************************************************************************
 command to set incremental / reset mode
 ***************************************************************************/
-void cmd_tarmode(char *dum_in, char *dum_out)
+void cmd_tarmode(void)
 {
   fstring buf;
 
@@ -2368,7 +1343,7 @@ void cmd_tarmode(char *dum_in, char *dum_out)
 /****************************************************************************
 Feeble attrib command
 ***************************************************************************/
-void cmd_setmode(char *dum_in, char *dum_out)
+void cmd_setmode(void)
 {
   char *q;
   fstring buf;
@@ -2423,7 +1398,7 @@ void cmd_setmode(char *dum_in, char *dum_out)
 /****************************************************************************
 Principal command for creating / extracting
 ***************************************************************************/
-void cmd_tar(char *inbuf, char *outbuf)
+void cmd_tar(void)
 {
   fstring buf;
   char **argl;
@@ -2439,7 +1414,7 @@ void cmd_tar(char *inbuf, char *outbuf)
   if (!tar_parseargs(argcl, argl, buf, 0))
     return;
 
-  process_tar(inbuf, outbuf);
+  process_tar();
 
   free(argl);
 }
@@ -2447,7 +1422,7 @@ void cmd_tar(char *inbuf, char *outbuf)
 /****************************************************************************
 Command line (option) version
 ***************************************************************************/
-int process_tar(char *inbuf, char *outbuf)
+int process_tar(void)
 {
   initarbuf();
   switch(tar_type) {
@@ -2488,19 +1463,19 @@ int process_tar(char *inbuf, char *outbuf)
          safe_strcpy(cur_dir, tarmac, sizeof(pstring));
          *(strrchr(cur_dir, '\\')+1)='\0';
 
-         do_dir((char *)inbuf,(char *)outbuf,tarmac,attribute,do_tar,recurse, True);
+         do_list(tarmac,attribute,do_tar, False, True);
          safe_strcpy(cur_dir,saved_dir, sizeof(pstring));
        } else {
          safe_strcpy(tarmac, cur_dir, sizeof(pstring));
          safe_strcat(tarmac, cliplist[i], sizeof(pstring));
-         do_dir((char *)inbuf,(char *)outbuf,tarmac,attribute,do_tar,recurse, True);
+         do_list(tarmac,attribute,do_tar, False, True);
        }
       }
     } else {
       pstring mask;
       safe_strcpy(mask,cur_dir, sizeof(pstring));
-      safe_strcat(mask,"\\*", sizeof(pstring));
-      do_dir((char *)inbuf,(char *)outbuf,mask,attribute,do_tar,recurse, True);
+      safe_strcat(mask,"\\*.*", sizeof(pstring));
+      do_list(mask,attribute,do_tar,False, True);
     }
     
     if (ntarf) dotareof(tarhandle);
index 9a4a95e9eda1807f24366ada38e0d291eefbfa3e..1a17d50ac37b0b3e8c251cb1cc5d12a0715d47c3 100644 (file)
@@ -5,12 +5,8 @@
 
 /*The following definitions come from  client/client.c  */
 
-void do_dir(char *inbuf,char *outbuf,char *mask,int attribute,void (*fn)(file_info *),BOOL recurse_dir, BOOL dirstoo);
-char *complete_cmd_null(char *text, int state);
-void complete_process_file(file_info *f);
-char *complete_remote_file(char *text, int state);
-char *complete_cmd(char *text, int state);
-char **completion_fn(char *text, int start, int end);
+void do_list(const char *mask,int attribute,void (*fn)(file_info *),BOOL rec, BOOL dirs);
+struct cli_state *do_connect(char *server, char *share);
 
 /*The following definitions come from  client/clientutil.c  */
 
@@ -37,11 +33,11 @@ BOOL cli_reopen_connection(char *inbuf,char *outbuf);
 
 /*The following definitions come from  client/clitar.c  */
 
-void cmd_block(char *dum_in, char *dum_out);
-void cmd_tarmode(char *dum_in, char *dum_out);
-void cmd_setmode(char *dum_in, char *dum_out);
-void cmd_tar(char *inbuf, char *outbuf);
-int process_tar(char *inbuf, char *outbuf);
+void cmd_block(void);
+void cmd_tarmode(void);
+void cmd_setmode(void);
+void cmd_tar(void);
+int process_tar(void);
 int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind);
 
 /*The following definitions come from  lib/access.c  */
@@ -397,8 +393,8 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti
 BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout);
 size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size);
 ssize_t cli_write(struct cli_state *cli,
-                               int fnum, uint16 write_mode,
-                               char *buf, off_t offset, size_t size);
+                 int fnum, uint16 write_mode,
+                 char *buf, off_t offset, size_t size);
 BOOL cli_getattrE(struct cli_state *cli, int fd, 
                  uint32 *attr, size_t *size, 
                  time_t *c_time, time_t *a_time, time_t *m_time);
@@ -416,14 +412,15 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
                   uint32 *mode, size_t *size,
                   time_t *c_time, time_t *a_time, time_t *m_time, 
                   time_t *w_time, SMB_INO_T *ino);
-int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info *));
+int cli_list(struct cli_state *cli,const char *Mask,int attribute, 
+            void (*fn)(file_info *, const char *));
 BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_password,
                              char *old_password);
 BOOL cli_negprot(struct cli_state *cli);
 BOOL cli_session_request(struct cli_state *cli,
                         struct nmb_name *calling, struct nmb_name *called);
 BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip);
-BOOL cli_initialise(struct cli_state *cli);
+struct cli_state *cli_initialise(struct cli_state *cli);
 void cli_shutdown(struct cli_state *cli);
 int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num);
 void cli_sockopt(struct cli_state *cli, char *options);
@@ -437,6 +434,12 @@ BOOL cli_establish_connection(struct cli_state *cli,
 int cli_printjob_del(struct cli_state *cli, int job);
 int cli_print_queue(struct cli_state *cli, 
                    void (*fn)(struct print_job_info *));
+BOOL cli_chkpath(struct cli_state *cli, char *path);
+BOOL cli_message_start(struct cli_state *cli, char *host, char *username, 
+                             int *grp);
+BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp);
+BOOL cli_message_end(struct cli_state *cli, int grp);
+BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail);
 
 /*The following definitions come from  libsmb/credentials.c  */
 
@@ -936,7 +939,6 @@ char *lp_nis_home_map_name(void);
 char *lp_netbios_aliases(void);
 char *lp_driverfile(void);
 char *lp_panic_action(void);
-char *lp_domain_sid(void);
 char *lp_domain_groups(void);
 char *lp_domain_admin_group(void);
 char *lp_domain_guest_group(void);
@@ -966,7 +968,6 @@ BOOL lp_wins_support(void);
 BOOL lp_we_are_a_wins_server(void);
 BOOL lp_wins_proxy(void);
 BOOL lp_local_master(void);
-BOOL lp_domain_controller(void);
 BOOL lp_domain_master(void);
 BOOL lp_domain_logons(void);
 BOOL lp_preferred_master(void);
@@ -986,7 +987,6 @@ BOOL lp_browse_list(void);
 BOOL lp_unix_realname(void);
 BOOL lp_nis_home_map(void);
 BOOL lp_bind_interfaces_only(void);
-BOOL lp_net_wksta_user_logon(void);
 BOOL lp_unix_password_sync(void);
 BOOL lp_passwd_chat_debug(void);
 BOOL lp_ole_locking_compat(void);
index 7168d9cd924ac68f2f99a1fa413274276ca7f2cf..650b9a27a3d25483d79faeecccb5e0298aa4a039 100644 (file)
 extern int DEBUGLEVEL;
 
 
+/****************************************************************************
+recv an smb
+****************************************************************************/
+static BOOL cli_receive_smb(struct cli_state *cli)
+{
+       return client_receive_smb(cli->fd,cli->inbuf,cli->timeout);
+}
+
 /****************************************************************************
   send an smb to a fd and re-establish if necessary
 ****************************************************************************/
@@ -256,7 +264,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans,
 
        if (this_ldata < ldata || this_lparam < lparam) {
                /* receive interim response */
-               if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout) || 
+               if (!cli_receive_smb(cli) || 
                    CVAL(cli->inbuf,smb_rcls) != 0) {
                        return(False);
                }      
@@ -317,7 +325,7 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans,
        
        *data_len = *param_len = 0;
 
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
+       if (!cli_receive_smb(cli))
                return False;
 
        show_msg(cli->inbuf);
@@ -371,7 +379,7 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans,
                if (total_data <= *data_len && total_param <= *param_len)
                        break;
                
-               if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
+               if (!cli_receive_smb(cli))
                        return False;
 
                show_msg(cli->inbuf);
@@ -752,7 +760,7 @@ BOOL cli_session_setup(struct cli_state *cli,
        }
 
       cli_send_smb(cli);
-      if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
+      if (!cli_receive_smb(cli))
              return False;
 
       show_msg(cli->inbuf);
@@ -783,7 +791,7 @@ BOOL cli_ulogoff(struct cli_state *cli)
        SSVAL(cli->outbuf,smb_vwv2,0);  /* no additional info */
 
         cli_send_smb(cli);
-        if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
+        if (!cli_receive_smb(cli))
                 return False;
 
         return CVAL(cli->inbuf,smb_rcls) == 0;
@@ -836,7 +844,7 @@ BOOL cli_send_tconX(struct cli_state *cli,
        SCVAL(cli->inbuf,smb_rcls, 1);
 
        cli_send_smb(cli);
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
+       if (!cli_receive_smb(cli))
                return False;
 
        if (CVAL(cli->inbuf,smb_rcls) != 0) {
@@ -877,7 +885,7 @@ BOOL cli_tdis(struct cli_state *cli)
        cli_setup_packet(cli);
        
        cli_send_smb(cli);
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
+       if (!cli_receive_smb(cli))
                return False;
        
        return CVAL(cli->inbuf,smb_rcls) == 0;
@@ -909,7 +917,7 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst)
         pstrcpy(p,fname_dst);
 
         cli_send_smb(cli);
-        if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+        if (!cli_receive_smb(cli)) {
                 return False;
         }
 
@@ -943,7 +951,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname)
        pstrcpy(p,fname);
 
        cli_send_smb(cli);
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+       if (!cli_receive_smb(cli)) {
                return False;
        }
 
@@ -975,7 +983,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname)
        pstrcpy(p,dname);
 
        cli_send_smb(cli);
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+       if (!cli_receive_smb(cli)) {
                return False;
        }
 
@@ -1007,7 +1015,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname)
        pstrcpy(p,dname);
 
        cli_send_smb(cli);
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+       if (!cli_receive_smb(cli)) {
                return False;
        }
 
@@ -1052,7 +1060,7 @@ int cli_nt_create(struct cli_state *cli, char *fname)
        p = skip_string(p,1);
 
        cli_send_smb(cli);
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+       if (!cli_receive_smb(cli)) {
                return -1;
        }
 
@@ -1075,7 +1083,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
 
        /* you must open for RW not just write - otherwise getattrE doesn't
           work! */
-       if ((flags & O_ACCMODE) == O_WRONLY) {
+       if ((flags & O_ACCMODE) == O_WRONLY && strncmp(cli->dev, "LPT", 3)) {
                flags = (flags & ~O_ACCMODE) | O_RDWR;
        }
 
@@ -1123,7 +1131,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
        p = skip_string(p,1);
 
        cli_send_smb(cli);
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+       if (!cli_receive_smb(cli)) {
                return -1;
        }
 
@@ -1155,7 +1163,7 @@ BOOL cli_close(struct cli_state *cli, int fnum)
        SIVALS(cli->outbuf,smb_vwv1,-1);
 
        cli_send_smb(cli);
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+       if (!cli_receive_smb(cli)) {
                return False;
        }
 
@@ -1199,7 +1207,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti
 
         cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout;
 
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+       if (!cli_receive_smb(cli)) {
                 cli->timeout = saved_timeout;
                return False;
        }
@@ -1242,7 +1250,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int
        SIVAL(p, 6, len);
 
        cli_send_smb(cli);
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+       if (!cli_receive_smb(cli)) {
                return False;
        }
 
@@ -1305,7 +1313,7 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t
                        issued++;
                }
 
-               if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+               if (!cli_receive_smb(cli)) {
                        return total;
                }
 
@@ -1341,7 +1349,7 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t
        }
 
        while (received < issued) {
-               client_receive_smb(cli->fd,cli->inbuf,cli->timeout);
+               cli_receive_smb(cli);
                received++;
        }
        
@@ -1395,8 +1403,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1
               0x0008 start of message mode named pipe protocol
 ****************************************************************************/
 ssize_t cli_write(struct cli_state *cli,
-                               int fnum, uint16 write_mode,
-                               char *buf, off_t offset, size_t size)
+                 int fnum, uint16 write_mode,
+                 char *buf, off_t offset, size_t size)
 {
        int total = -1;
        int issued=0;
@@ -1420,7 +1428,7 @@ ssize_t cli_write(struct cli_state *cli,
                        issued++;
                }
 
-               if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+               if (!cli_receive_smb(cli)) {
                        return total;
                }
 
@@ -1446,7 +1454,7 @@ ssize_t cli_write(struct cli_state *cli,
        }
 
        while (received < issued) {
-               client_receive_smb(cli->fd,cli->inbuf,cli->timeout);
+               cli_receive_smb(cli);
                received++;
        }
        
@@ -1473,7 +1481,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd,
        SSVAL(cli->outbuf,smb_vwv0,fd);
 
        cli_send_smb(cli);
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+       if (!cli_receive_smb(cli)) {
                return False;
        }
        
@@ -1527,7 +1535,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname,
        pstrcpy(p+1, fname);
 
        cli_send_smb(cli);
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+       if (!cli_receive_smb(cli)) {
                return False;
        }
        
@@ -1578,7 +1586,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t)
        *p = 4;
 
        cli_send_smb(cli);
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+       if (!cli_receive_smb(cli)) {
                return False;
        }
        
@@ -1914,7 +1922,8 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
 /****************************************************************************
   do a directory listing, calling fn on each file found
   ****************************************************************************/
-int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info *))
+int cli_list(struct cli_state *cli,const char *Mask,int attribute, 
+            void (*fn)(file_info *, const char *))
 {
        int max_matches = 512;
        /* NT uses 260, OS/2 uses 2. Both accept 1. */
@@ -2065,7 +2074,7 @@ int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info
 
        for (p=dirlist,i=0;i<total_received;i++) {
                p += interpret_long_filename(info_level,p,&finfo);
-               fn(&finfo);
+               fn(&finfo, Mask);
        }
 
        /* free up the dirlist buffer */
@@ -2200,7 +2209,7 @@ BOOL cli_negprot(struct cli_state *cli)
        CVAL(smb_buf(cli->outbuf),0) = 2;
 
        cli_send_smb(cli);
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
+       if (!cli_receive_smb(cli))
                return False;
 
        show_msg(cli->inbuf);
@@ -2284,7 +2293,7 @@ retry:
        cli_send_smb(cli);
        DEBUG(5,("Sent session request\n"));
 
-       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
+       if (!cli_receive_smb(cli))
                return False;
 
 #ifdef WITH_SSL
@@ -2336,14 +2345,18 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip)
 /****************************************************************************
 initialise a client structure
 ****************************************************************************/
-BOOL cli_initialise(struct cli_state *cli)
+struct cli_state *cli_initialise(struct cli_state *cli)
 {
-       if (cli->initialised)
-       {
+       if (!cli) {
+               cli = (struct cli_state *)malloc(sizeof(*cli));
+               if (!cli) return NULL;
+       }
+
+       if (cli->initialised) {
                cli_shutdown(cli);
        }
 
-       memset(cli, 0, sizeof(*cli));
+       ZERO_STRUCTP(cli);
 
        cli->fd = -1;
        cli->cnum = -1;
@@ -2363,7 +2376,7 @@ BOOL cli_initialise(struct cli_state *cli)
 
        cli->initialised = 1;
 
-       return True;
+       return cli;
 }
 
 /****************************************************************************
@@ -2773,3 +2786,154 @@ int cli_print_queue(struct cli_state *cli,
 
        return i;
 }
+
+/****************************************************************************
+check for existance of a dir
+****************************************************************************/
+BOOL cli_chkpath(struct cli_state *cli, char *path)
+{
+       fstring path2;
+       char *p;
+       
+       fstrcpy(path2,path);
+       trim_string(path2,NULL,"\\");
+       if (!*path2) *path2 = '\\';
+       
+       bzero(cli->outbuf,smb_size);
+       set_message(cli->outbuf,0,4 + strlen(path2),True);
+       SCVAL(cli->outbuf,smb_com,SMBchkpth);
+       SSVAL(cli->outbuf,smb_tid,cli->cnum);
+       cli_setup_packet(cli);
+       
+       p = smb_buf(cli->outbuf);
+       *p++ = 4;
+       fstrcpy(p,path2);
+
+       cli_send_smb(cli);
+       if (!cli_receive_smb(cli)) {
+               return False;
+       }
+
+       if (cli_error(cli, NULL, NULL)) return False;
+
+       return True;
+}
+
+
+/****************************************************************************
+start a message sequence
+****************************************************************************/
+BOOL cli_message_start(struct cli_state *cli, char *host, char *username, 
+                             int *grp)
+{
+       char *p;
+
+       /* send a SMBsendstrt command */
+       bzero(cli->outbuf,smb_size);
+       set_message(cli->outbuf,0,0,True);
+       CVAL(cli->outbuf,smb_com) = SMBsendstrt;
+       SSVAL(cli->outbuf,smb_tid,cli->cnum);
+       cli_setup_packet(cli);
+       
+       p = smb_buf(cli->outbuf);
+       *p++ = 4;
+       pstrcpy(p,username);
+       p = skip_string(p,1);
+       *p++ = 4;
+       pstrcpy(p,host);
+       p = skip_string(p,1);
+       
+       set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False);
+       
+       cli_send_smb(cli);      
+       
+       if (!cli_receive_smb(cli)) {
+               return False;
+       }
+
+       if (cli_error(cli, NULL, NULL)) return False;
+
+       *grp = SVAL(cli->inbuf,smb_vwv0);
+
+       return True;
+}
+
+
+/****************************************************************************
+send a message 
+****************************************************************************/
+BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp)
+{
+       char *p;
+
+       bzero(cli->outbuf,smb_size);
+       set_message(cli->outbuf,1,len+3,True);
+       CVAL(cli->outbuf,smb_com) = SMBsendtxt;
+       SSVAL(cli->outbuf,smb_tid,cli->cnum);
+       cli_setup_packet(cli);
+
+       SSVAL(cli->outbuf,smb_vwv0,grp);
+       
+       p = smb_buf(cli->outbuf);
+       *p = 1;
+       SSVAL(p,1,len);
+       memcpy(p+3,msg,len);
+       cli_send_smb(cli);
+
+       if (!cli_receive_smb(cli)) {
+               return False;
+       }
+
+       if (cli_error(cli, NULL, NULL)) return False;
+
+       return True;
+}      
+
+/****************************************************************************
+end a message 
+****************************************************************************/
+BOOL cli_message_end(struct cli_state *cli, int grp)
+{
+       bzero(cli->outbuf,smb_size);
+       set_message(cli->outbuf,1,0,True);
+       CVAL(cli->outbuf,smb_com) = SMBsendend;
+       SSVAL(cli->outbuf,smb_tid,cli->cnum);
+
+       SSVAL(cli->outbuf,smb_vwv0,grp);
+
+       cli_setup_packet(cli);
+       
+       cli_send_smb(cli);
+
+       if (!cli_receive_smb(cli)) {
+               return False;
+       }
+
+       if (cli_error(cli, NULL, NULL)) return False;
+
+       return True;
+}      
+
+
+/****************************************************************************
+query disk space
+****************************************************************************/
+BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
+{
+       bzero(cli->outbuf,smb_size);
+       set_message(cli->outbuf,0,0,True);
+       CVAL(cli->outbuf,smb_com) = SMBdskattr;
+       SSVAL(cli->outbuf,smb_tid,cli->cnum);
+       cli_setup_packet(cli);
+
+       cli_send_smb(cli);
+       if (!cli_receive_smb(cli)) {
+               return False;
+       }
+
+       *bsize = SVAL(cli->inbuf,smb_vwv1)*SVAL(cli->inbuf,smb_vwv2);
+       *total = SVAL(cli->inbuf,smb_vwv0);
+       *avail = SVAL(cli->inbuf,smb_vwv3);
+       
+       return True;
+}
index 020386645c219fb299532796d850412d0fe2307f..8cba8d0644a81b7a76028a24c567ceb81200345c 100644 (file)
@@ -205,7 +205,7 @@ static SMB_BIG_UINT disk_free(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree
 
        /* FIXME : Any reason for this assumption ? */
        if (*bsize < 256) {
-               DEBUG(5,("disk_free:Warning: bsize == %d < 256 . Changing to assumed correct bsize = 512\n",*bsize));
+               DEBUG(5,("disk_free:Warning: bsize == %d < 256 . Changing to assumed correct bsize = 512\n",(int)*bsize));
                *bsize = 512;
        }
 
index d49ea7c5625cb2e6b6b115575a691ce2a0219830..fb5acf156f3671d15492034312a9a3570e8ee8ce 100644 (file)
@@ -1037,7 +1037,6 @@ BOOL server_validate(char *user, char *domain,
                     char *ntpass, int ntpasslen)
 {
   struct cli_state *cli;
-  extern fstring local_machine;
   static unsigned char badpass[24];
   static BOOL tested_password_server = False;
   static BOOL bad_password_server = False;
index ef139414bc9824f31a8e3ab693c76007a4fa4fcb..2ee019b2dcb356a18decdb5476fc3fd98018e63b 100644 (file)
@@ -158,7 +158,6 @@ set a variable in the shared area
 *******************************************************/
 void smbw_setshared(const char *name, const char *val)
 {
-       int len;
        int l1, l2;
 
        /* we don't allow variable overwrite */
index 4d1e3cc179175203ce142ac1d95a6a0baec01376..4b8381176b3922e19bef3b7b6f12ef1ab01bbe88 100644 (file)
@@ -78,7 +78,7 @@ static struct smbw_dir *cur_dir;
 /***************************************************** 
 add a entry to a directory listing
 *******************************************************/
-static void smbw_dir_add(struct file_info *finfo)
+static void smbw_dir_add(struct file_info *finfo, const char *mask)
 {
        DEBUG(5,("%s\n", finfo->name));
 
@@ -111,7 +111,7 @@ static void smbw_share_add(const char *share, uint32 type, const char *comment)
        pstrcpy(finfo.name, share);
        finfo.mode = aRONLY | aDIR;     
 
-       smbw_dir_add(&finfo);
+       smbw_dir_add(&finfo, NULL);
 }
 
 
@@ -128,7 +128,7 @@ static void smbw_server_add(const char *name, uint32 type,
        pstrcpy(finfo.name, name);
        finfo.mode = aRONLY | aDIR;     
 
-       smbw_dir_add(&finfo);
+       smbw_dir_add(&finfo, NULL);
 }
 
 
@@ -150,7 +150,7 @@ static void smbw_printjob_add(struct print_job_info *job)
        finfo.mode = aRONLY;
        finfo.size = job->size;
 
-       smbw_dir_add(&finfo);
+       smbw_dir_add(&finfo, NULL);
 }
 
 
index b27bbbbd3bf98e292bbc02747ce93f605862a440..e1904f9c967417d78d05387b8c652c6a4e12b1f8 100644 (file)
@@ -476,7 +476,7 @@ int main(int argc, char **argv)
 
     if(remote_machine == NULL)
       remote_machine = "127.0.0.1";
-  }    
+  }
     
   if (*user_name == '\0') {
     fprintf(stderr, "%s: Unable to get a user name for password change.\n", prog_name);