Merge branch 'stable'
[gnulib.git] / tests / test-sameacls.c
index 7dcec2a..421f841 100644 (file)
@@ -1,5 +1,5 @@
 /* Test whether two files have the same ACLs.
-   Copyright (C) 2008-2010 Free Software Foundation, Inc.
+   Copyright (C) 2008-2011 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #include <string.h>
 #include <sys/stat.h>
 
-#if HAVE_ACL_GET_FILE || HAVE_ACL || HAVE_ACLX_GET || HAVE_STATACL
+#if HAVE_ACL_GET_FILE || HAVE_FACL || HAVE_GETACL || HAVE_ACLX_GET || HAVE_STATACL || HAVE_ACLSORT
 # include <sys/types.h>
 # include <sys/acl.h>
 #endif
+#if HAVE_ACLV_H
+# include <sys/types.h>
+# include <aclv.h>
+#endif
 
 #include "progname.h"
 #include "read-file.h"
@@ -218,12 +222,16 @@ main (int argc, char *argv[])
               }
           }
       }
-#elif HAVE_ACL && defined GETACL /* Solaris, Cygwin, not HP-UX */
+#elif HAVE_FACL && defined GETACL /* Solaris, Cygwin, not HP-UX */
   int count1;
   int count2;
 
   count1 = acl (file1, GETACLCNT, 0, NULL);
+  if (count1 < 0 && errno == ENOSYS) /* Can happen on Solaris 10 with ZFS */
+    count1 = 0;
   count2 = acl (file2, GETACLCNT, 0, NULL);
+  if (count2 < 0 && errno == ENOSYS) /* Can happen on Solaris 10 with ZFS */
+    count2 = 0;
 
   if (count1 < 0)
     {
@@ -249,13 +257,13 @@ main (int argc, char *argv[])
       aclent_t *entries2 = XNMALLOC (count2, aclent_t);
       int i;
 
-      if (acl (file1, GETACL, count1, entries1) < count1)
+      if (count1 > 0 && acl (file1, GETACL, count1, entries1) < count1)
         {
           fprintf (stderr, "error retrieving the ACLs of file %s\n", file1);
           fflush (stderr);
           abort ();
         }
-      if (acl (file2, GETACL, count2, entries2) < count1)
+      if (count2 > 0 && acl (file2, GETACL, count2, entries2) < count1)
         {
           fprintf (stderr, "error retrieving the ACLs of file %s\n", file2);
           fflush (stderr);
@@ -360,10 +368,12 @@ main (int argc, char *argv[])
   int count2;
 
   count1 = getacl (file1, 0, NULL);
-  if (count1 < 0 && (errno == ENOSYS || errno == EOPNOTSUPP))
+  if (count1 < 0
+      && (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP))
     count1 = 0;
   count2 = getacl (file2, 0, NULL);
-  if (count2 < 0 && (errno == ENOSYS || errno == EOPNOTSUPP))
+  if (count2 < 0
+      && (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP))
     count2 = 0;
 
   if (count1 < 0)
@@ -424,49 +434,137 @@ main (int argc, char *argv[])
             }
         }
     }
+
+# if HAVE_ACLV_H /* HP-UX >= 11.11 */
+  {
+    struct acl dummy_entries[NACLVENTRIES];
+
+    count1 = acl ((char *) file1, ACL_CNT, NACLVENTRIES, dummy_entries);
+    if (count1 < 0
+        && (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL))
+      count1 = 0;
+    count2 = acl ((char *) file2, ACL_CNT, NACLVENTRIES, dummy_entries);
+    if (count2 < 0
+        && (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL))
+      count2 = 0;
+  }
+
+  if (count1 < 0)
+    {
+      fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
+      fflush (stderr);
+      abort ();
+    }
+  if (count2 < 0)
+    {
+      fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
+      fflush (stderr);
+      abort ();
+    }
+  if (count1 != count2)
+    {
+      fprintf (stderr, "files %s and %s have different number of ACLs: %d and %d\n",
+               file1, file2, count1, count2);
+      return 1;
+    }
+  else if (count1 > 0)
+    {
+      struct acl *entries1 = XNMALLOC (count1, struct acl);
+      struct acl *entries2 = XNMALLOC (count2, struct acl);
+      int i;
+
+      if (acl ((char *) file1, ACL_GET, count1, entries1) < count1)
+        {
+          fprintf (stderr, "error retrieving the ACLs of file %s\n", file1);
+          fflush (stderr);
+          abort ();
+        }
+      if (acl ((char *) file2, ACL_GET, count2, entries2) < count1)
+        {
+          fprintf (stderr, "error retrieving the ACLs of file %s\n", file2);
+          fflush (stderr);
+          abort ();
+        }
+      for (i = 0; i < count1; i++)
+        {
+          if (entries1[i].a_type != entries2[i].a_type)
+            {
+              fprintf (stderr, "files %s and %s: different ACL entry #%d: different types %d and %d\n",
+                       file1, file2, i, entries1[i].a_type, entries2[i].a_type);
+              return 1;
+            }
+          if (entries1[i].a_id != entries2[i].a_id)
+            {
+              fprintf (stderr, "files %s and %s: different ACL entry #%d: different ids %d and %d\n",
+                       file1, file2, i, (int)entries1[i].a_id, (int)entries2[i].a_id);
+              return 1;
+            }
+          if (entries1[i].a_perm != entries2[i].a_perm)
+            {
+              fprintf (stderr, "files %s and %s: different ACL entry #%d: different permissions %03o and %03o\n",
+                       file1, file2, i, (unsigned int) entries1[i].a_perm, (unsigned int) entries2[i].a_perm);
+              return 1;
+            }
+        }
+    }
+# endif
 #elif HAVE_ACLX_GET /* AIX */
   acl_type_t type1;
   char acl1[1000];
   size_t aclsize1 = sizeof (acl1);
   mode_t mode1;
   char text1[1000];
