*** empty log message ***
authorLuke Leighton <lkcl@samba.org>
Tue, 30 Dec 1997 04:34:37 +0000 (04:34 +0000)
committerLuke Leighton <lkcl@samba.org>
Tue, 30 Dec 1997 04:34:37 +0000 (04:34 +0000)
28 files changed:
source/client/client.c
source/include/byteorder.h
source/include/includes.h
source/include/kanji.h
source/include/local.h
source/include/proto.h
source/include/smb.h
source/lib/charset.c
source/lib/membuffer.c
source/libsmb/clientgen.c
source/libsmb/namequery.c
source/locking/shmem_sysv.c
source/nmbd/asyncdns.c
source/param/loadparm.c
source/printing/pcap.c
source/pwd_validate.c
source/smbd/ipc.c
source/smbd/pipes.c
source/smbd/reply.c
source/smbd/server.c
source/smbd/trans2.c
source/ubiqx/ubi_AVLtree.c
source/ubiqx/ubi_AVLtree.h
source/ubiqx/ubi_BinTree.c
source/ubiqx/ubi_BinTree.h
source/ubiqx/ubi_SplayTree.c
source/ubiqx/ubi_SplayTree.h
source/utils/torture.c

index 35d17f79fd4f942cf3063869b5ed48977967ace0..8ee13d33a7e7f75744f998d7b1dd1b4d1eaea9cb 100644 (file)
@@ -187,7 +187,7 @@ static int process_tok(fstring tok)
          cmd = i;
          break;
        }
-      else if (strnequal(commands[i].name, tok, tok_len+1))
+      else if (strnequal(commands[i].name, tok, tok_len))
        {
          matches++;
          cmd = i;
@@ -256,6 +256,11 @@ static void wait_keyboard(struct cli_state *cli, int t_idx)
          }
       }
 #endif
+
+      /* We deliberately use receive_smb instead of
+         client_receive_smb as we want to receive
+         session keepalives and then drop them here.
+       */
       if (FD_ISSET(cli->fd,&fds))
        receive_smb(cli->fd,cli->inbuf,0);
       
@@ -386,7 +391,7 @@ static void usage(char *pname)
           pname);
 
   fprintf(out_hnd, "\nVersion %s\n",VERSION);
-  fprintf(out_hnd, "\t-p port               listen on the specified port\n");
+  fprintf(out_hnd, "\t-p port               connect to the specified port\n");
   fprintf(out_hnd, "\t-d debuglevel         set the debuglevel\n");
   fprintf(out_hnd, "\t-l log basename.      Basename for log/debug files\n");
   fprintf(out_hnd, "\t-n netbios name.      Use this name as my netbios name\n");
index 884e98f2fcffa6414cce7220963dc75ecf61b37e..1b90c72b82925f2eb2aa7611fcbead4445e0e10d 100644 (file)
@@ -204,42 +204,42 @@ it also defines lots of intermediate macros, just ignore those :-)
 
 /* macros for debug printing and reading / writing of data / arrays */
 
-#define DBG_RW_PCVAL(charmode,string,depth,base,read,inbuf,outbuf,len) \
+#define DBG_RW_PCVAL(charmode,string,depth,offset,read,inbuf,outbuf,len) \
        RW_PCVAL(read,inbuf,outbuf,len) \
-       DEBUG(5,("%s%04x %s: ", \
-             tab_depth(depth), PTR_DIFF(inbuf,base),string)); \
+       DEBUG(5,("%s%06x %s: ", \
+             tab_depth(depth), offset,string)); \
     if (charmode) print_asc(5, (unsigned char*)(outbuf), (len)); else \
        { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%02x ", (uint8)((outbuf)[idx]))); } } \
        DEBUG(5,("\n"));
 
-#define DBG_RW_PSVAL(charmode,string,depth,base,read,inbuf,outbuf,len) \
+#define DBG_RW_PSVAL(charmode,string,depth,offset,read,inbuf,outbuf,len) \
        RW_PSVAL(read,inbuf,outbuf,len) \
-       DEBUG(5,("%s%04x %s: ", \
-             tab_depth(depth), PTR_DIFF(inbuf,base),string)); \
+       DEBUG(5,("%s%06x %s: ", \
+             tab_depth(depth), offset,string)); \
     if (charmode) print_asc(5, (unsigned char*)(outbuf), 2*(len)); else \
        { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%04x ", (uint16)((outbuf)[idx]))); } } \
        DEBUG(5,("\n"));
 
-#define DBG_RW_PIVAL(charmode,string,depth,base,read,inbuf,outbuf,len) \
+#define DBG_RW_PIVAL(charmode,string,depth,offset,read,inbuf,outbuf,len) \
        RW_PIVAL(read,inbuf,outbuf,len) \
-       DEBUG(5,("%s%04x %s: ", \
-             tab_depth(depth), PTR_DIFF(inbuf,base),string)); \
+       DEBUG(5,("%s%06x %s: ", \
+             tab_depth(depth), offset,string)); \
     if (charmode) print_asc(5, (unsigned char*)(outbuf), 4*(len)); else \
        { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%08x ", (uint32)((outbuf)[idx]))); } } \
        DEBUG(5,("\n"));
 
-#define DBG_RW_CVAL(string,depth,base,read,inbuf,outbuf) \
+#define DBG_RW_CVAL(string,depth,offset,read,inbuf,outbuf) \
        RW_CVAL(read,inbuf,outbuf,0) \
-       DEBUG(5,("%s%04x %s: %02x\n", \
-             tab_depth(depth), PTR_DIFF(inbuf,base), string, outbuf));
+       DEBUG(5,("%s%06x %s: %02x\n", \
+             tab_depth(depth), offset, string, outbuf));
 
-#define DBG_RW_SVAL(string,depth,base,read,inbuf,outbuf) \
+#define DBG_RW_SVAL(string,depth,offset,read,inbuf,outbuf) \
        RW_SVAL(read,inbuf,outbuf,0) \
-       DEBUG(5,("%s%04x %s: %04x\n", \
-             tab_depth(depth), PTR_DIFF(inbuf,base), string, outbuf));
+       DEBUG(5,("%s%06x %s: %04x\n", \
+             tab_depth(depth), offset, string, outbuf));
 
-#define DBG_RW_IVAL(string,depth,base,read,inbuf,outbuf) \
+#define DBG_RW_IVAL(string,depth,offset,read,inbuf,outbuf) \
        RW_IVAL(read,inbuf,outbuf,0) \
-       DEBUG(5,("%s%04x %s: %08x\n", \
-             tab_depth(depth), PTR_DIFF(inbuf,base), string, outbuf));
+       DEBUG(5,("%s%06x %s: %08x\n", \
+             tab_depth(depth), offset, string, outbuf));
 
index c99880cad3c1b8f0f538aaf08914c9875e109b7f..b35f3539ae33521f444b057ce8e47cd772ffe3f0 100644 (file)
@@ -502,7 +502,21 @@ char *mktemp(char *); /* No standard include */
 #define REPLACE_INNETGR
 #endif 
 
-
+#ifdef __OpenBSD__
+#include <strings.h>
+#include <netinet/tcp.h>
+#define NO_GETSPNAM
+#define SIGNAL_CAST (void (*)())
+#define USE_DIRECT
+#define REPLACE_INNETGR
+#define HAVE_BZERO
+#define HAVE_PATHCONF
+#define HAVE_GETGRNAM 1
+#define HAVE_GETTIMEOFDAY
+#define HAVE_MEMMOVE
+#define USE_GETCWD
+#define USE_SETSID
+#endif 
 
 #ifdef FreeBSD
 #include <arpa/inet.h>
@@ -1104,6 +1118,23 @@ struct spwd { /* fake shadow password structure */
 #endif
 
 
+/* This defines the name of the printcap file. It is MOST UNLIKELY that
+   this will change BUT! Specifying a file with the format of a printcap
+   file but containing only a subset of the printers actually in your real 
+   printcap file is a quick-n-dirty way to allow dynamic access to a subset
+   of available printers.
+*/
+#ifndef PRINTCAP_NAME
+#ifdef AIX
+#define PRINTCAP_NAME "/etc/qconfig"
+#elif defined(SYSV)
+#define PRINTCAP_NAME "lpstat"
+#else
+#define PRINTCAP_NAME "/etc/printcap"
+#endif
+#endif
+
+
 #ifdef USE_SYSV_IPC
 #include <sys/ipc.h>
 #include <sys/sem.h>
index 5e8173ee14ca72d561f942e542359b5a580a2a8a..f42e4cd95db6490d293d1e6147fd990cc8b404af 100644 (file)
@@ -132,6 +132,30 @@ extern char *(*_unix_to_dos)(char *str, BOOL overwrite);
 
 /* Ensure we use our definitions. */
 
+/*
+ * The following is needed for AIX systems that have
+ * their own #defines for strchr, strrchr, strstr
+ * and strtok.
+ */
+
+#ifdef strchr
+#undef strchr
+#endif /* strchr */
+
+#ifdef strrchr
+#undef strrchr
+#endif /* strrchr */
+
+#ifdef strstr
+#undef strstr
+#endif /* strstr */
+
+#ifdef strtok
+#undef strtok
+#endif /* strtok */
+
+/* Ensure we use our definitions. */
+
 #define strchr sj_strchr
 #define strrchr sj_strrchr
 #define strstr sj_strstr
index 10906d1ff1eeeae9eb841b8990c07c906a18e5fd..9b0d4c2c4dcb7d048652a39e6536ed68e1887c03 100644 (file)
 #define FSTYPE_STRING "Samba"
 
 
+/* the default guest account - normally set in the Makefile or smb.conf */
+#ifndef GUEST_ACCOUNT
+#define GUEST_ACCOUNT "nobody"
+#endif
+
+
 /* the default guest account - normally set in the Makefile or smb.conf */
 #ifndef GUEST_ACCOUNT
 #define GUEST_ACCOUNT "nobody"
index e4d1f21f3fec349c42f51592d858caacb552bdd2..a99d986c8033516a0b12b58a17a71173e74343cc 100644 (file)
@@ -135,9 +135,16 @@ BOOL cli_dskattr(struct cli_state *cli, int t_idx,
 BOOL cli_mkdir(struct cli_state *cli, int t_idx, char *name);
 BOOL cli_move(struct cli_state *cli, int t_idx, char *src, char *dest);
 BOOL cli_getatr(struct cli_state *cli, int t_idx, char *fname,
-                               uint8 *fattr, uint16 *ftime, uint16 *fsize);
+                               uint16 *fattr, time_t *ftime, uint32 *fsize);
 BOOL cli_setatr(struct cli_state *cli, int t_idx, char *fname,
-                               uint8 fattr, uint16 write_time);
+                               uint16 fattr, time_t write_time);
+BOOL cli_qpathinfo(struct cli_state *cli, uint16 t_idx, char *fname, 
+                  time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size);
+BOOL cli_qpathinfo2(struct cli_state *cli, uint16 t_idx, char *fname, 
+                   time_t *c_time, time_t *a_time, time_t *m_time, 
+                   time_t *w_time, uint32 *size);
+BOOL cli_qfileinfo(struct cli_state *cli, uint16 t_idx, uint16 fnum, 
+                  time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size);
 BOOL cli_create(struct cli_state *cli, int t_idx,
                                char *name, uint16 file_mode, uint16 make_time, uint16 *fnum);
 uint16 cli_open(struct cli_state *cli, int t_idx, char *fname, int flags, int share_mode,
@@ -347,7 +354,7 @@ struct in_addr *iface_ip(struct in_addr ip);
 /*The following definitions come from  ipc.c  */
 
 int get_printerdrivernumber(int snum);
-int reply_trans(char *inbuf,char *outbuf);
+int reply_trans(char *inbuf,char *outbuf, int size, int bufsize);
 
 /*The following definitions come from  kanji.c  */
 
@@ -585,23 +592,21 @@ void mdfour(unsigned char *out, unsigned char *in, int n);
 
 /*The following definitions come from  membuffer.c  */
 
-void buf_init(struct mem_buf *buf, int align, int margin);
-void buf_create(struct mem_buf *buf, char *data, int size, int align, int margin);
-void buf_take(struct mem_buf *buf_to, struct mem_buf *buf_from);
-BOOL buf_alloc(struct mem_buf *buf, int size);
-void buf_free(struct mem_buf *buf);
-BOOL buf_realloc(struct mem_buf *buf, int new_size);
-void buf_grow(struct mem_buf *buf, int new_size);
-void buf_align(struct mem_buf *buf, int *data_off);
-void buf_uint8(char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, uint8 *data);
-void buf_uint16(char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, uint16 *data);
-void buf_uint32(char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, uint32 *data);
-void buf_uint8s(BOOL charmode, char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, uint8 *data, int len);
-void buf_uint16s(BOOL charmode, char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, uint16 *data, int len);
-void buf_uint32s(BOOL charmode, char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, uint32 *data, int len);
-void buf_uninotstr2(BOOL charmode, char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, UNINOTSTR2 *str);
-void buf_unistr2(BOOL charmode, char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, UNISTR2 *str);
-void buf_unistr(char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, UNISTR *str);
+void mem_init(struct mem_buf *buf, int margin);
+void mem_create(struct mem_buf *buf, char *data, int size, int margin);
+void mem_take(struct mem_buf *mem_to, struct mem_buf *mem_from);
+BOOL mem_alloc_data(struct mem_buf *buf, int size);
+BOOL mem_buf_copy(char *copy_into, struct mem_buf *buf,
+                               uint32 offset, uint32 len);
+BOOL mem_buf_init(struct mem_buf **buf, uint32 margin);
+void mem_buf_free(struct mem_buf **buf);
+void mem_free_chain(struct mem_buf **buf);
+void mem_free_data(struct mem_buf *buf);
+BOOL mem_realloc_data(struct mem_buf *buf, int new_size);
+BOOL mem_grow_data(struct mem_buf **buf, BOOL io, int new_size);
+BOOL mem_find(struct mem_buf **buf, uint32 offset);
+uint32 mem_buf_len(struct mem_buf *buf);
+char *mem_data(struct mem_buf **buf, uint32 offset);
 
 /*The following definitions come from  message.c  */
 
@@ -995,11 +1000,6 @@ void pcap_printer_fn(void (*fn)());
 int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize);
 int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize);
 int reply_pipe_close(char *inbuf,char *outbuf);
-BOOL api_LsarpcSNPHS(int pnum, int cnum, char *param);
-BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
-                    int mdrcnt,int mprcnt,
-                    char **rdata,char **rparam,
-                    int *rdata_len,int *rparam_len);
 
 /*The following definitions come from  predict.c  */
 
@@ -1121,28 +1121,28 @@ BOOL close_lsa_policy_hnd(POLICY_HND *hnd);
 /*The following definitions come from  rpc_pipes/lsaparse.c  */
 
 void make_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, uint32 sec_qos);
-void lsa_io_obj_attr(char *desc, BOOL io, LSA_OBJ_ATTR *attr, struct mem_buffer *buf, int *q, int depth);
+void lsa_io_obj_attr(char *desc,  LSA_OBJ_ATTR *attr, prs_struct *ps);
 void make_q_open_pol(LSA_Q_OPEN_POL *r_q, char *server_name,
                        uint32 attributes, uint32 sec_qos,
                        uint32 desired_access);
-void lsa_io_q_open_pol(char *desc, BOOL io, LSA_Q_OPEN_POL *r_q, struct mem_buffer *buf, int *q,  int depth);
-void lsa_io_r_open_pol(char *desc, BOOL io, LSA_R_OPEN_POL *r_p, struct mem_buffer *buf, int *q,  int depth);
+void lsa_io_q_open_pol(char *desc,  LSA_Q_OPEN_POL *r_q, prs_struct *ps);
+void lsa_io_r_open_pol(char *desc,  LSA_R_OPEN_POL *r_p, prs_struct *ps);
 void make_q_query(LSA_Q_QUERY_INFO *q_q, POLICY_HND *hnd, uint16 info_class);
-void lsa_io_q_query(char *desc, BOOL io, LSA_Q_QUERY_INFO *q_q, struct mem_buffer *buf, int *q,  int depth);
-void lsa_io_q_enum_trust_dom(char *desc, BOOL io, LSA_Q_ENUM_TRUST_DOM *q_e, struct mem_buffer *buf, int *q,  int depth);
+void lsa_io_q_query(char *desc,  LSA_Q_QUERY_INFO *q_q, prs_struct *ps);
+void lsa_io_q_enum_trust_dom(char *desc,  LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct *ps);
 void make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e,
                                uint32 enum_context, char *domain_name, char *domain_sid,
                                uint32 status);
-void lsa_io_r_enum_trust_dom(char *desc, BOOL io, LSA_R_ENUM_TRUST_DOM *r_e, struct mem_buffer *buf, int *q,  int depth);
+void lsa_io_r_enum_trust_dom(char *desc,  LSA_R_ENUM_TRUST_DOM *r_e, prs_struct *ps);
 void make_lsa_q_close(LSA_Q_CLOSE *q_c, POLICY_HND *hnd);
-void lsa_io_q_close(char *desc, BOOL io, LSA_Q_CLOSE *q_c, struct mem_buffer *buf, int *q,  int depth);
+void lsa_io_q_close(char *desc,  LSA_Q_CLOSE *q_c, prs_struct *ps);
 void make_lsa_r_close(LSA_R_CLOSE *q_r, POLICY_HND *hnd);
-void lsa_io_r_close(char *desc, BOOL io, LSA_R_CLOSE *r_c, struct mem_buffer *buf, int *q,  int depth);
-void lsa_io_r_query(char *desc, BOOL io, LSA_R_QUERY_INFO *r_q, struct mem_buffer *buf, int *q,  int depth);
-void lsa_io_q_lookup_sids(char *desc, BOOL io, LSA_Q_LOOKUP_SIDS *q_s, struct mem_buffer *buf, int *q,  int depth);
-void lsa_io_r_lookup_sids(char *desc, BOOL io, LSA_R_LOOKUP_SIDS *r_s, struct mem_buffer *buf, int *q,  int depth);
-void lsa_io_q_lookup_rids(char *desc, BOOL io, LSA_Q_LOOKUP_RIDS *q_r, struct mem_buffer *buf, int *q,  int depth);
-void lsa_io_r_lookup_rids(char *desc, BOOL io, LSA_R_LOOKUP_RIDS *r_r, struct mem_buffer *buf, int *q,  int depth);
+void lsa_io_r_close(char *desc,  LSA_R_CLOSE *r_c, prs_struct *ps);
+void lsa_io_r_query(char *desc,  LSA_R_QUERY_INFO *r_q, prs_struct *ps);
+void lsa_io_q_lookup_sids(char *desc,  LSA_Q_LOOKUP_SIDS *q_s, prs_struct *ps);
+void lsa_io_r_lookup_sids(char *desc,  LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps);
+void lsa_io_q_lookup_rids(char *desc,  LSA_Q_LOOKUP_RIDS *q_r, prs_struct *ps);
+void lsa_io_r_lookup_rids(char *desc,  LSA_R_LOOKUP_RIDS *r_r, prs_struct *ps);
 void make_lsa_user_info3(LSA_USER_INFO_3 *usr,
 
        NTTIME *logon_time,
@@ -1175,42 +1175,42 @@ void make_lsa_user_info3(LSA_USER_INFO_3 *usr,
 
        char *dom_sid,
        char *other_sids);
-void lsa_io_user_info3(char *desc, BOOL io, LSA_USER_INFO_3 *usr, struct mem_buffer *buf, int *q, int depth);
+void lsa_io_user_info3(char *desc,  LSA_USER_INFO_3 *usr, prs_struct *ps);
 
 /*The following definitions come from  rpc_pipes/netparse.c  */
 
 void make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, char *server_name,
                        uint32 function_code);
-void net_io_q_logon_ctrl2(char *desc, BOOL io, NET_Q_LOGON_CTRL2 *q_l, struct mem_buffer *buf, int *q,  int depth);
+void net_io_q_logon_ctrl2(char *desc,  NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps);
 void make_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
                                uint32 flags, uint32 pdc_status, uint32 logon_attempts,
                                uint32 tc_status, char *trusted_domain_name);
-void net_io_r_logon_ctrl2(char *desc, BOOL io, NET_R_LOGON_CTRL2 *r_l, struct mem_buffer *buf, int *q,  int depth);
+void net_io_r_logon_ctrl2(char *desc,  NET_R_LOGON_CTRL2 *r_l, prs_struct *ps);
 void make_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
                        uint32 num_doms, char *dom_name);
-void net_io_r_trust_dom(char *desc, BOOL io, NET_R_TRUST_DOM_LIST *r_t, struct mem_buffer *buf, int *q,  int depth);
+void net_io_r_trust_dom(char *desc,  NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps);
 void make_q_trust_dom(NET_Q_TRUST_DOM_LIST *q_l, char *server_name,
                        uint32 function_code);
-void net_io_q_trust_dom(char *desc, BOOL io, NET_Q_TRUST_DOM_LIST *q_l, struct mem_buffer *buf, int *q,  int depth);
+void net_io_q_trust_dom(char *desc,  NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps);
 void make_q_req_chal(NET_Q_REQ_CHAL *q_c,
                                char *logon_srv, char *logon_clnt,
                                DOM_CHAL *clnt_chal);
-void net_io_q_req_chal(char *desc, BOOL io, NET_Q_REQ_CHAL *q_c, struct mem_buffer *buf, int *q,  int depth);
-void net_io_r_req_chal(char *desc, BOOL io, NET_R_REQ_CHAL *r_c, struct mem_buffer *buf, int *q,  int depth);
+void net_io_q_req_chal(char *desc,  NET_Q_REQ_CHAL *q_c, prs_struct *ps);
+void net_io_r_req_chal(char *desc,  NET_R_REQ_CHAL *r_c, prs_struct *ps);
 void make_q_auth_2(NET_Q_AUTH_2 *q_a,
                char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
                DOM_CHAL *clnt_chal, uint32 clnt_flgs);
-void net_io_q_auth_2(char *desc, BOOL io, NET_Q_AUTH_2 *q_a, struct mem_buffer *buf, int *q,  int depth);
-void net_io_r_auth_2(char *desc, BOOL io, NET_R_AUTH_2 *r_a, struct mem_buffer *buf, int *q,  int depth);
+void net_io_q_auth_2(char *desc,  NET_Q_AUTH_2 *q_a, prs_struct *ps);
+void net_io_r_auth_2(char *desc,  NET_R_AUTH_2 *r_a, prs_struct *ps);
 void make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char sess_key[16],
                char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
                DOM_CRED *cred, char nt_cypher[16]);
-void net_io_q_srv_pwset(char *desc, BOOL io, NET_Q_SRV_PWSET *q_s, struct mem_buffer *buf, int *q,  int depth);
-void net_io_r_srv_pwset(char *desc, BOOL io, NET_R_SRV_PWSET *r_s, struct mem_buffer *buf, int *q,  int depth);
-void net_io_q_sam_logon(char *desc, BOOL io, NET_Q_SAM_LOGON *q_l, struct mem_buffer *buf, int *q,  int depth);
-void net_io_r_sam_logon(char *desc, BOOL io, NET_R_SAM_LOGON *r_l, struct mem_buffer *buf, int *q,  int depth);
-void net_io_q_sam_logoff(char *desc, BOOL io, NET_Q_SAM_LOGOFF *q_l, struct mem_buffer *buf, int *q,  int depth);
-void net_io_r_sam_logoff(char *desc, BOOL io, NET_R_SAM_LOGOFF *r_l, struct mem_buffer *buf, int *q,  int depth);
+void net_io_q_srv_pwset(char *desc,  NET_Q_SRV_PWSET *q_s, prs_struct *ps);
+void net_io_r_srv_pwset(char *desc,  NET_R_SRV_PWSET *r_s, prs_struct *ps);
+void net_io_q_sam_logon(char *desc,  NET_Q_SAM_LOGON *q_l, prs_struct *ps);
+void net_io_r_sam_logon(char *desc,  NET_R_SAM_LOGON *r_l, prs_struct *ps);
+void net_io_q_sam_logoff(char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps);
+void net_io_r_sam_logoff(char *desc,  NET_R_SAM_LOGOFF *r_l, prs_struct *ps);
 
 /*The following definitions come from  rpc_pipes/ntclientlogin.c  */
 
@@ -1280,6 +1280,13 @@ BOOL do_net_sam_logoff(struct cli_state *cli, int t_idx, uint16 fnum,
 
 /*The following definitions come from  rpc_pipes/ntclientpipe.c  */
 
+BOOL rpc_api_pipe(struct cli_state *cli, int t_idx,
+                               uint16 cmd, uint16 fnum,
+                               prs_struct *param , prs_struct *data,
+                               prs_struct *rparam, prs_struct *rdata);
+BOOL rpc_api_pipe_req(struct cli_state *cli, int t_idx, uint16 fnum,
+                               uint8 op_num,
+                               prs_struct *data, prs_struct *rdata);
 BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, int t_idx,
                                char *pipe_name, uint16 fnum, uint16 device_state);
 BOOL rpc_pipe_bind(struct cli_state *cli, int t_idx, char *pipe_name, uint16 fnum, 
@@ -1358,39 +1365,32 @@ void reset_chain_pnum(void);
 void set_chain_pnum(int new_pnum);
 void init_rpc_pipe_hnd(void);
 int open_rpc_pipe_hnd(char *pipe_name, int cnum);
-BOOL write_pipe(int pnum, struct mem_buffer *buf);
-int read_pipe(int pnum, char *data, uint32 pos, int n);
+int read_pipe(uint16 pnum, char *data, uint32 pos, int n);
+BOOL get_rpc_pipe(int pnum, pipes_struct **p);
 char *get_rpc_pipe_hnd_name(int pnum);
-BOOL set_rpc_pipe_hnd_state(int pnum, int cnum, uint16 device_state);
+BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state);
 BOOL close_rpc_pipe_hnd(int pnum, int cnum);
 int get_rpc_pipe_num(char *buf, int where);
 
 /*The following definitions come from  rpc_pipes/pipenetlog.c  */
 
-BOOL api_netlog_rpc(int cnum, int uid,
-                               struct mem_buffer *data, 
-                               struct mem_buffer *rdata);
+BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data);
 
 /*The following definitions come from  rpc_pipes/pipentlsa.c  */
 
-BOOL api_ntlsa_rpc(int cnum,int uid,
-                               struct mem_buffer *data, struct mem_buffer *rdata);
+BOOL api_ntlsa_rpc(pipes_struct *p, prs_struct *data);
 
 /*The following definitions come from  rpc_pipes/pipereg.c  */
 
-BOOL api_reg_rpc(int cnum,int uid,
-                               struct mem_buffer *data,
-                               struct mem_buffer *rdata);
+BOOL api_reg_rpc(pipes_struct *p, prs_struct *data);
 
 /*The following definitions come from  rpc_pipes/pipesamr.c  */
 
-BOOL api_samr_rpc(int cnum,int uid, struct mem_buffer *data, struct mem_buffer *rdata);
+BOOL api_samr_rpc(pipes_struct *p, prs_struct *data);
 
 /*The following definitions come from  rpc_pipes/pipesrvsvc.c  */
 
-BOOL api_srvsvc_rpc(int cnum,int uid,
-                               struct mem_buffer *data,
-                               struct mem_buffer *rdata);
+BOOL api_srvsvc_rpc(pipes_struct *p, prs_struct *data);
 
 /*The following definitions come from  rpc_pipes/pipeutil.c  */
 
@@ -1402,157 +1402,166 @@ char *dom_sid_to_string(DOM_SID *sid);
 int make_dom_sid2s(char *sids_str, DOM_SID2 *sids, int max_sids);
 int make_dom_gids(char *gids_str, DOM_GID *gids);
 void get_domain_user_groups(char *domain_groups, char *user);
