diff options
Diffstat (limited to 'include/fstree.h')
-rw-r--r-- | include/fstree.h | 240 |
1 files changed, 240 insertions, 0 deletions
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 */ |