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