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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [libfs/] [src/] [dosfs/] [msdos_eval.c] - Blame information for rev 1771

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
2
 *  MSDOS evaluation routines
3
 *
4
 *  Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
5
 *  Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
6
 *
7
 *  The license and distribution terms for this file may be
8
 *  found in the file LICENSE in this distribution or at
9
 *  http://www.OARcorp.com/rtems/license.html.
10
 *
11
 *  @(#) msdos_eval.c,v 1.1 2002/02/28 20:43:50 joel Exp
12
 */
13
 
14
#if HAVE_CONFIG_H
15
#include "config.h"
16
#endif
17
 
18
#include <sys/types.h>
19
#include <sys/stat.h>
20
#include <fcntl.h>
21
#include <unistd.h>
22
#include <errno.h>
23
#include <stdlib.h>
24
#include <assert.h>
25
 
26
#include <rtems/libio_.h>
27
 
28
#include "fat.h"
29
#include "fat_fat_operations.h"
30
#include "fat_file.h"
31
 
32
#include "msdos.h"
33
 
34
/* msdos_set_handlers --
35
 *     Set handlers for the node with specified type(i.e. handlers for file
36
 *     or directory).
37
 *
38
 * PARAMETERS:
39
 *     loc - node description
40
 *
41
 * RETURNS:
42
 *     None
43
 */
44
static void
45
msdos_set_handlers(rtems_filesystem_location_info_t *loc)
46
{
47
    msdos_fs_info_t *fs_info = loc->mt_entry->fs_info;
48
    fat_file_fd_t   *fat_fd = loc->node_access;
49
 
50
    if (fat_fd->fat_file_type == FAT_DIRECTORY)
51
        loc->handlers = fs_info->directory_handlers;
52
    else
53
        loc->handlers = fs_info->file_handlers;
54
}
55
 
56
/* msdos_eval_path --
57
 *
58
 *     The following routine evaluate path for a node that wishes to be
59
 *     accessed.  Structure 'pathloc' is returned with a pointer to the
60
 *     node to be accessed.
61
 *
62
 * PARAMETERS:
63
 *     pathname - path for evaluation
64
 *     flags    - flags
65
 *     pathloc  - node description (IN/OUT)
66
 *
67
 * RETURNS:
68
 *     RC_OK and filled pathloc on success, or -1 if error occured
69
 *     (errno set appropriately)
70
 *
71
 */
72
int
73
msdos_eval_path(
74
    const char                        *pathname,
75
    int                                flags,
76
    rtems_filesystem_location_info_t  *pathloc
77
    )
78
{
79
    int                               rc = RC_OK;
80
    rtems_status_code                 sc = RTEMS_SUCCESSFUL;
81
    msdos_fs_info_t                  *fs_info = pathloc->mt_entry->fs_info;
82
    fat_file_fd_t                    *fat_fd = NULL;
83
    rtems_filesystem_location_info_t  newloc;
84
    int                               i = 0;
85
    int                               len = 0;
86
    msdos_token_types_t               type = MSDOS_CURRENT_DIR;
87
    char                              token[MSDOS_NAME_MAX + 1];
88
 
89
    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
90
                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
91
    if (sc != RTEMS_SUCCESSFUL)
92
        set_errno_and_return_minus_one(EIO);
93
 
94
    if (!pathloc->node_access)
95
    {
96
        errno = ENOENT;
97
        rc = -1;
98
        goto err;
99
    }
100
 
101
    fat_fd = pathloc->node_access;
102
 
103
    rc = fat_file_reopen(fat_fd);
104
    if (rc != RC_OK)
105
        goto err;
106
 
107
    while ((type != MSDOS_NO_MORE_PATH) && (type != MSDOS_INVALID_TOKEN))
108
    {
109
        type = msdos_get_token(&pathname[i], token, &len);
110
        i += len;
111
 
112
        fat_fd = pathloc->node_access;
113
 
114
        switch (type)
115
        {
116
            case MSDOS_UP_DIR:
117
                /*
118
                 *  Only a directory can be decended into.
119
                 */
120
                if (fat_fd->fat_file_type != FAT_DIRECTORY)
121
                {
122
                    errno = ENOTDIR;
123
                    rc = -1;
124
                    goto error;
125
                }
126
 
127
                /*
128
                 *  Am I at the root of this mounted filesystem?
129
                 */
130
                if (pathloc->node_access ==
131
                    pathloc->mt_entry->mt_fs_root.node_access)
132
                {
133
                    /*
134
                     *  Am I at the root of all filesystems?
135
                     *  XXX: MSDOS is not supposed to be base fs.
136
                     */
137
                    if (pathloc->node_access ==
138
                        rtems_filesystem_root.node_access)
139
                    {
140
                        break;       /* Throw out the .. in this case */
141
                    }
142
                    else
143
                    {
144
                        newloc = pathloc->mt_entry->mt_point_node;
145
                        *pathloc = newloc;
146
 
147
                        rc = fat_file_close(pathloc->mt_entry, fat_fd);
148
                        if (rc != RC_OK)
149
                            goto err;
150
 
151
                        rtems_semaphore_release(fs_info->vol_sema);
152
                        return (*pathloc->ops->evalpath_h)(&(pathname[i-len]),
153
                                                           flags, pathloc);
154
                    }
155
                }
156
                else
157
                {
158
                    rc = msdos_find_name(pathloc, token);
159
                    if (rc != RC_OK)
160
                    {
161
                        if (rc == MSDOS_NAME_NOT_FOUND_ERR)
162
                        {
163
                            errno = ENOENT;
164
                            rc = -1;
165
                        }
166
                        goto error;
167
                    }
168
                }
169
                break;
170
 
171
            case MSDOS_NAME:
172
                /*
173
                 *  Only a directory can be decended into.
174
                 */
175
                if (fat_fd->fat_file_type != FAT_DIRECTORY)
176
                {
177
                    errno = ENOTDIR;
178
                    rc = -1;
179
                    goto error;
180
                }
181
 
182
                /*
183
                 *  Otherwise find the token name in the present location and
184
                 * set the node access to the point we have found.
185
                 */
186
                rc = msdos_find_name(pathloc, token);
187
                if (rc != RC_OK)
188
                {
189
                    if (rc == MSDOS_NAME_NOT_FOUND_ERR)
190
                    {
191
                        errno = ENOENT;
192
                        rc = -1;
193
                    }
194
                    goto error;
195
                }
196
                break;
197
 
198
            case MSDOS_NO_MORE_PATH:
199
            case MSDOS_CURRENT_DIR:
200
                break;
201
 
202
            case MSDOS_INVALID_TOKEN:
203
                errno = ENAMETOOLONG;
204
                rc = -1;
205
                goto error;
206
                break;
207
 
208
        }
209
    }
210
 
211
    /*
212
     *  Always return the root node.
213
     *
214
     *  If we are at a node that is a mount point. Set loc to the
215
     *  new fs root node and let let the mounted filesystem set the handlers.
216
     *
217
     *  NOTE: The behavior of stat() on a mount point appears to be
218
     *        questionable.
219
     *  NOTE: MSDOS filesystem currently doesn't support mount functionality ->
220
     *        action not implemented
221
     */
222
    fat_fd = pathloc->node_access;
223
 
224
    msdos_set_handlers(pathloc);
225
 
226
    rtems_semaphore_release(fs_info->vol_sema);
227
    return RC_OK;
228
 
229
error:
230
    fat_file_close(pathloc->mt_entry, fat_fd);
231
 
232
err:
233
    rtems_semaphore_release(fs_info->vol_sema);
234
    return rc;
235
}
236
 
237
/* msdos_eval4make --
238
 *     The following routine evaluate path for a new node to be created.
239
 *     'pathloc' is returned with a pointer to the parent of the new node.
240
 *     'name' is returned with a pointer to the first character in the
241
 *     new node name.  The parent node is verified to be a directory.
242
 *
243
 * PARAMETERS:
244
 *     path    - path for evaluation
245
 *     pathloc - IN/OUT (start point for evaluation/parent directory for
246
 *               creation)
247
 *     name    - new node name
248
 *
249
 * RETURNS:
250
 *     RC_OK, filled pathloc for parent directory and name of new node on
251
 *     success, or -1 if error occured (errno set appropriately)
252
 */
253
int
254
msdos_eval4make(
255
    const char                         *path,
256
    rtems_filesystem_location_info_t   *pathloc,
257
    const char                        **name
258
    )
259
{
260
    int                               rc = RC_OK;
261
    rtems_status_code                 sc = RTEMS_SUCCESSFUL;
262
    msdos_fs_info_t                  *fs_info = pathloc->mt_entry->fs_info;
263
    fat_file_fd_t                    *fat_fd = NULL;
264
    rtems_filesystem_location_info_t  newloc;
265
    msdos_token_types_t               type;
266
    int                               i = 0;
267
    int                               len;
268
    char                              token[ MSDOS_NAME_MAX + 1 ];
269
    rtems_boolean                     done = 0;
270
 
271
    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
272
                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
273
    if (sc != RTEMS_SUCCESSFUL)
274
        set_errno_and_return_minus_one(EIO);
275
 
276
    if (!pathloc->node_access)
277
    {
278
        errno = ENOENT;
279
        rc = -1;
280
        goto err;
281
    }
282
 
283
    fat_fd = pathloc->node_access;
284
 
285
    rc = fat_file_reopen(fat_fd);
286
    if (rc != RC_OK)
287
        goto err;
288
 
289
    while (!done)
290
    {
291
        type = msdos_get_token(&path[i], token, &len);
292
        i += len;
293
        fat_fd = pathloc->node_access;
294
 
295
        switch (type)
296
        {
297
            case MSDOS_UP_DIR:
298
                /*
299
                 *  Only a directory can be decended into.
300
                 */
301
                if (fat_fd->fat_file_type != FAT_DIRECTORY)
302
                {
303
                    errno = ENOTDIR;
304
                    rc = -1;
305
                    goto error;
306
                }
307
 
308
                /*
309
                 *  Am I at the root of this mounted filesystem?
310
                 */
311
                if (pathloc->node_access ==
312
                    pathloc->mt_entry->mt_fs_root.node_access)
313
                {
314
                    /*
315
                     *  Am I at the root of all filesystems?
316
                     *  XXX: MSDOS is not supposed to be base fs.
317
                     */
318
                    if (pathloc->node_access ==
319
                        rtems_filesystem_root.node_access)
320
                    {
321
                        break;       /* Throw out the .. in this case */
322
                    }
323
                    else
324
                    {
325
                        newloc = pathloc->mt_entry->mt_point_node;
326
                        *pathloc = newloc;
327
 
328
                        rc = fat_file_close(pathloc->mt_entry, fat_fd);
329
                        if (rc != RC_OK)
330
                            goto err;
331
 
332
                        rtems_semaphore_release(fs_info->vol_sema);
333
                        return (*pathloc->ops->evalformake_h)(&path[i-len],
334
                                                              pathloc, name);
335
                    }
336
                }
337
                else
338
                {
339
                    rc = msdos_find_name(pathloc, token);
340
                    if (rc != RC_OK)
341
                    {
342
                        if (rc == MSDOS_NAME_NOT_FOUND_ERR)
343
                        {
344
                            errno = ENOENT;
345
                            rc = -1;
346
                        }
347
                        goto error;
348
                    }
349
                }
350
                break;
351
 
352
            case MSDOS_NAME:
353
                /*
354
                 *  Only a directory can be decended into.
355
                 */
356
                if (fat_fd->fat_file_type != FAT_DIRECTORY)
357
                {
358
                    errno = ENOTDIR;
359
                    rc = -1;
360
                    goto error;
361
                }
362
 
363
                /*
364
                 *  Otherwise find the token name in the present location and
365
                 * set the node access to the point we have found.
366
                 */
367
                rc = msdos_find_name(pathloc, token);
368
                if (rc)
369
                {
370
                    if (rc != MSDOS_NAME_NOT_FOUND_ERR)
371
                    {
372
                        errno = ENOENT;
373
                        rc = -1;
374
                        goto error;
375
                    }
376
                    else
377
                        done = TRUE;
378
                }
379
                break;
380
 
381
            case MSDOS_NO_MORE_PATH:
382
                errno = EEXIST;
383
                rc = -1;
384
                goto error;
385
                break;
386
 
387
            case MSDOS_CURRENT_DIR:
388
                break;
389
 
390
            case MSDOS_INVALID_TOKEN:
391
                errno = ENAMETOOLONG;
392
                rc = -1;
393
                goto error;
394
                break;
395
 
396
        }
397
    }
398
 
399
    *name = &path[i - len];
400
 
401
    /*
402
     * We have evaluated the path as far as we can.
403
     * Verify there is not any invalid stuff at the end of the name.
404
     */
405
    for( ; path[i] != '\0'; i++)
406
    {
407
        if (!msdos_is_separator(path[i]))
408
        {
409
            errno = ENOENT;
410
            rc = -1;
411
            goto error;
412
        }
413
    }
414
 
415
    fat_fd = pathloc->node_access;
416
 
417
    if (fat_fd->fat_file_type != FAT_DIRECTORY)
418
    {
419
        errno = ENOTDIR;
420
        rc = -1;
421
        goto error;
422
    }
423
 
424
    msdos_set_handlers(pathloc);
425
 
426
    rtems_semaphore_release(fs_info->vol_sema);
427
    return RC_OK;
428
 
429
error:
430
    fat_file_close(pathloc->mt_entry, fat_fd);
431
 
432
err:
433
    rtems_semaphore_release(fs_info->vol_sema);
434
    return rc;
435
}

powered by: WebSVN 2.1.0

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