From 6aad18db892b090f8c64214c52996be7a9253023 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 10 Jun 1998 06:29:23 +0000 Subject: Don't attempt to change owner/mode/flags that don't need to changed. This should calm down attempts to `cp -p' to a nfs mount or some other filesystem that doesn't accept flags or all combinations of flags. It will warn if it fails to change flags though. --- bin/cp/utils.c | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) (limited to 'bin/cp') diff --git a/bin/cp/utils.c b/bin/cp/utils.c index 3ee49f6..7e001b2 100644 --- a/bin/cp/utils.c +++ b/bin/cp/utils.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)utils.c 8.3 (Berkeley) 4/1/94"; #endif static const char rcsid[] = - "$Id: utils.c,v 1.18 1998/05/13 07:25:17 charnier Exp $"; + "$Id: utils.c,v 1.19 1998/06/09 03:38:26 imp Exp $"; #endif /* not lint */ #include @@ -263,7 +263,9 @@ setfile(fs, fd) int fd; { static struct timeval tv[2]; + struct stat ts; int rval; + int gotstat; rval = 0; fs->st_mode &= S_ISUID | S_ISGID | S_ISVTX | @@ -275,30 +277,42 @@ setfile(fs, fd) warn("utimes: %s", to.p_path); rval = 1; } + if (fd ? fstat(fd, &ts) : stat(to.p_path, &ts)) + gotstat = 0; + else { + gotstat = 1; + ts.st_mode &= S_ISUID | S_ISGID | S_ISVTX | + S_IRWXU | S_IRWXG | S_IRWXO; + } /* * Changing the ownership probably won't succeed, unless we're root * or POSIX_CHOWN_RESTRICTED is not set. Set uid/gid before setting * the mode; current BSD behavior is to remove all setuid bits on * chown. If chown fails, lose setuid/setgid bits. */ - if (fd ? fchown(fd, fs->st_uid, fs->st_gid) : - chown(to.p_path, fs->st_uid, fs->st_gid)) { - if (errno != EPERM) { + if (!gotstat || fs->st_uid != ts.st_uid || fs->st_gid != ts.st_gid) + if (fd ? fchown(fd, fs->st_uid, fs->st_gid) : + chown(to.p_path, fs->st_uid, fs->st_gid)) { + if (errno != EPERM) { + warn("chown: %s", to.p_path); + rval = 1; + } + fs->st_mode &= ~(S_ISUID | S_ISGID); + } + + if (!gotstat || fs->st_mode != ts.st_mode) + if (fd ? fchmod(fd, fs->st_mode) : chmod(to.p_path, fs->st_mode)) { warn("chown: %s", to.p_path); rval = 1; } - fs->st_mode &= ~(S_ISUID | S_ISGID); - } - if (fd ? fchmod(fd, fs->st_mode) : chmod(to.p_path, fs->st_mode)) { - warn("chown: %s", to.p_path); - rval = 1; - } - if (fd ? - fchflags(fd, fs->st_flags) : chflags(to.p_path, fs->st_flags)) { - warn("chflags: %s", to.p_path); - rval = 1; - } + if (!gotstat || fs->st_flags != ts.st_flags) + if (fd ? + fchflags(fd, fs->st_flags) : chflags(to.p_path, fs->st_flags)) { + warn("chflags: %s", to.p_path); + rval = 1; + } + return (rval); } -- cgit v1.1