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>