aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-09-16 15:50:46 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-09-19 18:22:41 +0200
commitab0c4a02ba9d1a836f62a8601699c971b72eec07 (patch)
tree4ceb7a0a5d9c36189a05750da388941c8a223ebb /include
parent3f4f75777b9b558e0e8c4af4408b094b6d4b1034 (diff)
Add directory reader data structure
This moves a lot of the stuff that is done manually in the tree deserializer to a generic helper in libsquashfs. Due to how the fstree is implemented, as a work around, the inode needs to be temporarily stored in the tree node, but some of the directory details could be removed. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'include')
-rw-r--r--include/fstree.h10
-rw-r--r--include/sqfs/dir.h159
-rw-r--r--include/sqfs/error.h4
-rw-r--r--include/sqfs/predef.h1
4 files changed, 168 insertions, 6 deletions
diff --git a/include/fstree.h b/include/fstree.h
index 4c02ce5..880a870 100644
--- a/include/fstree.h
+++ b/include/fstree.h
@@ -16,6 +16,8 @@
#include <stddef.h>
#include <stdio.h>
+#include "sqfs/inode.h"
+
#include "str_table.h"
#define FSTREE_XATTR_KEY_BUCKETS 31
@@ -105,12 +107,6 @@ struct dir_info_t {
directory meta data to disk. */
uint64_t size;
- /* Start block offset, relative to directory table start. */
- uint64_t start_block;
-
- /* Byte offset into the uncompressed meta data block. */
- uint32_t block_offset;
-
/* Set to true for implicitly generated directories. */
bool created_implicitly;
};
@@ -126,6 +122,8 @@ struct tree_node_t {
/* For the root node, this points to an empty string. */
char *name;
+ sqfs_inode_generic_t *inode;
+
/*
A pointer to an extended attribute array or NULL if unused.
diff --git a/include/sqfs/dir.h b/include/sqfs/dir.h
index 18950df..d8603d7 100644
--- a/include/sqfs/dir.h
+++ b/include/sqfs/dir.h
@@ -59,6 +59,29 @@
* writer used for inodes.
*/
+/**
+ * @struct sqfs_dir_reader_t
+ *
+ * @brief Abstracts reading of directory entries
+ *
+ * SquashFS stores directory listings and inode structures seperated from
+ * each other in meta data blocks.
+ *
+ * The sqfs_dir_reader_t abstracts access to the filesystem tree in a SquashFS
+ * through a fairly simple interface. It keeps two meta data readers internally
+ * for reading directory listings and inodes. Externally, it offers a few
+ * simple functions for iterating over the contents of a directory that
+ * completely take care of fetching/decoding headers and sifting through the
+ * multi level hierarchie used for storing them on disk.
+ *
+ * See @ref sqfs_dir_writer_t for an overview on how directory entries are
+ * stored in SquashFS.
+ *
+ * The reader also abstracts easy access to the underlying inodes, allowing
+ * direct access to the inode referred to by a directory entry.
+ */
+
+
#define SQFS_MAX_DIR_ENT 256
/**
@@ -341,6 +364,142 @@ SQFS_API sqfs_inode_generic_t
*sqfs_dir_writer_create_inode(const sqfs_dir_writer_t *writer, size_t hlinks,
uint32_t xattr, uint32_t parent_ino);
+/**
+ * @brief Create a directory reader.
+ *
+ * @memberof sqfs_dir_reader_t
+ *
+ * @param super A pointer to the super block. Kept internally an used for
+ * resolving table positions.
+ * @param cmp A compressor to use for unpacking meta data blocks.
+ * @param file The input file to read from.
+ *
+ * @return A new directory reader on success, NULL on allocation failure.
+ */
+SQFS_API sqfs_dir_reader_t *sqfs_dir_reader_create(const sqfs_super_t *super,
+ sqfs_compressor_t *cmp,
+ sqfs_file_t *file);
+
+/**
+ * @brief Cleanup a directory reader and free all its memory.
+ *
+ * @memberof sqfs_dir_reader_t
+ */
+SQFS_API void sqfs_dir_reader_destroy(sqfs_dir_reader_t *rd);
+
+/**
+ * @brief Navigate a directory reader to the location of a directory
+ * represented by an inode.
+ *
+ * @memberof sqfs_dir_reader_t
+ *
+ * This function seeks to the meta data block containing the directory
+ * listing that the given inode referes to and resets the internal state.
+ * After that, consequtive cals to @ref sqfs_dir_reader_read can be made
+ * to iterate over the directory contents.
+ *
+ * @param rd A pointer to a directory reader.
+ * @param inode An directory or extended directory inode.
+ *
+ * @return Zero on success, an @ref E_SQFS_ERROR value on failure.
+ */
+SQFS_API int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd,
+ const sqfs_inode_generic_t *inode);
+
+/**
+ * @brief Reset a directory reader back to the beginning of the listing.
+ *
+ * @memberof sqfs_dir_reader_t
+ *
+ * @param rd A pointer to a directory reader.
+ *
+ * @return Zero on success, an @ref E_SQFS_ERROR value on failure.
+ */
+SQFS_API int sqfs_dir_reader_rewind(sqfs_dir_reader_t *rd);
+
+/**
+ * @brief Seek through the current directory listing to locate an
+ * entry by name.
+ *
+ * @memberof sqfs_dir_reader_t
+ *
+ * @param rd A pointer to a directory reader.
+ * @param name The name of the entry to find.
+ *
+ * @return Zero on success, an @ref E_SQFS_ERROR value on failure.
+ */
+SQFS_API int sqfs_dir_reader_find(sqfs_dir_reader_t *rd, const char *name);
+
+/**
+ * @brief Read a directory entry and advance the internal position indicator
+ * to the next one.
+ *
+ * @memberof sqfs_dir_reader_t
+ *
+ * Call this function repeatedly to iterate over a directory listing. It
+ * returns a positive number to indicate that it couldn't fetch any more data
+ * because the end of the listing was reached. A negative value indicates an
+ * error.
+ *
+ * After calling this function, you can use @ref sqfs_dir_reader_get_inode to
+ * read the full inode structure that the current entry referes to.
+ *
+ * @param rd A pointer to a directory reader.
+ * @param out Returns a pointer to a directory entry on success that can be
+ * freed with a single free call.
+ *
+ * @return Zero on success, an @ref E_SQFS_ERROR value on failure, a positive
+ * number if the end of the current directory listing has been reached.
+ */
+SQFS_API int sqfs_dir_reader_read(sqfs_dir_reader_t *rd,
+ sqfs_dir_entry_t **out);
+
+/**
+ * @brief Read the inode that the current directory entry points to.
+ *
+ * @memberof sqfs_dir_reader_t
+ *
+ * @param rd A pointer to a directory reader.
+ * @param out Returns a pointer to a generic inode that can be freed with a
+ * single free call.
+ *
+ * @return Zero on success, an @ref E_SQFS_ERROR value on failure.
+ */
+SQFS_API int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd,
+ sqfs_inode_generic_t **inode);
+
+/**
+ * @brief Read the root inode using the location given by the super block.
+ *
+ * @memberof sqfs_dir_reader_t
+ *
+ * @param rd A pointer to a directory reader.
+ * @param out Returns a pointer to a generic inode that can be freed with a
+ * single free call.
+ *
+ * @return Zero on success, an @ref E_SQFS_ERROR value on failure.
+ */
+SQFS_API int sqfs_dir_reader_get_root_inode(sqfs_dir_reader_t *rd,
+ sqfs_inode_generic_t **inode);
+
+/**
+ * @brief Find an inode through path traversal from the root node downwards.
+ *
+ * @memberof sqfs_dir_reader_t
+ *
+ * @param rd A pointer to a directory reader.
+ * @param path A path to resolve into an inode. Forward or backward slashes can
+ * be used to seperate path components. Resolving '.' or '..' is
+ * not supported.
+ * @param out Returns a pointer to a generic inode that can be freed with a
+ * single free call.
+ *
+ * @return Zero on success, an @ref E_SQFS_ERROR value on failure.
+ */
+SQFS_API int sqfs_dir_reader_find_by_path(sqfs_dir_reader_t *rd,
+ const char *path,
+ sqfs_inode_generic_t **out);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/sqfs/error.h b/include/sqfs/error.h
index a9a0acf..ddfeadd 100644
--- a/include/sqfs/error.h
+++ b/include/sqfs/error.h
@@ -103,6 +103,10 @@ typedef enum {
* legal range (4k to 1M).
*/
SQFS_ERROR_SUPER_BLOCK_SIZE = -11,
+
+ SQFS_ERROR_NOT_DIR = -12,
+
+ SQFS_ERROR_NO_ENTRY = -13,
} E_SQFS_ERROR;
#endif /* SQFS_ERROR_H */
diff --git a/include/sqfs/predef.h b/include/sqfs/predef.h
index 95d907f..4041a57 100644
--- a/include/sqfs/predef.h
+++ b/include/sqfs/predef.h
@@ -63,6 +63,7 @@ typedef struct sqfs_block_processor_t sqfs_block_processor_t;
typedef struct sqfs_compressor_config_t sqfs_compressor_config_t;
typedef struct sqfs_compressor_t sqfs_compressor_t;
typedef struct sqfs_dir_writer_t sqfs_dir_writer_t;
+typedef struct sqfs_dir_reader_t sqfs_dir_reader_t;
typedef struct sqfs_id_table_t sqfs_id_table_t;
typedef struct sqfs_meta_reader_t sqfs_meta_reader_t;
typedef struct sqfs_meta_writer_t sqfs_meta_writer_t;