From 3f7f3654d243275332d964f9ecbb79f9eb83a5d1 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Thu, 1 Jun 2023 14:55:58 +0200 Subject: libio: split dir_entry_t from dir_iterator_t, add create helper Signed-off-by: David Oberhollenzer --- lib/fstree/Makemodule.am | 11 +++-- lib/fstree/test/add_by_path.c | 3 +- lib/fstree/test/fstree_sort.c | 3 +- lib/fstree/test/gen_inode_numbers.c | 3 +- lib/fstree/test/get_path.c | 4 +- lib/fstree/test/mknode_dir.c | 4 +- lib/fstree/test/mknode_simple.c | 4 +- lib/io/Makemodule.am | 6 +-- lib/io/src/dir_entry.c | 98 +++++++++++++++++++++++++++++++++++++ lib/io/src/unix/dir_iterator.c | 28 +++++------ lib/io/src/xattr.c | 65 ------------------------ lib/tar/src/iterator.c | 25 +++++----- 12 files changed, 135 insertions(+), 119 deletions(-) create mode 100644 lib/io/src/dir_entry.c delete mode 100644 lib/io/src/xattr.c (limited to 'lib') diff --git a/lib/fstree/Makemodule.am b/lib/fstree/Makemodule.am index 965251b..8eeaa86 100644 --- a/lib/fstree/Makemodule.am +++ b/lib/fstree/Makemodule.am @@ -5,19 +5,20 @@ libfstree_a_SOURCES = include/fstree.h lib/fstree/src/fstree.c \ noinst_LIBRARIES += libfstree.a test_mknode_simple_SOURCES = lib/fstree/test/mknode_simple.c -test_mknode_simple_LDADD = libfstree.a libutil.a libcompat.a +test_mknode_simple_LDADD = libfstree.a libio.a libutil.a libcompat.a test_mknode_dir_SOURCES = lib/fstree/test/mknode_dir.c -test_mknode_dir_LDADD = libfstree.a libutil.a libcompat.a +test_mknode_dir_LDADD = libfstree.a libio.a libutil.a libcompat.a test_gen_inode_numbers_SOURCES = lib/fstree/test/gen_inode_numbers.c -test_gen_inode_numbers_LDADD = libcommon.a libfstree.a libutil.a libcompat.a +test_gen_inode_numbers_LDADD = libcommon.a libfstree.a libio.a \ + libutil.a libcompat.a test_add_by_path_SOURCES = lib/fstree/test/add_by_path.c -test_add_by_path_LDADD = libcommon.a libfstree.a libutil.a libcompat.a +test_add_by_path_LDADD = libcommon.a libfstree.a libio.a libutil.a libcompat.a test_get_path_SOURCES = lib/fstree/test/get_path.c -test_get_path_LDADD = libcommon.a libfstree.a libutil.a libcompat.a +test_get_path_LDADD = libcommon.a libfstree.a libio.a libutil.a libcompat.a test_fstree_sort_SOURCES = lib/fstree/test/fstree_sort.c test_fstree_sort_LDADD = libcommon.a libfstree.a libio.a libutil.a libcompat.a diff --git a/lib/fstree/test/add_by_path.c b/lib/fstree/test/add_by_path.c index 7fb9d37..4fd7d3d 100644 --- a/lib/fstree/test/add_by_path.c +++ b/lib/fstree/test/add_by_path.c @@ -13,10 +13,9 @@ static dir_entry_t *mkentry(const char *name, sqfs_u16 mode, sqfs_u32 uid, sqfs_u32 gid) { - dir_entry_t *ent = calloc(1, sizeof(*ent) + strlen(name) + 1); + dir_entry_t *ent = dir_entry_create(name); TEST_NOT_NULL(ent); - strcpy(ent->name, name); ent->mode = mode; ent->uid = uid; ent->gid = gid; diff --git a/lib/fstree/test/fstree_sort.c b/lib/fstree/test/fstree_sort.c index 82d6e9d..7bce367 100644 --- a/lib/fstree/test/fstree_sort.c +++ b/lib/fstree/test/fstree_sort.c @@ -12,11 +12,10 @@ static tree_node_t *mkentry(fstree_t *fs, const char *name) { - dir_entry_t *ent = calloc(1, sizeof(*ent) + strlen(name) + 1); + dir_entry_t *ent = dir_entry_create(name); tree_node_t *out; TEST_NOT_NULL(ent); - strcpy(ent->name, name); ent->mode = S_IFBLK | 0600; ent->rdev = 1337; diff --git a/lib/fstree/test/gen_inode_numbers.c b/lib/fstree/test/gen_inode_numbers.c index ae7198e..ea310a4 100644 --- a/lib/fstree/test/gen_inode_numbers.c +++ b/lib/fstree/test/gen_inode_numbers.c @@ -12,11 +12,10 @@ static tree_node_t *gen_node(fstree_t *fs, const char *path) { - dir_entry_t *ent = calloc(1, sizeof(*ent) + strlen(path) + 1); + dir_entry_t *ent = dir_entry_create(path); tree_node_t *ret; TEST_NOT_NULL(ent); - strcpy(ent->name, path); ent->mode = S_IFDIR | 0755; ret = fstree_add_generic(fs, ent, NULL); diff --git a/lib/fstree/test/get_path.c b/lib/fstree/test/get_path.c index a158764..50faeb4 100644 --- a/lib/fstree/test/get_path.c +++ b/lib/fstree/test/get_path.c @@ -12,10 +12,8 @@ static dir_entry_t *mkentry(const char *name) { - dir_entry_t *ent = calloc(1, sizeof(*ent) + strlen(name) + 1); + dir_entry_t *ent = dir_entry_create(name); TEST_NOT_NULL(ent); - - strcpy(ent->name, name); ent->mode = S_IFDIR | 0750; ent->uid = 1000; ent->gid = 100; diff --git a/lib/fstree/test/mknode_dir.c b/lib/fstree/test/mknode_dir.c index 20cba45..080cc0e 100644 --- a/lib/fstree/test/mknode_dir.c +++ b/lib/fstree/test/mknode_dir.c @@ -11,10 +11,8 @@ static dir_entry_t *mkentry(const char *name) { - dir_entry_t *ent = calloc(1, sizeof(*ent) + strlen(name) + 1); - + dir_entry_t *ent = dir_entry_create(name); TEST_NOT_NULL(ent); - strcpy(ent->name, name); ent->mode = S_IFDIR | 0654; ent->uid = 123; ent->gid = 456; diff --git a/lib/fstree/test/mknode_simple.c b/lib/fstree/test/mknode_simple.c index 2a18121..0e7c872 100644 --- a/lib/fstree/test/mknode_simple.c +++ b/lib/fstree/test/mknode_simple.c @@ -11,10 +11,8 @@ static dir_entry_t *mkentry(const char *name, sqfs_u16 mode) { - dir_entry_t *ent = calloc(1, sizeof(*ent) + strlen(name) + 1); - + dir_entry_t *ent = dir_entry_create(name); TEST_NOT_NULL(ent); - strcpy(ent->name, name); ent->mode = mode | 0654; ent->uid = 123; ent->gid = 456; diff --git a/lib/io/Makemodule.am b/lib/io/Makemodule.am index 3be208f..5b5fc7f 100644 --- a/lib/io/Makemodule.am +++ b/lib/io/Makemodule.am @@ -1,10 +1,10 @@ libio_a_SOURCES = include/io/istream.h include/io/ostream.h include/io/xfrm.h \ - include/io/file.h include/io/std.h \ - include/io/dir_iterator.h include/io/xattr.h \ + include/io/file.h include/io/std.h include/io/dir_entry.h \ + include/io/dir_iterator.h \ lib/io/src/internal.h lib/io/src/ostream.c \ lib/io/src/istream.c lib/io/src/get_line.c lib/io/src/xfrm/ostream.c \ lib/io/src/xfrm/istream.c lib/io/src/dir_tree_iterator.c \ - lib/io/src/xattr.c + lib/io/src/dir_entry.c libio_a_CFLAGS = $(AM_CFLAGS) $(ZLIB_CFLAGS) $(XZ_CFLAGS) libio_a_CFLAGS += $(ZSTD_CFLAGS) $(BZIP2_CFLAGS) diff --git a/lib/io/src/dir_entry.c b/lib/io/src/dir_entry.c new file mode 100644 index 0000000..b7f38f5 --- /dev/null +++ b/lib/io/src/dir_entry.c @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * dir_entry.c + * + * Copyright (C) 2023 David Oberhollenzer + */ +#include "io/dir_entry.h" +#include "compat.h" + +#include +#include + +dir_entry_t *dir_entry_create(const char *name) +{ + size_t len, name_len; + dir_entry_t *out; + + name_len = strlen(name); + if (SZ_ADD_OV(name_len, 1, &name_len)) + return NULL; + if (SZ_ADD_OV(sizeof(*out), name_len, &len)) + return NULL; + + out = calloc(1, len); + if (out == NULL) + return NULL; + + memcpy(out->name, name, name_len); + return out; +} + +dir_entry_xattr_t *dir_entry_xattr_create(const char *key, const sqfs_u8 *value, + size_t value_len) +{ + dir_entry_xattr_t *out; + size_t len, key_len; + + /* key_ley = strlen(key) + 1 */ + key_len = strlen(key); + if (SZ_ADD_OV(key_len, 1, &key_len)) + return NULL; + + /* len = key_len + value_len + 1 + sizeof(*out) */ + if (SZ_ADD_OV(key_len, value_len, &len)) + return NULL; + if (SZ_ADD_OV(len, 1, &len)) + return NULL; + if (SZ_ADD_OV(len, sizeof(*out), &len)) + return NULL; + + out = calloc(1, len); + if (out != NULL) { + out->key = out->data; + out->value = (sqfs_u8 *)out->data + key_len; + out->value_len = value_len; + + memcpy(out->key, key, key_len); + memcpy(out->value, value, value_len); + } + + return out; +} + +dir_entry_xattr_t *dir_entry_xattr_list_copy(const dir_entry_xattr_t *list) +{ + dir_entry_xattr_t *new, *copy = NULL, *copy_last = NULL; + const dir_entry_xattr_t *it; + + for (it = list; it != NULL; it = it->next) { + new = dir_entry_xattr_create(it->key, it->value, + it->value_len); + if (new == NULL) { + dir_entry_xattr_list_free(copy); + return NULL; + } + + if (copy_last == NULL) { + copy = new; + copy_last = new; + } else { + copy_last->next = new; + copy_last = new; + } + } + + return copy; +} + +void dir_entry_xattr_list_free(dir_entry_xattr_t *list) +{ + dir_entry_xattr_t *old; + + while (list != NULL) { + old = list; + list = list->next; + free(old); + } +} diff --git a/lib/io/src/unix/dir_iterator.c b/lib/io/src/unix/dir_iterator.c index 7154ec9..afbf0c0 100644 --- a/lib/io/src/unix/dir_iterator.c +++ b/lib/io/src/unix/dir_iterator.c @@ -76,8 +76,6 @@ static int dir_read_link(dir_iterator_t *base, char **out) static int dir_next(dir_iterator_t *base, dir_entry_t **out) { unix_dir_iterator_t *it = (unix_dir_iterator_t *)base; - dir_entry_t *decoded; - size_t len; *out = NULL; if (it->state != 0) @@ -102,29 +100,25 @@ static int dir_next(dir_iterator_t *base, dir_entry_t **out) return it->state; } - len = strlen(it->ent->d_name); - - decoded = alloc_flex(sizeof(*decoded), 1, len + 1); - if (decoded == NULL) { + *out = dir_entry_create(it->ent->d_name); + if ((*out) == NULL) { it->state = SQFS_ERROR_ALLOC; return it->state; } - memcpy(decoded->name, it->ent->d_name, len); - decoded->mtime = it->sb.st_mtime; - decoded->dev = it->sb.st_dev; - decoded->rdev = it->sb.st_rdev; - decoded->uid = it->sb.st_uid; - decoded->gid = it->sb.st_gid; - decoded->mode = it->sb.st_mode; + (*out)->mtime = it->sb.st_mtime; + (*out)->dev = it->sb.st_dev; + (*out)->rdev = it->sb.st_rdev; + (*out)->uid = it->sb.st_uid; + (*out)->gid = it->sb.st_gid; + (*out)->mode = it->sb.st_mode; if (S_ISREG(it->sb.st_mode)) - decoded->size = it->sb.st_size; + (*out)->size = it->sb.st_size; - if (decoded->dev != it->device) - decoded->flags |= DIR_ENTRY_FLAG_MOUNT_POINT; + if ((*out)->dev != it->device) + (*out)->flags |= DIR_ENTRY_FLAG_MOUNT_POINT; - *out = decoded; return it->state; } diff --git a/lib/io/src/xattr.c b/lib/io/src/xattr.c deleted file mode 100644 index 85b7e53..0000000 --- a/lib/io/src/xattr.c +++ /dev/null @@ -1,65 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * xattr.c - * - * Copyright (C) 2023 David Oberhollenzer - */ -#include "io/xattr.h" - -#include -#include - -dir_entry_xattr_t *dir_entry_xattr_create(const char *key, const sqfs_u8 *value, - size_t value_len) -{ - size_t key_len = strlen(key); - dir_entry_xattr_t *out = calloc(1, sizeof(*out) + key_len + 1 + - value_len + 1); - - if (out != NULL) { - out->key = out->data; - out->value = (sqfs_u8 *)(out->data + key_len + 1); - - memcpy(out->key, key, key_len); - memcpy(out->value, value, value_len); - out->value_len = value_len; - } - - return out; -} - -dir_entry_xattr_t *dir_entry_xattr_list_copy(const dir_entry_xattr_t *list) -{ - dir_entry_xattr_t *new, *copy = NULL, *copy_last = NULL; - const dir_entry_xattr_t *it; - - for (it = list; it != NULL; it = it->next) { - new = dir_entry_xattr_create(it->key, it->value, - it->value_len); - if (new == NULL) { - dir_entry_xattr_list_free(copy); - return NULL; - } - - if (copy_last == NULL) { - copy = new; - copy_last = new; - } else { - copy_last->next = new; - copy_last = new; - } - } - - return copy; -} - -void dir_entry_xattr_list_free(dir_entry_xattr_t *list) -{ - dir_entry_xattr_t *old; - - while (list != NULL) { - old = list; - list = list->next; - free(old); - } -} diff --git a/lib/tar/src/iterator.c b/lib/tar/src/iterator.c index 9a6b9f7..0940905 100644 --- a/lib/tar/src/iterator.c +++ b/lib/tar/src/iterator.c @@ -158,7 +158,6 @@ static void strm_destroy(sqfs_object_t *obj) static int it_next(dir_iterator_t *it, dir_entry_t **out) { tar_iterator_t *tar = (tar_iterator_t *)it; - dir_entry_t *ent; int ret; *out = NULL; @@ -202,28 +201,26 @@ retry: return tar->state; } - ent = calloc(1, sizeof(*ent) + strlen(tar->current.name) + 1); - if (ent == NULL) { + *out = dir_entry_create(tar->current.name); + if ((*out) == NULL) { tar->state = SQFS_ERROR_ALLOC; return tar->state; } - ent->mtime = tar->current.mtime; - ent->rdev = tar->current.devno; - ent->uid = tar->current.uid; - ent->gid = tar->current.gid; - ent->mode = tar->current.mode; - strcpy(ent->name, tar->current.name); + (*out)->mtime = tar->current.mtime; + (*out)->rdev = tar->current.devno; + (*out)->uid = tar->current.uid; + (*out)->gid = tar->current.gid; + (*out)->mode = tar->current.mode; if (tar->current.is_hard_link) { - ent->mode = (S_IFLNK | 0777); - ent->flags |= DIR_ENTRY_FLAG_HARD_LINK; + (*out)->mode = (S_IFLNK | 0777); + (*out)->flags |= DIR_ENTRY_FLAG_HARD_LINK; } - if (S_ISREG(ent->mode)) - ent->size = tar->current.actual_size; + if (S_ISREG((*out)->mode)) + (*out)->size = tar->current.actual_size; - *out = ent; return 0; fail: tar->state = ret < 0 ? SQFS_ERROR_IO : 1; -- cgit v1.2.3