+/*
+ * Some generic functions used by multiple OSes.
+ */
+static acl_type_t bac_to_os_acltype(bacl_type acltype)
+{
+ acl_type_t ostype;
+
+ switch (acltype) {
+ case BACL_TYPE_ACCESS:
+ ostype = ACL_TYPE_ACCESS;
+ break;
+ case BACL_TYPE_DEFAULT:
+ ostype = ACL_TYPE_DEFAULT;
+ break;
+
+#ifdef ACL_TYPE_DEFAULT_DIR
+ case BACL_TYPE_DEFAULT_DIR:
+ /*
+ * OSF1 has an additional acl type named ACL_TYPE_DEFAULT_DIR.
+ */
+ ostype = ACL_TYPE_DEFAULT_DIR;
+ break;
+#endif
+#ifdef ACL_TYPE_EXTENDED
+ case BACL_TYPE_EXTENDED:
+ /*
+ * MacOSX has an additional acl type named ACL_TYPE_EXTENDED.
+ */
+ ostype = ACL_TYPE_EXTENDED;
+ break;
+#endif
+ default:
+ /*
+ * This should never happen, as the per OS version function only tries acl
+ * types supported on a certain platform.
+ */
+ ostype = (acl_type_t)ACL_TYPE_NONE;
+ break;
+ }
+ return ostype;
+}
+
+#if !defined(HAVE_DARWIN_OS)
+/*
+ * See if an acl is a trivial one (e.g. just the stat bits encoded as acl.)
+ * There is no need to store those acls as we already store the stat bits too.
+ */
+static bool acl_is_trivial(acl_t acl)
+{
+ /*
+ * acl is trivial if it has only the following entries:
+ * "user::",
+ * "group::",
+ * "other::"
+ */
+ acl_entry_t ace;
+ acl_tag_t tag;
+#if defined(HAVE_FREEBSD_OS) || \
+ defined(HAVE_LINUX_OS)
+ int entry_available;
+
+ entry_available = acl_get_entry(acl, ACL_FIRST_ENTRY, &ace);
+ while (entry_available == 1) {
+ /*
+ * Get the tag type of this acl entry.
+ * If we fail to get the tagtype we call the acl non-trivial.
+ */
+ if (acl_get_tag_type(ace, &tag) < 0)
+ return true;
+ /*
+ * Anything other the ACL_USER_OBJ, ACL_GROUP_OBJ or ACL_OTHER breaks the spell.
+ */
+ if (tag != ACL_USER_OBJ &&
+ tag != ACL_GROUP_OBJ &&
+ tag != ACL_OTHER)
+ return false;
+ entry_available = acl_get_entry(acl, ACL_NEXT_ENTRY, &ace);
+ }
+ return true;
+#elif defined(HAVE_IRIX_OS)
+ int n;
+
+ for (n = 0; n < acl->acl_cnt; n++) {
+ ace = &acl->acl_entry[n];
+ tag = ace->ae_tag;
+
+ /*
+ * Anything other the ACL_USER_OBJ, ACL_GROUP_OBJ or ACL_OTHER breaks the spell.
+ */
+ if (tag != ACL_USER_OBJ &&
+ tag != ACL_GROUP_OBJ &&
+ tag != ACL_OTHER_OBJ)
+ return false;
+ }
+ return true;
+#elif defined(HAVE_OSF1_OS)
+ int count;
+
+ ace = acl->acl_first;
+ count = acl->acl_num;
+
+ while (count > 0) {
+ tag = ace->entry->acl_type;
+ /*
+ * Anything other the ACL_USER_OBJ, ACL_GROUP_OBJ or ACL_OTHER breaks the spell.
+ */
+ if (tag != ACL_USER_OBJ &&
+ tag != ACL_GROUP_OBJ &&
+ tag != ACL_OTHER)
+ return false;
+ /*
+ * On Tru64, perm can also contain non-standard bits such as
+ * PERM_INSERT, PERM_DELETE, PERM_MODIFY, PERM_LOOKUP, ...
+ */
+ if ((ace->entry->acl_perm & ~(ACL_READ | ACL_WRITE | ACL_EXECUTE)))
+ return false;
+ ace = ace->next;
+ count--;
+ }
+ return true;
+#endif
+}
+#endif
+
+/*
+ * Generic wrapper around acl_get_file call.
+ */
+static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype)