From owner-svn-src-head@FreeBSD.ORG Mon Aug 31 20:53:01 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C1522106566C; Mon, 31 Aug 2009 20:53:01 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id B08668FC18; Mon, 31 Aug 2009 20:53:01 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n7VKr1cq038656; Mon, 31 Aug 2009 20:53:01 GMT (envelope-from trasz@svn.freebsd.org) Received: (from trasz@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n7VKr12R038654; Mon, 31 Aug 2009 20:53:01 GMT (envelope-from trasz@svn.freebsd.org) Message-Id: <200908312053.n7VKr12R038654@svn.freebsd.org> From: Edward Tomasz Napierala Date: Mon, 31 Aug 2009 20:53:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r196712 - head/bin/ls X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 31 Aug 2009 20:53:01 -0000 Author: trasz Date: Mon Aug 31 20:53:01 2009 New Revision: 196712 URL: http://svn.freebsd.org/changeset/base/196712 Log: Add NFSv4 ACL support to ls(1). Modified: head/bin/ls/print.c Modified: head/bin/ls/print.c ============================================================================== --- head/bin/ls/print.c Mon Aug 31 20:42:07 2009 (r196711) +++ head/bin/ls/print.c Mon Aug 31 20:53:01 2009 (r196712) @@ -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,69 @@ 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. - */ - 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. + * XXX: ACLs are not supported on whiteouts and device files + * residing on UFS. */ - if (S_ISLNK(p->fts_statp->st_mode) || S_ISWHT(p->fts_statp->st_mode)) { - *haveacls = 1; + if (S_ISCHR(p->fts_statp->st_mode) || S_ISBLK(p->fts_statp->st_mode) || + S_ISWHT(p->fts_statp->st_mode)) return; - } - if ((ret = pathconf(name, _PC_ACL_EXTENDED)) <= 0) { - if (ret < 0 && errno != EINVAL) - warn("%s", name); + + if (previous_dev != p->fts_statp->st_dev) { + previous_dev = p->fts_statp->st_dev; + supports_acls = 0; + + if (p->fts_level == FTS_ROOTLEVEL) + snprintf(name, sizeof(name), "%s", p->fts_name); else - *haveacls = 0; + snprintf(name, sizeof(name), "%s/%s", + p->fts_parent->fts_accpath, p->fts_name); + 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); + 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); }