OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [ncpfs/] [ncplib_kernel.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1628 jcastillo
/*
2
 *  ncplib_kernel.c
3
 *
4
 *  Copyright (C) 1995, 1996 by Volker Lendecke
5
 *
6
 */
7
 
8
#include <linux/config.h>
9
 
10
#include "ncplib_kernel.h"
11
 
12
typedef __u8  byte;
13
typedef __u16 word;
14
typedef __u32 dword;
15
 
16
static inline int min(int a, int b)
17
{
18
        return a<b ? a : b;
19
}
20
 
21
static void
22
assert_server_locked(struct ncp_server *server)
23
{
24
        if (server->lock == 0)
25
        {
26
                DPRINTK("ncpfs: server not locked!\n");
27
        }
28
}
29
 
30
static void
31
ncp_add_byte(struct ncp_server *server, byte x)
32
{
33
        assert_server_locked(server);
34
        *(byte *)(&(server->packet[server->current_size])) = x;
35
        server->current_size += 1;
36
        return;
37
}
38
 
39
static void
40
ncp_add_word(struct ncp_server *server, word x)
41
{
42
        assert_server_locked(server);
43
        *(word *)(&(server->packet[server->current_size])) = x;
44
        server->current_size += 2;
45
        return;
46
}
47
 
48
static void
49
ncp_add_dword(struct ncp_server *server, dword x)
50
{
51
        assert_server_locked(server);
52
        *(dword *)(&(server->packet[server->current_size])) = x;
53
        server->current_size += 4;
54
        return;
55
}
56
 
57
static void
58
ncp_add_mem(struct ncp_server *server, const void *source, int size)
59
{
60
        assert_server_locked(server);
61
        memcpy(&(server->packet[server->current_size]), source, size);
62
        server->current_size += size;
63
        return;
64
}
65
 
66
static void
67
ncp_add_mem_fromfs(struct ncp_server *server, const char *source, int size)
68
{
69
        assert_server_locked(server);
70
        memcpy_fromfs(&(server->packet[server->current_size]), source, size);
71
        server->current_size += size;
72
        return;
73
}
74
 
75
static void
76
ncp_add_pstring(struct ncp_server *server, const char *s)
77
{
78
        int len = strlen(s);
79
        assert_server_locked(server);
80
        if (len > 255)
81
        {
82
                DPRINTK("ncpfs: string too long: %s\n", s);
83
                len = 255;
84
        }
85
        ncp_add_byte(server, len);
86
        ncp_add_mem(server, s, len);
87
        return;
88
}
89
 
90
static void
91
ncp_init_request(struct ncp_server *server)
92
{
93
        ncp_lock_server(server);
94
 
95
        server->current_size = sizeof(struct ncp_request_header);
96
        server->has_subfunction = 0;
97
}
98
 
99
static void
100
ncp_init_request_s(struct ncp_server *server, int subfunction)
101
{
102
        ncp_init_request(server);
103
        ncp_add_word(server, 0); /* preliminary size */
104
 
105
        ncp_add_byte(server, subfunction);
106
 
107
        server->has_subfunction = 1;
108
}
109
 
110
static char *
111
ncp_reply_data(struct ncp_server *server, int offset)
112
{
113
        return &(server->packet[sizeof(struct ncp_reply_header) + offset]);
114
}
115
 
116
static byte
117
ncp_reply_byte(struct ncp_server *server, int offset)
118
{
119
        return *(byte *)(ncp_reply_data(server, offset));
120
}
121
 
122
static word
123
ncp_reply_word(struct ncp_server *server, int offset)
124
{
125
        return *(word *)(ncp_reply_data(server, offset));
126
}
127
 
128
static dword
129
ncp_reply_dword(struct ncp_server *server, int offset)
130
{
131
        return *(dword *)(ncp_reply_data(server, offset));
132
}
133
 
134
 
135
/* options:
136
 *      bit 0   ipx checksum
137
 *      bit 1   packet signing
138
 */
139
int
140
ncp_negotiate_size_and_options(struct ncp_server *server,
141
        int size, int options, int *ret_size, int *ret_options) {
142
        int result;
143
 
144
        ncp_init_request(server);
145
        ncp_add_word(server, htons(size));
146
        ncp_add_byte(server, options);
147
 
148
        if ((result = ncp_request(server, 0x61)) != 0)
149
        {
150
                ncp_unlock_server(server);
151
                return result;
152
        }
153
 
154
        *ret_size = min(ntohs(ncp_reply_word(server, 0)), size);
155
        *ret_options = ncp_reply_byte(server, 4);
156
 
157
        ncp_unlock_server(server);
158
        return 0;
159
}
160
 
161
int
162
ncp_negotiate_buffersize(struct ncp_server *server,
163
                         int size, int *target)
164
{
165
        int result;
166
 
167
        ncp_init_request(server);
168
        ncp_add_word(server, htons(size));
169
 
170
        if ((result = ncp_request(server, 33)) != 0)
171
        {
172
                ncp_unlock_server(server);
173
                return result;
174
        }
175
 
176
        *target =min(ntohs(ncp_reply_word(server, 0)), size);
177
 
178
        ncp_unlock_server(server);
179
        return 0;
180
}
181
 
182
int
183
ncp_get_volume_info_with_number(struct ncp_server *server, int n,
184
                                struct ncp_volume_info *target)
185
{
186
        int result;
187
        int len;
188
 
189
        ncp_init_request_s(server, 44);
190
        ncp_add_byte(server, n);
191
 
192
        if ((result = ncp_request(server, 22)) != 0)
193
        {
194
                ncp_unlock_server(server);
195
                return result;
196
        }
197
 
198
        target->total_blocks = ncp_reply_dword(server, 0);
199
        target->free_blocks  = ncp_reply_dword(server, 4);
200
        target->purgeable_blocks = ncp_reply_dword(server, 8);
201
        target->not_yet_purgeable_blocks = ncp_reply_dword(server, 12);
202
        target->total_dir_entries = ncp_reply_dword(server, 16);
203
        target->available_dir_entries = ncp_reply_dword(server, 20);
204
        target->sectors_per_block = ncp_reply_byte(server, 28);
205
 
206
        memset(&(target->volume_name), 0, sizeof(target->volume_name));
207
 
208
        len = ncp_reply_byte(server, 29);
209
        if (len > NCP_VOLNAME_LEN)
210
        {
211
                DPRINTK("ncpfs: volume name too long: %d\n", len);
212
                ncp_unlock_server(server);
213
                return -EIO;
214
        }
215
 
216
        memcpy(&(target->volume_name), ncp_reply_data(server, 30), len);
217
        ncp_unlock_server(server);
218
        return 0;
219
}
220
 
221
int
222
ncp_close_file(struct ncp_server *server, const char *file_id)
223
{
224
        int result;
225
 
226
        ncp_init_request(server);
227
        ncp_add_byte(server, 0);
228
        ncp_add_mem(server, file_id, 6);
229
 
230
        result = ncp_request(server, 66);
231
        ncp_unlock_server(server);
232
        return result;
233
}
234
 
235
static void
236
ncp_add_handle_path(struct ncp_server *server,
237
                    __u8 vol_num,
238
                    __u32 dir_base, int have_dir_base,
239
                    char *path)
240
{
241
        ncp_add_byte(server, vol_num);
242
        ncp_add_dword(server, dir_base);
243
        if (have_dir_base != 0)
244
        {
245
                ncp_add_byte(server, 1); /* dir_base */
246
        }
247
        else
248
        {
249
                ncp_add_byte(server, 0xff); /* no handle */
250
        }
251
        if (path != NULL)
252
        {
253
                ncp_add_byte(server, 1); /* 1 component */
254
                ncp_add_pstring(server, path);
255
        }
256
        else
257
        {
258
                ncp_add_byte(server, 0);
259
        }
260
}
261
 
262
static void
263
ncp_extract_file_info(void *structure, struct nw_info_struct *target)
264
{
265
        __u8 *name_len;
266
        const int info_struct_size = sizeof(struct nw_info_struct) - 257;
267
 
268
        memcpy(target, structure, info_struct_size);
269
        name_len = structure + info_struct_size;
270
        target->nameLen = *name_len;
271
        strncpy(target->entryName, name_len+1, *name_len);
272
        target->entryName[*name_len] = '\0';
273
        return;
274
}
275
 
276
int
277
ncp_obtain_info(struct ncp_server *server,
278
                __u8 vol_num, __u32 dir_base,
279
                char *path, /* At most 1 component */
280
                struct nw_info_struct *target)
281
{
282
        int result;
283
 
284
        if (target == NULL)
285
        {
286
                return -EINVAL;
287
        }
288
 
289
        ncp_init_request(server);
290
        ncp_add_byte(server, 6); /* subfunction */
291
        ncp_add_byte(server, server->name_space[vol_num]);
292
        ncp_add_byte(server, server->name_space[vol_num]);
293
        ncp_add_word(server, 0x8006); /* get all */
294
        ncp_add_dword(server, RIM_ALL);
295
        ncp_add_handle_path(server, vol_num, dir_base, 1, path);
296
 
297
        if ((result = ncp_request(server, 87)) != 0)
298
        {
299
                ncp_unlock_server(server);
300
                return result;
301
        }
302
 
303
        ncp_extract_file_info(ncp_reply_data(server, 0), target);
304
        ncp_unlock_server(server);
305
        return 0;
306
}
307
 
308
static inline int
309
ncp_get_known_namespace(struct ncp_server *server, __u8 volume)
310
{
311
#if defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS)
312
        int result;
313
        __u8 *namespace;
314
        __u16 no_namespaces;
315
 
316
        ncp_init_request(server);
317
        ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */
318
        ncp_add_word(server, 0);
319
        ncp_add_byte(server, volume);
320
 
321
        if ((result = ncp_request(server, 87)) != 0)
322
        {
323
                ncp_unlock_server(server);
324
                return NW_NS_DOS;
325
        }
326
 
327
        result=NW_NS_DOS;
328
        no_namespaces = ncp_reply_word(server, 0);
329
        namespace = ncp_reply_data(server, 2);
330
 
331
        while (no_namespaces > 0)
332
        {
333
                DPRINTK("get_namespaces: found %d on %d\n", *namespace,volume);
334
 
335
#ifdef CONFIG_NCPFS_NFS_NS
336
                if ((*namespace == NW_NS_NFS) && !(server->m.flags&NCP_MOUNT_NO_NFS))
337
                {
338
                        result = NW_NS_NFS;
339
                        break;
340
                }
341
#endif  /* CONFIG_NCPFS_NFS_NS */
342
#ifdef CONFIG_NCPFS_OS2_NS
343
                if ((*namespace == NW_NS_OS2) && !(server->m.flags&NCP_MOUNT_NO_OS2))
344
                {
345
                        result = NW_NS_OS2;
346
                }
347
#endif  /* CONFIG_NCPFS_OS2_NS */
348
                namespace += 1;
349
                no_namespaces -= 1;
350
        }
351
        ncp_unlock_server(server);
352
        return result;
353
#else   /* neither OS2 nor NFS - only DOS */
354
        return NW_NS_DOS;
355
#endif  /* defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS) */
356
}
357
 
358
static int
359
ncp_ObtainSpecificDirBase(struct ncp_server *server,
360
                __u8 nsSrc, __u8 nsDst, __u8 vol_num, __u32 dir_base,
361
                char *path, /* At most 1 component */
362
                __u32 *dirEntNum)
363
{
364
        int result;
365
 
366
        ncp_init_request(server);
367
        ncp_add_byte(server, 6); /* subfunction */
368
        ncp_add_byte(server, nsSrc);
369
        ncp_add_byte(server, nsDst);
370
        ncp_add_word(server, 0x8006); /* get all */
371
        ncp_add_dword(server, RIM_ALL);
372
        ncp_add_handle_path(server, vol_num, dir_base, 1, path);
373
 
374
        if ((result = ncp_request(server, 87)) != 0)
375
        {
376
                ncp_unlock_server(server);
377
                return result;
378
        }
379
 
380
        if (dirEntNum)
381
                *dirEntNum = ncp_reply_dword(server, 0x30);
382
        ncp_unlock_server(server);
383
        return 0;
384
}
385
 
386
int
387
ncp_mount_subdir(struct ncp_server *server,
388
                __u8 volNumber,
389
                __u8 srcNS, __u32 dirEntNum)
390
{
391
        int dstNS;
392
        int result;
393
        __u32 newDirEnt;
394
 
395
        dstNS = ncp_get_known_namespace(server, volNumber);
396
        if ((result = ncp_ObtainSpecificDirBase(server, srcNS, dstNS, volNumber,
397
                                      dirEntNum, NULL, &newDirEnt)) != 0)
398
        {
399
                return result;
400
        }
401
        server->name_space[volNumber] = dstNS;
402
        server->root.finfo.i.volNumber = volNumber;
403
        server->root.finfo.i.dirEntNum = newDirEnt;
404
        server->m.mounted_vol[1] = 0;
405
        server->m.mounted_vol[0] = 'X';
406
        return 0;
407
}
408
 
409
static int
410
ncp_obtain_DOS_dir_base(struct ncp_server *server,
411
                struct nw_info_struct* file,
412
                char *path, /* At most 1 component */
413
                __u32 *DOS_dir_base)
414
{
415
        int result;
416
 
417
        ncp_init_request(server);
418
        ncp_add_byte(server, 6); /* subfunction */
419
        ncp_add_byte(server, server->name_space[file->volNumber]);
420
        ncp_add_byte(server, server->name_space[file->volNumber]);
421
        ncp_add_word(server, 0x8006); /* get all */
422
        ncp_add_dword(server, RIM_DIRECTORY);
423
        ncp_add_handle_path(server, file->volNumber, file->dirEntNum, 1, path);
424
 
425
        if ((result = ncp_request(server, 87)) != 0)
426
        {
427
                ncp_unlock_server(server);
428
                return result;
429
        }
430
 
431
        if (DOS_dir_base) *DOS_dir_base=ncp_reply_dword(server, 0x34);
432
        ncp_unlock_server(server);
433
        return 0;
434
}
435
 
436
int
437
ncp_lookup_volume(struct ncp_server *server,
438
                  char *volname,
439
                  struct nw_info_struct *target)
440
{
441
        int result;
442
        int volnum;
443
 
444
        DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname);
445
 
446
        ncp_init_request(server);
447
        ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */
448
        ncp_add_byte(server, 0); /* DOS namespace */
449
        ncp_add_byte(server, 0); /* reserved */
450
        ncp_add_byte(server, 0); /* reserved */
451
        ncp_add_byte(server, 0); /* reserved */
452
 
453
        ncp_add_byte(server, 0); /* faked volume number */
454
        ncp_add_dword(server, 0); /* faked dir_base */
455
        ncp_add_byte(server, 0xff); /* Don't have a dir_base */
456
        ncp_add_byte(server, 1); /* 1 path component */
457
        ncp_add_pstring(server, volname);
458
 
459
        if ((result = ncp_request(server, 87)) != 0)
460
        {
461
                ncp_unlock_server(server);
462
                return result;
463
        }
464
 
465
        memset(target, 0, sizeof(*target));
466
        target->DosDirNum = target->dirEntNum = ncp_reply_dword(server, 4);
467
        target->volNumber = volnum = ncp_reply_byte(server, 8);
468
        ncp_unlock_server(server);
469
 
470
        server->name_space[volnum] =
471
                ncp_get_known_namespace(server, volnum);
472
 
473
        DPRINTK("lookup_vol: namespace[%d] = %d\n",
474
                volnum, server->name_space[volnum]);
475
 
476
        target->nameLen = strlen(volname);
477
        strcpy(target->entryName, volname);
478
        target->attributes = aDIR;
479
        return 0;
480
}
481
 
