aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/data_reader.h51
-rw-r--r--include/highlevel.h6
-rw-r--r--include/sqfs/data_reader.h152
-rw-r--r--include/sqfs/predef.h1
-rw-r--r--lib/sqfs/Makemodule.am5
-rw-r--r--lib/sqfs/data_reader.c (renamed from lib/sqfshelper/data_reader.c)25
-rw-r--r--lib/sqfshelper/Makemodule.am1
-rw-r--r--lib/sqfshelper/data_reader_dump.c2
-rw-r--r--tar/sqfs2tar.c2
-rw-r--r--unpack/rdsquashfs.h2
10 files changed, 175 insertions, 72 deletions
diff --git a/include/data_reader.h b/include/data_reader.h
deleted file mode 100644
index 2ad3749..0000000
--- a/include/data_reader.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * data_reader.h
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#ifndef DATA_READER_H
-#define DATA_READER_H
-
-#include "config.h"
-
-#include "sqfs/compress.h"
-#include "sqfs/data.h"
-#include "fstree.h"
-
-typedef struct sqfs_data_reader_t sqfs_data_reader_t;
-
-
-sqfs_data_reader_t *sqfs_data_reader_create(sqfs_file_t *file,
- size_t block_size,
- sqfs_compressor_t *cmp);
-
-int sqfs_data_reader_load_fragment_table(sqfs_data_reader_t *data,
- const sqfs_super_t *super);
-
-void sqfs_data_reader_destroy(sqfs_data_reader_t *data);
-
-int sqfs_data_reader_get_fragment(sqfs_data_reader_t *data,
- const sqfs_inode_generic_t *inode,
- sqfs_block_t **out);
-
-int sqfs_data_reader_get_block(sqfs_data_reader_t *data,
- const sqfs_inode_generic_t *inode,
- size_t index, sqfs_block_t **out);
-
-int sqfs_data_reader_dump(sqfs_data_reader_t *data,
- const sqfs_inode_generic_t *inode,
- int outfd, size_t block_size, bool allow_sparse);
-
-/*
- Read a chunk of data from a file. Starting from 'offset' into the
- uncompressed file, read 'size' bytes into 'buffer'.
-
- Returns the number of bytes read, 0 if EOF, -1 on failure. Prints an
- error message to stderr on failure.
- */
-ssize_t sqfs_data_reader_read(sqfs_data_reader_t *data,
- const sqfs_inode_generic_t *inode,
- uint64_t offset, void *buffer, size_t size);
-
-#endif /* DATA_READER_H */
diff --git a/include/highlevel.h b/include/highlevel.h
index 6c0a112..46a2330 100644
--- a/include/highlevel.h
+++ b/include/highlevel.h
@@ -20,7 +20,7 @@
#include "sqfs/xattr.h"
#include "sqfs/dir.h"
#include "sqfs/io.h"
-#include "data_reader.h"
+#include "sqfs/data_reader.h"
#include "data_writer.h"
#include "fstree.h"
@@ -79,4 +79,8 @@ int inode_stat(const sqfs_tree_node_t *node, struct stat *sb);
char *sqfs_tree_node_get_path(const sqfs_tree_node_t *node);
+int sqfs_data_reader_dump(sqfs_data_reader_t *data,
+ const sqfs_inode_generic_t *inode,
+ int outfd, size_t block_size, bool allow_sparse);
+
#endif /* HIGHLEVEL_H */
diff --git a/include/sqfs/data_reader.h b/include/sqfs/data_reader.h
new file mode 100644
index 0000000..7d0f9d7
--- /dev/null
+++ b/include/sqfs/data_reader.h
@@ -0,0 +1,152 @@
+/* SPDX-License-Identifier: LGPL-3.0-or-later */
+/*
+ * data_reader.h - This file is part of libsquashfs
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+#ifndef SQFS_DATA_READER_H
+#define SQFS_DATA_READER_H
+
+#include "sqfs/predef.h"
+
+/**
+ * @file data_reader.h
+ *
+ * @brief Contains declarations for the @ref sqfs_data_reader_t.
+ */
+
+/**
+ * @struct sqfs_data_reader_t
+ *
+ * @brief Abstracts access to data blocks stored in a SquashFS image.
+ *
+ * A SquashFS image can contain a series of file data blocks between the
+ * super block and the inode table. Blocks may or may not be compressed.
+ * Data chunks that are smaller than the block size indicated by the super
+ * block (such as the final chunk of a file or an entire file that is smaller
+ * than a signle block) can be grouped in a single fragment block.
+ *
+ * Regular file inodes referre to the location of the first block and store a
+ * sequence of block sizes for all consequitve blocks, as well as a fragment
+ * index and fragment offset which is resolved through a fragment table.
+ *
+ * The data reader abstracts all of this away in a simple interface that allows
+ * reading file data through an inode description and a location in the file.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Create a data reader instance.
+ *
+ * @memberof sqfs_data_reader_t
+ *
+ * @param file A file interface through which to access the
+ * underlying filesystem image.
+ * @param block_size The data block size from the super block.
+ * @param cmp A compressor to use for uncompressing blocks read from disk.
+ *
+ * @return A pointer to a new data reader object. NULL means
+ * allocation failure.
+ */
+SQFS_API sqfs_data_reader_t *sqfs_data_reader_create(sqfs_file_t *file,
+ size_t block_size,
+ sqfs_compressor_t *cmp);
+
+/**
+ * @brief Destroy a data reader instance and free all memory used by it.
+ *
+ * @memberof sqfs_data_reader_t
+ *
+ * @param data A pointer to a data reader object.
+ */
+SQFS_API void sqfs_data_reader_destroy(sqfs_data_reader_t *data);
+
+/**
+ * @brief Read and decode the fragment table from disk.
+ *
+ * @memberof sqfs_data_reader_t
+ *
+ * @param data A pointer to a data reader object.
+ * @param super A pointer to the super block.
+ *
+ * @return Zero on succcess, an @ref E_SQFS_ERROR value on failure.
+ */
+SQFS_API int sqfs_data_reader_load_fragment_table(sqfs_data_reader_t *data,
+ const sqfs_super_t *super);
+
+/**
+ * @brief Get the tail end of a file.
+ *
+ * @memberof sqfs_data_reader_t
+ *
+ * @param data A pointer to a data reader object.
+ * @param inode A pointer to the inode describing the file.
+ * @param out Returns a pointer to the tail block of the file.
+ *
+ * @return Zero on succcess, an @ref E_SQFS_ERROR value on failure.
+ */
+SQFS_API int sqfs_data_reader_get_fragment(sqfs_data_reader_t *data,
+ const sqfs_inode_generic_t *inode,
+ sqfs_block_t **out);
+
+/**
+ * @brief Get a full sized data block of a file by block index.
+ *
+ * @memberof sqfs_data_reader_t
+ *
+ * @param data A pointer to a data reader object.
+ * @param inode A pointer to the inode describing the file.
+ * @param index The block index in the inodes block list.
+ * @param out Returns a pointer to the data block.
+ *
+ * @return Zero on succcess, an @ref E_SQFS_ERROR value on failure.
+ */
+SQFS_API int sqfs_data_reader_get_block(sqfs_data_reader_t *data,
+ const sqfs_inode_generic_t *inode,
+ size_t index, sqfs_block_t **out);
+
+/**
+ * @brief A simple UNIX-read-like function to read data from a file.
+ *
+ * @memberof sqfs_data_reader_t
+ *
+ * This function acts like the read system call in a Unix-like OS. It takes
+ * care of reading accross data blocks and fragment internally, using a
+ * data and fragment block cache.
+ *
+ * @param data A pointer to a data reader object.
+ * @param inode A pointer to the inode describing the file.
+ * @param offset An arbitrary byte offset into the uncompressed file.
+ * @param buffer Returns the data read from the file.
+ * @param size The number of uncompressed bytes to read from the given offset.
+ *
+ * @return The number of bytes read on succcess, zero if attempting to read
+ * past the end of the file and a negative @ref E_SQFS_ERROR value
+ * on failure.
+ */
+SQFS_API ssize_t sqfs_data_reader_read(sqfs_data_reader_t *data,
+ const sqfs_inode_generic_t *inode,
+ uint64_t offset, void *buffer,
+ size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SQFS_DATA_READER_H */
diff --git a/include/sqfs/predef.h b/include/sqfs/predef.h
index c25a858..aad4eae 100644
--- a/include/sqfs/predef.h
+++ b/include/sqfs/predef.h
@@ -71,6 +71,7 @@ typedef struct sqfs_xattr_reader_t sqfs_xattr_reader_t;
typedef struct sqfs_file_t sqfs_file_t;
typedef struct sqfs_sparse_map_t sqfs_sparse_map_t;
typedef struct sqfs_tree_node_t sqfs_tree_node_t;
+typedef struct sqfs_data_reader_t sqfs_data_reader_t;
typedef struct sqfs_fragment_t sqfs_fragment_t;
typedef struct sqfs_dir_header_t sqfs_dir_header_t;
diff --git a/lib/sqfs/Makemodule.am b/lib/sqfs/Makemodule.am
index 66d49b6..cb003c0 100644
--- a/lib/sqfs/Makemodule.am
+++ b/lib/sqfs/Makemodule.am
@@ -5,7 +5,8 @@ LIBSQFS_HEARDS = include/sqfs/data.h include/sqfs/meta_writer.h \
include/sqfs/dir.h include/sqfs/xattr.h \
include/sqfs/table.h include/sqfs/predef.h \
include/sqfs/error.h include/sqfs/dir_reader.h \
- include/sqfs/dir_writer.h include/sqfs/io.h
+ include/sqfs/dir_writer.h include/sqfs/io.h \
+ include/sqfs/data_reader.h
libsquashfs_la_SOURCES = $(LIBSQFS_HEARDS) lib/sqfs/id_table.c lib/sqfs/super.c
libsquashfs_la_SOURCES += lib/sqfs/readdir.c lib/sqfs/io_file.c lib/sqfs/xattr.c
@@ -17,7 +18,7 @@ libsquashfs_la_SOURCES += lib/sqfs/read_table.c lib/sqfs/comp/compressor.c
libsquashfs_la_SOURCES += lib/sqfs/io_stdin.c lib/sqfs/comp/internal.h
libsquashfs_la_SOURCES += lib/sqfs/dir_reader.c lib/sqfs/read_tree.c
libsquashfs_la_SOURCES += lib/sqfs/blk_proc/process_block.c lib/sqfs/io.c
-libsquashfs_la_SOURCES += lib/sqfs/blk_proc/internal.h
+libsquashfs_la_SOURCES += lib/sqfs/blk_proc/internal.h lib/sqfs/data_reader.c
libsquashfs_la_CPPFLAGS = $(AM_CPPFLAGS)
libsquashfs_la_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) $(ZLIB_CFLAGS)
libsquashfs_la_CFLAGS += $(XZ_CFLAGS) $(LZO_CFLAGS) $(LZ4_CFLAGS)
diff --git a/lib/sqfshelper/data_reader.c b/lib/sqfs/data_reader.c
index bf808ba..3de59ff 100644
--- a/lib/sqfshelper/data_reader.c
+++ b/lib/sqfs/data_reader.c
@@ -1,22 +1,24 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
+/* SPDX-License-Identifier: LGPL-3.0-or-later */
/*
* data_reader.c
*
* Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
*/
+#define SQFS_BUILDING_DLL
#include "config.h"
#include "sqfs/block_processor.h"
+#include "sqfs/data_reader.h"
+#include "sqfs/compress.h"
#include "sqfs/error.h"
-
-#include "data_reader.h"
-#include "highlevel.h"
+#include "sqfs/table.h"
+#include "sqfs/inode.h"
+#include "sqfs/data.h"
+#include "sqfs/io.h"
#include "util.h"
#include <stdlib.h>
-#include <unistd.h>
#include <string.h>
-#include <stdio.h>
struct sqfs_data_reader_t {
sqfs_fragment_t *frag;
@@ -113,10 +115,8 @@ static int precache_fragment_block(sqfs_data_reader_t *data, size_t idx)
if (data->frag_block != NULL && idx == data->current_frag_index)
return 0;
- if (idx >= data->num_fragments) {
- fputs("fragment index out of bounds\n", stderr);
- return -1;
- }
+ if (idx >= data->num_fragments)
+ return SQFS_ERROR_OUT_OF_BOUNDS;
free(data->frag_block);
@@ -351,7 +351,7 @@ ssize_t sqfs_data_reader_read(sqfs_data_reader_t *data,
return -1;
if (frag_off + filesz > data->block_size)
- goto fail_range;
+ return SQFS_ERROR_OUT_OF_BOUNDS;
if (offset >= filesz)
return total;
@@ -368,7 +368,4 @@ ssize_t sqfs_data_reader_read(sqfs_data_reader_t *data,
}
return total;
-fail_range:
- fputs("attempted to read past fragment block limits\n", stderr);
- return -1;
}
diff --git a/lib/sqfshelper/Makemodule.am b/lib/sqfshelper/Makemodule.am
index d711cf2..b85e6a5 100644
--- a/lib/sqfshelper/Makemodule.am
+++ b/lib/sqfshelper/Makemodule.am
@@ -6,7 +6,6 @@ libsqfshelper_a_SOURCES += lib/sqfshelper/print_version.c
libsqfshelper_a_SOURCES += lib/sqfshelper/inode_stat.c
libsqfshelper_a_SOURCES += lib/sqfshelper/data_reader_dump.c
libsqfshelper_a_SOURCES += lib/sqfshelper/compress.c lib/sqfshelper/comp_opt.c
-libsqfshelper_a_SOURCES += include/data_reader.h lib/sqfshelper/data_reader.c
libsqfshelper_a_SOURCES += include/data_writer.h lib/sqfshelper/data_writer.c
libsqfshelper_a_SOURCES += lib/sqfshelper/write_xattr.c include/highlevel.h
libsqfshelper_a_SOURCES += lib/sqfshelper/get_path.c
diff --git a/lib/sqfshelper/data_reader_dump.c b/lib/sqfshelper/data_reader_dump.c
index 0c7a0cc..e28bf20 100644
--- a/lib/sqfshelper/data_reader_dump.c
+++ b/lib/sqfshelper/data_reader_dump.c
@@ -7,7 +7,7 @@
#include "config.h"
#include "sqfs/block_processor.h"
-#include "data_reader.h"
+#include "sqfs/data_reader.h"
#include "highlevel.h"
#include "util.h"
diff --git a/tar/sqfs2tar.c b/tar/sqfs2tar.c
index f628807..0bacd0e 100644
--- a/tar/sqfs2tar.c
+++ b/tar/sqfs2tar.c
@@ -8,7 +8,7 @@
#include "sqfs/meta_reader.h"
#include "sqfs/compress.h"
-#include "data_reader.h"
+#include "sqfs/data_reader.h"
#include "highlevel.h"
#include "util.h"
#include "tar.h"
diff --git a/unpack/rdsquashfs.h b/unpack/rdsquashfs.h
index dafb73d..44a8675 100644
--- a/unpack/rdsquashfs.h
+++ b/unpack/rdsquashfs.h
@@ -10,12 +10,12 @@
#include "config.h"
#include "sqfs/meta_reader.h"
+#include "sqfs/data_reader.h"
#include "sqfs/compress.h"
#include "sqfs/id_table.h"
#include "sqfs/xattr.h"
#include "sqfs/data.h"
-#include "data_reader.h"
#include "highlevel.h"
#include "fstree.h"
#include "util.h"