https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=bd57946148b82afe7c3e73b6d1ba7a5b8f73f36e

commit bd57946148b82afe7c3e73b6d1ba7a5b8f73f36e
Author: Corinna Vinschen <[email protected]>
Date:   Thu Apr 16 13:31:16 2015 +0200

    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 <[email protected]>

Diff:
---
 winsup/doc/ChangeLog   |   4 ++
 winsup/doc/utils.xml   |  13 ++--
 winsup/utils/ChangeLog |  10 +++
 winsup/utils/getfacl.c | 181 +++++++++++++++++++++++++++++++++----------------
 4 files changed, 145 insertions(+), 63 deletions(-)

diff --git a/winsup/doc/ChangeLog b/winsup/doc/ChangeLog
index a0507a4..05cf519 100644
--- a/winsup/doc/ChangeLog
+++ b/winsup/doc/ChangeLog
@@ -1,3 +1,7 @@
+2015-04-16  Corinna Vinschen  <[email protected]>
+
+       * utils.xml (getfacl): Show new option output.
+
 2015-04-10  Corinna Vinschen  <[email protected]>
 
        * new-features.xml (ov-new2.0): Rename from ov-new1.7.36 and change
diff --git a/winsup/doc/utils.xml b/winsup/doc/utils.xml
index adafc2b..d711cf2 100644
--- a/winsup/doc/utils.xml
+++ b/winsup/doc/utils.xml
@@ -519,11 +519,14 @@ Usage: getfacl [-adn] FILE [FILE2...]
 
 Display file and directory access control lists (ACLs).
  
-  -a, --access   display the file access control list
-  -d, --default  display the default access control list
-  -h, --help     print help explaining the command line options
-  -n, --noname   display user and group IDs instead of names
-  -V, --version  output version information and exit
+  -a, --access        display the file access control list only
+  -d, --default       display the default access control list only
+  -c, --omit-header   do not display the comment header
+  -e, --all-effective print all effective rights
+  -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
 line separates the ACLs for each file.
diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog
index ef6d32e..5e7025d 100644
--- a/winsup/utils/ChangeLog
+++ b/winsup/utils/ChangeLog
@@ -1,3 +1,13 @@
+2015-04-16  Corinna Vinschen  <[email protected]>
+
+       * 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  <[email protected]>
 
        * getfacl.c (usage): Change --all to --access, --dir to --default.