482
int
483
ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
484
                                   struct nw_info_struct *file,
485
                                   __u32 info_mask,
486
                                   struct nw_modify_dos_info *info)
487
{
488
        int result;
489
 
490
        ncp_init_request(server);
491
        ncp_add_byte(server, 7); /* subfunction */
492
        ncp_add_byte(server, server->name_space[file->volNumber]);
493
        ncp_add_byte(server, 0); /* reserved */
494
        ncp_add_word(server, 0x8006); /* search attribs: all */
495
 
496
        ncp_add_dword(server, info_mask);
497
        ncp_add_mem(server, info, sizeof(*info));
498
        ncp_add_handle_path(server, file->volNumber,
499
                            file->dirEntNum, 1, NULL);
500
 
501
        result = ncp_request(server, 87);
502
        ncp_unlock_server(server);
503
        return result;
504
}
505
 
506
static int
507
ncp_DeleteNSEntry(struct ncp_server *server,
508
                  __u8 have_dir_base, __u8 volume, __u32 dir_base,
509
                  char* name, __u8 ns, int attr)
510
{
511
        int result;
512
 
513
        ncp_init_request(server);
514
        ncp_add_byte(server, 8); /* subfunction */
515
        ncp_add_byte(server, ns); /* namespace */
516
        ncp_add_byte(server, 0); /* reserved */
517
        ncp_add_word(server, attr); /* search attribs */
518
        ncp_add_handle_path(server, volume, dir_base, have_dir_base, name);
519
 
520
        result = ncp_request(server, 87);
521
        ncp_unlock_server(server);
522
        return result;
523
}
524
 
