diff options
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; +} |