aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/highlevel.h19
-rw-r--r--lib/Makemodule.am1
-rw-r--r--lib/sqfs/sqfs_reader.c72
-rw-r--r--tar/sqfs2tar.c68
-rw-r--r--unpack/rdsquashfs.c66
5 files changed, 118 insertions, 108 deletions
diff --git a/include/highlevel.h b/include/highlevel.h
index e3afbd7..f8c5bfb 100644
--- a/include/highlevel.h
+++ b/include/highlevel.h
@@ -9,6 +9,7 @@
#include "config.h"
+#include "data_reader.h"
#include "squashfs.h"
#include "compress.h"
#include "id_table.h"
@@ -17,6 +18,14 @@
#include <stdint.h>
#include <stddef.h>
+typedef struct {
+ compressor_t *cmp;
+ data_reader_t *data;
+ sqfs_super_t super;
+ fstree_t fs;
+ int sqfsfd;
+} sqfs_reader_t;
+
enum RDTREE_FLAGS {
RDTREE_NO_DEVICES = 0x01,
RDTREE_NO_SOCKETS = 0x02,
@@ -96,4 +105,14 @@ int write_export_table(int outfd, fstree_t *fs, sqfs_super_t *super,
/* Print out fancy statistics for squashfs packing tools */
void sqfs_print_statistics(fstree_t *fs, sqfs_super_t *super);
+/* Open a squashfs file, extract all the information we may need and
+ construct datastructures we need to access its contents.
+ Returns 0 on success. Prints error messages to stderr on failure.
+*/
+int sqfs_reader_open(sqfs_reader_t *rd, const char *filename,
+ int rdtree_flags);
+
+/* Cleanup after a successfull sqfs_reader_open */
+void sqfs_reader_close(sqfs_reader_t *rd);
+
#endif /* HIGHLEVEL_H */
diff --git a/lib/Makemodule.am b/lib/Makemodule.am
index c3451f4..82c910c 100644
--- a/lib/Makemodule.am
+++ b/lib/Makemodule.am
@@ -39,6 +39,7 @@ libsquashfs_a_SOURCES += include/data_writer.h include/xattr_reader.h
libsquashfs_a_SOURCES += include/data_reader.h lib/sqfs/data_reader.c
libsquashfs_a_SOURCES += lib/sqfs/write_export_table.c
libsquashfs_a_SOURCES += lib/sqfs/read_table.c lib/sqfs/statistics.c
+libsquashfs_a_SOURCES += lib/sqfs/sqfs_reader.c
libutil_a_SOURCES = lib/util/canonicalize_name.c lib/util/write_data.c
libutil_a_SOURCES += lib/util/read_data.c include/util.h
diff --git a/lib/sqfs/sqfs_reader.c b/lib/sqfs/sqfs_reader.c
new file mode 100644
index 0000000..85cf97a
--- /dev/null
+++ b/lib/sqfs/sqfs_reader.c
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * sqfs_reader.c
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+
+#include "highlevel.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+int sqfs_reader_open(sqfs_reader_t *rd, const char *filename, int rdtree_flags)
+{
+ memset(rd, 0, sizeof(*rd));
+
+ rd->sqfsfd = open(filename, O_RDONLY);
+ if (rd->sqfsfd < 0) {
+ perror(filename);
+ return -1;
+ }
+
+ if (sqfs_super_read(&rd->super, rd->sqfsfd))
+ goto fail_fd;
+
+ if (!compressor_exists(rd->super.compression_id)) {
+ fprintf(stderr, "%s: unknown compressor used.\n", filename);
+ goto fail_fd;
+ }
+
+ rd->cmp = compressor_create(rd->super.compression_id, false,
+ rd->super.block_size, NULL);
+ if (rd->cmp == NULL)
+ goto fail_fd;
+
+ if (rd->super.flags & SQFS_FLAG_COMPRESSOR_OPTIONS) {
+ if (rd->cmp->read_options(rd->cmp, rd->sqfsfd))
+ goto fail_cmp;
+ }
+
+ if (deserialize_fstree(&rd->fs, &rd->super, rd->cmp, rd->sqfsfd,
+ rdtree_flags)) {
+ goto fail_cmp;
+ }
+
+ fstree_gen_file_list(&rd->fs);
+
+ rd->data = data_reader_create(rd->sqfsfd, &rd->super, rd->cmp);
+ if (rd->data == NULL)
+ goto fail_fs;
+
+ return 0;
+fail_fs:
+ fstree_cleanup(&rd->fs);
+fail_cmp:
+ rd->cmp->destroy(rd->cmp);
+fail_fd:
+ close(rd->sqfsfd);
+ memset(rd, 0, sizeof(*rd));
+ return -1;
+}
+
+void sqfs_reader_close(sqfs_reader_t *rd)
+{
+ data_reader_destroy(rd->data);
+ fstree_cleanup(&rd->fs);
+ rd->cmp->destroy(rd->cmp);
+ close(rd->sqfsfd);
+ memset(rd, 0, sizeof(*rd));
+}
diff --git a/tar/sqfs2tar.c b/tar/sqfs2tar.c
index a49efda..59e9703 100644
--- a/tar/sqfs2tar.c
+++ b/tar/sqfs2tar.c
@@ -302,89 +302,51 @@ skip_hdr:
int main(int argc, char **argv)
{
- int sqfsfd, rdtree_flags = 0;
- data_reader_t *data = NULL;
- int status = EXIT_FAILURE;
- sqfs_super_t super;
- compressor_t *cmp;
+ int rdtree_flags = 0, status = EXIT_FAILURE;
+ sqfs_reader_t sqfs;
tree_node_t *root;
- fstree_t fs;
size_t i;
process_args(argc, argv);
- sqfsfd = open(filename, O_RDONLY);
- if (sqfsfd < 0) {
- perror(filename);
- return EXIT_FAILURE;
- }
-
- if (sqfs_super_read(&super, sqfsfd))
- goto out_fd;
-
- if (!compressor_exists(super.compression_id)) {
- fputs("Image uses a compressor that has not been built in\n",
- stderr);
- goto out_fd;
- }
-
- cmp = compressor_create(super.compression_id, false,
- super.block_size, NULL);
- if (cmp == NULL)
- goto out_fd;
-
- if (super.flags & SQFS_FLAG_COMPRESSOR_OPTIONS) {
- if (cmp->read_options(cmp, sqfsfd))
- goto out_cmp;
- }
-
if (!no_xattr)
rdtree_flags |= RDTREE_READ_XATTR;
- if (deserialize_fstree(&fs, &super, cmp, sqfsfd, rdtree_flags))
- goto out_cmp;
-
- data = data_reader_create(sqfsfd, &super, cmp);
- if (data == NULL)
- goto out_fs;
+ if (sqfs_reader_open(&sqfs, filename, rdtree_flags))
+ goto out_dirs;
for (i = 0; i < num_subdirs; ++i) {
- root = fstree_node_from_path(&fs, subdirs[i]);
+ root = fstree_node_from_path(&sqfs.fs, subdirs[i]);
if (root == NULL) {
perror(subdirs[i]);
- goto out_data;
+ goto out;
}
if (!S_ISDIR(root->mode)) {
fprintf(stderr, "%s is not a directory\n", subdirs[i]);
- goto out_data;
+ goto out;
}
current_subdir = subdirs[i];
- if (write_tree_dfs(&fs, root, data))
- goto out_data;
+ if (write_tree_dfs(&sqfs.fs, root, sqfs.data))
+ goto out;
}
current_subdir = NULL;
if (num_subdirs == 0) {
- if (write_tree_dfs(&fs, fs.root, data))
- goto out_data;
+ if (write_tree_dfs(&sqfs.fs, sqfs.fs.root, sqfs.data))
+ goto out;
}
if (terminate_archive())
- goto out_data;
+ goto out;
status = EXIT_SUCCESS;
-out_data:
- data_reader_destroy(data);
-out_fs:
- fstree_cleanup(&fs);
-out_cmp:
- cmp->destroy(cmp);
-out_fd:
- close(sqfsfd);
+out:
+ sqfs_reader_close(&sqfs);
+out_dirs:
for (i = 0; i < num_subdirs; ++i)
free(subdirs[i]);
free(subdirs);
diff --git a/unpack/rdsquashfs.c b/unpack/rdsquashfs.c
index dc43fcd..4fb3a78 100644
--- a/unpack/rdsquashfs.c
+++ b/unpack/rdsquashfs.c
@@ -24,54 +24,23 @@ static void dump_xattrs(fstree_t *fs, tree_xattr_t *xattr)
int main(int argc, char **argv)
{
int status = EXIT_FAILURE;
- data_reader_t *data = NULL;
- sqfs_super_t super;
- compressor_t *cmp;
+ sqfs_reader_t sqfs;
tree_node_t *n;
options_t opt;
- fstree_t fs;
- int sqfsfd;
process_command_line(&opt, argc, argv);
- sqfsfd = open(opt.image_name, O_RDONLY);
- if (sqfsfd < 0) {
- perror(opt.image_name);
+ if (sqfs_reader_open(&sqfs, opt.image_name, opt.rdtree_flags))
goto out_cmd;
- }
-
- if (sqfs_super_read(&super, sqfsfd))
- goto out_fd;
-
- if (!compressor_exists(super.compression_id)) {
- fputs("Image uses a compressor that has not been built in\n",
- stderr);
- goto out_fd;
- }
-
- cmp = compressor_create(super.compression_id, false,
- super.block_size, NULL);
- if (cmp == NULL)
- goto out_fd;
-
- if (super.flags & SQFS_FLAG_COMPRESSOR_OPTIONS) {
- if (cmp->read_options(cmp, sqfsfd))
- goto out_cmp;
- }
-
- if (deserialize_fstree(&fs, &super, cmp, sqfsfd, opt.rdtree_flags))
- goto out_cmp;
-
- fstree_gen_file_list(&fs);
if (opt.cmdpath != NULL) {
- n = fstree_node_from_path(&fs, opt.cmdpath);
+ n = fstree_node_from_path(&sqfs.fs, opt.cmdpath);
if (n == NULL) {
perror(opt.cmdpath);
goto out_fs;
}
} else {
- n = fs.root;
+ n = sqfs.fs.root;
}
switch (opt.op) {
@@ -85,11 +54,7 @@ int main(int argc, char **argv)
goto out_fs;
}
- data = data_reader_create(sqfsfd, &super, cmp);
- if (data == NULL)
- goto out_fs;
-
- if (data_reader_dump_file(data, n->data.file,
+ if (data_reader_dump_file(sqfs.data, n->data.file,
STDOUT_FILENO, false))
goto out_fs;
break;
@@ -105,38 +70,29 @@ int main(int argc, char **argv)
if (restore_fstree(n, opt.flags))
goto out_fs;
- data = data_reader_create(sqfsfd, &super, cmp);
- if (data == NULL)
- goto out_fs;
-
- if (fill_unpacked_files(&fs, data, opt.flags, opt.num_jobs))
+ if (fill_unpacked_files(&sqfs.fs, sqfs.data,
+ opt.flags, opt.num_jobs))
goto out_fs;
- if (update_tree_attribs(&fs, n, opt.flags))
+ if (update_tree_attribs(&sqfs.fs, n, opt.flags))
goto out_fs;
if (opt.unpack_root != NULL && popd() != 0)
goto out_fs;
break;
case OP_DESCRIBE:
- if (describe_tree(fs.root, opt.unpack_root))
+ if (describe_tree(sqfs.fs.root, opt.unpack_root))
goto out_fs;
break;
case OP_RDATTR:
if (n->xattr != NULL)
- dump_xattrs(&fs, n->xattr);
+ dump_xattrs(&sqfs.fs, n->xattr);
break;
}
status = EXIT_SUCCESS;
out_fs:
- if (data != NULL)
- data_reader_destroy(data);
- fstree_cleanup(&fs);
-out_cmp:
- cmp->destroy(cmp);
-out_fd:
- close(sqfsfd);
+ sqfs_reader_close(&sqfs);
out_cmd:
free(opt.cmdpath);
return status;