525
int
526
ncp_del_file_or_subdir(struct ncp_server *server,
527
                       struct nw_info_struct *dir, char *name)
528
{
529
#ifdef CONFIG_NCPFS_NFS_NS
530
        if (server->name_space[dir->volNumber]==NW_NS_NFS)
531
        {
532
                __u32 DOS_dir_base;
533
                int result;
534
 
535
                result=ncp_obtain_DOS_dir_base(server, dir, name, &DOS_dir_base);
536
                if (result) return result;
537
                return ncp_DeleteNSEntry(server, 1, dir->volNumber, DOS_dir_base, NULL, NW_NS_DOS, 0x8006);
538
        }
539
        else
540
#endif  /* CONFIG_NCPFS_NFS_NS */
541
                return ncp_DeleteNSEntry(server, 1, dir->volNumber, dir->dirEntNum, name, server->name_space[dir->volNumber], 0x8006);
542
}
543
 
544
static inline void
545
ConvertToNWfromDWORD ( __u32 sfd , __u8 ret[6] )
546
{
547
    __u16 *dest = (__u16 *) ret;
548
    memcpy(&(dest[1]), &sfd, 4);
549
    dest[0] = dest[1] + 1;
550
    return;
551
}
552
 
553
/* If both dir and name are NULL, then in target there's already a
554
   looked-up entry that wants to be opened. */
