Add output of effective rights to getfacl

* getfacl.c (usage): Align more closely to Linux version.  Add new
        options -c, -e, -E.  Change formatting to accommodate longer options.
        (longopts): Rename --noname to --numeric.  Keep --noname for backward
        compatibility.  Add --omit-header, --all-effective and --no-effective
        options.
        (opts): Add -c, -e and -E option.
        (main): Handle new -c, -e, and -E options.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2015-04-16 13:31:16 +02:00
parent 5d31049e66
commit bd57946148
4 changed files with 147 additions and 65 deletions

View File

@ -1,3 +1,7 @@
2015-04-16 Corinna Vinschen <corinna@vinschen.de>
* utils.xml (getfacl): Show new option output.
2015-04-10 Corinna Vinschen <corinna@vinschen.de> 2015-04-10 Corinna Vinschen <corinna@vinschen.de>
* new-features.xml (ov-new2.0): Rename from ov-new1.7.36 and change * new-features.xml (ov-new2.0): Rename from ov-new1.7.36 and change

View File

@ -519,11 +519,14 @@ Usage: getfacl [-adn] FILE [FILE2...]
Display file and directory access control lists (ACLs). Display file and directory access control lists (ACLs).
-a, --access display the file access control list -a, --access display the file access control list only
-d, --default display the default access control list -d, --default display the default access control list only
-h, --help print help explaining the command line options -c, --omit-header do not display the comment header
-n, --noname display user and group IDs instead of names -e, --all-effective print all effective rights
-V, --version output version information and exit -E, --no-effective print no effective rights
-n, --numeric print numeric user/group identifiers
-V, --version print version and exit
-h, --help this help text
When multiple files are specified on the command line, a blank When multiple files are specified on the command line, a blank
line separates the ACLs for each file. line separates the ACLs for each file.

View File

@ -1,3 +1,13 @@
2015-04-16 Corinna Vinschen <corinna@vinschen.de>
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
2015-02-28 Corinna Vinschen <corinna@vinschen.de> 2015-02-28 Corinna Vinschen <corinna@vinschen.de>
* getfacl.c (usage): Change --all to --access, --dir to --default. * getfacl.c (usage): Change --all to --access, --dir to --default.

View File

