aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--include/compat.h4
-rw-r--r--lib/compat/Makemodule.am1
-rw-r--r--lib/compat/strchrnul.c12
-rw-r--r--lib/sqfs/Makemodule.am1
-rw-r--r--lib/sqfs/dir_reader/dir_reader.c61
-rw-r--r--lib/sqfs/dir_reader/find_by_path.c82
-rw-r--r--lib/sqfs/dir_reader/read_tree.c9
8 files changed, 80 insertions, 92 deletions
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 <goliath@infraroot.at>
- */
-#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);