summaryrefslogtreecommitdiff
path: root/lib/file-has-acl.c
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2011-06-13 02:11:03 +0200
committerBruno Haible <bruno@clisp.org>2011-06-13 02:11:03 +0200
commit227b08bbf68b66e8d7cd4da5c1a6f0ebf5a5d9e8 (patch)
tree91f3e525a17a538c8e00c635064554f0c2f6469b /lib/file-has-acl.c
parent9cbf59b7fd224f263fce77ef1dadd3be5439fc4f (diff)
downloadgnulib-227b08bbf68b66e8d7cd4da5c1a6f0ebf5a5d9e8.tar.gz
acl: Add support for HP-UX >= 11.11 JFS ACLs.
* doc/acl-resources.txt: Add info about the ACL APIs on HP-UX. * m4/acl.m4 (gl_FUNC_ACL): Also test for HP-UX 11.11 API. * lib/acl-internal.h [HP-UX 11.11]: Include <aclv.h>. (acl, aclsort): New declarations. (aclv_nontrivial): New declaration. * lib/file-has-acl.c (aclv_nontrivial) [HP-UX 11.11]: New function. (file_has_acl): Read also the second kind of HP-UX ACLs. * lib/set-mode-acl.c (qset_acl) [HP-UX 11.11]: Try to set the second kind of HP-UX ACLs if the first kind fails. * lib/copy-acl.c (qcopy_acl) [HP-UX 11.11]: Read and set also the second kind of HP-UX ACLs. * tests/test-sameacls.c [HP-UX 11.11]: Include <aclv.h>. (main) [HP-UX 11.11]: Test also whether the second kind of HP-UX ACLs agree. * tests/test-file-has-acl.sh (acl_flavor) [HP-UX 11.11]: Set to hpuxjfs. Handle hpuxjfs. * tests/test-set-mode-acl.sh (acl_flavor) [HP-UX 11.11]: Set to hpuxjfs. Handle hpuxjfs. * tests/test-copy-acl.sh (acl_flavor) [HP-UX 11.11]: Set to hpuxjfs. (func_test_same_acls): Use both lsacl and getacl. Handle hpuxjfs. * tests/test-copy-file.sh (acl_flavor) [HP-UX 11.11]: Set to hpuxjfs. (func_test_same_acls): Use both lsacl and getacl. Handle hpuxjfs.
Diffstat (limited to 'lib/file-has-acl.c')
-rw-r--r--lib/file-has-acl.c75
1 files changed, 71 insertions, 4 deletions
diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c
index 03decf46ba..3d4d5c16ff 100644
--- a/lib/file-has-acl.c
+++ b/lib/file-has-acl.c
@@ -234,6 +234,33 @@ acl_nontrivial (int count, struct acl_entry *entries, struct stat *sb)
return 0;
}
+# if HAVE_ACLV_H /* HP-UX >= 11.11 */
+
+/* Return 1 if the given ACL is non-trivial.
+ Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
+int
+aclv_nontrivial (int count, struct acl *entries)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ struct acl *ace = &entries[i];
+
+ /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
+ If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
+ We don't need to check ace->a_id in these cases. */
+ if (!(ace->a_type == USER_OBJ /* no need to check ace->a_id here */
+ || ace->a_type == GROUP_OBJ /* no need to check ace->a_id here */
+ || ace->a_type == CLASS_OBJ
+ || ace->a_type == OTHER_OBJ))
+ return 1;
+ }
+ return 0;
+}
+
+# endif
+
#elif USE_ACL && (HAVE_ACLX_GET || HAVE_STATACL) /* AIX */
/* Return 1 if the given ACL is non-trivial.
@@ -519,11 +546,11 @@ file_has_acl (char const *name, struct stat const *sb)
# elif HAVE_GETACL /* HP-UX */
- int count;
- struct acl_entry entries[NACLENTRIES];
-
for (;;)
{
+ int count;
+ struct acl_entry entries[NACLENTRIES];
+
count = getacl (name, 0, NULL);
if (count < 0)
@@ -532,7 +559,7 @@ file_has_acl (char const *name, struct stat const *sb)
EOPNOTSUPP is typically seen on NFS mounts.
ENOTSUP was seen on Quantum StorNext file systems (cvfs). */
if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)
- return 0;
+ break;
else
return -1;
}
@@ -563,6 +590,46 @@ file_has_acl (char const *name, struct stat const *sb)
Repeat. */
}
+# if HAVE_ACLV_H /* HP-UX >= 11.11 */
+
+ for (;;)
+ {
+ int count;
+ struct acl entries[NACLVENTRIES];
+
+ count = acl ((char *) name, ACL_CNT, NACLVENTRIES, entries);
+
+ if (count < 0)
+ {
+ /* EOPNOTSUPP is seen on NFS in HP-UX 11.11, 11.23.
+ EINVAL is seen on NFS in HP-UX 11.31. */
+ if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)
+ break;
+ else
+ return -1;
+ }
+
+ if (count == 0)
+ return 0;
+
+ if (count > NACLVENTRIES)
+ /* If NACLVENTRIES cannot be trusted, use dynamic memory
+ allocation. */
+ abort ();
+
+ /* If there are more than 4 entries, there cannot be only the
+ four base ACL entries. */
+ if (count > 4)
+ return 1;
+
+ if (acl ((char *) name, ACL_GET, count, entries) == count)
+ return aclv_nontrivial (count, entries);
+ /* Huh? The number of ACL entries changed since the last call.
+ Repeat. */
+ }
+
+# endif
+
# elif HAVE_ACLX_GET && defined ACL_AIX_WIP /* AIX */
acl_type_t type;