summaryrefslogtreecommitdiff
path: root/include/fstree.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/fstree.h')
-rw-r--r--include/fstree.h240
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 */