555
int
556
ncp_open_create_file_or_subdir(struct ncp_server *server,
557
                               struct nw_info_struct *dir, char *name,
558
                               int open_create_mode,
559
                               __u32 create_attributes,
560
                               int desired_acc_rights,
561
                               struct nw_file_info *target)
562
{
563
        int result;
564
        __u16 search_attribs = 0x0006;
565
        __u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber;
566
 
567
        if ((create_attributes & aDIR) != 0)
568
        {
569
                search_attribs |= 0x8000;
570
        }
571
 
572
        ncp_init_request(server);
573
        ncp_add_byte(server, 1); /* subfunction */
574
        ncp_add_byte(server, server->name_space[volume]);
575
        ncp_add_byte(server, open_create_mode);
576
        ncp_add_word(server, search_attribs);
577
        ncp_add_dword(server, RIM_ALL);
578
        ncp_add_dword(server, create_attributes);
579
        /* The desired acc rights seem to be the inherited rights mask
580
           for directories */
581
        ncp_add_word(server, desired_acc_rights);
582
 
583
        if (dir != NULL)
584
        {
585
                ncp_add_handle_path(server, volume, dir->dirEntNum, 1, name);
586
        }
587
        else
588
        {
589
                ncp_add_handle_path(server, volume, target->i.dirEntNum,
590
                                    1, NULL);
591
        }
592
 
593
        if ((result = ncp_request(server, 87)) != 0)
594
        {
595
                ncp_unlock_server(server);
596
                return result;
597
        }
598
 
599
        target->opened = 1;
600
        target->server_file_handle = ncp_reply_dword(server, 0);
601
        target->open_create_action = ncp_reply_byte(server, 4);
602
 
603
        if (dir != NULL)
604
        {
605
                /* in target there's a new finfo to fill */
606
                ncp_extract_file_info(ncp_reply_data(server, 6), &(target->i));
607
        }
608
 
609
        ConvertToNWfromDWORD(target->server_file_handle, target->file_handle);
610
 
611
        ncp_unlock_server(server);
612
        return 0;
613
}
614
 
615
 
616
int
617
ncp_initialize_search(struct ncp_server *server,
618
                      struct nw_info_struct *dir,
619
                      struct nw_search_sequence *target)
620
{
621
        int result;
622
 
623
        ncp_init_request(server);
624
        ncp_add_byte(server, 2); /* subfunction */
625
        ncp_add_byte(server, server->name_space[dir->volNumber]);
626
        ncp_add_byte(server, 0); /* reserved */
627
        ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, NULL);
628
 
629
        if ((result = ncp_request(server, 87)) != 0)
630
        {
631
                ncp_unlock_server(server);
632
                return result;
633
        }
634
 
635
        memcpy(target, ncp_reply_data(server, 0), sizeof(*target));
636
 
637
        ncp_unlock_server(server);
638
        return 0;
639
}
640
 
641
/* Search for everything */
642
int
643
ncp_search_for_file_or_subdir(struct ncp_server *server,
644
                              struct nw_search_sequence *seq,
645
                              struct nw_info_struct *target)
646
{
647
        int result;
648
 
649
        ncp_init_request(server);
650
        ncp_add_byte(server, 3); /* subfunction */
651
        ncp_add_byte(server, server->name_space[seq->volNumber]);
652
        ncp_add_byte(server, 0); /* data stream (???) */
653
        ncp_add_word(server, 0x8006); /* Search attribs */
654
        ncp_add_dword(server, RIM_ALL); /* return info mask */
655
        ncp_add_mem(server, seq, 9);
656
#ifdef CONFIG_NCPFS_NFS_NS
657
        if (server->name_space[seq->volNumber]==NW_NS_NFS)
658
        {
659
                ncp_add_byte(server, 0);
660
        }
661
        else
662
#endif  /* CONFIG_NCPFS_NFS_NS */
663
        {
664
                ncp_add_byte(server, 2); /* 2 byte pattern */
665
                ncp_add_byte(server, 0xff); /* following is a wildcard */
666
                ncp_add_byte(server, '*');
667
        }
668
 
669
        if ((result = ncp_request(server, 87)) != 0)
670
        {
671
                ncp_unlock_server(server);
672
                return result;
673
        }
674
 
675
        memcpy(seq, ncp_reply_data(server, 0), sizeof(*seq));
676
        ncp_extract_file_info(ncp_reply_data(server, 10), target);
677
 
678
        ncp_unlock_server(server);
679
        return 0;
680
}
681
 
682
int
683
ncp_RenameNSEntry(struct ncp_server *server,
684
                  struct nw_info_struct *old_dir, char *old_name, int old_type,
685
                  struct nw_info_struct *new_dir, char *new_name)
686
{
687
        int result;
688
 
689
        if (   (old_dir == NULL) || (old_name == NULL)
690
            || (new_dir == NULL) || (new_name == NULL))
691
                return -EINVAL;
692
 
693
        ncp_init_request(server);
694
        ncp_add_byte(server, 4); /* subfunction */
695
        ncp_add_byte(server, server->name_space[old_dir->volNumber]);
696
        ncp_add_byte(server, 1); /* rename flag */
697
        ncp_add_word(server, old_type); /* search attributes */
698
 
699
        /* source Handle Path */
700
        ncp_add_byte(server, old_dir->volNumber);
701
        ncp_add_dword(server, old_dir->dirEntNum);
702
        ncp_add_byte(server, 1);
703
        ncp_add_byte(server, 1); /* 1 source component */
704
 
705
        /* dest Handle Path */
706
        ncp_add_byte(server, new_dir->volNumber);
707
        ncp_add_dword(server, new_dir->dirEntNum);
708
        ncp_add_byte(server, 1);
709
        ncp_add_byte(server, 1); /* 1 destination component */
710
 
711
        /* source path string */
712
        ncp_add_pstring(server, old_name);
713
        /* dest path string */
714
        ncp_add_pstring(server, new_name);
715
 
716
        result = ncp_request(server, 87);
717
        ncp_unlock_server(server);
718
        return result;
719
}
720
 
721
int
722
ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
723
                              struct nw_info_struct *old_dir, char *old_name,
724
                              struct nw_info_struct *new_dir, char *new_name)