+  size_t textsize1 = sizeof (text1);
   acl_type_t type2;
   char acl2[1000];
   size_t aclsize2 = sizeof (acl2);
   mode_t mode2;
   char text2[1000];
+  size_t textsize2 = sizeof (text2);
 
   /* The docs say that type1 being 0 is equivalent to ACL_ANY, but it is not
      true, in AIX 5.3.  */
   type1.u64 = ACL_ANY;
   if (aclx_get (file1, 0, &type1, acl1, &aclsize1, &mode1) < 0)
     {
-      fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
-      fflush (stderr);
-      abort ();
-    }
-  if (aclx_printStr (text1, sizeof (text1), acl1, aclsize1, type1, file1, 0) < 0)
-    {
-      fprintf (stderr, "cannot convert the ACLs of file %s to text\n", file1);
-      fflush (stderr);
-      abort ();
+      if (errno == ENOSYS)
+        text1[0] = '\0';
+      else
+        {
+          fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
+          fflush (stderr);
+          abort ();
+        }
     }
+  else
+    if (aclx_printStr (text1, &textsize1, acl1, aclsize1, type1, file1, 0) < 0)
+      {
+        fprintf (stderr, "cannot convert the ACLs of file %s to text\n", file1);
+        fflush (stderr);
+        abort ();
+      }
 
   /* The docs say that type2 being 0 is equivalent to ACL_ANY, but it is not
      true, in AIX 5.3.  */
   type2.u64 = ACL_ANY;
   if (aclx_get (file2, 0, &type2, acl2, &aclsize2, &mode2) < 0)
     {
-      fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
-      fflush (stderr);
-      abort ();
-    }
-  if (aclx_printStr (text2, sizeof (text2), acl2, aclsize2, type2, file2, 0) < 0)
-    {
-      fprintf (stderr, "cannot convert the ACLs of file %s to text\n", file2);
-      fflush (stderr);
-      abort ();
+      if (errno == ENOSYS)
+        text2[0] = '\0';
+      else
+        {
+          fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
+          fflush (stderr);
+          abort ();
+        }
     }
+  else
+    if (aclx_printStr (text2, &textsize2, acl2, aclsize2, type2, file2, 0) < 0)
+      {
+        fprintf (stderr, "cannot convert the ACLs of file %s to text\n", file2);
+        fflush (stderr);
+        abort ();
+      }
 
   if (strcmp (text1, text2) != 0)
     {
@@ -520,6 +618,71 @@ main (int argc, char *argv[])
                file1, file2);
       return 1;
     }
+#elif HAVE_ACLSORT /* NonStop Kernel */
+  int count1;
+  int count2;
+
+  count1 = acl ((char *) file1, ACL_CNT, NACLENTRIES, NULL);
+  count2 = acl ((char *) file2, ACL_CNT, NACLENTRIES, NULL);
+
+  if (count1 < 0)
+    {
+      fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
+      fflush (stderr);
+      abort ();
+    }
+  if (count2 < 0)
+    {
+      fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
+      fflush (stderr);
+      abort ();
+    }
+  if (count1 != count2)
+    {
+      fprintf (stderr, "files %s and %s have different number of ACLs: %d and %d\n",
+               file1, file2, count1, count2);
+      return 1;
+    }
+  else if (count1 > 0)
+    {
+      struct acl *entries1 = XNMALLOC (count1, struct acl);
+      struct acl *entries2 = XNMALLOC (count2, struct acl);
+      int i;
+
+      if (acl ((char *) file1, ACL_GET, count1, entries1) < count1)
+        {
+          fprintf (stderr, "error retrieving the ACLs of file %s\n", file1);
+          fflush (stderr);
+          abort ();
+        }
+      if (acl ((char *) file2, ACL_GET, count2, entries2) < count1)
+        {
+          fprintf (stderr, "error retrieving the ACLs of file %s\n", file2);
+          fflush (stderr);
+          abort ();
+        }
+      for (i = 0; i < count1; i++)
+        {
+          if (entries1[i].a_type != entries2[i].a_type)
+            {
+              fprintf (stderr, "files %s and %s: different ACL entry #%d: different types %d and %d\n",
+                       file1, file2, i, entries1[i].a_type, entries2[i].a_type);
+              return 1;
+            }
+          if (entries1[i].a_id != entries2[i].a_id)
+            {
+              fprintf (stderr, "files %s and %s: different ACL entry #%d: different ids %d and %d\n",
+                       file1, file2, i, (int)entries1[i].a_id, (int)entries2[i].a_id);
+              return 1;
+            }
+          if (entries1[i].a_perm != entries2[i].a_perm)
+            {
+              fprintf (stderr, "files %s and %s: different ACL entry #%d: different permissions %03o and %03o\n",
+                       file1, file2, i, (unsigned int) entries1[i].a_perm, (unsigned int) entries2[i].a_perm);
+              return 1;
+            }
+        }
+    }
 #endif
   }