Split off copy_acl function to separate file.
authorBruno Haible <bruno@clisp.org>
Thu, 22 May 2008 22:13:07 +0000 (00:13 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 22 May 2008 22:13:07 +0000 (00:13 +0200)
ChangeLog
lib/acl.c
lib/copy-acl.c [new file with mode: 0644]
m4/acl.m4
modules/acl

index 2d7f149..1c11e4a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2008-05-22  Bruno Haible  <bruno@clisp.org>
 
+       Split off copy_acl function to separate file.
+       * lib/copy-acl.c: New file, extracted from lib/acl.c.
+       * lib/acl.c (copy_acl): Moved function to separate file.
+       * m4/acl.m4 (gl_FUNC_ACL): Remove unconditional AC_LIBOBJs.
+       * modules/acl (Files): Add lib/copy-acl.c.
+       (Makefiles.am): Augment lib_SOURCES.
+
+2008-05-22  Bruno Haible  <bruno@clisp.org>
+
        * modules/copy-file-tests: New file.
        * tests/test-copy-file.sh: New file.
        * tests/test-copy-file.c: New file.
index b40e43a..10499a0 100644 (file)
--- a/lib/acl.c
+++ b/lib/acl.c
@@ -1,6 +1,6 @@
 /* acl.c - access control lists
 
-   Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2005-2008 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
@@ -37,149 +37,6 @@ chmod_or_fchmod (const char *name, int desc, mode_t mode)
     return chmod (name, mode);
 }
 
-/* Copy access control lists from one file to another. If SOURCE_DESC is
-   a valid file descriptor, use file descriptor operations, else use
-   filename based operations on SRC_NAME. Likewise for DEST_DESC and
-   DST_NAME.
-   If access control lists are not available, fchmod the target file to
-   MODE.  Also sets the non-permission bits of the destination file
-   (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set.
-   Return 0 if successful, otherwise output a diagnostic and return -1.  */
-
-int
-copy_acl (const char *src_name, int source_desc, const char *dst_name,
-         int dest_desc, mode_t mode)
-{
-  int ret;
-
-#if USE_ACL && HAVE_ACL_GET_FILE && HAVE_ACL_SET_FILE && HAVE_ACL_FREE
-  /* POSIX 1003.1e (draft 17 -- abandoned) specific version.  */
-
-  acl_t acl;
-  if (HAVE_ACL_GET_FD && source_desc != -1)
-    acl = acl_get_fd (source_desc);
-  else
-    acl = acl_get_file (src_name, ACL_TYPE_ACCESS);
-  if (acl == NULL)
-    {
-      if (ACL_NOT_WELL_SUPPORTED (errno))
-       return set_acl (dst_name, dest_desc, mode);
-      else
-        {
-         error (0, errno, "%s", quote (src_name));
-         return -1;
-       }
-    }
-
-  if (HAVE_ACL_SET_FD && dest_desc != -1)
-    ret = acl_set_fd (dest_desc, acl);
-  else
-    ret = acl_set_file (dst_name, ACL_TYPE_ACCESS, acl);
-  if (ret != 0)
-    {
-      int saved_errno = errno;
-
-      if (ACL_NOT_WELL_SUPPORTED (errno))
-        {
-         int n = acl_entries (acl);
-
-         acl_free (acl);
-         /* On most hosts an ACL is trivial if n == 3, and it cannot be
-            less than 3.  On IRIX 6.5 it is also trivial if n == -1.
-            For simplicity and safety, assume the ACL is trivial if n <= 3.
-            Also see file-has-acl.c for some of the other possibilities;
-            it's not clear whether that complexity is needed here.  */
-         if (n <= 3)
-           {
-             if (chmod_or_fchmod (dst_name, dest_desc, mode) != 0)
-               saved_errno = errno;
-             else
-               return 0;
-           }
-         else
-           chmod_or_fchmod (dst_name, dest_desc, mode);
-       }
-      else
-       {
-         acl_free (acl);
-         chmod_or_fchmod (dst_name, dest_desc, mode);
-       }
-      error (0, saved_errno, _("preserving permissions for %s"),
-            quote (dst_name));
-      return -1;
-    }
-  else
-    acl_free (acl);
-
-  if (mode & (S_ISUID | S_ISGID | S_ISVTX))
-    {
-      /* We did not call chmod so far, so the special bits have not yet
-         been set.  */
-
-      if (chmod_or_fchmod (dst_name, dest_desc, mode) != 0)
-       {
-         error (0, errno, _("preserving permissions for %s"),
-                quote (dst_name));
-         return -1;
-       }
-    }
-
-  if (S_ISDIR (mode))
-    {
-      acl = acl_get_file (src_name, ACL_TYPE_DEFAULT);
-      if (acl == NULL)
-       {
-         error (0, errno, "%s", quote (src_name));
-         return -1;
-       }
-
-      if (acl_set_file (dst_name, ACL_TYPE_DEFAULT, acl))
-       {
-         error (0, errno, _("preserving permissions for %s"),
-                quote (dst_name));
-         acl_free (acl);
-         return -1;
-       }
-      else
-        acl_free (acl);
-    }
-  return 0;
-
-#else
-
-# if USE_ACL && defined ACL_NO_TRIVIAL
-  /* Solaris 10 NFSv4 ACLs.  */
-  acl_t *aclp = NULL;
-  ret = (source_desc < 0
-        ? acl_get (src_name, ACL_NO_TRIVIAL, &aclp)
-        : facl_get (source_desc, ACL_NO_TRIVIAL, &aclp));
-  if (ret != 0 && errno != ENOSYS)
-    {
-      error (0, errno, "%s", quote (src_name));
-      return ret;
-    }
-# endif
-
-  ret = qset_acl (dst_name, dest_desc, mode);
-  if (ret != 0)
-    error (0, errno, _("preserving permissions for %s"), quote (dst_name));
-
-# if USE_ACL && defined ACL_NO_TRIVIAL
-  if (ret == 0 && aclp)
-    {
-      ret = (dest_desc < 0
-            ? acl_set (dst_name, aclp)
-            : facl_set (dest_desc, aclp));
-      if (ret != 0)
-       error (0, errno, _("preserving permissions for %s"), quote (dst_name));
-      acl_free (aclp);
-    }
-# endif
-
-  return ret;
-#endif
-}
-
 /* Set the access control lists of a file. If DESC is a valid file
    descriptor, use file descriptor operations where available, else use
    filename based operations on NAME.  If access control lists are not
diff --git a/lib/copy-acl.c b/lib/copy-acl.c
new file mode 100644 (file)
index 0000000..f5a879d
--- /dev/null
@@ -0,0 +1,167 @@
+/* copy-acl.c - copy access control list from one file to another file
+
+   Copyright (C) 2002-2003, 2005-2008 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
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+   Written by Paul Eggert and Andreas Gruenbacher.  */
+
+#include <config.h>
+
+#include "acl.h"
+
+#include "acl-internal.h"
+
+/* Copy access control lists from one file to another. If SOURCE_DESC is
+   a valid file descriptor, use file descriptor operations, else use
+   filename based operations on SRC_NAME. Likewise for DEST_DESC and
+   DST_NAME.
+   If access control lists are not available, fchmod the target file to
+   MODE.  Also sets the non-permission bits of the destination file
+   (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set.
+   Return 0 if successful, otherwise output a diagnostic and return -1.  */
+
+int
+copy_acl (const char *src_name, int source_desc, const char *dst_name,
+         int dest_desc, mode_t mode)
+{
+  int ret;
+
+#if USE_ACL && HAVE_ACL_GET_FILE && HAVE_ACL_SET_FILE && HAVE_ACL_FREE
+  /* POSIX 1003.1e (draft 17 -- abandoned) specific version.  */
+
+  acl_t acl;
+  if (HAVE_ACL_GET_FD && source_desc != -1)
+    acl = acl_get_fd (source_desc);
+  else
+    acl = acl_get_file (src_name, ACL_TYPE_ACCESS);
+  if (acl == NULL)
+    {
+      if (ACL_NOT_WELL_SUPPORTED (errno))
+       return set_acl (dst_name, dest_desc, mode);
+      else
+        {
+         error (0, errno, "%s", quote (src_name));
+         return -1;
+       }
+    }
+
+  if (HAVE_ACL_SET_FD && dest_desc != -1)
+    ret = acl_set_fd (dest_desc, acl);
+  else
+    ret = acl_set_file (dst_name, ACL_TYPE_ACCESS, acl);
+  if (ret != 0)
+    {
+      int saved_errno = errno;
+
+      if (ACL_NOT_WELL_SUPPORTED (errno))
+        {
+         int n = acl_entries (acl);
+
+         acl_free (acl);
+         /* On most hosts an ACL is trivial if n == 3, and it cannot be
+            less than 3.  On IRIX 6.5 it is also trivial if n == -1.
+            For simplicity and safety, assume the ACL is trivial if n <= 3.
+            Also see file-has-acl.c for some of the other possibilities;
+            it's not clear whether that complexity is needed here.  */
+         if (n <= 3)
+           {
+             if (chmod_or_fchmod (dst_name, dest_desc, mode) != 0)
+               saved_errno = errno;
+             else
+               return 0;
+           }
+         else
+           chmod_or_fchmod (dst_name, dest_desc, mode);
+       }
+      else
+       {
+         acl_free (acl);
+         chmod_or_fchmod (dst_name, dest_desc, mode);
+       }
+      error (0, saved_errno, _("preserving permissions for %s"),
+            quote (dst_name));
+      return -1;
+    }
+  else
+    acl_free (acl);
+
+  if (mode & (S_ISUID | S_ISGID | S_ISVTX))
+    {
+      /* We did not call chmod so far, so the special bits have not yet
+         been set.  */
+
+      if (chmod_or_fchmod (dst_name, dest_desc, mode) != 0)
+       {
+         error (0, errno, _("preserving permissions for %s"),
+                quote (dst_name));
+         return -1;
+       }
+    }
+
+  if (S_ISDIR (mode))
+    {
+      acl = acl_get_file (src_name, ACL_TYPE_DEFAULT);
+      if (acl == NULL)
+       {
+         error (0, errno, "%s", quote (src_name));
+         return -1;
+       }
+
+      if (acl_set_file (dst_name, ACL_TYPE_DEFAULT, acl))
+       {
+         error (0, errno, _("preserving permissions for %s"),
+                quote (dst_name));
+         acl_free (acl);
+         return -1;
+       }
+      else
+        acl_free (acl);
+    }
+  return 0;
+
+#else
+
+# if USE_ACL && defined ACL_NO_TRIVIAL
+  /* Solaris 10 NFSv4 ACLs.  */
+  acl_t *aclp = NULL;
+  ret = (source_desc < 0
+        ? acl_get (src_name, ACL_NO_TRIVIAL, &aclp)
+        : facl_get (source_desc, ACL_NO_TRIVIAL, &aclp));
+  if (ret != 0 && errno != ENOSYS)
+    {
+      error (0, errno, "%s", quote (src_name));
+      return ret;
+    }
+# endif
+
+  ret = qset_acl (dst_name, dest_desc, mode);
+  if (ret != 0)
+    error (0, errno, _("preserving permissions for %s"), quote (dst_name));
+
+# if USE_ACL && defined ACL_NO_TRIVIAL
+  if (ret == 0 && aclp)
+    {
+      ret = (dest_desc < 0
+            ? acl_set (dst_name, aclp)
+            : facl_set (dest_desc, aclp));
+      if (ret != 0)
+       error (0, errno, _("preserving permissions for %s"), quote (dst_name));
+      acl_free (aclp);
+    }
+# endif
+
+  return ret;
+#endif
+}
index 7b7cb64..2916a00 100644 (file)
--- a/m4/acl.m4
+++ b/m4/acl.m4
@@ -1,5 +1,5 @@
 # acl.m4 - check for access control list (ACL) primitives
-# serial 2
+# serial 3
 
 # Copyright (C) 2002, 2004-2008 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -10,9 +10,6 @@
 
 AC_DEFUN([gl_FUNC_ACL],
 [
-  AC_LIBOBJ([acl])
-  AC_LIBOBJ([file-has-acl])
-
   AC_ARG_ENABLE([acl],
     AS_HELP_STRING([--disable-acl], [do not support ACLs]),
     , [enable_acl=auto])
index 03a2217..9a7f277 100644 (file)
@@ -6,6 +6,7 @@ lib/acl.h
 lib/acl.c
 lib/acl-internal.h
 lib/acl_entries.c
+lib/copy-acl.c
 lib/file-has-acl.c
 m4/acl.m4
 
@@ -19,6 +20,7 @@ configure.ac:
 gl_FUNC_ACL
 
 Makefile.am:
+lib_SOURCES += acl.c copy-acl.c file-has-acl.c
 
 Include:
 "acl.h"