Please test this further.

This adds -u to our cp, which is a reimplemented GNU feature after Jim
Mock asked me if we supported -u in our cp.

Basically cp -u compares src and dest and only overwrites if dest's
mtime < src's mtime.

Only caveat which I haven't yet solved is that it still shows dirs on
cp -Ruv copy actions, whilst it doesn't copy the directory.  Solutions
welcome.

Question is, do we want to add this to our cp?

I found it handy for stuff like:

cp -Ruv mozilla mozilla-test

so that my mozilla CVS tree [not touched] only overwrites the
mozilla-test files which are older.

-- 
Jeroen Ruigrok van der Werven/Asmodai --=-- asmodai@[wxs.nl|freebsd.org]
Documentation nutter/C-rated Coder BSD: Technical excellence at its best  
http://www.freebsd.org/doc/en_US.ISO_8859-1/books/developers-handbook/
Only in sleep can one find salvation that resembles Death...
Index: src/bin/cp/cp.1
===================================================================
RCS file: /home/ncvs/FreeBSD/src/bin/cp/cp.1,v
retrieving revision 1.16.2.2
diff -u -r1.16.2.2 cp.1
--- src/bin/cp/cp.1     2001/03/05 04:32:59     1.16.2.2
+++ src/bin/cp/cp.1     2001/04/14 11:54:01
@@ -48,7 +48,10 @@
 .Op Fl H | Fl L | Fl P
 .Oc
 .Op Fl f | i
-.Op Fl pv
+.Oo
+.Fl v
+.Op Fl p | u
+.Oc
 .Ar source_file target_file
 .Nm
 .Oo
@@ -56,7 +59,10 @@
 .Op Fl H | Fl L | Fl P
 .Oc
 .Op Fl f | i
-.Op Fl pv
+.Oo
+.Fl v
+.Op Fl p | u
+.Oc
 .Ar source_file ... target_directory
 .Sh DESCRIPTION
 In the first synopsis form, the
@@ -155,6 +161,13 @@
 and either the user ID or group ID cannot be preserved, neither
 the set user ID nor set group ID bits are preserved in the copy's
 permissions.
+.It Fl u
+Cause
+.Nm
+to not copy the source file
+if the modification time is less than
+or equal to the modification time of the destination file,
+if it exists.
 .It Fl v
 Cause
 .Nm
Index: src/bin/cp/cp.c
===================================================================
RCS file: /home/ncvs/FreeBSD/src/bin/cp/cp.c,v
retrieving revision 1.24
diff -u -r1.24 cp.c
--- src/bin/cp/cp.c     1999/11/28 09:34:21     1.24
+++ src/bin/cp/cp.c     2001/04/12 16:16:37
@@ -83,7 +83,7 @@
 PATH_T to = { to.p_path, "", "" };
 
 uid_t myuid;
-int Rflag, iflag, pflag, rflag, fflag, vflag;
+int Rflag, iflag, pflag, rflag, fflag, uflag, vflag;
 int myumask;
 
 enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE };
@@ -102,7 +102,7 @@
        char *target;
 
        Hflag = Lflag = Pflag = 0;
-       while ((ch = getopt(argc, argv, "HLPRfiprv")) != -1)
+       while ((ch = getopt(argc, argv, "HLPRfipruv")) != -1)
                switch (ch) {
                case 'H':
                        Hflag = 1;
@@ -132,6 +132,11 @@
                        break;
                case 'r':
                        rflag = 1;
+                       break;
+               case 'u':
+                       uflag = 1;
+                       fflag = 0;
+                       pflag = 0;
                        break;
                case 'v':
                        vflag = 1;
Index: src/bin/cp/extern.h
===================================================================
RCS file: /home/ncvs/FreeBSD/src/bin/cp/extern.h,v
retrieving revision 1.9
diff -u -r1.9 extern.h
--- src/bin/cp/extern.h 1999/08/27 23:13:39     1.9
+++ src/bin/cp/extern.h 2001/04/12 16:07:56
@@ -42,7 +42,7 @@
 
 extern PATH_T to;
 extern uid_t myuid;
-extern int iflag, pflag, fflag, vflag, myumask;
+extern int iflag, pflag, fflag, uflag, vflag, myumask;
 
 #include <sys/cdefs.h>
 
Index: src/bin/cp/utils.c
===================================================================
RCS file: /home/ncvs/FreeBSD/src/bin/cp/utils.c,v
retrieving revision 1.27.2.1
diff -u -r1.27.2.1 utils.c
--- src/bin/cp/utils.c  2000/10/27 16:24:22     1.27.2.1
+++ src/bin/cp/utils.c  2001/04/15 19:21:27
@@ -62,7 +62,7 @@
        int dne;
 {
        static char buf[MAXBSIZE];
-       struct stat to_stat, *fs;
+       struct stat from_stat, to_stat, *fs;
        int ch, checkch, from_fd, rcount, rval, to_fd, wcount, wresid;
        char *bufp;
 #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED
@@ -105,9 +105,27 @@
                    (void)unlink(to.p_path);
                    to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT,
                                 fs->st_mode & ~(S_ISUID | S_ISGID));
-               } else 
-                   /* overwrite existing destination file name */
-                   to_fd = open(to.p_path, O_WRONLY | O_TRUNC, 0);
+               } else {
+                       if (uflag) {
+                               if (fstat(from_fd, &from_stat) == -1) {
+                                       warn("%s", entp->fts_path);
+                                       (void)close(from_fd);
+                                       return (1);
+                               } else if (stat(to.p_path, &to_stat) == -1) {
+                                       warn("%s", to.p_path);
+                                       (void)close(from_fd);
+                                       return (1);
+                               }
+
+                               if (from_stat.st_mtime <= to_stat.st_mtime) {
+                                       (void)close(from_fd);
+                                       return (1);
+                               }
+                       }
+
+                       /* overwrite existing destination file name */
+                       to_fd = open(to.p_path, O_WRONLY | O_TRUNC, 0);
+               }
        } else
                to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT,
                    fs->st_mode & ~(S_ISUID | S_ISGID));
@@ -324,7 +342,7 @@
 {
 
        (void)fprintf(stderr, "%s\n%s\n",
-"usage: cp [-R [-H | -L | -P]] [-f | -i] [-pv] src target",
-"       cp [-R [-H | -L | -P]] [-f | -i] [-pv] src1 ... srcN directory");
+"usage: cp [-R [-H | -L | -P]] [-f | -i] [-v [-p | -u]] src target",
+"       cp [-R [-H | -L | -P]] [-f | -i] [-v [-p | -u]] src1 ... srcN directory");
        exit(EX_USAGE);
 }

Reply via email to