diff options
-rw-r--r-- | include/sqfs/id_table.h | 20 | ||||
-rw-r--r-- | lib/Makemodule.am | 3 | ||||
-rw-r--r-- | lib/sqfs/id_table.c | 99 | ||||
-rw-r--r-- | lib/sqfs/id_table_read.c | 58 | ||||
-rw-r--r-- | lib/sqfs/id_table_write.c | 32 | ||||
-rw-r--r-- | lib/sqfshelper/deserialize_fstree.c | 13 | ||||
-rw-r--r-- | lib/sqfshelper/tree_node_from_inode.c | 18 | ||||
-rw-r--r-- | mkfs/mkfs.c | 11 | ||||
-rw-r--r-- | tar/tar2sqfs.c | 11 |
9 files changed, 128 insertions, 137 deletions
diff --git a/include/sqfs/id_table.h b/include/sqfs/id_table.h index b209785..951c55e 100644 --- a/include/sqfs/id_table.h +++ b/include/sqfs/id_table.h @@ -14,26 +14,16 @@ #include "compress.h" -/* Encapsulates the ID table used by SquashFS */ -typedef struct { - /* Array of unique 32 bit IDs */ - uint32_t *ids; - - /* Number of 32 bit IDs stored in the array */ - size_t num_ids; - - /* Actual size of the array, i.e. maximum available */ - size_t max_ids; -} id_table_t; +typedef struct id_table_t id_table_t; #ifdef __cplusplus extern "C" { #endif -/* Returns 0 on success. Prints error message to stderr on failure. */ -int id_table_init(id_table_t *tbl); +/* Prints error message to stderr on failure. */ +id_table_t *id_table_create(void); -void id_table_cleanup(id_table_t *tbl); +void id_table_destroy(id_table_t *tbl); /* Resolve a 32 bit to a 16 bit table index. Returns 0 on success. Internally prints errors to stderr. */ @@ -49,6 +39,8 @@ int id_table_write(id_table_t *tbl, int outfd, sqfs_super_t *super, int id_table_read(id_table_t *tbl, int fd, sqfs_super_t *super, compressor_t *cmp); +int id_table_index_to_id(const id_table_t *tbl, uint16_t index, uint32_t *out); + #ifdef __cplusplus } #endif diff --git a/lib/Makemodule.am b/lib/Makemodule.am index 3681344..180833e 100644 --- a/lib/Makemodule.am +++ b/lib/Makemodule.am @@ -53,8 +53,7 @@ libsquashfs_la_SOURCES += lib/sqfs/meta_writer.c lib/sqfs/super.c libsquashfs_la_SOURCES += lib/sqfs/id_table.c libsquashfs_la_SOURCES += lib/sqfs/write_table.c include/highlevel.h libsquashfs_la_SOURCES += lib/sqfs/read_super.c lib/sqfs/meta_reader.c -libsquashfs_la_SOURCES += lib/sqfs/id_table_write.c -libsquashfs_la_SOURCES += lib/sqfs/id_table_read.c lib/sqfs/read_inode.c +libsquashfs_la_SOURCES += lib/sqfs/read_inode.c libsquashfs_la_SOURCES += lib/sqfs/readdir.c libsquashfs_la_SOURCES += lib/sqfs/xattr.c libsquashfs_la_SOURCES += lib/sqfs/read_table.c diff --git a/lib/sqfs/id_table.c b/lib/sqfs/id_table.c index 192cdbb..75d5db4 100644 --- a/lib/sqfs/id_table.c +++ b/lib/sqfs/id_table.c @@ -7,20 +7,32 @@ #include "config.h" #include "sqfs/id_table.h" +#include "sqfs/table.h" #include <stdlib.h> #include <string.h> #include <stdio.h> -int id_table_init(id_table_t *tbl) +struct id_table_t { + uint32_t *ids; + size_t num_ids; + size_t max_ids; +}; + +id_table_t *id_table_create(void) { - memset(tbl, 0, sizeof(*tbl)); - return 0; + id_table_t *tbl = calloc(1, sizeof(*tbl)); + + if (tbl == NULL) + perror("Creating ID table"); + + return tbl; } -void id_table_cleanup(id_table_t *tbl) +void id_table_destroy(id_table_t *tbl) { free(tbl->ids); + free(tbl); } int id_table_id_to_index(id_table_t *tbl, uint32_t id, uint16_t *out) @@ -57,3 +69,82 @@ int id_table_id_to_index(id_table_t *tbl, uint32_t id, uint16_t *out) tbl->ids[tbl->num_ids++] = id; return 0; } + +int id_table_index_to_id(const id_table_t *tbl, uint16_t index, uint32_t *out) +{ + if (index >= tbl->num_ids) { + fputs("attempted out of bounds ID table access\n", stderr); + return -1; + } + + *out = tbl->ids[index]; + return 0; +} + +int id_table_read(id_table_t *tbl, int fd, sqfs_super_t *super, + compressor_t *cmp) +{ + uint64_t upper_limit, lower_limit; + size_t i; + + if (tbl->ids != NULL) { + free(tbl->ids); + tbl->num_ids = 0; + tbl->max_ids = 0; + tbl->ids = NULL; + } + + if (!super->id_count || super->id_table_start >= super->bytes_used) { + fputs("ID table missing from file system\n", stderr); + return -1; + } + + upper_limit = super->id_table_start; + lower_limit = super->directory_table_start; + + if (super->fragment_table_start > lower_limit && + super->fragment_table_start < upper_limit) { + lower_limit = super->fragment_table_start; + } + + if (super->export_table_start > lower_limit && + super->export_table_start < upper_limit) { + lower_limit = super->export_table_start; + } + + tbl->num_ids = super->id_count; + tbl->max_ids = super->id_count; + tbl->ids = sqfs_read_table(fd, cmp, tbl->num_ids * sizeof(uint32_t), + super->id_table_start, lower_limit, + upper_limit); + if (tbl->ids == NULL) + return -1; + + for (i = 0; i < tbl->num_ids; ++i) + tbl->ids[i] = le32toh(tbl->ids[i]); + + return 0; +} + +int id_table_write(id_table_t *tbl, int outfd, sqfs_super_t *super, + compressor_t *cmp) +{ + uint64_t start; + size_t i; + int ret; + + for (i = 0; i < tbl->num_ids; ++i) + tbl->ids[i] = htole32(tbl->ids[i]); + + super->id_count = tbl->num_ids; + + ret = sqfs_write_table(outfd, super, cmp, tbl->ids, + sizeof(tbl->ids[0]) * tbl->num_ids, &start); + + super->id_table_start = start; + + for (i = 0; i < tbl->num_ids; ++i) + tbl->ids[i] = le32toh(tbl->ids[i]); + + return ret; +} diff --git a/lib/sqfs/id_table_read.c b/lib/sqfs/id_table_read.c deleted file mode 100644 index ccb0fc8..0000000 --- a/lib/sqfs/id_table_read.c +++ /dev/null @@ -1,58 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * id_table_read.c - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#include "config.h" - -#include "highlevel.h" -#include "util.h" - -#include <stdlib.h> -#include <stdio.h> - -int id_table_read(id_table_t *tbl, int fd, sqfs_super_t *super, - compressor_t *cmp) -{ - uint64_t upper_limit, lower_limit; - size_t i; - - if (tbl->ids != NULL) { - free(tbl->ids); - tbl->num_ids = 0; - tbl->max_ids = 0; - tbl->ids = NULL; - } - - if (!super->id_count || super->id_table_start >= super->bytes_used) { - fputs("ID table missing from file system\n", stderr); - return -1; - } - - upper_limit = super->id_table_start; - lower_limit = super->directory_table_start; - - if (super->fragment_table_start > lower_limit && - super->fragment_table_start < upper_limit) { - lower_limit = super->fragment_table_start; - } - - if (super->export_table_start > lower_limit && - super->export_table_start < upper_limit) { - lower_limit = super->export_table_start; - } - - tbl->num_ids = super->id_count; - tbl->max_ids = super->id_count; - tbl->ids = sqfs_read_table(fd, cmp, tbl->num_ids * sizeof(uint32_t), - super->id_table_start, lower_limit, - upper_limit); - if (tbl->ids == NULL) - return -1; - - for (i = 0; i < tbl->num_ids; ++i) - tbl->ids[i] = le32toh(tbl->ids[i]); - - return 0; -} diff --git a/lib/sqfs/id_table_write.c b/lib/sqfs/id_table_write.c deleted file mode 100644 index 0f0e475..0000000 --- a/lib/sqfs/id_table_write.c +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * id_table_write.c - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#include "config.h" - -#include "highlevel.h" - -int id_table_write(id_table_t *tbl, int outfd, sqfs_super_t *super, - compressor_t *cmp) -{ - uint64_t start; - size_t i; - int ret; - - for (i = 0; i < tbl->num_ids; ++i) - tbl->ids[i] = htole32(tbl->ids[i]); - - super->id_count = tbl->num_ids; - - ret = sqfs_write_table(outfd, super, cmp, tbl->ids, - sizeof(tbl->ids[0]) * tbl->num_ids, &start); - - super->id_table_start = start; - - for (i = 0; i < tbl->num_ids; ++i) - tbl->ids[i] = le32toh(tbl->ids[i]); - - return ret; -} diff --git a/lib/sqfshelper/deserialize_fstree.c b/lib/sqfshelper/deserialize_fstree.c index 232c382..c418b16 100644 --- a/lib/sqfshelper/deserialize_fstree.c +++ b/lib/sqfshelper/deserialize_fstree.c @@ -207,7 +207,7 @@ int deserialize_fstree(fstree_t *out, sqfs_super_t *super, compressor_t *cmp, sqfs_inode_generic_t *root; meta_reader_t *ir, *dr; xattr_reader_t *xr; - id_table_t idtbl; + id_table_t *idtbl; int status = -1; size_t offset; @@ -226,10 +226,11 @@ int deserialize_fstree(fstree_t *out, sqfs_super_t *super, compressor_t *cmp, if (dr == NULL) goto out_ir; - if (id_table_init(&idtbl)) + idtbl = id_table_create(); + if (idtbl == NULL) goto out_dr; - if (id_table_read(&idtbl, fd, super, cmp)) + if (id_table_read(idtbl, fd, super, cmp)) goto out_id; xr = xattr_reader_create(fd, super, cmp); @@ -257,7 +258,7 @@ int deserialize_fstree(fstree_t *out, sqfs_super_t *super, compressor_t *cmp, out->defaults.st_mode = 0755; out->defaults.st_mtime = super->modification_time; - out->root = tree_node_from_inode(root, &idtbl, "", super->block_size); + out->root = tree_node_from_inode(root, idtbl, "", super->block_size); if (out->root == NULL) { free(root); @@ -285,7 +286,7 @@ int deserialize_fstree(fstree_t *out, sqfs_super_t *super, compressor_t *cmp, free(root); - if (fill_dir(ir, dr, out->root, super, &idtbl, out, xr, flags)) + if (fill_dir(ir, dr, out->root, super, idtbl, out, xr, flags)) goto fail_fs; tree_node_sort_recursive(out->root); @@ -294,7 +295,7 @@ int deserialize_fstree(fstree_t *out, sqfs_super_t *super, compressor_t *cmp, out_xr: xattr_reader_destroy(xr); out_id: - id_table_cleanup(&idtbl); + id_table_destroy(idtbl); out_dr: meta_reader_destroy(dr); out_ir: diff --git a/lib/sqfshelper/tree_node_from_inode.c b/lib/sqfshelper/tree_node_from_inode.c index 582399c..e77266a 100644 --- a/lib/sqfshelper/tree_node_from_inode.c +++ b/lib/sqfshelper/tree_node_from_inode.c @@ -73,26 +73,22 @@ tree_node_t *tree_node_from_inode(sqfs_inode_generic_t *inode, { tree_node_t *out; - if (inode->base.uid_idx >= idtbl->num_ids) { - fputs("converting inode to fs tree node: UID out of range\n", - stderr); + out = calloc(1, compute_size(inode, name, block_size)); + if (out == NULL) { + perror("converting inode to fs tree node"); return NULL; } - if (inode->base.gid_idx >= idtbl->num_ids) { - fputs("converting inode to fs tree node: GID out of range\n", - stderr); + if (id_table_index_to_id(idtbl, inode->base.uid_idx, &out->uid)) { + free(out); return NULL; } - out = calloc(1, compute_size(inode, name, block_size)); - if (out == NULL) { - perror("converting inode to fs tree node"); + if (id_table_index_to_id(idtbl, inode->base.gid_idx, &out->gid)) { + free(out); return NULL; } - out->uid = idtbl->ids[inode->base.uid_idx]; - out->gid = idtbl->ids[inode->base.gid_idx]; out->mode = inode->base.mode; out->inode_num = inode->base.inode_number; out->mod_time = inode->base.mod_time; diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c index 512b30b..75d4cd8 100644 --- a/mkfs/mkfs.c +++ b/mkfs/mkfs.c @@ -97,7 +97,7 @@ int main(int argc, char **argv) data_writer_t *data; sqfs_super_t super; compressor_t *cmp; - id_table_t idtbl; + id_table_t *idtbl; options_t opt; fstree_t fs; int outfd; @@ -117,7 +117,8 @@ int main(int argc, char **argv) goto out_fstree; } - if (id_table_init(&idtbl)) + idtbl = id_table_create(); + if (idtbl == NULL) goto out_fstree; outfd = open(opt.outfile, opt.outmode, 0644); @@ -173,7 +174,7 @@ int main(int argc, char **argv) if (pack_files(data, &fs, &opt)) goto out_data; - if (sqfs_serialize_fstree(outfd, &super, &fs, cmp, &idtbl)) + if (sqfs_serialize_fstree(outfd, &super, &fs, cmp, idtbl)) goto out_data; if (data_writer_write_fragment_table(data)) @@ -184,7 +185,7 @@ int main(int argc, char **argv) goto out_data; } - if (id_table_write(&idtbl, outfd, &super, cmp)) + if (id_table_write(idtbl, outfd, &super, cmp)) goto out_data; if (write_xattr(outfd, &fs, &super, cmp)) @@ -209,7 +210,7 @@ out_cmp: out_outfd: close(outfd); out_idtbl: - id_table_cleanup(&idtbl); + id_table_destroy(idtbl); out_fstree: fstree_cleanup(&fs); return status; diff --git a/tar/tar2sqfs.c b/tar/tar2sqfs.c index c0f8a14..fba1a31 100644 --- a/tar/tar2sqfs.c +++ b/tar/tar2sqfs.c @@ -359,7 +359,7 @@ int main(int argc, char **argv) data_writer_t *data; sqfs_super_t super; compressor_t *cmp; - id_table_t idtbl; + id_table_t *idtbl; fstree_t fs; int ret; @@ -404,7 +404,8 @@ int main(int argc, char **argv) if (data == NULL) goto out_cmp; - if (id_table_init(&idtbl)) + idtbl = id_table_create(); + if (idtbl == NULL) goto out_data; if (process_tar_ball(&fs, data)) @@ -421,7 +422,7 @@ int main(int argc, char **argv) fstree_xattr_deduplicate(&fs); - if (sqfs_serialize_fstree(outfd, &super, &fs, cmp, &idtbl)) + if (sqfs_serialize_fstree(outfd, &super, &fs, cmp, idtbl)) goto out; if (data_writer_write_fragment_table(data)) @@ -432,7 +433,7 @@ int main(int argc, char **argv) goto out; } - if (id_table_write(&idtbl, outfd, &super, cmp)) + if (id_table_write(idtbl, outfd, &super, cmp)) goto out; if (write_xattr(outfd, &fs, &super, cmp)) @@ -451,7 +452,7 @@ int main(int argc, char **argv) status = EXIT_SUCCESS; out: - id_table_cleanup(&idtbl); + id_table_destroy(idtbl); out_data: data_writer_destroy(data); out_cmp: |