This source file includes following definitions.
- min
- assert_server_locked
- ncp_add_byte
- ncp_add_word
- ncp_add_dword
- ncp_add_mem
- ncp_add_mem_fromfs
- ncp_add_pstring
- ncp_init_request
- ncp_init_request_s
- ncp_reply_data
- ncp_reply_byte
- ncp_reply_word
- ncp_reply_dword
- ncp_negotiate_buffersize
- ncp_get_volume_info_with_number
- ncp_get_volume_number
- ncp_close_file
- ncp_add_handle_path
- ncp_extract_file_info
- ncp_obtain_info
- ncp_lookup_volume
- ncp_modify_file_or_subdir_dos_info
- ncp_del_file_or_subdir
- ConvertToNWfromDWORD
- ncp_open_create_file_or_subdir
- ncp_initialize_search
- ncp_search_for_file_or_subdir
- ncp_ren_or_mov_file_or_subdir
- ncp_read
- ncp_write
1
2
3
4
5
6
7
8 #include "ncplib_kernel.h"
9
10 typedef __u8 byte;
11 typedef __u16 word;
12 typedef __u32 dword;
13
14 static inline int min(int a, int b)
15 {
16 return a<b ? a : b;
17 }
18
19 static void
20 assert_server_locked(struct ncp_server *server)
21 {
22 if (server->lock == 0)
23 {
24 DPRINTK("ncpfs: server not locked!\n");
25 }
26 }
27
28 static void
29 ncp_add_byte(struct ncp_server *server, byte x)
30 {
31 assert_server_locked(server);
32 *(byte *)(&(server->packet[server->current_size])) = x;
33 server->current_size += 1;
34 return;
35 }
36
37 static void
38 ncp_add_word(struct ncp_server *server, word x)
39 {
40 assert_server_locked(server);
41 *(word *)(&(server->packet[server->current_size])) = x;
42 server->current_size += 2;
43 return;
44 }
45
46 static void
47 ncp_add_dword(struct ncp_server *server, dword x)
48 {
49 assert_server_locked(server);
50 *(dword *)(&(server->packet[server->current_size])) = x;
51 server->current_size += 4;
52 return;
53 }
54
55 static void
56 ncp_add_mem(struct ncp_server *server, const void *source, int size)
57 {
58 assert_server_locked(server);
59 memcpy(&(server->packet[server->current_size]), source, size);
60 server->current_size += size;
61 return;
62 }
63
64 static void
65 ncp_add_mem_fromfs(struct ncp_server *server, const char *source, int size)
66 {
67 assert_server_locked(server);
68 memcpy_fromfs(&(server->packet[server->current_size]), source, size);
69 server->current_size += size;
70 return;
71 }
72
73 static void
74 ncp_add_pstring(struct ncp_server *server, const char *s)
75 {
76 int len = strlen(s);
77 assert_server_locked(server);
78 if (len > 255)
79 {
80 DPRINTK("ncpfs: string too long: %s\n", s);
81 len = 255;
82 }
83 ncp_add_byte(server, len);
84 ncp_add_mem(server, s, len);
85 return;
86 }
87
88 static void
89 ncp_init_request(struct ncp_server *server)
90 {
91 ncp_lock_server(server);
92
93 server->current_size = sizeof(struct ncp_request_header);
94 server->has_subfunction = 0;
95 }
96
97 static void
98 ncp_init_request_s(struct ncp_server *server, int subfunction)
99 {
100 ncp_init_request(server);
101 ncp_add_word(server, 0);
102
103 ncp_add_byte(server, subfunction);
104
105 server->has_subfunction = 1;
106 }
107
108 static char *
109 ncp_reply_data(struct ncp_server *server, int offset)
110 {
111 return &(server->packet[sizeof(struct ncp_reply_header) + offset]);
112 }
113
114 static byte
115 ncp_reply_byte(struct ncp_server *server, int offset)
116 {
117 return *(byte *)(ncp_reply_data(server, offset));
118 }
119
120 static word
121 ncp_reply_word(struct ncp_server *server, int offset)
122 {
123 return *(word *)(ncp_reply_data(server, offset));
124 }
125
126 static dword
127 ncp_reply_dword(struct ncp_server *server, int offset)
128 {
129 return *(dword *)(ncp_reply_data(server, offset));
130 }
131
132 int
133 ncp_negotiate_buffersize(struct ncp_server *server,
134 int size, int *target)
135 {
136 int result;
137
138 ncp_init_request(server);
139 ncp_add_word(server, htons(size));
140
141 if ((result = ncp_request(server, 33)) != 0)
142 {
143 ncp_unlock_server(server);
144 return result;
145 }
146
147 *target =min(ntohs(ncp_reply_word(server, 0)), size);
148
149 ncp_unlock_server(server);
150 return 0;
151 }
152
153 int
154 ncp_get_volume_info_with_number(struct ncp_server *server, int n,
155 struct ncp_volume_info *target)
156 {
157 int result;
158 int len;
159
160 ncp_init_request_s(server, 44);
161 ncp_add_byte(server, n);
162
163 if ((result = ncp_request(server, 22)) != 0)
164 {
165 ncp_unlock_server(server);
166 return result;
167 }
168
169 target->total_blocks = ncp_reply_dword(server, 0);
170 target->free_blocks = ncp_reply_dword(server, 4);
171 target->purgeable_blocks = ncp_reply_dword(server, 8);
172 target->not_yet_purgeable_blocks = ncp_reply_dword(server, 12);
173 target->total_dir_entries = ncp_reply_dword(server, 16);
174 target->available_dir_entries = ncp_reply_dword(server, 20);
175 target->sectors_per_block = ncp_reply_byte(server, 28);
176
177 memset(&(target->volume_name), 0, sizeof(target->volume_name));
178
179 len = ncp_reply_byte(server, 29);
180 if (len > NCP_VOLNAME_LEN)
181 {
182 DPRINTK("ncpfs: volume name too long: %d\n", len);
183 ncp_unlock_server(server);
184 return -EIO;
185 }
186
187 memcpy(&(target->volume_name), ncp_reply_data(server, 30), len);
188 ncp_unlock_server(server);
189 return 0;
190 }
191
192 int
193 ncp_get_volume_number(struct ncp_server *server, const char *name, int *target)
194 {
195 int result;
196
197 ncp_init_request_s(server, 5);
198 ncp_add_pstring(server, name);
199
200 if ((result = ncp_request(server, 22)) != 0)
201 {
202 ncp_unlock_server(server);
203 return result;
204 }
205
206 *target = ncp_reply_byte(server, 0);
207 ncp_unlock_server(server);
208 return 0;
209 }
210
211 int
212 ncp_close_file(struct ncp_server *server, const char *file_id)
213 {
214 int result;
215
216 ncp_init_request(server);
217 ncp_add_byte(server, 0);
218 ncp_add_mem(server, file_id, 6);
219
220 if ((result = ncp_request(server, 66)) != 0)
221 {
222 ncp_unlock_server(server);
223 return result;
224 }
225
226 ncp_unlock_server(server);
227 return 0;
228 }
229
230 static void
231 ncp_add_handle_path(struct ncp_server *server,
232 __u8 vol_num,
233 __u32 dir_base, int have_dir_base,
234 char *path)
235 {
236 ncp_add_byte(server, vol_num);
237 ncp_add_dword(server, dir_base);
238 if (have_dir_base != 0)
239 {
240 ncp_add_byte(server, 1);
241 }
242 else
243 {
244 ncp_add_byte(server, 0xff);
245 }
246 if (path != NULL)
247 {
248 ncp_add_byte(server, 1);
249 ncp_add_pstring(server, path);
250 }
251 else
252 {
253 ncp_add_byte(server, 0);
254 }
255 }
256
257 static void
258 ncp_extract_file_info(void *structure, struct nw_info_struct *target)
259 {
260 __u8 *name_len;
261 const int info_struct_size = sizeof(struct nw_info_struct) - 257;
262
263 memcpy(target, structure, info_struct_size);
264 name_len = structure + info_struct_size;
265 target->nameLen = *name_len;
266 strncpy(target->entryName, name_len+1, *name_len);
267 target->entryName[*name_len] = '\0';
268 return;
269 }
270
271 int
272 ncp_obtain_info(struct ncp_server *server,
273 __u8 vol_num, __u32 dir_base,
274 char *path,
275 struct nw_info_struct *target)
276 {
277 int result;
278
279 if (target == NULL)
280 {
281 return -EINVAL;
282 }
283
284 ncp_init_request(server);
285 ncp_add_byte(server, 6);
286 ncp_add_byte(server, 0);
287 ncp_add_byte(server, 0);
288 ncp_add_word(server, 0xff);
289 ncp_add_dword(server, RIM_ALL);
290 ncp_add_handle_path(server, vol_num, dir_base, 1, path);
291
292 if ((result = ncp_request(server, 87)) != 0)
293 {
294 ncp_unlock_server(server);
295 return result;
296 }
297
298 ncp_extract_file_info(ncp_reply_data(server, 0), target);
299 ncp_unlock_server(server);
300 return 0;
301 }
302
303 int
304 ncp_lookup_volume(struct ncp_server *server,
305 char *volname,
306 struct nw_info_struct *target)
307 {
308 int result;
309 __u8 vol_num;
310 __u32 dir_base;
311
312 DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname);
313
314 ncp_init_request(server);
315 ncp_add_byte(server, 22);
316 ncp_add_byte(server, 0);
317 ncp_add_byte(server, 0);
318 ncp_add_byte(server, 0);
319 ncp_add_byte(server, 0);
320
321 ncp_add_byte(server, 0);
322 ncp_add_dword(server, 0);
323 ncp_add_byte(server, 0xff);
324 ncp_add_byte(server, 1);
325 ncp_add_pstring(server, volname);
326
327 if ((result = ncp_request(server, 87)) != 0)
328 {
329 ncp_unlock_server(server);
330 return result;
331 }
332
333 dir_base = ncp_reply_dword(server, 4);
334 vol_num = ncp_reply_byte(server, 8);
335 ncp_unlock_server(server);
336
337 if ((result = ncp_obtain_info(server, vol_num, dir_base, NULL,
338 target)) != 0)
339 {
340 return result;
341 }
342
343 DPRINTK("ncp_lookup_volume: attribs = %X\n", target->attributes);
344
345 target->nameLen = strlen(volname);
346 strcpy(target->entryName, volname);
347 return 0;
348 }
349
350 int
351 ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
352 struct nw_info_struct *file,
353 __u32 info_mask,
354 struct nw_modify_dos_info *info)
355 {
356 int result;
357
358 ncp_init_request(server);
359 ncp_add_byte(server, 7);
360 ncp_add_byte(server, 0);
361 ncp_add_byte(server, 0);
362 ncp_add_word(server, 0x8006);
363
364 ncp_add_dword(server, info_mask);
365 ncp_add_mem(server, info, sizeof(*info));
366 ncp_add_handle_path(server, file->volNumber,
367 file->DosDirNum, 1, NULL);
368
369 if ((result = ncp_request(server, 87)) != 0)
370 {
371 ncp_unlock_server(server);
372 return result;
373 }
374
375 ncp_unlock_server(server);
376 return 0;
377 }
378
379 int
380 ncp_del_file_or_subdir(struct ncp_server *server,
381 struct nw_info_struct *dir, char *name)
382 {
383 int result;
384
385 ncp_init_request(server);
386 ncp_add_byte(server, 8);
387 ncp_add_byte(server, 0);
388 ncp_add_byte(server, 0);
389 ncp_add_word(server, 0x8006);
390 ncp_add_handle_path(server, dir->volNumber,
391 dir->DosDirNum, 1, name);
392
393 if ((result = ncp_request(server, 87)) != 0)
394 {
395 ncp_unlock_server(server);
396 return result;
397 }
398
399 ncp_unlock_server(server);
400 return 0;
401 }
402
403 static inline void
404 ConvertToNWfromDWORD ( __u32 sfd , __u8 ret[6] )
405 {
406 __u16 *dest = (__u16 *) ret;
407 memcpy(&(dest[1]), &sfd, 4);
408 dest[0] = dest[1] + 1;
409 return;
410 }
411
412
413
414 int
415 ncp_open_create_file_or_subdir(struct ncp_server *server,
416 struct nw_info_struct *dir, char *name,
417 int open_create_mode,
418 __u32 create_attributes,
419 int desired_acc_rights,
420 struct nw_file_info *target)
421 {
422 int result;
423 __u16 search_attribs = 0x0006;
424
425 if ((create_attributes & aDIR) != 0)
426 {
427 search_attribs |= 0x8000;
428 }
429
430 ncp_init_request(server);
431 ncp_add_byte(server, 1);
432 ncp_add_byte(server, 0);
433 ncp_add_byte(server, open_create_mode);
434 ncp_add_word(server, search_attribs);
435 ncp_add_dword(server, RIM_ALL);
436 ncp_add_dword(server, create_attributes);
437
438
439 ncp_add_word(server, desired_acc_rights);
440
441 if (dir != NULL)
442 {
443 ncp_add_handle_path(server, dir->volNumber,
444 dir->DosDirNum, 1, name);
445 }
446 else
447 {
448 ncp_add_handle_path(server,
449 target->i.volNumber, target->i.DosDirNum,
450 1, NULL);
451 }
452
453 if ((result = ncp_request(server, 87)) != 0)
454 {
455 ncp_unlock_server(server);
456 return result;
457 }
458
459 target->opened = 1;
460 target->server_file_handle = ncp_reply_dword(server, 0);
461 target->open_create_action = ncp_reply_byte(server, 4);
462
463 if (dir != NULL)
464 {
465
466 ncp_extract_file_info(ncp_reply_data(server, 5), &(target->i));
467 }
468
469 ConvertToNWfromDWORD(target->server_file_handle, target->file_handle);
470
471 ncp_unlock_server(server);
472 return 0;
473 }
474
475
476 int
477 ncp_initialize_search(struct ncp_server *server,
478 struct nw_info_struct *dir,
479 struct nw_search_sequence *target)
480 {
481 int result;
482
483 ncp_init_request(server);
484 ncp_add_byte(server, 2);
485 ncp_add_byte(server, 0);
486 ncp_add_byte(server, 0);
487 ncp_add_handle_path(server, dir->volNumber, dir->DosDirNum, 1, NULL);
488
489 if ((result = ncp_request(server, 87)) != 0)
490 {
491 ncp_unlock_server(server);
492 return result;
493 }
494
495 memcpy(target, ncp_reply_data(server, 0), sizeof(*target));
496
497 ncp_unlock_server(server);
498 return 0;
499 }
500
501
502 int
503 ncp_search_for_file_or_subdir(struct ncp_server *server,
504 struct nw_search_sequence *seq,
505 struct nw_info_struct *target)
506 {
507 int result;
508
509 ncp_init_request(server);
510 ncp_add_byte(server, 3);
511 ncp_add_byte(server, 0);
512 ncp_add_byte(server, 0);
513 ncp_add_word(server, 0xffff);
514 ncp_add_dword(server, RIM_ALL);
515 ncp_add_mem(server, seq, 9);
516 ncp_add_byte(server, 2);
517 ncp_add_byte(server, 0xff);
518 ncp_add_byte(server, '*');
519
520 if ((result = ncp_request(server, 87)) != 0)
521 {
522 ncp_unlock_server(server);
523 return result;
524 }
525
526 memcpy(seq, ncp_reply_data(server, 0), sizeof(*seq));
527 ncp_extract_file_info(ncp_reply_data(server, 10), target);
528
529 ncp_unlock_server(server);
530 return 0;
531 }
532
533 int
534 ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
535 struct nw_info_struct *old_dir, char *old_name,
536 struct nw_info_struct *new_dir, char *new_name)
537 {
538 int result;
539
540 if ( (old_dir == NULL) || (old_name == NULL)
541 || (new_dir == NULL) || (new_name == NULL))
542 return -EINVAL;
543
544 ncp_init_request(server);
545 ncp_add_byte(server, 4);
546 ncp_add_byte(server, 0);
547 ncp_add_byte(server, 1);
548 ncp_add_word(server, 0x8006);
549
550
551 ncp_add_byte(server, old_dir->volNumber);
552 ncp_add_dword(server, old_dir->DosDirNum);
553 ncp_add_byte(server, 1);
554 ncp_add_byte(server, 1);
555
556
557 ncp_add_byte(server, new_dir->volNumber);
558 ncp_add_dword(server, new_dir->DosDirNum);
559 ncp_add_byte(server, 1);
560 ncp_add_byte(server, 1);
561
562
563 ncp_add_pstring(server, old_name);
564
565 ncp_add_pstring(server, new_name);
566
567 result = ncp_request(server, 87);
568 ncp_unlock_server(server);
569 return result;
570 }
571
572
573
574 int
575 ncp_read(struct ncp_server *server, const char *file_id,
576 __u32 offset, __u16 to_read,
577 char *target, int *bytes_read)
578 {
579 int result;
580
581 ncp_init_request(server);
582 ncp_add_byte(server, 0);
583 ncp_add_mem(server, file_id, 6);
584 ncp_add_dword(server, htonl(offset));
585 ncp_add_word(server, htons(to_read));
586
587 if ((result = ncp_request(server, 72)) != 0)
588 {
589 ncp_unlock_server(server);
590 return result;
591 }
592
593 *bytes_read = ntohs(ncp_reply_word(server, 0));
594
595 memcpy_tofs(target, ncp_reply_data(server, 2+(offset&1)), *bytes_read);
596
597 ncp_unlock_server(server);
598 return 0;
599 }
600
601 int
602 ncp_write(struct ncp_server *server, const char *file_id,
603 __u32 offset, __u16 to_write,
604 const char *source, int *bytes_written)
605 {
606 int result;
607
608 ncp_init_request(server);
609 ncp_add_byte(server, 0);
610 ncp_add_mem(server, file_id, 6);
611 ncp_add_dword(server, htonl(offset));
612 ncp_add_word(server, htons(to_write));
613 ncp_add_mem_fromfs(server, source, to_write);
614
615 if ((result = ncp_request(server, 73)) != 0)
616 {
617 ncp_unlock_server(server);
618 return result;
619 }
620
621 *bytes_written = to_write;
622
623 ncp_unlock_server(server);
624 return 0;
625 }
626