aboutsummaryrefslogtreecommitdiff
path: root/unpack/read_fstree.c
diff options
context:
space:
mode:
Diffstat (limited to 'unpack/read_fstree.c')
-rw-r--r--unpack/read_fstree.c59
1 files changed, 53 insertions, 6 deletions
diff --git a/unpack/read_fstree.c b/unpack/read_fstree.c
index a6903b0..f200243 100644
--- a/unpack/read_fstree.c
+++ b/unpack/read_fstree.c
@@ -2,15 +2,36 @@
#include "unsquashfs.h"
+static int should_skip(int type, int flags)
+{
+ switch (type) {
+ case SQFS_INODE_BDEV:
+ case SQFS_INODE_CDEV:
+ case SQFS_INODE_EXT_CDEV:
+ case SQFS_INODE_EXT_BDEV:
+ return (flags & UNPACK_NO_DEVICES);
+ case SQFS_INODE_SLINK:
+ case SQFS_INODE_EXT_SLINK:
+ return (flags & UNPACK_NO_SLINKS);
+ case SQFS_INODE_SOCKET:
+ case SQFS_INODE_EXT_SOCKET:
+ return(flags & UNPACK_NO_SOCKETS);
+ case SQFS_INODE_FIFO:
+ case SQFS_INODE_EXT_FIFO:
+ return (flags & UNPACK_NO_FIFO);
+ }
+ return 0;
+}
+
static int fill_dir(meta_reader_t *ir, meta_reader_t *dr, tree_node_t *root,
- sqfs_super_t *super, id_table_t *idtbl)
+ sqfs_super_t *super, id_table_t *idtbl, int flags)
{
sqfs_inode_generic_t *inode;
sqfs_dir_header_t hdr;
sqfs_dir_entry_t *ent;
+ tree_node_t *n, *prev;
uint64_t block_start;
size_t size, diff;
- tree_node_t *n;
uint32_t i;
block_start = root->data.dir->start_block;
@@ -35,6 +56,11 @@ static int fill_dir(meta_reader_t *ir, meta_reader_t *dr, tree_node_t *root,
diff = sizeof(*ent) + strlen((char *)ent->name);
size -= diff > size ? size : diff;
+ if (should_skip(ent->type, flags)) {
+ free(ent);
+ continue;
+ }
+
inode = meta_reader_read_inode(ir, super,
hdr.start_block,
ent->offset);
@@ -58,17 +84,38 @@ static int fill_dir(meta_reader_t *ir, meta_reader_t *dr, tree_node_t *root,
}
}
- for (n = root->data.dir->children; n != NULL; n = n->next) {
+ n = root->data.dir->children;
+ prev = NULL;
+
+ while (n != NULL) {
if (S_ISDIR(n->mode)) {
- if (fill_dir(ir, dr, n, super, idtbl))
+ if (fill_dir(ir, dr, n, super, idtbl, flags))
return -1;
+
+ if (n->data.dir->children == NULL &&
+ (flags & UNPACK_NO_EMPTY)) {
+ if (prev == NULL) {
+ root->data.dir->children = n->next;
+ free(n);
+ n = root->data.dir->children;
+ } else {
+ prev->next = n->next;
+ free(n);
+ n = prev->next;
+ }
+ continue;
+ }
}
+
+ prev = n;
+ n = n->next;
}
return 0;
}
-int read_fstree(fstree_t *out, int fd, sqfs_super_t *super, compressor_t *cmp)
+int read_fstree(fstree_t *out, int fd, sqfs_super_t *super, compressor_t *cmp,
+ int flags)
{
sqfs_inode_generic_t *root;
meta_reader_t *ir, *dr;
@@ -119,7 +166,7 @@ int read_fstree(fstree_t *out, int fd, sqfs_super_t *super, compressor_t *cmp)
if (out->root == NULL)
goto out_id;
- if (fill_dir(ir, dr, out->root, super, &idtbl))
+ if (fill_dir(ir, dr, out->root, super, &idtbl, flags))
goto fail_fs;
fstree_sort(out);