diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2019-05-23 17:13:39 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2019-05-24 09:00:51 -0400 |
commit | f1fb3158d3f242f1884d8d8a7473ab0719e93e8c (patch) | |
tree | 4ab193109db3da98b779ed807f40adb3bb0b9fbd /fsade.c | |
parent | d9b3196d6c8f4fa0e7d0a4771040762edaebb1ee (diff) | |
download | bfs-f1fb3158d3f242f1884d8d8a7473ab0719e93e8c.tar.xz |
Implement -xattr predicate
Diffstat (limited to 'fsade.c')
-rw-r--r-- | fsade.c | 50 |
1 files changed, 48 insertions, 2 deletions
@@ -30,7 +30,11 @@ # include <sys/capability.h> #endif -#if BFS_CAN_CHECK_ACL || BFS_CAN_CHECK_CAPABILITIES +#if BFS_CAN_CHECK_XATTRS +# include <sys/xattr.h> +#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 |