aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-09-16 02:03:51 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-09-19 11:45:53 +0200
commit73ad00f9a414a13d8970d27296f52e774ff6954e (patch)
treef19285ecf4ba7a36ceee9672652d74fccf1b4706
parent2d01fe534a775dcab61651ef807fc118c579dd3d (diff)
Fix example code to use iterator/stream based API
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--Makefile.am2
-rw-r--r--extras/browse.c226
-rw-r--r--extras/extract_one.c145
-rw-r--r--extras/list_files.c160
4 files changed, 322 insertions, 211 deletions
diff --git a/Makefile.am b/Makefile.am
index ab960c5..141973e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -40,7 +40,7 @@ include bin/sqfs2tar/Makemodule.am
include bin/sqfsdiff/Makemodule.am
include bin/tar2sqfs/Makemodule.am
-#include extras/Makemodule.am
+include extras/Makemodule.am
if HAVE_DOXYGEN
@DX_RULES@
diff --git a/extras/browse.c b/extras/browse.c
index a608021..22bdfb1 100644
--- a/extras/browse.c
+++ b/extras/browse.c
@@ -9,9 +9,9 @@
#include "sqfs/dir_reader.h"
#include "sqfs/id_table.h"
#include "sqfs/inode.h"
+#include "sqfs/block.h"
#include "sqfs/super.h"
#include "sqfs/error.h"
-#include "sqfs/block.h"
#include "sqfs/dir.h"
#include "sqfs/io.h"
#include "compat.h"
@@ -27,35 +27,79 @@
static sqfs_dir_reader_t *dr;
static sqfs_super_t super;
-static sqfs_inode_generic_t *working_dir;
static sqfs_id_table_t *idtbl;
static sqfs_data_reader_t *data;
+static sqfs_u64 working_dir;
-/*****************************************************************************/
-
-static void change_directory(const char *dirname)
+static int resolve_ref(const char *path, sqfs_u64 *out)
{
+ sqfs_dir_reader_state_t state;
sqfs_inode_generic_t *inode;
+ sqfs_dir_node_t *ent;
+ const char *end;
+ sqfs_u64 ref;
+ size_t len;
int ret;
- if (dirname == NULL || *dirname == '/') {
- free(working_dir);
- working_dir = NULL;
+ ref = *path == '/' ? super.root_inode_ref : working_dir;
+
+ while (path != NULL && *path != '\0') {
+ if (*path == '/') {
+ while (*path == '/')
+ ++path;
+ continue;
+ }
+
+ end = strchr(path, '/');
+ len = (end == NULL) ? strlen(path) : (size_t)(end - path);
- sqfs_dir_reader_get_root_inode(dr, &working_dir);
+ ret = sqfs_dir_reader_get_inode(dr, ref, &inode);
+ if (ret != 0)
+ return ret;
+
+ ret = sqfs_dir_reader_open_dir(dr, inode, &state, 0);
+ sqfs_free(inode);
+
+ if (ret != 0)
+ return ret;
+
+ do {
+ ret = sqfs_dir_reader_read(dr, &state, &ent);
+ if (ret < 0)
+ return ret;
+ if (ret > 0)
+ return 1;
+
+ ret = strncmp((const char *)ent->name, path, len);
+ free(ent);
+ if (ret == 0 && ent->name[len] != '\0')
+ return 1;
+ } while (ret != 0);
+
+ ref = state.ent_ref;
+ path = end;
}
- if (dirname != NULL) {
- ret = sqfs_dir_reader_find_by_path(dr, working_dir,
- dirname, &inode);
- if (ret != 0) {
- printf("Error resolving '%s', error code %d\n",
- dirname, ret);
- return;
- }
+ *out = ref;
+ return 0;
+}
- free(working_dir);
- working_dir = inode;
+/*****************************************************************************/
+
+static void change_directory(const char *dirname)
+{
+ int ret;
+
+ if (dirname == NULL) {
+ working_dir = super.root_inode_ref;
+ return;
+ }
+
+ ret = resolve_ref(dirname, &working_dir);
+ if (ret < 0) {
+ fprintf(stderr, "%s: error resolving path: %d\n", dirname, ret);
+ } else if (ret > 0) {
+ fprintf(stderr, "%s: no such file or directory\n", dirname);
}
}
@@ -63,50 +107,42 @@ static void change_directory(const char *dirname)
static void list_directory(const char *dirname)
{
- sqfs_inode_generic_t *root, *inode;
+ sqfs_dir_reader_state_t state, init_state;
size_t i, max_len, len, col_count;
+ sqfs_inode_generic_t *inode;
sqfs_dir_node_t *ent;
+ sqfs_u64 ref;
int ret;
/* Get the directory inode we want to dump and open the directory */
if (dirname == NULL) {
- ret = sqfs_dir_reader_open_dir(dr, working_dir, 0);
- if (ret)
- goto fail_open;
- } else if (*dirname == '/') {
- sqfs_dir_reader_get_root_inode(dr, &root);
-
- ret = sqfs_dir_reader_find_by_path(dr, root, dirname, &inode);
- sqfs_free(root);
- if (ret)
- goto fail_resolve;
-
- ret = sqfs_dir_reader_open_dir(dr, inode, 0);
- sqfs_free(inode);
- if (ret)
- goto fail_open;
+ ref = working_dir;
} else {
- ret = sqfs_dir_reader_find_by_path(dr, working_dir,
- dirname, &inode);
- if (ret)
+ ret = resolve_ref(dirname, &ref);
+ if (ret < 0)
goto fail_resolve;
-
- ret = sqfs_dir_reader_open_dir(dr, inode, 0);
- sqfs_free(inode);
- if (ret)
- goto fail_open;
+ if (ret > 0)
+ goto fail_no_ent;
}
+ ret = sqfs_dir_reader_get_inode(dr, ref, &inode);
+ if (ret)
+ goto fail_open;
+
+ ret = sqfs_dir_reader_open_dir(dr, inode, &state, 0);
+ sqfs_free(inode);
+ if (ret)
+ goto fail_open;
+
/* first pass over the directory to figure out column count/length */
+ init_state = state;
+
for (max_len = 0; ; max_len = len > max_len ? len : max_len) {
- ret = sqfs_dir_reader_read(dr, &ent);
+ ret = sqfs_dir_reader_read(dr, &state, &ent);
if (ret > 0)
break;
-
- if (ret < 0) {
- fputs("Error while reading directory list\n", stderr);
- break;
- }
+ if (ret < 0)
+ goto fail_read;
len = ent->size + 1;
sqfs_free(ent);
@@ -116,18 +152,15 @@ static void list_directory(const char *dirname)
col_count = col_count < 1 ? 1 : col_count;
i = 0;
- /* second pass for printing directory contents */
- sqfs_dir_reader_rewind(dr);
+ state = init_state;
+ /* second pass for printing directory contents */
for (;;) {
- ret = sqfs_dir_reader_read(dr, &ent);
+ ret = sqfs_dir_reader_read(dr, &state, &ent);
if (ret > 0)
break;
-
- if (ret < 0) {
- fputs("Error while reading directory list\n", stderr);
- break;
- }
+ if (ret < 0)
+ goto fail_read;
/* entries always use basic types only */
switch (ent->type) {
@@ -174,12 +207,18 @@ static void list_directory(const char *dirname)
fputc('\n', stdout);
return;
+fail_read:
+ fputs("Error while reading directory list\n", stderr);
+ return;
fail_open:
printf("Error opening '%s', error code %d\n", dirname, ret);
return;
fail_resolve:
printf("Error resolving '%s', error code %d\n", dirname, ret);
return;
+fail_no_ent:
+ fprintf(stderr, "%s: no such file or directory\n", dirname);
+ return;
}
/*****************************************************************************/
@@ -221,13 +260,14 @@ static void mode_to_str(sqfs_u16 mode, char *p)
static void stat_cmd(const char *filename)
{
- sqfs_inode_generic_t *inode, *root;
+ sqfs_inode_generic_t *inode;
sqfs_dir_index_t *idx;
sqfs_u32 uid, gid;
const char *type;
char buffer[64];
time_t timeval;
struct tm *tm;
+ sqfs_u64 ref;
size_t i;
int ret;
@@ -237,18 +277,13 @@ static void stat_cmd(const char *filename)
return;
}
- if (*filename == '/') {
- sqfs_dir_reader_get_root_inode(dr, &root);
- ret = sqfs_dir_reader_find_by_path(dr, root, filename, &inode);
- sqfs_free(root);
- if (ret)
- goto fail_resolve;
- } else {
- ret = sqfs_dir_reader_find_by_path(dr, working_dir,
- filename, &inode);
- if (ret)
- goto fail_resolve;
- }
+ ret = resolve_ref(filename, &ref);
+ if (ret)
+ goto fail_resolve;
+
+ ret = sqfs_dir_reader_get_inode(dr, ref, &inode);
+ if (ret)
+ goto fail_resolve;
/* some basic information */
switch (inode->base.type) {
@@ -431,10 +466,10 @@ fail_resolve:
static void cat_cmd(const char *filename)
{
- sqfs_inode_generic_t *inode, *root;
- sqfs_u64 offset = 0;
+ sqfs_inode_generic_t *inode;
+ sqfs_istream_t *stream;
char buffer[512];
- sqfs_s32 diff;
+ sqfs_u64 ref;
int ret;
/* get the inode of the file */
@@ -443,17 +478,23 @@ static void cat_cmd(const char *filename)
return;
}
- if (*filename == '/') {
- sqfs_dir_reader_get_root_inode(dr, &root);
- ret = sqfs_dir_reader_find_by_path(dr, root, filename, &inode);
- sqfs_free(root);
- } else {
- ret = sqfs_dir_reader_find_by_path(dr, working_dir,
- filename, &inode);
+ ret = resolve_ref(filename, &ref);
+ if (ret) {
+ printf("Error resolving '%s', error code %d\n", filename, ret);
+ return;
}
+ ret = sqfs_dir_reader_get_inode(dr, ref, &inode);
if (ret) {
- printf("Error resolving '%s', error code %d\n", filename, ret);
+ printf("Error reading inode for '%s', error code %d\n",
+ filename, ret);
+ return;
+ }
+
+ ret = sqfs_data_reader_create_stream(data, inode, filename, &stream);
+ sqfs_free(inode);
+ if (ret) {
+ printf("Opening file '%s', error code %d\n", filename, ret);
return;
}
@@ -462,21 +503,19 @@ static void cat_cmd(const char *filename)
* or fragment access.
*/
for (;;) {
- diff = sqfs_data_reader_read(data, inode, offset, buffer,
- sizeof(buffer));
- if (diff == 0)
+ ret = sqfs_istream_read(stream, buffer, sizeof(buffer));
+ if (ret == 0)
break;
- if (diff < 0) {
+ if (ret < 0) {
printf("Error reading from file '%s', error code %d\n",
- filename, diff);
+ filename, ret);
break;
}
- fwrite(buffer, 1, diff, stdout);
- offset += diff;
+ fwrite(buffer, 1, ret, stdout);
}
- sqfs_free(inode);
+ sqfs_drop(stream);
}
/*****************************************************************************/
@@ -518,6 +557,8 @@ int main(int argc, char **argv)
goto out_fd;
}
+ working_dir = super.root_inode_ref;
+
sqfs_compressor_config_init(&cfg, super.compression_id,
super.block_size,
SQFS_COMP_FLAG_UNCOMPRESS);
@@ -550,11 +591,6 @@ int main(int argc, char **argv)
goto out_id;
}
- if (sqfs_dir_reader_get_root_inode(dr, &working_dir)) {
- fprintf(stderr, "%s: error reading root inode.\n", argv[1]);
- goto out_dir;
- }
-
/* create a data reader */
data = sqfs_data_reader_create(file, super.block_size, cmp, 0);
@@ -613,8 +649,6 @@ int main(int argc, char **argv)
out:
sqfs_drop(data);
out_dir:
- if (working_dir != NULL)
- free(working_dir);
sqfs_drop(dr);
out_id:
sqfs_drop(idtbl);
diff --git a/extras/extract_one.c b/extras/extract_one.c
index d0fe1b9..d0dbafd 100644
--- a/extras/extract_one.c
+++ b/extras/extract_one.c
@@ -8,35 +8,82 @@
#include "sqfs/compressor.h"
#include "sqfs/data_reader.h"
#include "sqfs/dir_reader.h"
+#include "sqfs/dir_entry.h"
#include "sqfs/error.h"
#include "sqfs/id_table.h"
#include "sqfs/io.h"
#include "sqfs/inode.h"
#include "sqfs/super.h"
-#include "sqfs/xattr_reader.h"
#include <string.h>
#include <stdlib.h>
-#include <errno.h>
#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
+
+static int find_file(sqfs_dir_iterator_t *it, const char *path,
+ sqfs_istream_t **out)
+{
+ const char *end = strchr(path, '/');
+ size_t len = end == NULL ? strlen(path) : (size_t)(end - path);
+
+ for (;;) {
+ sqfs_dir_entry_t *ent;
+ int ret;
+
+ ret = it->next(it, &ent);
+ if (ret < 0) {
+ fputs("error reading directory entry\n", stderr);
+ return -1;
+ }
+
+ if (ret > 0) {
+ fputs("entry not found\n", stderr);
+ return -1;
+ }
+
+ if (strncmp(ent->name, path, len) != 0 ||
+ ent->name[len] != '\0') {
+ free(ent);
+ continue;
+ }
+
+ if (end == NULL) {
+ ret = it->open_file_ro(it, out);
+ if (ret) {
+ fprintf(stderr, "%s: error opening file %d\n",
+ ent->name, ret);
+ }
+ } else {
+ sqfs_dir_iterator_t *sub;
+
+ ret = it->open_subdir(it, &sub);
+ if (ret != 0) {
+ fprintf(stderr, "%s: error opening subdir\n",
+ ent->name);
+ } else {
+ ret = find_file(sub, end + 1, out);
+ sqfs_drop(sub);
+ }
+ }
+
+ free(ent);
+ return ret;
+ }
+}
int main(int argc, char **argv)
{
- sqfs_xattr_reader_t *xattr = NULL;
+ sqfs_inode_generic_t *iroot = NULL;
sqfs_data_reader_t *data = NULL;
sqfs_dir_reader_t *dirrd = NULL;
sqfs_compressor_t *cmp = NULL;
sqfs_id_table_t *idtbl = NULL;
- sqfs_tree_node_t *n = NULL;
sqfs_file_t *file = NULL;
- sqfs_u8 *p, *output = NULL;
+ sqfs_dir_iterator_t *it = NULL;
sqfs_compressor_config_t cfg;
sqfs_super_t super;
- sqfs_u64 file_size;
int status = EXIT_FAILURE, ret;
+ sqfs_istream_t *is = NULL;
+ char buffer[512];
if (argc != 3) {
fputs("Usage: extract_one <squashfs-file> <source-file-path>\n", stderr);
@@ -56,8 +103,8 @@ int main(int argc, char **argv)
}
sqfs_compressor_config_init(&cfg, super.compression_id,
- super.block_size,
- SQFS_COMP_FLAG_UNCOMPRESS);
+ super.block_size,
+ SQFS_COMP_FLAG_UNCOMPRESS);
ret = sqfs_compressor_create(&cfg, &cmp);
if (ret != 0) {
@@ -65,20 +112,6 @@ int main(int argc, char **argv)
goto out;
}
- if (!(super.flags & SQFS_FLAG_NO_XATTRS)) {
- xattr = sqfs_xattr_reader_create(0);
- if (xattr == NULL) {
- fprintf(stderr, "%s: error creating xattr reader: %d.\n", argv[1], SQFS_ERROR_ALLOC);
- goto out;
- }
-
- ret = sqfs_xattr_reader_load(xattr, &super, file, cmp);
- if (ret) {
- fprintf(stderr, "%s: error loading xattr reader: %d.\n", argv[1], ret);
- goto out;
- }
- }
-
idtbl = sqfs_id_table_create(0);
if (idtbl == NULL) {
fprintf(stderr, "%s: error creating ID table: %d.\n", argv[1], ret);
@@ -109,69 +142,43 @@ int main(int argc, char **argv)
goto out;
}
- ret = sqfs_dir_reader_get_full_hierarchy(dirrd, idtbl, argv[2], 0, &n);
- if (ret) {
- fprintf(stderr, "%s: error reading filesystem hierarchy: %d.\n", argv[1], ret);
+ if (sqfs_dir_reader_get_root_inode(dirrd, &iroot)) {
+ fprintf(stderr, "%s: error reading root inode.\n", argv[1]);
goto out;
}
- if (!S_ISREG(n->inode->base.mode)) {
- fprintf(stderr, "/%s is not a file\n", argv[2]);
- goto out;
- }
-
- sqfs_inode_get_file_size(n->inode, &file_size);
+ ret = sqfs_dir_iterator_create(dirrd, idtbl, data, NULL, iroot, &it);
+ free(iroot);
- output = p = malloc(file_size);
- if (output == NULL) {
- fprintf(stderr, "malloc failed: %d\n", errno);
+ if (ret) {
+ fprintf(stderr, "%s: error creating root iterator.\n",
+ argv[2]);
goto out;
}
- for (size_t i = 0; i < sqfs_inode_get_file_block_count(n->inode); ++i) {
- size_t chunk_size, read = (file_size < super.block_size) ? file_size : super.block_size;
- sqfs_u8 *chunk;
-
- ret = sqfs_data_reader_get_block(data, n->inode, i, &chunk_size, &chunk);
- if (ret) {
- fprintf(stderr, "reading data block: %d\n", ret);
- goto out;
- }
-
- memcpy(p, chunk, chunk_size);
- p += chunk_size;
- free(chunk);
-
- file_size -= read;
- }
-
- if (file_size > 0) {
- size_t chunk_size;
- sqfs_u8 *chunk;
+ if (find_file(it, argv[2], &is))
+ goto out;
- ret = sqfs_data_reader_get_fragment(data, n->inode, &chunk_size, &chunk);
- if (ret) {
- fprintf(stderr, "reading fragment block: %d\n", ret);
+ for (;;) {
+ ret = sqfs_istream_read(is, buffer, sizeof(buffer));
+ if (ret < 0) {
+ fprintf(stderr, "%s: read error!\n", argv[2]);
goto out;
}
+ if (ret == 0)
+ break;
- memcpy(p, chunk, chunk_size);
- free(chunk);
+ fwrite(buffer, 1, ret, stdout);
}
- /* for example simplicity, assume this is a text file */
- fprintf(stdout, "%s\n", (char *)output);
-
status = EXIT_SUCCESS;
out:
- sqfs_dir_tree_destroy(n);
+ sqfs_drop(is);
+ sqfs_drop(it);
sqfs_drop(data);
sqfs_drop(dirrd);
sqfs_drop(idtbl);
- sqfs_drop(xattr);
sqfs_drop(cmp);
sqfs_drop(file);
- free(output);
-
return status;
}
diff --git a/extras/list_files.c b/extras/list_files.c
index 89a1f30..55b94e2 100644
--- a/extras/list_files.c
+++ b/extras/list_files.c
@@ -6,6 +6,7 @@
*/
#include "sqfs/compressor.h"
#include "sqfs/dir_reader.h"
+#include "sqfs/dir_entry.h"
#include "sqfs/id_table.h"
#include "sqfs/inode.h"
#include "sqfs/super.h"
@@ -16,52 +17,114 @@
#include <errno.h>
#include <stdio.h>
-static void write_tree_dfs(const sqfs_tree_node_t *n)
+static int count_entries(sqfs_dir_iterator_t *it, unsigned int *out)
{
- const sqfs_tree_node_t *p;
- unsigned int mask, level;
- int i;
-
- for (n = n->children; n != NULL; n = n->next) {
- level = 0;
- mask = 0;
-
- for (p = n->parent; p->parent != NULL; p = p->parent) {
- if (p->next != NULL)
- mask |= 1 << level;
- ++level;
+ sqfs_dir_entry_t *ent;
+ int ret;
+
+ *out = 0;
+
+ for (;;) {
+ ret = it->next(it, &ent);
+ if (ret < 0) {
+ *out = 0;
+ return -1;
}
+ if (ret > 0)
+ break;
- for (i = level - 1; i >= 0; --i)
+ *out += 1;
+ free(ent);
+ }
+
+ return 0;
+}
+
+static void write_tree_dfs(sqfs_dir_iterator_t *it,
+ unsigned int mask, unsigned int level,
+ unsigned int count)
+{
+ sqfs_dir_entry_t *ent;
+ unsigned int i;
+ sqfs_u16 type;
+
+ while (count--) {
+ for (i = 0; i < level; ++i)
fputs(mask & (1 << i) ? "│ " : " ", stdout);
- fputs(n->next == NULL ? "└─ " : "├─ ", stdout);
- fputs((const char *)n->name, stdout);
-
- if (n->inode->base.type == SQFS_INODE_SLINK) {
- printf(" ⭢ %.*s",
- (int)n->inode->data.slink.target_size,
- (const char *)n->inode->extra);
- } else if (n->inode->base.type == SQFS_INODE_EXT_SLINK) {
- printf(" ⭢ %.*s",
- (int)n->inode->data.slink_ext.target_size,
- (const char *)n->inode->extra);
+ if (it->next(it, &ent) != 0)
+ break;
+
+ fputs(count == 0 ? "└─ " : "├─ ", stdout);
+ fputs(ent->name, stdout);
+
+ type = ent->mode & SQFS_INODE_MODE_MASK;
+ free(ent);
+
+ if (type == SQFS_INODE_MODE_LNK) {
+ char *target;
+
+ if (it->read_link(it, &target) == 0)
+ printf(" ⭢ %s", target);
+
+ free(target);
}
fputc('\n', stdout);
- write_tree_dfs(n);
+
+ if (type == SQFS_INODE_MODE_DIR) {
+ sqfs_dir_iterator_t *sub;
+ unsigned int sub_count;
+
+ it->open_subdir(it, &sub);
+ count_entries(sub, &sub_count);
+ sub = sqfs_drop(sub);
+
+ it->open_subdir(it, &sub);
+ write_tree_dfs(sub,
+ mask | (count > 0 ? (1 << level) : 0),
+ level + 1, sub_count);
+ sqfs_drop(sub);
+ }
}
}
+static sqfs_dir_iterator_t *create_root_iterator(sqfs_dir_reader_t *dr,
+ sqfs_id_table_t *idtbl,
+ const char *filename)
+{
+ sqfs_inode_generic_t *iroot;
+ sqfs_dir_iterator_t *it;
+ int ret;
+
+ if (sqfs_dir_reader_get_root_inode(dr, &iroot)) {
+ fprintf(stderr, "%s: error reading root inode.\n",
+ filename);
+ return NULL;
+ }
+
+ ret = sqfs_dir_iterator_create(dr, idtbl, NULL, NULL, iroot, &it);
+ free(iroot);
+
+ if (ret) {
+ fprintf(stderr, "%s: error creating root iterator.\n",
+ filename);
+ return NULL;
+ }
+
+ return it;
+}
+
int main(int argc, char **argv)
{
int ret, status = EXIT_FAILURE;
+ sqfs_dir_iterator_t *it = NULL;
+ sqfs_compressor_t *cmp = NULL;
+ sqfs_id_table_t *idtbl = NULL;
+ sqfs_dir_reader_t *dr = NULL;
sqfs_compressor_config_t cfg;
- sqfs_compressor_t *cmp;
- sqfs_tree_node_t *root = NULL;
- sqfs_id_table_t *idtbl;
- sqfs_dir_reader_t *dr;
- sqfs_file_t *file;
+ sqfs_file_t *file = NULL;
+ unsigned int root_count;
sqfs_super_t super;
/* open the SquashFS file we want to read */
@@ -79,7 +142,7 @@ int main(int argc, char **argv)
process the compressor options */
if (sqfs_super_read(&super, file)) {
fprintf(stderr, "%s: error reading super block.\n", argv[1]);
- goto out_fd;
+ goto out;
}
sqfs_compressor_config_init(&cfg, super.compression_id,
@@ -90,50 +153,57 @@ int main(int argc, char **argv)
if (ret != 0) {
fprintf(stderr, "%s: error creating compressor: %d.\n",
argv[1], ret);
- goto out_fd;
+ goto out;
}
/* Create and read the UID/GID mapping table */
idtbl = sqfs_id_table_create(0);
if (idtbl == NULL) {
fputs("Error creating ID table.\n", stderr);
- goto out_cmp;
+ goto out;
}
if (sqfs_id_table_read(idtbl, file, &super, cmp)) {
fprintf(stderr, "%s: error loading ID table.\n", argv[1]);
- goto out_id;
+ goto out;
}
- /* create a directory reader and scan the entire directory hiearchy */
+ /* create a directory reader */
dr = sqfs_dir_reader_create(&super, cmp, file, 0);
if (dr == NULL) {
fprintf(stderr, "%s: error creating directory reader.\n",
argv[1]);
- goto out_id;
+ goto out;
}
- if (sqfs_dir_reader_get_full_hierarchy(dr, idtbl, NULL, 0, &root)) {
- fprintf(stderr, "%s: error loading directory tree.\n",
+ /* create a directory iterator for the root inode */
+ it = create_root_iterator(dr, idtbl, argv[1]);
+ if (it == NULL)
+ goto out;
+
+ if (count_entries(it, &root_count)) {
+ fprintf(stderr, "%s: error counting root iterator entries.\n",
argv[1]);
goto out;
}
+ it = sqfs_drop(it);
+
+ it = create_root_iterator(dr, idtbl, argv[1]);
+ if (it == NULL)
+ goto out;
+
/* fancy print the hierarchy */
printf("/\n");
- write_tree_dfs(root);
+ write_tree_dfs(it, 0, 0, root_count);
/* cleanup */
status = EXIT_SUCCESS;
out:
- if (root != NULL)
- sqfs_dir_tree_destroy(root);
+ sqfs_drop(it);
sqfs_drop(dr);
-out_id:
sqfs_drop(idtbl);
-out_cmp:
sqfs_drop(cmp);
-out_fd:
sqfs_drop(file);
return status;
}