aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/compress.h51
-rw-r--r--include/frag_reader.h45
-rw-r--r--include/fstree.h240
-rw-r--r--include/id_table.h79
-rw-r--r--include/meta_reader.h134
-rw-r--r--include/meta_writer.h80
-rw-r--r--include/table.h21
-rw-r--r--include/util.h40
8 files changed, 690 insertions, 0 deletions
diff --git a/include/compress.h b/include/compress.h
index ad193e8..5bb689b 100644
--- a/include/compress.h
+++ b/include/compress.h
@@ -11,15 +11,66 @@
typedef struct compressor_t compressor_t;
+/**
+ * @struct compressor_t
+ *
+ * @brief Encapsultes a compressor with a simple interface to compress or
+ * uncompress/extract blocks of data
+ */
struct compressor_t {
+ /**
+ * @brief Compress or uncompress a chunk of data
+ *
+ * @param cmp A pointer to the compressor object
+ * @param in A pointer to the input buffer
+ * @param size The number of bytes in the input buffer to process
+ * @param out A pointer to the output buffer
+ * @param outsize The number of bytes available in the output buffer
+ *
+ * @return On success, the number of bytes written to the output
+ * buffer, -1 on failure, 0 if the output buffer was too small.
+ * The compressor also returns 0 if the compressed result ends
+ * up larger than the original input.
+ */
ssize_t (*do_block)(compressor_t *cmp, const uint8_t *in, size_t size,
uint8_t *out, size_t outsize);
+ /**
+ * @brief Destroy a compressor object and free up all memory it uses
+ *
+ * @param cmp A pointer to the compressor object
+ */
void (*destroy)(compressor_t *stream);
};
+/**
+ * @brief Check if a given compressor is available
+ *
+ * @memberof compressor_t
+ *
+ * This function checks if a given compressor is available, since some
+ * compressors may not be supported yet, or simply disabled in the
+ * compile configuration.
+ *
+ * @param id A SquashFS compressor id
+ *
+ * @return true if the given compressor is available
+ */
bool compressor_exists(E_SQFS_COMPRESSOR id);
+/**
+ * @brief Create a compressor object
+ *
+ * @memberof compressor_t
+ *
+ * @param id A SquashFS compressor id
+ * @param compress true if the resulting object should compress data, false
+ * if it should actually extract already compressed blocks.
+ * @param block_size The configured block size for the SquashFS image. May be
+ * of interest to some compressors.
+ *
+ * @return A pointer to a new compressor object or NULL on failure.
+ */
compressor_t *compressor_create(E_SQFS_COMPRESSOR id, bool compress,
size_t block_size);
diff --git a/include/frag_reader.h b/include/frag_reader.h
index 6495f5b..8a3d4cc 100644
--- a/include/frag_reader.h
+++ b/include/frag_reader.h
@@ -8,6 +8,11 @@
#include <stdint.h>
#include <stddef.h>
+/**
+ * @struct frag_reader_t
+ *
+ * @brief A simple interface for accessing fragments in a SquashFS image
+ */
typedef struct {
sqfs_fragment_t *tbl;
size_t num_fragments;
@@ -20,11 +25,51 @@ typedef struct {
uint8_t buffer[];
} frag_reader_t;
+/**
+ * @brief Create a fragment reader
+ *
+ * @memberof frag_reader_t
+ *
+ * This function internally reads and decodes the fragment table from the
+ * image and prints error messages to stderr on the way if it fails.
+ *
+ * @param super A pointer to the SquashFS super block read from the image
+ * @param fd A file descriptor of opened the SquashFS image
+ * @param cmp A pointer to a compressor object to be used for reading meta
+ * data blocks from the image.
+ *
+ * @return A pointer to a new fragment reader or NULL on failure
+ */
frag_reader_t *frag_reader_create(sqfs_super_t *super, int fd,
compressor_t *cmp);
+/**
+ * @brief Destroy a fragment reader and free all memory it uses
+ *
+ * @memberof frag_reader_t
+ *
+ * @param f A pointer to a fragment reader object
+ */
void frag_reader_destroy(frag_reader_t *f);
+/**
+ * @brief Read tail-end packed data from a fragment
+ *
+ * @memberof frag_reader_t
+ *
+ * This function internally takes care of loading and uncompressing the
+ * fragment block (which is skipped if it has already been loaded earlier).
+ * It prints error messages to stderr on the way if it fails, including such
+ * errors as trying to index beyond the fragment table.
+ *
+ * @param f A pointer to a fragment reader object
+ * @param index A fragment index such as stored in an inode
+ * @param offset A byte offset into the fragment block addressed by the index
+ * @param buffer A pointer to a destination buffer to copy decoded data to
+ * @param size The number of bytes to copy into the destination buffer
+ *
+ * @return Zero on success, -1 on failure
+ */
int frag_reader_read(frag_reader_t *f, size_t index, size_t offset,
void *buffer, size_t size);
diff --git a/include/fstree.h b/include/fstree.h
index 5a8e422..f2ed67f 100644
--- a/include/fstree.h
+++ b/include/fstree.h
@@ -13,46 +13,197 @@ typedef struct file_info_t file_info_t;
typedef struct dir_info_t dir_info_t;
typedef struct fstree_t fstree_t;
+/**
+ * @struct file_info_t
+ *
+ * @brief Additional meta data stored in a @ref tree_node_t for regular files
+ */
struct file_info_t {
char *input_file;
+
+ /**
+ * @brief Linked list pointer for aggregating fragments
+ *
+ * When writing out data blocks, files that don't have a multiple of
+ * the block size have their tail ends gathered in a fragment block.
+ * A linked list is used to keep track of which files share the same
+ * fragment block.
+ */
file_info_t *frag_next;
+
+ /**
+ * @brief Total size of the file in bytes
+ */
uint64_t size;
+
+ /**
+ * @brief Absolute position of the first data block
+ */
uint64_t startblock;
+
+ /**
+ * @brief Fragment index
+ *
+ * If the size is not a multiple of the block size, this holds an
+ * index into the fragment table.
+ */
uint32_t fragment;
+
+ /**
+ * @brief Byte offset into the fragment block
+ *
+ * If the size is not a multiple of the block size, this holds an
+ * offset into the fragment block.
+ */
uint32_t fragment_offset;
+
+ /**
+ * @brief Stores the compressed file block sizes
+ *
+ * For each full data block, stores the compressed size. Bit number
+ * 24 is set if the block is stored uncompressed.
+ */
uint32_t blocksizes[];
};
+/**
+ * @struct dir_info_t
+ *
+ * @brief Additional meta data stored in a @ref tree_node_t for directories
+ */
struct dir_info_t {
+ /**
+ * @brief Pointer to the head of the linked list of children
+ */
tree_node_t *children;
+
+ /**
+ * @brief Size of the directory
+ *
+ * Computed and updated on the fly while writing directory
+ * meta data to disk.
+ */
uint64_t size;
+
+ /**
+ * @brief Start block offset, relative to directory table start
+ *
+ * Offset of the compressed meta data block where the directory
+ * listing is stored in the SquashFS image.
+ */
uint64_t start_block;
+
+ /**
+ * @brief Byte offset into the uncompressed meta data block
+ *
+ * Points at where in the meta data block the directory listing begins.
+ */
uint32_t block_offset;
+
+ /**
+ * @brief Set to true for implicitly generated directories
+ */
bool created_implicitly;
};
+/**
+ * @struct tree_node_t
+ *
+ * @brief A node in a file system tree
+ */
struct tree_node_t {
+ /**
+ * @brief Linked list pointer to the next node in the same directory
+ */
tree_node_t *next;
+
+ /**
+ * @brief Pointer to directory node that this node is in
+ *
+ * This is NULL only for the root node
+ */
tree_node_t *parent;
+
+ /**
+ * @brief Pointer into the payload area where the node name is stored
+ *
+ * For the root node, this points to an empty string
+ */
char *name;
+
uint32_t uid;
uint32_t gid;
uint16_t mode;
+ /**
+ * @brief SquashFS inode refernce number
+ *
+ * This is computed and stored here on the fly when writing inodes
+ * generated from tree nodes to the SquashFS image.
+ *
+ * An inode reference is the 32 bit offset of the compressed meta data
+ * block, shifted left by 16 and ored with a 13 bit offset into the
+ * uncompressed meta data block.
+ */
uint64_t inode_ref;
+
+ /**
+ * @brief inode number
+ *
+ * This is computed and stored here on the fly when writing inodes
+ * generated from tree nodes to the SquashFS image.
+ */
uint32_t inode_num;
+
+ /**
+ * @brief SquashFS inode type used for this tree node
+ *
+ * This is computed and stored here on the fly when writing inodes
+ * generated from tree nodes to the SquashFS image. It can't be
+ * easily determined in advance since it depends also on the size
+ * of the node, which means for directories the size of the directory
+ * entries once written to disk.
+ *
+ * All code that actually processes tree nodes should use the mode
+ * field instead (mode & S_IFMT gives us the node type). It is stored
+ * here when generating inodes since we need it later on to generate
+ * directory entries.
+ */
int type;
union {
+ /**
+ * @brief Pointer into payload area storing directory meta data
+ */
dir_info_t *dir;
+
+ /**
+ * @brief Pointer into payload area storing file meta data
+ */
file_info_t *file;
+
+ /**
+ * @brief Pointer into payload area storing symlink target
+ */
char *slink_target;
+
+ /**
+ * @brief A device number for device special files
+ */
uint64_t devno;
} data;
+ /**
+ * @brief Additional data stored in the tree node
+ */
uint8_t payload[];
};
+/**
+ * @struct fstree_t
+ *
+ * @brief Encapsulates a file system tree
+ */
struct fstree_t {
uint32_t default_uid;
uint32_t default_gid;
@@ -63,21 +214,110 @@ struct fstree_t {
tree_node_t *root;
};
+/**
+ * @brief Initialize an fstree object
+ *
+ * @memberof fstree_t
+ *
+ * Initializing means copying over the default values and creating a root node.
+ * On error, an error message is written to stderr.
+ *
+ * @param fs A pointer to an uninitialized fstree object
+ * @param block_size The data block size for regular files
+ * @param mtime Default modification time stamp to use on all nodes
+ * @param default_mode Default permission bits to use on implicitly created
+ * directories.
+ * @param default_uid Default UID to set on implicitly created directories.
+ * @param default_gid Default GID to set on implicitly created directories.
+ *
+ * @return Zero on success, -1 on failure
+ */
int fstree_init(fstree_t *fs, size_t block_size, uint32_t mtime,
uint16_t default_mode, uint32_t default_uid,
uint32_t default_gid);
+/**
+ * @brief Clean up an fstree object and free all memory it uses
+ *
+ * @memberof fstree_t
+ *
+ * This function also recursively frees all tree nodes.
+ *
+ * @param fs A pointer to an fstree object
+ */
void fstree_cleanup(fstree_t *fs);
+/**
+ * @brief Add a generic node to an fstree object
+ *
+ * @memberof fstree_t
+ *
+ * The new node is inserted by path. If some components of the path don't
+ * exist, they are created as directories with default permissions, like
+ * mkdir -p would, and marked as implcitily created. A subsequent call that
+ * tries to create an existing tree node will fail, except if the target
+ * is an implicitly created directory node and the call tries to create it
+ * as a directory. This will simply overwrite the permissions and ownership.
+ * The implicitly created flag is then cleared and subsequent attempts to
+ * create this directory again will also fail.
+ *
+ * This function does not print anything to stderr, instead it sets an
+ * appropriate errno value.
+ *
+ * @param fs A pointer to an fstree object
+ * @param path The path of the new object to insert
+ * @param mode Specifies both access permission and what kind of node
+ * to create
+ * @param uid The user id that owns the new node
+ * @param gid The group id that owns the new node
+ * @param extra_len An additional number of bytes to allocate for payload data
+ *
+ * @return A pointer to the new tree node or NULL on failure
+ */
tree_node_t *fstree_add(fstree_t *fs, const char *path, uint16_t mode,
uint32_t uid, uint32_t gid, size_t extra_len);
+/**
+ * @brief A wrappter around @ref fstree_add for regular files
+ *
+ * @memberof fstree_t
+ *
+ * This function internally computes the number of extra payload bytes
+ * requiered and sets up the payload pointers propperly, as they are
+ * different than for other types of nodes.
+ *
+ * @return A pointer to the new tree node or NULL on failure
+ */
tree_node_t *fstree_add_file(fstree_t *fs, const char *path, uint16_t mode,
uint32_t uid, uint32_t gid, uint64_t filesz,
const char *input);
+/**
+ * @brief Load an fstree from a text file describing it
+ *
+ * @memberof fstree_t
+ *
+ * This function parses the file format accepted by gensquashfs and restores
+ * a file system tree from it.
+ *
+ * On failure, an error report with filename and line number is written
+ * to stderr.
+ *
+ * @param fs A pointer to an fstree object that is already initialized
+ * prior to calling this function.
+ * @param filename The path to the input file to process.
+ *
+ * @return Zero on success, -1 on failure.
+ */
int fstree_from_file(fstree_t *fs, const char *filename);
+/**
+ * @brief Lexicographically sort all directory contents
+ *
+ * @memberof fstree_t
+ *
+ * @param fs A pointer to an fstree object
+ */
void fstree_sort(fstree_t *fs);
#endif /* FSTREE_H */
diff --git a/include/id_table.h b/include/id_table.h
index 600eb64..788519c 100644
--- a/include/id_table.h
+++ b/include/id_table.h
@@ -7,21 +7,100 @@
#include "compress.h"
+/**
+ * @struct id_table_t
+ *
+ * @brief Encapsulates the ID table used by SquashFS
+ */
typedef struct {
+ /**
+ * @brief Array of unique 32 bit IDs
+ */
uint32_t *ids;
+
+ /**
+ * @brief Number of 32 bit IDs stored in the array
+ */
size_t num_ids;
+
+ /**
+ * @brief Actual size of the array, i.e. maximum available
+ */
size_t max_ids;
} id_table_t;
+/**
+ * @brief Initialize an ID table
+ *
+ * @memberof id_table_t
+ *
+ * @note This function internally prints error message to stderr on failure
+ *
+ * @param tbl A pointer to an uninitialized ID table
+ *
+ * @return Zero on success, -1 on failure
+ */
int id_table_init(id_table_t *tbl);
+/**
+ * @brief Cleanup and free an ID table
+ *
+ * @memberof id_table_t
+ *
+ * @param tbl A pointer to an ID table
+ */
void id_table_cleanup(id_table_t *tbl);
+/**
+ * @brief Resolve a 32 bit to a 16 bit table index
+ *
+ * @memberof id_table_t
+ *
+ * @note This function internally prints error message to stderr on failure
+ *
+ * @param tbl A pointer to an ID table
+ * @param id A 32 bit ID to resolve
+ * @param out Returns the 16 bit table index
+ *
+ * @return Zero on success, -1 on failure
+ */
int id_table_id_to_index(id_table_t *tbl, uint32_t id, uint16_t *out);
+/**
+ * @brief Write an ID table to a SquashFS image
+ *
+ * @memberof id_table_t
+ *
+ * @note This function internally prints error message to stderr on failure
+ *
+ * @param tbl A pointer to an ID table
+ * @param outfd A file descriptor to write the data to
+ * @param super A pointer to the SquashFS super block to store the ID table
+ * offset in
+ * @param cmp A pointer to the compressor to use for compressing the ID
+ * table meta data blocks
+ *
+ * @return Zero on success, -1 on failure
+ */
int id_table_write(id_table_t *tbl, int outfd, sqfs_super_t *super,
compressor_t *cmp);
+/**
+ * @brief Read an ID table from a SquashFS image
+ *
+ * @memberof id_table_t
+ *
+ * @note This function internally prints error message to stderr on failure
+ *
+ * @param tbl A pointer to an ID table
+ * @param fd A file descriptor to read the data from
+ * @param super A pointer to the SquashFS super block that tells us where
+ * the ID table is stored
+ * @param cmp A pointer to the compressor to use for extracting the ID
+ * table meta data blocks
+ *
+ * @return Zero on success, -1 on failure
+ */
int id_table_read(id_table_t *tbl, int fd, sqfs_super_t *super,
compressor_t *cmp);
diff --git a/include/meta_reader.h b/include/meta_reader.h
index 3085383..78c0db3 100644
--- a/include/meta_reader.h
+++ b/include/meta_reader.h
@@ -5,32 +5,166 @@
#include "compress.h"
#include "squashfs.h"
+/**
+ * @struct meta_reader_t
+ *
+ * @brief Abstracts away I/O on SquashFS meta data
+ */
typedef struct {
+ /**
+ * @brief The location of the current block in the file
+ */
uint64_t block_offset;
+
+ /**
+ * @brief The location of the next block after the current one
+ */
uint64_t next_block;
+
+ /**
+ * @brief A byte offset into the uncompressed data of the current block
+ */
size_t offset;
+
+ /**
+ * @brief The underlying file descriptor to read from
+ */
int fd;
+
+ /**
+ * @brief A pointer to the compressor to use for extracting data
+ */
compressor_t *cmp;
+
+ /**
+ * @brief The raw data read from the input file
+ */
uint8_t data[SQFS_META_BLOCK_SIZE];
+
+ /**
+ * @brief The uncompressed data read from the input file
+ */
uint8_t scratch[SQFS_META_BLOCK_SIZE];
} meta_reader_t;
+/**
+ * @brief Create a meta data reader
+ *
+ * @memberof meta_reader_t
+ *
+ * @note This function internally prints error message to stderr on failure
+ *
+ * @param fd The underlying file descriptor to read from
+ * @param cmp A pointer to a compressor to use for extracting the data
+ *
+ * @return A pointer to a meta data reader, NULL on failure
+ */
meta_reader_t *meta_reader_create(int fd, compressor_t *cmp);
+/**
+ * @brief Destroy a meta data reader and free all memory used by it
+ *
+ * @memberof meta_reader_t
+ *
+ * @param m A pointer to a meta data reader
+ */
void meta_reader_destroy(meta_reader_t *m);
+/**
+ * @brief Seek to a specific meta data block and offset
+ *
+ * @memberof meta_reader_t
+ *
+ * @note This function internally prints error message to stderr on failure
+ *
+ * @param m A pointer to a meta data reader
+ * @param block_start The absolute position of the 16 bit header right before
+ * the compressed data block
+ * @param offset A byte offset into the data block
+ *
+ * @return Zero on success, -1 on failure
+ */
int meta_reader_seek(meta_reader_t *m, uint64_t block_start,
size_t offset);
+/**
+ * @brief Read a chunk of data from a meta data block
+ *
+ * @memberof meta_reader_t
+ *
+ * @note This function internally prints error message to stderr on failure
+ *
+ * If the end of the block is reached, this function transparently tries to
+ * interpret the data after the current block as a further meta data block,
+ * i.e. it can transparently read across multiple meta data blocks.
+ *
+ * @param m A pointer to a meta data reader
+ * @param data A pointer to a memory block to write the data to
+ * @param size The number of bytes to read
+ *
+ * @return Zero on success, -1 on failure
+ */
int meta_reader_read(meta_reader_t *m, void *data, size_t size);
+/**
+ * @brief Read an inode from a meta data block
+ *
+ * @memberof meta_reader_t
+ *
+ * @note This function internally prints error message to stderr on failure
+ *
+ * This function is a conveniance wrapper around @ref meta_reader_read that
+ * reads and decodes an entire SquashFS inode. It first reads the common inode
+ * header, interprets it and reads the additional, type dependend data.
+ *
+ * @param ir A pointer to a meta data reader
+ * @param super A pointer to the SquashFS super block
+ * @param block_start A byte offset relative to the inode table start where
+ * the meta data containing the inode starts
+ * @param offset A byte offset into the uncompressed meta data block
+ * where the inode is stored
+ *
+ * @return A pointer to the decoded inode or NULL on failure. Can be freed
+ * with a single free call.
+ */
sqfs_inode_generic_t *meta_reader_read_inode(meta_reader_t *ir,
sqfs_super_t *super,
uint64_t block_start,
size_t offset);
+/**
+ * @brief Read a directory header from a meta data block
+ *
+ * @memberof meta_reader_t
+ *
+ * @note This function internally prints error message to stderr on failure
+ *
+ * This function is a conveniance wrapper around @ref meta_reader_read that
+ * reads and decodes a SquashFS directory header.
+ *
+ * @param m A pointer to a meta data reader
+ * @param hdr A pointer to a directory header structure to write the decoded
+ * data to
+ *
+ * @return Zero on success, -1 on failure
+ */
int meta_reader_read_dir_header(meta_reader_t *m, sqfs_dir_header_t *hdr);
+/**
+ * @brief Read a directory entry from a meta data block
+ *
+ * @memberof meta_reader_t
+ *
+ * @note This function internally prints error message to stderr on failure
+ *
+ * This function is a conveniance wrapper around @ref meta_reader_read that
+ * reads and decodes a SquashFS directory entry.
+ *
+ * @param m A pointer to a meta data reader
+ *
+ * @return A pointer to a directory entry or NULL on failure. Can be freed
+ * with a single free call.
+ */
sqfs_dir_entry_t *meta_reader_read_dir_ent(meta_reader_t *m);
#endif /* META_READER_H */
diff --git a/include/meta_writer.h b/include/meta_writer.h
index 7f1be9a..9dcc22d 100644
--- a/include/meta_writer.h
+++ b/include/meta_writer.h
@@ -5,21 +5,101 @@
#include "compress.h"
#include "squashfs.h"
+/**
+ * @struct meta_writer_t
+ *
+ * @brief Abstracts away I/O on SquashFS meta data
+ */
typedef struct {
+ /**
+ * @brief A byte offset into the uncompressed data of the current block
+ */
size_t offset;
+
+ /**
+ * @brief The location of the current block in the file
+ */
size_t block_offset;
+
+ /**
+ * @brief The underlying file descriptor to write to
+ */
int outfd;
+
+ /**
+ * @brief A pointer to the compressor to use for compressing the data
+ */
compressor_t *cmp;
+
+ /**
+ * @brief The raw data chunk that data is appended to
+ */
uint8_t data[SQFS_META_BLOCK_SIZE + 2];
+
+ /**
+ * @brief Scratch buffer for compressing data
+ */
uint8_t scratch[SQFS_META_BLOCK_SIZE + 2];
} meta_writer_t;
+/**
+ * @brief Create a meta data writer
+ *
+ * @memberof meta_writer_t
+ *
+ * @note This function internally prints error message to stderr on failure
+ *
+ * @param fd The underlying file descriptor to write from
+ * @param cmp A pointer to a compressor to use for compressing the data
+ *
+ * @return A pointer to a meta data writer, NULL on failure
+ */
meta_writer_t *meta_writer_create(int fd, compressor_t *cmp);
+/**
+ * @brief Destroy a meta data writer and free all memory used by it
+ *
+ * @memberof meta_writer_t
+ *
+ * @param m A pointer to a meta data reader
+ */
void meta_writer_destroy(meta_writer_t *m);
+/**
+ * @brief Flush the currently unfinished meta data block to disk
+ *
+ * @memberof meta_writer_t
+ *
+ * @note This function internally prints error message to stderr on failure
+ *
+ * If data has been collected in the block buffer but it is not complete yet,
+ * this function tries to compress it and write it out anyway and reset the
+ * internal counters.
+ *
+ * @param m A pointer to a meta data reader
+ *
+ * @return Zero on success, -1 on failure
+ */
int meta_writer_flush(meta_writer_t *m);
+/**
+ * @brief Append data to the current meta data block
+ *
+ * @memberof meta_writer_t
+ *
+ * @note This function internally prints error message to stderr on failure
+ *
+ * This function appends the input data to an internal meta data buffer. If
+ * the internal buffer is full, it is compressed and written to disk using
+ * @ref meta_writer flush, i.e. the function allows for transparent writing
+ * across meta data blocks.
+ *
+ * @param m A pointer to a meta data reader
+ * @param data A pointer to the data block to append
+ * @param size The number of bytes to read from the data blob
+ *
+ * @return Zero on success, -1 on failure
+ */
int meta_writer_append(meta_writer_t *m, const void *data, size_t size);
#endif /* META_WRITER_H */
diff --git a/include/table.h b/include/table.h
index 3eb5655..ed2cb4a 100644
--- a/include/table.h
+++ b/include/table.h
@@ -8,6 +8,27 @@
#include <stdint.h>
#include <stddef.h>
+/**
+ * @brief Convenience function for writing meta data to a SquashFS image
+ *
+ * @note This function internally prints error message to stderr on failure
+ *
+ * This function internally creates a meta data writer and writes 'count'
+ * blocks of data from 'data' to it, each 'entsize' bytes in size. For each
+ * meta data block, it remembers the 64 bit start address, writes out all
+ * addresses to the and returns the location where the address list starts.
+ * For instance, the fragment table and ID table are stored in this format.
+ *
+ * @param outfd The file descriptor to write to
+ * @param super A pointer to the SquashFS super block
+ * @param data A pointer to the data to write out
+ * @param entsize The size of each data record
+ * @param count The number of data records to write out
+ * @param startblock Returns the location of the lookup table
+ * @param cmp A pointer to the compressor to use for the meta data writer
+ *
+ * @return Zero on success, -1 on failure
+ */
int sqfs_write_table(int outfd, sqfs_super_t *super, const void *data,
size_t entsize, size_t count, uint64_t *startblock,
compressor_t *cmp);
diff --git a/include/util.h b/include/util.h
index 1ec551c..4857539 100644
--- a/include/util.h
+++ b/include/util.h
@@ -4,14 +4,54 @@
#include <sys/types.h>
+/**
+ * @brief Turn a file path to a more usefull form
+ *
+ * Removes all preceeding and trailing slashes, shortens all sequences of
+ * slashes to a single slash and returns failure state if one of the path
+ * components is '..' or '.'.
+ *
+ * @param filename A pointer to the path to work on
+ *
+ * @return Zero on success, -1 on failure
+ */
int canonicalize_name(char *filename);
+/**
+ * @brief Write data to a file
+ *
+ * This is a wrapper around the Unix write() system call. It retries the write
+ * if it is interrupted by a signal or only part of the data was written.
+ */
ssize_t write_retry(int fd, void *data, size_t size);
+/**
+ * @brief Read data from a file
+ *
+ * This is a wrapper around the Unix read() system call. It retries the read
+ * if it is interrupted by a signal or less than the desired size was read.
+ */
ssize_t read_retry(int fd, void *buffer, size_t size);
+/**
+ * @brief A common implementation of the '--version' command line argument
+ *
+ * Prints out version information. The program name is extracted from the
+ * BSD style __progname global variable.
+ */
void print_version(void);
+/**
+ * @brief Create a directory and all its parents
+ *
+ * This is a wrapper around mkdir() that behaves like 'mkdir -p'. It tries to
+ * create every component of the given path and treats already existing entries
+ * as success.
+ *
+ * @param path A path to create
+ *
+ * @return Zero on success, -1 on failure
+ */
int mkdir_p(const char *path);
#endif /* UTIL_H */