-void create_rpc_request(struct mem_buffer *rdata, int *rdata_off, uint32 call_id, uint8 op_num, int data_len);
-void create_rpc_reply(struct mem_buffer *rdata, int *rdata_off, uint32 call_id, int data_len);
-BOOL rpc_api_pipe(struct cli_state *cli, int t_idx,
-                               uint16 cmd, uint16 fnum,
-                               struct mem_buffer *param , struct mem_buffer *data,
-                               struct mem_buffer *rparam, struct mem_buffer *rdata);
-BOOL api_rpcTNP(char *rpc_name, struct api_struct *api_rpc_cmds,
-                               int cnum, int uid,
-                               struct mem_buffer *data ,
-                               struct mem_buffer *rdata);
+BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds,
+                               prs_struct *data);
 
 /*The following definitions come from  rpc_pipes/pipewkssvc.c  */
 
-BOOL api_wkssvc_rpc(int cnum, int uid,
-                               struct mem_buffer *data, 
-                               struct mem_buffer *rdata);
+BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data);
+
+/*The following definitions come from  rpc_pipes/prsparse.c  */
+
+void prs_debug(prs_struct *ps, char *desc, char *fn_name);
+void prs_init(prs_struct *ps, uint32 size,
+                               uint8 align, uint32 margin,
+                               BOOL io, int depth);
+void prs_mem_free(prs_struct *ps);
+void prs_align(prs_struct *ps);
+BOOL prs_grow(prs_struct *ps);
+BOOL prs_uint8(char *name, prs_struct *ps, uint8 *data8);
+BOOL prs_uint16(char *name, prs_struct *ps, uint16 *data16);
+BOOL prs_uint32(char *name, prs_struct *ps, uint32 *data32);
+BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, uint8 *data8s, int len);
+BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, uint16 *data16s, int len);
+BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, uint32 *data32s, int len);
+BOOL prs_uninotstr2(BOOL charmode, char *name, prs_struct *ps, UNINOTSTR2 *str);
+BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, UNISTR2 *str);
+BOOL prs_unistr(char *name, prs_struct *ps, UNISTR *str);
 
 /*The following definitions come from  rpc_pipes/regparse.c  */
 
 void make_reg_q_open_policy(REG_Q_OPEN_POLICY *r_q,
                                uint16 unknown_0, uint32 level, uint16 unknown_1);
-void reg_io_q_open_policy(char *desc, BOOL io, REG_Q_OPEN_POLICY *r_q, struct mem_buffer *buf, int *q,  int depth);
+void reg_io_q_open_policy(char *desc,  REG_Q_OPEN_POLICY *r_q, prs_struct *ps);
 void make_reg_r_open_policy(REG_R_OPEN_POLICY *r_r,
                                POLICY_HND *pol, uint32 status);
-void reg_io_r_open_policy(char *desc, BOOL io, REG_R_OPEN_POLICY *r_r, struct mem_buffer *buf, int *q,  int depth);
-void reg_io_q_close(char *desc, BOOL io, REG_Q_CLOSE *q_u, struct mem_buffer *buf, int *q,  int depth);
-void reg_io_r_close(char *desc, BOOL io, REG_R_CLOSE *r_u, struct mem_buffer *buf, int *q,  int depth);
+void reg_io_r_open_policy(char *desc,  REG_R_OPEN_POLICY *r_r, prs_struct *ps);
+void reg_io_q_close(char *desc,  REG_Q_CLOSE *q_u, prs_struct *ps);
+void reg_io_r_close(char *desc,  REG_R_CLOSE *r_u, prs_struct *ps);
 void make_reg_q_info(REG_Q_INFO *r_q,
                                POLICY_HND *pol, char *product_type,
                                NTTIME *prod_time, uint8 major_version, uint8 minor_version,
                                uint32 unknown);
-void reg_io_q_info(char *desc, BOOL io, REG_Q_INFO *r_q, struct mem_buffer *buf, int *q,  int depth);
+void reg_io_q_info(char *desc,  REG_Q_INFO *r_q, prs_struct *ps);
 void make_reg_r_info(REG_R_INFO *r_r,
                                uint32 level, char *os_type,
                                uint32 unknown_0, uint32 unknown_1,
                                uint32 status);
-void reg_io_r_info(char *desc, BOOL io, REG_R_INFO *r_r, struct mem_buffer *buf, int *q,  int depth);
+void reg_io_r_info(char *desc,  REG_R_INFO *r_r, prs_struct *ps);
 void make_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q,
                                POLICY_HND *pol, char *name,
                                uint32 unknown_0, uint32 unknown_1, uint16 unknown_2);
-void reg_io_q_open_entry(char *desc, BOOL io, REG_Q_OPEN_ENTRY *r_q, struct mem_buffer *buf, int *q,  int depth);
+void reg_io_q_open_entry(char *desc,  REG_Q_OPEN_ENTRY *r_q, prs_struct *ps);
 void make_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
                                POLICY_HND *pol, uint32 status);
-void reg_io_r_open_entry(char *desc, BOOL io, REG_R_OPEN_ENTRY *r_r, struct mem_buffer *buf, int *q,  int depth);
+void reg_io_r_open_entry(char *desc,  REG_R_OPEN_ENTRY *r_r, prs_struct *ps);
 
 /*The following definitions come from  rpc_pipes/samrparse.c  */
 
 void make_samr_q_close_hnd(SAMR_Q_CLOSE_HND *q_c, POLICY_HND *hnd);
-void samr_io_q_close_hnd(char *desc, BOOL io, SAMR_Q_CLOSE_HND *q_u, struct mem_buffer *buf, int *q, int depth);
-void samr_io_r_close_hnd(char *desc, BOOL io, SAMR_R_CLOSE_HND *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_close_hnd(char *desc,  SAMR_Q_CLOSE_HND *q_u, prs_struct *ps);
+void samr_io_r_close_hnd(char *desc,  SAMR_R_CLOSE_HND *r_u, prs_struct *ps);
 void make_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
                                POLICY_HND *connect_pol, uint32 rid, char *sid);
-void samr_io_q_open_domain(char *desc, BOOL io, SAMR_Q_OPEN_DOMAIN *q_u, struct mem_buffer *buf, int *q, int depth);
-void samr_io_r_open_domain(char *desc, BOOL io, SAMR_R_OPEN_DOMAIN *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_open_domain(char *desc,  SAMR_Q_OPEN_DOMAIN *q_u, prs_struct *ps);
+void samr_io_r_open_domain(char *desc,  SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps);
 void make_samr_q_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
                                POLICY_HND *pol, uint32 switch_value);
-void samr_io_q_unknown_3(char *desc, BOOL io, SAMR_Q_UNKNOWN_3 *q_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_unknown_3(char *desc,  SAMR_Q_UNKNOWN_3 *q_u, prs_struct *ps);
 void make_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, char *sid);
-void sam_io_dom_sid3(char *desc, BOOL io, DOM_SID3 *sid3, struct mem_buffer *buf, int *q, int depth);
+void sam_io_dom_sid3(char *desc,  DOM_SID3 *sid3, prs_struct *ps);
 void make_sam_sid_stuff(SAM_SID_STUFF *stf,
                                uint16 unknown_2, uint16 unknown_3,
                                uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
                                int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS]);
-void sam_io_sid_stuff(char *desc, BOOL io, SAM_SID_STUFF *stf, struct mem_buffer *buf, int *q, int depth);
+void sam_io_sid_stuff(char *desc,  SAM_SID_STUFF *stf, prs_struct *ps);
 void make_samr_r_unknown_3(SAMR_R_UNKNOWN_3 *r_u,
                                uint16 unknown_2, uint16 unknown_3,
                                uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
                                int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS],
                                uint32 status);
-void samr_io_r_unknown_3(char *desc, BOOL io, SAMR_R_UNKNOWN_3 *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_r_unknown_3(char *desc,  SAMR_R_UNKNOWN_3 *r_u, prs_struct *ps);
 void make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
                                uint16 req_num_entries, uint16 unk_0,
                                uint16 acb_mask, uint16 unk_1, uint32 size);
-void samr_io_q_enum_dom_users(char *desc, BOOL io, SAMR_Q_ENUM_DOM_USERS *q_e, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_enum_dom_users(char *desc,  SAMR_Q_ENUM_DOM_USERS *q_e, prs_struct *ps);
 void make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
                uint16 total_num_entries, uint16 unk_0,
                uint32 num_sam_entries, struct smb_passwd pass[MAX_SAM_ENTRIES], uint32 status);
-void samr_io_r_enum_dom_users(char *desc, BOOL io, SAMR_R_ENUM_DOM_USERS *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_r_enum_dom_users(char *desc,  SAMR_R_ENUM_DOM_USERS *r_u, prs_struct *ps);
 void make_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_e, POLICY_HND *pol, uint32 size);
-void samr_io_q_enum_dom_aliases(char *desc, BOOL io, SAMR_Q_ENUM_DOM_ALIASES *q_e, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_enum_dom_aliases(char *desc,  SAMR_Q_ENUM_DOM_ALIASES *q_e, prs_struct *ps);
 void make_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u,
                uint32 num_sam_entries, struct smb_passwd grps[MAX_SAM_ENTRIES],
                uint32 status);
-void samr_io_r_enum_dom_aliases(char *desc, BOOL io, SAMR_R_ENUM_DOM_ALIASES *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_r_enum_dom_aliases(char *desc,  SAMR_R_ENUM_DOM_ALIASES *r_u, prs_struct *ps);
 void make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol,
                                uint16 switch_level, uint32 start_idx, uint32 size);
-void samr_io_q_query_dispinfo(char *desc, BOOL io, SAMR_Q_QUERY_DISPINFO *q_e, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_query_dispinfo(char *desc,  SAMR_Q_QUERY_DISPINFO *q_e, prs_struct *ps);
 void make_sam_info_2(SAM_INFO_2 *sam, uint32 acb_mask,
                uint32 start_idx, uint32 num_sam_entries,
                struct smb_passwd pass[MAX_SAM_ENTRIES]);
-void sam_io_sam_info_2(char *desc, BOOL io, SAM_INFO_2 *sam, struct mem_buffer *buf, int *q, int depth);
+void sam_io_sam_info_2(char *desc,  SAM_INFO_2 *sam, prs_struct *ps);
 void make_sam_info_1(SAM_INFO_1 *sam, uint32 acb_mask,
                uint32 start_idx, uint32 num_sam_entries,
                struct smb_passwd pass[MAX_SAM_ENTRIES]);
-void sam_io_sam_info_1(char *desc, BOOL io, SAM_INFO_1 *sam, struct mem_buffer *buf, int *q, int depth);
+void sam_io_sam_info_1(char *desc,  SAM_INFO_1 *sam, prs_struct *ps);
 void make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
                uint16 switch_level, SAM_INFO_CTR *ctr, uint32 status);
-void samr_io_r_query_dispinfo(char *desc, BOOL io, SAMR_R_QUERY_DISPINFO *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_r_query_dispinfo(char *desc,  SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps);
 void make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol,
                                uint16 switch_level, uint32 start_idx, uint32 size);
-void samr_io_q_enum_dom_groups(char *desc, BOOL io, SAMR_Q_ENUM_DOM_GROUPS *q_e, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_enum_dom_groups(char *desc,  SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps);
 void make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u,
                uint32 start_idx, uint32 num_sam_entries,
                struct smb_passwd pass[MAX_SAM_ENTRIES],
                uint32 status);
-void samr_io_r_enum_dom_groups(char *desc, BOOL io, SAMR_R_ENUM_DOM_GROUPS *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_r_enum_dom_groups(char *desc,  SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps);
 void make_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_e,
                                POLICY_HND *pol,
                                uint16 switch_level);
-void samr_io_q_query_aliasinfo(char *desc, BOOL io, SAMR_Q_QUERY_ALIASINFO *q_e, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_query_aliasinfo(char *desc,  SAMR_Q_QUERY_ALIASINFO *q_e, prs_struct *ps);
 void make_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO *r_u,
                uint16 switch_value, char *acct_desc,
                uint32 status);
-void samr_io_r_query_aliasinfo(char *desc, BOOL io, SAMR_R_QUERY_ALIASINFO *r_u, struct mem_buffer *buf, int *q, int depth);
-void samr_io_q_lookup_ids(char *desc, BOOL io, SAMR_Q_LOOKUP_IDS *q_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_r_query_aliasinfo(char *desc,  SAMR_R_QUERY_ALIASINFO *r_u, prs_struct *ps);
+void samr_io_q_lookup_ids(char *desc,  SAMR_Q_LOOKUP_IDS *q_u, prs_struct *ps);
 void make_samr_r_lookup_ids(SAMR_R_LOOKUP_IDS *r_u,
                uint32 num_rids, uint32 *rid, uint32 status);
-void samr_io_r_lookup_ids(char *desc, BOOL io, SAMR_R_LOOKUP_IDS *r_u, struct mem_buffer *buf, int *q, int depth);
-void samr_io_q_lookup_names(char *desc, BOOL io, SAMR_Q_LOOKUP_NAMES *q_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_r_lookup_ids(char *desc,  SAMR_R_LOOKUP_IDS *r_u, prs_struct *ps);
+void samr_io_q_lookup_names(char *desc,  SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps);
 void make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
                uint32 num_rids, uint32 *rid, uint32 status);
-void samr_io_r_lookup_names(char *desc, BOOL io, SAMR_R_LOOKUP_NAMES *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_r_lookup_names(char *desc,  SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps);
 void make_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
                POLICY_HND *pol, uint32 rid,
                uint32 num_gids, uint32 *gid);
-void samr_io_q_unknown_12(char *desc, BOOL io, SAMR_Q_UNKNOWN_12 *q_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_unknown_12(char *desc,  SAMR_Q_UNKNOWN_12 *q_u, prs_struct *ps);
 void make_samr_r_unknown_12(SAMR_R_UNKNOWN_12 *r_u,
                uint32 num_aliases, fstring *als_name, uint32 *num_als_usrs,
                uint32 status);
-void samr_io_r_unknown_12(char *desc, BOOL io, SAMR_R_UNKNOWN_12 *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_r_unknown_12(char *desc,  SAMR_R_UNKNOWN_12 *r_u, prs_struct *ps);
 void make_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
                                POLICY_HND *pol,
                                uint32 unk_0, uint32 rid);
-void samr_io_q_open_user(char *desc, BOOL io, SAMR_Q_OPEN_USER *q_u, struct mem_buffer *buf, int *q, int depth);
-void samr_io_r_open_user(char *desc, BOOL io, SAMR_R_OPEN_USER *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_open_user(char *desc,  SAMR_Q_OPEN_USER *q_u, prs_struct *ps);
+void samr_io_r_open_user(char *desc,  SAMR_R_OPEN_USER *r_u, prs_struct *ps);
 void make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
                                POLICY_HND *hnd);
-void samr_io_q_query_usergroups(char *desc, BOOL io, SAMR_Q_QUERY_USERGROUPS *q_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_query_usergroups(char *desc,  SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps);
 void make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u,
                uint32 num_gids, DOM_GID *gid, uint32 status);
-void samr_io_r_query_usergroups(char *desc, BOOL io, SAMR_R_QUERY_USERGROUPS *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_r_query_usergroups(char *desc,  SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps);
 void make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
                                POLICY_HND *hnd, uint16 switch_value);
-void samr_io_q_query_userinfo(char *desc, BOOL io, SAMR_Q_QUERY_USERINFO *q_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_query_userinfo(char *desc,  SAMR_Q_QUERY_USERINFO *q_u, prs_struct *ps);
 void make_sam_user_info11(SAM_USER_INFO_11 *usr,
                                NTTIME *expiry,
                                char *mach_acct,
                                uint32 rid_user,
                                uint32 rid_group,
                                uint16 acct_ctrl);
-void sam_io_user_info11(char *desc, BOOL io, SAM_USER_INFO_11 *usr, struct mem_buffer *buf, int *q, int depth);
+void sam_io_user_info11(char *desc,  SAM_USER_INFO_11 *usr, prs_struct *ps);
 void make_sam_user_info15(SAM_USER_INFO_15 *usr,
 
        NTTIME *logon_time,
@@ -1585,246 +1594,245 @@ void make_sam_user_info15(SAM_USER_INFO_15 *usr,
        LOGON_HRS *hrs,
        uint32 unknown_5,
        uint32 unknown_6);
-void sam_io_user_info15(char *desc, BOOL io, SAM_USER_INFO_15 *usr, struct mem_buffer *buf, int *q, int depth);
+void sam_io_user_info15(char *desc,  SAM_USER_INFO_15 *usr, prs_struct *ps);
 void make_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
                                uint16 switch_value, void *info, uint32 status);
-void samr_io_r_query_userinfo(char *desc, BOOL io, SAMR_R_QUERY_USERINFO *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_r_query_userinfo(char *desc,  SAMR_R_QUERY_USERINFO *r_u, prs_struct *ps);
 void make_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c,
                                POLICY_HND *hnd, uint16 unk_1, uint16 unk_2);
-void samr_io_q_unknown_21(char *desc, BOOL io, SAMR_Q_UNKNOWN_21 *q_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_unknown_21(char *desc,  SAMR_Q_UNKNOWN_21 *q_u, prs_struct *ps);
 void make_samr_q_unknown_13(SAMR_Q_UNKNOWN_13 *q_c,
                                POLICY_HND *hnd, uint16 unk_1, uint16 unk_2);
-void samr_io_q_unknown_13(char *desc, BOOL io, SAMR_Q_UNKNOWN_13 *q_u, struct mem_buffer *buf, int *q, int depth);
-void samr_io_q_unknown_32(char *desc, BOOL io, SAMR_Q_UNKNOWN_32 *q_u, struct mem_buffer *buf, int *q, int depth);
-void samr_io_r_unknown_32(char *desc, BOOL io, SAMR_R_UNKNOWN_32 *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_unknown_13(char *desc,  SAMR_Q_UNKNOWN_13 *q_u, prs_struct *ps);
+void samr_io_q_unknown_32(char *desc,  SAMR_Q_UNKNOWN_32 *q_u, prs_struct *ps);
+void samr_io_r_unknown_32(char *desc,  SAMR_R_UNKNOWN_32 *r_u, prs_struct *ps);
 void make_samr_q_connect(SAMR_Q_CONNECT *q_u,
                                char *srv_name, uint32 unknown_0);
-void samr_io_q_connect(char *desc, BOOL io, SAMR_Q_CONNECT *q_u, struct mem_buffer *buf, int *q, int depth);
-void samr_io_r_connect(char *desc, BOOL io, SAMR_R_CONNECT *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_connect(char *desc,  SAMR_Q_CONNECT *q_u, prs_struct *ps);
+void samr_io_r_connect(char *desc,  SAMR_R_CONNECT *r_u, prs_struct *ps);
 void make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
                                uint32 unknown_0, uint32 rid);
-void samr_io_q_open_alias(char *desc, BOOL io, SAMR_Q_OPEN_ALIAS *q_u, struct mem_buffer *buf, int *q, int depth);
-void samr_io_r_open_alias(char *desc, BOOL io, SAMR_R_OPEN_ALIAS *r_u, struct mem_buffer *buf, int *q, int depth);
+void samr_io_q_open_alias(char *desc,  SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps);
+void samr_io_r_open_alias(char *desc,  SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps);
 
 /*The following definitions come from  rpc_pipes/smbparse.c  */
 
-void smb_io_utime(char *desc, BOOL io, UTIME *t, struct mem_buffer *buf, int *q, int depth);
-void smb_io_time(char *desc, BOOL io, NTTIME *nttime, struct mem_buffer *buf, int *q, int depth);
+void smb_io_utime(char *desc,  UTIME *t, prs_struct *ps);
+void smb_io_time(char *desc,  NTTIME *nttime, prs_struct *ps);
 uint32 get_enum_hnd(ENUM_HND *enh);
 void make_enum_hnd(ENUM_HND *enh, uint32 hnd);
-void smb_io_enum_hnd(char *desc, BOOL io, ENUM_HND *hnd, struct mem_buffer *buf, int *q, int depth);
+void smb_io_enum_hnd(char *desc,  ENUM_HND *hnd, prs_struct *ps);
 void make_dom_sid(DOM_SID *sid, char *str_sid);
-void smb_io_dom_sid(char *desc, BOOL io, DOM_SID *sid, struct mem_buffer *buf, int *q, int depth);
+void smb_io_dom_sid(char *desc,  DOM_SID *sid, prs_struct *ps);
 void make_dom_sid2(DOM_SID2 *sid, char *str_sid);
-void smb_io_dom_sid2(char *desc, BOOL io, DOM_SID2 *sid, struct mem_buffer *buf, int *q, int depth);
+void smb_io_dom_sid2(char *desc,  DOM_SID2 *sid, prs_struct *ps);
 void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint32 buffer);
-void smb_io_unihdr(char *desc, BOOL io, UNIHDR *hdr, struct mem_buffer *buf, int *q, int depth);
+void smb_io_unihdr(char *desc,  UNIHDR *hdr, prs_struct *ps);
 void make_uni_hdr2(UNIHDR2 *hdr, int max_len, int len, uint16 terminate);
-void smb_io_unihdr2(char *desc, BOOL io, UNIHDR2 *hdr2, struct mem_buffer *buf, int *q, int depth);
+void smb_io_unihdr2(char *desc,  UNIHDR2 *hdr2, prs_struct *ps);
 void make_unistr(UNISTR *str, char *buf);
-void smb_io_unistr(char *desc, BOOL io, UNISTR *uni, struct mem_buffer *buf, int *q, int depth);
+void smb_io_unistr(char *desc,  UNISTR *uni, prs_struct *ps);
 void make_uninotstr2(UNINOTSTR2 *str, char *buf, int len);
-void smb_io_uninotstr2(char *desc, BOOL io, UNINOTSTR2 *uni2, uint32 buffer, struct mem_buffer *buf, int *q, int depth);
+void smb_io_uninotstr2(char *desc,  UNINOTSTR2 *uni2, uint32 buffer, prs_struct *ps);
 void make_buf_unistr2(UNISTR2 *str, uint32 *ptr, char *buf);
 void make_unistr2(UNISTR2 *str, char *buf, int len);
-void smb_io_unistr2(char *desc, BOOL io, UNISTR2 *uni2, uint32 buffer, struct mem_buffer *buf, int *q, int depth);
+void smb_io_unistr2(char *desc,  UNISTR2 *uni2, uint32 buffer, prs_struct *ps);
 void make_dom_str_sid(DOM_STR_SID *sid, char *sid_str);
-void smb_io_dom_str_sid(char *desc, BOOL io, DOM_STR_SID *sid, struct mem_buffer *buf, int *q, int depth);
+void smb_io_dom_str_sid(char *desc,  DOM_STR_SID *sid, prs_struct *ps);
 void make_dom_rid2(DOM_RID2 *rid2, uint32 rid);
-void smb_io_dom_rid2(char *desc, BOOL io, DOM_RID2 *rid2, struct mem_buffer *buf, int *q, int depth);
+void smb_io_dom_rid2(char *desc,  DOM_RID2 *rid2, prs_struct *ps);
 void make_dom_rid3(DOM_RID3 *rid3, uint32 rid);
-void smb_io_dom_rid3(char *desc, BOOL io, DOM_RID3 *rid3, struct mem_buffer *buf, int *q, int depth);
+void smb_io_dom_rid3(char *desc,  DOM_RID3 *rid3, prs_struct *ps);
 void make_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid);
-void smb_io_dom_rid4(char *desc, BOOL io, DOM_RID4 *rid4, struct mem_buffer *buf, int *q, int depth);
+void smb_io_dom_rid4(char *desc,  DOM_RID4 *rid4, prs_struct *ps);
 void make_sam_str1(SAM_STR1 *sam, char *sam_acct, char *sam_name, char *sam_desc);
-void smb_io_sam_str1(char *desc, BOOL io, SAM_STR1 *sam, uint32 acct_buf, uint32 name_buf, uint32 desc_buf, struct mem_buffer *buf, int *q, int depth);
+void smb_io_sam_str1(char *desc,  SAM_STR1 *sam, uint32 acct_buf, uint32 name_buf, uint32 desc_buf, prs_struct *ps);
 void make_sam_entry1(SAM_ENTRY1 *sam, uint32 user_idx, struct smb_passwd *pass,
                                char *sam_full, char *sam_desc);
-void smb_io_sam_entry1(char *desc, BOOL io, SAM_ENTRY1 *sam, struct mem_buffer *buf, int *q, int depth);
+void smb_io_sam_entry1(char *desc,  SAM_ENTRY1 *sam, prs_struct *ps);
 void make_sam_str2(SAM_STR2 *sam, char *sam_acct, char *sam_desc);
-void smb_io_sam_str2(char *desc, BOOL io, SAM_STR2 *sam, uint32 acct_buf, uint32 desc_buf, struct mem_buffer *buf, int *q, int depth);
+void smb_io_sam_str2(char *desc,  SAM_STR2 *sam, uint32 acct_buf, uint32 desc_buf, prs_struct *ps);
 void make_sam_entry2(SAM_ENTRY2 *sam, uint32 user_idx, struct smb_passwd *pass,
                                char *sam_desc);
-void smb_io_sam_entry2(char *desc, BOOL io, SAM_ENTRY2 *sam, struct mem_buffer *buf, int *q, int depth);
+void smb_io_sam_entry2(char *desc,  SAM_ENTRY2 *sam, prs_struct *ps);
 void make_sam_str3(SAM_STR3 *sam, char *grp_acct, char *grp_desc);
-void smb_io_sam_str3(char *desc, BOOL io, SAM_STR3 *sam, uint32 acct_buf, uint32 desc_buf, struct mem_buffer *buf, int *q, int depth);
+void smb_io_sam_str3(char *desc,  SAM_STR3 *sam, uint32 acct_buf, uint32 desc_buf, prs_struct *ps);
 void make_sam_entry3(SAM_ENTRY3 *sam, uint32 grp_idx, struct smb_passwd *pass,
                                char *grp_desc);
-void smb_io_sam_entry3(char *desc, BOOL io, SAM_ENTRY3 *sam, struct mem_buffer *buf, int *q, int depth);
+void smb_io_sam_entry3(char *desc,  SAM_ENTRY3 *sam, prs_struct *ps);
 void make_sam_entry(SAM_ENTRY *sam, char *sam_name, uint32 rid);
-void smb_io_sam_entry(char *desc, BOOL io, SAM_ENTRY *sam, struct mem_buffer *buf, int *q, int depth);
+void smb_io_sam_entry(char *desc,  SAM_ENTRY *sam, prs_struct *ps);
 void make_clnt_srv(DOM_CLNT_SRV *log, char *logon_srv, char *comp_name);
-void smb_io_clnt_srv(char *desc, BOOL io, DOM_CLNT_SRV *log, struct mem_buffer *buf, int *q, int depth);
+void smb_io_clnt_srv(char *desc,  DOM_CLNT_SRV *log, prs_struct *ps);
 void make_log_info(DOM_LOG_INFO *log, char *logon_srv, char *acct_name,
                uint16 sec_chan, char *comp_name);
-void smb_io_log_info(char *desc, BOOL io, DOM_LOG_INFO *log, struct mem_buffer *buf, int *q, int depth);
-void smb_io_chal(char *desc, BOOL io, DOM_CHAL *chal, struct mem_buffer *buf, int *q, int depth);
-void smb_io_cred(char *desc, BOOL io, DOM_CRED *cred, struct mem_buffer *buf, int *q, int depth);
+void smb_io_log_info(char *desc,  DOM_LOG_INFO *log, prs_struct *ps);
+void smb_io_chal(char *desc,  DOM_CHAL *chal, prs_struct *ps);
+void smb_io_cred(char *desc,  DOM_CRED *cred, prs_struct *ps);
 void make_clnt_info2(DOM_CLNT_INFO2 *clnt,
                                char *logon_srv, char *comp_name,
                                DOM_CRED *clnt_cred);
-void smb_io_clnt_info2(char *desc, BOOL io, DOM_CLNT_INFO2 *clnt, struct mem_buffer *buf, int *q, int depth);
+void smb_io_clnt_info2(char *desc,  DOM_CLNT_INFO2 *clnt, prs_struct *ps);
 void make_clnt_info(DOM_CLNT_INFO *clnt,
                char *logon_srv, char *acct_name,
                uint16 sec_chan, char *comp_name,
                                DOM_CRED *cred);
-void smb_io_clnt_info(char *desc, BOOL io, DOM_CLNT_INFO *clnt, struct mem_buffer *buf, int *q, int depth);
+void smb_io_clnt_info(char *desc,  DOM_CLNT_INFO *clnt, prs_struct *ps);
 void make_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high);
-void smb_io_logon_id(char *desc, BOOL io, DOM_LOGON_ID *log, struct mem_buffer *buf, int *q, int depth);
+void smb_io_logon_id(char *desc,  DOM_LOGON_ID *log, prs_struct *ps);
 void make_arc4_owf(ARC4_OWF *hash, uint8 data[16]);
-void smb_io_arc4_owf(char *desc, BOOL io, ARC4_OWF *hash, struct mem_buffer *buf, int *q, int depth);
+void smb_io_arc4_owf(char *desc,  ARC4_OWF *hash, prs_struct *ps);
 void make_id_info1(DOM_ID_INFO_1 *id, char *domain_name,
                                uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
                                char *user_name, char *wksta_name,
                                char sess_key[16],
                                unsigned char lm_cypher[16], unsigned char nt_cypher[16]);
-void smb_io_id_info1(char *desc, BOOL io, DOM_ID_INFO_1 *id, struct mem_buffer *buf, int *q, int depth);
+void smb_io_id_info1(char *desc,  DOM_ID_INFO_1 *id, prs_struct *ps);
 void make_sam_info(DOM_SAM_INFO *sam,
                                char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
                                DOM_CRED *rtn_cred, uint16 logon_level, uint16 switch_value,
                                DOM_ID_INFO_1 *id1, uint16 switch_value2);
-void smb_io_sam_info(char *desc, BOOL io, DOM_SAM_INFO *sam, struct mem_buffer *buf, int *q, int depth);
-void smb_io_gid(char *desc, BOOL io, DOM_GID *gid, struct mem_buffer *buf, int *q, int depth);
+void smb_io_sam_info(char *desc,  DOM_SAM_INFO *sam, prs_struct *ps);
+void smb_io_gid(char *desc,  DOM_GID *gid, prs_struct *ps);
 void make_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
                                uint32 call_id, int data_len);
-void smb_io_rpc_hdr(char *desc, BOOL io, RPC_HDR *rpc, struct mem_buffer *buf, int *q, int depth);
+void smb_io_rpc_hdr(char *desc,  RPC_HDR *rpc, prs_struct *ps);
 void make_rpc_iface(RPC_IFACE *ifc, char data[16], uint32 version);
-void smb_io_rpc_iface(char *desc, BOOL io, RPC_IFACE *ifc, struct mem_buffer *buf, int *q, int depth);
+void smb_io_rpc_iface(char *desc,  RPC_IFACE *ifc, prs_struct *ps);
 void make_rpc_addr_str(RPC_ADDR_STR *str, char *name);
-void smb_io_rpc_addr_str(char *desc, BOOL io, RPC_ADDR_STR *str, struct mem_buffer *buf, int *q, int depth);
+void smb_io_rpc_addr_str(char *desc,  RPC_ADDR_STR *str, prs_struct *ps);
 void make_rpc_hdr_bba(RPC_HDR_BBA *bba, uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid);
-void smb_io_rpc_hdr_bba(char *desc, BOOL io, RPC_HDR_BBA *rpc, struct mem_buffer *buf, int *q, int depth);
+void smb_io_rpc_hdr_bba(char *desc,  RPC_HDR_BBA *rpc, prs_struct *ps);
 void make_rpc_hdr_rb(RPC_HDR_RB *rpc, 
                                uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
                                uint32 num_elements, uint16 context_id, uint8 num_syntaxes,
                                RPC_IFACE *abstract, RPC_IFACE *transfer);
-void smb_io_rpc_hdr_rb(char *desc, BOOL io, RPC_HDR_RB *rpc, struct mem_buffer *buf, int *q, int depth);
+void smb_io_rpc_hdr_rb(char *desc,  RPC_HDR_RB *rpc, prs_struct *ps);
 void make_rpc_results(RPC_RESULTS *res, 
                                uint8 num_results, uint16 result, uint16 reason);
-void smb_io_rpc_results(char *desc, BOOL io, RPC_RESULTS *res, struct mem_buffer *buf, int *q, int depth);
+void smb_io_rpc_results(char *desc,  RPC_RESULTS *res, prs_struct *ps);
 void make_rpc_hdr_ba(RPC_HDR_BA *rpc, 
                                uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
                                char *pipe_addr,
                                uint8 num_results, uint16 result, uint16 reason,
                                RPC_IFACE *transfer);
-void smb_io_rpc_hdr_ba(char *desc, BOOL io, RPC_HDR_BA *rpc, struct mem_buffer *buf, int *q, int depth);
-void make_rpc_hdr_rr(RPC_HDR_RR *hdr, enum RPC_PKT_TYPE pkt_type,
-                               uint32 call_id, int data_len, uint8 opnum);
-void smb_io_rpc_hdr_rr(char *desc, BOOL io, RPC_HDR_RR *rpc, struct mem_buffer *buf, int *q, int depth);
-void smb_io_pol_hnd(char *desc, BOOL io, POLICY_HND *pol, struct mem_buffer *buf, int *q, int depth);
-void smb_io_dom_query_3(char *desc, BOOL io, DOM_QUERY_3 *d_q, struct mem_buffer *buf, int *q, int depth);
-void smb_io_dom_query_5(char *desc, BOOL io, DOM_QUERY_3 *d_q, struct mem_buffer *buf, int *q, int depth);
-void smb_io_dom_query(char *desc, BOOL io, DOM_QUERY *d_q, struct mem_buffer *buf, int *q, int depth);
-void smb_io_dom_r_ref(char *desc, BOOL io, DOM_R_REF *r_r, struct mem_buffer *buf, int *q, int depth);
-void smb_io_dom_name(char *desc, BOOL io, DOM_NAME *name, struct mem_buffer *buf, int *q, int depth);
-void smb_io_neg_flags(char *desc, BOOL io, NEG_FLAGS *neg, struct mem_buffer *buf, int *q, int depth);
+void smb_io_rpc_hdr_ba(char *desc,  RPC_HDR_BA *rpc, prs_struct *ps);
+void make_rpc_hdr_rr(RPC_HDR_RR *hdr, uint32 data_len, uint8 opnum);
+void smb_io_rpc_hdr_rr(char *desc,  RPC_HDR_RR *rpc, prs_struct *ps);
+void smb_io_pol_hnd(char *desc,  POLICY_HND *pol, prs_struct *ps);
+void smb_io_dom_query_3(char *desc,  DOM_QUERY_3 *d_q, prs_struct *ps);
+void smb_io_dom_query_5(char *desc,  DOM_QUERY_3 *d_q, prs_struct *ps);
+void smb_io_dom_query(char *desc,  DOM_QUERY *d_q, prs_struct *ps);
+void smb_io_dom_r_ref(char *desc,  DOM_R_REF *r_r, prs_struct *ps);
+void smb_io_dom_name(char *desc,  DOM_NAME *name, prs_struct *ps);
+void smb_io_neg_flags(char *desc,  NEG_FLAGS *neg, prs_struct *ps);
 void make_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts);
