diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sqfshelper/Makemodule.am | 5 | ||||
-rw-r--r-- | lib/sqfshelper/deserialize_fstree.c | 179 | ||||
-rw-r--r-- | lib/sqfshelper/sqfs_reader.c | 73 | ||||
-rw-r--r-- | lib/sqfshelper/tree_node_from_inode.c | 141 |
4 files changed, 1 insertions, 397 deletions
diff --git a/lib/sqfshelper/Makemodule.am b/lib/sqfshelper/Makemodule.am index 5078f69..e155fa6 100644 --- a/lib/sqfshelper/Makemodule.am +++ b/lib/sqfshelper/Makemodule.am @@ -1,8 +1,5 @@ -libsqfshelper_a_SOURCES = lib/sqfshelper/deserialize_fstree.c -libsqfshelper_a_SOURCES += lib/sqfshelper/serialize_fstree.c +libsqfshelper_a_SOURCES = lib/sqfshelper/serialize_fstree.c libsqfshelper_a_SOURCES += lib/sqfshelper/statistics.c -libsqfshelper_a_SOURCES += lib/sqfshelper/tree_node_from_inode.c -libsqfshelper_a_SOURCES += lib/sqfshelper/sqfs_reader.c libsqfshelper_a_SOURCES += lib/sqfshelper/tree_node_to_inode.c libsqfshelper_a_SOURCES += lib/sqfshelper/write_export_table.c libsqfshelper_a_SOURCES += lib/sqfshelper/print_version.c diff --git a/lib/sqfshelper/deserialize_fstree.c b/lib/sqfshelper/deserialize_fstree.c deleted file mode 100644 index 411711b..0000000 --- a/lib/sqfshelper/deserialize_fstree.c +++ /dev/null @@ -1,179 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * deserialize_fstree.c - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#include "config.h" - -#include "sqfs/meta_reader.h" -#include "sqfs/dir.h" - -#include "highlevel.h" - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -static bool node_would_be_own_parent(tree_node_t *root, tree_node_t *n) -{ - while (root != NULL) { - if (root->inode_num == n->inode_num) - return true; - - root = root->parent; - } - - return false; -} - -static bool is_name_sane(const char *name) -{ - if (strchr(name, '/') != NULL || strchr(name, '\\') != NULL) - goto fail; - - if (strcmp(name, "..") == 0 || strcmp(name, ".") == 0) - goto fail; - - return true; -fail: - fprintf(stderr, "WARNING: Found directory entry named '%s', " - "skipping\n", name); - return false; -} - -static int fill_dir(sqfs_dir_reader_t *dr, - tree_node_t *root, sqfs_id_table_t *idtbl, - fstree_t *fs) -{ - sqfs_inode_generic_t *inode; - sqfs_dir_entry_t *ent; - tree_node_t *n; - int err; - - for (;;) { - err = sqfs_dir_reader_read(dr, &ent); - if (err > 0) - break; - if (err < 0) - return -1; - - if (!is_name_sane((const char *)ent->name)) { - free(ent); - continue; - } - - err = sqfs_dir_reader_get_inode(dr, &inode); - if (err) { - free(ent); - return err; - } - - n = tree_node_from_inode(inode, idtbl, (char *)ent->name); - if (n == NULL) { - free(ent); - free(inode); - return -1; - } - - if (node_would_be_own_parent(root, n)) { - fputs("WARNING: Found a directory that " - "contains itself, skipping loop back " - "reference!\n", stderr); - free(n); - free(ent); - free(inode); - continue; - } - - free(ent); - - n->inode = inode; - n->parent = root; - n->next = root->data.dir->children; - root->data.dir->children = n; - } - - for (n = root->data.dir->children; n != NULL; n = n->next) { - if (S_ISDIR(n->mode)) { - err = sqfs_dir_reader_open_dir(dr, n->inode); - if (err) - return -1; - - if (fill_dir(dr, n, idtbl, fs)) - return -1; - } - - free(n->inode); - n->inode = NULL; - } - - return 0; -} - -int deserialize_fstree(fstree_t *out, sqfs_super_t *super, - sqfs_compressor_t *cmp, sqfs_file_t *file) -{ - sqfs_inode_generic_t *root; - sqfs_id_table_t *idtbl; - sqfs_dir_reader_t *dr; - int status = -1; - - dr = sqfs_dir_reader_create(super, cmp, file); - if (dr == NULL) - return -1; - - idtbl = sqfs_id_table_create(); - if (idtbl == NULL) - goto out_dr; - - if (sqfs_id_table_read(idtbl, file, super, cmp)) - goto out_id; - - if (sqfs_dir_reader_get_root_inode(dr, &root)) - goto out_id; - - if (root->base.type != SQFS_INODE_DIR && - root->base.type != SQFS_INODE_EXT_DIR) { - free(root); - fputs("File system root inode is not a directory inode!\n", - stderr); - goto out_id; - } - - memset(out, 0, sizeof(*out)); - out->block_size = super->block_size; - out->defaults.st_uid = 0; - out->defaults.st_gid = 0; - out->defaults.st_mode = 0755; - out->defaults.st_mtime = super->modification_time; - - out->root = tree_node_from_inode(root, idtbl, ""); - - if (out->root == NULL) { - free(root); - goto out_id; - } - - if (sqfs_dir_reader_open_dir(dr, root)) { - free(root); - goto fail_fs; - } - - free(root); - - if (fill_dir(dr, out->root, idtbl, out)) - goto fail_fs; - - tree_node_sort_recursive(out->root); - - status = 0; -out_id: - sqfs_id_table_destroy(idtbl); -out_dr: - sqfs_dir_reader_destroy(dr); - return status; -fail_fs: - fstree_cleanup(out); - goto out_id; -} diff --git a/lib/sqfshelper/sqfs_reader.c b/lib/sqfshelper/sqfs_reader.c deleted file mode 100644 index b947cf7..0000000 --- a/lib/sqfshelper/sqfs_reader.c +++ /dev/null @@ -1,73 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * sqfs_reader.c - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#include "config.h" - -#include "highlevel.h" - -#include <string.h> -#include <unistd.h> -#include <fcntl.h> - -int sqfs_reader_open(sqfs_reader_t *rd, const char *filename) -{ - sqfs_compressor_config_t cfg; - - memset(rd, 0, sizeof(*rd)); - - rd->file = sqfs_open_file(filename, SQFS_FILE_OPEN_READ_ONLY); - if (rd->file == NULL) - return -1; - - if (sqfs_super_read(&rd->super, rd->file)) - goto fail_fd; - - if (!sqfs_compressor_exists(rd->super.compression_id)) { - fprintf(stderr, "%s: unknown compressor used.\n", filename); - goto fail_fd; - } - - sqfs_compressor_config_init(&cfg, rd->super.compression_id, - rd->super.block_size, - SQFS_COMP_FLAG_UNCOMPRESS); - - rd->cmp = sqfs_compressor_create(&cfg); - if (rd->cmp == NULL) - goto fail_fd; - - if (rd->super.flags & SQFS_FLAG_COMPRESSOR_OPTIONS) { - if (rd->cmp->read_options(rd->cmp, rd->file)) - goto fail_cmp; - } - - if (deserialize_fstree(&rd->fs, &rd->super, rd->cmp, rd->file)) - goto fail_cmp; - - fstree_gen_file_list(&rd->fs); - - rd->data = data_reader_create(rd->file, &rd->super, rd->cmp); - if (rd->data == NULL) - goto fail_fs; - - return 0; -fail_fs: - fstree_cleanup(&rd->fs); -fail_cmp: - rd->cmp->destroy(rd->cmp); -fail_fd: - rd->file->destroy(rd->file); - memset(rd, 0, sizeof(*rd)); - return -1; -} - -void sqfs_reader_close(sqfs_reader_t *rd) -{ - data_reader_destroy(rd->data); - fstree_cleanup(&rd->fs); - rd->cmp->destroy(rd->cmp); - rd->file->destroy(rd->file); - memset(rd, 0, sizeof(*rd)); -} diff --git a/lib/sqfshelper/tree_node_from_inode.c b/lib/sqfshelper/tree_node_from_inode.c deleted file mode 100644 index 3ada722..0000000 --- a/lib/sqfshelper/tree_node_from_inode.c +++ /dev/null @@ -1,141 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * tree_node_from_inode.c - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#include "config.h" - -#include "highlevel.h" - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -static size_t compute_size(sqfs_inode_generic_t *inode, const char *name) -{ - size_t size = sizeof(tree_node_t) + strlen(name) + 1; - - switch (inode->base.type) { - case SQFS_INODE_DIR: - case SQFS_INODE_EXT_DIR: - size += sizeof(dir_info_t); - break; - case SQFS_INODE_FILE: - case SQFS_INODE_EXT_FILE: - size += sizeof(file_info_t); - size += inode->num_file_blocks * - sizeof(((file_info_t *)0)->block_size[0]); - break; - case SQFS_INODE_SLINK: - case SQFS_INODE_EXT_SLINK: - size += strlen(inode->slink_target) + 1; - break; - default: - break; - } - - return size; -} - -static void copy_block_sizes(sqfs_inode_generic_t *inode, tree_node_t *out) -{ - size_t i; - - out->name += inode->num_file_blocks * - sizeof(out->data.file->block_size[0]); - - for (i = 0; i < inode->num_file_blocks; ++i) - out->data.file->block_size[i] = inode->block_sizes[i]; -} - -tree_node_t *tree_node_from_inode(sqfs_inode_generic_t *inode, - const sqfs_id_table_t *idtbl, - const char *name) -{ - tree_node_t *out; - - out = calloc(1, compute_size(inode, name)); - if (out == NULL) { - perror("converting inode to fs tree node"); - return NULL; - } - - if (sqfs_id_table_index_to_id(idtbl, inode->base.uid_idx, &out->uid)) { - free(out); - return NULL; - } - - if (sqfs_id_table_index_to_id(idtbl, inode->base.gid_idx, &out->gid)) { - free(out); - return NULL; - } - - out->mode = inode->base.mode; - out->inode_num = inode->base.inode_number; - out->mod_time = inode->base.mod_time; - out->name = (char *)out->payload; - - switch (inode->base.type) { - case SQFS_INODE_DIR: - out->data.dir = (dir_info_t *)out->payload; - out->name += sizeof(dir_info_t); - - out->data.dir->size = inode->data.dir.size; - break; - case SQFS_INODE_EXT_DIR: - out->data.dir = (dir_info_t *)out->payload; - out->name += sizeof(dir_info_t); - - out->data.dir->size = inode->data.dir_ext.size; - break; - case SQFS_INODE_FILE: - out->data.file = (file_info_t *)out->payload; - out->name += sizeof(file_info_t); - - out->data.file->size = inode->data.file.file_size; - out->data.file->startblock = inode->data.file.blocks_start; - out->data.file->fragment = inode->data.file.fragment_index; - out->data.file->fragment_offset = - inode->data.file.fragment_offset; - - copy_block_sizes(inode, out); - break; - case SQFS_INODE_EXT_FILE: - out->data.file = (file_info_t *)out->payload; - out->name += sizeof(file_info_t); - - out->data.file->size = inode->data.file_ext.file_size; - out->data.file->sparse = inode->data.file_ext.sparse; - out->data.file->startblock = inode->data.file_ext.blocks_start; - out->data.file->fragment = inode->data.file_ext.fragment_idx; - out->data.file->fragment_offset = - inode->data.file_ext.fragment_offset; - - copy_block_sizes(inode, out); - break; - case SQFS_INODE_SLINK: - case SQFS_INODE_EXT_SLINK: - out->data.slink_target = (char *)out->payload; - strcpy(out->data.slink_target, inode->slink_target); - - out->name = (char *)out->payload + - strlen(inode->slink_target) + 1; - break; - case SQFS_INODE_BDEV: - case SQFS_INODE_CDEV: - out->name = (char *)out->payload; - out->data.devno = inode->data.dev.devno; - break; - case SQFS_INODE_EXT_BDEV: - case SQFS_INODE_EXT_CDEV: - out->name = (char *)out->payload; - out->data.devno = inode->data.dev_ext.devno; - break; - default: - break; - } - - strcpy(out->name, name); - return out; -} |