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
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, 0x8006);
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