From f1fb3158d3f242f1884d8d8a7473ab0719e93e8c Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 23 May 2019 17:13:39 -0400 Subject: Implement -xattr predicate --- fsade.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'fsade.c') diff --git a/fsade.c b/fsade.c index 7d796e0..822fbd1 100644 --- a/fsade.c +++ b/fsade.c @@ -30,7 +30,11 @@ # include #endif -#if BFS_CAN_CHECK_ACL || BFS_CAN_CHECK_CAPABILITIES +#if BFS_CAN_CHECK_XATTRS +# include +#endif + +#if BFS_CAN_CHECK_ACL || BFS_CAN_CHECK_CAPABILITIES || BFS_CAN_CHECK_XATTRS /** * Many of the APIs used here don't have *at() variants, but we can try to @@ -103,7 +107,7 @@ static bool is_absence_error(int error) { return false; } -#endif // BFS_CAN_CHECK_ACL || BFS_CAN_CHECK_CAPABILITIES +#endif // BFS_CAN_CHECK_ACL || BFS_CAN_CHECK_CAPABILITIES || BFS_CAN_CHECK_XATTRS #if BFS_CAN_CHECK_ACL @@ -230,3 +234,45 @@ int bfs_check_capabilities(const struct BFTW *ftwbuf) { } #endif + +#if BFS_CAN_CHECK_XATTRS + +int bfs_check_xattrs(const struct BFTW *ftwbuf) { + const char *path = fake_at(ftwbuf); + ssize_t len; + +#if __APPLE__ + int options = ftwbuf->typeflag == BFTW_LNK ? XATTR_NOFOLLOW : 0; + len = listxattr(path, NULL, 0, options); +#else + if (ftwbuf->typeflag == BFTW_LNK) { + len = llistxattr(path, NULL, 0); + } else { + len = listxattr(path, NULL, 0); + } +#endif + + int error = errno; + + free_fake_at(ftwbuf, path); + + if (len > 0) { + return 1; + } else if (len == 0 || is_absence_error(error)) { + return 0; + } else if (error == E2BIG) { + return 1; + } else { + errno = error; + return -1; + } +} + +#else // !BFS_CAN_CHECK_XATTRS + +int bfs_check_xattrs(const struct BFTW *ftwbuf) { + errno = ENOTSUP; + return -1; +} + +#endif -- cgit v1.2.3