archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
    struct archive_entry *entry, int *fd)
{
	const char	*accpath;
	void		*aclp;
	int		aclcnt;
	int		r;

	accpath = NULL;

	if (*fd < 0) {
		accpath = archive_read_disk_entry_setup_path(a, entry, fd);
		if (accpath == NULL)
			return (ARCHIVE_WARN);
	}

	archive_entry_acl_clear(entry);

	aclp = NULL;

#if ARCHIVE_ACL_SUNOS_NFS4
	if (*fd >= 0)
		aclp = sunacl_get(ACE_GETACL, &aclcnt, *fd, NULL);
	else if ((!a->follow_symlinks)
	    && (archive_entry_filetype(entry) == AE_IFLNK))
		/* We can't get the ACL of a symlink, so we assume it can't
		   have one. */
		aclp = NULL;
	else
		aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, accpath);

	if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
	    archive_entry_mode(entry), 1, S_ISDIR(archive_entry_mode(entry)),
	    &r) == 0 && r == 1) {
		free(aclp);
		aclp = NULL;
		return (ARCHIVE_OK);
	}

	if (aclp != NULL) {
		r = translate_acl(a, entry, aclp, aclcnt,
		    ARCHIVE_ENTRY_ACL_TYPE_NFS4);
		free(aclp);
		aclp = NULL;

		if (r != ARCHIVE_OK) {
			archive_set_error(&a->archive, errno,
			    "Couldn't translate NFSv4 ACLs");
		}
		return (r);
	}
#endif	/* ARCHIVE_ACL_SUNOS_NFS4 */

	/* Retrieve POSIX.1e ACLs from file. */
	if (*fd >= 0)
		aclp = sunacl_get(GETACL, &aclcnt, *fd, NULL);
	else if ((!a->follow_symlinks)
	    && (archive_entry_filetype(entry) == AE_IFLNK))
		/* We can't get the ACL of a symlink, so we assume it can't
		   have one. */
		aclp = NULL;
	else
		aclp = sunacl_get(GETACL, &aclcnt, 0, accpath);

	/* Ignore "trivial" ACLs that just mirror the file mode. */
	if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
	    archive_entry_mode(entry), 0, S_ISDIR(archive_entry_mode(entry)),
	    &r) == 0 && r == 1) {
		free(aclp);
		aclp = NULL;
	}

	if (aclp != NULL)
	{
		r = translate_acl(a, entry, aclp, aclcnt,
		    ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
		free(aclp);
		aclp = NULL;

		if (r != ARCHIVE_OK) {
			archive_set_error(&a->archive, errno,
			    "Couldn't translate access ACLs");
			return (r);
		}
	}

	return (ARCHIVE_OK);
}
archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
    struct archive_entry *entry, int *fd)
{
	const char	*accpath;
	void		*aclp;
	int		aclcnt;
	int		r;

	accpath = NULL;

	if (*fd < 0) {
		accpath = archive_read_disk_entry_setup_path(a, entry, fd);
		if (accpath == NULL)
			return (ARCHIVE_WARN);
	}

	archive_entry_acl_clear(entry);

	aclp = NULL;

#if ARCHIVE_ACL_SUNOS_NFS4
	if (*fd >= 0)
		aclp = sunacl_get(ACE_GETACL, &aclcnt, *fd, NULL);
	else if ((!a->follow_symlinks)
	    && (archive_entry_filetype(entry) == AE_IFLNK))
		 
		aclp = NULL;
	else
		aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, accpath);

	if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
	    archive_entry_mode(entry), 1, S_ISDIR(archive_entry_mode(entry)),
	    &r) == 0 && r == 1) {
		free(aclp);
		aclp = NULL;
		return (ARCHIVE_OK);
	}

	if (aclp != NULL) {
		r = translate_acl(a, entry, aclp, aclcnt,
		    ARCHIVE_ENTRY_ACL_TYPE_NFS4);
		free(aclp);
		aclp = NULL;

		if (r != ARCHIVE_OK) {
			archive_set_error(&a->archive, errno,
			    "Couldn't translate NFSv4 ACLs");
		}
		return (r);
	}
#endif	 

	 
	if (*fd >= 0)
		aclp = sunacl_get(GETACL, &aclcnt, *fd, NULL);
	else if ((!a->follow_symlinks)
	    && (archive_entry_filetype(entry) == AE_IFLNK))
		 
		aclp = NULL;
	else
		aclp = sunacl_get(GETACL, &aclcnt, 0, accpath);

	 
	if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
	    archive_entry_mode(entry), 0, S_ISDIR(archive_entry_mode(entry)),
	    &r) == 0 && r == 1) {
		free(aclp);
		aclp = NULL;
	}

	if (aclp != NULL)
	{
		r = translate_acl(a, entry, aclp, aclcnt,
		    ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
		free(aclp);
		aclp = NULL;

		if (r != ARCHIVE_OK) {
			archive_set_error(&a->archive, errno,
			    "Couldn't translate access ACLs");
			return (r);
		}
	}

	return (ARCHIVE_OK);
}