Subversion Repositories HelenOS

Rev

Rev 2751 | Rev 2753 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2751 Rev 2752
Line 47... Line 47...
47
#include "vfs.h"
47
#include "vfs.h"
48
 
48
 
49
#define min(a, b)   ((a) < (b) ? (a) : (b))
49
#define min(a, b)   ((a) < (b) ? (a) : (b))
50
 
50
 
51
/* Forward static declarations. */
51
/* Forward static declarations. */
52
static char *canonify(char *path);
52
static char *canonify(char *path, size_t *lenp);
53
 
53
 
54
atomic_t plb_futex = FUTEX_INITIALIZER;
54
atomic_t plb_futex = FUTEX_INITIALIZER;
55
link_t plb_head;    /**< PLB entry ring buffer. */
55
link_t plb_head;    /**< PLB entry ring buffer. */
56
uint8_t *plb = NULL;
56
uint8_t *plb = NULL;
57
 
57
 
58
/** Perform a path lookup.
58
/** Perform a path lookup.
59
 *
59
 *
60
 * @param path      Path to be resolved; it needn't be an ASCIIZ string.
60
 * @param path      Path to be resolved; it must be a NULL-terminated
61
 * @param len       Number of path characters pointed by path.
61
 *          string.
62
 * @param lflag     Flags to be used during lookup.
62
 * @param lflag     Flags to be used during lookup.
63
 * @param result    Empty structure where the lookup result will be stored.
63
 * @param result    Empty structure where the lookup result will be stored.
64
 *          Can be NULL.
64
 *          Can be NULL.
65
 * @param altroot   If non-empty, will be used instead of rootfs as the root
65
 * @param altroot   If non-empty, will be used instead of rootfs as the root
66
 *          of the whole VFS tree.
66
 *          of the whole VFS tree.
67
 *
67
 *
68
 * @return      EOK on success or an error code from errno.h.
68
 * @return      EOK on success or an error code from errno.h.
69
 */
69
 */
70
int vfs_lookup_internal(char *path, size_t len, int lflag,
70
int vfs_lookup_internal(char *path, int lflag, vfs_lookup_res_t *result,
71
    vfs_lookup_res_t *result, vfs_pair_t *altroot)
71
    vfs_pair_t *altroot)
72
{
72
{
73
    vfs_pair_t *root;
73
    vfs_pair_t *root;
74
 
74
 
75
    if (!len)
-
 
76
        return EINVAL;
-
 
77
 
-
 
78
    if (altroot)
75
    if (altroot)
79
        root = altroot;
76
        root = altroot;
80
    else
77
    else
81
        root = (vfs_pair_t *) &rootfs;
78
        root = (vfs_pair_t *) &rootfs;
82
 
79
 
83
    if (!root->fs_handle)
80
    if (!root->fs_handle)
84
        return ENOENT;
81
        return ENOENT;
85
   
82
   
-
 
83
    size_t len;
-
 
84
    path = canonify(path, &len);
-
 
85
    if (!path)
-
 
86
        return EINVAL;
-
 
87
   
86
    futex_down(&plb_futex);
88
    futex_down(&plb_futex);
87
 
89
 
88
    plb_entry_t entry;
90
    plb_entry_t entry;
89
    link_initialize(&entry.plb_link);
91
    link_initialize(&entry.plb_link);
90
    entry.len = len;
92
    entry.len = len;
Line 271... Line 273...
271
{
273
{
272
    *tlcomp = *t;
274
    *tlcomp = *t;
273
}
275
}
274
static void terminate_slash(token_t *t, token_t *tfsl, token_t *tlcomp)
276
static void terminate_slash(token_t *t, token_t *tfsl, token_t *tlcomp)
275
{
277
{
-
 
278
    if (tfsl->stop[1])  /* avoid writing to a well-formatted path */
276
    tfsl->stop[1] = '\0';
279
        tfsl->stop[1] = '\0';
277
}
280
}
278
static void remove_trailing_slash(token_t *t, token_t *tfsl, token_t *tlcomp)
281
static void remove_trailing_slash(token_t *t, token_t *tfsl, token_t *tlcomp)
279
{
282
{
280
    t->start[-1] = '\0';
283
    t->start[-1] = '\0';
281
}
284
}
Line 432... Line 435...
432
 * 5) there is no '..' component in the path (i.e. /a/b/../c is not canonical)
435
 * 5) there is no '..' component in the path (i.e. /a/b/../c is not canonical)
433
 *
436
 *
434
 * This function makes a potentially non-canonical file system path canonical.
437
 * This function makes a potentially non-canonical file system path canonical.
435
 * It works in-place and requires a NULL-terminated input string.
438
 * It works in-place and requires a NULL-terminated input string.
436
 *
439
 *
437
 * @param       Path to be canonified.
440
 * @param path      Path to be canonified.
-
 
441
 * @param lenp      Pointer where the length of the final path will be
-
 
442
 *          stored. Can be NULL.
438
 *
443
 *
439
 * @return      Canonified path or NULL on failure.
444
 * @return      Canonified path or NULL on failure.
440
 */
445
 */
441
char *canonify(char *path)
446
char *canonify(char *path, size_t *lenp)
442
{
447
{
443
    state_t state;
448
    state_t state;
444
    token_t t;
449
    token_t t;
445
    token_t tfsl;       /* first slash */
450
    token_t tfsl;       /* first slash */
446
    token_t tlcomp;     /* last component */
451
    token_t tlcomp;     /* last component */
Line 448... Line 453...
448
        return NULL;
453
        return NULL;
449
    tfsl = slash_token(path);
454
    tfsl = slash_token(path);
450
restart:
455
restart:
451
    state = S_INI;
456
    state = S_INI;
452
    t = tfsl;
457
    t = tfsl;
-
 
458
    tlcomp = tfsl;
453
    while (state != S_ACCEPT && state != S_RESTART && state != S_REJECT) {
459
    while (state != S_ACCEPT && state != S_RESTART && state != S_REJECT) {
454
        if (trans[state][t.kind].f)
460
        if (trans[state][t.kind].f)
455
            trans[state][t.kind].f(&t, &tfsl, &tlcomp);
461
            trans[state][t.kind].f(&t, &tfsl, &tlcomp);
456
        state = trans[state][t.kind].s;
462
        state = trans[state][t.kind].s;
457
        t = next_token(&t);
463
        t = next_token(&t);
Line 461... Line 467...
461
    case S_RESTART:
467
    case S_RESTART:
462
        goto restart;
468
        goto restart;
463
    case S_REJECT:
469
    case S_REJECT:
464
        return NULL;
470
        return NULL;
465
    case S_ACCEPT:
471
    case S_ACCEPT:
-
 
472
        if (lenp)
-
 
473
            *lenp = (size_t)((tlcomp.stop - tfsl.start) + 1);
466
        return tfsl.start;
474
        return tfsl.start;
467
    default:
475
    default:
468
        abort();
476
        abort();
469
    }
477
    }
470
}
478
}