bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

acl: split off copy-file.c


From: Bruno Haible
Subject: acl: split off copy-file.c
Date: Thu, 22 May 2008 20:02:20 +0200
User-agent: KMail/1.5.4

Hi Jim (and Paul, if you are still listening),

I'm starting to fix the 6 portability problems of the 'acl' module.

First of all, since there will be more ifdefs
  - to distinguish some of the Linux, FreeBSD, MacOS X, IRIX, Tru64, Cygwin
    platforms which have a POSIX like API,
  - to add support for 4 other APIs (Solaris, HP-UX, AIX, older AIX),

I propose to move copy_acl() to a file of its own. Simply to make the
basic acl.c easier to read and understand.

OK to commit?


2008-05-22  Bruno Haible  <address@hidden>

        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.

*** lib/acl.c.orig      2008-05-22 20:00:42.000000000 +0200
--- lib/acl.c   2008-05-22 19:44:23.000000000 +0200
***************
*** 1,6 ****
  /* acl.c - access control lists
  
!    Copyright (C) 2002, 2003, 2005, 2006, 2007 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
--- 1,6 ----
  /* acl.c - access control lists
  
!    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,185 ****
      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
--- 37,42 ----
*** m4/acl.m4.orig      2008-05-22 20:00:42.000000000 +0200
--- m4/acl.m4   2008-05-22 19:46:40.000000000 +0200
***************
*** 1,5 ****
  # acl.m4 - check for access control list (ACL) primitives
! # serial 2
  
  # Copyright (C) 2002, 2004-2008 Free Software Foundation, Inc.
  # This file is free software; the Free Software Foundation
--- 1,5 ----
  # acl.m4 - check for access control list (ACL) primitives
! # serial 3
  
  # Copyright (C) 2002, 2004-2008 Free Software Foundation, Inc.
  # This file is free software; the Free Software Foundation
***************
*** 10,18 ****
  
  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])
--- 10,15 ----
*** modules/acl.orig    2008-05-22 20:00:42.000000000 +0200
--- modules/acl 2008-05-22 19:47:07.000000000 +0200
***************
*** 6,11 ****
--- 6,12 ----
  lib/acl.c
  lib/acl-internal.h
  lib/acl_entries.c
+ lib/copy-acl.c
  lib/file-has-acl.c
  m4/acl.m4
  
***************
*** 19,24 ****
--- 20,26 ----
  gl_FUNC_ACL
  
  Makefile.am:
+ lib_SOURCES += acl.c copy-acl.c file-has-acl.c
  
  Include:
  "acl.h"
*** /dev/null   2003-09-23 19:59:22.000000000 +0200
--- lib/copy-acl.c      2008-05-22 19:45:14.000000000 +0200
***************
*** 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
+ }





reply via email to

[Prev in Thread] Current Thread [Next in Thread]