diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-01-19 17:51:33 +0100 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-01-19 17:51:33 +0100 |
commit | 1a4af498b497bfe1acb40d8aff0c65d9b22b3aa5 (patch) | |
tree | be88b633cf30bc168cc22afedec57114bc3d410d /lib | |
parent | 84bd62267760fd02db895e21c5c2c8bf20162342 (diff) |
Add a helper function to unpack directory index entries
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sqfs/inode.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/sqfs/inode.c b/lib/sqfs/inode.c index bb1ccef..3a4ec09 100644 --- a/lib/sqfs/inode.c +++ b/lib/sqfs/inode.c @@ -9,10 +9,13 @@ #include "sqfs/inode.h" #include "sqfs/error.h" +#include "sqfs/dir.h" #include <string.h> #include <stdlib.h> +#include "util.h" + static int inverse_type[] = { [SQFS_INODE_DIR] = SQFS_INODE_EXT_DIR, [SQFS_INODE_FILE] = SQFS_INODE_EXT_FILE, @@ -386,3 +389,44 @@ int sqfs_inode_get_file_block_start(const sqfs_inode_generic_t *inode, return 0; } + +int sqfs_inode_unpack_dir_index_entry(const sqfs_inode_generic_t *inode, + sqfs_dir_index_t **out, + size_t index) +{ + sqfs_dir_index_t ent; + size_t offset; + char *ptr; + + if (inode->base.type != SQFS_INODE_EXT_DIR) { + if (inode->base.type == SQFS_INODE_DIR) + return SQFS_ERROR_OUT_OF_BOUNDS; + + return SQFS_ERROR_NOT_DIR; + } + + offset = 0; + ptr = (char *)inode->extra; + + for (;;) { + if (offset >= inode->num_dir_idx_bytes) + return SQFS_ERROR_OUT_OF_BOUNDS; + + if (index == 0) + break; + + memcpy(&ent, ptr + offset, sizeof(ent)); + offset += sizeof(ent) + ent.size + 1; + index -= 1; + } + + memcpy(&ent, ptr + offset, sizeof(ent)); + + *out = alloc_flex(sizeof(ent), 1, ent.size + 2); + if (*out == NULL) + return SQFS_ERROR_ALLOC; + + memcpy(*out, &ent, sizeof(ent)); + memcpy((*out)->name, ptr + offset + sizeof(ent), ent.size + 1); + return 0; +} |