]> git.ipfire.org Git - thirdparty/squid.git/blame - lib/smblib/file.c
SourceFormat Enforcement
[thirdparty/squid.git] / lib / smblib / file.c
CommitLineData
f7f3304a 1#include "squid.h"
7c16470c
AJ
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
0ab648c9 27#include "rfcnb/rfcnb.h"
602d9612 28#include "smblib/smblib-priv.h"
7c16470c 29
0ab648c9
AJ
30#if HAVE_STRING_H
31#include <string.h>
32#endif
7c16470c
AJ
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
37SMB_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
0ab648c9 89 memset(SMB_Hdr(pkt), 0, SMB_open_len);
7c16470c
AJ
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
185int 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
0ab648c9 213 memset(SMB_Hdr(pkt), 0, SMB_clos_len);
7c16470c
AJ
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
290int 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
0ab648c9 342 memset(SMB_Hdr(snd_pkt), 0, SMB_read_len);
7c16470c
AJ
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
439off_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
7c16470c
AJ
471/* Write numbytes from data to the file pointed to by the File_Handle at */
472/* the offset in the File_Handle. */
473
474int SMB_Write(SMB_File *File_Handle, char *data, int numbytes)
475
476{
477 int tot_written = 0;
478 struct RFCNB_Pkt *pkt, *data_ptr;
479 int pkt_len, i, this_write, max_write_data, bytes_left = numbytes;
480
481 /* We loop around, writing the data, accumulating what was written */
482 /* We build an SMB packet, where the data is pointed to by a fragment */
483 /* tagged onto the end ... */
484
485 data_ptr = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(0);
486 if (data_ptr == NULL) {
487
488 SMBlib_errno = SMBlibE_NoSpace;
489 return(SMBlibE_BAD);
490
491 }
492
493 pkt_len = SMB_write_len + 3; /* + 3 for the datablockID and blklen */
494
495 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
496
497 if (pkt == NULL) {
498
499 RFCNB_Free_Pkt(data_ptr);
500 SMBlib_errno = SMBlibE_NoSpace;
501 return(SMBlibE_BAD);
502
503 }
504
505 /* Now init the things that will be the same across the possibly multiple
506 packets to write this data. */
507
0ab648c9 508 memset(SMB_Hdr(pkt), 0, SMB_write_len);
7c16470c
AJ
509 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
510 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBwrite;
511 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, File_Handle -> tree -> con -> pid);
512 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, File_Handle -> tree -> tid);
513 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, File_Handle -> tree -> con -> mid);
514 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, File_Handle -> tree -> con -> uid);
515 SSVAL(SMB_Hdr(pkt), SMB_write_fid_offset, File_Handle -> fid);
516
517 /* We will program this as send/response for the moment, but if we could
518 only send the second block before getting the first, we could speed
519 things up a bit ... */
520
521 max_write_data = (File_Handle -> tree -> mbs) - pkt_len;
522
523 /* the 3 is for the data block id and length that preceeds the data */
524
525 while (bytes_left > 0) {
526
527 /* bytes to write? */
528
529 this_write = (bytes_left > max_write_data?max_write_data:bytes_left);
530
531 data_ptr -> next = NULL;
532 data_ptr -> len = this_write;
533 data_ptr -> data = data + tot_written;
534
535 pkt -> next = data_ptr; /* link the data on the end */
536
537 SSVAL(SMB_Hdr(pkt), SMB_hdr_flg_offset, 0);
538 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 5;
539 SSVAL(SMB_Hdr(pkt), SMB_write_fid_offset, File_Handle -> fid);
540 SSVAL(SMB_Hdr(pkt), SMB_write_cnt_offset, this_write);
541 SIVAL(SMB_Hdr(pkt), SMB_write_ofs_offset, File_Handle -> fileloc);
542 SSVAL(SMB_Hdr(pkt), SMB_write_clf_offset, 0);
543 SSVAL(SMB_Hdr(pkt), SMB_write_bcc_offset, (this_write + 3));
544
545 *(SMB_Hdr(pkt) + SMB_write_buf_offset) = SMBdatablockID;
546 SSVAL(SMB_Hdr(pkt), SMB_write_buf_offset + 1, this_write);
547
548 /* Now send the packet and wait for a response */
549
550 if (RFCNB_Send(File_Handle -> tree -> con -> Trans_Connect, pkt, pkt_len + this_write) < 0) {
551
552#ifdef DEBUG
553 fprintf(stderr, "Error sending write request\n");
554#endif
555
556 data_ptr -> next = NULL;
557 data_ptr -> len = 0;
558 RFCNB_Free_Pkt(pkt);
559 SMBlib_errno = -SMBlibE_SendFailed;
560 return(-1);
561
562 }
563
564 /* Now get the response ... */
565
566 if (RFCNB_Recv(File_Handle -> tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
567
568#ifdef DEBUG
569 fprintf(stderr, "Error receiving response to write\n");
570#endif
571
572 data_ptr -> next = NULL;
573 data_ptr -> len = 0;
574 RFCNB_Free_Pkt(pkt);
575 SMBlib_errno = -SMBlibE_RecvFailed;
576 return(-1);
577
578 }
579
580 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
581
582#ifdef DEBUG
583 fprintf(stderr, "SMB_Write failed with errorclass = %i, Error Code = %i\n",
584 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
585 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
586#endif
587
588 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
589 data_ptr -> data = NULL;
590 data_ptr -> len = 0;
591 RFCNB_Free_Pkt(pkt);
592 SMBlib_errno = SMBlibE_Remote;
593 return(SMBlibE_BAD);
594
595 }
596
597 /* Ok, that worked, so update some things here ... */
598
599 tot_written = tot_written + this_write;
600 bytes_left = bytes_left - this_write;
601
602 /* Assume that it is ok to update this now, but what about only part */
603 /* of the write succeeding? */
604
605 File_Handle -> fileloc = File_Handle -> fileloc + this_write;
606
607#ifdef DEBUG
608 fprintf(stderr, "--This_write = %i, bytes_left = %i\n",
609 this_write, bytes_left);
610#endif
611
612 }
613
614 /* Let's get rid of those packet headers we are using ... */
615
616 data_ptr -> data = NULL;
617 pkt -> next = NULL;
618
619 RFCNB_Free_Pkt(pkt);
620
621 return(tot_written);
622
623}
624
625/* Create file on the server with name file_name and attributes search */
626
627SMB_File *SMB_Create(SMB_Tree_Handle Tree_Handle,
628 SMB_File *File_Handle,
629 char *file_name,
630 WORD search)
631
632{
633 struct RFCNB_Pkt *pkt;
634 int pkt_len, param_len;
635 char *p;
636 struct SMB_File_Def *file_tmp;
637
638 /* We allocate a file object and copy some things ... */
639
640 file_tmp = File_Handle;
641
642 if (File_Handle == NULL) {
643
644 if ((file_tmp = (SMB_File *)malloc(sizeof(SMB_File))) == NULL) {
645
646#ifdef DEBUG
647 fprintf(stderr, "Could not allocate file handle space ...");
648#endif
649
650 SMBlib_errno = SMBlibE_NoSpace;
651 return(NULL);
652
653 }
654
655 }
656
657 strncpy(file_tmp -> filename, file_name, sizeof(file_tmp -> filename));
658 file_tmp -> tree = Tree_Handle;
659 file_tmp -> fid = 0xFFFF; /* Is this an invalid FID? */
660
661 param_len = strlen(file_name) + 2; /* 1 for null, 1 for ASCII marker */
662
663 pkt_len = SMB_creat_len + param_len;
664
665 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
666
667 if (pkt == NULL) { /* Really should do some error handling */
668
669 if (File_Handle == NULL)
670 free(file_tmp);
671 SMBlib_errno = SMBlibE_NoSpace;
672 return(NULL);
673
674 }
675
676 /* Now plug in the bits we need */
677
0ab648c9 678 memset(SMB_Hdr(pkt), 0, SMB_creat_len);
7c16470c
AJ
679 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
680 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBcreate;
681 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Tree_Handle -> con -> pid);
682 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, Tree_Handle -> tid);
683 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Tree_Handle -> con -> mid);
684 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Tree_Handle -> con -> uid);
685 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 3;
686
687 SSVAL(SMB_Hdr(pkt), SMB_creat_atr_offset, search);
688 SSVAL(SMB_Hdr(pkt), SMB_creat_tim_offset, 0);
689 SSVAL(SMB_Hdr(pkt), SMB_creat_dat_offset, 0);
690 SSVAL(SMB_Hdr(pkt), SMB_creat_bcc_offset, param_len);
691
692 /* Now plug in the file name ... */
693
694 p = (char *)(SMB_Hdr(pkt) + SMB_creat_buf_offset);
695 *p = SMBasciiID;
696 strcpy(p+1, file_name);
697 p = p + strlen(file_name);
698 *(p+1) = 0; /* plug in a null ... */
699
700 /* Now send the packet and get the response ... */
701
702 if (RFCNB_Send(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) {
703
704#ifdef DEBUG
705 fprintf(stderr, "Error sending Open request\n");
706#endif
707
708 if (File_Handle == NULL)
709 free(file_tmp);
710 RFCNB_Free_Pkt(pkt);
711 SMBlib_errno = -SMBlibE_SendFailed;
712 return(NULL);
713
714 }
715
716 /* Now get the response ... */
717
718#ifdef DEBUG
719 fprintf(stderr, "Pkt_Len for Create resp = %i\n", pkt_len);
720#endif
721
722 if (RFCNB_Recv(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) {
723
724#ifdef DEBUG
725 fprintf(stderr, "Error receiving response to create request\n");
726#endif
727
728 if (File_Handle == NULL)
729 free(file_tmp);
730 RFCNB_Free_Pkt(pkt);
731 SMBlib_errno = -SMBlibE_RecvFailed;
732 return(NULL);
733
734 }
735
736 /* Now parse the response and pass back any error ... */
737
738 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
739
740#ifdef DEBUG
741 fprintf(stderr, "SMB_Create failed with errorclass = %i, Error Code = %i\n",
742 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
743 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
744#endif
745
746 if (File_Handle == NULL)
747 free(file_tmp);
748 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
749 RFCNB_Free_Pkt(pkt);
750 SMBlib_errno = SMBlibE_Remote;
751 return(NULL); /* Should clean up ... */
752
753 }
754
755 file_tmp -> fid = SVAL(SMB_Hdr(pkt), SMB_creatr_fid_offset);
756 file_tmp -> lastmod = 0;
757 file_tmp -> size = 0;
758 file_tmp -> access = SMB_AMODE_OPENRW;
759 file_tmp -> fileloc = 0;
760
761 RFCNB_Free_Pkt(pkt); /* Free up this space */
762
763#ifdef DEBUG
764 fprintf(stderr, "SMB_Create succeeded, FID = %i\n", file_tmp -> fid);
765#endif
766
767 return(file_tmp);
768
769}
770
771/* Delete the file passed in as file_name. */
772
773int SMB_Delete(SMB_Tree_Handle tree, char *file_name, WORD search)
774
775{
776 struct RFCNB_Pkt *pkt;
777 int pkt_len, param_len;
778 char *p;
779
780 param_len = strlen(file_name) + 2;
781 pkt_len = SMB_delet_len + param_len;
782
783 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
784
785 if (pkt == NULL) { /* Really should do some error handling */
786
787 SMBlib_errno = SMBlibE_NoSpace;
788 return(SMBlibE_BAD);
789
790 }
791
792 /* Now plug in the bits we need */
793
0ab648c9 794 memset(SMB_Hdr(pkt), 0, SMB_delet_len);
7c16470c
AJ
795 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
796 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBunlink;
797 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
798 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
799 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
800 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
801 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 1;
802
803 SIVAL(SMB_Hdr(pkt), SMB_delet_sat_offset, search);
804 SSVAL(SMB_Hdr(pkt), SMB_delet_bcc_offset, param_len);
805
806 /* Now plug in the file name ... */
807
808 p = (char *)(SMB_Hdr(pkt) + SMB_delet_buf_offset);
809 *p = SMBasciiID;
810 strcpy(p+1, file_name);
811 p = p + strlen(file_name);
812 *(p+1) = 0; /* plug in a null ... */
813
814 /* Now send the packet and get the response ... */
815
816 if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
817
818#ifdef DEBUG
819 fprintf(stderr, "Error sending Delete request\n");
820#endif
821
822 RFCNB_Free_Pkt(pkt);
823 SMBlib_errno = -SMBlibE_SendFailed;
824 return(SMBlibE_BAD);
825
826 }
827
828 /* Now get the response ... */
829
830 if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
831
832#ifdef DEBUG
833 fprintf(stderr, "Error receiving response to delete request\n");
834#endif
835
836 RFCNB_Free_Pkt(pkt);
837 SMBlib_errno = -SMBlibE_RecvFailed;
838 return(SMBlibE_BAD);
839
840 }
841
842 /* Now parse the response and pass back any error ... */
843
844 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
845
846#ifdef DEBUG
847 fprintf(stderr, "SMB_Delete failed with errorclass = %i, Error Code = %i\n",
848 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
849 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
850#endif
851
852 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
853 RFCNB_Free_Pkt(pkt);
854 SMBlib_errno = SMBlibE_Remote;
855 return(SMBlibE_BAD); /* Should clean up ... */
856
857 }
858
859#ifdef DEBUG
860 fprintf(stderr, "File %s deleted successfully.\n", file_name);
861#endif DEBUG
862
863 RFCNB_Free_Pkt(pkt);
864
865 return(0);
866}
867
868/* Create the directory passed in as dir_name */
869
870int SMB_Create_Dir(SMB_Tree_Handle tree, char *dir_name)
871
872{
873 struct RFCNB_Pkt *pkt;
874 int pkt_len, param_len;
875 char *p;
876
877 param_len = strlen(dir_name) + 2; /* + null and + asciiID */
878 pkt_len = SMB_creatdir_len + param_len;
879
880 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
881
882 if (pkt == NULL) { /* Really should do some error handling */
883
884 SMBlib_errno = SMBlibE_NoSpace;
885 return(SMBlibE_BAD);
886
887 }
888
889 /* Now plug in the bits we need */
890
0ab648c9 891 memset(SMB_Hdr(pkt), 0, SMB_creatdir_len);
7c16470c
AJ
892 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
893 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBmkdir;
894 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
895 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
896 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
897 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
898 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;
899
900 SSVAL(SMB_Hdr(pkt), SMB_creatdir_bcc_offset, param_len);
901
902 /* Now plug in the file name ... */
903
904 p = (char *)(SMB_Hdr(pkt) + SMB_creatdir_buf_offset);
905 *p = SMBasciiID;
906 strcpy(p+1, dir_name);
907 p = p + strlen(dir_name);
908 *(p+1) = 0; /* plug in a null ... */
909
910 /* Now send the packet and get the response ... */
911
912 if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
913
914#ifdef DEBUG
915 fprintf(stderr, "Error sending Create Dir request\n");
916#endif
917
918 RFCNB_Free_Pkt(pkt);
919 SMBlib_errno = -SMBlibE_SendFailed;
920 return(SMBlibE_BAD);
921
922 }
923
924 /* Now get the response ... */
925
926 if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
927
928#ifdef DEBUG
929 fprintf(stderr, "Error receiving response to Create Dir request\n");
930#endif
931
932 RFCNB_Free_Pkt(pkt);
933 SMBlib_errno = -SMBlibE_RecvFailed;
934 return(SMBlibE_BAD);
935
936 }
937
938 /* Now parse the response and pass back any error ... */
939
940 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
941
942#ifdef DEBUG
943 fprintf(stderr, "SMB_Create_Dir failed with errorclass = %i, Error Code = %i\n",
944 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
945 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
946#endif
947
948 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
949 RFCNB_Free_Pkt(pkt);
950 SMBlib_errno = SMBlibE_Remote;
951 return(SMBlibE_BAD); /* Should clean up ... */
952
953 }
954
955#ifdef DEBUG
956 fprintf(stderr, "Directory %s created successfully.\n", dir_name);
957#endif DEBUG
958
959 RFCNB_Free_Pkt(pkt);
960
961 return(0);
962}
963
964/* Delete the directory passed as dir_name, as long as it is empty ... */
965
966int SMB_Delete_Dir(SMB_Tree_Handle tree, char *dir_name)
967
968{
969 struct RFCNB_Pkt *pkt;
970 int pkt_len, param_len;
971 char *p;
972
973 param_len = strlen(dir_name) + 2; /* + null and + asciiID */
974 pkt_len = SMB_deletdir_len + param_len;
975
976 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
977
978 if (pkt == NULL) { /* Really should do some error handling */
979
980 SMBlib_errno = SMBlibE_NoSpace;
981 return(SMBlibE_BAD);
982
983 }
984
985 /* Now plug in the bits we need */
986
0ab648c9 987 memset(SMB_Hdr(pkt), 0, SMB_deletdir_len);
7c16470c
AJ
988 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
989 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBrmdir;
990 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
991 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
992 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
993 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
994 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;
995
996 SSVAL(SMB_Hdr(pkt), SMB_deletdir_bcc_offset, param_len);
997
998 /* Now plug in the file name ... */
999
1000 p = (char *)(SMB_Hdr(pkt) + SMB_deletdir_buf_offset);
1001 *p = SMBasciiID;
1002 strcpy(p+1, dir_name);
1003 p = p + strlen(dir_name);
1004 *(p+1) = 0; /* plug in a null ... */
1005
1006 /* Now send the packet and get the response ... */
1007
1008 if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
1009
1010#ifdef DEBUG
1011 fprintf(stderr, "Error sending Delete Dir request\n");
1012#endif
1013
1014 RFCNB_Free_Pkt(pkt);
1015 SMBlib_errno = -SMBlibE_SendFailed;
1016 return(SMBlibE_BAD);
1017
1018 }
1019
1020 /* Now get the response ... */
1021
1022 if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
1023
1024#ifdef DEBUG
1025 fprintf(stderr, "Error receiving response to Delete Dir request\n");
1026#endif
1027
1028 RFCNB_Free_Pkt(pkt);
1029 SMBlib_errno = -SMBlibE_RecvFailed;
1030 return(SMBlibE_BAD);
1031
1032 }
1033
1034 /* Now parse the response and pass back any error ... */
1035
1036 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
1037
1038#ifdef DEBUG
1039 fprintf(stderr, "SMB_Delete_Dir failed with errorclass = %i, Error Code = %i\n",
1040 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
1041 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
1042#endif
1043
1044 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
1045 RFCNB_Free_Pkt(pkt);
1046 SMBlib_errno = SMBlibE_Remote;
1047 return(SMBlibE_BAD); /* Should clean up ... */
1048
1049 }
1050
1051#ifdef DEBUG
1052 fprintf(stderr, "Directory %s deleted successfully.\n", dir_name);
1053#endif DEBUG
1054
1055 RFCNB_Free_Pkt(pkt);
1056
1057 return(0);
1058}
1059
1060/* Check for the existence of the directory in dir_name */
1061
1062int SMB_Check_Dir(SMB_Tree_Handle tree, char *dir_name)
1063
1064{
1065 struct RFCNB_Pkt *pkt;
1066 int pkt_len, param_len;
1067 char *p;
1068
1069 param_len = strlen(dir_name) + 2; /* + null and + asciiID */
1070 pkt_len = SMB_checkdir_len + param_len;
1071
1072 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
1073
1074 if (pkt == NULL) { /* Really should do some error handling */
1075
1076 SMBlib_errno = SMBlibE_NoSpace;
1077 return(SMBlibE_BAD);
1078
1079 }
1080
1081 /* Now plug in the bits we need */
1082
0ab648c9 1083 memset(SMB_Hdr(pkt), 0, SMB_checkdir_len);
7c16470c
AJ
1084 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
1085 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBchkpth;
1086 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
1087 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
1088 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
1089 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
1090 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;
1091
1092 SSVAL(SMB_Hdr(pkt), SMB_checkdir_bcc_offset, param_len);
1093
1094 /* Now plug in the file name ... */
1095
1096 p = (char *)(SMB_Hdr(pkt) + SMB_checkdir_buf_offset);
1097 *p = SMBasciiID;
1098 strcpy(p+1, dir_name);
1099 p = p + strlen(dir_name);
1100 *(p+1) = 0; /* plug in a null ... */
1101
1102 /* Now send the packet and get the response ... */
1103
1104 if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
1105
1106#ifdef DEBUG
1107 fprintf(stderr, "Error sending Check Dir Path request\n");
1108#endif
1109
1110 RFCNB_Free_Pkt(pkt);
1111 SMBlib_errno = -SMBlibE_SendFailed;
1112 return(SMBlibE_BAD);
1113
1114 }
1115
1116 /* Now get the response ... */
1117
1118 if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
1119
1120#ifdef DEBUG
1121 fprintf(stderr, "Error receiving response to Check Dir request\n");
1122#endif
1123
1124 RFCNB_Free_Pkt(pkt);
1125 SMBlib_errno = -SMBlibE_RecvFailed;
1126 return(SMBlibE_BAD);
1127
1128 }
1129
1130 /* Now parse the response and pass back any error ... */
1131
1132 if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
1133
1134#ifdef DEBUG
1135 fprintf(stderr, "SMB_Check_Dir failed with errorclass = %i, Error Code = %i\n",
1136 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
1137 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
1138#endif
1139
1140 SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
1141 RFCNB_Free_Pkt(pkt);
1142 SMBlib_errno = SMBlibE_Remote;
1143 return(SMBlibE_BAD); /* Should clean up ... */
1144
1145 }
1146
1147#ifdef DEBUG
1148 fprintf(stderr, "Directory %s checked successfully.\n", dir_name);
1149#endif DEBUG
1150
1151 RFCNB_Free_Pkt(pkt);
1152
1153 return(0);
1154}
1155
1156/* Search directory for the files listed ... Relative to the TID in the */
1157/* Con Handle. Return number of Dir Ents returned as the result. */
1158
1159int SMB_Search(SMB_Tree_Handle tree,
1160 char *dir_name,
1161 WORD search,
1162 SMB_CP_dirent *dirents,
1163 int direntc,
1164 char *resumekey,
1165 int resumekey_len)
1166
1167{
1168 struct RFCNB_Pkt *pkt, *recv_pkt;
1169 int pkt_len, param_len, recv_param_len, recv_pkt_len, ret_count, i;
1170 char *p;
1171
1172 param_len = strlen(dir_name) + 2 + resumekey_len + 3; /* You have to know */
1173 pkt_len = SMB_search_len + param_len;
1174
1175 recv_param_len = direntc * SMB_searchr_dirent_len + 3;
1176 recv_pkt_len = SMB_searchr_len + recv_param_len;
1177
1178 pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len);
1179
1180 if (pkt == NULL) { /* Really should do some error handling */
1181
1182 SMBlib_errno = SMBlibE_NoSpace;
1183 return(SMBlibE_BAD);
1184
1185 }
1186
1187 recv_pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(recv_pkt_len);
1188
1189 if (recv_pkt == NULL) { /* Really should do some error handling */
1190
1191 RFCNB_Free_Pkt(pkt);
1192 SMBlib_errno = SMBlibE_NoSpace;
1193 return(SMBlibE_BAD);
1194
1195 }
1196
7c16470c
AJ
1197 /* Now plug in the bits we need */
1198
0ab648c9 1199 memset(SMB_Hdr(pkt), 0, SMB_search_len);
7c16470c
AJ
1200 SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
1201 *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsearch;
1202 SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid);
1203 SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid);
1204 SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid);
1205 SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid);
1206
1207 /* Tell server we known about non-dos names and extended attibutes */
1208
1209 SSVAL(SMB_Hdr(pkt), SMB_hdr_flg2_offset,
1210 (SMB_FLG2_NON_DOS | SMB_FLG2_EXT_ATR));
1211
1212 *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 2;
1213
1214 SSVAL(SMB_Hdr(pkt), SMB_search_mdc_offset, direntc); /* How many we want */
1215 SSVAL(SMB_Hdr(pkt), SMB_search_atr_offset, search);
1216 SSVAL(SMB_Hdr(pkt), SMB_search_bcc_offset, param_len);
1217
1218 /* Now plug in the file name ... */
1219
1220 p = (char *)(SMB_Hdr(pkt) + SMB_search_buf_offset);
1221 *p = SMBasciiID;
1222 strcpy(p+1, dir_name);
1223 p = p + strlen(dir_name) + 2; /* Skip the null */
1224
7c16470c
AJ
1225 *p = SMBvariableblockID;
1226 p = p + 1;
1227
1228 /* And now the resume key */
1229
1230 SSVAL(p, 0, resumekey_len);
1231
1232 p = p + 2;
1233
1234 bcopy(resumekey, p, resumekey_len);
1235
1236 /* Now send the packet and get the response ... */
1237
1238 if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) {
1239
1240#ifdef DEBUG
1241 fprintf(stderr, "Error sending search request\n");
1242#endif
1243
1244 RFCNB_Free_Pkt(pkt);
1245 RFCNB_Free_Pkt(recv_pkt);
1246 SMBlib_errno = -SMBlibE_SendFailed;
1247 return(SMBlibE_BAD);
1248
1249 }
1250
1251 /* Now get the response ... */
1252
1253 if (RFCNB_Recv(tree -> con -> Trans_Connect, recv_pkt, recv_pkt_len) < 0) {
1254
1255#ifdef DEBUG
1256 fprintf(stderr, "Error receiving response to Check Dir request\n");
1257#endif
1258
1259 RFCNB_Free_Pkt(pkt);
1260 RFCNB_Free_Pkt(recv_pkt);
1261 SMBlib_errno = -SMBlibE_RecvFailed;
1262 return(SMBlibE_BAD);
1263
1264 }
1265
1266 /* Now parse the response and pass back any error ... */
1267
1268 if (CVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */
1269
1270#ifdef DEBUG
1271 fprintf(stderr, "SMB_Check_Dir failed with errorclass = %i, Error Code = %i\n",
1272 CVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset),
1273 SVAL(SMB_Hdr(recv_pkt), SMB_hdr_err_offset));
1274#endif
1275
1276 SMBlib_SMB_Error = IVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset);
1277 RFCNB_Free_Pkt(pkt);
1278 RFCNB_Free_Pkt(recv_pkt);
1279 SMBlib_errno = SMBlibE_Remote;
1280 return(SMBlibE_BAD); /* Should clean up ... */
1281
1282 }
1283
1284 /* Now copy the results into the user's structure */
1285
1286 ret_count = SVAL(SMB_Hdr(recv_pkt), SMB_searchr_dec_offset);
1287
1288 p = SMB_Hdr(recv_pkt) + SMB_searchr_buf_offset + 3;
1289
1290 /* Hmmm, should check that we have the right number of bytes ... */
1291
1292 for (i = 0; i < ret_count; i++) {
1293
1294 bcopy(p, dirents[i].resume_key, 21);
1295
1296 p = p + 21;
1297
1298 dirents[i].file_attributes = (unsigned char)*p;
1299
1300 p = p + 1;
1301
1302 dirents[i].date_time = IVAL(p, 0); /* Should this be IVAL? */
1303
1304 p = p + 4;
1305
1306 dirents[i].size = IVAL(p, 0);
1307
1308 p = p + 4;
1309
1310 bcopy(p, dirents[i].filename, 13); /* Copy in file name */
1311
1312 p = p + 13;
1313
1314 }
1315
1316 return(ret_count);
1317
1318}