summaryrefslogtreecommitdiffstats
path: root/bin/cp/utils.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-06-10 06:29:23 +0000
committerpeter <peter@FreeBSD.org>1998-06-10 06:29:23 +0000
commit6aad18db892b090f8c64214c52996be7a9253023 (patch)
tree37485a164b03bf86c056a732c50e18d2199a3961 /bin/cp/utils.c
parent538c54fd9e27ac35ca3365167e7978a19cce6a14 (diff)
downloadFreeBSD-src-6aad18db892b090f8c64214c52996be7a9253023.zip
FreeBSD-src-6aad18db892b090f8c64214c52996be7a9253023.tar.gz
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.
Diffstat (limited to 'bin/cp/utils.c')
-rw-r--r--bin/cp/utils.c44
1 files changed, 29 insertions, 15 deletions
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 <sys/param.h>
@@ -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);
}
OpenPOWER on IntegriCloud