X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fset-mode-acl.c;h=5ba86a5bcbead478bf2f553273d7adfeb66ed3e4;hb=30c3201628476927fee18e778dacafe1dadd7de2;hp=2cd2c75f387376f40be3fdbb907093dd91b33c65;hpb=ca156dd87d41d9dbd0eb90f4d8b7a2a73c78a47e;p=gnulib.git diff --git a/lib/set-mode-acl.c b/lib/set-mode-acl.c index 2cd2c75f3..5ba86a5bc 100644 --- a/lib/set-mode-acl.c +++ b/lib/set-mode-acl.c @@ -1,6 +1,6 @@ /* set-mode-acl.c - set access control list equivalent to a mode - Copyright (C) 2002-2003, 2005-2010 Free Software Foundation, Inc. + Copyright (C) 2002-2003, 2005-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 @@ -201,7 +201,7 @@ qset_acl (char const *name, int desc, mode_t mode) return chmod_or_fchmod (name, desc, mode); # endif -# elif HAVE_ACL && defined GETACLCNT /* Solaris, Cygwin, not HP-UX */ +# elif HAVE_FACL && defined GETACLCNT /* Solaris, Cygwin, not HP-UX */ # if defined ACL_NO_TRIVIAL /* Solaris 10 (newer version), which has additional API declared in @@ -406,7 +406,6 @@ qset_acl (char const *name, int desc, mode_t mode) # elif HAVE_GETACL /* HP-UX */ struct stat statbuf; - struct acl_entry entries[3]; int ret; if (desc != -1) @@ -416,25 +415,68 @@ qset_acl (char const *name, int desc, mode_t mode) if (ret < 0) return -1; - entries[0].uid = statbuf.st_uid; - entries[0].gid = ACL_NSGROUP; - entries[0].mode = (mode >> 6) & 7; - entries[1].uid = ACL_NSUSER; - entries[1].gid = statbuf.st_gid; - entries[1].mode = (mode >> 3) & 7; - entries[2].uid = ACL_NSUSER; - entries[2].gid = ACL_NSGROUP; - entries[2].mode = mode & 7; + { + struct acl_entry entries[3]; + + entries[0].uid = statbuf.st_uid; + entries[0].gid = ACL_NSGROUP; + entries[0].mode = (mode >> 6) & 7; + entries[1].uid = ACL_NSUSER; + entries[1].gid = statbuf.st_gid; + entries[1].mode = (mode >> 3) & 7; + entries[2].uid = ACL_NSUSER; + entries[2].gid = ACL_NSGROUP; + entries[2].mode = mode & 7; - if (desc != -1) - ret = fsetacl (desc, sizeof (entries) / sizeof (struct acl_entry), entries); - else - ret = setacl (name, sizeof (entries) / sizeof (struct acl_entry), entries); + if (desc != -1) + ret = fsetacl (desc, sizeof (entries) / sizeof (struct acl_entry), entries); + else + ret = setacl (name, sizeof (entries) / sizeof (struct acl_entry), entries); + } if (ret < 0) { - if (errno == ENOSYS || errno == EOPNOTSUPP) - return chmod_or_fchmod (name, desc, mode); - return -1; + if (!(errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)) + return -1; + +# if HAVE_ACLV_H /* HP-UX >= 11.11 */ + { + struct acl entries[4]; + + entries[0].a_type = USER_OBJ; + entries[0].a_id = 0; /* irrelevant */ + entries[0].a_perm = (mode >> 6) & 7; + entries[1].a_type = GROUP_OBJ; + entries[1].a_id = 0; /* irrelevant */ + entries[1].a_perm = (mode >> 3) & 7; + entries[2].a_type = CLASS_OBJ; + entries[2].a_id = 0; + entries[2].a_perm = (mode >> 3) & 7; + entries[3].a_type = OTHER_OBJ; + entries[3].a_id = 0; + entries[3].a_perm = mode & 7; + + ret = aclsort (sizeof (entries) / sizeof (struct acl), 1, entries); + if (ret > 0) + abort (); + if (ret < 0) + { + if (0) + return chmod_or_fchmod (name, desc, mode); + return -1; + } + + ret = acl ((char *) name, ACL_SET, + sizeof (entries) / sizeof (struct acl), entries); + if (ret < 0) + { + if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL) + return chmod_or_fchmod (name, desc, mode); + return -1; + } + } +# else + return chmod_or_fchmod (name, desc, mode); +# endif } if (mode & (S_ISUID | S_ISGID | S_ISVTX)) @@ -573,6 +615,51 @@ qset_acl (char const *name, int desc, mode_t mode) return ret; +# elif HAVE_ACLSORT /* NonStop Kernel */ + + struct acl entries[4]; + int ret; + + entries[0].a_type = USER_OBJ; + entries[0].a_id = 0; /* irrelevant */ + entries[0].a_perm = (mode >> 6) & 7; + entries[1].a_type = GROUP_OBJ; + entries[1].a_id = 0; /* irrelevant */ + entries[1].a_perm = (mode >> 3) & 7; + entries[2].a_type = CLASS_OBJ; + entries[2].a_id = 0; + entries[2].a_perm = (mode >> 3) & 7; + entries[3].a_type = OTHER_OBJ; + entries[3].a_id = 0; + entries[3].a_perm = mode & 7; + + ret = aclsort (sizeof (entries) / sizeof (struct acl), 1, entries); + if (ret > 0) + abort (); + if (ret < 0) + { + if (0) + return chmod_or_fchmod (name, desc, mode); + return -1; + } + + ret = acl ((char *) name, ACL_SET, + sizeof (entries) / sizeof (struct acl), entries); + if (ret < 0) + { + if (0) + return chmod_or_fchmod (name, desc, mode); + return -1; + } + + if (mode & (S_ISUID | S_ISGID | S_ISVTX)) + { + /* We did not call chmod so far, so the special bits have not yet + been set. */ + return chmod_or_fchmod (name, desc, mode); + } + return 0; + # else /* Unknown flavor of ACLs */ return chmod_or_fchmod (name, desc, mode); # endif