Rework sun_acl_is_trivial() once again

Make the NFSv4 ACL part more readable
Declare constants as constants
ACE_DELETE_CHILD for write perms was introduced by illumos in
illumos/illumos-gate@d316fffc9c361532a482208561bbb614dac7f916
The best solution is to treat both types of write perms as trivial
diff --git a/libarchive/archive_read_disk_entry_from_file.c b/libarchive/archive_read_disk_entry_from_file.c
index 7b201bd..50e74d9 100644
--- a/libarchive/archive_read_disk_entry_from_file.c
+++ b/libarchive/archive_read_disk_entry_from_file.c
@@ -665,12 +665,17 @@
 static int
 sun_acl_is_trivial(acl_t *acl, mode_t mode, int *trivialp)
 {
-	uint32_t pubset, ownset, rperm, wperm, eperm;
-	uint32_t o_allow_pre, o_allow, g_allow, e_allow;
-	uint32_t o_deny, g_deny;
-	int i;
+	int i, p;
+	const uint32_t rperm = ACE_READ_DATA;
+	const uint32_t wperm = ACE_WRITE_DATA | ACE_APPEND_DATA;
+	const uint32_t eperm = ACE_EXECUTE;
+	const uint32_t pubset = ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
+	    ACE_READ_ACL | ACE_SYNCHRONIZE;
+	const uint32_t ownset = pubset | ACE_WRITE_ATTRIBUTES |
+	    ACE_WRITE_NAMED_ATTRS | ACE_WRITE_ACL | ACE_WRITE_OWNER;
 
 	ace_t *ace;
+	ace_t tace[6];
 
 	if (acl == NULL || trivialp == NULL)
 		return (-1);
@@ -695,123 +700,112 @@
 	if (acl->acl_type != ACE_T || acl->acl_entry_size != sizeof(ace_t))
 		return (-1);
 
-	/* Continue with checking NFSv4 ACLs */
-	pubset = ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS | ACE_READ_ACL |
-	    ACE_SYNCHRONIZE;
-	ownset = pubset | ACE_WRITE_ATTRIBUTES | ACE_WRITE_NAMED_ATTRS |
-	    ACE_WRITE_ACL | ACE_WRITE_OWNER;
+	/*
+	 * Continue with checking NFSv4 ACLs
+	 *
+	 * Create list of trivial ace's to be compared
+	 */
 
-	o_allow = ownset;
-	o_allow_pre = o_deny = g_deny = 0;
-	g_allow = e_allow = pubset;
+	/* owner@ allow pre */
+	tace[0].a_flags = ACE_OWNER;
+	tace[0].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
+	tace[0].a_access_mask = 0;
 
-	rperm = ACE_READ_DATA;
-	wperm = ACE_WRITE_DATA | ACE_APPEND_DATA;
-	eperm = ACE_EXECUTE;
+	/* owner@ deny */
+	tace[1].a_flags = ACE_OWNER;
+	tace[1].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
+	tace[1].a_access_mask = 0;
 
-	if ((acl->acl_flags & ACL_IS_DIR) != 0)
-		wperm |= ACE_DELETE_CHILD;
+	/* group@ deny */
+	tace[2].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
+	tace[2].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
+	tace[2].a_access_mask = 0;
+
+	/* owner@ allow */
+	tace[3].a_flags = ACE_OWNER;
+	tace[3].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
+	tace[3].a_access_mask = ownset;
+
+	/* group@ allow */
+	tace[4].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
+	tace[4].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
+	tace[4].a_access_mask = pubset;
+
+	/* everyone@ allow */
+	tace[5].a_flags = ACE_EVERYONE;
+	tace[5].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
+	tace[5].a_access_mask = pubset;
 
 	/* Permissions for everyone@ */
 	if (mode & 0004)
-		e_allow |= rperm;
+		tace[5].a_access_mask |= rperm;
 	if (mode & 0002)
-		e_allow |= wperm;
+		tace[5].a_access_mask |= wperm;
 	if (mode & 0001)
-		e_allow |= eperm;
+		tace[5].a_access_mask |= eperm;
 
 	/* Permissions for group@ */
 	if (mode & 0040)
-		g_allow |= rperm;
+		tace[4].a_access_mask |= rperm;
 	else if (mode & 0004)
-		g_deny |= rperm;
+		tace[2].a_access_mask |= rperm;
 	if (mode & 0020)
-		g_allow |= wperm;
+		tace[4].a_access_mask |= wperm;
 	else if (mode & 0002)
-		g_deny |= wperm;
+		tace[2].a_access_mask |= wperm;
 	if (mode & 0010)
-		g_allow |= eperm;
+		tace[4].a_access_mask |= eperm;
 	else if (mode & 0001)
-		g_deny |= eperm;
+		tace[2].a_access_mask |= eperm;
 
 	/* Permissions for owner@ */
 	if (mode & 0400) {
-		o_allow |= rperm;
+		tace[3].a_access_mask |= rperm;
 		if (!(mode & 0040) && (mode & 0004))
-			o_allow_pre |= rperm;
+			tace[0].a_access_mask |= rperm;
 	} else if ((mode & 0040) || (mode & 0004))
-		o_deny |= rperm;
+		tace[1].a_access_mask |= rperm;
 	if (mode & 0200) {
-		o_allow |= wperm;
+		tace[3].a_access_mask |= wperm;
 		if (!(mode & 0020) && (mode & 0002))
-			o_allow_pre |= wperm;
+			tace[0].a_access_mask |= wperm;
 	} else if ((mode & 0020) || (mode & 0002))
-		o_deny |= wperm;
+		tace[1].a_access_mask |= wperm;
 	if (mode & 0100) {
-		o_allow |= eperm;
+		tace[3].a_access_mask |= eperm;
 		if (!(mode & 0010) && (mode & 0001))
-			o_allow_pre |= eperm;
+			tace[0].a_access_mask |= eperm;
 	} else if ((mode & 0010) || (mode & 0001))
-		o_deny |= eperm;
-
-	i = 3;
-
-	if (o_allow_pre != 0)
-		i++;
-	if (o_deny != 0)
-		i++;
-	if (g_deny != 0)
-		i++;
+		tace[1].a_access_mask |= eperm;
 
 	/* Check if the acl count matches */
-	if (acl->acl_cnt != i)
+	p = 3;
+	for (i = 0; i < 3; i++) {
+		if (tace[i].a_access_mask != 0)
+			p++;
+	}
+	if (acl->acl_cnt != p)
 		return (0);
 
-	i = 0;
-	if (o_allow_pre != 0) {
-		ace = &((ace_t *)acl->acl_aclp)[i];
-		if (ace->a_flags != ACE_OWNER ||
-		    ace->a_type != ACE_ACCESS_ALLOWED_ACE_TYPE ||
-		    ace->a_access_mask != o_allow_pre)
-			return (0);
-		i++;
+	p = 0;
+	for (i = 0; i < 6; i++) {
+		if (tace[i].a_access_mask != 0) {
+			ace = &((ace_t *)acl->acl_aclp)[p];
+			/*
+			 * Illumos added ACE_DELETE_CHILD to write perms for
+			 * directories. We have to check against that, too.
+			 */
+			if (ace->a_flags != tace[i].a_flags ||
+			    ace->a_type != tace[i].a_type ||
+			    (ace->a_access_mask != tace[i].a_access_mask &&
+			    ((acl->acl_flags & ACL_IS_DIR) == 0 ||
+			    (tace[i].a_access_mask & wperm) == 0 ||
+			    ace->a_access_mask !=
+			    (tace[i].a_access_mask | ACE_DELETE_CHILD))))
+				return (0);
+			p++;
+		}
 	}
-	if (o_deny != 0) {
-		ace = &((ace_t *)acl->acl_aclp)[i];
-		if (ace->a_flags != ACE_OWNER ||
-		    ace->a_type != ACE_ACCESS_DENIED_ACE_TYPE ||
-		    ace->a_access_mask != o_deny)
-			return (0);
-		i++;
-	}
-	if (g_deny != 0) {
-		ace = &((ace_t *)acl->acl_aclp)[i];
-		if (ace->a_flags != (ACE_GROUP | ACE_IDENTIFIER_GROUP) ||
-		    ace->a_type != ACE_ACCESS_DENIED_ACE_TYPE ||
-		    ace->a_access_mask != g_deny)
-			return (0);
-		i++;
-	}
-
-	ace = &((ace_t *)acl->acl_aclp)[i];
-	if (ace->a_flags != ACE_OWNER ||
-	    ace->a_type != ACE_ACCESS_ALLOWED_ACE_TYPE ||
-	    ace->a_access_mask != o_allow)
-			return (0);
-	i++;
-
-	ace = &((ace_t *)acl->acl_aclp)[i];
-	if (ace->a_flags != (ACE_GROUP | ACE_IDENTIFIER_GROUP) ||
-	    ace->a_type != ACE_ACCESS_ALLOWED_ACE_TYPE ||
-	    ace->a_access_mask != g_allow)
-			return (0);
-	i++;
-
-	ace = &((ace_t *)acl->acl_aclp)[i];
-	if (ace->a_flags != ACE_EVERYONE ||
-	    ace->a_type != ACE_ACCESS_ALLOWED_ACE_TYPE ||
-	    ace->a_access_mask != e_allow)
-			return (0);
 
 	*trivialp = 1;
 	return (0);