summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2024-01-03 15:55:27 -0500
committerTavian Barnes <tavianator@tavianator.com>2024-01-03 16:43:15 -0500
commitd874481987c381fd572a6f3c43840c50111a9554 (patch)
tree991fe47290d47125d5f14fe73ec8d9f8010aae47
parent976514edfb6063170049f561f5edbf330bbe4132 (diff)
downloadbfs-d874481987c381fd572a6f3c43840c50111a9554.tar.xz
fsade: Fix ACL checks on DragonFly BSD
-rw-r--r--GNUmakefile4
-rw-r--r--src/fsade.c54
2 files changed, 49 insertions, 9 deletions
diff --git a/GNUmakefile b/GNUmakefile
index a4d1c2d..7680cb3 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -160,6 +160,10 @@ ifeq ($(OS),NetBSD)
LOCAL_LDLIBS += -lutil
endif
+ifeq ($(OS),DragonFly)
+LOCAL_LDLIBS += -lposix1e
+endif
+
ifneq ($(filter gcov,$(MAKECMDGOALS)),)
LOCAL_CFLAGS += --coverage
# gcov only intercepts fork()/exec() with -std=gnu*
diff --git a/src/fsade.c b/src/fsade.c
index a48eeb0..d6ef4b8 100644
--- a/src/fsade.c
+++ b/src/fsade.c
@@ -117,24 +117,60 @@ static bool is_absence_error(int error) {
#if BFS_CAN_CHECK_ACL
+/** Unified interface for incompatible acl_get_entry() implementations. */
+static int bfs_acl_entry(acl_t acl, int which, acl_entry_t *entry) {
+#if __DragonFly__ && !defined(ACL_FIRST_ENTRY) && !defined(ACL_NEXT_ENTRY)
+# define ACL_FIRST_ENTRY 0
+# define ACL_NEXT_ENTRY 1
+
+ switch (which) {
+ case ACL_FIRST_ENTRY:
+ *entry = &acl->acl_entry[0];
+ break;
+ case ACL_NEXT_ENTRY:
+ ++*entry;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ acl_entry_t last = &acl->acl_entry[acl->acl_cnt];
+ return *entry == last;
+#else
+ int ret = acl_get_entry(acl, which, entry);
+# if __APPLE__
+ // POSIX.1e specifies a return value of 1 for success, but macOS returns 0 instead
+ return !ret;
+# else
+ return ret;
+# endif
+#endif
+}
+
+/** Unified interface for acl_get_tag_type(). */
+static int bfs_acl_tag_type(acl_entry_t entry, acl_tag_t *tag) {
+#if __DragonFly__
+ *tag = entry->ae_tag;
+ return 0;
+#else
+ return acl_get_tag_type(entry, tag);
+#endif
+}
+
/** Check if a POSIX.1e ACL is non-trivial. */
static int bfs_check_posix1e_acl(acl_t acl, bool ignore_required) {
int ret = 0;
acl_entry_t entry;
- for (int status = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
-#if __APPLE__
- // POSIX.1e specifies a return value of 1 for success, but macOS
- // returns 0 instead
- status == 0;
-#else
+ for (int status = bfs_acl_entry(acl, ACL_FIRST_ENTRY, &entry);
status > 0;
-#endif
- status = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry)) {
+ status = bfs_acl_entry(acl, ACL_NEXT_ENTRY, &entry))
+ {
#if defined(ACL_USER_OBJ) && defined(ACL_GROUP_OBJ) && defined(ACL_OTHER)
if (ignore_required) {
acl_tag_t tag;
- if (acl_get_tag_type(entry, &tag) != 0) {
+ if (bfs_acl_tag_type(entry, &tag) != 0) {
ret = -1;
continue;
}