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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [fs/] [ncpfs/] [ioctl.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 *  ioctl.c
3
 *
4
 *  Copyright (C) 1995, 1996 by Volker Lendecke
5
 *
6
 */
7
 
8
#include <linux/config.h>
9
 
10
#include <asm/segment.h>
11
#include <linux/errno.h>
12
#include <linux/fs.h>
13
#include <linux/ncp_fs.h>
14
#include <linux/ioctl.h>
15
#include <linux/sched.h>
16
#include <linux/mm.h>
17
#include <linux/ncp.h>
18
#include "ncplib_kernel.h"
19
 
20
int
21
ncp_ioctl (struct inode * inode, struct file * filp,
22
           unsigned int cmd, unsigned long arg)
23
{
24
        int result;
25
        struct ncp_ioctl_request request;
26
        struct ncp_fs_info info;
27
        struct ncp_server *server = NCP_SERVER(inode);
28
 
29
        /*
30
         * Binary compatible with 1.3.XX releases.
31
         * Take this out in 2.1.0 development series.
32
         * <mec@duracef.shout.net> 12 Mar 1996
33
         */
34
        switch(cmd) {
35
        case _IOR('n', 1, unsigned char *):
36
            cmd = NCP_IOC_NCPREQUEST;
37
            break;
38
        case _IOR('u', 1, uid_t):
39
            cmd = NCP_IOC_GETMOUNTUID;
40
            break;
41
        case _IO('l', 1):
42
            cmd = NCP_IOC_CONN_LOGGED_IN;
43
            break;
44
        case _IOWR('i', 1, unsigned char *):
45
            cmd = NCP_IOC_GET_FS_INFO;
46
            break;
47
        }
48
 
49
        switch(cmd) {
50
        case NCP_IOC_NCPREQUEST:
51
 
52
                if (   (permission(inode, MAY_WRITE) != 0)
53
                    && (current->uid != server->m.mounted_uid))
54
                {
55
                        return -EACCES;
56
                }
57
 
58
                if ((result = verify_area(VERIFY_READ, (char *)arg,
59
                                          sizeof(request))) != 0)
60
                {
61
                        return result;
62
                }
63
 
64
                memcpy_fromfs(&request, (struct ncp_ioctl_request *)arg,
65
                              sizeof(request));
66
 
67
                if (   (request.function > 255)
68
                    || (request.size >
69
                        NCP_PACKET_SIZE - sizeof(struct ncp_request_header)))
70
                {
71
                        return -EINVAL;
72
                }
73
 
74
                if ((result = verify_area(VERIFY_WRITE, (char *)request.data,
75
                                          NCP_PACKET_SIZE)) != 0)
76
                {
77
                        return result;
78
                }
79
 
80
                ncp_lock_server(server);
81
 
82
                /* FIXME: We hack around in the server's structures
83
                   here to be able to use ncp_request */
84
 
85
                server->has_subfunction = 0;
86
                server->current_size = request.size;
87
                memcpy_fromfs(server->packet, request.data, request.size);
88
 
89
                ncp_request(server, request.function);
90
 
91
                DPRINTK("ncp_ioctl: copy %d bytes\n",
92
                        server->reply_size);
93
                memcpy_tofs(request.data, server->packet, server->reply_size);
94
 
95
                ncp_unlock_server(server);
96
 
97
                return server->reply_size;
98
 
99
        case NCP_IOC_CONN_LOGGED_IN:
100
 
101
                if (   (permission(inode, MAY_WRITE) != 0)
102
                    && (current->uid != server->m.mounted_uid))
103
                {
104
                        return -EACCES;
105
                }
106
 
107
                return ncp_conn_logged_in(server);
108
 
109
        case NCP_IOC_GET_FS_INFO:
110
 
111
                if (   (permission(inode, MAY_WRITE) != 0)
112
                    && (current->uid != server->m.mounted_uid))
113
                {
114
                        return -EACCES;
115
                }
116
 
117
                if ((result = verify_area(VERIFY_WRITE, (char *)arg,
118
                                          sizeof(info))) != 0)
119
                {
120
                        return result;
121
                }
122
 
123
                memcpy_fromfs(&info, (struct ncp_fs_info *)arg,
124
                              sizeof(info));
125
 
126
                if (info.version != NCP_GET_FS_INFO_VERSION)
127
                {
128
                        DPRINTK("info.version invalid: %d\n", info.version);
129
                        return -EINVAL;
130
                }
131
 
132
                info.addr          = server->m.serv_addr;
133
                info.mounted_uid   = server->m.mounted_uid;
134
                info.connection    = server->connection;
135
                info.buffer_size   = server->buffer_size;
136
                info.volume_number = NCP_ISTRUCT(inode)->volNumber;
137
                info.directory_id  = NCP_ISTRUCT(inode)->DosDirNum;
138
 
139
                memcpy_tofs((struct ncp_fs_info *)arg, &info, sizeof(info));
140
                return 0;
141
 
142
        case NCP_IOC_GETMOUNTUID:
143
 
144
                if (   (permission(inode, MAY_READ) != 0)
145
                    && (current->uid != server->m.mounted_uid))
146
                {
147
                        return -EACCES;
148
                }
149
 
150
                if ((result = verify_area(VERIFY_WRITE, (uid_t*) arg,
151
                                          sizeof(uid_t))) != 0)
152
                {
153
                        return result;
154
                }
155
                put_fs_word(server->m.mounted_uid, (uid_t*) arg);
156
                return 0;
157
 
158
#if 0
159
        case NCP_IOC_GETMOUNTUID_INT:
160
                if (   (permission(inode, MAY_READ) != 0)
161
                    && (current->uid != server->m.mounted_uid))
162
                {
163
                        return -EACCES;
164
                }
165
 
166
                if ((result = verify_area(VERIFY_WRITE, (unsigned int*)arg,
167
                                        sizeof(unsigned int))) != 0)
168
                {
169
                        return result;
170
                }
171
                {
172
                        unsigned int tmp=server->m.mounted_uid;
173
                        put_fs_long(tmp, (unsigned int*) arg);
174
                }
175
                return 0;
176
#endif
177
 
178
#ifdef CONFIG_NCPFS_MOUNT_SUBDIR
179
        case NCP_IOC_GETROOT:
180
                {
181
                        struct ncp_setroot_ioctl sr;
182
 
183
                        if (   (permission(inode, MAY_READ) != 0)
184
                            && (current->uid != server->m.mounted_uid))
185
                        {
186
                                return -EACCES;
187
                        }
188
                        if (server->m.mounted_vol[0]) {
189
                                sr.volNumber = server->root.finfo.i.volNumber;
190
                                sr.dirEntNum = server->root.finfo.i.dirEntNum;
191
                                sr.namespace = server->name_space[sr.volNumber];
192
                        } else {
193
                                sr.volNumber = -1;
194
                                sr.namespace = 0;
195
                                sr.dirEntNum = 0;
196
                        }
197
                        if ((result = verify_area(VERIFY_WRITE,
198
                                                  (struct ncp_setroot_ioctl*)arg,
199
                                                  sizeof(sr))) != 0)
200
                        {
201
                                return result;
202
                        }
203
                        memcpy_tofs((struct ncp_setroot_ioctl*)arg,
204
                                    &sr, sizeof(sr));
205
                        return 0;
206
                }
207
        case NCP_IOC_SETROOT:
208
                {
209
                        struct ncp_setroot_ioctl sr;
210
 
211
                        if (   (permission(inode, MAY_WRITE) != 0)
212
                            && (current->uid != server->m.mounted_uid))
213
                        {
214
                                return -EACCES;
215
                        }
216
                        if ((result = verify_area(VERIFY_READ,
217
                                                  (struct ncp_setroot_ioctl*)arg,
218
                                                  sizeof(sr))) != 0)
219
                        {
220
                                return result;
221
                        }
222
                        memcpy_fromfs(&sr, (struct ncp_setroot_ioctl*)arg, sizeof(sr));
223
                        if (sr.volNumber < 0) {
224
                                server->m.mounted_vol[0] = 0;
225
                                server->root.finfo.i.volNumber = 0;
226
                                server->root.finfo.i.dirEntNum = 0;
227
                        } else if (sr.volNumber >= NCP_NUMBER_OF_VOLUMES) {
228
                                return -EINVAL;
229
                        } else {
230
                                if (ncp_mount_subdir(server, sr.volNumber, sr.namespace, sr.dirEntNum)) {
231
                                        return -ENOENT;
232
                                }
233
                        }
234
                        return 0;
235
                }
236
#endif  /* CONFIG_NCPFS_MOUNT_SUBDIR */
237
 
238
#ifdef CONFIG_NCPFS_PACKET_SIGNING      
239
        case NCP_IOC_SIGN_INIT:
240
                if ((permission(inode, MAY_WRITE) != 0)
241
                    && (current->uid != server->m.mounted_uid))
242
                {
243
                        return -EACCES;
244
                }
245
                if ((result = verify_area(VERIFY_READ, (struct ncp_sign_init*)arg,
246
                                          sizeof(struct ncp_sign_init))) != 0)
247
                {
248
                        return result;
249
                }
250
                if (server->sign_active)
251
                {
252
                        return -EINVAL;
253
                }
254
                if (server->sign_wanted)
255
                {
256
                        struct ncp_sign_init sign;
257
 
258
                        memcpy_fromfs(&sign, (struct ncp_sign_init *) arg,
259
                              sizeof(sign));
260
                        memcpy(server->sign_root,sign.sign_root,8);
261
                        memcpy(server->sign_last,sign.sign_last,16);
262
                        server->sign_active = 1;
263
                }
264
                /* ignore when signatures not wanted */
265
                return 0;
266
 
267
        case NCP_IOC_SIGN_WANTED:
268
                if (   (permission(inode, MAY_READ) != 0)
269
                    && (current->uid != server->m.mounted_uid))
270
                {
271
                        return -EACCES;
272
                }
273
                if ((result = verify_area(VERIFY_WRITE, (int*) arg,
274
                                          sizeof(int))) != 0)
275
                {
276
                        return result;
277
                }
278
                /* Should not it be put_fs_long? Vandrove@vc.cvut.cz */
279
                put_fs_word(server->sign_wanted, (int*) arg);
280
                return 0;
281
 
282
        case NCP_IOC_SET_SIGN_WANTED:
283
                {
284
                        int newstate;
285
 
286
                        if (   (permission(inode, MAY_WRITE) != 0)
287
                            && (current->uid != server->m.mounted_uid))
288
                        {
289
                                return -EACCES;
290
                        }
291
                        if ((result = verify_area(VERIFY_READ, (int*) arg,
292
                                                  sizeof(int))) != 0)
293
                        {
294
                                return result;
295
                        }
296
                        /* get only low 8 bits... */
297
                        newstate = get_fs_byte((unsigned char*)arg);
298
                        if (server->sign_active) {
299
                                /* cannot turn signatures OFF when active */
300
                                if (!newstate) return -EINVAL;
301
                        } else {
302
                                server->sign_wanted = newstate != 0;
303
                        }
304
                        return 0;
305
                }
306
 
307
#endif /* CONFIG_NCPFS_PACKET_SIGNING */
308
 
309
#ifdef CONFIG_NCPFS_IOCTL_LOCKING
310
        case NCP_IOC_LOCKUNLOCK:
311
                if (   (permission(inode, MAY_WRITE) != 0)
312
                    && (current->uid != server->m.mounted_uid))
313
                {
314
                        return -EACCES;
315
                }
316
                {
317
                        struct ncp_lock_ioctl    rqdata;
318
                        struct nw_file_info     *finfo;
319
                        int result;
320
 
321
                        if ((result = verify_area(VERIFY_READ,
322
                                        (struct ncp_lock_ioctl*)arg,
323
                                        sizeof(rqdata))) != 0)
324
                        {
325
                                return result;
326
                        }
327
                        memcpy_fromfs(&rqdata, (struct ncp_lock_ioctl*)arg,
328
                                sizeof(rqdata));
329
                        if (rqdata.origin != 0)
330
                                return -EINVAL;
331
                        /* check for cmd */
332
                        switch (rqdata.cmd) {
333
                                case NCP_LOCK_EX:
334
                                case NCP_LOCK_SH:
335
                                                if (rqdata.timeout == 0)
336
                                                        rqdata.timeout = NCP_LOCK_DEFAULT_TIMEOUT;
337
                                                else if (rqdata.timeout > NCP_LOCK_MAX_TIMEOUT)
338
                                                        rqdata.timeout = NCP_LOCK_MAX_TIMEOUT;
339
                                                break;
340
                                case NCP_LOCK_LOG:
341
                                                rqdata.timeout = NCP_LOCK_DEFAULT_TIMEOUT;      /* has no effect */
342
                                case NCP_LOCK_CLEAR:
343
                                                break;
344
                                default:
345
                                                return -EINVAL;
346
                        }
347
                        if ((result = ncp_make_open(inode, O_RDWR)) != 0)
348
                        {
349
                                return result;
350
                        }
351
                        if (!ncp_conn_valid(server))
352
                        {
353
                                return -EIO;
354
                        }
355
                        if (!S_ISREG(inode->i_mode))
356
                        {
357
                                return -EISDIR;
358
                        }
359
                        finfo=NCP_FINFO(inode);
360
                        if (!finfo->opened)
361
                        {
362
                                return -EBADFD;
363
                        }
364
                        if (rqdata.cmd == NCP_LOCK_CLEAR)
365
                        {
366
                                result = ncp_ClearPhysicalRecord(NCP_SERVER(inode),
367
                                                        finfo->file_handle,
368
                                                        rqdata.offset,
369
                                                        rqdata.length);
370
                                if (result > 0) result = 0;       /* no such lock */
371
                        }
372
                        else
373
                        {
374
                                int lockcmd;
375
 
376
                                switch (rqdata.cmd)
377
                                {
378
                                        case NCP_LOCK_EX:  lockcmd=1; break;
379
                                        case NCP_LOCK_SH:  lockcmd=3; break;
380
                                        default:           lockcmd=0; break;
381
                                }
382
                                result = ncp_LogPhysicalRecord(NCP_SERVER(inode),
383
                                                        finfo->file_handle,
384
                                                        lockcmd,
385
                                                        rqdata.offset,
386
                                                        rqdata.length,
387
                                                        rqdata.timeout);
388
                                if (result > 0) result = -EAGAIN;
389
                        }
390
                        return result;
391
                }
392
#endif  /* CONFIG_NCPFS_IOCTL_LOCKING */
393
 
394
        default:
395
                return -EINVAL;
396
        }
397
 
398
        return -EINVAL;
399
}

powered by: WebSVN 2.1.0

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