From 569e6758e26e23c27d94c0d132bf5e26ee5af862 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 22 Apr 2024 09:23:55 -0400 Subject: config: Check for extattr_{get,list}_{file,link}() This lets us implement -xattr on DragonFly BSD. --- config/extattr-get-file.c | 10 ++++++++ config/extattr-get-link.c | 10 ++++++++ config/extattr-list-file.c | 10 ++++++++ config/extattr-list-link.c | 10 ++++++++ config/header.mk | 4 +++ src/fsade.c | 62 ++++++++++++++++++++++++++++++++++++++-------- src/prelude.h | 2 +- 7 files changed, 97 insertions(+), 11 deletions(-) create mode 100644 config/extattr-get-file.c create mode 100644 config/extattr-get-link.c create mode 100644 config/extattr-list-file.c create mode 100644 config/extattr-list-link.c 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 +// SPDX-License-Identifier: 0BSD + +#include +#include +#include + +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 +// SPDX-License-Identifier: 0BSD + +#include +#include +#include + +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 +// SPDX-License-Identifier: 0BSD + +#include +#include +#include + +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 +// SPDX-License-Identifier: 0BSD + +#include +#include +#include + +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 -- cgit v1.2.3