Add support saving both user/group permission on symlinks(-p)
authorDavid Rhodus <drhodus@dragonflybsd.org>
Tue, 14 Sep 2004 00:42:21 +0000 (00:42 +0000)
committerDavid Rhodus <drhodus@dragonflybsd.org>
Tue, 14 Sep 2004 00:42:21 +0000 (00:42 +0000)
Merged from fbsd.

bin/cp/utils.c

index a91d1e9..1af3da7 100644 (file)
@@ -32,7 +32,7 @@
  *
  * @(#)utils.c 8.3 (Berkeley) 4/1/94
  * $FreeBSD: src/bin/cp/utils.c,v 1.27.2.6 2002/08/10 13:20:19 johan Exp $
- * $DragonFly: src/bin/cp/utils.c,v 1.5 2004/08/25 01:23:15 dillon Exp $
+ * $DragonFly: src/bin/cp/utils.c,v 1.6 2004/09/14 00:42:21 drhodus Exp $
  */
 
 #include <sys/param.h>
@@ -207,7 +207,7 @@ copy_link(FTSENT *p, int exists)
                warn("symlink: %s", linkname);
                return (1);
        }
-       return (0);
+       return (pflag ? setfile(p->fts_statp, -1) : 0);
 }
 
 int
@@ -221,7 +221,7 @@ copy_fifo(struct stat *from_stat, int exists)
                warn("mkfifo: %s", to.p_path);
                return (1);
        }
-       return (pflag ? setfile(from_stat, 0) : 0);
+       return (pflag ? setfile(from_stat, -1) : 0);
 }
 
 int
@@ -235,7 +235,7 @@ copy_special(struct stat *from_stat, int exists)
                warn("mknod: %s", to.p_path);
                return (1);
        }
-       return (pflag ? setfile(from_stat, 0) : 0);
+       return (pflag ? setfile(from_stat, -1) : 0);
 }
 
 int
@@ -243,17 +243,18 @@ setfile(struct stat *fs, int fd)
 {
        static struct timeval tv[2];
        struct stat ts;
-       int rval;
-       int gotstat;
+       int rval, gotstat, islink, fdval;
 
        rval = 0;
+       fdval = fd != -1;
+       islink = !fdval && S_ISLNK(fs->st_mode);
        fs->st_mode &= S_ISUID | S_ISGID | S_ISVTX |
                       S_IRWXU | S_IRWXG | S_IRWXO;
 
        TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec);
        TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec);
-       if (utimes(to.p_path, tv)) {
-               warn("utimes: %s", to.p_path);
+       if (islink ? lutimes(to.p_path, tv) : utimes(to.p_path, tv)) {
+               warn("%sutimes: %s", islink ? "l" : "", to.p_path);
                rval = 1;
        }
        if (fd ? fstat(fd, &ts) : stat(to.p_path, &ts))
@@ -280,14 +281,18 @@ setfile(struct stat *fs, int fd)
                }
 
        if (!gotstat || fs->st_mode != ts.st_mode)
-               if (fd ? fchmod(fd, fs->st_mode) : chmod(to.p_path, fs->st_mode)) {
+               if (fdval ? fchmod(fd, fs->st_mode) :
+                   (islink ? lchmod(to.p_path, fs->st_mode) :
+                   chmod(to.p_path, fs->st_mode))) {
                        warn("chmod: %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)) {
+               if (fdval ?
+                   fchflags(fd, fs->st_flags) :
+                   (islink ? (errno = ENOSYS) :
+                   chflags(to.p_path, fs->st_flags))) {
                        warn("chflags: %s", to.p_path);
                        rval = 1;
                }