Date: Sat, 30 Jan 2010 14:44:32 +0000 (UTC) From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r203187 - stable/8/bin/ls Message-ID: <201001301444.o0UEiWIr021612@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: trasz Date: Sat Jan 30 14:44:32 2010 New Revision: 203187 URL: http://svn.freebsd.org/changeset/base/203187 Log: MFC r196712: Add NFSv4 ACL support to ls(1). MFC r196773: Fix regression introduced in r196712 - the 'name' string needs to be rewritten for each file we want to check ACL on. Without this change, ls(1) would check only the ACL on the first file to list. Modified: stable/8/bin/ls/print.c Directory Properties: stable/8/bin/ls/ (props changed) Modified: stable/8/bin/ls/print.c ============================================================================== --- stable/8/bin/ls/print.c Sat Jan 30 14:40:42 2010 (r203186) +++ stable/8/bin/ls/print.c Sat Jan 30 14:44:32 2010 (r203187) @@ -70,7 +70,7 @@ static void printsize(size_t, off_t); static void endcolor(int); static int colortype(mode_t); #endif -static void aclmode(char *, const FTSENT *, int *); +static void aclmode(char *, const FTSENT *); #define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT) @@ -139,16 +139,12 @@ printlong(const DISPLAY *dp) #ifdef COLORLS int color_printed = 0; #endif - int haveacls; - dev_t prevdev; if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) && (f_longform || f_size)) { (void)printf("total %lu\n", howmany(dp->btotal, blocksize)); } - haveacls = 1; - prevdev = (dev_t)-1; for (p = dp->list; p; p = p->fts_link) { if (IS_NOPRINT(p)) continue; @@ -159,14 +155,7 @@ printlong(const DISPLAY *dp) (void)printf("%*jd ", dp->s_block, howmany(sp->st_blocks, blocksize)); strmode(sp->st_mode, buf); - /* - * Cache whether or not the filesystem supports ACL's to - * avoid expensive syscalls. Try again when we change devices. - */ - if (haveacls || sp->st_dev != prevdev) { - aclmode(buf, p, &haveacls); - prevdev = sp->st_dev; - } + aclmode(buf, p); np = p->fts_pointer; (void)printf("%s %*u %-*s %-*s ", buf, dp->s_nlink, sp->st_nlink, dp->s_user, np->user, dp->s_group, @@ -612,56 +601,73 @@ printsize(size_t width, off_t bytes) (void)printf("%*jd ", (u_int)width, bytes); } +/* + * Add a + after the standard rwxrwxrwx mode if the file has an + * ACL. strmode() reserves space at the end of the string. + */ static void -aclmode(char *buf, const FTSENT *p, int *haveacls) +aclmode(char *buf, const FTSENT *p) { char name[MAXPATHLEN + 1]; - int entries, ret; + int ret, trivial; + static dev_t previous_dev = NODEV; + static int supports_acls = -1; + static int type = ACL_TYPE_ACCESS; acl_t facl; - acl_entry_t ae; /* - * Add a + after the standard rwxrwxrwx mode if the file has an - * extended ACL. strmode() reserves space at the end of the string. + * XXX: ACLs are not supported on whiteouts and device files + * residing on UFS. */ + if (S_ISCHR(p->fts_statp->st_mode) || S_ISBLK(p->fts_statp->st_mode) || + S_ISWHT(p->fts_statp->st_mode)) + return; + + if (previous_dev == p->fts_statp->st_dev && supports_acls == 0) + return; + if (p->fts_level == FTS_ROOTLEVEL) snprintf(name, sizeof(name), "%s", p->fts_name); else 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. - */ - if (S_ISLNK(p->fts_statp->st_mode) || S_ISWHT(p->fts_statp->st_mode)) { - *haveacls = 1; - return; - } - if ((ret = pathconf(name, _PC_ACL_EXTENDED)) <= 0) { - if (ret < 0 && errno != EINVAL) + + if (previous_dev != p->fts_statp->st_dev) { + previous_dev = p->fts_statp->st_dev; + supports_acls = 0; + + ret = lpathconf(name, _PC_ACL_NFS4); + if (ret > 0) { + type = ACL_TYPE_NFS4; + supports_acls = 1; + } else if (ret < 0 && errno != EINVAL) { warn("%s", name); - else - *haveacls = 0; + return; + } + if (supports_acls == 0) { + ret = lpathconf(name, _PC_ACL_EXTENDED); + if (ret > 0) { + type = ACL_TYPE_ACCESS; + supports_acls = 1; + } else if (ret < 0 && errno != EINVAL) { + warn("%s", name); + return; + } + } + } + if (supports_acls == 0) + return; + facl = acl_get_link_np(name, type); + if (facl == NULL) { + 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] = '+'; - } + if (acl_is_trivial_np(facl, &trivial)) { acl_free(facl); - } else warn("%s", name); + return; + } + if (!trivial) + buf[10] = '+'; + acl_free(facl); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001301444.o0UEiWIr021612>