diff options
Diffstat (limited to 'unpack')
-rw-r--r-- | unpack/extract_file.c | 26 | ||||
-rw-r--r-- | unpack/rdsquashfs.c | 62 | ||||
-rw-r--r-- | unpack/rdsquashfs.h | 19 | ||||
-rw-r--r-- | unpack/read_fstree.c | 11 | ||||
-rw-r--r-- | unpack/restore_fstree.c | 23 |
5 files changed, 70 insertions, 71 deletions
diff --git a/unpack/extract_file.c b/unpack/extract_file.c index 0e62f75..4d5997a 100644 --- a/unpack/extract_file.c +++ b/unpack/extract_file.c @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: GPL-3.0-or-later */ #include "rdsquashfs.h" -int extract_file(file_info_t *fi, compressor_t *cmp, size_t block_size, - frag_reader_t *frag, int sqfsfd, int outfd) +int extract_file(file_info_t *fi, unsqfs_info_t *info, int outfd) { void *buffer, *scratch, *ptr; size_t i, count, fragsz; @@ -10,17 +9,17 @@ int extract_file(file_info_t *fi, compressor_t *cmp, size_t block_size, uint32_t bs; ssize_t ret; - buffer = malloc(block_size * 2); + buffer = malloc(info->block_size * 2); if (buffer == NULL) { perror("allocating scratch buffer"); return -1; } - scratch = (char *)buffer + block_size; - count = fi->size / block_size; + scratch = (char *)buffer + info->block_size; + count = fi->size / info->block_size; if (count > 0) { - if (lseek(sqfsfd, fi->startblock, SEEK_SET) == (off_t)-1) + if (lseek(info->sqfsfd, fi->startblock, SEEK_SET) == (off_t)-1) goto fail_seek; for (i = 0; i < count; ++i) { @@ -29,10 +28,10 @@ int extract_file(file_info_t *fi, compressor_t *cmp, size_t block_size, compressed = (bs & (1 << 24)) == 0; bs &= (1 << 24) - 1; - if (bs > block_size) + if (bs > info->block_size) goto fail_bs; - ret = read_retry(sqfsfd, buffer, bs); + ret = read_retry(info->sqfsfd, buffer, bs); if (ret < 0) goto fail_rd; @@ -40,8 +39,9 @@ int extract_file(file_info_t *fi, compressor_t *cmp, size_t block_size, goto fail_trunc; if (compressed) { - ret = cmp->do_block(cmp, buffer, bs, - scratch, block_size); + ret = info->cmp->do_block(info->cmp, buffer, bs, + scratch, + info->block_size); if (ret <= 0) goto fail; @@ -60,11 +60,11 @@ int extract_file(file_info_t *fi, compressor_t *cmp, size_t block_size, } } - fragsz = fi->size % block_size; + fragsz = fi->size % info->block_size; if (fragsz > 0) { - if (frag_reader_read(frag, fi->fragment, fi->fragment_offset, - buffer, fragsz)) { + if (frag_reader_read(info->frag, fi->fragment, + fi->fragment_offset, buffer, fragsz)) { goto fail; } diff --git a/unpack/rdsquashfs.c b/unpack/rdsquashfs.c index 4b3a573..deba5be 100644 --- a/unpack/rdsquashfs.c +++ b/unpack/rdsquashfs.c @@ -112,15 +112,16 @@ static char *get_path(char *old, const char *arg) int main(int argc, char **argv) { - int i, fd, status = EXIT_FAILURE, op = OP_NONE, unpack_flags = 0; + int i, status = EXIT_FAILURE, op = OP_NONE; const char *unpack_root = NULL; - frag_reader_t *frag = NULL; char *cmdpath = NULL; + unsqfs_info_t info; sqfs_super_t super; - compressor_t *cmp; tree_node_t *n; fstree_t fs; + memset(&info, 0, sizeof(info)); + for (;;) { i = getopt_long(argc, argv, short_opts, long_opts, NULL); if (i == -1) @@ -128,25 +129,25 @@ int main(int argc, char **argv) switch (i) { case 'D': - unpack_flags |= UNPACK_NO_DEVICES; + info.flags |= UNPACK_NO_DEVICES; break; case 'S': - unpack_flags |= UNPACK_NO_SOCKETS; + info.flags |= UNPACK_NO_SOCKETS; break; case 'F': - unpack_flags |= UNPACK_NO_FIFO; + info.flags |= UNPACK_NO_FIFO; break; case 'L': - unpack_flags |= UNPACK_NO_SLINKS; + info.flags |= UNPACK_NO_SLINKS; break; case 'C': - unpack_flags |= UNPACK_CHMOD; + info.flags |= UNPACK_CHMOD; break; case 'O': - unpack_flags |= UNPACK_CHOWN; + info.flags |= UNPACK_CHOWN; break; case 'E': - unpack_flags |= UNPACK_NO_EMPTY; + info.flags |= UNPACK_NO_EMPTY; break; case 'c': op = OP_CAT; @@ -186,13 +187,13 @@ int main(int argc, char **argv) goto fail_arg; } - fd = open(argv[optind], O_RDONLY); - if (fd < 0) { + info.sqfsfd = open(argv[optind], O_RDONLY); + if (info.sqfsfd < 0) { perror(argv[optind]); goto out_cmd; } - if (sqfs_super_read(&super, fd)) + if (sqfs_super_read(&super, info.sqfsfd)) goto out_fd; if ((super.version_major != SQFS_VERSION_MAJOR) || @@ -218,13 +219,16 @@ int main(int argc, char **argv) goto out_fd; } - cmp = compressor_create(super.compression_id, false, super.block_size); - if (cmp == NULL) + info.cmp = compressor_create(super.compression_id, false, + super.block_size); + if (info.cmp == NULL) goto out_fd; - if (read_fstree(&fs, fd, &super, cmp, unpack_flags)) + if (read_fstree(&fs, &super, &info)) goto out_cmp; + info.block_size = super.block_size; + switch (op) { case OP_LS: n = find_node(fs.root, cmdpath); @@ -250,15 +254,14 @@ int main(int argc, char **argv) if (super.fragment_entry_count > 0 && super.fragment_table_start < super.bytes_used && !(super.flags & SQFS_FLAG_NO_FRAGMENTS)) { - frag = frag_reader_create(&super, fd, cmp); - if (frag == NULL) + info.frag = frag_reader_create(&super, info.sqfsfd, + info.cmp); + if (info.frag == NULL) goto out_fs; } - if (extract_file(n->data.file, cmp, super.block_size, - frag, fd, STDOUT_FILENO)) { + if (extract_file(n->data.file, &info, STDOUT_FILENO)) goto out_fs; - } break; case OP_UNPACK: if (cmdpath == NULL) { @@ -274,27 +277,26 @@ int main(int argc, char **argv) if (super.fragment_entry_count > 0 && super.fragment_table_start < super.bytes_used && !(super.flags & SQFS_FLAG_NO_FRAGMENTS)) { - frag = frag_reader_create(&super, fd, cmp); - if (frag == NULL) + info.frag = frag_reader_create(&super, info.sqfsfd, + info.cmp); + if (info.frag == NULL) goto out_fs; } - if (restore_fstree(unpack_root, n, cmp, super.block_size, - frag, fd, unpack_flags)) { + if (restore_fstree(unpack_root, n, &info)) goto out_fs; - } break; } status = EXIT_SUCCESS; out_fs: - if (frag != NULL) - frag_reader_destroy(frag); + if (info.frag != NULL) + frag_reader_destroy(info.frag); fstree_cleanup(&fs); out_cmp: - cmp->destroy(cmp); + info.cmp->destroy(info.cmp); out_fd: - close(fd); + close(info.sqfsfd); out_cmd: free(cmdpath); return status; diff --git a/unpack/rdsquashfs.h b/unpack/rdsquashfs.h index 995eee7..0961591 100644 --- a/unpack/rdsquashfs.h +++ b/unpack/rdsquashfs.h @@ -29,21 +29,26 @@ enum UNPACK_FLAGS { UNPACK_CHOWN = 0x40, }; +typedef struct { + compressor_t *cmp; + size_t block_size; + frag_reader_t *frag; + int sqfsfd; + int flags; +} unsqfs_info_t; + tree_node_t *tree_node_from_inode(sqfs_inode_generic_t *inode, const id_table_t *idtbl, const char *name, size_t block_size); -int read_fstree(fstree_t *out, int fd, sqfs_super_t *super, compressor_t *cmp, - int flags); +int read_fstree(fstree_t *out, sqfs_super_t *super, unsqfs_info_t *info); void list_files(tree_node_t *node); -int extract_file(file_info_t *fi, compressor_t *cmp, size_t block_size, - frag_reader_t *frag, int sqfsfd, int outfd); +int extract_file(file_info_t *fi, unsqfs_info_t *info, int outfd); -int restore_fstree(const char *rootdir, tree_node_t *root, compressor_t *cmp, - size_t block_size, frag_reader_t *frag, int sqfsfd, - int flags); +int restore_fstree(const char *rootdir, tree_node_t *root, + unsqfs_info_t *info); #endif /* RDSQUASHFS_H */ diff --git a/unpack/read_fstree.c b/unpack/read_fstree.c index 0b75d8b..544af83 100644 --- a/unpack/read_fstree.c +++ b/unpack/read_fstree.c @@ -114,8 +114,7 @@ static int fill_dir(meta_reader_t *ir, meta_reader_t *dr, tree_node_t *root, return 0; } -int read_fstree(fstree_t *out, int fd, sqfs_super_t *super, compressor_t *cmp, - int flags) +int read_fstree(fstree_t *out, sqfs_super_t *super, unsqfs_info_t *info) { sqfs_inode_generic_t *root; meta_reader_t *ir, *dr; @@ -124,18 +123,18 @@ int read_fstree(fstree_t *out, int fd, sqfs_super_t *super, compressor_t *cmp, int status = -1; size_t offset; - ir = meta_reader_create(fd, cmp); + ir = meta_reader_create(info->sqfsfd, info->cmp); if (ir == NULL) return -1; - dr = meta_reader_create(fd, cmp); + dr = meta_reader_create(info->sqfsfd, info->cmp); if (dr == NULL) goto out_ir; if (id_table_init(&idtbl)) goto out_dr; - if (id_table_read(&idtbl, fd, super, cmp)) + if (id_table_read(&idtbl, info->sqfsfd, super, info->cmp)) goto out_id; block_start = super->root_inode_ref >> 16; @@ -166,7 +165,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, flags)) + if (fill_dir(ir, dr, out->root, super, &idtbl, info->flags)) goto fail_fs; fstree_sort(out); diff --git a/unpack/restore_fstree.c b/unpack/restore_fstree.c index 270b25a..c06cd2b 100644 --- a/unpack/restore_fstree.c +++ b/unpack/restore_fstree.c @@ -1,9 +1,7 @@ /* SPDX-License-Identifier: GPL-3.0-or-later */ #include "rdsquashfs.h" -static int create_node(int dirfd, tree_node_t *n, compressor_t *cmp, - size_t block_size, frag_reader_t *frag, - int sqfsfd, int flags) +static int create_node(int dirfd, tree_node_t *n, unsqfs_info_t *info) { int fd; @@ -23,8 +21,7 @@ static int create_node(int dirfd, tree_node_t *n, compressor_t *cmp, } for (n = n->data.dir->children; n != NULL; n = n->next) { - if (create_node(fd, n, cmp, block_size, frag, sqfsfd, - flags)) { + if (create_node(fd, n, info)) { close(fd); return -1; } @@ -65,8 +62,7 @@ static int create_node(int dirfd, tree_node_t *n, compressor_t *cmp, return -1; } - if (extract_file(n->data.file, cmp, block_size, - frag, sqfsfd, fd)) { + if (extract_file(n->data.file, info, fd)) { close(fd); return -1; } @@ -77,7 +73,7 @@ static int create_node(int dirfd, tree_node_t *n, compressor_t *cmp, break; } - if (flags & UNPACK_CHOWN) { + if (info->flags & UNPACK_CHOWN) { if (fchownat(dirfd, n->name, n->uid, n->gid, AT_SYMLINK_NOFOLLOW)) { fprintf(stderr, "chown %s: %s\n", @@ -86,7 +82,7 @@ static int create_node(int dirfd, tree_node_t *n, compressor_t *cmp, } } - if (flags & UNPACK_CHMOD) { + if (info->flags & UNPACK_CHMOD) { if (fchmodat(dirfd, n->name, n->mode, AT_SYMLINK_NOFOLLOW)) { fprintf(stderr, "chmod %s: %s\n", @@ -97,9 +93,7 @@ static int create_node(int dirfd, tree_node_t *n, compressor_t *cmp, return 0; } -int restore_fstree(const char *rootdir, tree_node_t *root, compressor_t *cmp, - size_t block_size, frag_reader_t *frag, int sqfsfd, - int flags) +int restore_fstree(const char *rootdir, tree_node_t *root, unsqfs_info_t *info) { tree_node_t *n; int dirfd; @@ -115,8 +109,7 @@ int restore_fstree(const char *rootdir, tree_node_t *root, compressor_t *cmp, if (S_ISDIR(root->mode)) { for (n = root->data.dir->children; n != NULL; n = n->next) { - if (create_node(dirfd, n, cmp, block_size, frag, - sqfsfd, flags)) { + if (create_node(dirfd, n, info)) { close(dirfd); return -1; } @@ -124,7 +117,7 @@ int restore_fstree(const char *rootdir, tree_node_t *root, compressor_t *cmp, return 0; } - if (create_node(dirfd, root, cmp, block_size, frag, sqfsfd, flags)) { + if (create_node(dirfd, root, info)) { close(dirfd); return -1; } |