diff options
-rw-r--r-- | include/sqfs/dir_reader.h | 10 | ||||
-rw-r--r-- | lib/common/src/read_tree.c | 24 | ||||
-rw-r--r-- | lib/sqfs/src/dir_reader.c | 56 |
3 files changed, 45 insertions, 45 deletions
diff --git a/include/sqfs/dir_reader.h b/include/sqfs/dir_reader.h index 0f1f231..1c95e30 100644 --- a/include/sqfs/dir_reader.h +++ b/include/sqfs/dir_reader.h @@ -204,6 +204,7 @@ SQFS_API sqfs_dir_reader_t *sqfs_dir_reader_create(const sqfs_super_t *super, */ SQFS_API int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd, const sqfs_inode_generic_t *inode, + sqfs_dir_reader_state_t *state, sqfs_u32 flags); /** @@ -217,9 +218,6 @@ SQFS_API int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd, * because the end of the listing was reached. A negative value indicates an * error. * - * After calling this function, you can use @ref sqfs_dir_reader_get_inode to - * read the full inode structure that the current entry referes to. - * * @param rd A pointer to a directory reader. * @param out Returns a pointer to a directory entry on success that can be * freed with a single @ref sqfs_free call. @@ -228,20 +226,22 @@ SQFS_API int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd, * number if the end of the current directory listing has been reached. */ SQFS_API int sqfs_dir_reader_read(sqfs_dir_reader_t *rd, + sqfs_dir_reader_state_t *state, sqfs_dir_node_t **out); /** - * @brief Read the inode that the current directory entry points to. + * @brief Resolve and deserialize an inode using an inode reference * * @memberof sqfs_dir_reader_t * * @param rd A pointer to a directory reader. + * @param ref An inode reference. * @param out Returns a pointer to a generic inode that can be freed with a * single @ref sqfs_free call. * * @return Zero on success, an @ref SQFS_ERROR value on failure. */ -SQFS_API int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd, +SQFS_API int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd, sqfs_u64 ref, sqfs_inode_generic_t **inode); /** diff --git a/lib/common/src/read_tree.c b/lib/common/src/read_tree.c index 5d089e5..2879ff4 100644 --- a/lib/common/src/read_tree.c +++ b/lib/common/src/read_tree.c @@ -63,6 +63,7 @@ static sqfs_tree_node_t *create_node(sqfs_inode_generic_t *inode, } static int fill_dir(sqfs_dir_reader_t *dr, sqfs_tree_node_t *root, + sqfs_dir_reader_state_t *state, unsigned int flags) { sqfs_tree_node_t *n, *prev, **tail; @@ -73,7 +74,7 @@ static int fill_dir(sqfs_dir_reader_t *dr, sqfs_tree_node_t *root, tail = &root->children; for (;;) { - err = sqfs_dir_reader_read(dr, &ent); + err = sqfs_dir_reader_read(dr, state, &ent); if (err > 0) break; if (err < 0) @@ -84,7 +85,7 @@ static int fill_dir(sqfs_dir_reader_t *dr, sqfs_tree_node_t *root, continue; } - err = sqfs_dir_reader_get_inode(dr, &inode); + err = sqfs_dir_reader_get_inode(dr, state->ent_ref, &inode); if (err) { free(ent); return err; @@ -115,13 +116,16 @@ static int fill_dir(sqfs_dir_reader_t *dr, sqfs_tree_node_t *root, while (n != NULL) { if (n->inode->base.type == SQFS_INODE_DIR || n->inode->base.type == SQFS_INODE_EXT_DIR) { + sqfs_dir_reader_state_t nstate; + if (!(flags & SQFS_TREE_NO_RECURSE)) { err = sqfs_dir_reader_open_dir(dr, n->inode, + &nstate, SQFS_DIR_OPEN_NO_DOT_ENTRIES); if (err) return err; - err = fill_dir(dr, n, flags); + err = fill_dir(dr, n, &nstate, flags); if (err) return err; } @@ -192,13 +196,15 @@ int sqfs_dir_reader_get_full_hierarchy(sqfs_dir_reader_t *rd, inode = NULL; while (path != NULL && *path != '\0') { + sqfs_dir_reader_state_t state; + if (*path == '/') { while (*path == '/') ++path; continue; } - ret = sqfs_dir_reader_open_dir(rd, tail->inode, + ret = sqfs_dir_reader_open_dir(rd, tail->inode, &state, SQFS_DIR_OPEN_NO_DOT_ENTRIES); if (ret) goto fail; @@ -206,7 +212,7 @@ int sqfs_dir_reader_get_full_hierarchy(sqfs_dir_reader_t *rd, ptr = strchrnul(path, '/'); for (;;) { - ret = sqfs_dir_reader_read(rd, &ent); + ret = sqfs_dir_reader_read(rd, &state, &ent); if (ret < 0) goto fail; if (ret > 0) { @@ -221,7 +227,7 @@ int sqfs_dir_reader_get_full_hierarchy(sqfs_dir_reader_t *rd, free(ent); } - ret = sqfs_dir_reader_get_inode(rd, &inode); + ret = sqfs_dir_reader_get_inode(rd, state.ent_ref, &inode); if (ret) { free(ent); goto fail; @@ -251,12 +257,14 @@ int sqfs_dir_reader_get_full_hierarchy(sqfs_dir_reader_t *rd, if (tail->inode->base.type == SQFS_INODE_DIR || tail->inode->base.type == SQFS_INODE_EXT_DIR) { - ret = sqfs_dir_reader_open_dir(rd, tail->inode, + sqfs_dir_reader_state_t state; + + ret = sqfs_dir_reader_open_dir(rd, tail->inode, &state, SQFS_DIR_OPEN_NO_DOT_ENTRIES); if (ret) goto fail; - ret = fill_dir(rd, tail, flags); + ret = fill_dir(rd, tail, &state, flags); if (ret) goto fail; } diff --git a/lib/sqfs/src/dir_reader.c b/lib/sqfs/src/dir_reader.c index c904f35..2b6d0e8 100644 --- a/lib/sqfs/src/dir_reader.c +++ b/lib/sqfs/src/dir_reader.c @@ -36,8 +36,6 @@ struct sqfs_dir_reader_t { sqfs_u32 flags; rbtree_t dcache; - - sqfs_dir_reader_state_t state; }; static int dcache_key_compare(const void *ctx, const void *l, const void *r) @@ -189,6 +187,7 @@ fail_dcache: int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd, const sqfs_inode_generic_t *inode, + sqfs_dir_reader_state_t *state, sqfs_u32 flags) { sqfs_u32 parent; @@ -197,7 +196,9 @@ int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd, if (flags & (~SQFS_DIR_OPEN_ALL_FLAGS)) return SQFS_ERROR_UNSUPPORTED; - ret = sqfs_readdir_state_init(&rd->state.cursor, &rd->super, inode); + memset(state, 0, sizeof(*state)); + + ret = sqfs_readdir_state_init(&state->cursor, &rd->super, inode); if (ret) return ret; @@ -209,21 +210,21 @@ int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd, parent = inode->data.dir.parent_inode; } - if (dcache_find(rd, inode->base.inode_number, &rd->state.cur_ref)) + if (dcache_find(rd, inode->base.inode_number, &state->cur_ref)) return SQFS_ERROR_NO_ENTRY; - if (rd->state.cur_ref == rd->super.root_inode_ref) { - rd->state.parent_ref = rd->state.cur_ref; - } else if (dcache_find(rd, parent, &rd->state.parent_ref)) { + if (state->cur_ref == rd->super.root_inode_ref) { + state->parent_ref = state->cur_ref; + } else if (dcache_find(rd, parent, &state->parent_ref)) { return SQFS_ERROR_NO_ENTRY; } - rd->state.state = DIR_STATE_OPENED; + state->state = DIR_STATE_OPENED; } else { - rd->state.state = DIR_STATE_ENTRIES; + state->state = DIR_STATE_ENTRIES; } - rd->state.start_state = rd->state.state; + state->start_state = state->state; return 0; } @@ -245,23 +246,24 @@ static int mk_dummy_entry(const char *str, sqfs_dir_node_t **out) return 0; } -int sqfs_dir_reader_read(sqfs_dir_reader_t *rd, sqfs_dir_node_t **out) +int sqfs_dir_reader_read(sqfs_dir_reader_t *rd, sqfs_dir_reader_state_t *state, + sqfs_dir_node_t **out) { int err; - switch (rd->state.state) { + switch (state->state) { case DIR_STATE_OPENED: err = mk_dummy_entry(".", out); if (err == 0) { - rd->state.state = DIR_STATE_DOT; - rd->state.ent_ref = rd->state.cur_ref; + state->state = DIR_STATE_DOT; + state->ent_ref = state->cur_ref; } return err; case DIR_STATE_DOT: err = mk_dummy_entry("..", out); if (err == 0) { - rd->state.state = DIR_STATE_ENTRIES; - rd->state.ent_ref = rd->state.parent_ref; + state->state = DIR_STATE_ENTRIES; + state->ent_ref = state->parent_ref; } return err; case DIR_STATE_ENTRIES: @@ -270,35 +272,25 @@ int sqfs_dir_reader_read(sqfs_dir_reader_t *rd, sqfs_dir_node_t **out) return SQFS_ERROR_SEQUENCE; } - return sqfs_meta_reader_readdir(rd->meta_dir, &rd->state.cursor, - out, NULL, &rd->state.ent_ref); + return sqfs_meta_reader_readdir(rd->meta_dir, &state->cursor, + out, NULL, &state->ent_ref); } -int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd, +int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd, sqfs_u64 ref, sqfs_inode_generic_t **inode) { int ret; ret = sqfs_meta_reader_read_inode(rd->meta_inode, &rd->super, - rd->state.ent_ref >> 16, - rd->state.ent_ref & 0x0FFFF, inode); + ref >> 16, ref & 0x0FFFF, inode); if (ret != 0) return ret; - return dcache_add(rd, *inode, rd->state.ent_ref); + return dcache_add(rd, *inode, ref); } int sqfs_dir_reader_get_root_inode(sqfs_dir_reader_t *rd, sqfs_inode_generic_t **inode) { - sqfs_u64 block_start = rd->super.root_inode_ref >> 16; - sqfs_u16 offset = rd->super.root_inode_ref & 0xFFFF; - int ret; - - ret = sqfs_meta_reader_read_inode(rd->meta_inode, &rd->super, - block_start, offset, inode); - if (ret != 0) - return ret; - - return dcache_add(rd, *inode, rd->super.root_inode_ref); + return sqfs_dir_reader_get_inode(rd, rd->super.root_inode_ref, inode); } |