diff options
-rw-r--r-- | include/data_reader.h | 51 | ||||
-rw-r--r-- | include/highlevel.h | 6 | ||||
-rw-r--r-- | include/sqfs/data_reader.h | 152 | ||||
-rw-r--r-- | include/sqfs/predef.h | 1 | ||||
-rw-r--r-- | lib/sqfs/Makemodule.am | 5 | ||||
-rw-r--r-- | lib/sqfs/data_reader.c (renamed from lib/sqfshelper/data_reader.c) | 25 | ||||
-rw-r--r-- | lib/sqfshelper/Makemodule.am | 1 | ||||
-rw-r--r-- | lib/sqfshelper/data_reader_dump.c | 2 | ||||
-rw-r--r-- | tar/sqfs2tar.c | 2 | ||||
-rw-r--r-- | unpack/rdsquashfs.h | 2 |
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" |