diff options
Diffstat (limited to 'firmware/common/dircache.c')
-rw-r--r-- | firmware/common/dircache.c | 89 |
1 files changed, 26 insertions, 63 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index c5062d47ed..41564194d0 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c | |||
@@ -2488,81 +2488,44 @@ struct get_path_sub_data | |||
2488 | 2488 | ||
2489 | static ssize_t get_path_sub(int idx, struct get_path_sub_data *data) | 2489 | static ssize_t get_path_sub(int idx, struct get_path_sub_data *data) |
2490 | { | 2490 | { |
2491 | |||
2492 | #ifdef HAVE_MULTIVOLUME | ||
2493 | #define NAMEBUFLEN (MAX(VOL_MAX_LEN+1, MAX_TINYNAME+1)) | ||
2494 | #else | ||
2495 | #define NAMEBUFLEN (MAX_TINYNAME+1) | ||
2496 | #endif | ||
2497 | char namebuf[NAMEBUFLEN]; | ||
2498 | #undef NAMEBUFLEN | ||
2499 | |||
2500 | if (idx == 0) | 2491 | if (idx == 0) |
2501 | return -1; /* entry is an orphan split from any root */ | 2492 | return -1; /* entry is an orphan split from any root */ |
2502 | 2493 | ||
2503 | char *cename = ""; | 2494 | ssize_t len; |
2504 | size_t cename_len = (-1u); | 2495 | char *cename; |
2505 | ssize_t len = 0; | ||
2506 | int next_idx = idx; | ||
2507 | int count = 1; /* +1 for the idx incoming */ | ||
2508 | int remain; | ||
2509 | 2496 | ||
2510 | do /* go all the way up to the root */ | 2497 | if (idx > 0) |
2511 | { | 2498 | { |
2512 | count++; | 2499 | struct dircache_entry *ce = get_entry(idx); |
2513 | if (next_idx > (int)dircache.numentries) | ||
2514 | return -1; /* ERROR! */ | ||
2515 | next_idx = dircache_runinfo.pentry[next_idx].up; | ||
2516 | } while (next_idx > 0); | ||
2517 | 2500 | ||
2518 | if (next_idx < 0) /* root */ | 2501 | data->serialhash = dc_hash_serialnum(ce->serialnum, data->serialhash); |
2519 | { | ||
2520 | data->serialhash = dc_hash_serialnum(get_idx_dcvolp(next_idx)->serialnum, | ||
2521 | data->serialhash); | ||
2522 | #ifdef HAVE_MULTIVOLUME | ||
2523 | /* prepend the volume specifier */ | ||
2524 | cename = namebuf; | ||
2525 | get_volume_name(IF_MV_VOL(-next_idx - 1), cename); | ||
2526 | #endif /* HAVE_MULTIVOLUME */ | ||
2527 | } | ||
2528 | 2502 | ||
2529 | /* we have the volume name write it to the buffer */ | 2503 | /* go all the way up then move back down from the root */ |
2530 | goto write_path_component; | 2504 | len = get_path_sub(ce->up, data) - 1; |
2531 | /* if not MULTIVOLUME it will just be adding '/' */ | 2505 | if (len < 0) |
2506 | return -2; | ||
2532 | 2507 | ||
2533 | while (next_idx > 0 && count > 0) | 2508 | cename = alloca(DC_MAX_NAME + 1); |
2509 | entry_name_copy(cename, ce); | ||
2510 | } | ||
2511 | else /* idx < 0 */ | ||
2534 | { | 2512 | { |
2535 | struct dircache_entry *ce = &dircache_runinfo.pentry[next_idx]; | 2513 | len = 0; |
2536 | if (remain <= 0) | 2514 | cename = ""; |
2537 | { | ||
2538 | data->serialhash = dc_hash_serialnum(ce->serialnum, data->serialhash); | ||
2539 | if (LIKELY(!ce->tinyname)) | ||
2540 | { | ||
2541 | cename = get_name(ce->name); | ||
2542 | cename_len = CE_NAMESIZE(ce->namelen); | ||
2543 | } | ||
2544 | else | ||
2545 | { | ||
2546 | cename = namebuf; | ||
2547 | entry_name_copy(cename, ce); | ||
2548 | cename_len = -1u; | ||
2549 | } | ||
2550 | write_path_component: | ||
2551 | len += path_append_ex(data->buf + len, PA_SEP_HARD, -1u, cename, cename_len, | ||
2552 | data->size > (size_t)len ? data->size - len : 0); | ||
2553 | 2515 | ||
2554 | count--; | 2516 | #ifdef HAVE_MULTIVOLUME |
2555 | remain = count - 1; | 2517 | /* prepend the volume specifier */ |
2556 | next_idx = idx; | 2518 | int volume = IF_MV_VOL(-idx - 1); |
2557 | } | 2519 | cename = alloca(VOL_MAX_LEN+1); |
2558 | else | 2520 | get_volume_name(volume, cename); |
2559 | { | 2521 | #endif /* HAVE_MULTIVOLUME */ |
2560 | remain--; | ||
2561 | next_idx = ce->up; | ||
2562 | } | ||
2563 | 2522 | ||
2523 | data->serialhash = dc_hash_serialnum(get_idx_dcvolp(idx)->serialnum, | ||
2524 | data->serialhash); | ||
2564 | } | 2525 | } |
2565 | return len; | 2526 | |
2527 | return len + path_append(data->buf + len, PA_SEP_HARD, cename, | ||
2528 | data->size > (size_t)len ? data->size - len : 0); | ||
2566 | } | 2529 | } |
2567 | 2530 | ||
2568 | /** | 2531 | /** |