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 | } |