-void smb_io_netinfo_3(char *desc, BOOL io, NETLOGON_INFO_3 *info, struct mem_buffer *buf, int *q, int depth);
+void smb_io_netinfo_3(char *desc,  NETLOGON_INFO_3 *info, prs_struct *ps);
 void make_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status);
-void smb_io_netinfo_1(char *desc, BOOL io, NETLOGON_INFO_1 *info, struct mem_buffer *buf, int *q, int depth);
+void smb_io_netinfo_1(char *desc,  NETLOGON_INFO_1 *info, prs_struct *ps);
 void make_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
                                uint32 tc_status, char *trusted_dc_name);
-void smb_io_netinfo_2(char *desc, BOOL io, NETLOGON_INFO_2 *info, struct mem_buffer *buf, int *q, int depth);
-void smb_io_logon_hrs(char *desc, BOOL io, LOGON_HRS *hrs, struct mem_buffer *buf, int *q, int depth);
+void smb_io_netinfo_2(char *desc,  NETLOGON_INFO_2 *info, prs_struct *ps);
+void smb_io_logon_hrs(char *desc,  LOGON_HRS *hrs, prs_struct *ps);
 
 /*The following definitions come from  rpc_pipes/srvparse.c  */
 
 void make_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark);
-void srv_io_share_info1_str(char *desc, BOOL io, SH_INFO_1_STR *sh1, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_share_info1_str(char *desc,  SH_INFO_1_STR *sh1, prs_struct *ps);
 void make_srv_share_info1(SH_INFO_1 *sh1, char *net_name, uint32 type, char *remark);
-void srv_io_share_info1(char *desc, BOOL io, SH_INFO_1 *sh1, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_srv_share_info_1(char *desc, BOOL io, SRV_SHARE_INFO_1 *ctr, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_srv_share_ctr(char *desc, BOOL io, SRV_SHARE_INFO_CTR *ctr, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_share_info1(char *desc,  SH_INFO_1 *sh1, prs_struct *ps);
+void srv_io_srv_share_info_1(char *desc,  SRV_SHARE_INFO_1 *ctr, prs_struct *ps);
+void srv_io_srv_share_ctr(char *desc,  SRV_SHARE_INFO_CTR *ctr, prs_struct *ps);
 void make_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n, 
                                char *srv_name, 
                                uint32 share_level, SRV_SHARE_INFO_CTR *ctr,
                                uint32 preferred_len,
                                ENUM_HND *hnd);
-void srv_io_q_net_share_enum(char *desc, BOOL io, SRV_Q_NET_SHARE_ENUM *q_n, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_r_net_share_enum(char *desc, BOOL io, SRV_R_NET_SHARE_ENUM *r_n, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_q_net_share_enum(char *desc,  SRV_Q_NET_SHARE_ENUM *q_n, prs_struct *ps);
+void srv_io_r_net_share_enum(char *desc,  SRV_R_NET_SHARE_ENUM *r_n, prs_struct *ps);
 void make_srv_sess_info0_str(SESS_INFO_0_STR *ss0, char *name);
-void srv_io_sess_info0_str(char *desc, BOOL io, SESS_INFO_0_STR *ss0, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_sess_info0_str(char *desc,  SESS_INFO_0_STR *ss0, prs_struct *ps);
 void make_srv_sess_info0(SESS_INFO_0 *ss0, char *name);
-void srv_io_sess_info0(char *desc, BOOL io, SESS_INFO_0 *ss0, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_srv_sess_info_0(char *desc, BOOL io, SRV_SESS_INFO_0 *ss0, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_sess_info0(char *desc,  SESS_INFO_0 *ss0, prs_struct *ps);
+void srv_io_srv_sess_info_0(char *desc,  SRV_SESS_INFO_0 *ss0, prs_struct *ps);
 void make_srv_sess_info1_str(SESS_INFO_1_STR *ss1, char *name, char *user);
-void srv_io_sess_info1_str(char *desc, BOOL io, SESS_INFO_1_STR *ss1, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_sess_info1_str(char *desc,  SESS_INFO_1_STR *ss1, prs_struct *ps);
 void make_srv_sess_info1(SESS_INFO_1 *ss1, 
                                char *name, char *user,
                                uint32 num_opens, uint32 open_time, uint32 idle_time,
                                uint32 user_flags);
-void srv_io_sess_info1(char *desc, BOOL io, SESS_INFO_1 *ss1, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_srv_sess_info_1(char *desc, BOOL io, SRV_SESS_INFO_1 *ss1, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_srv_sess_ctr(char *desc, BOOL io, SRV_SESS_INFO_CTR *ctr, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_sess_info1(char *desc,  SESS_INFO_1 *ss1, prs_struct *ps);
+void srv_io_srv_sess_info_1(char *desc,  SRV_SESS_INFO_1 *ss1, prs_struct *ps);
+void srv_io_srv_sess_ctr(char *desc,  SRV_SESS_INFO_CTR *ctr, prs_struct *ps);
 void make_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n, 
                                char *srv_name, char *qual_name,
                                uint32 sess_level, SRV_SESS_INFO_CTR *ctr,
                                uint32 preferred_len,
                                ENUM_HND *hnd);
-void srv_io_q_net_sess_enum(char *desc, BOOL io, SRV_Q_NET_SESS_ENUM *q_n, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_r_net_sess_enum(char *desc, BOOL io, SRV_R_NET_SESS_ENUM *r_n, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_q_net_sess_enum(char *desc,  SRV_Q_NET_SESS_ENUM *q_n, prs_struct *ps);
+void srv_io_r_net_sess_enum(char *desc,  SRV_R_NET_SESS_ENUM *r_n, prs_struct *ps);
 void make_srv_conn_info0(CONN_INFO_0 *ss0, uint32 id);
-void srv_io_conn_info0(char *desc, BOOL io, CONN_INFO_0 *ss0, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_srv_conn_info_0(char *desc, BOOL io, SRV_CONN_INFO_0 *ss0, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_conn_info0(char *desc,  CONN_INFO_0 *ss0, prs_struct *ps);
+void srv_io_srv_conn_info_0(char *desc,  SRV_CONN_INFO_0 *ss0, prs_struct *ps);
 void make_srv_conn_info1_str(CONN_INFO_1_STR *ss1, char *usr_name, char *net_name);
-void srv_io_conn_info1_str(char *desc, BOOL io, CONN_INFO_1_STR *ss1, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_conn_info1_str(char *desc,  CONN_INFO_1_STR *ss1, prs_struct *ps);
 void make_srv_conn_info1(CONN_INFO_1 *ss1, 
                                uint32 id, uint32 type,
                                uint32 num_opens, uint32 num_users, uint32 open_time,
                                char *usr_name, char *net_name);
-void srv_io_conn_info1(char *desc, BOOL io, CONN_INFO_1 *ss1, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_srv_conn_info_1(char *desc, BOOL io, SRV_CONN_INFO_1 *ss1, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_srv_conn_ctr(char *desc, BOOL io, SRV_CONN_INFO_CTR *ctr, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_conn_info1(char *desc,  CONN_INFO_1 *ss1, prs_struct *ps);
+void srv_io_srv_conn_info_1(char *desc,  SRV_CONN_INFO_1 *ss1, prs_struct *ps);
+void srv_io_srv_conn_ctr(char *desc,  SRV_CONN_INFO_CTR *ctr, prs_struct *ps);
 void make_srv_q_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n, 
                                char *srv_name, char *qual_name,
                                uint32 conn_level, SRV_CONN_INFO_CTR *ctr,
                                uint32 preferred_len,
                                ENUM_HND *hnd);
-void srv_io_q_net_conn_enum(char *desc, BOOL io, SRV_Q_NET_CONN_ENUM *q_n, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_r_net_conn_enum(char *desc, BOOL io, SRV_R_NET_CONN_ENUM *r_n, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_q_net_conn_enum(char *desc,  SRV_Q_NET_CONN_ENUM *q_n, prs_struct *ps);
+void srv_io_r_net_conn_enum(char *desc,  SRV_R_NET_CONN_ENUM *r_n, prs_struct *ps);
 void make_srv_file_info3_str(FILE_INFO_3_STR *fi3, char *user_name, char *path_name);
-void srv_io_file_info3_str(char *desc, BOOL io, FILE_INFO_3_STR *sh1, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_file_info3_str(char *desc,  FILE_INFO_3_STR *sh1, prs_struct *ps);
 void make_srv_file_info3(FILE_INFO_3 *fl3,
                                uint32 id, uint32 perms, uint32 num_locks,
                                char *path_name, char *user_name);
-void srv_io_file_info3(char *desc, BOOL io, FILE_INFO_3 *fl3, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_srv_file_info_3(char *desc, BOOL io, SRV_FILE_INFO_3 *fl3, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_srv_file_ctr(char *desc, BOOL io, SRV_FILE_INFO_CTR *ctr, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_file_info3(char *desc,  FILE_INFO_3 *fl3, prs_struct *ps);
+void srv_io_srv_file_info_3(char *desc,  SRV_FILE_INFO_3 *fl3, prs_struct *ps);
+void srv_io_srv_file_ctr(char *desc,  SRV_FILE_INFO_CTR *ctr, prs_struct *ps);
 void make_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n, 
                                char *srv_name, char *qual_name,
                                uint32 file_level, SRV_FILE_INFO_CTR *ctr,
                                uint32 preferred_len,
                                ENUM_HND *hnd);
-void srv_io_q_net_file_enum(char *desc, BOOL io, SRV_Q_NET_FILE_ENUM *q_n, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_r_net_file_enum(char *desc, BOOL io, SRV_R_NET_FILE_ENUM *r_n, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_q_net_file_enum(char *desc,  SRV_Q_NET_FILE_ENUM *q_n, prs_struct *ps);
+void srv_io_r_net_file_enum(char *desc,  SRV_R_NET_FILE_ENUM *r_n, prs_struct *ps);
 void make_srv_info_101(SRV_INFO_101 *sv101, uint32 platform_id, char *name,
                                uint32 ver_major, uint32 ver_minor,
                                uint32 srv_type, char *comment);
-void srv_io_info_101(char *desc, BOOL io, SRV_INFO_101 *sv101, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_info_101(char *desc,  SRV_INFO_101 *sv101, prs_struct *ps);
 void make_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, char *name,
                                char *comment, uint32 ver_major, uint32 ver_minor,
                                uint32 srv_type, uint32 users, uint32 disc, uint32 hidden,
                                uint32 announce, uint32 ann_delta, uint32 licenses,
                                char *usr_path);
-void srv_io_info_102(char *desc, BOOL io, SRV_INFO_102 *sv102, struct mem_buffer *buf, int *q,  int depth);
-void srv_io_info_ctr(char *desc, BOOL io, SRV_INFO_CTR *ctr, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_info_102(char *desc,  SRV_INFO_102 *sv102, prs_struct *ps);
+void srv_io_info_ctr(char *desc,  SRV_INFO_CTR *ctr, prs_struct *ps);
 void make_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv,
                                char *server_name, uint32 switch_value);
-void srv_io_q_net_srv_get_info(char *desc, BOOL io, SRV_Q_NET_SRV_GET_INFO *q_n, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_q_net_srv_get_info(char *desc,  SRV_Q_NET_SRV_GET_INFO *q_n, prs_struct *ps);
 void make_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv,
                                uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status);
-void srv_io_r_net_srv_get_info(char *desc, BOOL io, SRV_R_NET_SRV_GET_INFO *r_n, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_r_net_srv_get_info(char *desc,  SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps);
 void make_srv_q_net_srv_set_info(SRV_Q_NET_SRV_SET_INFO *srv,
                                uint32 switch_value, SRV_INFO_CTR *ctr);
-void srv_io_q_net_srv_set_info(char *desc, BOOL io, SRV_Q_NET_SRV_SET_INFO *q_n, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_q_net_srv_set_info(char *desc,  SRV_Q_NET_SRV_SET_INFO *q_n, prs_struct *ps);
 void make_srv_r_net_srv_set_info(SRV_R_NET_SRV_SET_INFO *srv,
                                uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status);
-void srv_io_r_net_srv_set_info(char *desc, BOOL io, SRV_R_NET_SRV_SET_INFO *r_n, struct mem_buffer *buf, int *q,  int depth);
+void srv_io_r_net_srv_set_info(char *desc,  SRV_R_NET_SRV_SET_INFO *r_n, prs_struct *ps);
 
 /*The following definitions come from  rpc_pipes/wksparse.c  */
 
-void wks_io_q_unknown_0(char *desc, BOOL io, WKS_Q_UNKNOWN_0 *q_u, struct mem_buffer *buf, int *q,  int depth);
-void wks_io_r_unknown_0(char *desc, BOOL io, WKS_R_UNKNOWN_0 *r_u, struct mem_buffer *buf, int *q,  int depth);
+void wks_io_q_unknown_0(char *desc,  WKS_Q_UNKNOWN_0 *q_u, prs_struct *ps);
+void wks_io_r_unknown_0(char *desc,  WKS_R_UNKNOWN_0 *r_u, prs_struct *ps);
 
 /*The following definitions come from  server.c  */
 
index d21f5568828cabbd389a09b2d5a56bd9ce7ef3bd..89940a1f3e6d7b7b61d4b947facaa5b8f4bd7398 100644 (file)
 enum display_type   { DISPLAY_NONE, DISPLAY_TXT, DISPLAY_HTML };
 enum action_type    { ACTION_HEADER, ACTION_ENUMERATE, ACTION_FOOTER };
 
-#ifndef MAX_CONNECTIONS
-#define MAX_CONNECTIONS 127
-#endif
-
-#ifndef MAX_OPEN_FILES
-#define MAX_OPEN_FILES 50
-#endif
-
-#ifndef GUEST_ACCOUNT
-#define GUEST_ACCOUNT "nobody"
-#endif
-
 #define BUFFER_SIZE (0xFFFF)
 #define SAFETY_MARGIN 1024
 
@@ -517,6 +505,28 @@ typedef struct
   int real_open_flags;
 } file_fd_struct;
 
+struct mem_desc
+{
+       /* array memory offsets */
+       uint32 start;
+       uint32 end; 
+};
+
+struct mem_buf
+{
+       char *data;
+       uint32 data_size;
+       uint32 data_used;
+
+       uint32 margin; /* safety margin when reallocing. */
+                      /* this can be abused quite nicely */
+       uint8 align;   /* alignment of data structures (smb, dce/rpc, udp etc) */
+
+       struct mem_desc offset;
+
+       struct mem_buf *next;
+};
+
 typedef struct
 {
   int cnum;
@@ -539,28 +549,47 @@ typedef struct
   BOOL granted_oplock;
   BOOL sent_oplock_break;
   char *name;
+
 } files_struct;
 
-struct mem_buf
+typedef struct
 {
-       char *data;
-       uint32 data_size;
-       uint32 data_used;
+       struct mem_buf *data; /* memory buffer */
+       uint32 offset; /* offset currently being accessed in memory buffer */
+       uint8 align; /* data alignment */
+       BOOL io; /* parsing in or out of data stream */
+       int depth; /* debug level depth */
 
-       uint32 margin; /* safety margin when reallocing. */
-                           /* this can be abused quite nicely */
+} prs_struct;
 
-       uint8 align; /* alignment of data structures (smb, dce/rpc, udp etc) */
-       uint32 start_offset; /* when used with mem_array, this can be non-zero */
-};
+typedef struct
+{
+       int cnum;
+       int uid;
+       BOOL open; /* open connection */
+       uint16 device_state;
+       fstring name;
+       fstring pipe_srv_name;
+
+       /* output header */
+       prs_struct rhdr;
+
+       /* output data */
+       prs_struct rdata;
+
+       RPC_HDR     hdr;
+       RPC_HDR_BA  hdr_ba;
+       RPC_HDR_RB  hdr_rb;
+       RPC_HDR_RR  hdr_rr;
+
+} pipes_struct;
 
-#define mem_buffer mem_buf /* for now... */
 
 struct api_struct
 {
   char *name;
   uint8 opnum;
-  void (*fn) (int uid, struct mem_buf*, int*, struct mem_buf*, int*);
+  void (*fn) (int uid, prs_struct*, prs_struct*);
 };
 
 struct uid_cache {
index 41bc61f44290377de77ea4908dde396e4cd67cf6..674c3f114415a4d3177be6211cb64ddfc0b0d47c 100644 (file)
@@ -132,6 +132,8 @@ static void add_dos_char(int lower, BOOL map_lower_to_upper,
          map_upper_to_lower ? "True" : "False"));
   if (lower) dos_char_map[lower] = 1;
   if (upper) dos_char_map[upper] = 1;
+  lower_char_map[lower] = (char)lower; /* Define tolower(lower) */
+  upper_char_map[upper] = (char)upper; /* Define toupper(upper) */
   if (lower && upper) {
     if(map_upper_to_lower)
     lower_char_map[upper] = (char)lower;
@@ -165,8 +167,13 @@ void charset_initialise(void)
   for (i=0; i<=255; i++) {
     char c = (char)i;
     upper_char_map[i] = lower_char_map[i] = c;
+
+    /* Some systems have buggy isupper/islower for characters
+       above 127. Best not to rely on them. */
+    if(i < 128) {
     if (isupper(c)) lower_char_map[i] = tolower(c);
     if (islower(c)) upper_char_map[i] = toupper(c);
+    }
   }
 }
 
index b99ecc81b46bb284cdb7d130aede714bbb2355e7..6e9a04e4c748507a14c7cc16f529d7582b3c8524 100644 (file)
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+/*******************************************************************
+ *
+ * Description: memory buffer / stream management.
+ * Author     : Luke K C Leighton
+ * Created    : Dec 1997
+ *
+
+ * this module is intended for use in streaming data in and out of
+ * buffers.  it is intended that a single data stream be subdivided
+ * into manageable sections.
+
+ * for example, an rpc header contains a length field, but until the
+ * data has been created, the length is unknown.  using this module,
+ * the header section can be tacked onto the front of the data memory
+ * list once the size of the data section preceding it is known.
+ * the "margin" can be used to over-run and retrospectively lengthen
+ * the buffer.  this is to save time in some of the loops, where it is
+ * not particularly desirable to realloc data by 1, 2 or 4 bytes
+ * repetitively...
+
+ * each memory buffer contains a start and end offset.  the end of
+ * one buffer should equal to the start of the next in the chain.
+ * (end - start = len, instead of end - start + 1 = len)
+
+ * the debug log levels are very high in some of the routines: you
+ * have no idea how boring it gets staring at debug output from these
+
+ ********************************************************************/
+
+
 #include "includes.h"
 
 extern int DEBUGLEVEL;
@@ -27,42 +58,52 @@ extern int DEBUGLEVEL;
 /*******************************************************************
  initialise a memory buffer.
  ********************************************************************/
-void buf_init(struct mem_buf *buf, int align, int margin)
+void mem_init(struct mem_buf *buf, int margin)
 {
        buf->data      = NULL;
        buf->data_size = 0;
        buf->data_used = 0;
-       buf->align     = align;
+
        buf->margin    = margin;
+
+       buf->next      = NULL;
+
+       buf->offset.start = 0;
+       buf->offset.end   = 0;
 }
 
 /*******************************************************************
  initialise a memory buffer.
  ********************************************************************/
-void buf_create(struct mem_buf *buf, char *data, int size, int align, int margin)
+void mem_create(struct mem_buf *buf, char *data, int size, int margin)
 {
        buf->data      = data;
        buf->data_size = size;
        buf->data_used = size;
-       buf->align     = align;
+
        buf->margin    = margin;
+
+       buf->next      = NULL;
+
+       buf->offset.start = 0;
+       buf->offset.end   = size;
 }
 
 /*******************************************************************
  takes a memory buffer out of one structure: puts it in the other.
  NULLs the one that the buffer is being stolen from.
  ********************************************************************/
-void buf_take(struct mem_buf *buf_to, struct mem_buf *buf_from)
+void mem_take(struct mem_buf *mem_to, struct mem_buf *mem_from)
 {
-       memcpy(buf_to, buf_from, sizeof(*buf_to));
+       memcpy(mem_to, mem_from, sizeof(*mem_to));
 
-       buf_init(buf_from, buf_from->align, buf_from->margin);
+       mem_init(mem_from, mem_from->margin);
 }
 
 /*******************************************************************
  allocate a memory buffer.  assume it's empty
  ********************************************************************/
-BOOL buf_alloc(struct mem_buf *buf, int size)
+BOOL mem_alloc_data(struct mem_buf *buf, int size)
 {
        buf->data_size = size + buf->margin;
        buf->data_used = size;
@@ -71,10 +112,9 @@ BOOL buf_alloc(struct mem_buf *buf, int size)
 
        if (buf->data == NULL)
        {
-               DEBUG(3,("buf_alloc: could not malloc size %d\n",
+               DEBUG(3,("mem_alloc: could not malloc size %d\n",
                                          buf->data_size));
-               buf->data_size = 0;
-               buf->data_used = 0;
+               mem_init(buf, buf->margin);
 
                return False;
        }
@@ -84,22 +124,120 @@ BOOL buf_alloc(struct mem_buf *buf, int size)
        return True;
 }
 
+/*******************************************************************
+ allocates a memory buffer structure
+ ********************************************************************/
+BOOL mem_buf_copy(char *copy_into, struct mem_buf *buf,
+                               uint32 offset, uint32 len)
+{
+       uint32 end = offset + len;
+       char *q = NULL;
+       uint32 data_len = mem_buf_len(buf);
+       uint32 start_offset = offset;
+       struct mem_buf **bcp = &buf;
+       
+       if (buf == NULL || copy_into == NULL) return False;
+
+       DEBUG(200,("mem_buf_copy: data[%d..%d] offset %d len %d\n",
+                   buf->offset.start, data_len, offset, len));
+
+       /* there's probably an off-by-one bug, here, and i haven't even tested the code :-) */
+       while (offset < end && ((q = mem_data(bcp, offset)) != NULL))
+       {
+               uint32 copy_len = (*bcp)->offset.end - offset;
+
+               DEBUG(200,("\tdata[%d..%d] - offset %d len %d\n",
+                       (*bcp)->offset.start, (*bcp)->offset.end,
+                       offset, copy_len));
+
+               memcpy(copy_into, q, copy_len);
+       
+               offset    += copy_len;
+               copy_into += copy_len;
+       }
+
+       if ((*bcp) != NULL)
+       {
+               DEBUG(200,("mem_buf_copy: copied %d bytes\n", offset - start_offset));
+       }
+       else
+       {
+               DEBUG(200,("mem_buf_copy: failed\n"));
+       }
+
+       return buf != NULL;
+}
+
+/*******************************************************************
+ allocates a memory buffer structure
+ ********************************************************************/
+BOOL mem_buf_init(struct mem_buf **buf, uint32 margin)
+{
+       if (buf == NULL) return False;
+
+       if ((*buf) == NULL)
+       {
+               (*buf) = malloc(sizeof(**buf));
+               if ((*buf) != NULL) 
+               {
+                       mem_init((*buf), margin);
+                       return True;
+               }
+       }
+       else
+       {
+               (*buf)->margin = margin;
+               return True;
+       }
+       return False;
+}
+
+/*******************************************************************
+ frees up a memory buffer.
+ ********************************************************************/
+void mem_buf_free(struct mem_buf **buf)
+{
+       if (buf == NULL) return;
+       if ((*buf) == NULL) return;
+
+       mem_free_data(*buf);            /* delete memory data */
+       free(*buf);                     /* delete item */
+       (*buf) = NULL;
+}
+
+/*******************************************************************
+ frees a memory buffer chain.  assumes that all items are malloced.
+ ********************************************************************/
+void mem_free_chain(struct mem_buf **buf)
+{
+       if (buf == NULL) return;
+       if ((*buf) == NULL) return;
+
+       if ((*buf)->next != NULL)
+       {
+               mem_free_chain(&((*buf)->next)); /* delete all other items in chain */
+       }
+       mem_buf_free(buf);
+}
+
 /*******************************************************************
  frees a memory buffer.
  ********************************************************************/
-void buf_free(struct mem_buf *buf)
+void mem_free_data(struct mem_buf *buf)
 {
+       if (buf == NULL) return;
+
        if (buf->data != NULL)
        {
-               free(buf->data);
+               free(buf->data);     /* delete data in this structure */
        }
-       buf_init(buf, buf->align, buf->margin);
+       mem_init(buf, buf->margin);
 }
 
 /*******************************************************************
  reallocate a memory buffer, including a safety margin
  ********************************************************************/
-BOOL buf_realloc(struct mem_buf *buf, int new_size)
+BOOL mem_realloc_data(struct mem_buf *buf, int new_size)
 {
        /* hm.  maybe we want to align the data size here... */
        char *new_data = realloc(buf->data, new_size + buf->margin);
@@ -112,17 +250,17 @@ BOOL buf_realloc(struct mem_buf *buf, int new_size)
        }
        else if (buf->data_size <= new_size)
        {
-               DEBUG(3,("buf_realloc: warning - could not realloc to %d(+%d)\n",
+               DEBUG(3,("mem_realloc: warning - could not realloc to %d(+%d)\n",
                                  new_size, buf->margin));
 
                buf->data_used = new_size;
        }
        else 
        {
-               DEBUG(3,("buf_realloc: error - could not realloc to %d\n",
+               DEBUG(3,("mem_realloc: error - could not realloc to %d\n",
                                  new_size));
 
-               buf_free(buf);
+               mem_free_data(buf);
                return False;
        }
 
@@ -132,129 +270,78 @@ BOOL buf_realloc(struct mem_buf *buf, int new_size)
 /*******************************************************************
  reallocate a memory buffer, retrospectively :-)
  ********************************************************************/
-void buf_grow(struct mem_buf *buf, int new_size)
-{
-       if (new_size + buf->margin >= buf->data_size)
-       {
-               buf_realloc(buf, new_size);
-       }
-}
-
-/*******************************************************************
-align a pointer to a multiple of align_offset bytes.  looks like it
-will work for offsets of 0, 2 and 4...
-********************************************************************/
-void buf_align(struct mem_buf *buf, int *data_off)
+BOOL mem_grow_data(struct mem_buf **buf, BOOL io, int new_size)
 {
-       int mod = ((*data_off) & (buf->align-1));
-       if (buf->align != 0 && mod != 0)
+       if (new_size + (*buf)->margin >= (*buf)->data_size)
        {
-               (*data_off) += buf->align - mod;
+               if (io)
+               {
+                       return mem_realloc_data((*buf), new_size);
+               }
+               else
+               {
+                       DEBUG(3,("mem_grow_data: cannot resize when reading from a data stream\n"));
+                       return False;
+               }
        }
+       return True;
 }
 
 /*******************************************************************
- stream a uint8
+ search for a memory buffer that falls within the specified offset
  ********************************************************************/
-void buf_uint8(char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, uint8 *data)
+BOOL mem_find(struct mem_buf **buf, uint32 offset)
 {
-       char *q = &(buf->data[(*data_off)]);
-       DBG_RW_CVAL(name, depth, buf->data, io, q, *data)
-       (*data_off) += 1;
-}
+       struct mem_buf *f;
+       if (buf == NULL) return False;
 
-/*******************************************************************
- stream a uint16
- ********************************************************************/
-void buf_uint16(char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, uint16 *data)
-{
-       char *q = &(buf->data[(*data_off)]);
-       DBG_RW_SVAL(name, depth, buf->data, io, q, *data)
-       (*data_off) += 2;
-}
+       f = *buf;
 
-/*******************************************************************
- stream a uint32
- ********************************************************************/
-void buf_uint32(char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, uint32 *data)
-{
-       char *q = &(buf->data[(*data_off)]);
-       DBG_RW_IVAL(name, depth, buf->data, io, q, *data)
-       (*data_off) += 4;
-}
+       DEBUG(200,("mem_find: data[%d..%d] offset: %d\n",
+             f->offset.start, f->offset.end, offset));
 
+       while (f != NULL && offset >= f->offset.end)
+       {
+               f = f->next;
 
-/******************************************************************
- stream an array of uint8s.  length is number of uint8s
- ********************************************************************/
-void buf_uint8s(BOOL charmode, char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, uint8 *data, int len)
-{
-       char *q = &(buf->data[(*data_off)]);
-       DBG_RW_PCVAL(charmode, name, depth, buf->data, io, q, data, len)
-       (*data_off) += len;
-}
+               DEBUG(200,("mem_find: next[%d..%d]\n",
+             f->offset.start, f->offset.end));
+       }
 
-/******************************************************************
- stream an array of uint16s.  length is number of uint16s
- ********************************************************************/
-void buf_uint16s(BOOL charmode, char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, uint16 *data, int len)
-{
-       char *q = &(buf->data[(*data_off)]);
-       DBG_RW_PSVAL(charmode, name, depth, buf->data, io, q, data, len)
-       (*data_off) += len * sizeof(uint16);
-}
+       (*buf) = f;
 
-/******************************************************************
- stream an array of uint32s.  length is number of uint32s
- ********************************************************************/
-void buf_uint32s(BOOL charmode, char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, uint32 *data, int len)
-{
-       char *q = &(buf->data[(*data_off)]);
-       DBG_RW_PIVAL(charmode, name, depth, buf->data, io, q, data, len)
-       (*data_off) += len * sizeof(uint32);
-}
+       DEBUG(200,("mem_find: found data[%d..%d]\n",
+             (*buf)->offset.start,(*buf)->offset.end));
 
-/******************************************************************
- stream a "not" unicode string, length/buffer specified separately,
- in byte chars
- ********************************************************************/
-void buf_uninotstr2(BOOL charmode, char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, UNINOTSTR2 *str)
-{
-       char *q = &(buf->data[(*data_off)]);
-       DBG_RW_PSVAL(charmode, name, depth, buf->data, io, q, str->buffer, str->uni_max_len)
-       (*data_off) += str->uni_buf_len;
+       return f != NULL;
 }
 
-/******************************************************************
- stream a unicode string, length/buffer specified separately,
int uint16 chars.
+
+/*******************************************************************
add up the lengths of all sections.
  ********************************************************************/
-void buf_unistr2(BOOL charmode, char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, UNISTR2 *str)
+uint32 mem_buf_len(struct mem_buf *buf)
 {
-       char *q = &(buf->data[(*data_off)]);
-       DBG_RW_PSVAL(charmode, name, depth, buf->data, io, q, str->buffer, str->uni_max_len)
-       (*data_off) += str->uni_str_len * sizeof(uint16);
+       int len = 0;
+       while (buf != NULL)
+       {
+               len += buf->offset.end - buf->offset.start;
+               buf = buf->next;
+       }
+       return len;
 }
 
+
 /*******************************************************************
- stream a unicode  null-terminated string
+ return the memory location specified by offset.  may return NULL.
  ********************************************************************/
-void buf_unistr(char *name, int depth, struct mem_buf *buf, int *data_off, BOOL io, UNISTR *str)
+char *mem_data(struct mem_buf **buf, uint32 offset)
 {
-       int i = 0;
-       char *ptr = buf->data;
-       uint8 *start = (uint8*)ptr;
-
-       do 
+       if (mem_find(buf, offset))
        {
-               RW_SVAL(io, ptr, str->buffer[i], 0);
-               ptr += 2;
-               i++;
-
-       } while ((i < sizeof(str->buffer) / sizeof(str->buffer[0])) &&
-                    (str->buffer[i] != 0));
+               return &((*buf)->data[offset - (*buf)->offset.start]);
+       }
+       return NULL;
+}
 
-       (*data_off) += i*2;
 
-       dump_data(5+depth, start, (*data_off));
-}
index cf9b2cefa24dadd01c2645b30f89f6b2438c0a82..58e6719d8ba6df5e687aac797afe065a6c77882a 100644 (file)
@@ -24,6 +24,7 @@
 #endif
 
 #include "includes.h"
+#include "trans2.h"
 
 /* value for unused fid field in trans2 secondary request */
 #define FID_UNUSED (0xFFFF)
@@ -88,8 +89,8 @@ BOOL cli_send_trans(struct cli_state *cli, int t_idx,
        char *outdata,*outparam;
        char *p;
 
-       this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */
-       this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*SIZEOFWORD+this_lparam));
+       this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */
+       this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam));
 
        cli_set_smb_cmd(cli, t_idx,  trans, 14+lsetup, 0, True);
 
@@ -110,7 +111,7 @@ BOOL cli_send_trans(struct cli_state *cli, int t_idx,
        SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */
        SCVAL(cli->outbuf,smb_suwcnt,lsetup);   /* suwcnt */
        for (i=0;i<lsetup;i++)          /* setup[] */
-               SSVAL(cli->outbuf,smb_setup+i*SIZEOFWORD,setup[i]);
+               SSVAL(cli->outbuf,smb_setup+i*2,setup[i]);
        p = smb_buf(cli->outbuf);
        if (trans==SMBtrans) {
                memcpy(p,name, pipe_name_len + 1);                      /* name[] */
@@ -130,7 +131,7 @@ BOOL cli_send_trans(struct cli_state *cli, int t_idx,
 
        if (this_ldata < ldata || this_lparam < lparam) {
                /* receive interim response */
-               if (!receive_smb(cli->fd,cli->inbuf,cli->timeout) || 
+               if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout) || 
                    cli_error(cli, NULL, NULL)) {
                        return(False);
                }      
@@ -158,7 +159,7 @@ BOOL cli_send_trans(struct cli_state *cli, int t_idx,
                        SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */
                        SSVAL(cli->outbuf,smb_sdsdisp,tot_data);        /* dsdisp */
                        if (trans==SMBtrans2)
-                               SSVAL(cli->outbuf,smb_sfid,fid);                /* fid */
+                               SSVALS(cli->outbuf,smb_sfid,fid);               /* fid */
                        if (this_lparam)                        /* param[] */
                                memcpy(outparam,param,this_lparam);
                        if (this_ldata)                 /* data[] */
@@ -191,7 +192,7 @@ BOOL cli_receive_trans(struct cli_state *cli, int t_idx,
        
        *data_len = *param_len = 0;
        
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
                return False;
 
        show_msg(cli->inbuf);
@@ -241,7 +242,7 @@ BOOL cli_receive_trans(struct cli_state *cli, int t_idx,
                if (total_data <= *data_len && total_param <= *param_len)
                        break;
                
-               if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
+               if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
                        return False;
 
                show_msg(cli->inbuf);
@@ -296,15 +297,17 @@ BOOL cli_api_pipe(struct cli_state *cli, int t_idx,
 call a remote api on the LANMAN pipe.  only takes param and data buffers
 ****************************************************************************/
 static BOOL cli_api(struct cli_state *cli, int t_idx,
-                   int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt,
-                   int *rdrcnt, char *param,char *data, 
+                   int prcnt,int drcnt, int srcnt,
+                       int mprcnt,int mdrcnt,
+                       int *rprcnt, int *rdrcnt,
+                       char *param,char *data, uint16 *setup,
                    char **rparam, char **rdata)
 {
        return cli_api_pipe(cli, t_idx,  "\\PIPE\\LANMAN", 0,
-                               prcnt, drcnt, 0,
+                               prcnt, drcnt, srcnt,
                                mprcnt, mdrcnt,
                                rprcnt, rdrcnt,
-                               param, data, NULL,
+                               param, data, setup,
                                rparam, rdata);
 }
 
@@ -345,10 +348,10 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli, int t_idx,char *user, char *wo
        
        cli->error = -1;
        
-       if (cli_api(cli, t_idx,  PTR_DIFF(p,param),0,
+       if (cli_api(cli, t_idx,  PTR_DIFF(p,param),0,0,
                    1024,BUFFER_SIZE,
                    &rprcnt,&rdrcnt,
-                   param,NULL,
+                   param,NULL,NULL,
                    &rparam,&rdata)) {
                cli->error = SVAL(rparam,0);
                p = rdata;
@@ -408,10 +411,11 @@ BOOL cli_NetShareEnum(struct cli_state *cli, int t_idx,
        if (cli_api(cli, t_idx,  
                    PTR_DIFF(p,param), /* param count */
                    0, /*data count */
+                       0, /* setup count */
                    10, /* mprcount */
                    BUFFER_SIZE, /* mdrcount */
                &resp_data_len, &resp_param_len,
-                   param, NULL, 
+                   param, NULL, NULL,
                &resp_param,    &resp_data))
        {
                int res = SVAL(resp_param,0);
@@ -497,10 +501,11 @@ BOOL cli_NetServerEnum(struct cli_state *cli, int t_idx,
        if (cli_api(cli, t_idx,  
                    PTR_DIFF(p,param), /* param count */
                    0, /*data count */
+                       0, /* setup count */
                    8, /* mprcount */
                    BUFFER_SIZE, /* mdrcount */
                    &rprcnt,&rdrcnt,
-                   param, NULL, 
+                   param, NULL, NULL,
                    &rparam,&rdata)) {
                int res = SVAL(rparam,0);
                int converter=SVAL(rparam,2);
@@ -512,8 +517,9 @@ BOOL cli_NetServerEnum(struct cli_state *cli, int t_idx,
                                        
                        for (i = 0;i < count;i++, p += 26) {
                                char *sname = p;
-                               int comment_offset = IVAL(p,22) & 0xFFFF;
-                               char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
+                               int comment_offset = (IVAL(p,22) & 0xFFFF)-converter;
+                               char *cmnt = comment_offset?(rdata+comment_offset):"";
+                               if (comment_offset < 0 || comment_offset > rdrcnt) continue;
 
                                stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;
 
@@ -596,7 +602,10 @@ BOOL cli_session_setup(struct cli_state *cli,
 #endif
 
        if (cli->protocol < PROTOCOL_LANMAN1)
-               return False;
+       {
+               DEBUG(5,("cli_session_setup: protocol < LANMAN1: sesssetup not needed\n"));
+               return True;
+       }
 
        if (passlen > sizeof(pword)-1) {
                return False;
@@ -732,7 +741,7 @@ BOOL cli_session_setup(struct cli_state *cli,
       show_msg(cli->outbuf);
 
       send_smb(cli->fd,cli->outbuf);
-      if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
+      if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
              return False;
 
       show_msg(cli->inbuf);
@@ -811,7 +820,7 @@ BOOL cli_send_tconX(struct cli_state *cli, int *t_idx,
        SCVAL(cli->inbuf,smb_rcls, 1);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
                return False;
 
     if (cli_error(cli, NULL, NULL)) return(False);
@@ -829,7 +838,7 @@ BOOL cli_tdis(struct cli_state *cli, int t_idx)
        cli_set_smb_cmd(cli, t_idx,  SMBtdis, 0,0,True);
        
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
                return False;
        
     return !cli_error(cli, NULL, NULL);
@@ -850,10 +859,7 @@ BOOL cli_rmdir(struct cli_state *cli, int t_idx, char *dname)
        strcpy(p,dname);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
-               return False;
-       }
-
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
     if (cli_error(cli, NULL, NULL)) return False;
 
        return True;
@@ -875,13 +881,9 @@ BOOL cli_unlink(struct cli_state *cli, int t_idx, char *fname)
        p = smb_buf(cli->outbuf);
        *p++ = 4;      
        strcpy(p,fname);
-       p = skip_string(p,1);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
-               return False;
-       }
-
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
     if (cli_error(cli, NULL, NULL)) return False;
 
        return True;
@@ -918,7 +920,7 @@ int cli_send_message(struct cli_state *cli, int t_idx,
 
        send_smb(cli->fd,cli->outbuf);
 
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
        if (cli_error(cli, NULL, NULL)) return False;
 
        grp_id = SVAL(cli->inbuf,smb_vwv0);
@@ -948,7 +950,7 @@ int cli_send_message(struct cli_state *cli, int t_idx,
 
                send_smb(cli->fd,cli->outbuf);
 
-               if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
+               if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
                if (cli_error(cli,  NULL, NULL)) return False;
 
                (*total_len) += l;
@@ -959,7 +961,7 @@ int cli_send_message(struct cli_state *cli, int t_idx,
 
        send_smb(cli->fd,cli->outbuf);
 
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
        if (cli_error(cli,  NULL, NULL)) return False;
 
        return True;
@@ -1218,7 +1220,7 @@ BOOL cli_print(struct cli_state *cli, int t_idx, struct client_info *info,
        strcpy(p,rname);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
        if (cli_error(cli,  NULL, NULL)) return False;
 
        fnum = SVAL(cli->inbuf,smb_vwv0);
@@ -1265,7 +1267,7 @@ BOOL cli_print(struct cli_state *cli, int t_idx, struct client_info *info,
                SSVAL(smb_buf(cli->outbuf),1,n);
 
                send_smb(cli->fd,cli->outbuf);
-               if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
+               if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
                if (cli_error(cli,  NULL, NULL))
                {
                        DEBUG(0,("%s printing remote file\n", cli_errstr(cli)));
@@ -1282,7 +1284,7 @@ BOOL cli_print(struct cli_state *cli, int t_idx, struct client_info *info,
        SSVAL(cli->outbuf,smb_vwv0,fnum);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
        if (cli_error(cli,  NULL, NULL))
        {
                DEBUG(0,("%s closing print file\n", cli_errstr(cli)));
@@ -1311,7 +1313,7 @@ int cli_queue(struct cli_state *cli, int t_idx, struct client_info *info,
        SSVAL(cli->outbuf, smb_vwv1, 0); /* the index into the queue */
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
        if (cli_error(cli,  NULL, NULL))
        {
                DEBUG(0,("%s obtaining print queue\n", cli_errstr(cli)));
@@ -1888,7 +1890,7 @@ int cli_short_dir(struct cli_state *cli, int t_idx, struct client_info *info,
        }
 
        send_smb(cli->fd,cli->outbuf);
-       if (receive_smb(cli->fd, cli->inbuf, cli->timeout))
+       if (client_receive_smb(cli->fd, cli->inbuf, cli->timeout))
        { 
       received = SVAL(cli->inbuf,smb_vwv0);
     }
@@ -1943,7 +1945,7 @@ int cli_short_dir(struct cli_state *cli, int t_idx, struct client_info *info,
       memcpy(p,status,21);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd, cli->inbuf, cli->timeout) ||
+       if (!client_receive_smb(cli->fd, cli->inbuf, cli->timeout) ||
             cli_error(cli,  NULL, NULL))
        { 
        DEBUG(0,("Error closing search: %s\n", cli_errstr(cli)));      
@@ -2241,7 +2243,7 @@ int cli_get(struct cli_state *cli, int t_idx, struct client_info *info,
            }
          
       send_smb(cli->fd,cli->outbuf);
-      if (!receive_smb(cli->fd, cli->inbuf, cli->timeout)) break;
+      if (!client_receive_smb(cli->fd, cli->inbuf, cli->timeout)) break;
       if (cli_error(cli,  NULL, NULL)) break;
 
          if (close_done &&
@@ -2323,7 +2325,7 @@ int cli_get(struct cli_state *cli, int t_idx, struct client_info *info,
          SSVAL(cli->outbuf,smb_vwv4,finfo.size - nread);
 
   send_smb(cli->fd,cli->outbuf);
-  if (!receive_smb(cli->fd, cli->inbuf, cli->timeout)) break;
+  if (!client_receive_smb(cli->fd, cli->inbuf, cli->timeout)) break;
   if (cli_error(cli,  NULL, NULL)) break;
 
          datalen = SVAL(cli->inbuf,smb_vwv0);
@@ -2417,7 +2419,7 @@ BOOL cli_chkpath(struct cli_state *cli, int t_idx, char *path)
 #endif
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
        {
                return False;
        }
@@ -2437,7 +2439,7 @@ BOOL cli_dskattr(struct cli_state *cli, int t_idx,
        cli_set_smb_cmd(cli, t_idx,  SMBdskattr, 0,0,True);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
     if (cli_error(cli, NULL, NULL)) return False;
 
        *num_blocks  = SVAL(cli->inbuf,smb_vwv0);
@@ -2461,7 +2463,7 @@ BOOL cli_mkdir(struct cli_state *cli, int t_idx, char *name)
        strcpy(p,name);
   
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
     if (cli_error(cli, NULL, NULL)) return False;
 
        return(True);
@@ -2487,7 +2489,7 @@ BOOL cli_move(struct cli_state *cli, int t_idx, char *src, char *dest)
        strcpy(p,dest);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
     if (cli_error(cli, NULL, NULL)) return False;
 
        return(True);
@@ -2497,7 +2499,7 @@ BOOL cli_move(struct cli_state *cli, int t_idx, char *src, char *dest)
 Get DOS file attributes
 ***************************************************************************/
 BOOL cli_getatr(struct cli_state *cli, int t_idx, char *fname,
-                               uint8 *fattr, uint16 *ftime, uint16 *fsize)
+                               uint16 *fattr, time_t *ftime, uint32 *fsize)
 {
        char *p;
 
@@ -2512,16 +2514,16 @@ BOOL cli_getatr(struct cli_state *cli, int t_idx, char *fname,
        *p++ = 0; /* zero this, due to byte-alignment issues... */
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
        if (cli_error(cli,  NULL, NULL)) return False;
 
-       if (fattr) (*fattr) = CVAL(cli->inbuf,smb_vwv0);
-       if (ftime) (*ftime) = SVAL(cli->inbuf,smb_vwv1);
-       if (fsize) (*fsize) = SVAL(cli->inbuf,smb_vwv3);
+       if (fattr) (*fattr) = SVAL(cli->inbuf,smb_vwv0);
+       if (ftime) make_unix_date3(cli->inbuf + smb_vwv1);
+       if (fsize) (*fsize) = IVAL(cli->inbuf,smb_vwv3);
 
        if (fattr && ftime && fsize)
        {
-               DEBUG(5,("SMBgetatr attr:0x%X time:%d  size:%d\n",
+               DEBUG(5,("SMBgetatr attr:0x%x time:%d size:%d\n",
                                *fattr, *ftime, *fsize));
        }
 
@@ -2533,14 +2535,14 @@ BOOL cli_getatr(struct cli_state *cli, int t_idx, char *fname,
 Set DOS file attributes
 ***************************************************************************/
 BOOL cli_setatr(struct cli_state *cli, int t_idx, char *fname,
-                               uint8 fattr, uint16 write_time)
+                               uint16 fattr, time_t write_time)
 {
        char *p;
 
        cli_set_smb_cmd(cli, t_idx,  SMBsetatr, 8,4 + strlen(fname),True);
 
        SSVAL(cli->outbuf,smb_vwv0, fattr);
-       SSVAL(cli->outbuf,smb_vwv1, write_time); /* zero indicates no change */
+       put_dos_date3(cli->outbuf,smb_vwv1, write_time); /* zero indicates no change */
        /* all the other 6 words are reserved, so says cifs6.txt... */
 
        p = smb_buf(cli->outbuf);
@@ -2552,13 +2554,155 @@ BOOL cli_setatr(struct cli_state *cli, int t_idx, char *fname,
        *p++ = 0; /* zero this, due to byte-alignment issues... */
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
        if (cli_error(cli,  NULL, NULL)) return False;
 
        return(True);
 }
 
 
+/****************************************************************************
+send a qpathinfo call
+
+c_time - create time
+a_time - accessed time
+m_time - modified time
+
+****************************************************************************/
+BOOL cli_qpathinfo(struct cli_state *cli, uint16 t_idx, char *fname, 
+                  time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size)
+{
+       int data_len = 0;
+       int param_len = 0;
+       uint16 setup = TRANSACT2_QPATHINFO;
+       pstring param;
+       char *rparam=NULL, *rdata=NULL;
+
+       param_len = strlen(fname) + 7;
+
+       memset(param, 0, param_len);
+       SSVAL(param, 0, SMB_INFO_STANDARD);
+       pstrcpy(&param[6], fname);
+
+       if (cli_api(cli, t_idx,  param_len,data_len,1,
+                   1024,BUFFER_SIZE,
+                   &param_len,&data_len,
+                   param,NULL, &setup,
+                   &rparam,&rdata)) {
+               return False;
+       }
+
+       if (!rdata || data_len < 22) {
+               return False;
+       }
+
+       if (c_time) (*c_time) = make_unix_date2(rdata+0);
+       if (a_time) (*a_time) = make_unix_date2(rdata+4);
+       if (m_time) (*m_time) = make_unix_date2(rdata+8);
+       if (size  ) (*size  ) = IVAL(rdata, 12);
+
+       if (rdata) free(rdata);
+       if (rparam) free(rparam);
+
+       return True;
+}
+
+/****************************************************************************
+send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level
+
+c_time - create time
+a_time - accessed time
+m_time - modified time
+w_time - write time
+
+****************************************************************************/
+BOOL cli_qpathinfo2(struct cli_state *cli, uint16 t_idx, char *fname, 
+                   time_t *c_time, time_t *a_time, time_t *m_time, 
+                   time_t *w_time, uint32 *size)
+{
+       int data_len = 0;
+       int param_len = 0;
+       uint16 setup = TRANSACT2_QPATHINFO;
+       pstring param;
+       char *rparam=NULL, *rdata=NULL;
+
+       param_len = strlen(fname) + 7;
+
+       memset(param, 0, param_len);
+       SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO);
+       pstrcpy(&param[6], fname);
+
+       if (cli_api(cli, t_idx,  param_len,data_len,1,
+                   1024,BUFFER_SIZE,
+                   &param_len,&data_len,
+                   param,NULL, &setup,
+                   &rparam,&rdata)) {
+               return False;
+       }
+
+       if (!rdata || data_len < 22) {
+               return False;
+       }
+
+       if (c_time) (*c_time) = interpret_long_date(rdata+0) - cli->serverzone;
+       if (a_time) (*a_time) = interpret_long_date(rdata+8) - cli->serverzone;
+       if (m_time) (*m_time) = interpret_long_date(rdata+16) - cli->serverzone;
+       if (w_time) (*w_time) = interpret_long_date(rdata+24) - cli->serverzone;
+       if (size  ) (*size  ) = IVAL(rdata, 40);
+
+       if (rdata) free(rdata);
+       if (rparam) free(rparam);
+
+       return True;
+}
+
+
+/****************************************************************************
+send a qfileinfo call
+
+c_time - create time
+a_time - accessed time
+m_time - modified time
+
+****************************************************************************/
+BOOL cli_qfileinfo(struct cli_state *cli, uint16 t_idx, uint16 fnum, 
+                  time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size)
+{
+       int data_len = 0;
+       int param_len = 0;
+       uint16 setup = TRANSACT2_QFILEINFO;
+       pstring param;
+       char *rparam=NULL, *rdata=NULL;
+
+       param_len = 4;
+
+       memset(param, 0, param_len);
+       SSVAL(param, 0, fnum);
+       SSVAL(param, 2, SMB_INFO_STANDARD);
+
+       if (cli_api(cli, t_idx,  param_len,data_len,1,
+                   1024,BUFFER_SIZE,
+                   &param_len,&data_len,
+                   param,NULL, &setup,
+                   &rparam,&rdata)) {
+               return False;
+       }
+
+       if (!rdata || data_len < 22) {
+               return False;
+       }
+
+       if (c_time) (*c_time) = make_unix_date2(rdata+0);
+       if (a_time) (*a_time) = make_unix_date2(rdata+4);
+       if (m_time) (*m_time) = make_unix_date2(rdata+8);
+       if (size  ) (*size  ) = IVAL(rdata, 12);
+
+       if (rdata) free(rdata);
+       if (rparam) free(rparam);
+
+       return True;
+}
+
 /****************************************************************************
 Create a file on a share
 ***************************************************************************/
@@ -2577,7 +2721,7 @@ BOOL cli_create(struct cli_state *cli, int t_idx,
        strcpy(p, name);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False;
        if (cli_error(cli,  NULL, NULL)) return False;
 
        *fnum = SVAL(cli->inbuf,smb_vwv0);
@@ -2622,7 +2766,7 @@ uint16 cli_open(struct cli_state *cli, int t_idx, char *fname, int flags, int sh
        SSVAL(cli->outbuf,smb_vwv2,1);  /* return additional info */
        SSVAL(cli->outbuf,smb_vwv3,accessmode);
        SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
-       SSVAL(cli->outbuf,smb_vwv5,aSYSTEM | aHIDDEN);
+       SSVAL(cli->outbuf,smb_vwv5,0);
        SSVAL(cli->outbuf,smb_vwv8,openfn);
        SSVAL(cli->outbuf,smb_vwv11,0xffff);
        SSVAL(cli->outbuf,smb_vwv12,0xffff);
@@ -2632,7 +2776,7 @@ uint16 cli_open(struct cli_state *cli, int t_idx, char *fname, int flags, int sh
        p = skip_string(p,1);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return 0xffff;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return 0xffff;
     if (cli_error(cli,  NULL, NULL)) return 0xffff;
 
        fnum                = SVAL(cli->inbuf,smb_vwv2);
@@ -2647,8 +2791,6 @@ uint16 cli_open(struct cli_state *cli, int t_idx, char *fname, int flags, int sh
 }
 
 
-
-
 /****************************************************************************
   close a file
 ****************************************************************************/
@@ -2661,7 +2803,7 @@ BOOL cli_close(struct cli_state *cli, int t_idx, uint16 fnum, time_t close_time)
        SSVAL(cli->outbuf,smb_vwv2,0);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
                return False;
        }
 
@@ -2693,7 +2835,7 @@ BOOL cli_lock(struct cli_state *cli, int t_idx, uint16 fnum, uint32 offset, uint
        SIVAL(p, 6, len);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
                return False;
        }
 
@@ -2724,7 +2866,7 @@ BOOL cli_unlock(struct cli_state *cli, int t_idx, uint16 fnum, uint32 offset, ui
        SIVAL(p, 6, len);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) {
                return False;
        }
 
@@ -2753,7 +2895,7 @@ int cli_readx(struct cli_state *cli, int t_idx, uint16 fnum, char *buf, uint32 o
 
        show_msg(cli->outbuf);
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return -1;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return -1;
        show_msg(cli->inbuf);
 
     if (cli_error(cli, NULL, NULL)) return -1;
@@ -2784,14 +2926,14 @@ int cli_writeraw(struct cli_state *cli, int t_idx, uint16 fnum,int pos,char *buf
        SSVAL(cli->outbuf,smb_vwv7,1);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return -1;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return -1;
     if (cli_error(cli, NULL, NULL)) return -1;
 
        /* direct write */
        _smb_setlen(buf-4,n);           /* HACK! XXXX */
        if (write_socket(cli->fd,buf-4,n+4) != n+4) return(0);
 
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return -1;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return -1;
 
        return(SVAL(cli->inbuf,smb_vwv0));
 }
@@ -2822,7 +2964,7 @@ int cli_write(struct cli_state *cli, int t_idx, uint16 fnum,int pos,char *buf,in
        memcpy(smb_buf(cli->outbuf)+3,buf,n);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return -1;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return -1;
     if (cli_error(cli, NULL, NULL)) return -1;
 
        len = SVAL(cli->inbuf,smb_vwv0);
@@ -2858,7 +3000,7 @@ int cli_write_x(struct cli_state *cli, int t_idx, uint16 fnum, char *buf, uint32
        memcpy(p, buf, size);
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return -1;
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return -1;
     if (cli_error(cli, NULL, NULL)) return -1;
 
        return SVAL(cli->inbuf, smb_vwv2);
@@ -2906,7 +3048,7 @@ BOOL cli_negprot(struct cli_state *cli)
        CVAL(smb_buf(cli->outbuf),0) = 2;
 
        send_smb(cli->fd,cli->outbuf);
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
                return False;
 
        show_msg(cli->inbuf);
@@ -2917,19 +3059,7 @@ BOOL cli_negprot(struct cli_state *cli)
        cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;
 
 
-       if (cli->protocol < PROTOCOL_NT1) {    
-               cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
-               cli->max_xmit = SVAL(cli->inbuf,smb_vwv2);
-               cli->sesskey = IVAL(cli->inbuf,smb_vwv6);
-               cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60;
-               /* this time is converted to GMT by make_unix_date */
-               cli->servertime = make_unix_date(cli->inbuf+smb_vwv8);
-               if (cli->protocol >= PROTOCOL_COREPLUS) {
-                       cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0);
-                       cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0);
-               }
-               memcpy(cli->cryptkey,smb_buf(cli->inbuf),8);
-       } else {
+       if (cli->protocol >= PROTOCOL_NT1) {    
                /* NT protocol */
                cli->sec_mode = CVAL(cli->inbuf,smb_vwv1);
                cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1);
@@ -2941,6 +3071,20 @@ BOOL cli_negprot(struct cli_state *cli)
                if (IVAL(cli->inbuf,smb_vwv9+1) & 1)
                        cli->readbraw_supported = 
                                cli->writebraw_supported = True;      
+       } else if (cli->protocol >= PROTOCOL_LANMAN1) {
+               cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
+               cli->max_xmit = SVAL(cli->inbuf,smb_vwv2);
+               cli->sesskey = IVAL(cli->inbuf,smb_vwv6);
+               cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60;
+               /* this time is converted to GMT by make_unix_date */
+               cli->servertime = make_unix_date(cli->inbuf+smb_vwv8);
+               cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0);
+               cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0);
+               memcpy(cli->cryptkey,smb_buf(cli->inbuf),8);
+       } else {
+               /* the old core protocol */
+               cli->sec_mode = 0;
+               cli->serverzone = TimeDiff(time(NULL));
        }
 
        DEBUG(5,("cli_negprot: secmode:%x\n", cli->sec_mode));
@@ -2971,7 +3115,8 @@ BOOL cli_session_request(struct cli_state *cli,
 #ifdef TRUNCATE_NETBIOS_NAME
        /* ok.  this is because of a stupid microsoft-ism.  if the called host
           name contains a '.', microsoft clients expect you to truncate the
-          netbios name up to and including the '.'
+          netbios name up to and including the '.'  this even applies, by
+          mistake, to workgroup (domain) names, which is _really_ daft.
         */
        p = strchr(cli->called_netbios_name, '.');
        if (p) *p = 0;
@@ -2994,7 +3139,7 @@ BOOL cli_session_request(struct cli_state *cli,
        send_smb(cli->fd,cli->outbuf);
        DEBUG(5,("Sent session request\n"));
 
-       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
+       if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout))
                return False;
 
        if (CVAL(cli->inbuf,0) != 0x82) {
index 9915ee92a850dbb06dbbccf9967e73f35000d57c..a6adce8249261969dfa54eaf774a951d866c178c 100644 (file)
@@ -132,7 +132,7 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
   GetTimeOfDay(&tval);
 
   if (!send_packet(&p)) 
-    return(False);
+    return False;
 
   retries--;
 
index 52479d37df56d87bb0757069e4c57dade6977399..6b5d9b1ea6841b55d5672e76474e8bcd00c69be0 100644 (file)
@@ -558,8 +558,9 @@ struct shmem_ops *sysv_shm_open(int ronly)
                while (hash_size > 1) {
                        sem_id = semget(SEMAPHORE_KEY, hash_size+1, 
                                        IPC_CREAT|IPC_EXCL| SEMAPHORE_PERMS);
-                       if (sem_id != -1 || errno != EINVAL) break;
-                       hash_size--;
+                       if (sem_id != -1 || 
+                           (errno != EINVAL && errno != ENOSPC)) break;
+                       hash_size -= 5;
                }
 
                if (sem_id == -1) {
@@ -640,8 +641,9 @@ struct shmem_ops *sysv_shm_open(int ronly)
                while (shm_size > MIN_SHM_SIZE) {
                        shm_id = shmget(SHMEM_KEY, shm_size, 
                                        IPC_CREAT | IPC_EXCL | IPC_PERMS);
-                       if (shm_id != -1 || errno != EINVAL) break;
-                       shm_size *= 0.9;
+                       if (shm_id != -1 || 
+                           (errno != EINVAL && errno != ENOSPC)) break;
+                       shm_size *= 0.8;
                }
                created_new = (shm_id != -1);
        }
index 1ee9dab065855f6ab7dbea3950a5a43118e2d3ba..9099507bbb77aed664581c30b3ee33a4a3b8c6e8 100644 (file)
@@ -154,7 +154,6 @@ void start_async_dns(void)
        asyncdns_process();
 }
 
-
 /***************************************************************************
 check if a particular name is already being queried
   ****************************************************************************/
index d45da58c01982df725724f3c47fd5c2504682922..781d23d7d20ead271fefe3d3ad8c437fd57f3b59 100644 (file)
@@ -897,7 +897,6 @@ FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
 FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
-
 FN_GLOBAL_STRING(lp_domain_sid,&Globals.szDomainSID)
 FN_GLOBAL_STRING(lp_domain_other_sids,&Globals.szDomainOtherSIDs)
 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
@@ -905,7 +904,6 @@ FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
 FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
 FN_GLOBAL_STRING(lp_domain_hostsallow,&Globals.szDomainHostsallow)
 FN_GLOBAL_STRING(lp_domain_hostsdeny,&Globals.szDomainHostsdeny)
-
 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
@@ -2092,7 +2090,7 @@ static void lp_add_auto_services(char *str)
 
       if (lp_servicenumber(p) >= 0) continue;
 
-      if (home && homes >= 0)
+      if (home[0] != 0 && homes >= 0)
        {
          lp_add_home(p,homes,home);
          continue;
index ff0a2b54772e47d25679f25e26a36d1caeafd893..d6299a0f088609e5d705a61dc08b95036df77358 100644 (file)
 
    Modified for SVID support by Norm Jacobs, 1997
    
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-   
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
index b18fc057efca63971c7d6a5dfbb37bbbff756fae..131cf92f22223e7458c4f6f0529db33a4e498efc 100644 (file)
@@ -245,12 +245,14 @@ BOOL server_validate(struct cli_state *clnt, char *user, char *domain,
        }
 
 
+#ifdef USE_NETWKSTAUSERLOGON
        if (!cli_NetWkstaUserLogon(clnt, t_idx, user, clnt->called_netbios_name))
        {
                DEBUG(1,("password server %s failed NetWkstaUserLogon\n", clnt->full_dest_host_name));
                cli_tdis(clnt, t_idx);
                return False;
        }
+#endif
 
        if (clnt->privileges == 0)
        {
index 05da262e261ca5e93db9a9654b06de4b93bef64f..c8f85f6bddce0759d217b88d7154932424f9f807 100644 (file)
@@ -63,6 +63,8 @@ extern fstring myworkgroup;
 #define QNLEN 12               /* queue name maximum length */
 
 extern int Client;
+extern int oplock_sock;
+extern int smb_read_error;
 
 static BOOL api_Unsupported(int cnum,uint16 vuid, char *param,char *data,
                            int mdrcnt,int mprcnt,
@@ -130,92 +132,128 @@ static BOOL prefix_ok(char *str,char *prefix)
   return(strncmp(str,prefix,strlen(prefix)) == 0);
 }
 
+/*******************************************************************
+ copies parameters and data, as needed, into the smb buffer
+
+ *both* the data and params sections should be aligned.  this
+ is fudged in the rpc pipes by 
+ at present, only the data section is.  this may be a possible
+ cause of some of the ipc problems being experienced.  lkcl26dec97
+
+ ******************************************************************/
+static void copy_trans_params_and_data(char *outbuf, int align,
+                               struct mem_buf *rparam, struct mem_buf *rdata,
+                               int param_offset, int data_offset,
+                               int param_len, int data_len)
+{
+       char *copy_into = smb_buf(outbuf);
+
+       DEBUG(5,("copy_trans_params_and_data: params[%d..%d] data[%d..%d]\n",
+                       param_offset, param_offset + param_len,
+                       data_offset , data_offset  + data_len));
+
+       if (param_len) mem_buf_copy(copy_into, rparam, param_offset, param_len);
+       copy_into += param_len + align;
+       if (data_len ) mem_buf_copy(copy_into, rdata , data_offset , data_len);
+}
 
 /****************************************************************************
   send a trans reply
   ****************************************************************************/
-static void send_trans_reply(char *outbuf,char *data,char *param,uint16 *setup,
-                            int ldata,int lparam,int lsetup, int max_data_ret)
+static void send_trans_reply(char *outbuf,
+                               struct mem_buf *rdata,
+                               struct mem_buf *rparam,
+                               uint16 *setup, int lsetup, int max_data_ret)
 {
-  int i;
-  int this_ldata,this_lparam;
-  int tot_data=0,tot_param=0;
-  int align;
-  BOOL buffer_too_large = max_data_ret ? ldata > max_data_ret : False;
+       int i;
+       int this_ldata,this_lparam;
+       int tot_data=0,tot_param=0;
+       int align;
 
-  if (buffer_too_large)
-  {
-    DEBUG(5,("send_trans_reply: buffer %d too large %d\n", ldata, max_data_ret));
-    ldata = max_data_ret;
-  }
+       int ldata  = rdata  ? mem_buf_len(rdata ) : 0;
+       int lparam = rparam ? mem_buf_len(rparam) : 0;
+
+       BOOL buffer_too_large = max_data_ret ? ldata > max_data_ret : False;
+
+       if (buffer_too_large)
+       {
+               DEBUG(5,("send_trans_reply: buffer %d too large %d\n", ldata, max_data_ret));
+               ldata = max_data_ret;
+       }
 
-  this_lparam = MIN(lparam,max_send - (500+lsetup*SIZEOFWORD)); /* hack */
-  this_ldata  = MIN(ldata,max_send - (500+lsetup*SIZEOFWORD+this_lparam));
+       this_lparam = MIN(lparam,max_send - (500+lsetup*SIZEOFWORD)); /* hack */
+       this_ldata  = MIN(ldata,max_send - (500+lsetup*SIZEOFWORD+this_lparam));
 
 #ifdef CONFUSE_NETMONITOR_MSRPC_DECODING
-  /* if you don't want Net Monitor to decode your packets, do this!!! */
-  align = ((this_lparam+1)%4);
+       /* if you don't want Net Monitor to decode your packets, do this!!! */
+       align = ((this_lparam+1)%4);
 #else
-  align = (this_lparam%4);
+       align = (this_lparam%4);
 #endif
 
-  set_message(outbuf,10+lsetup,align+this_ldata+this_lparam,True);
+       set_message(outbuf,10+lsetup,align+this_ldata+this_lparam,True);
 
-  if (buffer_too_large)
-  {
-    /* issue a buffer size warning.  on a DCE/RPC pipe, expect an SMBreadX... */
-    SIVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-    SIVAL(outbuf, smb_rcls, 0x80000000 | NT_STATUS_ACCESS_VIOLATION);
-  }
+       if (buffer_too_large)
+       {
+               /* issue a buffer size warning.  on a DCE/RPC pipe, expect an SMBreadX... */
+               SIVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+               SIVAL(outbuf, smb_rcls, 0x80000000 | NT_STATUS_ACCESS_VIOLATION);
+       }
 
-  if (this_lparam) memcpy(smb_buf(outbuf),param,this_lparam);
-  if (this_ldata ) memcpy(smb_buf(outbuf)+this_lparam+align,data,this_ldata);
+       copy_trans_params_and_data(outbuf, align,
+                                  rparam     , rdata,
+                                  tot_param  , tot_data,
+                                  this_lparam, this_ldata);
+
+       SSVAL(outbuf,smb_vwv0,lparam);
+       SSVAL(outbuf,smb_vwv1,ldata);
+       SSVAL(outbuf,smb_vwv3,this_lparam);
+       SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf));
+       SSVAL(outbuf,smb_vwv5,0);
+       SSVAL(outbuf,smb_vwv6,this_ldata);
+       SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf));
+       SSVAL(outbuf,smb_vwv8,0);
+       SSVAL(outbuf,smb_vwv9,lsetup);
+
+       for (i=0;i<lsetup;i++)
+       {
+               SSVAL(outbuf,smb_vwv10+i*SIZEOFWORD,setup[i]);
+       }
 
-  SSVAL(outbuf,smb_vwv0,lparam);
-  SSVAL(outbuf,smb_vwv1,ldata);
-  SSVAL(outbuf,smb_vwv3,this_lparam);
-  SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf));
-  SSVAL(outbuf,smb_vwv5,0);
-  SSVAL(outbuf,smb_vwv6,this_ldata);
-  SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf));
-  SSVAL(outbuf,smb_vwv8,0);
-  SSVAL(outbuf,smb_vwv9,lsetup);
-  for (i=0;i<lsetup;i++)
-    SSVAL(outbuf,smb_vwv10+i*SIZEOFWORD,setup[i]);
+       show_msg(outbuf);
+       send_smb(Client,outbuf);
 
-  show_msg(outbuf);
-  send_smb(Client,outbuf);
+       tot_data = this_ldata;
+       tot_param = this_lparam;
 
-  tot_data = this_ldata;
-  tot_param = this_lparam;
+       while (tot_data < ldata || tot_param < lparam)
+       {
+               this_lparam = MIN(lparam-tot_param, max_send - 500); /* hack */
+               this_ldata  = MIN(ldata -tot_data , max_send - (500+this_lparam));
 
-  while (tot_data < ldata || tot_param < lparam)
-    {
-      this_lparam = MIN(lparam-tot_param,max_send - 500); /* hack */
-      this_ldata = MIN(ldata-tot_data,max_send - (500+this_lparam));
+               align = (this_lparam%4);
 
-      align = (this_lparam%4);
+               set_message(outbuf,10,this_ldata+this_lparam+align,False);
 
-      set_message(outbuf,10,this_ldata+this_lparam+align,False);
-      if (this_lparam)
-       memcpy(smb_buf(outbuf),param+tot_param,this_lparam);
-      if (this_ldata)
-       memcpy(smb_buf(outbuf)+this_lparam+align,data+tot_data,this_ldata);
+               copy_trans_params_and_data(outbuf, align,
+                                          rparam     , rdata,
+                                          tot_param  , tot_data,
+                                          this_lparam, this_ldata);
 
-      SSVAL(outbuf,smb_vwv3,this_lparam);
-      SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf));
-      SSVAL(outbuf,smb_vwv5,tot_param);
-      SSVAL(outbuf,smb_vwv6,this_ldata);
-      SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf));
-      SSVAL(outbuf,smb_vwv8,tot_data);
-      SSVAL(outbuf,smb_vwv9,0);
+               SSVAL(outbuf,smb_vwv3,this_lparam);
+               SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf));
+               SSVAL(outbuf,smb_vwv5,tot_param);
+               SSVAL(outbuf,smb_vwv6,this_ldata);
+               SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf));
+               SSVAL(outbuf,smb_vwv8,tot_data);
+               SSVAL(outbuf,smb_vwv9,0);
 
-      show_msg(outbuf);
-      send_smb(Client,outbuf);
+               show_msg(outbuf);
+               send_smb(Client,outbuf);
 
-      tot_data += this_ldata;
-      tot_param += this_lparam;
-    }
+               tot_data  += this_ldata;
+               tot_param += this_lparam;
+       }
 }
 
 struct pack_desc {
@@ -2201,7 +2239,7 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data,
        {         
                SSVAL(p,usri11_priv,Connections[cnum].admin_user?USER_PRIV_ADMIN:USER_PRIV_USER); 
                SIVAL(p,usri11_auth_flags,AF_OP_PRINT);         /* auth flags */
-               SIVALS(p,usri11_password_age,0xffffffff);               /* password age */
+               SIVALS(p,usri11_password_age,-1);               /* password age */
                SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */
                strcpy(p2, lp_logon_path());
                p2 = skip_string(p2,1);
@@ -2210,8 +2248,8 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data,
                p2 = skip_string(p2,1);
                SIVAL(p,usri11_last_logon,0);           /* last logon */
                SIVAL(p,usri11_last_logoff,0);          /* last logoff */
-               SSVALS(p,usri11_bad_pw_count,0xffffffff);               /* bad pw counts */
-               SSVALS(p,usri11_num_logons,0xffffffff);         /* num logons */
+               SSVALS(p,usri11_bad_pw_count,-1);       /* bad pw counts */
+               SSVALS(p,usri11_num_logons,-1);         /* num logons */
                SIVAL(p,usri11_logon_server,PTR_DIFF(p2,p)); /* logon server */
                strcpy(p2,"\\\\*");
                p2 = skip_string(p2,1);
@@ -2221,7 +2259,7 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data,
                strcpy(p2,"");
                p2 = skip_string(p2,1);
 
-               SIVALS(p,usri11_max_storage,0xffffffff);                /* max storage */
+               SIVALS(p,usri11_max_storage,-1);                /* max storage */
                SSVAL(p,usri11_units_per_week,168);             /* units per week */
                SIVAL(p,usri11_logon_hours,PTR_DIFF(p2,p)); /* logon hours */
 
@@ -2878,199 +2916,296 @@ static BOOL api_WPrintPortEnum(int cnum,uint16 vuid, char *param,char *data,
 }
 
 
-static struct
+struct api_cmd
 {
   char * pipe_clnt_name;
   char * pipe_srv_name;
-  int subcommand;
-  BOOL (*fn) (int, int, struct mem_buffer*, struct mem_buffer*);
-}
-api_fd_commands [] =
-{
-    { "lsarpc",   "lsass",   0x26, api_ntlsa_rpc },
-    { "samr",     "lsass",   0x26, api_samr_rpc },
-    { "srvsvc",   "ntsvcs",  0x26, api_srvsvc_rpc },
-    { "wkssvc",   "ntsvcs",  0x26, api_wkssvc_rpc },
-    { "NETLOGON", "lsass",   0x26, api_netlog_rpc },
-    { "winreg",   "winreg",  0x26, api_reg_rpc },
-    { NULL,       NULL,      -1,   NULL }
+  BOOL (*fn) (pipes_struct *, prs_struct *);
 };
 
-/****************************************************************************
-  handle remote api calls delivered to a named pipe already opened.
-  ****************************************************************************/
-static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
-                       uint16 *setup,char *data,char *params,
-                       int suwcnt,int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
+static struct api_cmd api_fd_commands[] =
 {
-       struct mem_buffer rdata;
-       struct mem_buffer data_buf;
-       char *rparam = NULL;
-       int data_len  = 0;
-       int rdata_len  = 0;
-       int rparam_len = 0;
-
-       BOOL reply    = False;
-       BOOL bind_req = False;
-       BOOL set_nphs = False;
-
-       int i;
-       int pnum;
-       int subcommand;
-       char *pipe_name;
-
-       DEBUG(5,("api_fd_reply\n"));
-
-       /* First find out the name of this file. */
-       if (suwcnt != 2)
-       {
-               DEBUG(0,("Unexpected named pipe transaction.\n"));
-               return(-1);
-       }
-
-       /* Get the file handle and hence the file name. */
-       pnum = setup[1];
-       subcommand = setup[0];
-       pipe_name = get_rpc_pipe_hnd_name(pnum);
+    { "lsarpc",   "lsass",   api_ntlsa_rpc },
+    { "samr",     "lsass",   api_samr_rpc },
+    { "srvsvc",   "ntsvcs",  api_srvsvc_rpc },
+    { "wkssvc",   "ntsvcs",  api_wkssvc_rpc },
+    { "NETLOGON", "lsass",   api_netlog_rpc },
+    { "winreg",   "winreg",  api_reg_rpc },
+    { NULL,       NULL,      NULL }
+};
 
-       if (pipe_name == NULL)
-       {
-               DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
-       }
+static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd)
+{
+       fstring ack_pipe_name;
+       int i = 0;
 
-       DEBUG(3,("Got API command %d on pipe %s (pnum %x)",
-                 subcommand, pipe_name, pnum));
-       DEBUG(3,("(tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d,cnum=%d,vuid=%d)\n",
-                 tdscnt,tpscnt,mdrcnt,mprcnt,cnum,vuid));
+       DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
 
        for (i = 0; api_fd_commands[i].pipe_clnt_name; i++)
        {
-               if (strequal(api_fd_commands[i].pipe_clnt_name, pipe_name) &&
-                   api_fd_commands[i].subcommand == subcommand &&
+               if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
                    api_fd_commands[i].fn != NULL)
                {
-                       DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name));
+                       DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
+                                  api_fd_commands[i].pipe_clnt_name,
+                                  api_fd_commands[i].pipe_srv_name));
+                       fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name);
                        break;
                }
        }
 
-       buf_create(&data_buf, data, tdscnt, 4, 0);
+       if (api_fd_commands[i].fn == NULL) return False;
 
-       buf_init(&rdata, 4, SAFETY_MARGIN);
-       buf_alloc(&rdata, 1024);
+       /* decode the bind request */
+       smb_io_rpc_hdr_rb("", &p->hdr_rb, pd);
 
-       rparam = (char *)malloc(1024); if (rparam) bzero(rparam,1024);
+       if (pd->offset == 0) return False;
 
-       /* RPC Pipe command 0x26. */
-       if (data != NULL && api_fd_commands[i].subcommand == 0x26)
-       {
-               RPC_HDR hdr;
+       /* name has to be \PIPE\xxxxx */
+       strcpy(ack_pipe_name, "\\PIPE\\");
+       strcat(ack_pipe_name, p->pipe_srv_name);
 
-               /* process the rpc header */
-               data_len = 0;
-               smb_io_rpc_hdr("", True, &hdr, &data_buf, &data_len, 0);
+       /* make a bind acknowledgement */
+       make_rpc_hdr_ba(&p->hdr_ba,
+                                       p->hdr_rb.bba.max_tsize,
+                       p->hdr_rb.bba.max_rsize,
+                       p->hdr_rb.bba.assoc_gid,
+                                       ack_pipe_name,
+                                       0x1, 0x0, 0x0,
+                                       &(p->hdr_rb.transfer));
 
-               /* bind request received */
-               if ((bind_req = ((data_len != 0) && (hdr.pkt_type == RPC_BIND))))
-               {
-                       RPC_HDR_RB hdr_rb;
+       DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
 
-                       /* decode the bind request */
-                       smb_io_rpc_hdr_rb("", True, &hdr_rb, &data_buf, &data_len, 0);
+       /*** do the bind ack first ***/
 
-                       if ((bind_req = (data_len != 0)))
-                       {
-                               RPC_HDR_BA hdr_ba;
-                               fstring ack_pipe_name;
-                               int p;
+       mem_buf_init(&(p->rdata.data), 0);
+       mem_alloc_data(p->rdata.data, 1024);
 
-                               /* name has to be \PIPE\xxxxx */
-                               strcpy(ack_pipe_name, "\\PIPE\\");
-                               strcat(ack_pipe_name, api_fd_commands[i].pipe_srv_name);
+       p->rdata.offset = 0x0;
+       p->rdata.align = 4;
+       p->rdata.depth = 0;
+       p->rdata.io = False;
 
-                               /* make a bind acknowledgement */
-                               make_rpc_hdr_ba(&hdr_ba,
-                                               hdr_rb.bba.max_tsize, hdr_rb.bba.max_rsize, hdr_rb.bba.assoc_gid,
-                                               ack_pipe_name,
-                                               0x1, 0x0, 0x0,
-                                               &(hdr_rb.transfer));
+       p->rdata.data->offset.start = 0;
+       p->rdata.data->offset.end = 0xffffffff;
 
-                               /* write out the bind ack first */
-                               rdata_len = 0x10;
-                               smb_io_rpc_hdr_ba("", False, &hdr_ba, &rdata, &rdata_len, 0);
+       smb_io_rpc_hdr_ba("", &p->hdr_ba, &p->rdata);
 
-                               /* then do the header, now we know the length */
-                               make_rpc_hdr(&hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST,
-                                            hdr.call_id, rdata_len);
+       mem_realloc_data(p->rdata.data, p->rdata.offset);
 
-                               p = 0x0;
-                               smb_io_rpc_hdr("", False, &hdr, &rdata, &p, 0);
+       /**** then do the header, now we know the length ***/
 
-                               reply = True;
-                       }
-               }
-       }
+       make_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST,
+                                p->hdr.call_id, p->rdata.offset + 0x10);
+
+       mem_buf_init(&(p->rhdr.data), 0);
+       mem_alloc_data(p->rhdr.data, 0x10);
 
-       /* Set Named Pipe Handle state */
-       if (subcommand == 0x1)
+       p->rdata.offset = 0x0;
+       p->rdata.align = 4;
+       p->rdata.depth = 0;
+       p->rdata.io = False;
+
+       p->rhdr.data->offset.start = 0;
+       p->rhdr.data->offset.end = 0xffffffff;
+
+       smb_io_rpc_hdr("", &p->hdr, &p->rhdr);
+
+       /*** link the rpc header to the bind acknowledgment response ***/
+
+       p->rhdr.data->offset.start = 0;
+       p->rhdr.data->offset.end   = p->rhdr.offset;
+       p->rhdr.data->next         = p->rdata.data;
+
+       p->rdata.data->offset.start = p->rhdr.offset;
+       p->rdata.data->offset.end   = p->rhdr.offset + p->rdata.offset;
+       p->rdata.data->next         = NULL;
+
+       return True;
+}
+
+static BOOL api_pipe_request(pipes_struct *p, prs_struct *pd)
+{
+       int i = 0;
+
+       for (i = 0; api_fd_commands[i].pipe_clnt_name; i++)
        {
-               set_nphs = True;
-               reply = api_LsarpcSNPHS(pnum, cnum, params);
+               if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
+                   api_fd_commands[i].fn != NULL)
+               {
+                       DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name));
+                       return api_fd_commands[i].fn(p, pd);
+               }
        }
+       return False;
+}
 
-       if (!bind_req && !set_nphs)
-       {
-               DEBUG(10,("calling api_fd_command\n"));
+static BOOL api_dce_rpc_command(char *outbuf,
+                               pipes_struct *p,
+                               prs_struct *pd,
+                               int max_rdata_len)
+{
+       BOOL reply = False;
+       if (pd->data == NULL) return False;
+
+       /* process the rpc header */
+       smb_io_rpc_hdr("", &p->hdr, pd);
 
+       if (pd->offset == 0) return False;
 
-               if (api_fd_commands[i].fn == NULL)
+       switch (p->hdr.pkt_type)
+       {
+               case RPC_BIND   :
                {
-                       reply = api_Unsupported(cnum,vuid,params,data,mdrcnt,mprcnt,
-                                      &(rdata.data), &rparam,
-                                      & rdata_len  , &rparam_len);
+                       reply = api_pipe_bind_req(p, pd);
+                       break;
                }
-               else
+               case RPC_REQUEST:
                {
-                       /* reset the data pointer because it gets re-processed unnecessarily */
-                       reply = api_fd_commands[i].fn(cnum, vuid, &data_buf, &rdata);
-                       rdata_len = rdata.data_used;
+                       reply = api_pipe_request (p, pd);
+                       break;
                }
-
-               DEBUG(10,("called api_fd_command.  data_len: %d\n", rdata_len));
        }
 
-       if (rparam_len > mprcnt)
+       if (reply)
        {
-               reply = api_TooSmall(cnum,vuid,params,data,mdrcnt,mprcnt,
-                                      &(rdata.data), &rparam,
-                                      &(rdata_len ), &rparam_len);
+               /* now send the reply */
+               send_trans_reply(outbuf, p->rhdr.data, NULL, NULL, 0, max_rdata_len);
+
+               if (mem_buf_len(p->rhdr.data) <= max_rdata_len)
+               {
+                       /* all of data was sent: no need to wait for SMBreadX calls */
+                       mem_free_data(p->rhdr .data);
+                       mem_free_data(p->rdata.data);
+               }
        }
 
-       /* if we get False back then it's actually unsupported */
-       if (!reply)
+       return reply;
+}
+
+/****************************************************************************
+ SetNamedPipeHandleState 
+****************************************************************************/
+static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param, int max_rdata_len)
+{
+       uint16 id;
+
+       if (!param) return False;
+
+       id = param[0] + (param[1] << 8);
+       DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n", id));
+
+       if (set_rpc_pipe_hnd_state(p, id))
        {
-               api_Unsupported(cnum,vuid,params,data,mdrcnt,mprcnt,
-                                      &(rdata.data), &rparam,
-                                      &(rdata_len ), &rparam_len);
+               /* now send the reply */
+               send_trans_reply(outbuf, NULL, NULL, NULL, 0, max_rdata_len);
+               return True;
        }
+       return False;
+}
+
+
+/****************************************************************************
+ when no reply is generated, indicate unsupported.
+ ****************************************************************************/
+static BOOL api_no_reply(char *outbuf, int max_rdata_len)
+{
+       struct mem_buf rparam;
+
+       mem_init(&rparam, 0);
+       mem_alloc_data(&rparam, 4);
+
+       rparam.offset.start = 0;
+       rparam.offset.end   = 4;
+
+       /* unsupported */
+       SSVAL(rparam.data,0,NERR_notsupported);
+       SSVAL(rparam.data,2,0); /* converter word */
+
+       DEBUG(3,("Unsupported API fd command\n"));
 
        /* now send the reply */
-       send_trans_reply(outbuf, rdata.data, rparam, NULL, rdata_len, rparam_len, 0, mdrcnt);
+       send_trans_reply(outbuf, NULL, &rparam, NULL, 0, max_rdata_len);
+
+       mem_free_data(&rparam);
+
+       return(-1);
+}
+
+/****************************************************************************
+  handle remote api calls delivered to a named pipe already opened.
+  ****************************************************************************/
+static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
+                       uint16 *setup,char *data,char *params,
+                       int suwcnt,int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
+{
+       BOOL reply    = False;
+
+       int pnum;
+       int subcommand;
+       pipes_struct *p = NULL;
+       prs_struct pd;
+       struct mem_buf data_buf;
+
+       DEBUG(5,("api_fd_reply\n"));
+
+       /* fake up a data buffer from the api_fd_reply data parameters */
+       mem_create(&data_buf, data, tdscnt, 0);
+       data_buf.offset.start = 0;
+       data_buf.offset.end   = tdscnt;
 
-       if (rdata.data_used <= mdrcnt)
+       /* fake up a parsing structure */
+       pd.data = &data_buf;
+       pd.align = 4;
+       pd.io = True;
+       pd.depth = 0;
+       pd.offset = 0;
+
+       /* First find out the name of this file. */
+       if (suwcnt != 2)
        {
-               buf_free(&rdata);
-               write_pipe(pnum, NULL); /* erase the previous (if there was one) data */
+               DEBUG(0,("Unexpected named pipe transaction.\n"));
+               return(-1);
+       }
+
+       /* Get the file handle and hence the file name. */
+       pnum = setup[1];
+       subcommand = setup[0];
+       get_rpc_pipe(pnum, &p);
+
+       if (p != NULL)
+       {
+               DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)",
+                                 subcommand, p->name, pnum));
+               DEBUG(3,("(tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d,cnum=%d,vuid=%d)\n",
+                                 tdscnt,tpscnt,mdrcnt,mprcnt,cnum,vuid));
+
+               switch (subcommand)
+               {
+                       case 0x26:
+                       {
+                               /* dce/rpc command */
+                               reply = api_dce_rpc_command(outbuf, p, &pd, mdrcnt);
+                               break;
+                       }
+                       case 0x01:
+                       {
+                               /* Set Named Pipe Handle state */
+                               reply = api_SNPHS(outbuf, p, params, mdrcnt);
+                               break;
+                       }
+               }
        }
        else
        {
-               /* data is too large.  keep it in case we get an SMBreadX on the pipe */
-               write_pipe(pnum, &rdata);
+               DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
        }
 
-       if (rparam) free(rparam);
-
-       return(-1);
+       if (!reply)
+       {
+               return api_no_reply(outbuf, mdrcnt);
+       }
+       return -1;
 }
 
 
@@ -3083,17 +3218,17 @@ static BOOL api_TooSmall(int cnum,uint16 vuid, char *param,char *data,
                         char **rdata,char **rparam,
                         int *rdata_len,int *rparam_len)
 {
-  *rparam_len = MIN(*rparam_len,mprcnt);
-  *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam_len = MIN(*rparam_len,mprcnt);
+       *rparam = REALLOC(*rparam,*rparam_len);
 
-  *rdata_len = 0;
+       if (rdata_len) *rdata_len = 0;
 
-  SSVAL(*rparam,0,NERR_BufTooSmall);
+       SSVAL(*rparam,0,NERR_BufTooSmall);
 
-  DEBUG(3,("Supplied buffer too small in API command\n"));
+       DEBUG(3,("Supplied buffer too small in API command\n"));
 
-  return(True);
-}
+       return(True);
+       }
 
 
 /****************************************************************************
@@ -3104,22 +3239,21 @@ static BOOL api_Unsupported(int cnum,uint16 vuid, char *param,char *data,
                            char **rdata,char **rparam,
                            int *rdata_len,int *rparam_len)
 {
-  *rparam_len = 4;
-  *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam_len = 4;
+       *rparam = REALLOC(*rparam,*rparam_len);
 
-  *rdata_len = 0;
+       if (rdata_len) *rdata_len = 0;
 
-  SSVAL(*rparam,0,NERR_notsupported);
-  SSVAL(*rparam,2,0);          /* converter word */
+       SSVAL(*rparam,0,NERR_notsupported);
+       SSVAL(*rparam,2,0);             /* converter word */
 
-  DEBUG(3,("Unsupported API command\n"));
+       DEBUG(3,("Unsupported API command\n"));
 
-  return(True);
+       return(True);
 }
 
 
 
-
 struct
 {
   char *name;
@@ -3162,6 +3296,8 @@ static int api_reply(int cnum,uint16 vuid,char *outbuf,char *data,char *params,
                     int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
 {
   int api_command = SVAL(params,0);
+       struct mem_buf rdata_buf;
+       struct mem_buf rparam_buf;
   char *rdata = NULL;
   char *rparam = NULL;
   int rdata_len = 0;
@@ -3201,14 +3337,20 @@ static int api_reply(int cnum,uint16 vuid,char *outbuf,char *data,char *params,
                    &rdata,&rparam,&rdata_len,&rparam_len);
 
       
+       mem_create(&rdata_buf , rdata , rdata_len , 0);
+       mem_create(&rparam_buf, rparam, rparam_len, 0);
+
+       rdata_buf.offset.start = 0;
+       rdata_buf.offset.end   = rdata_len;
+
+       rparam_buf.offset.start = 0;
+       rparam_buf.offset.end   = rparam_len;
 
   /* now send the reply */
-  send_trans_reply(outbuf,rdata,rparam,NULL,rdata_len,rparam_len,0, 0);
+  send_trans_reply(outbuf, &rdata_buf, &rparam_buf, NULL, 0, 0);
 
-  if (rdata)
-    free(rdata);
-  if (rparam)
-    free(rparam);
+  if (rdata ) free(rdata);
+  if (rparam) free(rparam);
   
   return(-1);
 }
@@ -3245,7 +3387,7 @@ static int named_pipe(int cnum,uint16 vuid, char *outbuf,char *name,
 /****************************************************************************
   reply to a SMBtrans
   ****************************************************************************/
-int reply_trans(char *inbuf,char *outbuf)
+int reply_trans(char *inbuf,char *outbuf, int size, int bufsize)
 {
   fstring name;
 
@@ -3308,12 +3450,18 @@ int reply_trans(char *inbuf,char *outbuf)
   /* receive the rest of the trans packet */
   while (pscnt < tpscnt || dscnt < tdscnt)
     {
+      BOOL ret;
       int pcnt,poff,dcnt,doff,pdisp,ddisp;
       
-      if (!receive_smb(Client,inbuf, SMB_SECONDARY_WAIT) ||
-         CVAL(inbuf, smb_com) != SMBtrans)
+      ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,SMB_SECONDARY_WAIT);
+
+      if ((ret && (CVAL(inbuf, smb_com) != SMBtrans)) || !ret)
        {
-         DEBUG(2,("Invalid secondary trans2 packet\n"));
+          if(ret)
+            DEBUG(0,("reply_trans: Invalid secondary trans packet\n"));
+          else
+            DEBUG(0,("reply_trans: %s in getting secondary trans response.\n",
+              (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
          if (params) free(params);
          if (data) free(data);
          if (setup) free(setup);
index 604f8b838c4cdfe59aa07de4600b6399bce01e48..e3d28aa228c340563dbf975b3c299b018796b6c7 100644 (file)
@@ -185,175 +185,3 @@ int reply_pipe_close(char *inbuf,char *outbuf)
   return(outsize);
 }
 
-
-/****************************************************************************
- api_LsarpcSNPHS
-
- SetNamedPipeHandleState on \PIPE\lsarpc. 
-****************************************************************************/
-BOOL api_LsarpcSNPHS(int pnum, int cnum, char *param)
-{
-  uint16 id;
-
-  if (!param) return False;
-
-  id = param[0] + (param[1] << 8);
-  DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
-
-  return set_rpc_pipe_hnd_state(pnum, cnum, id);
-}
-
-
-/****************************************************************************
- api_LsarpcTNP
-
- TransactNamedPipe on \PIPE\lsarpc.
-****************************************************************************/
-static void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
-{
-  uint32 dword1, dword2;
-  char pname[] = "\\PIPE\\lsass";
-
-  /* All kinds of mysterious numbers here */
-  *rdata_len = 68;
-  *rdata = REALLOC(*rdata,*rdata_len);
-
-  dword1 = IVAL(data,0xC);
-  dword2 = IVAL(data,0x10);
-
-  SIVAL(*rdata,0,0xc0005);
-  SIVAL(*rdata,4,0x10);
-  SIVAL(*rdata,8,0x44);
-  SIVAL(*rdata,0xC,dword1);
-  
-  SIVAL(*rdata,0x10,dword2);
-  SIVAL(*rdata,0x14,0x15);
-  SSVAL(*rdata,0x18,sizeof(pname));
-  strcpy(*rdata + 0x1a,pname);
-  SIVAL(*rdata,0x28,1);
-  memcpy(*rdata + 0x30, data + 0x34, 0x14);
-}
-
-static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
-{
-  uint32 dword1;
-
-  /* All kinds of mysterious numbers here */
-  *rdata_len = 48;
-  *rdata = REALLOC(*rdata,*rdata_len);
-
-  dword1 = IVAL(data,0xC);
-
-  SIVAL(*rdata,0,0x03020005);
-  SIVAL(*rdata,4,0x10);
-  SIVAL(*rdata,8,0x30);
-  SIVAL(*rdata,0xC,dword1);
-  SIVAL(*rdata,0x10,0x18);
-  SIVAL(*rdata,0x1c,0x44332211);
-  SIVAL(*rdata,0x20,0x88776655);
-  SIVAL(*rdata,0x24,0xCCBBAA99);
-  SIVAL(*rdata,0x28,0x11FFEEDD);
-}
-
-static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
-{
-  uint32 dword1;
-  uint16 word1;
-  char * workgroup = myworkgroup;
-  int wglen = strlen(workgroup);
-  int i;
-
-  /* All kinds of mysterious numbers here */
-  *rdata_len = 90 + 2 * wglen;
-  *rdata = REALLOC(*rdata,*rdata_len);
-
-  dword1 = IVAL(data,0xC);
-  word1 = SVAL(data,0x2C);
-
-  SIVAL(*rdata,0,0x03020005);
-  SIVAL(*rdata,4,0x10);
-  SIVAL(*rdata,8,0x60);
-  SIVAL(*rdata,0xC,dword1);
-  SIVAL(*rdata,0x10,0x48);
-  SSVAL(*rdata,0x18,0x5988);   /* This changes */
-  SSVAL(*rdata,0x1A,0x15);
-  SSVAL(*rdata,0x1C,word1);
-  SSVAL(*rdata,0x20,6);
-  SSVAL(*rdata,0x22,8);
-  SSVAL(*rdata,0x24,0x8E8);    /* So does this */
-  SSVAL(*rdata,0x26,0x15);
-  SSVAL(*rdata,0x28,0x4D48);   /* And this */
-  SSVAL(*rdata,0x2A,0x15);
-  SIVAL(*rdata,0x2C,4);
-  SIVAL(*rdata,0x34,wglen);
-  for ( i = 0 ; i < wglen ; i++ )
-    (*rdata)[0x38 + i * 2] = workgroup[i];
-   
-  /* Now fill in the rest */
-  i = 0x38 + wglen * 2;
-  SSVAL(*rdata,i,0x648);
-  SIVAL(*rdata,i+2,4);
-  SIVAL(*rdata,i+6,0x401);
-  SSVAL(*rdata,i+0xC,0x500);
-  SIVAL(*rdata,i+0xE,0x15);
-  SIVAL(*rdata,i+0x12,0x2372FE1);
-  SIVAL(*rdata,i+0x16,0x7E831BEF);
-  SIVAL(*rdata,i+0x1A,0x4B454B2);
-}
-
-static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
-{
-  uint32 dword1;
-
-  /* All kinds of mysterious numbers here */
-  *rdata_len = 48;
-  *rdata = REALLOC(*rdata,*rdata_len);
-
-  dword1 = IVAL(data,0xC);
-
-  SIVAL(*rdata,0,0x03020005);
-  SIVAL(*rdata,4,0x10);
-  SIVAL(*rdata,8,0x30);
-  SIVAL(*rdata,0xC,dword1);
-  SIVAL(*rdata,0x10,0x18);
-}
-
-
-BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
-                    int mdrcnt,int mprcnt,
-                    char **rdata,char **rparam,
-                    int *rdata_len,int *rparam_len)
-{
-  uint32 id,id2;
-
-  id = IVAL(data,0);
-
-  DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
-  switch (id)
-  {
-    case 0xb0005:
-      LsarpcTNP1(data,rdata,rdata_len);
-      break;
-
-    case 0x03000005:
-      id2 = IVAL(data,8);
-      DEBUG(4,("\t- Suboperation %lx\n",id2));
-      switch (id2 & 0xF)
-      {
-        case 8:
-          LsarpcTNP2(data,rdata,rdata_len);
-          break;
-
-        case 0xC:
-          LsarpcTNP4(data,rdata,rdata_len);
-          break;
-
-        case 0xE:
-          LsarpcTNP3(data,rdata,rdata_len);
-          break;
-      }
-      break;
-  }
-  return(True);
-}
-
index 9d6714ec36f2d9b9b5f2b87251dabbe0725a8636..f88657a9d7767d07f9b15b0f6b5e26ca81226242 100644 (file)
@@ -259,7 +259,6 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   int connection_num;
   uint16 vuid = SVAL(inbuf,smb_uid);
   int passlen = SVAL(inbuf,smb_vwv3);
-  BOOL doencrypt = SMBENCRYPT();
 
   *service = *user = *password = *devicename = 0;
 
@@ -279,7 +278,7 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize)
     password[passlen]=0;    
     path = smb_buf(inbuf) + passlen;
 
-    if (!doencrypt || passlen != 24) {
+    if (passlen != 24) {
       if (strequal(password," "))
        *password = 0;
       passlen = strlen(password);
@@ -509,6 +508,7 @@ static void sess_get_info(char *inbuf, char *user, char *domain,
     }
 
     memcpy(smb_passwd,smb_buf(inbuf),*smb_passlen);
+       smb_passwd[*smb_passlen] = 0;
     pstrcpy(user,smb_buf(inbuf)+*smb_passlen);
 
     if (lp_security() != SEC_SERVER && !doencrypt)
@@ -570,14 +570,16 @@ static void sess_get_info_nt1(char *inbuf, char *user, char *domain,
        passlen1 = MIN(passlen1, MAX_PASS_LEN);
        passlen2 = MIN(passlen2, MAX_PASS_LEN);
 
-       if (doencrypt)
+       if (doencrypt || (lp_security() == SEC_SERVER))
        {
                /* Save the lanman2 password and the NT md4 password. */
                *smb_passlen = passlen1;
                memcpy(smb_passwd,p,*smb_passlen);
+               smb_passwd[passlen1] = 0;
 
                *smb_nt_passlen = passlen2;
                memcpy(smb_nt_passwd,p+passlen1,*smb_nt_passlen);
+               smb_nt_passwd[passlen2] = 0;
        }
        else
        {
index fe00cbf920cb47a97afd6829826d9ca24f6f78a6..c78b88c46c657602d69e7aba0eae87045375df6c 100644 (file)
@@ -1525,6 +1525,11 @@ void close_file(int fnum, BOOL normal_close)
 
   fs_p->sent_oplock_break = False;
 
+  if(fs_p->granted_oplock == True)
+    global_oplocks_open--;
+
+  fs_p->sent_oplock_break = False;
+
   DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
           timestring(),Connections[cnum].user,fs_p->name,
           Connections[cnum].num_files_open));
@@ -2982,6 +2987,14 @@ inode = %x).\n", timestring(), fsp->name, fnum, dev, inode));
   free(inbuf);
   free(outbuf);
 
+  /* We need this in case a readraw crossed on the wire. */
+  if(global_oplock_break)
+    global_oplock_break = False;
+
+  /* Free the buffers we've been using to recurse. */
+  free(inbuf);
+  free(outbuf);
+
   /* We need this in case a readraw crossed on the wire. */
   if(global_oplock_break)
     global_oplock_break = False;
@@ -3173,7 +3186,6 @@ oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
 /****************************************************************************
 Get the next SMB packet, doing the local message processing automatically.
 ****************************************************************************/
-
 BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
 {
   BOOL got_smb = False;
@@ -5193,6 +5205,10 @@ static void usage(char *pname)
       argc--;
     }
 
+  if (!directory_exist(lp_lockdir(), NULL)) {
+         mkdir(lp_lockdir(), 0755);
+  }
+
   while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
     switch (opt)
       {
index ce4a45005020d7b4b50d447180b4a90923172547..e40b3ce40182f1aebd95b43fab54282099994747 100644 (file)
@@ -734,6 +734,14 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum
   if(numentries == 0)
     return(ERROR(ERRDOS,ERRbadfile));
 
+  /* 
+   * If there are no matching entries we must return ERRDOS/ERRbadfile - 
+   * from observation of NT.
+   */
+
+  if(numentries == 0)
+    return(ERROR(ERRDOS,ERRbadfile));
+
   /* At this point pdata points to numentries directory entries. */
 
   /* Set up the return parameter block */
index 2cd8d1cbedf02390c99601f1755c3329c05ac388..29ecc7474085d4e88aee365d880cb2d7d58016af 100644 (file)
  *
  * -------------------------------------------------------------------------- **
  *
- * Log: ubi_AVLtree.c,v
- * Revision 2.5  1997/12/23 04:00:42  crh
- * In this version, all constants & macros defined in the header file have
- * the ubi_tr prefix.  Also cleaned up anything that gcc complained about
- * when run with '-pedantic -fsyntax-only -Wall'.
- *
  * Revision 2.4  1997/07/26 04:36:20  crh
  * Andrew Leppard, aka "Grazgur", discovered that I still had my brains tied
  * on backwards with respect to node deletion.  I did some more digging and
  */
 
 static char ModuleID[] = "ubi_AVLtree\n\
-\tRevision: 2.5\n\
-\tDate: 1997/12/23 04:00:42\n\
+\tRevision: 2.4\n\
+\tDate: 1997/07/26 04:36:20\n\
 \tAuthor: crh\n";
 
 /* ========================================================================== **
@@ -159,22 +153,22 @@ static ubi_avlNodePtr L1( ubi_avlNodePtr p )
   {
   ubi_avlNodePtr tmp;
 
-  tmp                      = p->Link[ubi_trRIGHT];
-  p->Link[ubi_trRIGHT]     = tmp->Link[ubi_trLEFT];
-  tmp->Link[ubi_trLEFT]    = p;
-
-  tmp->Link[ubi_trPARENT]  = p->Link[ubi_trPARENT];
-  tmp->gender              = p->gender;
-  if(tmp->Link[ubi_trPARENT])
-    (tmp->Link[ubi_trPARENT])->Link[(int)(tmp->gender)] = tmp;
-  p->Link[ubi_trPARENT]    = tmp;
-  p->gender                = ubi_trLEFT;
-  if( p->Link[ubi_trRIGHT] )
+  tmp                = p->Link[RIGHT];
+  p->Link[RIGHT]     = tmp->Link[LEFT];
+  tmp->Link[LEFT]    = p;
+
+  tmp->Link[PARENT]  = p->Link[PARENT];
+  tmp->gender        = p->gender;
+  if(tmp->Link[PARENT])
+    (tmp->Link[PARENT])->Link[(tmp->gender)] = tmp;
+  p->Link[PARENT]    = tmp;
+  p->gender          LEFT;
+  if( p->Link[RIGHT] )
     {
-    p->Link[ubi_trRIGHT]->Link[ubi_trPARENT] = p;
-    (p->Link[ubi_trRIGHT])->gender           = ubi_trRIGHT;
+    p->Link[RIGHT]->Link[PARENT] = p;
+    (p->Link[RIGHT])->gender     = RIGHT;
     }
-  p->balance -= ubi_trNormalize( tmp->balance );
+  p->balance -= Normalize( tmp->balance );
   (tmp->balance)--;
   return( tmp );
   } /* L1 */
@@ -191,22 +185,22 @@ static ubi_avlNodePtr R1( ubi_avlNodePtr p )
   {
   ubi_avlNodePtr tmp;
 
-  tmp                      = p->Link[ubi_trLEFT];
-  p->Link[ubi_trLEFT]      = tmp->Link[ubi_trRIGHT];
-  tmp->Link[ubi_trRIGHT]   = p;
-
-  tmp->Link[ubi_trPARENT]  = p->Link[ubi_trPARENT];
-  tmp->gender              = p->gender;
-  if(tmp->Link[ubi_trPARENT])
-    (tmp->Link[ubi_trPARENT])->Link[(int)(tmp->gender)] = tmp;
-  p->Link[ubi_trPARENT]    = tmp;
-  p->gender                = ubi_trRIGHT;
-  if(p->Link[ubi_trLEFT])
+  tmp                = p->Link[LEFT];
+  p->Link[LEFT]      = tmp->Link[RIGHT];
+  tmp->Link[RIGHT]   = p;
+
+  tmp->Link[PARENT]  = p->Link[PARENT];
+  tmp->gender        = p->gender;
+  if(tmp->Link[PARENT])
+    (tmp->Link[PARENT])->Link[(tmp->gender)] = tmp;
+  p->Link[PARENT]    = tmp;
+  p->gender          RIGHT;
+  if(p->Link[LEFT])
     {
-    p->Link[ubi_trLEFT]->Link[ubi_trPARENT]  = p;
-    p->Link[ubi_trLEFT]->gender              = ubi_trLEFT;
+    p->Link[LEFT]->Link[PARENT]  = p;
+    p->Link[LEFT]->gender        = LEFT;
     }
-  p->balance -= ubi_trNormalize( tmp->balance );
+  p->balance -= Normalize( tmp->balance );
   (tmp->balance)++;
   return( tmp );
   } /* R1 */
@@ -223,43 +217,43 @@ static ubi_avlNodePtr L2( ubi_avlNodePtr tree )
   {
   ubi_avlNodePtr tmp, newroot;
 
-  tmp                         = tree->Link[ubi_trRIGHT];
-  newroot                     = tmp->Link[ubi_trLEFT];
-  tmp->Link[ubi_trLEFT]       = newroot->Link[ubi_trRIGHT];
-  newroot->Link[ubi_trRIGHT]  = tmp;
-  tree->Link[ubi_trRIGHT]     = newroot->Link[ubi_trLEFT];
-  newroot->Link[ubi_trLEFT]   = tree;
-
-  newroot->Link[ubi_trPARENT] = tree->Link[ubi_trPARENT];
-  newroot->gender             = tree->gender;
-  tree->Link[ubi_trPARENT]    = newroot;
-  tree->gender                = ubi_trLEFT;
-  tmp->Link[ubi_trPARENT]     = newroot;
-  tmp->gender                 = ubi_trRIGHT;
-
-  if( tree->Link[ubi_trRIGHT] )
+  tmp                   = tree->Link[RIGHT];
+  newroot               = tmp->Link[LEFT];
+  tmp->Link[LEFT]       = newroot->Link[RIGHT];
+  newroot->Link[RIGHT]  = tmp;
+  tree->Link[RIGHT]     = newroot->Link[LEFT];
+  newroot->Link[LEFT]   = tree;
+
+  newroot->Link[PARENT] = tree->Link[PARENT];
+  newroot->gender       = tree->gender;
+  tree->Link[PARENT]    = newroot;
+  tree->gender          LEFT;
+  tmp->Link[PARENT]     = newroot;
+  tmp->gender           RIGHT;
+
+  if( tree->Link[RIGHT] )
     {
-    tree->Link[ubi_trRIGHT]->Link[ubi_trPARENT] = tree;
-    tree->Link[ubi_trRIGHT]->gender             = ubi_trRIGHT;
+    tree->Link[RIGHT]->Link[PARENT] = tree;
+    tree->Link[RIGHT]->gender       = RIGHT;
     }
-  if( tmp->Link[ubi_trLEFT] )
+  if( tmp->Link[LEFT] )
     {
-    tmp->Link[ubi_trLEFT]->Link[ubi_trPARENT]   = tmp;
-    tmp->Link[ubi_trLEFT]->gender               = ubi_trLEFT;
+    tmp->Link[LEFT]->Link[PARENT]   = tmp;
+    tmp->Link[LEFT]->gender         = LEFT;
     }
-  if(newroot->Link[ubi_trPARENT])
-    newroot->Link[ubi_trPARENT]->Link[(int)(newroot->gender)] = newroot;
+  if(newroot->Link[PARENT])
+    newroot->Link[PARENT]->Link[newroot->gender] = newroot;
 
   switch( newroot->balance )
     {
-    case ubi_trLEFT :
-      tree->balance = ubi_trEQUAL; tmp->balance = ubi_trRIGHT; break;
-    case ubi_trEQUAL:
-      tree->balance = ubi_trEQUAL; tmp->balance = ubi_trEQUAL; break;
-    case ubi_trRIGHT:
-      tree->balance = ubi_trLEFT;  tmp->balance = ubi_trEQUAL; break;
+    case LEFT :
+      tree->balance = EQUAL; tmp->balance = RIGHT; break;
+    case EQUAL:
+      tree->balance = EQUAL; tmp->balance = EQUAL; break;
+    case RIGHT:
+      tree->balance = LEFT;  tmp->balance = EQUAL; break;
     }
-  newroot->balance = ubi_trEQUAL;
+  newroot->balance = EQUAL;
   return( newroot );
   } /* L2 */
 
@@ -275,43 +269,43 @@ static ubi_avlNodePtr R2( ubi_avlNodePtr tree )
   {
   ubi_avlNodePtr tmp, newroot;
 
-  tmp                         = tree->Link[ubi_trLEFT];
-  newroot                     = tmp->Link[ubi_trRIGHT];
-  tmp->Link[ubi_trRIGHT]      = newroot->Link[ubi_trLEFT];
-  newroot->Link[ubi_trLEFT]   = tmp;
-  tree->Link[ubi_trLEFT]      = newroot->Link[ubi_trRIGHT];
-  newroot->Link[ubi_trRIGHT]  = tree;
-
-  newroot->Link[ubi_trPARENT] = tree->Link[ubi_trPARENT];
-  newroot->gender             = tree->gender;
-  tree->Link[ubi_trPARENT]    = newroot;
-  tree->gender                = ubi_trRIGHT;
-  tmp->Link[ubi_trPARENT]     = newroot;
-  tmp->gender                 = ubi_trLEFT;
-
-  if( tree->Link[ubi_trLEFT] )
+  tmp                   = tree->Link[LEFT];
+  newroot               = tmp->Link[RIGHT];
+  tmp->Link[RIGHT]      = newroot->Link[LEFT];
+  newroot->Link[LEFT]   = tmp;
+  tree->Link[LEFT]      = newroot->Link[RIGHT];
+  newroot->Link[RIGHT]  = tree;
+
+  newroot->Link[PARENT] = tree->Link[PARENT];
+  newroot->gender       = tree->gender;
+  tree->Link[PARENT]    = newroot;
+  tree->gender          RIGHT;
+  tmp->Link[PARENT]     = newroot;
+  tmp->gender           LEFT;
+
+  if( tree->Link[LEFT] )
     {
-    tree->Link[ubi_trLEFT]->Link[ubi_trPARENT]  = tree;
-    tree->Link[ubi_trLEFT]->gender              = ubi_trLEFT;
+    tree->Link[LEFT]->Link[PARENT]  = tree;
+    tree->Link[LEFT]->gender        = LEFT;
     }
-  if( tmp->Link[ubi_trRIGHT] )
+  if( tmp->Link[RIGHT] )
     {
-    tmp->Link[ubi_trRIGHT]->Link[ubi_trPARENT]  = tmp;
-    tmp->Link[ubi_trRIGHT]->gender              = ubi_trRIGHT;
+    tmp->Link[RIGHT]->Link[PARENT]  = tmp;
+    tmp->Link[RIGHT]->gender        = RIGHT;
     }
-  if(newroot->Link[ubi_trPARENT])
-    newroot->Link[ubi_trPARENT]->Link[(int)(newroot->gender)] = newroot;
+  if(newroot->Link[PARENT])
+    newroot->Link[PARENT]->Link[newroot->gender] = newroot;
 
   switch( newroot->balance )
     {
-    case ubi_trLEFT  :
-      tree->balance = ubi_trRIGHT; tmp->balance = ubi_trEQUAL; break;
-    case ubi_trEQUAL :
-      tree->balance = ubi_trEQUAL; tmp->balance = ubi_trEQUAL; break;
-    case ubi_trRIGHT :
-      tree->balance = ubi_trEQUAL; tmp->balance = ubi_trLEFT;  break;
+    case LEFT  :
+      tree->balance = RIGHT; tmp->balance = EQUAL; break;
+    case EQUAL :
+      tree->balance = EQUAL; tmp->balance = EQUAL; break;
+    case RIGHT :
+      tree->balance = EQUAL; tmp->balance = LEFT;  break;
     }
-  newroot->balance = ubi_trEQUAL;
+  newroot->balance = EQUAL;
   return( newroot );
   } /* R2 */
 
@@ -335,16 +329,16 @@ static ubi_avlNodePtr Adjust( ubi_avlNodePtr p, char LorR )
    */
   {
   if( p->balance != LorR )
-    p->balance += ubi_trNormalize(LorR);
+    p->balance += Normalize(LorR);
   else
     {
     char tallerbal;  /* Balance value of the root of the taller subtree of p. */
 
-    tallerbal = p->Link[(int)LorR]->balance;
-    if( ( ubi_trEQUAL == tallerbal ) || ( p->balance == tallerbal ) )
-      p = ( (ubi_trLEFT==LorR) ? R1(p) : L1(p) );   /* single rotation */
+    tallerbal = p->Link[LorR]->balance;
+    if( ( EQUAL == tallerbal ) || ( p->balance == tallerbal ) )
+      p = ( (LEFT==LorR) ? R1(p) : L1(p) );   /* single rotation */
     else
-      p = ( (ubi_trLEFT==LorR) ? R2(p) : L2(p) );   /* double rotation */
+      p = ( (LEFT==LorR) ? R2(p) : L2(p) );   /* double rotation */
     }
   return( p );
   } /* Adjust */
@@ -377,12 +371,12 @@ static ubi_avlNodePtr Rebalance( ubi_avlNodePtr Root,
   while( subtree )
     {
     subtree = Adjust( subtree, LorR );
-    if( ubi_trPARENT == subtree->gender )
+    if( PARENT == subtree->gender )
       return( subtree );
-    if( ubi_trEQUAL == subtree->balance )
+    if( EQUAL == subtree->balance )
       return( Root );
     LorR = subtree->gender;
-    subtree = subtree->Link[ubi_trPARENT];
+    subtree = subtree->Link[PARENT];
     }
   return( Root );
   } /* Rebalance */
@@ -417,13 +411,13 @@ static ubi_avlNodePtr Debalance( ubi_avlNodePtr Root,
   {
   while( subtree )
     {
-    subtree = Adjust( subtree, ubi_trRevWay(LorR) );
-    if( ubi_trPARENT == subtree->gender )
+    subtree = Adjust( subtree, RevWay(LorR) );
+    if( PARENT == subtree->gender )
       return( subtree );
-    if( ubi_trEQUAL != subtree->balance )
+    if( EQUAL != subtree->balance )
       return( Root );
     LorR = subtree->gender;
-    subtree = subtree->Link[ubi_trPARENT];
+    subtree = subtree->Link[PARENT];
     }
   return( Root );
   } /* Debalance */
@@ -464,10 +458,10 @@ static void ReplaceNode( ubi_avlNodePtr *parent,
     ((unsigned char *)newnode)[i] = ((unsigned char *)oldnode)[i];
   (*parent) = newnode;
 
-  if(oldnode->Link[ubi_trLEFT ] )
-    (oldnode->Link[ubi_trLEFT ])->Link[ubi_trPARENT] = newnode;
-  if(oldnode->Link[ubi_trRIGHT] )
-    (oldnode->Link[ubi_trRIGHT])->Link[ubi_trPARENT] = newnode;
+  if(oldnode->Link[LEFT ] )
+    (oldnode->Link[LEFT ])->Link[PARENT] = newnode;
+  if(oldnode->Link[RIGHT] )
+    (oldnode->Link[RIGHT])->Link[PARENT] = newnode;
   } /* ReplaceNode */
 
 static void SwapNodes( ubi_btRootPtr  RootPtr,
@@ -495,20 +489,20 @@ static void SwapNodes( ubi_btRootPtr  RootPtr,
   ubi_avlNode     dummy;
   ubi_avlNodePtr  dummy_p = &dummy;
 
-  if( Node1->Link[ubi_trPARENT] )
-    Parent = &((Node1->Link[ubi_trPARENT])->Link[(int)(Node1->gender)]);
+  if( Node1->Link[PARENT] )
+    Parent = &((Node1->Link[PARENT])->Link[Node1->gender]);
   else
     Parent = (ubi_avlNodePtr *)&(RootPtr->root);
   ReplaceNode( Parent, Node1, dummy_p );
 
-  if( Node2->Link[ubi_trPARENT] )
-    Parent = &((Node2->Link[ubi_trPARENT])->Link[(int)(Node2->gender)]);
+  if( Node2->Link[PARENT] )
+    Parent = &((Node2->Link[PARENT])->Link[Node2->gender]);
   else
     Parent = (ubi_avlNodePtr *)&(RootPtr->root);
   ReplaceNode( Parent, Node2, Node1 );
 
-  if( dummy_p->Link[ubi_trPARENT] )
-    Parent = &((dummy_p->Link[ubi_trPARENT])->Link[(int)(dummy_p->gender)]);
+  if( dummy_p->Link[PARENT] )
+    Parent = &((dummy_p->Link[PARENT])->Link[dummy_p->gender]);
   else
     Parent = (ubi_avlNodePtr *)&(RootPtr->root);
   ReplaceNode( Parent, dummy_p, Node2 );
@@ -532,7 +526,7 @@ ubi_avlNodePtr ubi_avlInitNode( ubi_avlNodePtr NodePtr )
    */
   {
   (void)ubi_btInitNode( (ubi_btNodePtr)NodePtr );
-  NodePtr->balance = ubi_trEQUAL;
+  NodePtr->balance = EQUAL;
   return( NodePtr );
   } /* ubi_avlInitNode */
 
@@ -597,9 +591,9 @@ ubi_trBool ubi_avlInsert( ubi_btRootPtr   RootPtr,
       NewNode->balance = (*OldNode)->balance;
     else
       {
-      NewNode->balance = ubi_trEQUAL;
+      NewNode->balance = EQUAL;
       RootPtr->root = (ubi_btNodePtr)Rebalance( (ubi_avlNodePtr)RootPtr->root,
-                                                NewNode->Link[ubi_trPARENT],
+                                                NewNode->Link[PARENT],
                                                 NewNode->gender );
       }
     return( ubi_trTRUE );
@@ -631,33 +625,33 @@ ubi_avlNodePtr ubi_avlRemove( ubi_btRootPtr  RootPtr,
   /* if the node has both left and right subtrees, then we have to swap
    * it with another node.
    */
-  if( (DeadNode->Link[ubi_trLEFT]) && (DeadNode->Link[ubi_trRIGHT]) )
+  if( (DeadNode->Link[LEFT]) && (DeadNode->Link[RIGHT]) )
     SwapNodes( RootPtr, DeadNode, ubi_trPrev( DeadNode ) );
 
   /* The parent of the node to be deleted may be another node, or it may be
    * the root of the tree.  Since we're not sure, it's best just to have
    * a pointer to the parent pointer, whatever it is.
    */
-  if( DeadNode->Link[ubi_trPARENT] )
+  if( DeadNode->Link[PARENT] )
     parentp = (ubi_btNodePtr *)
-              &((DeadNode->Link[ubi_trPARENT])->Link[(int)(DeadNode->gender)]);
+              &((DeadNode->Link[PARENT])->Link[(DeadNode->gender)]);
   else
     parentp = &( RootPtr->root );
 
   /* Now link the parent to the only grand-child.  Patch up the gender and
    * such, and rebalance.
    */
-  if( ubi_trEQUAL == DeadNode->balance )
+  if( EQUAL == DeadNode->balance )
     (*parentp) = NULL;
   else
     {
-    p = (ubi_btNodePtr)(DeadNode->Link[(int)(DeadNode->balance)]);
-    p->Link[ubi_trPARENT] = (ubi_btNodePtr)DeadNode->Link[ubi_trPARENT];
-    p->gender  = DeadNode->gender;
+    p = (ubi_btNodePtr)(DeadNode->Link[(DeadNode->balance)]);
+    p->Link[PARENT]  = (ubi_btNodePtr)DeadNode->Link[PARENT];
+    p->gender        = DeadNode->gender;
     (*parentp) = p;
     }
   RootPtr->root = (ubi_btNodePtr)Debalance( (ubi_avlNodePtr)RootPtr->root,
-                                            DeadNode->Link[ubi_trPARENT],
+                                            DeadNode->Link[PARENT],
                                             DeadNode->gender );
 
   (RootPtr->count)--;
index ebae7f3c1316e53a3aae716741badd3c5149a82c..b86f24a412b95049caedcf5a42d6657648a9e037 100644 (file)
  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * -------------------------------------------------------------------------- **
- * Log: ubi_AVLtree.h,v
- * Revision 2.5  1997/12/23 04:00:15  crh
- * In this version, all constants & macros defined in the header file have
- * the ubi_tr prefix.  Also cleaned up anything that gcc complained about
- * when run with '-pedantic -fsyntax-only -Wall'.
  *
  * Revision 2.4  1997/07/26 04:36:23  crh
  * Andrew Leppard, aka "Grazgur", discovered that I still had my brains tied
@@ -159,7 +154,7 @@ typedef struct ubi_avlNodeStruct {
                         /* that may be balanced, or be one node longer to the */
                         /* right or left.  This field keeps track of the      */
                         /* balance value of each node.                        */
-    } ubi_avlNode;
+    } ubi_avlNode;  /* Typedef'd name for an avl tree node. */
 
 typedef ubi_avlNode *ubi_avlNodePtr;    /* a Pointer to an AVL node */
 
index 501f3eeca79812c435f86cdf03e7f73e7a8b4e6a..68e819a14b2cd7d118aff476df96537bd81815f6 100644 (file)
@@ -6,7 +6,12 @@
  *  Email:  crh@ubiqx.mn.org
  * -------------------------------------------------------------------------- **
  *
- *  This module implements a simple binary tree.
+ *  ubi_BinTree manages a simple binary tree.  Nothing fancy here.  No height
+ *  balancing, no restructuring.  Still, a good tool for creating short, low-
+ *  overhead sorted lists of things that need to be found in a hurry.
+ *
+ *  In addition, this module provides a good basis for creating other types
+ *  of binary tree handling modules.
  *
  * -------------------------------------------------------------------------- **
  *
  *
  * -------------------------------------------------------------------------- **
  *
- * Log: ubi_BinTree.c,v
- * Revision 2.5  1997/12/23 03:56:29  crh
- * In this version, all constants & macros defined in the header file have
- * the ubi_tr prefix.  Also cleaned up anything that gcc complained about
- * when run with '-pedantic -fsyntax-only -Wall'.
- *
  * Revision 2.4  1997/07/26 04:11:10  crh
  * + Just to be annoying I changed ubi_TRUE and ubi_FALSE to ubi_trTRUE
  *   and ubi_trFALSE.
  */
 
 static char ModuleID[] = "ubi_BinTree\n\
-\tRevision: 2.5\n\
-\tDate: 1997/12/23 03:56:29\n\
+\tRevision: 2.4\n\
+\tDate: 1997/07/26 04:11:10\n\
 \tAuthor: crh\n";
 
 /* ========================================================================== **
@@ -149,9 +148,9 @@ static ubi_btNodePtr qFind( ubi_btCompFunc cmp,
    * ------------------------------------------------------------------------ **
    */
   {
-  int tmp;
+  char tmp;
 
-  while( p && (( tmp = ubi_trAbNormal((*cmp)(FindMe, p)) ) != ubi_trEQUAL) )
+  while( p && (( tmp = AbNormal((*cmp)(FindMe, p)) ) != EQUAL) )
     p = p->Link[tmp];
 
   return( p );
@@ -190,19 +189,18 @@ static ubi_btNodePtr TreeFind( ubi_btItemPtr  findme,
    */
   {
   register ubi_btNodePtr tmp_p = p;
-  ubi_btNodePtr tmp_pp         = NULL;
-  int tmp_gender               = ubi_trEQUAL;
-  int tmp_cmp;
+  ubi_btNodePtr tmp_pp = NULL;
+  char tmp_sex = EQUAL;
+  char tmp_cmp;
 
-  while( tmp_p
-     && (ubi_trEQUAL != (tmp_cmp = ubi_trAbNormal((*CmpFunc)(findme, tmp_p)))) )
+  while( tmp_p && (EQUAL != (tmp_cmp = AbNormal((*CmpFunc)(findme, tmp_p)))) )
     {
-    tmp_pp     = tmp_p;                 /* Keep track of previous node. */
-    tmp_gender = tmp_cmp;               /* Keep track of sex of child.  */
-    tmp_p      = tmp_p->Link[tmp_cmp];  /* Go to child. */
+    tmp_pp  = tmp_p;                /* Keep track of previous node. */
+    tmp_sex = tmp_cmp;              /* Keep track of sex of child.  */
+    tmp_p = tmp_p->Link[tmp_cmp];   /* Go to child. */
     }
   *parentp = tmp_pp;                /* Return results. */
-  *gender  = tmp_gender;
+  *gender  = tmp_sex;
   return( tmp_p );
   } /* TreeFind */
 
@@ -237,10 +235,8 @@ static void ReplaceNode( ubi_btNodePtr *parent,
     ((unsigned char *)newnode)[i] = ((unsigned char *)oldnode)[i];
   (*parent) = newnode;              /* Old node's parent points to new child. */
   /* Now tell the children about their new step-parent. */
-  if( oldnode->Link[ubi_trLEFT] )
-    (oldnode->Link[ubi_trLEFT])->Link[ubi_trPARENT] = newnode;
-  if( oldnode->Link[ubi_trRIGHT] )
-    (oldnode->Link[ubi_trRIGHT])->Link[ubi_trPARENT] = newnode;
+  if( oldnode->Link[LEFT ] ) (oldnode->Link[LEFT ])->Link[PARENT] = newnode;
+  if( oldnode->Link[RIGHT] ) (oldnode->Link[RIGHT])->Link[PARENT] = newnode;
   } /* ReplaceNode */
 
 static void SwapNodes( ubi_btRootPtr RootPtr,
@@ -267,22 +263,22 @@ static void SwapNodes( ubi_btRootPtr RootPtr,
   ubi_btNodePtr  dummy_p = &dummy;
 
   /* Replace Node 1 with the dummy, thus removing Node1 from the tree. */
-  if( Node1->Link[ubi_trPARENT] )
-    Parent = &((Node1->Link[ubi_trPARENT])->Link[(int)(Node1->gender)]);
+  if( Node1->Link[PARENT] )
+    Parent = &((Node1->Link[PARENT])->Link[Node1->gender]);
   else
     Parent = &(RootPtr->root);
   ReplaceNode( Parent, Node1, dummy_p );
 
   /* Swap Node 1 with Node 2, placing Node 1 back into the tree. */
-  if( Node2->Link[ubi_trPARENT] )
-    Parent = &((Node2->Link[ubi_trPARENT])->Link[(int)(Node2->gender)]);
+  if( Node2->Link[PARENT] )
+    Parent = &((Node2->Link[PARENT])->Link[Node2->gender]);
   else
     Parent = &(RootPtr->root);
   ReplaceNode( Parent, Node2, Node1 );
 
   /* Swap Node 2 and the dummy, thus placing Node 2 back into the tree. */
-  if( dummy_p->Link[ubi_trPARENT] )
-    Parent = &((dummy_p->Link[ubi_trPARENT])->Link[(int)(dummy_p->gender)]);
+  if( dummy_p->Link[PARENT] )
+    Parent = &((dummy_p->Link[PARENT])->Link[dummy_p->gender]);
   else
     Parent = &(RootPtr->root);
   ReplaceNode( Parent, dummy_p, Node2 );
@@ -293,7 +289,7 @@ static void SwapNodes( ubi_btRootPtr RootPtr,
  */
 
 static ubi_btNodePtr SubSlide( register ubi_btNodePtr P,
-                               register int           whichway )
+                               register char  whichway )
   /* ------------------------------------------------------------------------ **
    * Slide down the side of a subtree.
    *
@@ -321,7 +317,7 @@ static ubi_btNodePtr SubSlide( register ubi_btNodePtr P,
   } /* SubSlide */
 
 static ubi_btNodePtr Neighbor( register ubi_btNodePtr P,
-                               register int           whichway )
+                               register char  whichway )
   /* ------------------------------------------------------------------------ **
    * Given starting point p, return the (key order) next or preceeding node
    * in the tree.
@@ -340,14 +336,14 @@ static ubi_btNodePtr Neighbor( register ubi_btNodePtr P,
   if( P )
     {
     if( P->Link[ whichway ] )
-      return( SubSlide( P->Link[ whichway ], (char)ubi_trRevWay(whichway) ) );
+      return( SubSlide( P->Link[ whichway ], (char)RevWay(whichway) ) );
     else
-      while( P->Link[ ubi_trPARENT ] )
+      while( P->Link[ PARENT ] )
         {
-        if( (P->Link[ ubi_trPARENT ])->Link[ whichway ] == P )
-          P = P->Link[ ubi_trPARENT ];
+        if( (P->Link[ PARENT ])->Link[ whichway ] == P )
+          P = P->Link[ PARENT ];
         else
-          return( P->Link[ ubi_trPARENT ] );
+          return( P->Link[ PARENT ] );
         }
     }
   return( NULL );
@@ -356,7 +352,7 @@ static ubi_btNodePtr Neighbor( register ubi_btNodePtr P,
 static ubi_btNodePtr Border( ubi_btRootPtr RootPtr,
                              ubi_btItemPtr FindMe,
                              ubi_btNodePtr p,
-                             int           whichway )
+                             char          whichway )
   /* ------------------------------------------------------------------------ **
    * Given starting point p, which has a key value equal to *FindMe, locate
    * the first (index order) node with the same key value.
@@ -388,25 +384,24 @@ static ubi_btNodePtr Border( ubi_btRootPtr RootPtr,
   register ubi_btNodePtr q;
 
   /* Exit if there's nothing that can be done. */
-  if( !ubi_trDups_OK( RootPtr ) || (ubi_trPARENT == whichway) )
+  if( !Dups_OK( RootPtr ) || (PARENT == whichway) )
     return( p );
 
   /* First, if needed, move up the tree.  We need to get to the root of the
    * subtree that contains all of the matching nodes.
    */
-  q = p->Link[ubi_trPARENT];
-  while( q && (ubi_trEQUAL == ubi_trAbNormal( (*(RootPtr->cmp))(FindMe, q) )) )
+  q = p->Link[PARENT];
+  while( q && (EQUAL == AbNormal( (*(RootPtr->cmp))(FindMe, q) )) )
     {
     p = q;
-    q = p->Link[ubi_trPARENT];
+    q = p->Link[PARENT];
     }
 
   /* Next, move back down in the "whichway" direction. */
   q = p->Link[whichway];
   while( q )
     {
-    q = qFind( RootPtr->cmp, FindMe, q );
-    if( q )
+    if( q = qFind( RootPtr->cmp, FindMe, q ) )
       {
       p = q;
       q = p->Link[whichway];
@@ -434,7 +429,7 @@ long ubi_btSgn( register long x )
    * Note: This utility is provided in order to facilitate the conversion
    *       of C comparison function return values into BinTree direction
    *       values: {LEFT, PARENT, EQUAL}.  It is INCORPORATED into the
-   *       ubi_trAbNormal() conversion macro!
+   *       AbNormal() conversion macro!
    *
    * ------------------------------------------------------------------------ **
    */
@@ -452,10 +447,10 @@ ubi_btNodePtr ubi_btInitNode( ubi_btNodePtr NodePtr )
    * ------------------------------------------------------------------------ **
    */
   {
-  NodePtr->Link[ ubi_trLEFT ]   = NULL;
-  NodePtr->Link[ ubi_trPARENT ] = NULL;
-  NodePtr->Link[ ubi_trRIGHT ]  = NULL;
-  NodePtr->gender               = ubi_trEQUAL;
+  NodePtr->Link[ LEFT ]   = NULL;
+  NodePtr->Link[ PARENT ] = NULL;
+  NodePtr->Link[ RIGHT ]  = NULL;
+  NodePtr->gender         EQUAL;
   return( NodePtr );
   } /* ubi_btInitNode */
 
@@ -565,9 +560,9 @@ ubi_trBool ubi_btInsert( ubi_btRootPtr  RootPtr,
       RootPtr->root = NewNode;
     else
       {
-      parent->Link[(int)tmp]      = NewNode;
-      NewNode->Link[ubi_trPARENT] = parent;
-      NewNode->gender             = tmp;
+      parent->Link[tmp]     = NewNode;
+      NewNode->Link[PARENT] = parent;
+      NewNode->gender       = tmp;
       }
     (RootPtr->count)++;
     return( ubi_trTRUE );
@@ -576,25 +571,24 @@ ubi_trBool ubi_btInsert( ubi_btRootPtr  RootPtr,
   /* If we reach this point, we know that a duplicate node exists.  This
    * section adds the node to the tree if duplicate keys are allowed.
    */
-  if( ubi_trDups_OK(RootPtr) )    /* Key exists, add duplicate */
+  if( Dups_OK(RootPtr) )    /* Key exists, add duplicate */
     {
     ubi_btNodePtr q;
 
-    tmp = ubi_trRIGHT;
+    tmp = RIGHT;
     q = (*OldNode);
     *OldNode = NULL;
     while( q )
       {
       parent = q;
-      if( tmp == ubi_trEQUAL )
-        tmp = ubi_trRIGHT;
-      q = q->Link[(int)tmp];
+      if( tmp == EQUAL ) tmp = RIGHT;
+      q = q->Link[tmp];
       if ( q )
-        tmp = ubi_trAbNormal( (*(RootPtr->cmp))(ItemPtr, q) );
+        tmp = AbNormal( (*(RootPtr->cmp))(ItemPtr, q) );
       }
-    parent->Link[(int)tmp]       = NewNode;
-    NewNode->Link[ubi_trPARENT]  = parent;
-    NewNode->gender              = tmp;
+    parent->Link[tmp]      = NewNode;
+    NewNode->Link[PARENT]  = parent;
+    NewNode->gender        = tmp;
     (RootPtr->count)++;
     return( ubi_trTRUE );
     }
@@ -603,13 +597,12 @@ ubi_trBool ubi_btInsert( ubi_btRootPtr  RootPtr,
    * duplicate nodes, but our node keys match, so... may we replace the
    * old one?
    */
-  if( ubi_trOvwt_OK(RootPtr) )    /* Key exists, we replace */
+  if( Ovwt_OK(RootPtr) )    /* Key exists, we replace */
     {
     if (!(parent))
       ReplaceNode( &(RootPtr->root), *OldNode, NewNode );
     else
-      ReplaceNode( &(parent->Link[(int)((*OldNode)->gender)]),
-                   *OldNode, NewNode );
+      ReplaceNode( &(parent->Link[(*OldNode)->gender]), *OldNode, NewNode );
     return( ubi_trTRUE );
     }
 
@@ -635,31 +628,31 @@ ubi_btNodePtr ubi_btRemove( ubi_btRootPtr RootPtr,
   {
   ubi_btNodePtr p,
                *parentp;
-  int           tmp;
+  char          tmp;
 
   /* if the node has both left and right subtrees, then we have to swap
    * it with another node.  The other node we choose will be the Prev()ious
    * node, which is garunteed to have no RIGHT child.
    */
-  if( (DeadNode->Link[ubi_trLEFT]) && (DeadNode->Link[ubi_trRIGHT]) )
+  if( (DeadNode->Link[LEFT]) && (DeadNode->Link[RIGHT]) )
     SwapNodes( RootPtr, DeadNode, ubi_btPrev( DeadNode ) );
 
   /* The parent of the node to be deleted may be another node, or it may be
    * the root of the tree.  Since we're not sure, it's best just to have
    * a pointer to the parent pointer, whatever it is.
    */
-  if (DeadNode->Link[ubi_trPARENT])
-    parentp = &((DeadNode->Link[ubi_trPARENT])->Link[(int)(DeadNode->gender)]);
+  if (DeadNode->Link[PARENT])
+    parentp = &((DeadNode->Link[PARENT])->Link[DeadNode->gender]);
   else
     parentp = &( RootPtr->root );
 
   /* Now link the parent to the only grand-child and patch up the gender. */
-  tmp = ((DeadNode->Link[ubi_trLEFT])?ubi_trLEFT:ubi_trRIGHT);
+  tmp = ((DeadNode->Link[LEFT])?LEFT:RIGHT);
 
   p = (DeadNode->Link[tmp]);
   if( p )
     {
-    p->Link[ubi_trPARENT] = DeadNode->Link[ubi_trPARENT];
+    p->Link[PARENT] = DeadNode->Link[PARENT];
     p->gender       = DeadNode->gender;
     }
   (*parentp) = p;
@@ -737,15 +730,14 @@ ubi_btNodePtr ubi_btLocate( ubi_btRootPtr RootPtr,
     switch( CompOp )
       {
       case ubi_trLT:            /* It's just a jump to the left...  */
-        p = Border( RootPtr, FindMe, p, ubi_trLEFT );
-        return( Neighbor( p, ubi_trLEFT ) );
+        p = Border( RootPtr, FindMe, p, LEFT );
+        return( Neighbor( p, LEFT ) );
       case ubi_trGT:            /* ...and then a jump to the right. */
-        p = Border( RootPtr, FindMe, p, ubi_trRIGHT );
-        return( Neighbor( p, ubi_trRIGHT ) );
-      default:
-        p = Border( RootPtr, FindMe, p, ubi_trLEFT );
-        return( p );
+        p = Border( RootPtr, FindMe, p, RIGHT );
+        return( Neighbor( p, RIGHT ) );
       }
+    p = Border( RootPtr, FindMe, p, LEFT );
+    return( p );
     }
 
   /* Else, no match. */
@@ -758,9 +750,9 @@ ubi_btNodePtr ubi_btLocate( ubi_btRootPtr RootPtr,
    * Remaining possibilities are LT and GT (including LE & GE).
    */
   if( (ubi_trLT == CompOp) || (ubi_trLE == CompOp) )
-    return( (ubi_trLEFT == whichkid) ? Neighbor( parent, whichkid ) : parent );
+    return( (LEFT  == whichkid) ? Neighbor( parent, whichkid ) : parent );
   else
-    return( (ubi_trRIGHT == whichkid) ? Neighbor( parent, whichkid ) : parent );
+    return( (RIGHT == whichkid) ? Neighbor( parent, whichkid ) : parent );
   } /* ubi_btLocate */
 
 ubi_btNodePtr ubi_btFind( ubi_btRootPtr RootPtr,
@@ -797,7 +789,7 @@ ubi_btNodePtr ubi_btNext( ubi_btNodePtr P )
    * ------------------------------------------------------------------------ **
    */
   {
-  return( Neighbor( P, ubi_trRIGHT ) );
+  return( Neighbor( P, RIGHT ) );
   } /* ubi_btNext */
 
 ubi_btNodePtr ubi_btPrev( ubi_btNodePtr P )
@@ -810,7 +802,7 @@ ubi_btNodePtr ubi_btPrev( ubi_btNodePtr P )
    * ------------------------------------------------------------------------ **
    */
   {
-  return( Neighbor( P, ubi_trLEFT ) );
+  return( Neighbor( P, LEFT ) );
   } /* ubi_btPrev */
 
 ubi_btNodePtr ubi_btFirst( ubi_btNodePtr P )
@@ -825,7 +817,7 @@ ubi_btNodePtr ubi_btFirst( ubi_btNodePtr P )
    * ------------------------------------------------------------------------ **
    */
   {
-  return( SubSlide( P, ubi_trLEFT ) );
+  return( SubSlide( P, LEFT ) );
   } /* ubi_btFirst */
 
 ubi_btNodePtr ubi_btLast( ubi_btNodePtr P )
@@ -840,7 +832,7 @@ ubi_btNodePtr ubi_btLast( ubi_btNodePtr P )
    * ------------------------------------------------------------------------ **
    */
   {
-  return( SubSlide( P, ubi_trRIGHT ) );
+  return( SubSlide( P, RIGHT ) );
   } /* ubi_btLast */
 
 ubi_btNodePtr ubi_btFirstOf( ubi_btRootPtr RootPtr,
@@ -863,9 +855,9 @@ ubi_btNodePtr ubi_btFirstOf( ubi_btRootPtr RootPtr,
    */
   {
   /* If our starting point is invalid, return NULL. */
-  if( !p || ubi_trAbNormal( (*(RootPtr->cmp))( MatchMe, p ) != ubi_trEQUAL ) )
+  if( !p || AbNormal( (*(RootPtr->cmp))( MatchMe, p ) != EQUAL ) )
     return( NULL );
-  return( Border( RootPtr, MatchMe, p, ubi_trLEFT ) );
+  return( Border( RootPtr, MatchMe, p, LEFT ) );
   } /* ubi_btFirstOf */
 
 ubi_btNodePtr ubi_btLastOf( ubi_btRootPtr RootPtr,
@@ -888,9 +880,9 @@ ubi_btNodePtr ubi_btLastOf( ubi_btRootPtr RootPtr,
    */
   {
   /* If our starting point is invalid, return NULL. */
-  if( !p || ubi_trAbNormal( (*(RootPtr->cmp))( MatchMe, p ) != ubi_trEQUAL ) )
+  if( !p || AbNormal( (*(RootPtr->cmp))( MatchMe, p ) != EQUAL ) )
     return( NULL );
-  return( Border( RootPtr, MatchMe, p, ubi_trRIGHT ) );
+  return( Border( RootPtr, MatchMe, p, RIGHT ) );
   } /* ubi_btLastOf */
 
 ubi_trBool ubi_btTraverse( ubi_btRootPtr   RootPtr,
@@ -949,11 +941,11 @@ ubi_trBool ubi_btKillTree( ubi_btRootPtr     RootPtr,
   while( p )
     {
     q = p;
-    while( q->Link[ubi_trRIGHT] )
-      q = SubSlide( q->Link[ubi_trRIGHT], ubi_trLEFT );
-    p = q->Link[ubi_trPARENT];
+    while( q->Link[RIGHT] )
+      q = SubSlide( q->Link[RIGHT], LEFT );
+    p = q->Link[PARENT];
     if( p )
-      p->Link[ ((p->Link[ubi_trLEFT] == q)?ubi_trLEFT:ubi_trRIGHT) ] = NULL;
+      p->Link[ ((p->Link[LEFT] == q)?LEFT:RIGHT) ] = NULL;
     FreeNode((void *)q);
     }
 
@@ -992,7 +984,7 @@ ubi_btNodePtr ubi_btLeafNode( ubi_btNodePtr leader )
    */
   {
   ubi_btNodePtr follower = NULL;
-  int           whichway = ubi_trLEFT;
+  int           whichway = LEFT;
 
   while( NULL != leader )
     {
@@ -1000,7 +992,7 @@ ubi_btNodePtr ubi_btLeafNode( ubi_btNodePtr leader )
     leader   = follower->Link[ whichway ];
     if( NULL == leader )
       {
-      whichway = ubi_trRevWay( whichway );
+      whichway = RevWay( whichway );
       leader   = follower->Link[ whichway ];
       }
     }
index 4b918a46096c7379c3ab7d732a64d5e751ad844d..ee512989f98b339d3d3fe37fdad3ed69d3417689 100644 (file)
@@ -8,7 +8,12 @@
  *  Email:  crh@ubiqx.mn.org
  * -------------------------------------------------------------------------- **
  *
- *  This module implements a simple binary tree.
+ *  ubi_BinTree manages a simple binary tree.  Nothing fancy here.  No height
+ *  balancing, no restructuring.  Still, a good tool for creating short, low-
+ *  overhead sorted lists of things that need to be found in a hurry.
+ *
+ *  In addition, this module provides a good basis for creating other types
+ *  of binary tree handling modules.
  *
  * -------------------------------------------------------------------------- **
  *
  *
  * -------------------------------------------------------------------------- **
  *
- * Log: ubi_BinTree.h,v
- * Revision 2.5  1997/12/23 03:59:21  crh
- * In this version, all constants & macros defined in the header file have
- * the ubi_tr prefix.  Also cleaned up anything that gcc complained about
- * when run with '-pedantic -fsyntax-only -Wall'.
- *
  * Revision 2.4  1997/07/26 04:11:14  crh
  * + Just to be annoying I changed ubi_TRUE and ubi_FALSE to ubi_trTRUE
  *   and ubi_trFALSE.
  *  Node link array index constants:  (Each node has an array of three
  *  pointers.  One to the left, one to the right, and one back to the
  *  parent.)
- *    ubi_trLEFT    - Left child pointer.
- *    ubi_trPARENT  - Parent pointer.
- *    ubi_trRIGHT   - Right child pointer.
- *    ubi_trEQUAL   - Synonym for PARENT.
+ *    LEFT    - Left child pointer.
+ *    PARENT  - Parent pointer.
+ *    RIGHT   - Right child pointer.
+ *    EQUAL   - Synonym for PARENT.
  *
  *  ubi_trCompOps:  These values are used in the ubi_trLocate() function.
  *    ubi_trLT  - request the first instance of the greatest key less than
 #define ubi_trDUPKEY    0x02        /* Turn on allow duplicate keys */
 
 /* Pointer array index constants... */
-#define ubi_trLEFT   0x00
-#define ubi_trPARENT 0x01
-#define ubi_trRIGHT  0x02
-#define ubi_trEQUAL  ubi_trPARENT
+#define LEFT   0x00
+#define PARENT 0x01
+#define RIGHT  0x02
+#define EQUAL  PARENT
 
 typedef enum {
   ubi_trLT = 1,
@@ -183,19 +182,17 @@ typedef enum {
  *                   is left as is.
  * -------------------------------------------------------------------------- **
  */
-#define ubi_trNormalize(W) ((char)( (W) - ubi_trEQUAL ))
-#define ubi_trAbNormal(W)  ((char)( ((char)ubi_btSgn( W )) + ubi_trEQUAL ))
-#define ubi_trRevWay(W)    ((char)( ubi_trEQUAL - ((W) - ubi_trEQUAL) ))
+#define Normalize(W) ((char)((W)-EQUAL))
+#define AbNormal(W) ((char)( EQUAL+((char)ubi_btSgn( (W) )) ))
+#define RevWay(W) ((char)((W)==LEFT?RIGHT:((W)==RIGHT?LEFT:EQUAL)))
 
 /* -------------------------------------------------------------------------- **
  * These macros allow us to quickly read the values of the OVERWRITE and
  * DUPlicate KEY bits of the tree root flags field.
  * -------------------------------------------------------------------------- **
  */
-#define ubi_trDups_OK(A) \
-        ((ubi_trDUPKEY & ((A)->flags))?(ubi_trTRUE):(ubi_trFALSE))
-#define ubi_trOvwt_OK(A) \
-        ((ubi_trOVERWRITE & ((A)->flags))?(ubi_trTRUE):(ubi_trFALSE))
+#define Dups_OK(A) ((ubi_trDUPKEY & ((A)->flags))?(ubi_trTRUE):(ubi_trFALSE))
+#define Ovwt_OK(A) ((ubi_trOVERWRITE & ((A)->flags))?(ubi_trTRUE):(ubi_trFALSE))
 
 /* -------------------------------------------------------------------------- **
  * Typedefs...
index 799996b6cc3739c00cca54e1ce2a3409bc14040d..88be2ba9f49bbafae2c8ffa40938f032de6e730e 100644 (file)
  *
  * -------------------------------------------------------------------------- **
  *
- * Log: ubi_SplayTree.c,v
- * Revision 2.6  1997/12/23 04:01:12  crh
- * In this version, all constants & macros defined in the header file have
- * the ubi_tr prefix.  Also cleaned up anything that gcc complained about
- * when run with '-pedantic -fsyntax-only -Wall'.
- *
  * Revision 2.5  1997/07/26 04:15:42  crh
  * + Cleaned up a few minor syntax annoyances that gcc discovered for me.
  * + Changed ubi_TRUE and ubi_FALSE to ubi_trTRUE and ubi_trFALSE.
  */
 
 static char ModuleID[] = "ubi_SplayTree\n\
-\tRevision: 2.6\n\
-\tDate: 1997/12/23 04:01:12\n\
+\tRevision: 2.5\n\
+\tDate: 1997/07/26 04:15:42\n\
 \tAuthor: crh\n";
 
 
@@ -152,30 +146,30 @@ static void Rotate( ubi_btNodePtr p )
   char          way;
   char          revway;
 
-  parentp = p->Link[ubi_trPARENT];    /* Find parent. */
+  parentp = p->Link[PARENT];    /* Find parent. */
 
   if( parentp )                 /* If no parent, then we're already the root. */
     {
-    way    = p->gender;
-    revway = ubi_trRevWay(way);
-    tmp    = p->Link[(int)revway];
+    way     = p->gender;
+    revway  = RevWay(way);
+    tmp     = p->Link[revway];
 
-    parentp->Link[(int)way] = tmp;
+    parentp->Link[way]  = tmp;
     if( tmp )
       {
-      tmp->Link[ubi_trPARENT] = parentp;
-      tmp->gender             = way;
+      tmp->Link[PARENT] = parentp;
+      tmp->gender       = way;
       }
 
-    tmp                   = parentp->Link[ubi_trPARENT];
-    p->Link[ubi_trPARENT] = tmp;
-    p->gender             = parentp->gender;
+    tmp                 = parentp->Link[PARENT];
+    p->Link[PARENT]     = tmp;
+    p->gender           = parentp->gender;
     if( tmp )
-      tmp->Link[(int)(p->gender)] = p;
+      tmp->Link[p->gender] = p;
 
-    parentp->Link[ubi_trPARENT] = p;
-    parentp->gender             = revway;
-    p->Link[(int)revway]        = parentp;
+    parentp->Link[PARENT] = p;
+    parentp->gender       = revway;
+    p->Link[revway]       = parentp;
     }
   } /* Rotate */
 
@@ -193,13 +187,13 @@ static ubi_btNodePtr Splay( ubi_btNodePtr SplayWithMe )
   {
   ubi_btNodePtr parent;
 
-  while( (parent = SplayWithMe->Link[ubi_trPARENT]) )
+  while( (parent = SplayWithMe->Link[PARENT]) )
     {
     if( parent->gender == SplayWithMe->gender )       /* Zig-Zig */
       Rotate( parent );
     else
       {
-      if( ubi_trEQUAL != parent->gender )             /* Zig-Zag */
+      if( EQUAL != parent->gender )                   /* Zig-Zag */
         Rotate( SplayWithMe );
       }
     Rotate( SplayWithMe );                            /* Zig */
@@ -295,24 +289,24 @@ ubi_btNodePtr ubi_sptRemove( ubi_btRootPtr RootPtr, ubi_btNodePtr DeadNode )
   ubi_btNodePtr p;
 
   (void)Splay( DeadNode );                  /* Move dead node to root.        */
-  if( (p = DeadNode->Link[ubi_trLEFT]) )    /* If left subtree exists...      */
+  if( (p = DeadNode->Link[LEFT]) )          /* If left subtree exists...      */
     {
-    ubi_btNodePtr q = DeadNode->Link[ubi_trRIGHT];
+    ubi_btNodePtr q = DeadNode->Link[RIGHT];
 
-    p->Link[ubi_trPARENT] = NULL;           /* Left subtree node becomes root.*/
-    p->gender             = ubi_trPARENT;
-    p                     = ubi_btLast( p );  /* Find rightmost left node...  */
-    p->Link[ubi_trRIGHT]  = q;                /* ...attach right tree.        */
+    p->Link[PARENT] = NULL;                 /* Left subtree node becomes root.*/
+    p->gender       PARENT;
+    p               = ubi_btLast( p );      /* Find rightmost left tree node..*/
+    p->Link[RIGHT]  = q;                    /* ...attach right tree.          */
     if( q )
-      q->Link[ubi_trPARENT] = p;
+      q->Link[PARENT] = p;
     RootPtr->root   = Splay( p );           /* Resplay at p.                  */
     }
   else
     {
-    if( (p = DeadNode->Link[ubi_trRIGHT]) ) /* No left, but right subtree...  */
+    if( (p = DeadNode->Link[RIGHT]) )       /* No left, but right subtree...  */
       {                                     /* ...exists...                   */
-      p->Link[ubi_trPARENT] = NULL;         /* Right subtree root becomes...  */
-      p->gender       = ubi_trPARENT;       /* ...overall tree root.          */
+      p->Link[PARENT] = NULL;               /* Right subtree root becomes...  */
+      p->gender       = PARENT;             /* ...overall tree root.          */
       RootPtr->root   = p;
       }
     else
index d45c32fce83d9858ca2a72ad2d4bcaaf335b278e..7585d532cea381b0e9b3b8e5e13db76f3d3dfc80 100644 (file)
  *
  * -------------------------------------------------------------------------- **
  *
- * Log: ubi_SplayTree.h,v
- * Revision 2.6  1997/12/23 04:02:20  crh
- * In this version, all constants & macros defined in the header file have
- * the ubi_tr prefix.  Also cleaned up anything that gcc complained about
- * when run with '-pedantic -fsyntax-only -Wall'.
- *
  * Revision 2.5  1997/07/26 04:15:46  crh
  * + Cleaned up a few minor syntax annoyances that gcc discovered for me.
  * + Changed ubi_TRUE and ubi_FALSE to ubi_trTRUE and ubi_trFALSE.
index 8711af3fe1ae2335ffa8c41bc5215420122e8db2..9378dd34d20469d12a71a57a10e5de6c877b6670 100644 (file)
@@ -60,6 +60,8 @@ static BOOL open_connection(struct cli_state *c)
 
        c->protocol = max_protocol;
 
+       c->protocol = max_protocol;
+
        if (!cli_negprot(c)) {
                printf("%s rejected the negprot (%s)\n",host, cli_errstr(c));
                cli_shutdown(c);
@@ -175,6 +177,9 @@ static BOOL rw_torture(struct cli_state *c, int numops)
        cli_close(c, fnum2);
        cli_unlink(c, lockfname);
 
+       cli_close(c, fnum2);
+       cli_unlink(c, lockfname);
+
        printf("%d\n", i);
 
        return True;
@@ -437,6 +442,9 @@ static void run_locktest2(void)
                return;
        }
 
+       cli_close(&cli, fnum);
+       cli_unlink(&cli, fname);
+
        close_connection(&cli);
 
        printf("locktest2 finished\n");
@@ -792,6 +800,198 @@ static void run_trans2test(void)
 }
 
 
+static void browse_callback(char *sname, uint32 stype, char *comment)
+{
+       printf("\t%20.20s %08x %s\n", sname, stype, comment);
+}
+
+
+/*
+  This test checks the browse list code
+
+*/
+static void run_browsetest(void)
+{
+       static struct cli_state cli;
+
+       printf("starting browse test\n");
+
+       if (!open_connection(&cli)) {
+               return;
+       }
+
+       printf("domain list:\n");
+       cli_NetServerEnum(&cli, workgroup, 
+                         SV_TYPE_DOMAIN_ENUM,
+                         browse_callback);
+
+       printf("machine list:\n");
+       cli_NetServerEnum(&cli, workgroup, 
+                         SV_TYPE_ALL,
+                         browse_callback);
+
+       close_connection(&cli);
+
+       printf("browse test finished\n");
+}
+
+
+/*
+  This checks how the getatr calls works
+*/
+static void run_attrtest(void)
+{
+       static struct cli_state cli;
+       int fnum;
+       time_t t, t2;
+       char *fname = "\\attrib.tst";
+
+       printf("starting attrib test\n");
+
+       if (!open_connection(&cli)) {
+               return;
+       }
+
+       cli_unlink(&cli, fname);
+       fnum = cli_open(&cli, fname, 
+                       O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+       cli_close(&cli, fnum);
+       if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
+               printf("getatr failed (%s)\n", cli_errstr(&cli));
+       }
+
+       if (abs(t - time(NULL)) > 2) {
+               printf("ERROR: SMBgetatr bug. time is %s",
+                      ctime(&t));
+               t = time(NULL);
+       }
+
+       t2 = t-60*60*24; /* 1 day ago */
+
+       if (!cli_setatr(&cli, fname, 0, t2)) {
+               printf("setatr failed (%s)\n", cli_errstr(&cli));
+       }
+
+       if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
+               printf("getatr failed (%s)\n", cli_errstr(&cli));
+       }
+
+       if (t != t2) {
+               printf("ERROR: getatr/setatr bug. times are\n%s",
+                      ctime(&t));
+               printf("%s", ctime(&t2));
+       }
+
+       cli_unlink(&cli, fname);
+
+       close_connection(&cli);
+
+       printf("attrib test finished\n");
+}
+
+
+/*
+  This checks a couple of trans2 calls
+*/
+static void run_trans2test(void)
+{
+       static struct cli_state cli;
+       int fnum;
+       uint32 size;
+       time_t c_time, a_time, m_time, w_time, m_time2;
+       char *fname = "\\trans2.tst";
+       char *dname = "\\trans2";
+       char *fname2 = "\\trans2\\trans2.tst";
+
+       printf("starting trans2 test\n");
+
+       if (!open_connection(&cli)) {
+               return;
+       }
+
+       cli_unlink(&cli, fname);
+       fnum = cli_open(&cli, fname, 
+                       O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+       if (!cli_qfileinfo(&cli, fnum, &c_time, &a_time, &m_time, &size)) {
+               printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
+       }
+       cli_close(&cli, fnum);
+
+       sleep(2);
+
+       cli_unlink(&cli, fname);
+       fnum = cli_open(&cli, fname, 
+                       O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+       cli_close(&cli, fnum);
+
+       if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size)) {
+               printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
+       } else {
+               if (c_time != m_time) {
+                       printf("create time=%s", ctime(&c_time));
+                       printf("modify time=%s", ctime(&m_time));
+                       printf("This system appears to have sticky create times\n");
+               }
+               if (a_time % (60*60) == 0) {
+                       printf("access time=%s", ctime(&a_time));
+                       printf("This system appears to set a midnight access time\n");
+               }
+
+               if (abs(m_time - time(NULL)) > 60*60*24*7) {
+                       printf("ERROR: totally incorrect times - maybe word reversed?\n");
+               }
+       }
+
+
+       cli_unlink(&cli, fname);
+       fnum = cli_open(&cli, fname, 
+                       O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+       cli_close(&cli, fnum);
+       if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time, 
+                           &w_time, &size)) {
+               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+       } else {
+               if (w_time < 60*60*24*2) {
+                       printf("write time=%s", ctime(&w_time));
+                       printf("This system appears to set a initial 0 write time\n");
+               }
+       }
+
+       cli_unlink(&cli, fname);
+
+
+       /* check if the server updates the directory modification time
+           when creating a new file */
+       if (!cli_mkdir(&cli, dname)) {
+               printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
+       }
+       sleep(3);
+       if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time, 
+                           &w_time, &size)) {
+               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+       }
+
+       fnum = cli_open(&cli, fname2, 
+                       O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+       cli_write(&cli, fnum,  (char *)&fnum, 0, sizeof(fnum));
+       cli_close(&cli, fnum);
+       if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2, 
+                           &w_time, &size)) {
+               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+       } else {
+               if (m_time2 == m_time)
+                       printf("This system does not update directory modification times\n");
+       }
+       cli_unlink(&cli, fname2);
+       cli_rmdir(&cli, dname);
+
+
+       close_connection(&cli);
+
+       printf("trans2 test finished\n");
+}
+
+
 static void create_procs(int nprocs, int numops)
 {
        int i, status;