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 result = ncp_request(server, 66);
221 ncp_unlock_server(server);
222 return result;
223 }
224
225 static void
226 ncp_add_handle_path(struct ncp_server *server,
227 __u8 vol_num,
228 __u32 dir_base, int have_dir_base,
229 char *path)
230 {
231 ncp_add_byte(server, vol_num);
232 ncp_add_dword(server, dir_base);
233 if (have_dir_base != 0)
234 {
235 ncp_add_byte(server, 1);
236 }
237 else
238 {
239 ncp_add_byte(server, 0xff);
240 }
241 if (path != NULL)
242 {
243 ncp_add_byte(server, 1);
244 ncp_add_pstring(server, path);
245 }
246 else
247 {
248 ncp_add_byte(server, 0);
249 }
250 }
251
252 static void
253 ncp_extract_file_info(void *structure, struct nw_info_struct *target)
254 {
255 __u8 *name_len;
256 const int info_struct_size = sizeof(struct nw_info_struct) - 257;
257
258 memcpy(target, structure, info_struct_size);
259 name_len = structure + info_struct_size;
260 target->nameLen = *name_len;
261 strncpy(target->entryName, name_len+1, *name_len);
262 target->entryName[*name_len] = '\0';
263 return;
264 }
265
266 int
267 ncp_obtain_info(struct ncp_server *server,
268 __u8 vol_num, __u32 dir_base,
269 char *path,
270 struct nw_info_struct *target)
271 {
272 int result;
273
274 if (target == NULL)
275 {
276 return -EINVAL;
277 }
278
279 ncp_init_request(server);
280 ncp_add_byte(server, 6);
281 ncp_add_byte(server, 0);
282 ncp_add_byte(server, 0);
283 ncp_add_word(server, 0xff);
284 ncp_add_dword(server, RIM_ALL);
285 ncp_add_handle_path(server, vol_num, dir_base, 1, path);
286
287 if ((result = ncp_request(server, 87)) != 0)
288 {
289 ncp_unlock_server(server);
290 return result;
291 }
292
293 ncp_extract_file_info(ncp_reply_data(server, 0), target);
294 ncp_unlock_server(server);
295 return 0;
296 }
297
298 int
299 ncp_lookup_volume(struct ncp_server *server,
300 char *volname,
301 struct nw_info_struct *target)
302 {
303 int result;
304 __u8 vol_num;
305 __u32 dir_base;
306
307 DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname);
308
309 ncp_init_request(server);
310 ncp_add_byte(server, 22);
311 ncp_add_byte(server, 0);
312 ncp_add_byte(server, 0);
313 ncp_add_byte(server, 0);
314 ncp_add_byte(server, 0);
315
316 ncp_add_byte(server, 0);
317 ncp_add_dword(server, 0);
318 ncp_add_byte(server, 0xff);
319 ncp_add_byte(server, 1);
320 ncp_add_pstring(server, volname);
321
322 if ((result = ncp_request(server, 87)) != 0)
323 {
324 ncp_unlock_server(server);
325 return result;
326 }
327
328 dir_base = ncp_reply_dword(server, 4);
329 vol_num = ncp_reply_byte(server, 8);
330 ncp_unlock_server(server);
331
332 if ((result = ncp_obtain_info(server, vol_num, dir_base, NULL,
333 target)) != 0)
334 {
335 return result;
336 }
337
338 DPRINTK("ncp_lookup_volume: attribs = %X\n", target->attributes);
339
340 target->nameLen = strlen(volname);
341 strcpy(target->entryName, volname);
342 return 0;
343 }
344
345 int
346 ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
347 struct nw_info_struct *file,
348 __u32 info_mask,
349 struct nw_modify_dos_info *info)
350 {
351 int result;
352
353 ncp_init_request(server);
354 ncp_add_byte(server, 7);
355 ncp_add_byte(server, 0);
356 ncp_add_byte(server, 0);
357 ncp_add_word(server, 0x8006);
358
359 ncp_add_dword(server, info_mask);
360 ncp_add_mem(server, info, sizeof(*info));
361 ncp_add_handle_path(server, file->volNumber,
362 file->DosDirNum, 1, NULL);
363
364 result = ncp_request(server, 87);
365 ncp_unlock_server(server);
366 return result;
367 }
368
369 int
370 ncp_del_file_or_subdir(struct ncp_server *server,
371 struct nw_info_struct *dir, char *name)
372 {
373 int result;
374
375 ncp_init_request(server);
376 ncp_add_byte(server, 8);
377 ncp_add_byte(server, 0);
378 ncp_add_byte(server, 0);
379 ncp_add_word(server, 0x8006);
380 ncp_add_handle_path(server, dir->volNumber,
381 dir->DosDirNum, 1, name);
382
383 result = ncp_request(server, 87);
384 ncp_unlock_server(server);
385 return result;
386 }
387
388 static inline void
389 ConvertToNWfromDWORD ( __u32 sfd , __u8 ret[6] )
390 {
391 __u16 *dest = (__u16 *) ret;
392 memcpy(&(dest[1]), &sfd, 4);
393 dest[0] = dest[1] + 1;
394 return;
395 }
396
397
398
399 int
400 ncp_open_create_file_or_subdir(struct ncp_server *server,
401 struct nw_info_struct *dir, char *name,
402 int open_create_mode,
403 __u32 create_attributes,
404 int desired_acc_rights,
405 struct nw_file_info *target)
406 {
407 int result;
408 __u16 search_attribs = 0x0006;
409
410 if ((create_attributes & aDIR) != 0)
411 {
412 search_attribs |= 0x8000;
413 }
414
415 ncp_init_request(server);
416 ncp_add_byte(server, 1);
417 ncp_add_byte(server, 0);
418 ncp_add_byte(server, open_create_mode);
419 ncp_add_word(server, search_attribs);
420 ncp_add_dword(server, RIM_ALL);
421 ncp_add_dword(server, create_attributes);
422
423
424 ncp_add_word(server, desired_acc_rights);
425
426 if (dir != NULL)
427 {
428 ncp_add_handle_path(server, dir->volNumber,
429 dir->DosDirNum, 1, name);
430 }
431 else
432 {
433 ncp_add_handle_path(server,
434 target->i.volNumber, target->i.DosDirNum,
435 1, NULL);
436 }
437
438 if ((result = ncp_request(server, 87)) != 0)
439 {
440 ncp_unlock_server(server);
441 return result;
442 }
443
444 target->opened = 1;
445 target->server_file_handle = ncp_reply_dword(server, 0);
446 target->open_create_action = ncp_reply_byte(server, 4);
447
448 if (dir != NULL)
449 {
450
451 ncp_extract_file_info(ncp_reply_data(server, 5), &(target->i));
452 }
453
454 ConvertToNWfromDWORD(target->server_file_handle, target->file_handle);
455
456 ncp_unlock_server(server);
457 return 0;
458 }
459
460
461 int
462 ncp_initialize_search(struct ncp_server *server,
463 struct nw_info_struct *dir,
464 struct nw_search_sequence *target)
465 {
466 int result;
467
468 ncp_init_request(server);
469 ncp_add_byte(server, 2);
470 ncp_add_byte(server, 0);
471 ncp_add_byte(server, 0);
472 ncp_add_handle_path(server, dir->volNumber, dir->DosDirNum, 1, NULL);
473
474 if ((result = ncp_request(server, 87)) != 0)
475 {
476 ncp_unlock_server(server);
477 return result;
478 }
479
480 memcpy(target, ncp_reply_data(server, 0), sizeof(*target));
481
482 ncp_unlock_server(server);
483 return 0;
484 }
485
486
487 int
488 ncp_search_for_file_or_subdir(struct ncp_server *server,
489 struct nw_search_sequence *seq,
490 struct nw_info_struct *target)
491 {
492 int result;
493
494 ncp_init_request(server);
495 ncp_add_byte(server, 3);
496 ncp_add_byte(server, 0);
497 ncp_add_byte(server, 0);
498 ncp_add_word(server, 0xffff);
499 ncp_add_dword(server, RIM_ALL);
500 ncp_add_mem(server, seq, 9);
501 ncp_add_byte(server, 2);
502 ncp_add_byte(server, 0xff);
503 ncp_add_byte(server, '*');
504
505 if ((result = ncp_request(server, 87)) != 0)
506 {
507 ncp_unlock_server(server);
508 return result;
509 }
510
511 memcpy(seq, ncp_reply_data(server, 0), sizeof(*seq));
512 ncp_extract_file_info(ncp_reply_data(server, 10), target);
513
514 ncp_unlock_server(server);
515 return 0;
516 }
517
518 int
519 ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
520 struct nw_info_struct *old_dir, char *old_name,
521 struct nw_info_struct *new_dir, char *new_name)
522 {
523 int result;
524
525 if ( (old_dir == NULL) || (old_name == NULL)
526 || (new_dir == NULL) || (new_name == NULL))
527 return -EINVAL;
528
529 ncp_init_request(server);
530 ncp_add_byte(server, 4);
531 ncp_add_byte(server, 0);
532 ncp_add_byte(server, 1);
533 ncp_add_word(server, 0x8006);
534
535
536 ncp_add_byte(server, old_dir->volNumber);
537 ncp_add_dword(server, old_dir->DosDirNum);
538 ncp_add_byte(server, 1);
539 ncp_add_byte(server, 1);
540
541
542 ncp_add_byte(server, new_dir->volNumber);
543 ncp_add_dword(server, new_dir->DosDirNum);
544 ncp_add_byte(server, 1);
545 ncp_add_byte(server, 1);
546
547
548 ncp_add_pstring(server, old_name);
549
550 ncp_add_pstring(server, new_name);
551
552 result = ncp_request(server, 87);
553 ncp_unlock_server(server);
554 return result;
555 }
556
557
558
559 int
560 ncp_read(struct ncp_server *server, const char *file_id,
561 __u32 offset, __u16 to_read,
562 char *target, int *bytes_read)
563 {
564 int result;
565
566 ncp_init_request(server);
567 ncp_add_byte(server, 0);
568 ncp_add_mem(server, file_id, 6);
569 ncp_add_dword(server, htonl(offset));
570 ncp_add_word(server, htons(to_read));
571
572 if ((result = ncp_request(server, 72)) != 0)
573 {
574 ncp_unlock_server(server);
575 return result;
576 }
577
578 *bytes_read = ntohs(ncp_reply_word(server, 0));
579
580 memcpy_tofs(target, ncp_reply_data(server, 2+(offset&1)), *bytes_read);
581
582 ncp_unlock_server(server);
583 return 0;
584 }
585
586 int
587 ncp_write(struct ncp_server *server, const char *file_id,
588 __u32 offset, __u16 to_write,
589 const char *source, int *bytes_written)
590 {
591 int result;
592
593 ncp_init_request(server);
594 ncp_add_byte(server, 0);
595 ncp_add_mem(server, file_id, 6);
596 ncp_add_dword(server, htonl(offset));
597 ncp_add_word(server, htons(to_write));
598 ncp_add_mem_fromfs(server, source, to_write);
599
600 if ((result = ncp_request(server, 73)) != 0)
601 {
602 ncp_unlock_server(server);
603 return result;
604 }
605
606 *bytes_written = to_write;
607
608 ncp_unlock_server(server);
609 return 0;
610 }
611