git: 8bf37c868f45 - main - getfacl: implement --skip-base (-s)
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 21 Apr 2025 03:58:06 UTC
The branch main has been updated by kevans:
URL: https://cgit.FreeBSD.org/src/commit/?id=8bf37c868f45e73345b791f9abc6c5a07a1629db
commit 8bf37c868f45e73345b791f9abc6c5a07a1629db
Author: Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2025-04-21 03:57:45 +0000
Commit: Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2025-04-21 03:57:45 +0000
getfacl: implement --skip-base (-s)
This skips files that only have a trivial ACL, which is useful for
callers that want to examine files with more unique ACLs.
While we're here, don't issue the file name/ownership header if we're
just going to error out on the file; this adds extra noise for little
gain.
Reviewed by: markj, olce
Sponsored by: Klara, Inc.
Differential Revision: https://reviews.freebsd.org/D40603
---
bin/getfacl/getfacl.1 | 5 ++++
bin/getfacl/getfacl.c | 65 +++++++++++++++++++++++++++++++++++++--------------
2 files changed, 52 insertions(+), 18 deletions(-)
diff --git a/bin/getfacl/getfacl.1 b/bin/getfacl/getfacl.1
index b2b6294c46de..475c86e275bc 100644
--- a/bin/getfacl/getfacl.1
+++ b/bin/getfacl/getfacl.1
@@ -75,6 +75,11 @@ Ignored for POSIX.1e ACLs.
Do not write commented information about file name and ownership.
This is
useful when dealing with filenames with unprintable characters.
+.It Fl s , Fl -skip-base
+Skip files that only have a trivial ACL, as defined by
+.Xr acl_is_trivial_np 3 .
+Notably, files with POSIX.1e ACLs that only represent the owner, group and other
+to match the mode of the file will be skipped.
.It Fl v
For NFSv4 ACLs, display access mask and flags in a verbose form.
Ignored for POSIX.1e ACLs.
diff --git a/bin/getfacl/getfacl.c b/bin/getfacl/getfacl.c
index 2b98f923d618..5f55819c81a1 100644
--- a/bin/getfacl/getfacl.c
+++ b/bin/getfacl/getfacl.c
@@ -52,6 +52,7 @@ static const struct option long_options[] =
{ "default", no_argument, NULL, 'd' },
{ "numeric", no_argument, NULL, 'n' },
{ "omit-header", no_argument, NULL, 'q' },
+ { "skip-base", no_argument, NULL, 's' },
{ NULL, no_argument, NULL, 0 },
};
@@ -90,7 +91,7 @@ getgname(gid_t gid)
static int
print_acl(char *path, acl_type_t type, int hflag, int iflag, int nflag,
- int qflag, int vflag)
+ int qflag, int vflag, int sflag)
{
struct stat sb;
acl_t acl;
@@ -122,25 +123,49 @@ print_acl(char *path, acl_type_t type, int hflag, int iflag, int nflag,
return (-1);
}
+ if (hflag)
+ acl = acl_get_link_np(path, type);
+ else
+ acl = acl_get_file(path, type);
+
+ if (!acl && errno != EOPNOTSUPP) {
+ warn("%s", path);
+ return(-1);
+ }
+
+ if (sflag) {
+ int trivial;
+
+ /*
+ * With the -s flag, we shouldn't synthesize a trivial ACL if
+ * they aren't supported as we do below.
+ */
+ if (!acl)
+ return(0);
+
+ /*
+ * We also shouldn't render anything for this path if it's a
+ * trivial ACL. If we error out, we'll issue a warning but
+ * proceed with this file to err on the side of caution.
+ */
+ error = acl_is_trivial_np(acl, &trivial);
+ if (error != 0) {
+ warn("%s: acl_is_trivial_np failed", path);
+ } else if (trivial) {
+ (void)acl_free(acl);
+ return(0);
+ }
+ }
+
if (more_than_one)
printf("\n");
else
more_than_one++;
-
if (!qflag)
printf("# file: %s\n# owner: %s\n# group: %s\n", path,
getuname(sb.st_uid), getgname(sb.st_gid));
- if (hflag)
- acl = acl_get_link_np(path, type);
- else
- acl = acl_get_file(path, type);
if (!acl) {
- if (errno != EOPNOTSUPP) {
- warn("%s", path);
- return(-1);
- }
- errno = 0;
if (type == ACL_TYPE_DEFAULT)
return(0);
acl = acl_from_mode_np(sb.st_mode);
@@ -176,7 +201,7 @@ print_acl(char *path, acl_type_t type, int hflag, int iflag, int nflag,
static int
print_acl_from_stdin(acl_type_t type, int hflag, int iflag, int nflag,
- int qflag, int vflag)
+ int qflag, int vflag, int sflag)
{
char *p, pathname[PATH_MAX];
int carried_error = 0;
@@ -185,7 +210,7 @@ print_acl_from_stdin(acl_type_t type, int hflag, int iflag, int nflag,
if ((p = strchr(pathname, '\n')) != NULL)
*p = '\0';
if (print_acl(pathname, type, hflag, iflag, nflag,
- qflag, vflag) == -1) {
+ qflag, vflag, sflag) == -1) {
carried_error = -1;
}
}
@@ -199,14 +224,15 @@ main(int argc, char *argv[])
acl_type_t type = ACL_TYPE_ACCESS;
int carried_error = 0;
int ch, error, i;
- int hflag, iflag, qflag, nflag, vflag;
+ int hflag, iflag, qflag, nflag, sflag, vflag;
hflag = 0;
iflag = 0;
qflag = 0;
nflag = 0;
+ sflag = 0;
vflag = 0;
- while ((ch = getopt_long(argc, argv, "+dhinqv", long_options,
+ while ((ch = getopt_long(argc, argv, "+dhinqsv", long_options,
NULL)) != -1)
switch(ch) {
case 'd':
@@ -224,6 +250,9 @@ main(int argc, char *argv[])
case 'q':
qflag = 1;
break;
+ case 's':
+ sflag = 1;
+ break;
case 'v':
vflag = 1;
break;
@@ -236,19 +265,19 @@ main(int argc, char *argv[])
if (argc == 0) {
error = print_acl_from_stdin(type, hflag, iflag, nflag,
- qflag, vflag);
+ qflag, vflag, sflag);
return(error ? 1 : 0);
}
for (i = 0; i < argc; i++) {
if (!strcmp(argv[i], "-")) {
error = print_acl_from_stdin(type, hflag, iflag, nflag,
- qflag, vflag);
+ qflag, vflag, sflag);
if (error == -1)
carried_error = -1;
} else {
error = print_acl(argv[i], type, hflag, iflag, nflag,
- qflag, vflag);
+ qflag, vflag, sflag);
if (error == -1)
carried_error = -1;
}