From 9d474f278d21ddc452d8a1a722b3735fae94115c Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Wed, 1 Jun 2022 14:21:56 +0200 Subject: Cleanup: libsqfs: sqfs_dir_reader_find_by_path Split out several repated patterns into helper functions and move the rest of the code back into dir_reader.c Signed-off-by: David Oberhollenzer --- configure.ac | 2 +- include/compat.h | 4 ++ lib/compat/Makemodule.am | 1 + lib/compat/strchrnul.c | 12 ++++++ lib/sqfs/Makemodule.am | 1 - lib/sqfs/dir_reader/dir_reader.c | 61 ++++++++++++++++++++++++++++ lib/sqfs/dir_reader/find_by_path.c | 82 -------------------------------------- lib/sqfs/dir_reader/read_tree.c | 9 +---- 8 files changed, 80 insertions(+), 92 deletions(-) create mode 100644 lib/compat/strchrnul.c delete mode 100644 lib/sqfs/dir_reader/find_by_path.c diff --git a/configure.ac b/configure.ac index 16a288f..72d4983 100644 --- a/configure.ac +++ b/configure.ac @@ -291,7 +291,7 @@ AC_CHECK_HEADERS([sys/xattr.h], [], []) AC_CHECK_HEADERS([sys/sysinfo.h], [], []) AC_CHECK_HEADERS([alloca.h], [], []) -AC_CHECK_FUNCS([strndup getopt getopt_long getsubopt fnmatch]) +AC_CHECK_FUNCS([strndup getopt getopt_long getsubopt fnmatch strchrnul]) ##### generate output ##### diff --git a/include/compat.h b/include/compat.h index 65872ec..4810acb 100644 --- a/include/compat.h +++ b/include/compat.h @@ -245,4 +245,8 @@ int stfs_tools_fprintf(FILE *strm, const char *fmt, ...) PRINTF_ATTRIB(2, 3); #define putc stfs_tools_fputc #endif +#ifndef HAVE_STRCHRNUL +char *strchrnul(const char *s, int c); +#endif + #endif /* COMPAT_H */ diff --git a/lib/compat/Makemodule.am b/lib/compat/Makemodule.am index 0426075..06fc95e 100644 --- a/lib/compat/Makemodule.am +++ b/lib/compat/Makemodule.am @@ -8,5 +8,6 @@ libcompat_a_SOURCES += lib/compat/w32_stdio.c libcompat_a_SOURCES += lib/compat/fnmatch.c libcompat_a_SOURCES += lib/compat/getopt.c libcompat_a_SOURCES += lib/compat/getopt_long.c +libcompat_a_SOURCES += lib/compat/strchrnul.c noinst_LIBRARIES += libcompat.a diff --git a/lib/compat/strchrnul.c b/lib/compat/strchrnul.c new file mode 100644 index 0000000..681b287 --- /dev/null +++ b/lib/compat/strchrnul.c @@ -0,0 +1,12 @@ +#include "config.h" +#include "compat.h" + +#ifndef HAVE_STRCHRNUL +char *strchrnul(const char *s, int c) +{ + while (*s && *((unsigned char *)s) != c) + ++s; + + return (char *)s; +} +#endif diff --git a/lib/sqfs/Makemodule.am b/lib/sqfs/Makemodule.am index f7292b1..aaf63d8 100644 --- a/lib/sqfs/Makemodule.am +++ b/lib/sqfs/Makemodule.am @@ -19,7 +19,6 @@ libsquashfs_la_SOURCES += lib/sqfs/dir_writer.c lib/sqfs/xattr/xattr_reader.c libsquashfs_la_SOURCES += lib/sqfs/read_table.c lib/sqfs/comp/compressor.c libsquashfs_la_SOURCES += lib/sqfs/comp/internal.h libsquashfs_la_SOURCES += lib/sqfs/dir_reader/dir_reader.c -libsquashfs_la_SOURCES += lib/sqfs/dir_reader/find_by_path.c libsquashfs_la_SOURCES += lib/sqfs/dir_reader/read_tree.c libsquashfs_la_SOURCES += lib/sqfs/dir_reader/internal.h libsquashfs_la_SOURCES += lib/sqfs/inode.c lib/sqfs/xattr/xattr_writer.c diff --git a/lib/sqfs/dir_reader/dir_reader.c b/lib/sqfs/dir_reader/dir_reader.c index d09e901..4ac9829 100644 --- a/lib/sqfs/dir_reader/dir_reader.c +++ b/lib/sqfs/dir_reader/dir_reader.c @@ -7,6 +7,17 @@ #define SQFS_BUILDING_DLL #include "internal.h" +static int inode_copy(const sqfs_inode_generic_t *inode, + sqfs_inode_generic_t **out) +{ + *out = alloc_flex(sizeof(*inode), 1, inode->payload_bytes_used); + if (*out == NULL) + return SQFS_ERROR_ALLOC; + + memcpy(*out, inode, sizeof(*inode) + inode->payload_bytes_used); + return 0; +} + static int dcache_key_compare(const void *ctx, const void *l, const void *r) { sqfs_u32 lhs = *((const sqfs_u32 *)l), rhs = *((const sqfs_u32 *)r); @@ -310,3 +321,53 @@ int sqfs_dir_reader_get_root_inode(sqfs_dir_reader_t *rd, return dcache_add(rd, *inode, rd->super->root_inode_ref); } + +int sqfs_dir_reader_find_by_path(sqfs_dir_reader_t *rd, + const sqfs_inode_generic_t *start, + const char *path, sqfs_inode_generic_t **out) +{ + sqfs_inode_generic_t *inode; + const char *ptr; + int ret = 0; + char *name; + + if (start == NULL) { + ret = sqfs_dir_reader_get_root_inode(rd, &inode); + } else { + ret = inode_copy(start, &inode); + } + + if (ret) + return ret; + + for (; *path != '\0'; path = ptr) { + if (*path == '/') { + for (ptr = path; *ptr == '/'; ++ptr) + ; + continue; + } + + ret = sqfs_dir_reader_open_dir(rd, inode, 0); + free(inode); + if (ret) + return ret; + + ptr = strchrnul(path, '/'); + + name = strndup(path, ptr - path); + if (name == NULL) + return SQFS_ERROR_ALLOC; + + ret = sqfs_dir_reader_find(rd, name); + free(name); + if (ret) + return ret; + + ret = sqfs_dir_reader_get_inode(rd, &inode); + if (ret) + return ret; + } + + *out = inode; + return 0; +} diff --git a/lib/sqfs/dir_reader/find_by_path.c b/lib/sqfs/dir_reader/find_by_path.c deleted file mode 100644 index 0cd800f..0000000 --- a/lib/sqfs/dir_reader/find_by_path.c +++ /dev/null @@ -1,82 +0,0 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ -/* - * find_by_path.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#define SQFS_BUILDING_DLL -#include "internal.h" - -int sqfs_dir_reader_find_by_path(sqfs_dir_reader_t *rd, - const sqfs_inode_generic_t *start, - const char *path, sqfs_inode_generic_t **out) -{ - sqfs_inode_generic_t *inode; - sqfs_dir_entry_t *ent; - const char *ptr; - int ret = 0; - - if (start == NULL) { - ret = sqfs_dir_reader_get_root_inode(rd, &inode); - } else { - inode = alloc_flex(sizeof(*inode), 1, - start->payload_bytes_used); - if (inode == NULL) { - ret = SQFS_ERROR_ALLOC; - } else { - memcpy(inode, start, - sizeof(*start) + start->payload_bytes_used); - } - } - - if (ret) - return ret; - - while (*path != '\0') { - if (*path == '/') { - while (*path == '/') - ++path; - continue; - } - - ret = sqfs_dir_reader_open_dir(rd, inode, 0); - free(inode); - if (ret) - return ret; - - ptr = strchr(path, '/'); - if (ptr == NULL) { - - if (ptr == NULL) { - for (ptr = path; *ptr != '\0'; ++ptr) - ; - } - } - - do { - ret = sqfs_dir_reader_read(rd, &ent); - if (ret < 0) - return ret; - - if (ret == 0) { - ret = strncmp((const char *)ent->name, - path, ptr - path); - if (ret == 0) - ret = ent->name[ptr - path]; - free(ent); - } - } while (ret < 0); - - if (ret > 0) - return SQFS_ERROR_NO_ENTRY; - - ret = sqfs_dir_reader_get_inode(rd, &inode); - if (ret) - return ret; - - path = ptr; - } - - *out = inode; - return 0; -} diff --git a/lib/sqfs/dir_reader/read_tree.c b/lib/sqfs/dir_reader/read_tree.c index 7fa944a..91cc2c0 100644 --- a/lib/sqfs/dir_reader/read_tree.c +++ b/lib/sqfs/dir_reader/read_tree.c @@ -218,14 +218,7 @@ int sqfs_dir_reader_get_full_hierarchy(sqfs_dir_reader_t *rd, if (ret) goto fail; - ptr = strchr(path, '/'); - if (ptr == NULL) { - - if (ptr == NULL) { - for (ptr = path; *ptr != '\0'; ++ptr) - ; - } - } + ptr = strchrnul(path, '/'); for (;;) { ret = sqfs_dir_reader_read(rd, &ent); -- cgit v1.2.3