Author: trasz
Date: Fri Sep  4 21:49:37 2009
New Revision: 196841
URL: http://svn.freebsd.org/changeset/base/196841

Log:
  Add NFSv4 ACL support to mv(1).
  
  Reviewed by:  rwatson

Modified:
  head/bin/mv/mv.c

Modified: head/bin/mv/mv.c
==============================================================================
--- head/bin/mv/mv.c    Fri Sep  4 21:00:45 2009        (r196840)
+++ head/bin/mv/mv.c    Fri Sep  4 21:49:37 2009        (r196841)
@@ -74,6 +74,8 @@ static int    copy(const char *, const char
 static int     do_move(const char *, const char *);
 static int     fastcopy(const char *, const char *, struct stat *);
 static void    usage(void);
+static void    preserve_fd_acls(int source_fd, int dest_fd, const char 
*source_path,
+                   const char *dest_path);
 
 int
 main(int argc, char *argv[])
@@ -260,7 +262,6 @@ fastcopy(const char *from, const char *t
        struct timeval tval[2];
        static u_int blen;
        static char *bp;
-       acl_t acl;
        mode_t oldmode;
        int nread, from_fd, to_fd;
 
@@ -311,23 +312,15 @@ err:              if (unlink(to))
                        sbp->st_mode &= ~(S_ISUID | S_ISGID);
                }
        }
+       if (fchmod(to_fd, sbp->st_mode))
+               warn("%s: set mode (was: 0%03o)", to, oldmode);
        /*
         * POSIX 1003.2c states that if _POSIX_ACL_EXTENDED is in effect
         * for dest_file, then its ACLs shall reflect the ACLs of the
         * source_file.
         */
-       if (fpathconf(to_fd, _PC_ACL_EXTENDED) == 1 &&
-           fpathconf(from_fd, _PC_ACL_EXTENDED) == 1) {
-               acl = acl_get_fd(from_fd);
-               if (acl == NULL)
-                       warn("failed to get acl entries while setting %s",
-                           from);
-               else if (acl_set_fd(to_fd, acl) < 0)
-                       warn("failed to set acl entries for %s", to);
-       }
+       preserve_fd_acls(from_fd, to_fd, from, to);
        (void)close(from_fd);
-       if (fchmod(to_fd, sbp->st_mode))
-               warn("%s: set mode (was: 0%03o)", to, oldmode);
        /*
         * XXX
         * NFS doesn't support chflags; ignore errors unless there's reason
@@ -439,6 +432,59 @@ copy(const char *from, const char *to)
 }
 
 static void
+preserve_fd_acls(int source_fd, int dest_fd, const char *source_path,
+    const char *dest_path)
+{
+       acl_t acl;
+       acl_type_t acl_type;
+       int acl_supported = 0, ret, trivial;
+
+       ret = fpathconf(source_fd, _PC_ACL_NFS4);
+       if (ret > 0 ) {
+               acl_supported = 1;
+               acl_type = ACL_TYPE_NFS4;
+       } else if (ret < 0 && errno != EINVAL) {
+               warn("fpathconf(..., _PC_ACL_NFS4) failed for %s",
+                   source_path);
+               return;
+       }
+       if (acl_supported == 0) {
+               ret = fpathconf(source_fd, _PC_ACL_EXTENDED);
+               if (ret > 0 ) {
+                       acl_supported = 1;
+                       acl_type = ACL_TYPE_ACCESS;
+               } else if (ret < 0 && errno != EINVAL) {
+                       warn("fpathconf(..., _PC_ACL_EXTENDED) failed for %s",
+                           source_path);
+                       return;
+               }
+       }
+       if (acl_supported == 0)
+               return;
+
+       acl = acl_get_fd_np(source_fd, acl_type);
+       if (acl == NULL) {
+               warn("failed to get acl entries for %s", source_path);
+               return;
+       }
+       if (acl_is_trivial_np(acl, &trivial)) {
+               warn("acl_is_trivial() failed for %s", source_path);
+               acl_free(acl);
+               return;
+       }
+       if (trivial) {
+               acl_free(acl);
+               return;
+       }
+       if (acl_set_fd_np(dest_fd, acl, acl_type) < 0) {
+               warn("failed to set acl entries for %s", dest_path);
+               acl_free(acl);
+               return;
+       }
+       acl_free(acl);
+}
+
+static void
 usage(void)
 {
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to