summaryrefslogtreecommitdiff
path: root/unpack
diff options
context:
space:
mode:
Diffstat (limited to 'unpack')
-rw-r--r--unpack/extract_file.c26
-rw-r--r--unpack/rdsquashfs.c62
-rw-r--r--unpack/rdsquashfs.h19
-rw-r--r--unpack/read_fstree.c11
-rw-r--r--unpack/restore_fstree.c23
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;
}