]> git.ipfire.org Git - thirdparty/squid.git/blob - lib/smblib/file.c
Renamed squid.h to squid-old.h and config.h to squid.h.
[thirdparty/squid.git] / lib / smblib / file.c
1 #include "squid.h"
2 /* UNIX SMBlib NetBIOS implementation
3
4 Version 1.0
5 SMBlib File Access Routines
6
7 Copyright (C) Richard Sharpe 1996
8
9 */
10
11 /*
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27 #include "smblib/smblib-priv.h"
28 #include "rfcnb/rfcnb.h"
29
30 #if HAVE_STRING_H
31 #include <string.h>
32 #endif
33
34 /* Open a file with file_name using desired mode and search attr */
35 /* If File_Handle is null, then create and populate a file handle */
36
37 SMB_File *SMB_Open(SMB_Tree_Handle Tree_Handle,
38 SMB_File *File_Handle,
39 char *file_name,
40 WORD mode,
41 WORD search)
42
43 {
44 struct RFCNB_Pkt *pkt;
45 int pkt_len, param_len;
46 char *p;
47 struct SMB_File_Def *file_tmp;
48
49 /* We allocate a file object and copy some things ... */
50
51 file_tmp = File_Handle;
52
53 if (File_Handle == NULL) {
54
55 if ((file_tmp = (SMB_File *)malloc(sizeof(SMB_File))) == NULL) {
56
57 #ifdef DEBUG
58 fprintf(stderr, "Could not allocate file handle space ...");
59 #endif
60
61 SMBlib_errno = SMBlibE_NoSpace;
62 return(NULL);
63
64 }
65
66 }
67
68 strncpy(file_tmp -> filename, file_name, sizeof(file_tmp -> filename) - 1);
69 file_tmp -> tree = Tree_Handle;
70 file_tmp -> fid = 0xFFFF; /* Is this an invalid FID? */
71
72 param_len = strlen(file_name) + 2; /* 1 for null, 1 for ASCII marker */
73
74 pkt_len = SMB_open_len + param_len;
75
76 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(max(pkt_len, SMB_openr_len));
77
78 if (pkt == NULL) { /* Really should do some error handling */
79
80 if (File_Handle == NULL)
81 free(file_tmp);
82 SMBlib_errno = SMBlibE_NoSpace;
83 return(NULL);
84
85 }
86
87 /* Now plug in the bits we need */
88
89 memset(SMB_Hdr(pkt), 0, SMB_open_len);
90 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
91 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBopen;
92 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Tree_Handle -> con -> pid);
93 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, Tree_Handle -> tid);
94 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Tree_Handle -> con -> mid);
95 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Tree_Handle -> con -> uid);
96 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 2;
97
98 SSVAL(SMB_Hdr(pkt), SMB_open_mod_offset, mode);
99 SSVAL(SMB_Hdr(pkt), SMB_open_atr_offset, search);
100 SSVAL(SMB_Hdr(pkt), SMB_open_bcc_offset, param_len);
101
102 /* Now plug in the file name ... */
103
104 p = (char *)(SMB_Hdr(pkt) + SMB_open_buf_offset);
105 *p = SMBasciiID;
106 strcpy(p+1, file_name);
107 p = p + strlen(file_name);
108 *(p+1) = 0; /* plug in a null ... */
109
110 /* Now send the packet and get the response ... */
111
112 if (RFCNB_Send(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) {
113
114 #ifdef DEBUG
115 fprintf(stderr, "Error sending Open request\n");
116 #endif
117
118 if (File_Handle == NULL)
119 free(file_tmp);
120 RFCNB_Free_Pkt(pkt);
121 SMBlib_errno = -SMBlibE_SendFailed;
122 return(NULL);
123
124 }
125
126 /* Now get the response ... */
127
128 #ifdef DEBUG
129 fprintf(stderr, "Pkt_Len for Open resp = %i\n", pkt_len);
130 #endif
131
132 if (RFCNB_Recv(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) {
133
134 #ifdef DEBUG
135 fprintf(stderr, "Error receiving response to open request\n");
136 #endif
137
138 if (File_Handle = NULL)
139 free(file_tmp);
140 RFCNB_Free_Pkt(pkt);
141 SMBlib_errno = -SMBlibE_RecvFailed;
142 return(NULL);
143
144 }
145
146 /* Now parse the response and pass back any error ... */
147
148 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
149
150 #ifdef DEBUG
151 fprintf(stderr, "SMB_Open failed with errorclass = %i, Error Code = %i\n",
152 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
153 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
154 #endif
155
156 if (File_Handle = NULL)
157 free(file_tmp);
158 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
159 RFCNB_Free_Pkt(pkt);
160 SMBlib_errno = SMBlibE_Remote;
161 return(NULL); /* Should clean up ... */
162
163 }
164
165 file_tmp -> fid = SVAL(SMB_Hdr(pkt), SMB_openr_fid_offset);
166 file_tmp -> lastmod = IVAL(SMB_Hdr(pkt), SMB_openr_tim_offset);
167 file_tmp -> size = IVAL(SMB_Hdr(pkt), SMB_openr_fsz_offset);
168 file_tmp -> access = SVAL(SMB_Hdr(pkt), SMB_openr_acc_offset);
169 file_tmp -> fileloc = 0;
170
171 RFCNB_Free_Pkt(pkt); /* Free up this space */
172
173 #ifdef DEBUG
174 fprintf(stderr, "SMB_Open succeeded, FID = %i\n", file_tmp -> fid);
175 #endif
176
177 RFCNB_Free_Pkt(pkt);
178
179 return(file_tmp);
180
181 }
182
183 /* Close the file referred to in File_Handle */
184
185 int SMB_Close(SMB_File *File_Handle)
186
187 {
188 struct SMB_Close_Prot_Def *prot_pkt;
189 struct SMB_Hdr_Def_LM12 *resp_pkt;
190 struct RFCNB_Pkt *pkt;
191 int pkt_len;
192
193 if (File_Handle == NULL) { /* Error */
194
195 /*SMBLIB_errno = SMBLIBE_BadHandle; */
196 return(-1);
197
198 }
199
200 pkt_len = SMB_clos_len;
201
202 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
203
204 if (pkt == NULL) { /* Really should do some error handling */
205
206 SMBlib_errno = SMBlibE_NoSpace;
207 return(SMBlibE_BAD);
208
209 }
210
211 /* Now plug in the bits we need */
212
213 memset(SMB_Hdr(pkt), 0, SMB_clos_len);
214 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
215 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBclose;
216 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, File_Handle -> tree -> con -> pid);
217 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, File_Handle -> tree -> tid);
218 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, File_Handle -> tree -> con -> mid);
219 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, File_Handle -> tree -> con -> uid);
220 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 3;
221
222 SSVAL(SMB_Hdr(pkt), SMB_clos_fid_offset, File_Handle -> fid);
223 SIVAL(SMB_Hdr(pkt), SMB_clos_tim_offset, 0);
224 SSVAL(SMB_Hdr(pkt), SMB_clos_bcc_offset, 0);
225
226 /* Now send the packet and get the response ... */
227
228 if (RFCNB_Send(File_Handle -> tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
229
230 #ifdef DEBUG
231 fprintf(stderr, "Error sending Open request\n");
232 #endif
233
234 RFCNB_Free_Pkt(pkt);
235 SMBlib_errno = SMBlibE_SendFailed;
236 return(SMBlibE_BAD);
237
238 }
239
240 /* Now get the response ... */
241
242 if (RFCNB_Recv(File_Handle -> tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
243
244 #ifdef DEBUG
245 fprintf(stderr, "Error receiving response to open request\n");
246 #endif
247
248 RFCNB_Free_Pkt(pkt);
249 SMBlib_errno = SMBlibE_RecvFailed;
250 return(SMBlibE_BAD);
251
252 }
253
254 /* Now parse the response and pass back any error ... */
255
256 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
257
258 #ifdef DEBUG
259 fprintf(stderr, "SMB_Close failed with errorclass = %i, Error Code = %i\n",
260 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
261 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
262 #endif
263
264 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
265 RFCNB_Free_Pkt(pkt);
266 SMBlib_errno = SMBlibE_Remote;
267 return(SMBlibE_BAD); /* Should clean up ... */
268
269 }
270
271 #ifdef DEBUG
272 fprintf(stderr, "File %s closed successfully.\n", File_Handle -> filename);
273 #endif DEBUG
274
275 /* We should deallocate the File_Handle now ... */
276
277 File_Handle -> tree = NULL;
278 File_Handle -> filename[0] = 0;
279 File_Handle -> fid = 0xFFFF;
280
281 RFCNB_Free_Pkt(pkt);
282 free(File_Handle);
283
284 return(0);
285 }
286
287 /* Read numbytes into data from the file pointed to by File_Handle from */
288 /* the offset in the File_Handle. */
289
290 int SMB_Read(SMB_File *File_Handle, char *data, int numbytes)
291
292 {
293 int tot_read;
294 struct RFCNB_Pkt *snd_pkt, *recv_pkt, *data_ptr;
295 int snd_pkt_len, recv_pkt_len, this_read, bytes_left = numbytes;
296 int max_read_data, bytes_read = 0;
297
298 /* We loop around, reading the data, accumulating it into the buffer */
299 /* We build an SMB packet, where the data is pointed to by a fragment*/
300 /* tagged onto the end */
301
302 data_ptr = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(0);
303 if (data_ptr == NULL) {
304
305 /* We should handle the error here */
306
307 SMBlib_errno = SMBlibE_NoSpace;
308 return(SMBlibE_BAD);
309
310 }
311
312 snd_pkt_len = SMB_read_len; /* size for the read SMB */
313 recv_pkt_len = SMB_readr_len + 3; /* + 3 for the datablockID and blklen */
314
315 snd_pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(snd_pkt_len);
316
317 if (snd_pkt == NULL) {
318
319 RFCNB_Free_Pkt(data_ptr);
320 SMBlib_errno = SMBlibE_NoSpace;
321 return(SMBlibE_BAD);
322
323 }
324
325 recv_pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(recv_pkt_len);
326
327 if (recv_pkt == NULL) {
328
329 RFCNB_Free_Pkt(snd_pkt);
330 RFCNB_Free_Pkt(data_ptr);
331 SMBlib_errno = SMBlibE_NoSpace;
332 return(SMBlibE_BAD);
333
334 }
335
336 /* Put the recv pkt together */
337
338 recv_pkt -> next = data_ptr;
339
340 /* Now build the read request and the receive packet etc ... */
341
342 memset(SMB_Hdr(snd_pkt), 0, SMB_read_len);
343 SIVAL(SMB_Hdr(snd_pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
344 *(SMB_Hdr(snd_pkt) + SMB_hdr_com_offset) = SMBread;
345 SSVAL(SMB_Hdr(snd_pkt), SMB_hdr_pid_offset, File_Handle -> tree -> con -> pid);
346 SSVAL(SMB_Hdr(snd_pkt), SMB_hdr_tid_offset, File_Handle -> tree -> tid);
347 SSVAL(SMB_Hdr(snd_pkt), SMB_hdr_mid_offset, File_Handle -> tree -> con -> mid);
348 SSVAL(SMB_Hdr(snd_pkt), SMB_hdr_uid_offset, File_Handle -> tree -> con -> uid);
349 *(SMB_Hdr(snd_pkt) + SMB_hdr_wct_offset) = 5;
350 SSVAL(SMB_Hdr(snd_pkt), SMB_read_fid_offset, File_Handle -> fid);
351
352 max_read_data = (File_Handle -> tree -> mbs) - recv_pkt_len;
353
354 while (bytes_left > 0) {
355
356 this_read = (bytes_left > max_read_data?max_read_data: bytes_left);
357
358 SSVAL(SMB_Hdr(snd_pkt), SMB_read_cnt_offset, this_read);
359 SIVAL(SMB_Hdr(snd_pkt), SMB_read_ofs_offset, File_Handle -> fileloc);
360 SSVAL(SMB_Hdr(snd_pkt), SMB_read_clf_offset, 0x0);
361 SSVAL(SMB_Hdr(snd_pkt), SMB_read_bcc_offset, 0x0);
362
363 /* Now send the packet and wait for a response */
364
365 if (RFCNB_Send(File_Handle -> tree -> con -> Trans_Connect, snd_pkt, snd_pkt_len) < 0) {
366
367 #ifdef DEBUG
368 fprintf(stderr, "Error sending read request\n");
369 #endif
370
371 data_ptr -> data = NULL;
372 data_ptr -> len = 0;
373 RFCNB_Free_Pkt(recv_pkt);
374 RFCNB_Free_Pkt(snd_pkt);
375 SMBlib_errno = SMBlibE_SendFailed;
376 return(SMBlibE_BAD);
377
378 }
379
380 /* Now get the response ... first point the data portion to the right */
381 /* place in the read buffer ... what we are doing is ugly */
382
383 data_ptr -> data = (data + bytes_read);
384 data_ptr -> len = this_read;
385
386 if (RFCNB_Recv(File_Handle -> tree -> con -> Trans_Connect, recv_pkt, recv_pkt_len + this_read) < 0) {
387
388 #ifdef DEBUG
389 fprintf(stderr, "Error receiving response to write\n");
390 #endif
391
392 data_ptr -> len = 0;
393 data_ptr -> data = NULL;
394 RFCNB_Free_Pkt(recv_pkt);
395 RFCNB_Free_Pkt(snd_pkt);
396 SMBlib_errno = SMBlibE_RecvFailed;
397 return(SMBlibE_BAD);
398
399 }
400
401 if (CVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
402
403 #ifdef DEBUG
404 fprintf(stderr, "SMB_Read failed with errorclass = %i, Error Code = %i\n",
405 CVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset),
406 SVAL(SMB_Hdr(recv_pkt), SMB_hdr_err_offset));
407 #endif
408
409 SMBlib_SMB_Error = IVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset);
410 data_ptr -> data = NULL;
411 data_ptr -> len = 0;
412 RFCNB_Free_Pkt(recv_pkt);
413 RFCNB_Free_Pkt(snd_pkt);
414 SMBlib_errno = SMBlibE_Remote;
415 return(-1);
416
417 }
418
419 /* Ok, that worked, so update some things here ... */
420
421 bytes_read = bytes_read + SVAL(SMB_Hdr(recv_pkt), SMB_readr_cnt_offset);
422 bytes_left = bytes_left - SVAL(SMB_Hdr(recv_pkt), SMB_readr_cnt_offset);
423
424 }
425
426 /* Now free those packet headers that we allocated ... */
427
428 data_ptr -> data = NULL; /* Since recv_pkt points to data_ptr */
429 data_ptr -> len = 0; /* it is freed too */
430 RFCNB_Free_Pkt(recv_pkt);
431 RFCNB_Free_Pkt(snd_pkt);
432
433 return(bytes_read);
434
435 }
436
437 /* Lseek seeks just like the UNIX version does ... */
438
439 off_t SMB_Lseek(SMB_File *File_Handle, off_t offset, int whence)
440
441 {
442
443 /* We should check that the file handle is kosher ... We may also blow up
444 if we get a 64 bit offset ... should avoid wrap-around ... */
445
446 switch (whence) {
447 case SEEK_SET:
448
449 File_Handle -> fileloc = offset;
450 break;
451
452 case SEEK_CUR:
453
454 File_Handle -> fileloc = File_Handle -> fileloc + offset;
455 break;
456
457 case SEEK_END:
458
459 File_Handle -> fileloc = File_Handle -> size + offset;
460 break;
461
462 default:
463 return(-1);
464
465 }
466
467 return(File_Handle -> fileloc);
468
469 }
470
471
472 /* Write numbytes from data to the file pointed to by the File_Handle at */
473 /* the offset in the File_Handle. */
474
475 int SMB_Write(SMB_File *File_Handle, char *data, int numbytes)
476
477 {
478 int tot_written = 0;
479 struct RFCNB_Pkt *pkt, *data_ptr;
480 int pkt_len, i, this_write, max_write_data, bytes_left = numbytes;
481
482 /* We loop around, writing the data, accumulating what was written */
483 /* We build an SMB packet, where the data is pointed to by a fragment */
484 /* tagged onto the end ... */
485
486 data_ptr = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(0);
487 if (data_ptr == NULL) {
488
489 SMBlib_errno = SMBlibE_NoSpace;
490 return(SMBlibE_BAD);
491
492 }
493
494 pkt_len = SMB_write_len + 3; /* + 3 for the datablockID and blklen */
495
496 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
497
498 if (pkt == NULL) {
499
500 RFCNB_Free_Pkt(data_ptr);
501 SMBlib_errno = SMBlibE_NoSpace;
502 return(SMBlibE_BAD);
503
504 }
505
506 /* Now init the things that will be the same across the possibly multiple
507 packets to write this data. */
508
509 memset(SMB_Hdr(pkt), 0, SMB_write_len);
510 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
511 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBwrite;
512 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, File_Handle -> tree -> con -> pid);
513 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, File_Handle -> tree -> tid);
514 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, File_Handle -> tree -> con -> mid);
515 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, File_Handle -> tree -> con -> uid);
516 SSVAL(SMB_Hdr(pkt), SMB_write_fid_offset, File_Handle -> fid);
517
518 /* We will program this as send/response for the moment, but if we could
519 only send the second block before getting the first, we could speed
520 things up a bit ... */
521
522 max_write_data = (File_Handle -> tree -> mbs) - pkt_len;
523
524 /* the 3 is for the data block id and length that preceeds the data */
525
526 while (bytes_left > 0) {
527
528 /* bytes to write? */
529
530 this_write = (bytes_left > max_write_data?max_write_data:bytes_left);
531
532 data_ptr -> next = NULL;
533 data_ptr -> len = this_write;
534 data_ptr -> data = data + tot_written;
535
536 pkt -> next = data_ptr; /* link the data on the end */
537
538 SSVAL(SMB_Hdr(pkt), SMB_hdr_flg_offset, 0);
539 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 5;
540 SSVAL(SMB_Hdr(pkt), SMB_write_fid_offset, File_Handle -> fid);
541 SSVAL(SMB_Hdr(pkt), SMB_write_cnt_offset, this_write);
542 SIVAL(SMB_Hdr(pkt), SMB_write_ofs_offset, File_Handle -> fileloc);
543 SSVAL(SMB_Hdr(pkt), SMB_write_clf_offset, 0);
544 SSVAL(SMB_Hdr(pkt), SMB_write_bcc_offset, (this_write + 3));
545
546 *(SMB_Hdr(pkt) + SMB_write_buf_offset) = SMBdatablockID;
547 SSVAL(SMB_Hdr(pkt), SMB_write_buf_offset + 1, this_write);
548
549 /* Now send the packet and wait for a response */
550
551 if (RFCNB_Send(File_Handle -> tree -> con -> Trans_Connect, pkt, pkt_len + this_write) < 0) {
552
553 #ifdef DEBUG
554 fprintf(stderr, "Error sending write request\n");
555 #endif
556
557 data_ptr -> next = NULL;
558 data_ptr -> len = 0;
559 RFCNB_Free_Pkt(pkt);
560 SMBlib_errno = -SMBlibE_SendFailed;
561 return(-1);
562
563 }
564
565 /* Now get the response ... */
566
567 if (RFCNB_Recv(File_Handle -> tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
568
569 #ifdef DEBUG
570 fprintf(stderr, "Error receiving response to write\n");
571 #endif
572
573 data_ptr -> next = NULL;
574 data_ptr -> len = 0;
575 RFCNB_Free_Pkt(pkt);
576 SMBlib_errno = -SMBlibE_RecvFailed;
577 return(-1);
578
579 }
580
581 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
582
583 #ifdef DEBUG
584 fprintf(stderr, "SMB_Write failed with errorclass = %i, Error Code = %i\n",
585 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
586 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
587 #endif
588
589 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
590 data_ptr -> data = NULL;
591 data_ptr -> len = 0;
592 RFCNB_Free_Pkt(pkt);
593 SMBlib_errno = SMBlibE_Remote;
594 return(SMBlibE_BAD);
595
596 }
597
598 /* Ok, that worked, so update some things here ... */
599
600 tot_written = tot_written + this_write;
601 bytes_left = bytes_left - this_write;
602
603 /* Assume that it is ok to update this now, but what about only part */
604 /* of the write succeeding? */
605
606 File_Handle -> fileloc = File_Handle -> fileloc + this_write;
607
608 #ifdef DEBUG
609 fprintf(stderr, "--This_write = %i, bytes_left = %i\n",
610 this_write, bytes_left);
611 #endif
612
613 }
614
615 /* Let's get rid of those packet headers we are using ... */
616
617 data_ptr -> data = NULL;
618 pkt -> next = NULL;
619
620 RFCNB_Free_Pkt(pkt);
621
622 return(tot_written);
623
624 }
625
626 /* Create file on the server with name file_name and attributes search */
627
628 SMB_File *SMB_Create(SMB_Tree_Handle Tree_Handle,
629 SMB_File *File_Handle,
630 char *file_name,
631 WORD search)
632
633 {
634 struct RFCNB_Pkt *pkt;
635 int pkt_len, param_len;
636 char *p;
637 struct SMB_File_Def *file_tmp;
638
639 /* We allocate a file object and copy some things ... */
640
641 file_tmp = File_Handle;
642
643 if (File_Handle == NULL) {
644
645 if ((file_tmp = (SMB_File *)malloc(sizeof(SMB_File))) == NULL) {
646
647 #ifdef DEBUG
648 fprintf(stderr, "Could not allocate file handle space ...");
649 #endif
650
651 SMBlib_errno = SMBlibE_NoSpace;
652 return(NULL);
653
654 }
655
656 }
657
658 strncpy(file_tmp -> filename, file_name, sizeof(file_tmp -> filename));
659 file_tmp -> tree = Tree_Handle;
660 file_tmp -> fid = 0xFFFF; /* Is this an invalid FID? */
661
662 param_len = strlen(file_name) + 2; /* 1 for null, 1 for ASCII marker */
663
664 pkt_len = SMB_creat_len + param_len;
665
666 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
667
668 if (pkt == NULL) { /* Really should do some error handling */
669
670 if (File_Handle == NULL)
671 free(file_tmp);
672 SMBlib_errno = SMBlibE_NoSpace;
673 return(NULL);
674
675 }
676
677 /* Now plug in the bits we need */
678
679 memset(SMB_Hdr(pkt), 0, SMB_creat_len);
680 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
681 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBcreate;
682 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Tree_Handle -> con -> pid);
683 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, Tree_Handle -> tid);
684 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Tree_Handle -> con -> mid);
685 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Tree_Handle -> con -> uid);
686 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 3;
687
688 SSVAL(SMB_Hdr(pkt), SMB_creat_atr_offset, search);
689 SSVAL(SMB_Hdr(pkt), SMB_creat_tim_offset, 0);
690 SSVAL(SMB_Hdr(pkt), SMB_creat_dat_offset, 0);
691 SSVAL(SMB_Hdr(pkt), SMB_creat_bcc_offset, param_len);
692
693 /* Now plug in the file name ... */
694
695 p = (char *)(SMB_Hdr(pkt) + SMB_creat_buf_offset);
696 *p = SMBasciiID;
697 strcpy(p+1, file_name);
698 p = p + strlen(file_name);
699 *(p+1) = 0; /* plug in a null ... */
700
701 /* Now send the packet and get the response ... */
702
703 if (RFCNB_Send(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) {
704
705 #ifdef DEBUG
706 fprintf(stderr, "Error sending Open request\n");
707 #endif
708
709 if (File_Handle == NULL)
710 free(file_tmp);
711 RFCNB_Free_Pkt(pkt);
712 SMBlib_errno = -SMBlibE_SendFailed;
713 return(NULL);
714
715 }
716
717 /* Now get the response ... */
718
719 #ifdef DEBUG
720 fprintf(stderr, "Pkt_Len for Create resp = %i\n", pkt_len);
721 #endif
722
723 if (RFCNB_Recv(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) {
724
725 #ifdef DEBUG
726 fprintf(stderr, "Error receiving response to create request\n");
727 #endif
728
729 if (File_Handle == NULL)
730 free(file_tmp);
731 RFCNB_Free_Pkt(pkt);
732 SMBlib_errno = -SMBlibE_RecvFailed;
733 return(NULL);
734
735 }
736
737 /* Now parse the response and pass back any error ... */
738
739 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
740
741 #ifdef DEBUG
742 fprintf(stderr, "SMB_Create failed with errorclass = %i, Error Code = %i\n",
743 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
744 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
745 #endif
746
747 if (File_Handle == NULL)
748 free(file_tmp);
749 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
750 RFCNB_Free_Pkt(pkt);
751 SMBlib_errno = SMBlibE_Remote;
752 return(NULL); /* Should clean up ... */
753
754 }
755
756 file_tmp -> fid = SVAL(SMB_Hdr(pkt), SMB_creatr_fid_offset);
757 file_tmp -> lastmod = 0;
758 file_tmp -> size = 0;
759 file_tmp -> access = SMB_AMODE_OPENRW;
760 file_tmp -> fileloc = 0;
761
762 RFCNB_Free_Pkt(pkt); /* Free up this space */
763
764 #ifdef DEBUG
765 fprintf(stderr, "SMB_Create succeeded, FID = %i\n", file_tmp -> fid);
766 #endif
767
768 return(file_tmp);
769
770 }
771
772 /* Delete the file passed in as file_name. */
773
774 int SMB_Delete(SMB_Tree_Handle tree, char *file_name, WORD search)
775
776 {
777 struct RFCNB_Pkt *pkt;
778 int pkt_len, param_len;
779 char *p;
780
781 param_len = strlen(file_name) + 2;
782 pkt_len = SMB_delet_len + param_len;
783
784 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
785
786 if (pkt == NULL) { /* Really should do some error handling */
787
788 SMBlib_errno = SMBlibE_NoSpace;
789 return(SMBlibE_BAD);
790
791 }
792
793 /* Now plug in the bits we need */
794
795 memset(SMB_Hdr(pkt), 0, SMB_delet_len);
796 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
797 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBunlink;
798 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
799 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
800 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
801 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
802 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 1;
803
804 SIVAL(SMB_Hdr(pkt), SMB_delet_sat_offset, search);
805 SSVAL(SMB_Hdr(pkt), SMB_delet_bcc_offset, param_len);
806
807 /* Now plug in the file name ... */
808
809 p = (char *)(SMB_Hdr(pkt) + SMB_delet_buf_offset);
810 *p = SMBasciiID;
811 strcpy(p+1, file_name);
812 p = p + strlen(file_name);
813 *(p+1) = 0; /* plug in a null ... */
814
815 /* Now send the packet and get the response ... */
816
817 if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
818
819 #ifdef DEBUG
820 fprintf(stderr, "Error sending Delete request\n");
821 #endif
822
823 RFCNB_Free_Pkt(pkt);
824 SMBlib_errno = -SMBlibE_SendFailed;
825 return(SMBlibE_BAD);
826
827 }
828
829 /* Now get the response ... */
830
831 if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
832
833 #ifdef DEBUG
834 fprintf(stderr, "Error receiving response to delete request\n");
835 #endif
836
837 RFCNB_Free_Pkt(pkt);
838 SMBlib_errno = -SMBlibE_RecvFailed;
839 return(SMBlibE_BAD);
840
841 }
842
843 /* Now parse the response and pass back any error ... */
844
845 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
846
847 #ifdef DEBUG
848 fprintf(stderr, "SMB_Delete failed with errorclass = %i, Error Code = %i\n",
849 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
850 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
851 #endif
852
853 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
854 RFCNB_Free_Pkt(pkt);
855 SMBlib_errno = SMBlibE_Remote;
856 return(SMBlibE_BAD); /* Should clean up ... */
857
858 }
859
860 #ifdef DEBUG
861 fprintf(stderr, "File %s deleted successfully.\n", file_name);
862 #endif DEBUG
863
864 RFCNB_Free_Pkt(pkt);
865
866 return(0);
867 }
868
869 /* Create the directory passed in as dir_name */
870
871 int SMB_Create_Dir(SMB_Tree_Handle tree, char *dir_name)
872
873 {
874 struct RFCNB_Pkt *pkt;
875 int pkt_len, param_len;
876 char *p;
877
878 param_len = strlen(dir_name) + 2; /* + null and + asciiID */
879 pkt_len = SMB_creatdir_len + param_len;
880
881 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
882
883 if (pkt == NULL) { /* Really should do some error handling */
884
885 SMBlib_errno = SMBlibE_NoSpace;
886 return(SMBlibE_BAD);
887
888 }
889
890 /* Now plug in the bits we need */
891
892 memset(SMB_Hdr(pkt), 0, SMB_creatdir_len);
893 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
894 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBmkdir;
895 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
896 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
897 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
898 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
899 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;
900
901 SSVAL(SMB_Hdr(pkt), SMB_creatdir_bcc_offset, param_len);
902
903 /* Now plug in the file name ... */
904
905 p = (char *)(SMB_Hdr(pkt) + SMB_creatdir_buf_offset);
906 *p = SMBasciiID;
907 strcpy(p+1, dir_name);
908 p = p + strlen(dir_name);
909 *(p+1) = 0; /* plug in a null ... */
910
911 /* Now send the packet and get the response ... */
912
913 if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
914
915 #ifdef DEBUG
916 fprintf(stderr, "Error sending Create Dir request\n");
917 #endif
918
919 RFCNB_Free_Pkt(pkt);
920 SMBlib_errno = -SMBlibE_SendFailed;
921 return(SMBlibE_BAD);
922
923 }
924
925 /* Now get the response ... */
926
927 if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
928
929 #ifdef DEBUG
930 fprintf(stderr, "Error receiving response to Create Dir request\n");
931 #endif
932
933 RFCNB_Free_Pkt(pkt);
934 SMBlib_errno = -SMBlibE_RecvFailed;
935 return(SMBlibE_BAD);
936
937 }
938
939 /* Now parse the response and pass back any error ... */
940
941 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
942
943 #ifdef DEBUG
944 fprintf(stderr, "SMB_Create_Dir failed with errorclass = %i, Error Code = %i\n",
945 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
946 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
947 #endif
948
949 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
950 RFCNB_Free_Pkt(pkt);
951 SMBlib_errno = SMBlibE_Remote;
952 return(SMBlibE_BAD); /* Should clean up ... */
953
954 }
955
956 #ifdef DEBUG
957 fprintf(stderr, "Directory %s created successfully.\n", dir_name);
958 #endif DEBUG
959
960 RFCNB_Free_Pkt(pkt);
961
962 return(0);
963 }
964
965 /* Delete the directory passed as dir_name, as long as it is empty ... */
966
967 int SMB_Delete_Dir(SMB_Tree_Handle tree, char *dir_name)
968
969 {
970 struct RFCNB_Pkt *pkt;
971 int pkt_len, param_len;
972 char *p;
973
974 param_len = strlen(dir_name) + 2; /* + null and + asciiID */
975 pkt_len = SMB_deletdir_len + param_len;
976
977 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
978
979 if (pkt == NULL) { /* Really should do some error handling */
980
981 SMBlib_errno = SMBlibE_NoSpace;
982 return(SMBlibE_BAD);
983
984 }
985
986 /* Now plug in the bits we need */
987
988 memset(SMB_Hdr(pkt), 0, SMB_deletdir_len);
989 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
990 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBrmdir;
991 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
992 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
993 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
994 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
995 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;
996
997 SSVAL(SMB_Hdr(pkt), SMB_deletdir_bcc_offset, param_len);
998
999 /* Now plug in the file name ... */
1000
1001 p = (char *)(SMB_Hdr(pkt) + SMB_deletdir_buf_offset);
1002 *p = SMBasciiID;
1003 strcpy(p+1, dir_name);
1004 p = p + strlen(dir_name);
1005 *(p+1) = 0; /* plug in a null ... */
1006
1007 /* Now send the packet and get the response ... */
1008
1009 if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
1010
1011 #ifdef DEBUG
1012 fprintf(stderr, "Error sending Delete Dir request\n");
1013 #endif
1014
1015 RFCNB_Free_Pkt(pkt);
1016 SMBlib_errno = -SMBlibE_SendFailed;
1017 return(SMBlibE_BAD);
1018
1019 }
1020
1021 /* Now get the response ... */
1022
1023 if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
1024
1025 #ifdef DEBUG
1026 fprintf(stderr, "Error receiving response to Delete Dir request\n");
1027 #endif
1028
1029 RFCNB_Free_Pkt(pkt);
1030 SMBlib_errno = -SMBlibE_RecvFailed;
1031 return(SMBlibE_BAD);
1032
1033 }
1034
1035 /* Now parse the response and pass back any error ... */
1036
1037 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
1038
1039 #ifdef DEBUG
1040 fprintf(stderr, "SMB_Delete_Dir failed with errorclass = %i, Error Code = %i\n",
1041 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
1042 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
1043 #endif
1044
1045 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
1046 RFCNB_Free_Pkt(pkt);
1047 SMBlib_errno = SMBlibE_Remote;
1048 return(SMBlibE_BAD); /* Should clean up ... */
1049
1050 }
1051
1052 #ifdef DEBUG
1053 fprintf(stderr, "Directory %s deleted successfully.\n", dir_name);
1054 #endif DEBUG
1055
1056 RFCNB_Free_Pkt(pkt);
1057
1058 return(0);
1059 }
1060
1061 /* Check for the existence of the directory in dir_name */
1062
1063 int SMB_Check_Dir(SMB_Tree_Handle tree, char *dir_name)
1064
1065 {
1066 struct RFCNB_Pkt *pkt;
1067 int pkt_len, param_len;
1068 char *p;
1069
1070 param_len = strlen(dir_name) + 2; /* + null and + asciiID */
1071 pkt_len = SMB_checkdir_len + param_len;
1072
1073 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
1074
1075 if (pkt == NULL) { /* Really should do some error handling */
1076
1077 SMBlib_errno = SMBlibE_NoSpace;
1078 return(SMBlibE_BAD);
1079
1080 }
1081
1082 /* Now plug in the bits we need */
1083
1084 memset(SMB_Hdr(pkt), 0, SMB_checkdir_len);
1085 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
1086 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBchkpth;
1087 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
1088 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
1089 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
1090 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
1091 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;
1092
1093 SSVAL(SMB_Hdr(pkt), SMB_checkdir_bcc_offset, param_len);
1094
1095 /* Now plug in the file name ... */
1096
1097 p = (char *)(SMB_Hdr(pkt) + SMB_checkdir_buf_offset);
1098 *p = SMBasciiID;
1099 strcpy(p+1, dir_name);
1100 p = p + strlen(dir_name);
1101 *(p+1) = 0; /* plug in a null ... */
1102
1103 /* Now send the packet and get the response ... */
1104
1105 if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
1106
1107 #ifdef DEBUG
1108 fprintf(stderr, "Error sending Check Dir Path request\n");
1109 #endif
1110
1111 RFCNB_Free_Pkt(pkt);
1112 SMBlib_errno = -SMBlibE_SendFailed;
1113 return(SMBlibE_BAD);
1114
1115 }
1116
1117 /* Now get the response ... */
1118
1119 if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
1120
1121 #ifdef DEBUG
1122 fprintf(stderr, "Error receiving response to Check Dir request\n");
1123 #endif
1124
1125 RFCNB_Free_Pkt(pkt);
1126 SMBlib_errno = -SMBlibE_RecvFailed;
1127 return(SMBlibE_BAD);
1128
1129 }
1130
1131 /* Now parse the response and pass back any error ... */
1132
1133 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
1134
1135 #ifdef DEBUG
1136 fprintf(stderr, "SMB_Check_Dir failed with errorclass = %i, Error Code = %i\n",
1137 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
1138 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
1139 #endif
1140
1141 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
1142 RFCNB_Free_Pkt(pkt);
1143 SMBlib_errno = SMBlibE_Remote;
1144 return(SMBlibE_BAD); /* Should clean up ... */
1145
1146 }
1147
1148 #ifdef DEBUG
1149 fprintf(stderr, "Directory %s checked successfully.\n", dir_name);
1150 #endif DEBUG
1151
1152 RFCNB_Free_Pkt(pkt);
1153
1154 return(0);
1155 }
1156
1157 /* Search directory for the files listed ... Relative to the TID in the */
1158 /* Con Handle. Return number of Dir Ents returned as the result. */
1159
1160 int SMB_Search(SMB_Tree_Handle tree,
1161 char *dir_name,
1162 WORD search,
1163 SMB_CP_dirent *dirents,
1164 int direntc,
1165 char *resumekey,
1166 int resumekey_len)
1167
1168 {
1169 struct RFCNB_Pkt *pkt, *recv_pkt;
1170 int pkt_len, param_len, recv_param_len, recv_pkt_len, ret_count, i;
1171 char *p;
1172
1173 param_len = strlen(dir_name) + 2 + resumekey_len + 3; /* You have to know */
1174 pkt_len = SMB_search_len + param_len;
1175
1176 recv_param_len = direntc * SMB_searchr_dirent_len + 3;
1177 recv_pkt_len = SMB_searchr_len + recv_param_len;
1178
1179 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
1180
1181 if (pkt == NULL) { /* Really should do some error handling */
1182
1183 SMBlib_errno = SMBlibE_NoSpace;
1184 return(SMBlibE_BAD);
1185
1186 }
1187
1188 recv_pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(recv_pkt_len);
1189
1190 if (recv_pkt == NULL) { /* Really should do some error handling */
1191
1192 RFCNB_Free_Pkt(pkt);
1193 SMBlib_errno = SMBlibE_NoSpace;
1194 return(SMBlibE_BAD);
1195
1196 }
1197
1198
1199 /* Now plug in the bits we need */
1200
1201 memset(SMB_Hdr(pkt), 0, SMB_search_len);
1202 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
1203 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsearch;
1204 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
1205 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
1206 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
1207 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
1208
1209 /* Tell server we known about non-dos names and extended attibutes */
1210
1211 SSVAL(SMB_Hdr(pkt), SMB_hdr_flg2_offset,
1212 (SMB_FLG2_NON_DOS | SMB_FLG2_EXT_ATR));
1213
1214 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 2;
1215
1216 SSVAL(SMB_Hdr(pkt), SMB_search_mdc_offset, direntc); /* How many we want */
1217 SSVAL(SMB_Hdr(pkt), SMB_search_atr_offset, search);
1218 SSVAL(SMB_Hdr(pkt), SMB_search_bcc_offset, param_len);
1219
1220 /* Now plug in the file name ... */
1221
1222 p = (char *)(SMB_Hdr(pkt) + SMB_search_buf_offset);
1223 *p = SMBasciiID;
1224 strcpy(p+1, dir_name);
1225 p = p + strlen(dir_name) + 2; /* Skip the null */
1226
1227
1228
1229 *p = SMBvariableblockID;
1230 p = p + 1;
1231
1232 /* And now the resume key */
1233
1234 SSVAL(p, 0, resumekey_len);
1235
1236 p = p + 2;
1237
1238 bcopy(resumekey, p, resumekey_len);
1239
1240 /* Now send the packet and get the response ... */
1241
1242 if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
1243
1244 #ifdef DEBUG
1245 fprintf(stderr, "Error sending search request\n");
1246 #endif
1247
1248 RFCNB_Free_Pkt(pkt);
1249 RFCNB_Free_Pkt(recv_pkt);
1250 SMBlib_errno = -SMBlibE_SendFailed;
1251 return(SMBlibE_BAD);
1252
1253 }
1254
1255 /* Now get the response ... */
1256
1257 if (RFCNB_Recv(tree -> con -> Trans_Connect, recv_pkt, recv_pkt_len) < 0) {
1258
1259 #ifdef DEBUG
1260 fprintf(stderr, "Error receiving response to Check Dir request\n");
1261 #endif
1262
1263 RFCNB_Free_Pkt(pkt);
1264 RFCNB_Free_Pkt(recv_pkt);
1265 SMBlib_errno = -SMBlibE_RecvFailed;
1266 return(SMBlibE_BAD);
1267
1268 }
1269
1270 /* Now parse the response and pass back any error ... */
1271
1272 if (CVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
1273
1274 #ifdef DEBUG
1275 fprintf(stderr, "SMB_Check_Dir failed with errorclass = %i, Error Code = %i\n",
1276 CVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset),
1277 SVAL(SMB_Hdr(recv_pkt), SMB_hdr_err_offset));
1278 #endif
1279
1280 SMBlib_SMB_Error = IVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset);
1281 RFCNB_Free_Pkt(pkt);
1282 RFCNB_Free_Pkt(recv_pkt);
1283 SMBlib_errno = SMBlibE_Remote;
1284 return(SMBlibE_BAD); /* Should clean up ... */
1285
1286 }
1287
1288 /* Now copy the results into the user's structure */
1289
1290 ret_count = SVAL(SMB_Hdr(recv_pkt), SMB_searchr_dec_offset);
1291
1292 p = SMB_Hdr(recv_pkt) + SMB_searchr_buf_offset + 3;
1293
1294 /* Hmmm, should check that we have the right number of bytes ... */
1295
1296 for (i = 0; i < ret_count; i++) {
1297
1298 bcopy(p, dirents[i].resume_key, 21);
1299
1300 p = p + 21;
1301
1302 dirents[i].file_attributes = (unsigned char)*p;
1303
1304 p = p + 1;
1305
1306 dirents[i].date_time = IVAL(p, 0); /* Should this be IVAL? */
1307
1308 p = p + 4;
1309
1310 dirents[i].size = IVAL(p, 0);
1311
1312 p = p + 4;
1313
1314 bcopy(p, dirents[i].filename, 13); /* Copy in file name */
1315
1316 p = p + 13;
1317
1318 }
1319
1320 return(ret_count);
1321
1322 }