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