diff options
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | include/compat.h | 4 | ||||
| -rw-r--r-- | lib/compat/Makemodule.am | 1 | ||||
| -rw-r--r-- | lib/compat/strchrnul.c | 12 | ||||
| -rw-r--r-- | lib/sqfs/Makemodule.am | 1 | ||||
| -rw-r--r-- | lib/sqfs/dir_reader/dir_reader.c | 61 | ||||
| -rw-r--r-- | lib/sqfs/dir_reader/find_by_path.c | 82 | ||||
| -rw-r--r-- | lib/sqfs/dir_reader/read_tree.c | 9 | 
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);  | 
