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