diff --git a/winsup/utils/getfacl.c b/winsup/utils/getfacl.c
index 0bc4848..07d8a8a 100644
--- a/winsup/utils/getfacl.c
+++ b/winsup/utils/getfacl.c
@@ -66,61 +66,68 @@ static void
 usage (FILE * stream)
 {
   fprintf (stream, "Usage: %s [-adn] FILE [FILE2...]\n"
-           "\n"
-           "Display file and directory access control lists (ACLs).\n"
-           "\n"
-           "  -a, --access   display the file access control list\n"
-           "  -d, --default  display the default access control list\n"
-           "  -h, --help     print help explaining the command line options\n"
-           "  -n, --noname   display user and group IDs instead of names\n"
-           "  -V, --version  output version information and exit\n"
-           "\n"
-           "When multiple files are specified on the command line, a blank\n"
-           "line separates the ACLs for each file.\n", prog_name);
+       "\n"
+       "Display file and directory access control lists (ACLs).\n"
+       "\n"
+       "  -a, --access        display the file access control list only\n"
+       "  -d, --default       display the default access control list only\n"
+       "  -c, --omit-header   do not display the comment header\n"
+       "  -e, --all-effective print all effective rights\n"
+       "  -E, --no-effective  print no effective rights\n"
+       "  -n, --numeric       print numeric user/group identifiers\n"
+       "  -V, --version       print version and exit\n"
+       "  -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)
     {
       fprintf (stream, ""
-           "For each argument that is a regular file, special file or\n"
-           "directory, getfacl displays the owner, the group, and the ACL.\n"
-           "For directories getfacl displays additionally the default ACL.\n"
-           "\n"
-           "With no options specified, getfacl displays the filename, the\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"
-           "exists.\n"
-           "\n"
-           "The format for ACL output is as follows:\n"
-           "     # file: filename\n"
-           "     # owner: name or uid\n"
-           "     # group: name or uid\n"
-           "     # flags: sst\n"
-           "     user::perm\n"
-           "     user:name or uid:perm\n"
-           "     group::perm\n"
-           "     group:name or gid:perm\n"
-           "     mask:perm\n"
-           "     other:perm\n"
-           "     default:user::perm\n"
-           "     default:user:name or uid:perm\n"
-           "     default:group::perm\n"
-           "     default:group:name or gid:perm\n"
-           "     default:mask:perm\n"
-           "     default:other:perm\n"
-           "\n");
+       "For each argument that is a regular file, special file or\n"
+       "directory, getfacl displays the owner, the group, and the ACL.\n"
+       "For directories getfacl displays additionally the default ACL.\n"
+       "\n"
+       "With no options specified, getfacl displays the filename, the\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"
+       "exists.\n"
+       "\n"
+       "The format for ACL output is as follows:\n"
+       "     # file: filename\n"
+       "     # owner: name or uid\n"
+       "     # group: name or uid\n"
+       "     # flags: sst\n"
+       "     user::perm\n"
+       "     user:name or uid:perm\n"
+       "     group::perm\n"
+       "     group:name or gid:perm\n"
+       "     mask:perm\n"
+       "     other:perm\n"
+       "     default:user::perm\n"
+       "     default:user:name or uid:perm\n"
+       "     default:group::perm\n"
+       "     default:group:name or gid:perm\n"
+       "     default:mask:perm\n"
+       "     default:other:perm\n"
+       "\n");
     }
 }
 
 struct option longopts[] = {
   {"access", 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'},
   {"dir", no_argument, NULL, 'd'},
   {"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'},
   {0, no_argument, NULL, 0}
 };
-const char *opts = "adhnV";
+const char *opts = "acdeEhnV";
 
 static void
 print_version ()
@@ -142,8 +149,11 @@ main (int argc, char **argv)
   int c;
   int ret = 0;
   int aopt = 0;
+  int copt = 0;
+  int eopt = 0;
   int dopt = 0;
   int nopt = 0;
+  int istty = isatty (fileno (stdout));
   struct stat st;
   aclent_t acls[MAX_ACL_ENTRIES];
 
@@ -155,9 +165,18 @@ main (int argc, char **argv)
       case 'a':
        aopt = 1;
        break;
+      case 'c':
+       copt = 1;
+       break;
       case 'd':
        dopt = 1;
        break;
+      case 'e':
+       eopt = 1;
+       break;
+      case 'E':
+       eopt = -1;
+       break;
       case 'h':
        usage (stdout);
        return 0;
@@ -179,6 +198,8 @@ main (int argc, char **argv)
   for (; optind < argc; ++optind)
     {
       int i, num_acls;
+      mode_t mask = S_IRWXO, def_mask = S_IRWXO;
+
       if (stat (argv[optind], &st)
          || (num_acls = acl (argv[optind], GETACL, MAX_ACL_ENTRIES, acls)) < 0)
        {
@@ -187,28 +208,42 @@ main (int argc, char **argv)
          ret = 2;
          continue;
        }
-      printf ("# file: %s\n", argv[optind]);
-      if (nopt)
+      if (!copt)
        {
-         printf ("# owner: %lu\n", (unsigned long)st.st_uid);
-         printf ("# group: %lu\n", (unsigned long)st.st_gid);
+         printf ("# file: %s\n", argv[optind]);
+         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
+      for (i = 0; i < num_acls; ++i)
        {
-         printf ("# owner: %s\n", username (st.st_uid));
-         printf ("# group: %s\n", groupname (st.st_gid));
+         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;
        }
-      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)
        {
+         int n = 0;
+         int print_effective = 0;
+         mode_t effective = acls[i].a_perm;
+
          if (acls[i].a_type & ACL_DEFAULT)
            {
              if (aopt)
                continue;
-             printf ("default:");
+             n += printf ("default:");
            }
          else if (dopt)
            continue;
@@ -219,18 +254,18 @@ main (int argc, char **argv)
              break;
            case USER:
              if (nopt)
-               printf ("user:%lu:", (unsigned long)acls[i].a_id);
+               n += printf ("user:%lu:", (unsigned long)acls[i].a_id);
              else
-               printf ("user:%s:", username (acls[i].a_id));
+               n += printf ("user:%s:", username (acls[i].a_id));
              break;
            case GROUP_OBJ:
-             printf ("group::");
+             n += printf ("group::");
              break;
            case GROUP:
              if (nopt)
-               printf ("group:%lu:", (unsigned long)acls[i].a_id);
+               n += printf ("group:%lu:", (unsigned long)acls[i].a_id);
              else
-               printf ("group:%s:", groupname (acls[i].a_id));
+               n += printf ("group:%s:", groupname (acls[i].a_id));
              break;
            case CLASS_OBJ:
              printf ("mask:");
@@ -239,7 +274,37 @@ main (int argc, char **argv)
              printf ("other:");
              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');
     }

Reply via email to