Index: print.c =================================================================== --- print.c (revision 195005) +++ print.c (working copy) @@ -616,9 +616,8 @@ static void aclmode(char *buf, const FTSENT *p, int *haveacls) { char name[MAXPATHLEN + 1]; - int entries, ret; + int type = ACL_TYPE_ACCESS, ret, trivial; acl_t facl; - acl_entry_t ae; /* * Add a + after the standard rwxrwxrwx mode if the file has an @@ -630,38 +629,49 @@ aclmode(char *buf, const FTSENT *p, int *haveacls) snprintf(name, sizeof(name), "%s/%s", p->fts_parent->fts_accpath, p->fts_name); /* - * We have no way to tell whether a symbolic link has an ACL since - * pathconf() and acl_get_file() both follow them. They also don't - * support whiteouts. + * We have no way to tell whether a whiteout has an ACL. */ - if (S_ISLNK(p->fts_statp->st_mode) || S_ISWHT(p->fts_statp->st_mode)) { + if (S_ISWHT(p->fts_statp->st_mode)) { *haveacls = 1; return; } - if ((ret = pathconf(name, _PC_ACL_EXTENDED)) <= 0) { - if (ret < 0 && errno != EINVAL) - warn("%s", name); - else - *haveacls = 0; + *haveacls = 0; + ret = pathconf(name, _PC_ACL_EXTENDED); + if (ret > 0) { + type = ACL_TYPE_ACCESS; + *haveacls = 1; + } else if (ret < 0 && errno != EINVAL) { + warn("%s", name); return; } - *haveacls = 1; - if ((facl = acl_get_file(name, ACL_TYPE_ACCESS)) != NULL) { - if (acl_get_entry(facl, ACL_FIRST_ENTRY, &ae) == 1) { - entries = 1; - while (acl_get_entry(facl, ACL_NEXT_ENTRY, &ae) == 1) - if (++entries > 3) - break; - /* - * POSIX.1e requires that ACLs of type ACL_TYPE_ACCESS - * must have at least three entries (owner, group, - * and other). So anything with more than 3 ACLs looks - * interesting to us. - */ - if (entries > 3) - buf[10] = '+'; - } + ret = pathconf(name, _PC_ACL_NFS4); + if (ret > 0) { + type = ACL_TYPE_NFS4; + *haveacls = 1; + } else if (ret < 0 && errno != EINVAL) { + warn("%s", name); + return; + } + if (*haveacls == 0) + return; + facl = acl_get_link_np(name, type); + if (facl == NULL) { + /* + * If we were denied access, there must be some ACL + * entry denying READ_ACL. + */ + if (errno == EPERM || errno == EACCES) + buf[10] = '+'; + + warn("%s", name); + return; + } + if (acl_is_trivial_np(facl, &trivial) != 0) { + warn("%s", name); acl_free(facl); - } else - warn("%s", name); + return; + } + if (!trivial) + buf[10] = '+'; + acl_free(facl); }