Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 Jan 2010 14:56:13 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r203192 - stable/8/bin/mv
Message-ID:  <201001301456.o0UEuDYU024556@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trasz
Date: Sat Jan 30 14:56:13 2010
New Revision: 203192
URL: http://svn.freebsd.org/changeset/base/203192

Log:
  MFC r196841:
  
  Add NFSv4 ACL support to mv(1).

Modified:
  stable/8/bin/mv/mv.c
Directory Properties:
  stable/8/bin/mv/   (props changed)

Modified: stable/8/bin/mv/mv.c
==============================================================================
--- stable/8/bin/mv/mv.c	Sat Jan 30 14:54:12 2010	(r203191)
+++ stable/8/bin/mv/mv.c	Sat Jan 30 14:56:13 2010	(r203192)
@@ -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)
 {
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001301456.o0UEuDYU024556>