diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2024-04-22 09:23:55 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2024-04-22 11:19:20 -0400 |
commit | 569e6758e26e23c27d94c0d132bf5e26ee5af862 (patch) | |
tree | 945d605388a524a196e96a351a8c59f7b51c6847 | |
parent | 75311e2f9aabd1e4775176e9adff5cd5f1fe42aa (diff) | |
download | bfs-569e6758e26e23c27d94c0d132bf5e26ee5af862.tar.xz |
config: Check for extattr_{get,list}_{file,link}()
This lets us implement -xattr on DragonFly BSD.
-rw-r--r-- | config/extattr-get-file.c | 10 | ||||
-rw-r--r-- | config/extattr-get-link.c | 10 | ||||
-rw-r--r-- | config/extattr-list-file.c | 10 | ||||
-rw-r--r-- | config/extattr-list-link.c | 10 | ||||
-rw-r--r-- | config/header.mk | 4 | ||||
-rw-r--r-- | src/fsade.c | 62 | ||||
-rw-r--r-- | src/prelude.h | 2 |
7 files changed, 97 insertions, 11 deletions
diff --git a/config/extattr-get-file.c b/config/extattr-get-file.c new file mode 100644 index 0000000..ac9cf96 --- /dev/null +++ b/config/extattr-get-file.c @@ -0,0 +1,10 @@ +// Copyright © Tavian Barnes <tavianator@tavianator.com> +// SPDX-License-Identifier: 0BSD + +#include <stddef.h> +#include <sys/types.h> +#include <sys/extattr.h> + +int main(void) { + return extattr_get_file("file", EXTATTR_NAMESPACE_USER, "xattr", NULL, 0); +} diff --git a/config/extattr-get-link.c b/config/extattr-get-link.c new file mode 100644 index 0000000..c35be5b --- /dev/null +++ b/config/extattr-get-link.c @@ -0,0 +1,10 @@ +// Copyright © Tavian Barnes <tavianator@tavianator.com> +// SPDX-License-Identifier: 0BSD + +#include <stddef.h> +#include <sys/types.h> +#include <sys/extattr.h> + +int main(void) { + return extattr_get_link("link", EXTATTR_NAMESPACE_USER, "xattr", NULL, 0); +} diff --git a/config/extattr-list-file.c b/config/extattr-list-file.c new file mode 100644 index 0000000..e68a8bb --- /dev/null +++ b/config/extattr-list-file.c @@ -0,0 +1,10 @@ +// Copyright © Tavian Barnes <tavianator@tavianator.com> +// SPDX-License-Identifier: 0BSD + +#include <stddef.h> +#include <sys/types.h> +#include <sys/extattr.h> + +int main(void) { + return extattr_list_file("file", EXTATTR_NAMESPACE_USER, NULL, 0); +} diff --git a/config/extattr-list-link.c b/config/extattr-list-link.c new file mode 100644 index 0000000..49f0ec2 --- /dev/null +++ b/config/extattr-list-link.c @@ -0,0 +1,10 @@ +// Copyright © Tavian Barnes <tavianator@tavianator.com> +// SPDX-License-Identifier: 0BSD + +#include <stddef.h> +#include <sys/types.h> +#include <sys/extattr.h> + +int main(void) { + return extattr_list_link("link", EXTATTR_NAMESPACE_USER, NULL, 0); +} diff --git a/config/header.mk b/config/header.mk index bba03ef..4da0fd2 100644 --- a/config/header.mk +++ b/config/header.mk @@ -12,6 +12,10 @@ HEADERS := \ ${GEN}/acl-is-trivial-np.h \ ${GEN}/aligned-alloc.h \ ${GEN}/confstr.h \ + ${GEN}/extattr-get-file.h \ + ${GEN}/extattr-get-link.h \ + ${GEN}/extattr-list-file.h \ + ${GEN}/extattr-list-link.h \ ${GEN}/fdclosedir.h \ ${GEN}/getdents.h \ ${GEN}/getdents64.h \ diff --git a/src/fsade.c b/src/fsade.c index 51b629f..02b12d0 100644 --- a/src/fsade.c +++ b/src/fsade.c @@ -327,17 +327,62 @@ int bfs_check_capabilities(const struct BFTW *ftwbuf) { #if BFS_CAN_CHECK_XATTRS +#if BFS_USE_SYS_EXTATTR_H + +/** Wrapper for extattr_list_{file,link}. */ +static ssize_t bfs_extattr_list(const char *path, enum bfs_type type, int namespace) { + if (type == BFS_LNK) { +#if BFS_HAS_EXTATTR_LIST_LINK + return extattr_list_link(path, namespace, NULL, 0); +#elif BFS_HAS_EXTATTR_GET_LINK + return extattr_get_link(path, namespace, "", NULL, 0); +#else + return 0; +#endif + } + +#if BFS_HAS_EXTATTR_LIST_FILE + return extattr_list_file(path, namespace, NULL, 0); +#elif BFS_HAS_EXTATTR_GET_FILE + // From man extattr(2): + // + // In earlier versions of this API, passing an empty string for the + // attribute name to extattr_get_file() would return the list of attributes + // defined for the target object. This interface has been deprecated in + // preference to using the explicit list API, and should not be used. + return extattr_get_file(path, namespace, "", NULL, 0); +#else + return 0; +#endif +} + +/** Wrapper for extattr_get_{file,link}. */ +static ssize_t bfs_extattr_get(const char *path, enum bfs_type type, int namespace, const char *name) { + if (type == BFS_LNK) { +#if BFS_HAS_EXTATTR_GET_LINK + return extattr_get_link(path, namespace, name, NULL, 0); +#else + return 0; +#endif + } + +#if BFS_HAS_EXTATTR_GET_FILE + return extattr_get_file(path, namespace, name, NULL, 0); +#else + return 0; +#endif +} + +#endif // BFS_USE_SYS_EXTATTR_H + int bfs_check_xattrs(const struct BFTW *ftwbuf) { const char *path = fake_at(ftwbuf); ssize_t len; #if BFS_USE_SYS_EXTATTR_H - ssize_t (*extattr_list)(const char *, int, void *, size_t) = - ftwbuf->type == BFS_LNK ? extattr_list_link : extattr_list_file; - - len = extattr_list(path, EXTATTR_NAMESPACE_SYSTEM, NULL, 0); + len = bfs_extattr_list(path, ftwbuf->type, EXTATTR_NAMESPACE_SYSTEM); if (len <= 0) { - len = extattr_list(path, EXTATTR_NAMESPACE_USER, NULL, 0); + len = bfs_extattr_list(path, ftwbuf->type, EXTATTR_NAMESPACE_USER); } #elif __APPLE__ int options = ftwbuf->type == BFS_LNK ? XATTR_NOFOLLOW : 0; @@ -371,12 +416,9 @@ int bfs_check_xattr_named(const struct BFTW *ftwbuf, const char *name) { ssize_t len; #if BFS_USE_SYS_EXTATTR_H - ssize_t (*extattr_get)(const char *, int, const char *, void *, size_t) = - ftwbuf->type == BFS_LNK ? extattr_get_link : extattr_get_file; - - len = extattr_get(path, EXTATTR_NAMESPACE_SYSTEM, name, NULL, 0); + len = bfs_extattr_get(path, ftwbuf->type, EXTATTR_NAMESPACE_SYSTEM, name); if (len < 0) { - len = extattr_get(path, EXTATTR_NAMESPACE_USER, name, NULL, 0); + len = bfs_extattr_get(path, ftwbuf->type, EXTATTR_NAMESPACE_USER, name); } #elif __APPLE__ int options = ftwbuf->type == BFS_LNK ? XATTR_NOFOLLOW : 0; diff --git a/src/prelude.h b/src/prelude.h index 390666b..9e64260 100644 --- a/src/prelude.h +++ b/src/prelude.h @@ -106,7 +106,7 @@ extern const char bfs_version[]; # define BFS_USE_SYS_CAPABILITY_H (BFS_HAS_SYS_CAPABILITY_H && !__FreeBSD__ && (!__linux__ || BFS_USE_LIBCAP)) #endif #ifndef BFS_USE_SYS_EXTATTR_H -# define BFS_USE_SYS_EXTATTR_H (BFS_HAS_SYS_EXTATTR_H && !__DragonFly__) +# define BFS_USE_SYS_EXTATTR_H BFS_HAS_SYS_EXTATTR_H #endif #ifndef BFS_USE_SYS_MKDEV_H # define BFS_USE_SYS_MKDEV_H BFS_HAS_SYS_MKDEV_H |