X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fcopy-acl.c;h=f0dc1165deb2988d9c750fccec42cd1cd8c70acc;hb=ae0b8a21cc48db0d06413df85be4184f17de8d5f;hp=c047913d42da537bfa2f3b94862e86ed17fa6f0a;hpb=ca156dd87d41d9dbd0eb90f4d8b7a2a73c78a47e;p=gnulib.git diff --git a/lib/copy-acl.c b/lib/copy-acl.c index c047913d4..f0dc1165d 100644 --- a/lib/copy-acl.c +++ b/lib/copy-acl.c @@ -1,6 +1,6 @@ /* copy-acl.c - copy access control list from one file to another file - 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 @@ -358,7 +358,7 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name, if (ret < 0 && saved_errno == 0) { saved_errno = errno; - if ((errno == ENOSYS || errno == EOPNOTSUPP) + if ((errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL) && !acl_nontrivial (count, entries)) saved_errno = 0; } @@ -420,7 +420,7 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name, if (count < 0) { - if (errno == ENOSYS || errno == EOPNOTSUPP) + if (ACL_NOT_WELL_SUPPORTED (errno)) { count = 0; break; @@ -455,7 +455,7 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name, { int saved_errno = errno; - if (errno == ENOSYS || errno == EOPNOTSUPP) + if (ACL_NOT_WELL_SUPPORTED (errno)) { struct stat source_statbuf; @@ -516,6 +516,68 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name, return 0; +#elif USE_ACL && HAVE_ACLSORT /* NonStop Kernel */ + + int count; + struct acl entries[NACLENTRIES]; + int ret; + + for (;;) + { + count = acl ((char *) src_name, ACL_CNT, NACLENTRIES, NULL); + + if (count < 0) + { + if (0) + { + count = 0; + break; + } + else + return -2; + } + + if (count == 0) + break; + + if (count > NACLENTRIES) + /* If NACLENTRIES cannot be trusted, use dynamic memory allocation. */ + abort (); + + if (acl ((char *) src_name, ACL_GET, count, entries) == count) + break; + /* Huh? The number of ACL entries changed since the last call. + Repeat. */ + } + + if (count == 0) + return qset_acl (dst_name, dest_desc, mode); + + ret = acl ((char *) dst_name, ACL_SET, count, entries); + if (ret < 0) + { + int saved_errno = errno; + + if (0) + { + if (!acl_nontrivial (count, entries)) + return chmod_or_fchmod (dst_name, dest_desc, mode); + } + + chmod_or_fchmod (dst_name, dest_desc, mode); + errno = saved_errno; + return -1; + } + + if (mode & (S_ISUID | S_ISGID | S_ISVTX)) + { + /* We did not call chmod so far, and either the mode and the ACL are + separate or special bits are to be set which don't fit into ACLs. */ + + return chmod_or_fchmod (dst_name, dest_desc, mode); + } + return 0; + #else return qset_acl (dst_name, dest_desc, mode);