summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makemodule.am3
-rw-r--r--lib/sqfs/id_table.c99
-rw-r--r--lib/sqfs/id_table_read.c58
-rw-r--r--lib/sqfs/id_table_write.c32
-rw-r--r--lib/sqfshelper/deserialize_fstree.c13
-rw-r--r--lib/sqfshelper/tree_node_from_inode.c18
6 files changed, 110 insertions, 113 deletions
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;