gto ri of a bunch more #ifdef LARGE_SMB_OFF_T checks by introducing a
[tprouty/samba.git] / source / smbd / trans2.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    SMB transaction2 handling
5    Copyright (C) Jeremy Allison 1994-1998
6
7    Extensively modified by Andrew Tridgell, 1995
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25 #include "trans2.h"
26
27 extern int DEBUGLEVEL;
28 extern int Protocol;
29 extern BOOL case_sensitive;
30 extern int Client;
31 extern int oplock_sock;
32 extern int smb_read_error;
33 extern fstring local_machine;
34 extern int global_oplock_break;
35
36 /****************************************************************************
37   Send the required number of replies back.
38   We assume all fields other than the data fields are
39   set correctly for the type of call.
40   HACK ! Always assumes smb_setup field is zero.
41 ****************************************************************************/
42 static int send_trans2_replies(char *outbuf, int bufsize, char *params, 
43                                int paramsize, char *pdata, int datasize)
44 {
45   /* As we are using a protocol > LANMAN1 then the max_send
46      variable must have been set in the sessetupX call.
47      This takes precedence over the max_xmit field in the
48      global struct. These different max_xmit variables should
49      be merged as this is now too confusing */
50
51   extern int max_send;
52   int data_to_send = datasize;
53   int params_to_send = paramsize;
54   int useable_space;
55   char *pp = params;
56   char *pd = pdata;
57   int params_sent_thistime, data_sent_thistime, total_sent_thistime;
58   int alignment_offset = 3;
59   int data_alignment_offset = 0;
60
61   /* Initially set the wcnt area to be 10 - this is true for all
62      trans2 replies */
63   set_message(outbuf,10,0,True);
64
65   /* If there genuinely are no parameters or data to send just send
66      the empty packet */
67   if(params_to_send == 0 && data_to_send == 0)
68   {
69     send_smb(Client,outbuf);
70     return 0;
71   }
72
73   /* When sending params and data ensure that both are nicely aligned */
74   /* Only do this alignment when there is also data to send - else
75      can cause NT redirector problems. */
76   if (((params_to_send % 4) != 0) && (data_to_send != 0))
77     data_alignment_offset = 4 - (params_to_send % 4);
78
79   /* Space is bufsize minus Netbios over TCP header minus SMB header */
80   /* The alignment_offset is to align the param bytes on an even byte
81      boundary. NT 4.0 Beta needs this to work correctly. */
82   useable_space = bufsize - ((smb_buf(outbuf)+
83                     alignment_offset+data_alignment_offset) - 
84                     outbuf);
85
86   /* useable_space can never be more than max_send minus the
87      alignment offset. */
88   useable_space = MIN(useable_space, 
89                       max_send - (alignment_offset+data_alignment_offset));
90
91
92   while (params_to_send || data_to_send)
93   {
94     /* Calculate whether we will totally or partially fill this packet */
95     total_sent_thistime = params_to_send + data_to_send + 
96                             alignment_offset + data_alignment_offset;
97     /* We can never send more than useable_space */
98     total_sent_thistime = MIN(total_sent_thistime, useable_space);
99
100     set_message(outbuf, 10, total_sent_thistime, True);
101
102     /* Set total params and data to be sent */
103     SSVAL(outbuf,smb_tprcnt,paramsize);
104     SSVAL(outbuf,smb_tdrcnt,datasize);
105
106     /* Calculate how many parameters and data we can fit into
107        this packet. Parameters get precedence */
108
109     params_sent_thistime = MIN(params_to_send,useable_space);
110     data_sent_thistime = useable_space - params_sent_thistime;
111     data_sent_thistime = MIN(data_sent_thistime,data_to_send);
112
113     SSVAL(outbuf,smb_prcnt, params_sent_thistime);
114     if(params_sent_thistime == 0)
115     {
116       SSVAL(outbuf,smb_proff,0);
117       SSVAL(outbuf,smb_prdisp,0);
118     }
119     else
120     {
121       /* smb_proff is the offset from the start of the SMB header to the
122          parameter bytes, however the first 4 bytes of outbuf are
123          the Netbios over TCP header. Thus use smb_base() to subtract
124          them from the calculation */
125       SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
126       /* Absolute displacement of param bytes sent in this packet */
127       SSVAL(outbuf,smb_prdisp,pp - params);
128     }
129
130     SSVAL(outbuf,smb_drcnt, data_sent_thistime);
131     if(data_sent_thistime == 0)
132     {
133       SSVAL(outbuf,smb_droff,0);
134       SSVAL(outbuf,smb_drdisp, 0);
135     }
136     else
137     {
138       /* The offset of the data bytes is the offset of the
139          parameter bytes plus the number of parameters being sent this time */
140       SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) - 
141             smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
142       SSVAL(outbuf,smb_drdisp, pd - pdata);
143     }
144
145     /* Copy the param bytes into the packet */
146     if(params_sent_thistime)
147       memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
148     /* Copy in the data bytes */
149     if(data_sent_thistime)
150       memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
151              data_alignment_offset,pd,data_sent_thistime);
152
153     DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
154           params_sent_thistime, data_sent_thistime, useable_space));
155     DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
156           params_to_send, data_to_send, paramsize, datasize));
157
158     /* Send the packet */
159     send_smb(Client,outbuf);
160
161     pp += params_sent_thistime;
162     pd += data_sent_thistime;
163
164     params_to_send -= params_sent_thistime;
165     data_to_send -= data_sent_thistime;
166
167     /* Sanity check */
168     if(params_to_send < 0 || data_to_send < 0)
169     {
170       DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
171             params_to_send, data_to_send));
172       return -1;
173     }
174   }
175
176   return 0;
177 }
178
179
180 /****************************************************************************
181   reply to a TRANSACT2_OPEN
182 ****************************************************************************/
183 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, 
184                            int bufsize,  
185                            char **pparams, char **ppdata)
186 {
187   char *params = *pparams;
188   int16 open_mode = SVAL(params, 2);
189   int16 open_attr = SVAL(params,6);
190   BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
191 #if 0
192   BOOL return_additional_info = BITSETW(params,0);
193   int16 open_sattr = SVAL(params, 4);
194   time_t open_time = make_unix_date3(params+8);
195 #endif
196   int16 open_ofun = SVAL(params,12);
197   int32 open_size = IVAL(params,14);
198   char *pname = &params[28];
199   int16 namelen = strlen(pname)+1;
200
201   pstring fname;
202   mode_t unixmode;
203   SMB_OFF_T size=0;
204   int fmode=0,mtime=0,rmode;
205   SMB_INO_T inode = 0;
206   SMB_STRUCT_STAT sbuf;
207   int smb_action = 0;
208   BOOL bad_path = False;
209   files_struct *fsp;
210
211   StrnCpy(fname,pname,namelen);
212
213   DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
214            fname,open_mode, open_attr, open_ofun, open_size));
215
216   /* XXXX we need to handle passed times, sattr and flags */
217
218   unix_convert(fname,conn,0,&bad_path,NULL);
219     
220   fsp = file_new();
221   if (!fsp)
222     return(ERROR(ERRSRV,ERRnofids));
223
224   if (!check_name(fname,conn))
225   {
226     if((errno == ENOENT) && bad_path)
227     {
228       unix_ERR_class = ERRDOS;
229       unix_ERR_code = ERRbadpath;
230     }
231     file_free(fsp);
232     return(UNIXERROR(ERRDOS,ERRnoaccess));
233   }
234
235   unixmode = unix_mode(conn,open_attr | aARCH);
236       
237   open_file_shared(fsp,conn,fname,open_mode,open_ofun,unixmode,
238                    oplock_request, &rmode,&smb_action);
239       
240   if (!fsp->open)
241   {
242     if((errno == ENOENT) && bad_path)
243     {
244       unix_ERR_class = ERRDOS;
245       unix_ERR_code = ERRbadpath;
246     }
247     file_free(fsp);
248     return(UNIXERROR(ERRDOS,ERRnoaccess));
249   }
250
251   if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
252     close_file(fsp,False);
253     return(ERROR(ERRDOS,ERRnoaccess));
254   }
255     
256   size = sbuf.st_size;
257   fmode = dos_mode(conn,fname,&sbuf);
258   mtime = sbuf.st_mtime;
259   inode = sbuf.st_ino;
260   if (fmode & aDIR) {
261     close_file(fsp,False);
262     return(ERROR(ERRDOS,ERRnoaccess));
263   }
264
265   /* Realloc the size of parameters and data we will return */
266   params = *pparams = Realloc(*pparams, 28);
267   if(params == NULL)
268     return(ERROR(ERRDOS,ERRnomem));
269
270   bzero(params,28);
271   SSVAL(params,0,fsp->fnum);
272   SSVAL(params,2,fmode);
273   put_dos_date2(params,4, mtime);
274   SIVAL(params,8, (uint32)size);
275   SSVAL(params,12,rmode);
276
277   if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
278     smb_action |= EXTENDED_OPLOCK_GRANTED;
279   }
280
281   SSVAL(params,18,smb_action);
282   /*
283    * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
284    */
285   SIVAL(params,20,inode);
286  
287   /* Send the required number of replies */
288   send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
289
290   return -1;
291 }
292
293 /****************************************************************************
294   get a level dependent lanman2 dir entry.
295 ****************************************************************************/
296 static int get_lanman2_dir_entry(connection_struct *conn,
297                                  char *path_mask,int dirtype,int info_level,
298                                  int requires_resume_key,
299                                  BOOL dont_descend,char **ppdata, 
300                                  char *base_data, int space_remaining, 
301                                  BOOL *out_of_space,
302                                  int *last_name_off)
303 {
304   char *dname;
305   BOOL found = False;
306   SMB_STRUCT_STAT sbuf;
307   pstring mask;
308   pstring pathreal;
309   pstring fname;
310   char *p, *pdata = *ppdata;
311   uint32 reskey=0;
312   int prev_dirpos=0;
313   int mode=0;
314   SMB_OFF_T size = 0;
315   uint32 len;
316   time_t mdate=0, adate=0, cdate=0;
317   char *nameptr;
318   BOOL isrootdir = (strequal(conn->dirpath,"./") ||
319                     strequal(conn->dirpath,".") ||
320                     strequal(conn->dirpath,"/"));
321   BOOL was_8_3;
322   int nt_extmode; /* Used for NT connections instead of mode */
323   BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
324
325   *fname = 0;
326   *out_of_space = False;
327
328   if (!conn->dirptr)
329     return(False);
330
331   p = strrchr(path_mask,'/');
332   if(p != NULL)
333   {
334     if(p[1] == '\0')
335       pstrcpy(mask,"*.*");
336     else
337       pstrcpy(mask, p+1);
338   }
339   else
340     pstrcpy(mask, path_mask);
341
342   while (!found)
343   {
344     /* Needed if we run out of space */
345     prev_dirpos = TellDir(conn->dirptr);
346     dname = ReadDirName(conn->dirptr);
347
348     /*
349      * Due to bugs in NT client redirectors we are not using
350      * resume keys any more - set them to zero.
351      * Check out the related comments in findfirst/findnext.
352      * JRA.
353      */
354
355     reskey = 0;
356
357     DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
358       (unsigned)conn->dirptr,TellDir(conn->dirptr)));
359       
360     if (!dname) 
361       return(False);
362
363     pstrcpy(fname,dname);      
364
365     if(mask_match(fname, mask, case_sensitive, True))
366     {
367       BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
368       if (dont_descend && !isdots)
369         continue;
370           
371       if (isrootdir && isdots)
372         continue;
373
374       pstrcpy(pathreal,conn->dirpath);
375       if(needslash)
376         pstrcat(pathreal,"/");
377       pstrcat(pathreal,dname);
378       if (dos_stat(pathreal,&sbuf) != 0) 
379       {
380         DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
381         continue;
382       }
383
384       mode = dos_mode(conn,pathreal,&sbuf);
385
386       if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
387         DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
388         continue;
389       }
390
391       size = sbuf.st_size;
392       mdate = sbuf.st_mtime;
393       adate = sbuf.st_atime;
394       cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
395       if(mode & aDIR)
396         size = 0;
397
398       DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
399           
400       found = True;
401     }
402   }
403
404   name_map_mangle(fname,False,SNUM(conn));
405
406   p = pdata;
407   nameptr = p;
408
409   nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
410
411   switch (info_level)
412   {
413     case 1:
414       if(requires_resume_key) {
415         SIVAL(p,0,reskey);
416         p += 4;
417       }
418       put_dos_date2(p,l1_fdateCreation,cdate);
419       put_dos_date2(p,l1_fdateLastAccess,adate);
420       put_dos_date2(p,l1_fdateLastWrite,mdate);
421       SIVAL(p,l1_cbFile,(uint32)size);
422       SIVAL(p,l1_cbFileAlloc,ROUNDUP(size,1024));
423       SSVAL(p,l1_attrFile,mode);
424       SCVAL(p,l1_cchName,strlen(fname));
425       pstrcpy(p + l1_achName, fname);
426       nameptr = p + l1_achName;
427       p += l1_achName + strlen(fname) + 1;
428       break;
429
430     case 2:
431       /* info_level 2 */
432       if(requires_resume_key) {
433         SIVAL(p,0,reskey);
434         p += 4;
435       }
436       put_dos_date2(p,l2_fdateCreation,cdate);
437       put_dos_date2(p,l2_fdateLastAccess,adate);
438       put_dos_date2(p,l2_fdateLastWrite,mdate);
439       SIVAL(p,l2_cbFile,(uint32)size);
440       SIVAL(p,l2_cbFileAlloc,ROUNDUP(size,1024));
441       SSVAL(p,l2_attrFile,mode);
442       SIVAL(p,l2_cbList,0); /* No extended attributes */
443       SCVAL(p,l2_cchName,strlen(fname));
444       pstrcpy(p + l2_achName, fname);
445       nameptr = p + l2_achName;
446       p += l2_achName + strlen(fname) + 1;
447       break;
448
449     case 3:
450       SIVAL(p,0,reskey);
451       put_dos_date2(p,4,cdate);
452       put_dos_date2(p,8,adate);
453       put_dos_date2(p,12,mdate);
454       SIVAL(p,16,(uint32)size);
455       SIVAL(p,20,ROUNDUP(size,1024));
456       SSVAL(p,24,mode);
457       SIVAL(p,26,4);
458       CVAL(p,30) = strlen(fname);
459       pstrcpy(p+31, fname);
460       nameptr = p+31;
461       p += 31 + strlen(fname) + 1;
462       break;
463
464     case 4:
465       if(requires_resume_key) {
466         SIVAL(p,0,reskey);
467         p += 4;
468       }
469       SIVAL(p,0,33+strlen(fname)+1);
470       put_dos_date2(p,4,cdate);
471       put_dos_date2(p,8,adate);
472       put_dos_date2(p,12,mdate);
473       SIVAL(p,16,(uint32)size);
474       SIVAL(p,20,ROUNDUP(size,1024));
475       SSVAL(p,24,mode);
476       CVAL(p,32) = strlen(fname);
477       pstrcpy(p + 33, fname);
478       nameptr = p+33;
479       p += 33 + strlen(fname) + 1;
480       break;
481
482     case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
483       was_8_3 = is_8_3(fname, True);
484       len = 94+strlen(fname);
485       len = (len + 3) & ~3;
486       SIVAL(p,0,len); p += 4;
487       SIVAL(p,0,reskey); p += 4;
488       put_long_date(p,cdate); p += 8;
489       put_long_date(p,adate); p += 8;
490       put_long_date(p,mdate); p += 8;
491       put_long_date(p,mdate); p += 8;
492       SOFF_T(p,0,size);
493       SOFF_T(p,8,size);
494       p += 16;
495       SIVAL(p,0,nt_extmode); p += 4;
496       SIVAL(p,0,strlen(fname)); p += 4;
497       SIVAL(p,0,0); p += 4;
498       if (!was_8_3) {
499         pstrcpy(p+2,fname);
500         if (!name_map_mangle(p+2,True,SNUM(conn)))
501           (p+2)[12] = 0;
502       } else
503         *(p+2) = 0;
504       strupper(p+2);
505       SSVAL(p,0,strlen(p+2));
506       p += 2 + 24;
507       /* nameptr = p;  */
508       pstrcpy(p,fname); p += strlen(p);
509       p = pdata + len;
510       break;
511
512     case SMB_FIND_FILE_DIRECTORY_INFO:
513       len = 64+strlen(fname);
514       len = (len + 3) & ~3;
515       SIVAL(p,0,len); p += 4;
516       SIVAL(p,0,reskey); p += 4;
517       put_long_date(p,cdate); p += 8;
518       put_long_date(p,adate); p += 8;
519       put_long_date(p,mdate); p += 8;
520       put_long_date(p,mdate); p += 8;
521       SOFF_T(p,0,size);
522       SOFF_T(p,8,size);
523       p += 16;
524       SIVAL(p,0,nt_extmode); p += 4;
525       SIVAL(p,0,strlen(fname)); p += 4;
526       pstrcpy(p,fname);
527       p = pdata + len;
528       break;
529       
530       
531     case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
532       len = 68+strlen(fname);
533       len = (len + 3) & ~3;
534       SIVAL(p,0,len); p += 4;
535       SIVAL(p,0,reskey); p += 4;
536       put_long_date(p,cdate); p += 8;
537       put_long_date(p,adate); p += 8;
538       put_long_date(p,mdate); p += 8;
539       put_long_date(p,mdate); p += 8;
540       SOFF_T(p,0,size); 
541       SOFF_T(p,8,size);
542       p += 16;
543       SIVAL(p,0,nt_extmode); p += 4;
544       SIVAL(p,0,strlen(fname)); p += 4;
545       SIVAL(p,0,0); p += 4;
546       pstrcpy(p,fname);
547       p = pdata + len;
548       break;
549
550     case SMB_FIND_FILE_NAMES_INFO:
551       len = 12+strlen(fname);
552       len = (len + 3) & ~3;
553       SIVAL(p,0,len); p += 4;
554       SIVAL(p,0,reskey); p += 4;
555       SIVAL(p,0,strlen(fname)); p += 4;
556       pstrcpy(p,fname);
557       p = pdata + len;
558       break;
559
560     default:      
561       return(False);
562     }
563
564
565   if (PTR_DIFF(p,pdata) > space_remaining) {
566     /* Move the dirptr back to prev_dirpos */
567     SeekDir(conn->dirptr, prev_dirpos);
568     *out_of_space = True;
569     DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
570     return False; /* Not finished - just out of space */
571   }
572
573   /* Setup the last_filename pointer, as an offset from base_data */
574   *last_name_off = PTR_DIFF(nameptr,base_data);
575   /* Advance the data pointer to the next slot */
576   *ppdata = p;
577   return(found);
578 }
579   
580 /****************************************************************************
581  Convert the directory masks formated for the wire.
582 ****************************************************************************/
583
584 void mask_convert( char *mask)
585 {
586   /*
587    * We know mask is a pstring.
588    */
589   char *p = mask;
590   while (*p) {
591     if (*p == '<') {
592       pstring expnd;
593       if(p[1] != '"' && p[1] != '.') {
594         pstrcpy( expnd, p+1 );
595         *p++ = '*';
596         *p = '.';
597         safe_strcpy( p+1, expnd, sizeof(pstring) - (p - mask) - 2);
598       } else
599         *p = '*';
600     }
601     if (*p == '>') *p = '?';
602     if (*p == '"') *p = '.';
603     p++;
604   }
605 }
606
607 /****************************************************************************
608   reply to a TRANS2_FINDFIRST
609 ****************************************************************************/
610 static int call_trans2findfirst(connection_struct *conn,
611                                 char *inbuf, char *outbuf, int bufsize,  
612                                 char **pparams, char **ppdata)
613 {
614   /* We must be careful here that we don't return more than the
615      allowed number of data bytes. If this means returning fewer than
616      maxentries then so be it. We assume that the redirector has
617      enough room for the fixed number of parameter bytes it has
618      requested. */
619   uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
620   char *params = *pparams;
621   char *pdata = *ppdata;
622   int dirtype = SVAL(params,0);
623   int maxentries = SVAL(params,2);
624   BOOL close_after_first = BITSETW(params+4,0);
625   BOOL close_if_end = BITSETW(params+4,1);
626   BOOL requires_resume_key = BITSETW(params+4,2);
627   int info_level = SVAL(params,6);
628   pstring directory;
629   pstring mask;
630   char *p, *wcard;
631   int last_name_off=0;
632   int dptr_num = -1;
633   int numentries = 0;
634   int i;
635   BOOL finished = False;
636   BOOL dont_descend = False;
637   BOOL out_of_space = False;
638   int space_remaining;
639   BOOL bad_path = False;
640
641   *directory = *mask = 0;
642
643   DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
644            dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
645            info_level, max_data_bytes));
646   
647   switch (info_level) 
648     {
649     case 1:
650     case 2:
651     case 3:
652     case 4:
653     case SMB_FIND_FILE_DIRECTORY_INFO:
654     case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
655     case SMB_FIND_FILE_NAMES_INFO:
656     case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
657       break;
658     default:
659       return(ERROR(ERRDOS,ERRunknownlevel));
660     }
661
662   pstrcpy(directory, params + 12); /* Complete directory path with 
663                                      wildcard mask appended */
664
665   DEBUG(5,("path=%s\n",directory));
666
667   unix_convert(directory,conn,0,&bad_path,NULL);
668   if(!check_name(directory,conn)) {
669     if((errno == ENOENT) && bad_path)
670     {
671       unix_ERR_class = ERRDOS;
672       unix_ERR_code = ERRbadpath;
673     }
674
675 #if 0
676     /* Ugly - NT specific hack - maybe not needed ? (JRA) */
677     if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) && 
678        (get_remote_arch() == RA_WINNT))
679     {
680       unix_ERR_class = ERRDOS;
681       unix_ERR_code = ERRbaddirectory;
682     }
683 #endif 
684
685     return(ERROR(ERRDOS,ERRbadpath));
686   }
687
688   p = strrchr(directory,'/');
689   if(p == NULL) {
690     pstrcpy(mask,directory);
691     pstrcpy(directory,"./");
692   } else {
693     pstrcpy(mask,p+1);
694     *p = 0;
695   }
696
697   DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
698
699   pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
700   if(!*ppdata)
701     return(ERROR(ERRDOS,ERRnomem));
702   bzero(pdata,max_data_bytes);
703
704   /* Realloc the params space */
705   params = *pparams = Realloc(*pparams, 10);
706   if(params == NULL)
707     return(ERROR(ERRDOS,ERRnomem));
708
709   dptr_num = dptr_create(conn,directory, True ,SVAL(inbuf,smb_pid));
710   if (dptr_num < 0)
711     return(ERROR(ERRDOS,ERRbadfile));
712
713   /* Convert the formatted mask. */
714   mask_convert(mask);
715
716 #if 0 /* JRA */
717   /*
718    * Now we have a working mask_match in util.c, I believe
719    * we no longer need these hacks (in fact they break
720    * things). JRA. 
721    */
722
723   /* a special case for 16 bit apps */
724   if (strequal(mask,"????????.???")) pstrcpy(mask,"*");
725
726   /* handle broken clients that send us old 8.3 format */
727   string_sub(mask,"????????","*");
728   string_sub(mask,".???",".*");
729 #endif /* JRA */
730
731   /* Save the wildcard match and attribs we are using on this directory - 
732      needed as lanman2 assumes these are being saved between calls */
733
734   if(!(wcard = strdup(mask))) {
735     dptr_close(dptr_num);
736     return(ERROR(ERRDOS,ERRnomem));
737   }
738
739   dptr_set_wcard(dptr_num, wcard);
740   dptr_set_attr(dptr_num, dirtype);
741
742   DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
743
744   /* We don't need to check for VOL here as this is returned by 
745      a different TRANS2 call. */
746   
747   DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
748            conn->dirpath,lp_dontdescend(SNUM(conn))));
749   if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
750     dont_descend = True;
751     
752   p = pdata;
753   space_remaining = max_data_bytes;
754   out_of_space = False;
755
756   for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
757     {
758
759       /* this is a heuristic to avoid seeking the dirptr except when 
760          absolutely necessary. It allows for a filename of about 40 chars */
761       if (space_remaining < DIRLEN_GUESS && numentries > 0)
762         {
763           out_of_space = True;
764           finished = False;
765         }
766       else
767         {
768           finished = 
769             !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
770                                    requires_resume_key,dont_descend,
771                                    &p,pdata,space_remaining, &out_of_space,
772                                    &last_name_off);
773         }
774
775       if (finished && out_of_space)
776         finished = False;
777
778       if (!finished && !out_of_space)
779         numentries++;
780       space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
781     }
782   
783   /* Check if we can close the dirptr */
784   if(close_after_first || (finished && close_if_end))
785     {
786       dptr_close(dptr_num);
787       DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
788       dptr_num = -1;
789     }
790
791   /* 
792    * If there are no matching entries we must return ERRDOS/ERRbadfile - 
793    * from observation of NT.
794    */
795
796   if(numentries == 0)
797     return(ERROR(ERRDOS,ERRbadfile));
798
799   /* At this point pdata points to numentries directory entries. */
800
801   /* Set up the return parameter block */
802   SSVAL(params,0,dptr_num);
803   SSVAL(params,2,numentries);
804   SSVAL(params,4,finished);
805   SSVAL(params,6,0); /* Never an EA error */
806   SSVAL(params,8,last_name_off);
807
808   send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
809
810   if ((! *directory) && dptr_path(dptr_num))
811     slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
812
813   DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
814             smb_fn_name(CVAL(inbuf,smb_com)), 
815             mask, directory, dirtype, numentries ) );
816
817   return(-1);
818 }
819
820
821 /****************************************************************************
822   reply to a TRANS2_FINDNEXT
823 ****************************************************************************/
824 static int call_trans2findnext(connection_struct *conn, 
825                                char *inbuf, char *outbuf, 
826                                int length, int bufsize,
827                                char **pparams, char **ppdata)
828 {
829   /* We must be careful here that we don't return more than the
830      allowed number of data bytes. If this means returning fewer than
831      maxentries then so be it. We assume that the redirector has
832      enough room for the fixed number of parameter bytes it has
833      requested. */
834   int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
835   char *params = *pparams;
836   char *pdata = *ppdata;
837   int16 dptr_num = SVAL(params,0);
838   int maxentries = SVAL(params,2);
839   uint16 info_level = SVAL(params,4);
840   uint32 resume_key = IVAL(params,6);
841   BOOL close_after_request = BITSETW(params+10,0);
842   BOOL close_if_end = BITSETW(params+10,1);
843   BOOL requires_resume_key = BITSETW(params+10,2);
844   BOOL continue_bit = BITSETW(params+10,3);
845   pstring resume_name;
846   pstring mask;
847   pstring directory;
848   char *p;
849   uint16 dirtype;
850   int numentries = 0;
851   int i, last_name_off=0;
852   BOOL finished = False;
853   BOOL dont_descend = False;
854   BOOL out_of_space = False;
855   int space_remaining;
856
857   *mask = *directory = *resume_name = 0;
858
859   pstrcpy( resume_name, params+12);
860
861   DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
862 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
863 resume_key = %d resume name = %s continue=%d level = %d\n",
864            dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end, 
865            requires_resume_key, resume_key, resume_name, continue_bit, info_level));
866
867   switch (info_level) 
868     {
869     case 1:
870     case 2:
871     case 3:
872     case 4:
873     case SMB_FIND_FILE_DIRECTORY_INFO:
874     case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
875     case SMB_FIND_FILE_NAMES_INFO:
876     case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
877       break;
878     default:
879       return(ERROR(ERRDOS,ERRunknownlevel));
880     }
881
882   pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
883   if(!*ppdata)
884     return(ERROR(ERRDOS,ERRnomem));
885   bzero(pdata,max_data_bytes);
886
887   /* Realloc the params space */
888   params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
889   if(!params)
890     return(ERROR(ERRDOS,ERRnomem));
891
892   /* Check that the dptr is valid */
893   if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
894     return(ERROR(ERRDOS,ERRnofiles));
895
896   string_set(&conn->dirpath,dptr_path(dptr_num));
897
898   /* Get the wildcard mask from the dptr */
899   if((p = dptr_wcard(dptr_num))== NULL) {
900     DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
901     return (ERROR(ERRDOS,ERRnofiles));
902   }
903   pstrcpy(mask, p);
904   pstrcpy(directory,conn->dirpath);
905
906   /* Get the attr mask from the dptr */
907   dirtype = dptr_attr(dptr_num);
908
909   DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%X,%d)\n",
910            dptr_num, mask, dirtype, 
911            (unsigned)conn->dirptr,
912            TellDir(conn->dirptr)));
913
914   /* We don't need to check for VOL here as this is returned by 
915      a different TRANS2 call. */
916
917   DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
918   if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
919     dont_descend = True;
920     
921   p = pdata;
922   space_remaining = max_data_bytes;
923   out_of_space = False;
924
925   /* 
926    * Seek to the correct position. We no longer use the resume key but
927    * depend on the last file name instead.
928    */
929   if(requires_resume_key && *resume_name && !continue_bit)
930   {
931     /*
932      * Fix for NT redirector problem triggered by resume key indexes
933      * changing between directory scans. We now return a resume key of 0
934      * and instead look for the filename to continue from (also given
935      * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
936      * findfirst/findnext (as is usual) then the directory pointer
937      * should already be at the correct place. Check this by scanning
938      * backwards looking for an exact (ie. case sensitive) filename match. 
939      * If we get to the beginning of the directory and haven't found it then scan
940      * forwards again looking for a match. JRA.
941      */
942
943     int current_pos, start_pos;
944     char *dname = NULL;
945     void *dirptr = conn->dirptr;
946     start_pos = TellDir(dirptr);
947     for(current_pos = start_pos; current_pos >= 0; current_pos--)
948     {
949       DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
950
951       SeekDir(dirptr, current_pos);
952       dname = ReadDirName(dirptr);
953
954       /*
955        * Remember, name_map_mangle is called by
956        * get_lanman2_dir_entry(), so the resume name
957        * could be mangled. Ensure we do the same
958        * here.
959        */
960
961       if(dname != NULL)
962         name_map_mangle( dname, False, SNUM(conn));
963
964       if(dname && strcsequal( resume_name, dname))
965       {
966         SeekDir(dirptr, current_pos+1);
967         DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
968         break;
969       }
970     }
971
972     /*
973      * Scan forward from start if not found going backwards.
974      */
975
976     if(current_pos < 0)
977     {
978       DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
979       SeekDir(dirptr, start_pos);
980       for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
981       {
982         /*
983          * Remember, name_map_mangle is called by
984          * get_lanman2_dir_entry(), so the resume name
985          * could be mangled. Ensure we do the same
986          * here.
987          */
988
989         if(dname != NULL)
990           name_map_mangle( dname, False, SNUM(conn));
991
992         if(dname && strcsequal( resume_name, dname))
993         {
994           SeekDir(dirptr, current_pos+1);
995           DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
996           break;
997         }
998       } /* end for */
999     } /* end if current_pos */
1000   } /* end if requires_resume_key && !continue_bit */
1001
1002   for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1003     {
1004       /* this is a heuristic to avoid seeking the dirptr except when 
1005          absolutely necessary. It allows for a filename of about 40 chars */
1006       if (space_remaining < DIRLEN_GUESS && numentries > 0)
1007         {
1008           out_of_space = True;
1009           finished = False;
1010         }
1011       else
1012         {
1013           finished = 
1014             !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
1015                                    requires_resume_key,dont_descend,
1016                                    &p,pdata,space_remaining, &out_of_space,
1017                                    &last_name_off);
1018         }
1019
1020       if (finished && out_of_space)
1021         finished = False;
1022
1023       if (!finished && !out_of_space)
1024         numentries++;
1025       space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1026     }
1027   
1028   /* Check if we can close the dirptr */
1029   if(close_after_request || (finished && close_if_end))
1030     {
1031       dptr_close(dptr_num); /* This frees up the saved mask */
1032       DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1033       dptr_num = -1;
1034     }
1035
1036
1037   /* Set up the return parameter block */
1038   SSVAL(params,0,numentries);
1039   SSVAL(params,2,finished);
1040   SSVAL(params,4,0); /* Never an EA error */
1041   SSVAL(params,6,last_name_off);
1042
1043   send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1044
1045   if ((! *directory) && dptr_path(dptr_num))
1046     slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1047
1048   DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1049             smb_fn_name(CVAL(inbuf,smb_com)), 
1050             mask, directory, dirtype, numentries ) );
1051
1052   return(-1);
1053 }
1054
1055 /****************************************************************************
1056   reply to a TRANS2_QFSINFO (query filesystem info)
1057 ****************************************************************************/
1058
1059 static int call_trans2qfsinfo(connection_struct *conn, 
1060                               char *inbuf, char *outbuf, 
1061                               int length, int bufsize,
1062                               char **pparams, char **ppdata)
1063 {
1064   char *pdata = *ppdata;
1065   char *params = *pparams;
1066   uint16 info_level = SVAL(params,0);
1067   int data_len;
1068   SMB_STRUCT_STAT st;
1069   char *vname = volume_label(SNUM(conn));
1070   int snum = SNUM(conn);
1071  
1072   DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1073
1074   if(dos_stat(".",&st)!=0) {
1075     DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1076     return (ERROR(ERRSRV,ERRinvdevice));
1077   }
1078
1079   pdata = *ppdata = Realloc(*ppdata, 1024); bzero(pdata,1024);
1080
1081   switch (info_level) 
1082   {
1083     case 1:
1084     {
1085       SMB_BIG_UINT dfree,dsize,bsize;
1086       data_len = 18;
1087       sys_disk_free(".",&bsize,&dfree,&dsize);  
1088       SIVAL(pdata,l1_idFileSystem,st.st_dev);
1089       SIVAL(pdata,l1_cSectorUnit,bsize/512);
1090       SIVAL(pdata,l1_cUnit,dsize);
1091       SIVAL(pdata,l1_cUnitAvail,dfree);
1092       SSVAL(pdata,l1_cbSector,512);
1093       DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1094                  (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1095          (unsigned int)dfree, 512));
1096       break;
1097     }
1098     case 2:
1099     { 
1100       /* Return volume name */
1101       int volname_len = MIN(strlen(vname),11);
1102       data_len = l2_vol_szVolLabel + volname_len + 1;
1103       /* 
1104        * Add volume serial number - hash of a combination of
1105        * the called hostname and the service name.
1106        */
1107       SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1108       SCVAL(pdata,l2_vol_cch,volname_len);
1109       StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
1110       DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1111                (unsigned)st.st_ctime, volname_len,
1112                pdata+l2_vol_szVolLabel));
1113       break;
1114     }
1115     case SMB_QUERY_FS_ATTRIBUTE_INFO:
1116       data_len = 12 + 2*strlen(FSTYPE_STRING);
1117       SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES); /* FS ATTRIBUTES */
1118 #if 0 /* Old code. JRA. */
1119       SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
1120 #endif /* Old code. */
1121       SIVAL(pdata,4,128); /* Max filename component length */
1122       SIVAL(pdata,8,2*strlen(FSTYPE_STRING));
1123       PutUniCode(pdata+12,FSTYPE_STRING);
1124       SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1125       break;
1126     case SMB_QUERY_FS_LABEL_INFO:
1127       data_len = 4 + strlen(vname);
1128       SIVAL(pdata,0,strlen(vname));
1129       pstrcpy(pdata+4,vname);      
1130       break;
1131     case SMB_QUERY_FS_VOLUME_INFO:      
1132
1133       /*
1134        * NB: The earlier CIFS spec that says this always  
1135        * uses UNICODE is incorrect ! JRA.
1136        */
1137
1138       data_len = 18 + strlen(vname);
1139
1140       /* 
1141        * Add volume serial number - hash of a combination of
1142        * the called hostname and the service name.
1143        */
1144       SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1145       SIVAL(pdata,12,strlen(vname));
1146       pstrcpy(pdata+18,vname);      
1147       DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", strlen(vname),
1148                vname));
1149       break;
1150     case SMB_QUERY_FS_SIZE_INFO:
1151     {
1152       SMB_BIG_UINT dfree,dsize,bsize;
1153       data_len = 24;
1154       sys_disk_free(".",&bsize,&dfree,&dsize);  
1155       SIVAL(pdata,0,dsize);
1156       SIVAL(pdata,8,dfree);
1157       SIVAL(pdata,16,bsize/512);
1158       SIVAL(pdata,20,512);
1159       break;
1160     }
1161     case SMB_QUERY_FS_DEVICE_INFO:
1162       data_len = 8;
1163       SIVAL(pdata,0,0); /* dev type */
1164       SIVAL(pdata,4,0); /* characteristics */
1165       break;
1166     default:
1167       return(ERROR(ERRDOS,ERRunknownlevel));
1168   }
1169
1170
1171   send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1172
1173   DEBUG( 4, ( "%s info_level = %d\n",
1174             smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1175
1176   return -1;
1177 }
1178
1179 /****************************************************************************
1180   reply to a TRANS2_SETFSINFO (set filesystem info)
1181 ****************************************************************************/
1182 static int call_trans2setfsinfo(connection_struct *conn,
1183                                 char *inbuf, char *outbuf, int length, 
1184                                 int bufsize,
1185                                 char **pparams, char **ppdata)
1186 {
1187   /* Just say yes we did it - there is nothing that
1188      can be set here so it doesn't matter. */
1189   int outsize;
1190   DEBUG(3,("call_trans2setfsinfo\n"));
1191
1192   if (!CAN_WRITE(conn))
1193     return(ERROR(ERRSRV,ERRaccess));
1194
1195   outsize = set_message(outbuf,10,0,True);
1196
1197   return outsize;
1198 }
1199
1200 /****************************************************************************
1201   Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1202   file name or file id).
1203 ****************************************************************************/
1204
1205 static int call_trans2qfilepathinfo(connection_struct *conn,
1206                                     char *inbuf, char *outbuf, int length, 
1207                                     int bufsize,
1208                                     char **pparams,char **ppdata,
1209                                     int total_data)
1210 {
1211   char *params = *pparams;
1212   char *pdata = *ppdata;
1213   uint16 tran_call = SVAL(inbuf, smb_setup0);
1214   uint16 info_level;
1215   int mode=0;
1216   SMB_OFF_T size=0;
1217   unsigned int data_size;
1218   SMB_STRUCT_STAT sbuf;
1219   pstring fname1;
1220   char *fname;
1221   char *p;
1222   int l;
1223   SMB_OFF_T pos;
1224   BOOL bad_path = False;
1225
1226   if (tran_call == TRANSACT2_QFILEINFO) {
1227     files_struct *fsp = file_fsp(params,0);
1228     info_level = SVAL(params,2);
1229
1230     CHECK_FSP(fsp,conn);
1231     CHECK_ERROR(fsp);
1232
1233     fname = fsp->fsp_name;
1234     if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
1235       DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1236       return(UNIXERROR(ERRDOS,ERRbadfid));
1237     }
1238     pos = sys_lseek(fsp->fd_ptr->fd,0,SEEK_CUR);
1239   } else {
1240     /* qpathinfo */
1241     info_level = SVAL(params,0);
1242     fname = &fname1[0];
1243     pstrcpy(fname,&params[6]);
1244     unix_convert(fname,conn,0,&bad_path,&sbuf);
1245     if (!check_name(fname,conn) || (!VALID_STAT(sbuf) && dos_stat(fname,&sbuf))) {
1246       DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1247       if((errno == ENOENT) && bad_path)
1248       {
1249         unix_ERR_class = ERRDOS;
1250         unix_ERR_code = ERRbadpath;
1251       }
1252       return(UNIXERROR(ERRDOS,ERRbadpath));
1253     }
1254     pos = 0;
1255   }
1256
1257
1258   DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1259            fname,info_level,tran_call,total_data));
1260
1261   p = strrchr(fname,'/'); 
1262   if (!p) 
1263     p = fname;
1264   else
1265     p++;
1266   l = strlen(p);  
1267   mode = dos_mode(conn,fname,&sbuf);
1268   size = sbuf.st_size;
1269   if (mode & aDIR) size = 0;
1270
1271   /* from now on we only want the part after the / */
1272   fname = p;
1273   
1274   params = *pparams = Realloc(*pparams,2); bzero(params,2);
1275   data_size = 1024;
1276   pdata = *ppdata = Realloc(*ppdata, data_size); 
1277
1278   if (total_data > 0 && IVAL(pdata,0) == total_data) {
1279     /* uggh, EAs for OS2 */
1280     DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1281     return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1282   }
1283
1284   bzero(pdata,data_size);
1285
1286   switch (info_level) 
1287     {
1288     case SMB_INFO_STANDARD:
1289     case SMB_INFO_QUERY_EA_SIZE:
1290       data_size = (info_level==1?22:26);
1291       put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1292       put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1293       put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1294       SIVAL(pdata,l1_cbFile,(uint32)size);
1295       SIVAL(pdata,l1_cbFileAlloc,ROUNDUP(size,1024));
1296       SSVAL(pdata,l1_attrFile,mode);
1297       SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1298       break;
1299
1300     case SMB_INFO_QUERY_EAS_FROM_LIST:
1301       data_size = 24;
1302       put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1303       put_dos_date2(pdata,4,sbuf.st_atime);
1304       put_dos_date2(pdata,8,sbuf.st_mtime);
1305       SIVAL(pdata,12,(uint32)size);
1306       SIVAL(pdata,16,ROUNDUP(size,1024));
1307       SIVAL(pdata,20,mode);
1308       break;
1309
1310     case SMB_INFO_QUERY_ALL_EAS:
1311       data_size = 4;
1312       SIVAL(pdata,0,data_size);
1313       break;
1314
1315     case 6:
1316       return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */      
1317
1318     case SMB_QUERY_FILE_BASIC_INFO:
1319       data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1320       put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1321       put_long_date(pdata+8,sbuf.st_atime);
1322       put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1323       put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1324       SIVAL(pdata,32,mode);
1325
1326       DEBUG(5,("SMB_QFBI - "));
1327       {
1328         time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1329         DEBUG(5,("create: %s ", ctime(&create_time)));
1330       }
1331       DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1332       DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1333       DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1334       DEBUG(5,("mode: %x\n", mode));
1335
1336       break;
1337
1338     case SMB_QUERY_FILE_STANDARD_INFO:
1339       data_size = 22;
1340       SOFF_T(pdata,0,size);
1341       SOFF_T(pdata,8,size);
1342       SIVAL(pdata,16,sbuf.st_nlink);
1343       CVAL(pdata,20) = 0;
1344       CVAL(pdata,21) = (mode&aDIR)?1:0;
1345       break;
1346
1347     case SMB_QUERY_FILE_EA_INFO:
1348       data_size = 4;
1349       break;
1350
1351     /* Get the 8.3 name - used if NT SMB was negotiated. */
1352     case SMB_QUERY_FILE_ALT_NAME_INFO:
1353       {
1354         pstring short_name;
1355         pstrcpy(short_name,p);
1356         /* Mangle if not already 8.3 */
1357         if(!is_8_3(short_name, True))
1358         {
1359           if(!name_map_mangle(short_name,True,SNUM(conn)))
1360             *short_name = '\0';
1361         }
1362         strupper(short_name);
1363         l = strlen(short_name);
1364         PutUniCode(pdata + 4, short_name);
1365         data_size = 4 + (2*l);
1366         SIVAL(pdata,0,2*l);
1367       }
1368       break;
1369
1370     case SMB_QUERY_FILE_NAME_INFO:
1371       data_size = 4 + l;
1372       SIVAL(pdata,0,l);
1373       pstrcpy(pdata+4,fname);
1374       break;
1375
1376     case SMB_QUERY_FILE_ALLOCATION_INFO:
1377     case SMB_QUERY_FILE_END_OF_FILEINFO:
1378       data_size = 8;
1379       SOFF_T(pdata,0,size);
1380       break;
1381
1382     case SMB_QUERY_FILE_ALL_INFO:
1383       put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1384       put_long_date(pdata+8,sbuf.st_atime);
1385       put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1386       put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1387       SIVAL(pdata,32,mode);
1388       pdata += 40;
1389       SOFF_T(pdata,0,size);
1390       SOFF_T(pdata,8,size);
1391       SIVAL(pdata,16,sbuf.st_nlink);
1392       CVAL(pdata,20) = 0;
1393       CVAL(pdata,21) = (mode&aDIR)?1:0;
1394       pdata += 24;
1395       pdata += 8; /* index number */
1396       pdata += 4; /* EA info */
1397       if (mode & aRONLY)
1398         SIVAL(pdata,0,0xA9);
1399       else
1400         SIVAL(pdata,0,0xd01BF);
1401       pdata += 4;
1402       SIVAL(pdata,0,pos); /* current offset */
1403       pdata += 8;
1404       SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1405       pdata += 4;
1406       pdata += 4; /* alignment */
1407       SIVAL(pdata,0,l);
1408       pstrcpy(pdata+4,fname);
1409       pdata += 4 + l;
1410       data_size = PTR_DIFF(pdata,(*ppdata));
1411       break;
1412
1413 #if 0
1414       /* NT4 server just returns "invalid query" to this - if we try to answer 
1415          it then NTws gets a BSOD! (tridge) */
1416     case SMB_QUERY_FILE_STREAM_INFO:
1417       data_size = 24 + l;
1418       SIVAL(pdata,0,pos);
1419       SIVAL(pdata,4,size);
1420       SIVAL(pdata,12,size);
1421       SIVAL(pdata,20,l);        
1422       pstrcpy(pdata+24,fname);
1423       break;
1424 #endif
1425
1426     default:
1427       return(ERROR(ERRDOS,ERRunknownlevel));
1428     }
1429
1430   send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1431
1432   return(-1);
1433 }
1434
1435 /****************************************************************************
1436   reply to a TRANS2_SETFILEINFO (set file info by fileid)
1437 ****************************************************************************/
1438 static int call_trans2setfilepathinfo(connection_struct *conn,
1439                                       char *inbuf, char *outbuf, int length, 
1440                                       int bufsize, char **pparams, 
1441                                       char **ppdata, int total_data)
1442 {
1443   char *params = *pparams;
1444   char *pdata = *ppdata;
1445   uint16 tran_call = SVAL(inbuf, smb_setup0);
1446   uint16 info_level;
1447   int mode=0;
1448   SMB_OFF_T size=0;
1449   struct utimbuf tvs;
1450   SMB_STRUCT_STAT st;
1451   pstring fname1;
1452   char *fname;
1453   int fd = -1;
1454   BOOL bad_path = False;
1455
1456   if (!CAN_WRITE(conn))
1457     return(ERROR(ERRSRV,ERRaccess));
1458
1459   if (tran_call == TRANSACT2_SETFILEINFO) {
1460     files_struct *fsp = file_fsp(params,0);
1461     info_level = SVAL(params,2);    
1462
1463     CHECK_FSP(fsp,conn);
1464     CHECK_ERROR(fsp);
1465
1466     fname = fsp->fsp_name;
1467     fd = fsp->fd_ptr->fd;
1468
1469     if(sys_fstat(fd,&st)!=0) {
1470       DEBUG(3,("fstat of %s failed (%s)\n", fname, strerror(errno)));
1471       return(ERROR(ERRDOS,ERRbadpath));
1472     }
1473   } else {
1474     /* set path info */
1475     info_level = SVAL(params,0);    
1476     fname = fname1;
1477     pstrcpy(fname,&params[6]);
1478     unix_convert(fname,conn,0,&bad_path,&st);
1479     if(!check_name(fname, conn))
1480     {
1481       if((errno == ENOENT) && bad_path)
1482       {
1483         unix_ERR_class = ERRDOS;
1484         unix_ERR_code = ERRbadpath;
1485       }
1486       return(UNIXERROR(ERRDOS,ERRbadpath));
1487     }
1488  
1489     if(!VALID_STAT(st) && dos_stat(fname,&st)!=0) {
1490       DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1491       if((errno == ENOENT) && bad_path)
1492       {
1493         unix_ERR_class = ERRDOS;
1494         unix_ERR_code = ERRbadpath;
1495       }
1496       return(UNIXERROR(ERRDOS,ERRbadpath));
1497     }    
1498   }
1499
1500   DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1501            tran_call,fname,info_level,total_data));
1502
1503   /* Realloc the parameter and data sizes */
1504   params = *pparams = Realloc(*pparams,2); SSVAL(params,0,0);
1505   if(params == NULL)
1506     return(ERROR(ERRDOS,ERRnomem));
1507
1508   size = st.st_size;
1509   tvs.modtime = st.st_mtime;
1510   tvs.actime = st.st_atime;
1511   mode = dos_mode(conn,fname,&st);
1512
1513   if (total_data > 0 && IVAL(pdata,0) == total_data) {
1514     /* uggh, EAs for OS2 */
1515     DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1516     return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1517   }
1518
1519   switch (info_level)
1520   {
1521     case SMB_INFO_STANDARD:
1522     case SMB_INFO_QUERY_EA_SIZE:
1523     {
1524       /* access time */
1525       tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1526
1527       /* write time */
1528       tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1529
1530       mode = SVAL(pdata,l1_attrFile);
1531       size = IVAL(pdata,l1_cbFile);
1532       break;
1533     }
1534
1535     /* XXXX um, i don't think this is right.
1536        it's also not in the cifs6.txt spec.
1537      */
1538     case SMB_INFO_QUERY_EAS_FROM_LIST:
1539       tvs.actime = make_unix_date2(pdata+8);
1540       tvs.modtime = make_unix_date2(pdata+12);
1541       size = IVAL(pdata,16);
1542       mode = IVAL(pdata,24);
1543       break;
1544
1545     /* XXXX nor this.  not in cifs6.txt, either. */
1546     case SMB_INFO_QUERY_ALL_EAS:
1547       tvs.actime = make_unix_date2(pdata+8);
1548       tvs.modtime = make_unix_date2(pdata+12);
1549       size = IVAL(pdata,16);
1550       mode = IVAL(pdata,24);
1551       break;
1552
1553     case SMB_SET_FILE_BASIC_INFO:
1554     {
1555       /* Ignore create time at offset pdata. */
1556
1557       /* access time */
1558       tvs.actime = interpret_long_date(pdata+8);
1559
1560       /* write time + changed time, combined. */
1561       tvs.modtime=MAX(interpret_long_date(pdata+16),
1562                       interpret_long_date(pdata+24));
1563
1564 #if 0 /* Needs more testing... */
1565       /* Test from Luke to prevent Win95 from
1566          setting incorrect values here.
1567        */
1568       if (tvs.actime < tvs.modtime)
1569         return(ERROR(ERRDOS,ERRnoaccess));
1570 #endif /* Needs more testing... */
1571
1572       /* attributes */
1573       mode = IVAL(pdata,32);
1574       break;
1575     }
1576
1577     case SMB_SET_FILE_END_OF_FILE_INFO:
1578     {
1579       size = IVAL(pdata,0);
1580 #ifdef LARGE_SMB_OFF_T
1581       size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1582 #else /* LARGE_SMB_OFF_T */
1583       if (IVAL(pdata,4) != 0)   /* more than 32 bits? */
1584          return(ERROR(ERRDOS,ERRunknownlevel));
1585 #endif /* LARGE_SMB_OFF_T */
1586       break;
1587     }
1588
1589     case SMB_SET_FILE_ALLOCATION_INFO:
1590       break; /* We don't need to do anything for this call. */
1591
1592     case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1593     {
1594       if (tran_call == TRANSACT2_SETFILEINFO) {
1595         files_struct *fsp = file_fsp(params,0);
1596         if(fsp->is_directory)
1597           return(ERROR(ERRDOS,ERRnoaccess));
1598         /*
1599          * TODO - check here is this means set
1600          * this flag bit on all open files that
1601          * reference this particular dev/inode pair.
1602          * If so we'll need to search the open
1603          * file entries here and set this flag on 
1604          * all of them that match. JRA.
1605          */
1606         fsp->delete_on_close = CVAL(pdata,0);
1607       } else
1608         return(ERROR(ERRDOS,ERRunknownlevel));
1609       break;
1610     }
1611
1612     default:
1613     {
1614       return(ERROR(ERRDOS,ERRunknownlevel));
1615     }
1616   }
1617
1618   DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1619   DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1620   DEBUG(6,("size: %.0f ", (double)size));
1621   DEBUG(6,("mode: %x\n"  , mode));
1622
1623   /* get some defaults (no modifications) if any info is zero. */
1624   if (!tvs.actime) tvs.actime = st.st_atime;
1625   if (!tvs.modtime) tvs.modtime = st.st_mtime;
1626   if (!size) size = st.st_size;
1627
1628   /* Try and set the times, size and mode of this file -
1629      if they are different from the current values
1630    */
1631   if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime)
1632   {
1633     if(file_utime(conn, fname, &tvs)!=0)
1634     {
1635       return(ERROR(ERRDOS,ERRnoaccess));
1636     }
1637   }
1638
1639   /* check the mode isn't different, before changing it */
1640   if (mode != dos_mode(conn, fname, &st) && file_chmod(conn, fname, mode, NULL))
1641   {
1642     DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1643     return(ERROR(ERRDOS,ERRnoaccess));
1644   }
1645
1646   if(size != st.st_size)
1647   {
1648     if (fd == -1)
1649     {
1650       fd = dos_open(fname,O_RDWR,0);
1651       if (fd == -1)
1652       {
1653         return(ERROR(ERRDOS,ERRbadpath));
1654       }
1655       set_filelen(fd, size);
1656       close(fd);
1657     }
1658     else
1659     {
1660       set_filelen(fd, size);
1661     }
1662   }
1663
1664   SSVAL(params,0,0);
1665
1666   send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1667   
1668   return(-1);
1669 }
1670
1671 /****************************************************************************
1672   reply to a TRANS2_MKDIR (make directory with extended attributes).
1673 ****************************************************************************/
1674 static int call_trans2mkdir(connection_struct *conn,
1675                             char *inbuf, char *outbuf, int length, int bufsize,
1676                             char **pparams, char **ppdata)
1677 {
1678   char *params = *pparams;
1679   pstring directory;
1680   int ret = -1;
1681   BOOL bad_path = False;
1682
1683   if (!CAN_WRITE(conn))
1684     return(ERROR(ERRSRV,ERRaccess));
1685
1686   pstrcpy(directory, &params[4]);
1687
1688   DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
1689
1690   unix_convert(directory,conn,0,&bad_path,NULL);
1691   if (check_name(directory,conn))
1692     ret = dos_mkdir(directory,unix_mode(conn,aDIR));
1693   
1694   if(ret < 0)
1695     {
1696       DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
1697       if((errno == ENOENT) && bad_path)
1698       {
1699         unix_ERR_class = ERRDOS;
1700         unix_ERR_code = ERRbadpath;
1701       }
1702       return(UNIXERROR(ERRDOS,ERRnoaccess));
1703     }
1704
1705   /* Realloc the parameter and data sizes */
1706   params = *pparams = Realloc(*pparams,2);
1707   if(params == NULL)
1708     return(ERROR(ERRDOS,ERRnomem));
1709
1710   SSVAL(params,0,0);
1711
1712   send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1713   
1714   return(-1);
1715 }
1716
1717 /****************************************************************************
1718   reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
1719   We don't actually do this - we just send a null response.
1720 ****************************************************************************/
1721 static int call_trans2findnotifyfirst(connection_struct *conn,
1722                                       char *inbuf, char *outbuf, 
1723                                       int length, int bufsize,
1724                                       char **pparams, char **ppdata)
1725 {
1726   static uint16 fnf_handle = 257;
1727   char *params = *pparams;
1728   uint16 info_level = SVAL(params,4);
1729
1730   DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
1731
1732   switch (info_level) 
1733     {
1734     case 1:
1735     case 2:
1736       break;
1737     default:
1738       return(ERROR(ERRDOS,ERRunknownlevel));
1739     }
1740
1741   /* Realloc the parameter and data sizes */
1742   params = *pparams = Realloc(*pparams,6);
1743   if(params == NULL)
1744     return(ERROR(ERRDOS,ERRnomem));
1745
1746   SSVAL(params,0,fnf_handle);
1747   SSVAL(params,2,0); /* No changes */
1748   SSVAL(params,4,0); /* No EA errors */
1749
1750   fnf_handle++;
1751
1752   if(fnf_handle == 0)
1753     fnf_handle = 257;
1754
1755   send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
1756   
1757   return(-1);
1758 }
1759
1760 /****************************************************************************
1761   reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for 
1762   changes). Currently this does nothing.
1763 ****************************************************************************/
1764 static int call_trans2findnotifynext(connection_struct *conn,
1765                                      char *inbuf, char *outbuf, 
1766                                      int length, int bufsize,
1767                                      char **pparams, char **ppdata)
1768 {
1769   char *params = *pparams;
1770
1771   DEBUG(3,("call_trans2findnotifynext\n"));
1772
1773   /* Realloc the parameter and data sizes */
1774   params = *pparams = Realloc(*pparams,4);
1775   if(params == NULL)
1776     return(ERROR(ERRDOS,ERRnomem));
1777
1778   SSVAL(params,0,0); /* No changes */
1779   SSVAL(params,2,0); /* No EA errors */
1780
1781   send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
1782   
1783   return(-1);
1784 }
1785
1786 /****************************************************************************
1787   reply to a SMBfindclose (stop trans2 directory search)
1788 ****************************************************************************/
1789 int reply_findclose(connection_struct *conn,
1790                     char *inbuf,char *outbuf,int length,int bufsize)
1791 {
1792         int outsize = 0;
1793         int16 dptr_num=SVALS(inbuf,smb_vwv0);
1794
1795         DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
1796
1797         dptr_close(dptr_num);
1798
1799         outsize = set_message(outbuf,0,0,True);
1800
1801         DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
1802
1803         return(outsize);
1804 }
1805
1806 /****************************************************************************
1807   reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
1808 ****************************************************************************/
1809 int reply_findnclose(connection_struct *conn, 
1810                      char *inbuf,char *outbuf,int length,int bufsize)
1811 {
1812         int outsize = 0;
1813         int dptr_num= -1;
1814         
1815         dptr_num = SVAL(inbuf,smb_vwv0);
1816
1817         DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
1818
1819         /* We never give out valid handles for a 
1820            findnotifyfirst - so any dptr_num is ok here. 
1821            Just ignore it. */
1822
1823         outsize = set_message(outbuf,0,0,True);
1824
1825         DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
1826
1827         return(outsize);
1828 }
1829
1830
1831 /****************************************************************************
1832   reply to a SMBtranss2 - just ignore it!
1833 ****************************************************************************/
1834 int reply_transs2(connection_struct *conn,
1835                   char *inbuf,char *outbuf,int length,int bufsize)
1836 {
1837         DEBUG(4,("Ignoring transs2 of length %d\n",length));
1838         return(-1);
1839 }
1840
1841 /****************************************************************************
1842   reply to a SMBtrans2
1843 ****************************************************************************/
1844 int reply_trans2(connection_struct *conn,
1845                  char *inbuf,char *outbuf,int length,int bufsize)
1846 {
1847         int outsize = 0;
1848         unsigned int total_params = SVAL(inbuf, smb_tpscnt);
1849         unsigned int total_data =SVAL(inbuf, smb_tdscnt);
1850 #if 0
1851         unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
1852         unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
1853         unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
1854         BOOL close_tid = BITSETW(inbuf+smb_flags,0);
1855         BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
1856         int32 timeout = IVALS(inbuf,smb_timeout);
1857 #endif
1858         unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
1859         unsigned int tran_call = SVAL(inbuf, smb_setup0);
1860         char *params = NULL, *data = NULL;
1861         int num_params, num_params_sofar, num_data, num_data_sofar;
1862
1863         if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
1864                 /* Queue this open message as we are the process of an
1865                  * oplock break.  */
1866
1867                 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
1868                 DEBUGADD(2,( "in oplock break state.\n"));
1869
1870                 push_oplock_pending_smb_message(inbuf, length);
1871                 return -1;
1872         }
1873         
1874         outsize = set_message(outbuf,0,0,True);
1875
1876         /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
1877            is so as a sanity check */
1878         if (suwcnt != 1) {
1879                 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
1880                 return(ERROR(ERRSRV,ERRerror));
1881         }
1882     
1883         /* Allocate the space for the maximum needed parameters and data */
1884         if (total_params > 0)
1885                 params = (char *)malloc(total_params);
1886         if (total_data > 0)
1887                 data = (char *)malloc(total_data);
1888   
1889         if ((total_params && !params)  || (total_data && !data)) {
1890                 DEBUG(2,("Out of memory in reply_trans2\n"));
1891                 return(ERROR(ERRDOS,ERRnomem));
1892         }
1893
1894         /* Copy the param and data bytes sent with this request into
1895            the params buffer */
1896         num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
1897         num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
1898
1899         if (num_params > total_params || num_data > total_data)
1900                 exit_server("invalid params in reply_trans2");
1901
1902         if(params)
1903                 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
1904         if(data)
1905                 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
1906
1907         if(num_data_sofar < total_data || num_params_sofar < total_params)  {
1908                 /* We need to send an interim response then receive the rest
1909                    of the parameter/data bytes */
1910                 outsize = set_message(outbuf,0,0,True);
1911                 send_smb(Client,outbuf);
1912
1913                 while (num_data_sofar < total_data || 
1914                        num_params_sofar < total_params) {
1915                         BOOL ret;
1916
1917                         ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,
1918                                                SMB_SECONDARY_WAIT);
1919                         
1920                         if ((ret && 
1921                              (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
1922                                 outsize = set_message(outbuf,0,0,True);
1923                                 if(ret)
1924                                         DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
1925                                 else
1926                                         DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
1927                                                  (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
1928                                 if(params)
1929                                         free(params);
1930                                 if(data)
1931                                         free(data);
1932                                 return(ERROR(ERRSRV,ERRerror));
1933                         }
1934       
1935                         /* Revise total_params and total_data in case
1936                            they have changed downwards */
1937                         total_params = SVAL(inbuf, smb_tpscnt);
1938                         total_data = SVAL(inbuf, smb_tdscnt);
1939                         num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
1940                         num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
1941                         if (num_params_sofar > total_params || num_data_sofar > total_data)
1942                                 exit_server("data overflow in trans2");
1943                         
1944                         memcpy( &params[ SVAL(inbuf, smb_spsdisp)], 
1945                                 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
1946                         memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
1947                                 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
1948                 }
1949         }
1950         
1951         if (Protocol >= PROTOCOL_NT1) {
1952                 uint16 flg2 = SVAL(outbuf,smb_flg2);
1953                 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
1954         }
1955
1956         /* Now we must call the relevant TRANS2 function */
1957         switch(tran_call)  {
1958         case TRANSACT2_OPEN:
1959                 outsize = call_trans2open(conn, 
1960                                           inbuf, outbuf, bufsize, 
1961                                           &params, &data);
1962                 break;
1963
1964         case TRANSACT2_FINDFIRST:
1965                 outsize = call_trans2findfirst(conn, inbuf, outbuf, 
1966                                                bufsize, &params, &data);
1967                 break;
1968
1969         case TRANSACT2_FINDNEXT:
1970                 outsize = call_trans2findnext(conn, inbuf, outbuf, 
1971                                               length, bufsize, 
1972                                               &params, &data);
1973                 break;
1974
1975         case TRANSACT2_QFSINFO:
1976             outsize = call_trans2qfsinfo(conn, inbuf, outbuf, 
1977                                          length, bufsize, &params, 
1978                                          &data);
1979             break;
1980
1981         case TRANSACT2_SETFSINFO:
1982                 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, 
1983                                                length, bufsize, 
1984                                                &params, &data);
1985                 break;
1986
1987         case TRANSACT2_QPATHINFO:
1988         case TRANSACT2_QFILEINFO:
1989                 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, 
1990                                                    length, bufsize, 
1991                                                    &params, &data, total_data);
1992                 break;
1993         case TRANSACT2_SETPATHINFO:
1994         case TRANSACT2_SETFILEINFO:
1995                 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, 
1996                                                      length, bufsize, 
1997                                                      &params, &data, 
1998                                                      total_data);
1999                 break;
2000
2001         case TRANSACT2_FINDNOTIFYFIRST:
2002                 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, 
2003                                                      length, bufsize, 
2004                                                      &params, &data);
2005                 break;
2006
2007         case TRANSACT2_FINDNOTIFYNEXT:
2008                 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, 
2009                                                     length, bufsize, 
2010                                                     &params, &data);
2011                 break;
2012         case TRANSACT2_MKDIR:
2013                 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, 
2014                                            bufsize, &params, &data);
2015                 break;
2016         default:
2017                 /* Error in request */
2018                 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2019                 if(params)
2020                         free(params);
2021                 if(data)
2022                         free(data);
2023                 return (ERROR(ERRSRV,ERRerror));
2024         }
2025         
2026         /* As we do not know how many data packets will need to be
2027            returned here the various call_trans2xxxx calls
2028            must send their own. Thus a call_trans2xxx routine only
2029            returns a value other than -1 when it wants to send
2030            an error packet. 
2031         */
2032         
2033         if(params)
2034                 free(params);
2035         if(data)
2036                 free(data);
2037         return outsize; /* If a correct response was needed the
2038                            call_trans2xxx calls have already sent
2039                            it. If outsize != -1 then it is returning */
2040 }