@ -66,61 +66,68 @@ static void
usage (FILE * stream) usage (FILE * stream)
{ {
fprintf (stream, "Usage: %s [-adn] FILE [FILE2...]\n" fprintf (stream, "Usage: %s [-adn] FILE [FILE2...]\n"
"\n" "\n"
"Display file and directory access control lists (ACLs).\n" "Display file and directory access control lists (ACLs).\n"
"\n" "\n"
" -a, --access display the file access control list\n" " -a, --access display the file access control list only\n"
" -d, --default display the default access control list\n" " -d, --default display the default access control list only\n"
" -h, --help print help explaining the command line options\n" " -c, --omit-header do not display the comment header\n"
" -n, --noname display user and group IDs instead of names\n" " -e, --all-effective print all effective rights\n"
" -V, --version output version information and exit\n" " -E, --no-effective print no effective rights\n"
"\n" " -n, --numeric print numeric user/group identifiers\n"
"When multiple files are specified on the command line, a blank\n" " -V, --version print version and exit\n"
"line separates the ACLs for each file.\n", prog_name); " -h, --help this help text\n"
"\n"
"When multiple files are specified on the command line, a blank\n"
"line separates the ACLs for each file.\n", prog_name);
if (stream == stdout) if (stream == stdout)
{ {
fprintf (stream, "" fprintf (stream, ""
"For each argument that is a regular file, special file or\n" "For each argument that is a regular file, special file or\n"
"directory, getfacl displays the owner, the group, and the ACL.\n" "directory, getfacl displays the owner, the group, and the ACL.\n"
"For directories getfacl displays additionally the default ACL.\n" "For directories getfacl displays additionally the default ACL.\n"
"\n" "\n"
"With no options specified, getfacl displays the filename, the\n" "With no options specified, getfacl displays the filename, the\n"
"owner, the group, the setuid (s), setgid (s), and sticky (t)\n" "owner, the group, the setuid (s), setgid (s), and sticky (t)\n"
"bits if available, and both the ACL and the default ACL, if it\n" "bits if available, and both the ACL and the default ACL, if it\n"
"exists.\n" "exists.\n"
"\n" "\n"
"The format for ACL output is as follows:\n" "The format for ACL output is as follows:\n"
" # file: filename\n" " # file: filename\n"
" # owner: name or uid\n" " # owner: name or uid\n"
" # group: name or uid\n" " # group: name or uid\n"
" # flags: sst\n" " # flags: sst\n"
" user::perm\n" " user::perm\n"
" user:name or uid:perm\n" " user:name or uid:perm\n"
" group::perm\n" " group::perm\n"
" group:name or gid:perm\n" " group:name or gid:perm\n"
" mask:perm\n" " mask:perm\n"
" other:perm\n" " other:perm\n"
" default:user::perm\n" " default:user::perm\n"
" default:user:name or uid:perm\n" " default:user:name or uid:perm\n"
" default:group::perm\n" " default:group::perm\n"
" default:group:name or gid:perm\n" " default:group:name or gid:perm\n"
" default:mask:perm\n" " default:mask:perm\n"
" default:other:perm\n" " default:other:perm\n"
"\n"); "\n");
} }
} }
struct option longopts[] = { struct option longopts[] = {
{"access", no_argument, NULL, 'a'}, {"access", no_argument, NULL, 'a'},
{"all", no_argument, NULL, 'a'}, {"all", no_argument, NULL, 'a'},
{"omit-header", no_argument, NULL, 'c'},
{"all-effective", no_argument, NULL, 'e'},
{"no-effective", no_argument, NULL, 'E'},
{"default", no_argument, NULL, 'd'}, {"default", no_argument, NULL, 'd'},
{"dir", no_argument, NULL, 'd'}, {"dir", no_argument, NULL, 'd'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"noname", no_argument, NULL, 'n'}, {"noname", no_argument, NULL, 'n'}, /* Backward compat */
{"numeric", no_argument, NULL, 'n'},
{"version", no_argument, NULL, 'V'}, {"version", no_argument, NULL, 'V'},
{0, no_argument, NULL, 0} {0, no_argument, NULL, 0}
}; };
const char *opts = "adhnV"; const char *opts = "acdeEhnV";
static void static void
print_version () print_version ()
@ -142,8 +149,11 @@ main (int argc, char **argv)
int c; int c;
int ret = 0; int ret = 0;
int aopt = 0; int aopt = 0;
int copt = 0;
int eopt = 0;
int dopt = 0; int dopt = 0;
int nopt = 0; int nopt = 0;
int istty = isatty (fileno (stdout));
struct stat st; struct stat st;
aclent_t acls[MAX_ACL_ENTRIES]; aclent_t acls[MAX_ACL_ENTRIES];
@ -155,9 +165,18 @@ main (int argc, char **argv)
case 'a': case 'a':
aopt = 1; aopt = 1;
break; break;
case 'c':
copt = 1;
break;
case 'd': case 'd':
dopt = 1; dopt = 1;
break; break;
case 'e':
eopt = 1;
break;
case 'E':
eopt = -1;
break;
case 'h': case 'h':
usage (stdout); usage (stdout);
return 0; return 0;
@ -179,6 +198,8 @@ main (int argc, char **argv)
for (; optind < argc; ++optind) for (; optind < argc; ++optind)
{ {
int i, num_acls; int i, num_acls;
mode_t mask = S_IRWXO, def_mask = S_IRWXO;
if (stat (argv[optind], &st) if (stat (argv[optind], &st)
|| (num_acls = acl (argv[optind], GETACL, MAX_ACL_ENTRIES, acls)) < 0) || (num_acls = acl (argv[optind], GETACL, MAX_ACL_ENTRIES, acls)) < 0)
{ {
@ -187,28 +208,42 @@ main (int argc, char **argv)
ret = 2; ret = 2;
continue; continue;
} }
printf ("# file: %s\n", argv[optind]); if (!copt)
if (nopt)
{ {
printf ("# owner: %lu\n", (unsigned long)st.st_uid); printf ("# file: %s\n", argv[optind]);
printf ("# group: %lu\n", (unsigned long)st.st_gid); if (nopt)
{
printf ("# owner: %lu\n", (unsigned long)st.st_uid);
printf ("# group: %lu\n", (unsigned long)st.st_gid);
}
else
{
printf ("# owner: %s\n", username (st.st_uid));
printf ("# group: %s\n", groupname (st.st_gid));
}
if (st.st_mode & (S_ISUID | S_ISGID | S_ISVTX))
printf ("# flags: %c%c%c\n", (st.st_mode & S_ISUID) ? 's' : '-',
(st.st_mode & S_ISGID) ? 's' : '-',
(st.st_mode & S_ISVTX) ? 't' : '-');
} }
else
{
printf ("# owner: %s\n", username (st.st_uid));
printf ("# group: %s\n", groupname (st.st_gid));
}
if (st.st_mode & (S_ISUID | S_ISGID | S_ISVTX))
printf ("# flags: %c%c%c\n", (st.st_mode & S_ISUID) ? 's' : '-',
(st.st_mode & S_ISGID) ? 's' : '-',
(st.st_mode & S_ISVTX) ? 't' : '-');
for (i = 0; i < num_acls; ++i) for (i = 0; i < num_acls; ++i)
{ {
if (acls[i].a_type == CLASS_OBJ)
mask = acls[i].a_perm;
else if (acls[i].a_type == DEF_CLASS_OBJ)
def_mask = acls[i].a_perm;
}
for (i = 0; i < num_acls; ++i)
{
int n = 0;
int print_effective = 0;
mode_t effective = acls[i].a_perm;
if (acls[i].a_type & ACL_DEFAULT) if (acls[i].a_type & ACL_DEFAULT)
{ {
if (aopt) if (aopt)
continue; continue;
printf ("default:"); n += printf ("default:");
} }
else if (dopt) else if (dopt)
continue; continue;
@ -219,18 +254,18 @@ main (int argc, char **argv)
break; break;
case USER: case USER:
if (nopt) if (nopt)
printf ("user:%lu:", (unsigned long)acls[i].a_id); n += printf ("user:%lu:", (unsigned long)acls[i].a_id);
else else
printf ("user:%s:", username (acls[i].a_id)); n += printf ("user:%s:", username (acls[i].a_id));
break; break;
case GROUP_OBJ: case GROUP_OBJ:
printf ("group::"); n += printf ("group::");
break; break;
case GROUP: case GROUP:
if (nopt) if (nopt)
printf ("group:%lu:", (unsigned long)acls[i].a_id); n += printf ("group:%lu:", (unsigned long)acls[i].a_id);
else else
printf ("group:%s:", groupname (acls[i].a_id)); n += printf ("group:%s:", groupname (acls[i].a_id));
break; break;
case CLASS_OBJ: case CLASS_OBJ:
printf ("mask:"); printf ("mask:");
@ -239,7 +274,37 @@ main (int argc, char **argv)
printf ("other:"); printf ("other:");
break; break;
} }
printf ("%s\n", permstr (acls[i].a_perm)); n += printf ("%s", permstr (acls[i].a_perm));
switch (acls[i].a_type)
{
case USER:
case GROUP_OBJ:
case GROUP:
effective = acls[i].a_perm & mask;
print_effective = 1;
break;
case DEF_USER:
case DEF_GROUP_OBJ:
case DEF_GROUP:
effective = acls[i].a_perm & def_mask;
print_effective = 1;
break;
}
if (print_effective && eopt >= 0
&& (eopt > 0 || effective != acls[i].a_perm))
{
if (istty)
{
n = 40 - n;
if (n <= 0)
n = 1;
printf ("%*s", n, " ");
}
else
putchar ('\t');
printf ("#effective:%s", permstr (effective));
}
putchar ('\n');
} }
putchar ('\n'); putchar ('\n');
} }