725
{
726
        int result;
727
        int old_type = 0x0006;
728
 
729
/* If somebody can do it atomic, call me... vandrove@vc.cvut.cz */
730
        result = ncp_RenameNSEntry(server, old_dir, old_name, old_type,
731
                                           new_dir, new_name);
732
        if (result == 0xFF)     /* File Not Found, try directory */
733
        {
734
                old_type = 0x0016;
735
                result = ncp_RenameNSEntry(server, old_dir, old_name, old_type,
736
                                                   new_dir, new_name);
737
        }
738
        if (result != 0x92) return result;      /* All except NO_FILES_RENAMED */
739
        result = ncp_del_file_or_subdir(server, new_dir, new_name);
740
        if (result != 0) return -EACCES;
741
        result = ncp_RenameNSEntry(server, old_dir, old_name, old_type,
742
                                           new_dir, new_name);
743
        return result;
744
}
745
 
746
 
747
/* We have to transfer to/from user space */
748
int
749
ncp_read(struct ncp_server *server, const char *file_id,
750
         __u32 offset, __u16 to_read,
751
         char *target, int *bytes_read)
752
{
753
        int result;
754
 
755
        ncp_init_request(server);
756
        ncp_add_byte(server, 0);
757
        ncp_add_mem(server, file_id, 6);
758
        ncp_add_dword(server, htonl(offset));
759
        ncp_add_word(server, htons(to_read));
760
 
761
        if ((result = ncp_request(server, 72)) != 0)
762
        {
763
                ncp_unlock_server(server);
764
                return result;
765
        }
766
 
767
        *bytes_read = ntohs(ncp_reply_word(server, 0));
768
 
769
        memcpy_tofs(target, ncp_reply_data(server, 2+(offset&1)), *bytes_read);
770
 
771
        ncp_unlock_server(server);
772
        return 0;
773
}
774
 
775
int
776
ncp_write(struct ncp_server *server, const char *file_id,
777
          __u32 offset, __u16 to_write,
778
          const char *source, int *bytes_written)
779
{
780
        int result;
781
 
782
        ncp_init_request(server);
783
        ncp_add_byte(server, 0);
784
        ncp_add_mem(server, file_id, 6);
785
        ncp_add_dword(server, htonl(offset));
786
        ncp_add_word(server, htons(to_write));
787
        ncp_add_mem_fromfs(server, source, to_write);
788
 
789
        if ((result = ncp_request(server, 73)) != 0)
790
        {
791
                ncp_unlock_server(server);
792
                return result;
793
        }
794
 
795
        *bytes_written = to_write;
796
 
797
        ncp_unlock_server(server);
798
        return 0;
799
}
800
 
801
#ifdef CONFIG_NCPFS_IOCTL_LOCKING
802
int
803
ncp_LogPhysicalRecord(struct ncp_server *server, const char *file_id,
804
          __u8 locktype, __u32 offset, __u32 length, __u16 timeout)
805
{
806
        int result;
807
 
808
        ncp_init_request(server);
809
        ncp_add_byte(server, locktype);
810
        ncp_add_mem(server, file_id, 6);
811
        ncp_add_dword(server, htonl(offset));
812
        ncp_add_dword(server, htonl(length));
813
        ncp_add_word(server, htons(timeout));
814
 
815
        if ((result = ncp_request(server, 0x1A)) != 0)
816
        {
817
                ncp_unlock_server(server);
818
                return result;
819
        }
820
        ncp_unlock_server(server);
821
        return 0;
822
}
823
 
824
int
825
ncp_ClearPhysicalRecord(struct ncp_server *server, const char *file_id,
826
          __u32 offset, __u32 length)
827
{
828
        int result;
829
 
830
        ncp_init_request(server);
831
        ncp_add_byte(server, 0); /* who knows... lanalyzer says that */
832
        ncp_add_mem(server, file_id, 6);
833
        ncp_add_dword(server, htonl(offset));
834
        ncp_add_dword(server, htonl(length));
835
 
836
        if ((result = ncp_request(server, 0x1E)) != 0)
837
        {
838
                ncp_unlock_server(server);
839
                return result;
840
        }
841
        ncp_unlock_server(server);
842
        return 0;
843
}
844
#endif  /* CONFIG_NCPFS_IOCTL_LOCKING */
845
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.