diff options
-rw-r--r-- | include/fstree.h | 2 | ||||
-rw-r--r-- | include/io/dir_entry.h | 112 | ||||
-rw-r--r-- | include/io/dir_iterator.h | 78 | ||||
-rw-r--r-- | include/io/xattr.h | 35 | ||||
-rw-r--r-- | lib/fstree/Makemodule.am | 11 | ||||
-rw-r--r-- | lib/fstree/test/add_by_path.c | 3 | ||||
-rw-r--r-- | lib/fstree/test/fstree_sort.c | 3 | ||||
-rw-r--r-- | lib/fstree/test/gen_inode_numbers.c | 3 | ||||
-rw-r--r-- | lib/fstree/test/get_path.c | 4 | ||||
-rw-r--r-- | lib/fstree/test/mknode_dir.c | 4 | ||||
-rw-r--r-- | lib/fstree/test/mknode_simple.c | 4 | ||||
-rw-r--r-- | lib/io/Makemodule.am | 6 | ||||
-rw-r--r-- | lib/io/src/dir_entry.c (renamed from lib/io/src/xattr.c) | 47 | ||||
-rw-r--r-- | lib/io/src/unix/dir_iterator.c | 28 | ||||
-rw-r--r-- | lib/tar/src/iterator.c | 25 |
15 files changed, 191 insertions, 174 deletions
diff --git a/include/fstree.h b/include/fstree.h index 55f0928..779cd28 100644 --- a/include/fstree.h +++ b/include/fstree.h @@ -15,7 +15,7 @@ #include <stdio.h> #include "sqfs/predef.h" -#include "io/dir_iterator.h" +#include "io/dir_entry.h" #include "io/istream.h" #include "compat.h" diff --git a/include/io/dir_entry.h b/include/io/dir_entry.h new file mode 100644 index 0000000..7546daf --- /dev/null +++ b/include/io/dir_entry.h @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * dir_entry.h + * + * Copyright (C) 2023 David Oberhollenzer <goliath@infraroot.at> + */ +#ifndef IO_DIR_ENTRY_H +#define IO_DIR_ENTRY_H + +#include "sqfs/predef.h" + +typedef enum { + DIR_ENTRY_FLAG_MOUNT_POINT = 0x0001, + + DIR_ENTRY_FLAG_HARD_LINK = 0x0002, +} DIR_ENTRY_FLAG; + +/** + * @struct dir_entry_t + * + * @brief A directory entry returned by a @ref dir_iterator_t + */ +typedef struct { + /** + * @brief Total size of file entries + */ + sqfs_u64 size; + + /** + * @brief Unix time stamp when the entry was last modified. + * + * If necessary, the OS native time stamp is converted to Unix time. + */ + sqfs_s64 mtime; + + /** + * @brief Device number where the entry is stored on. + * + * On Windows and other non-Unix OSes, a dummy value is stored here. + */ + sqfs_u64 dev; + + /** + * @brief Device number for device special files. + * + * On Windows and other non-Unix OSes, a dummy value is stored here. + */ + sqfs_u64 rdev; + + /** + * @brief ID of the user that owns the entry. + * + * On Windows and other non-Unix OSes, this always reports user 0. + */ + sqfs_u64 uid; + + /** + * @brief ID of the group that owns the entry. + * + * On Windows and other non-Unix OSes, this always reports group 0. + */ + sqfs_u64 gid; + + /** + * @brief Unix style permissions and entry type. + * + * On Windows and other non-Unix OSes, this is synthesized from the + * Unix-like file type, default 0755 permissions for directories or + * 0644 for files. + */ + sqfs_u16 mode; + + /** + * @brief Combination of DIR_ENTRY_FLAG values + */ + sqfs_u16 flags; + + /** + * @brief Name of the entry + * + * On Unix-like OSes, the name is returned as-is. On systems like + * Windows with encoding-aware APIs, the name is converted to UTF-8. + */ + char name[]; +} dir_entry_t; + +typedef struct dir_entry_xattr_t { + struct dir_entry_xattr_t *next; + char *key; + sqfs_u8 *value; + size_t value_len; + char data[]; +} dir_entry_xattr_t; + +#ifdef __cplusplus +extern "C" { +#endif + +dir_entry_t *dir_entry_create(const char *name); + +dir_entry_xattr_t *dir_entry_xattr_create(const char *key, const sqfs_u8 *value, + size_t value_len); + +dir_entry_xattr_t *dir_entry_xattr_list_copy(const dir_entry_xattr_t *list); + +void dir_entry_xattr_list_free(dir_entry_xattr_t *list); + +#ifdef __cplusplus +} +#endif + +#endif /* IO_DIR_ENTRY_H */ diff --git a/include/io/dir_iterator.h b/include/io/dir_iterator.h index 20fcdff..6ae1cd1 100644 --- a/include/io/dir_iterator.h +++ b/include/io/dir_iterator.h @@ -7,84 +7,8 @@ #ifndef IO_DIR_ITERATOR_H #define IO_DIR_ITERATOR_H -#include "sqfs/predef.h" +#include "io/dir_entry.h" #include "io/istream.h" -#include "io/xattr.h" - -typedef enum { - DIR_ENTRY_FLAG_MOUNT_POINT = 0x0001, - - DIR_ENTRY_FLAG_HARD_LINK = 0x0002, -} DIR_ENTRY_FLAG; - -/** - * @struct dir_entry_t - * - * @brief A directory entry returned by a @ref dir_iterator_t - */ -typedef struct { - /** - * @brief Total size of file entries - */ - sqfs_u64 size; - - /** - * @brief Unix time stamp when the entry was last modified. - * - * If necessary, the OS native time stamp is converted to Unix time. - */ - sqfs_s64 mtime; - - /** - * @brief Device number where the entry is stored on. - * - * On Windows and other non-Unix OSes, a dummy value is stored here. - */ - sqfs_u64 dev; - - /** - * @brief Device number for device special files. - * - * On Windows and other non-Unix OSes, a dummy value is stored here. - */ - sqfs_u64 rdev; - - /** - * @brief ID of the user that owns the entry. - * - * On Windows and other non-Unix OSes, this always reports user 0. - */ - sqfs_u64 uid; - - /** - * @brief ID of the group that owns the entry. - * - * On Windows and other non-Unix OSes, this always reports group 0. - */ - sqfs_u64 gid; - - /** - * @brief Unix style permissions and entry type. - * - * On Windows and other non-Unix OSes, this is synthesized from the - * Unix-like file type, default 0755 permissions for directories or - * 0644 for files. - */ - sqfs_u16 mode; - - /** - * @brief Combination of DIR_ENTRY_FLAG values - */ - sqfs_u16 flags; - - /** - * @brief Name of the entry - * - * On Unix-like OSes, the name is returned as-is. On systems like - * Windows with encoding-aware APIs, the name is converted to UTF-8. - */ - char name[]; -} dir_entry_t; /** * @interface dir_iterator_t diff --git a/include/io/xattr.h b/include/io/xattr.h deleted file mode 100644 index d9f3e65..0000000 --- a/include/io/xattr.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * xattr.h - * - * Copyright (C) 2023 David Oberhollenzer <goliath@infraroot.at> - */ -#ifndef IO_XATTR_H -#define IO_XATTR_H - -#include "sqfs/predef.h" - -typedef struct dir_entry_xattr_t { - struct dir_entry_xattr_t *next; - char *key; - sqfs_u8 *value; - size_t value_len; - char data[]; -} dir_entry_xattr_t; - -#ifdef __cplusplus -extern "C" { -#endif - -dir_entry_xattr_t *dir_entry_xattr_create(const char *key, const sqfs_u8 *value, - size_t value_len); - -dir_entry_xattr_t *dir_entry_xattr_list_copy(const dir_entry_xattr_t *list); - -void dir_entry_xattr_list_free(dir_entry_xattr_t *list); - -#ifdef __cplusplus -} -#endif - -#endif /* IO_XATTR_H */ 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/xattr.c b/lib/io/src/dir_entry.c index 85b7e53..b7f38f5 100644 --- a/lib/io/src/xattr.c +++ b/lib/io/src/dir_entry.c @@ -1,28 +1,61 @@ /* SPDX-License-Identifier: GPL-3.0-or-later */ /* - * xattr.c + * dir_entry.c * * Copyright (C) 2023 David Oberhollenzer <goliath@infraroot.at> */ -#include "io/xattr.h" +#include "io/dir_entry.h" +#include "compat.h" #include <stdlib.h> #include <string.h> +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) { - size_t key_len = strlen(key); - dir_entry_xattr_t *out = calloc(1, sizeof(*out) + key_len + 1 + - value_len + 1); + 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 + 1); + 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); - out->value_len = value_len; } return out; 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/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; |