[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    [PATCH] (v2) cp: add -u/--update and --remove-destination
From:       wdlkmpx <wdlkmpx () gmail ! com>
Date:       2016-05-22 14:26:42
Message-ID: 20160522142642.6278-1-wdlkmpx () gmail ! com
[Download RAW message or body]

This matches the behavior of GNU coreutils cp
when ENABLE_FEATURE_NON_POSIX_CP is not set
and ENABLE_FEATURE_CP_LONG_OPTIONS is defined

The verbose option now shows the same message
when --remove-destination is used

It works the same in most combinations.
Needs more testing to detect issues...
---
 coreutils/cp.c    | 15 ++++++++++++---
 include/libbb.h   |  2 ++
 libbb/copy_file.c | 21 +++++++++++++++++++++
 3 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/coreutils/cp.c b/coreutils/cp.c
index 247ed0f..b42c3b2 100644
--- a/coreutils/cp.c
+++ b/coreutils/cp.c
@@ -31,6 +31,7 @@
 //usage:     "\n	-f	Overwrite"
 //usage:     "\n	-i	Prompt before overwrite"
 //usage:     "\n	-l,-s	Create (sym)links"
+//usage:     "\n	-u	Copy if SOURCE file is newer than the destination"
 
 #include "libbb.h"
 #include "libcoreutils/coreutils.h"
@@ -53,8 +54,10 @@ int cp_main(int argc, char **argv)
 		OPT_r = 1 << (sizeof(FILEUTILS_CP_OPTSTR)),
 		OPT_P = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+1),
 		OPT_v = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+2),
+		OPT_u = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3),
 #if ENABLE_FEATURE_CP_LONG_OPTIONS
-		OPT_parents = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3),
+		OPT_parents = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+4),
+		OPT_rmdest  = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+5),
 #endif
 	};
 
@@ -76,10 +79,12 @@ int cp_main(int argc, char **argv)
 		"recursive\0"      No_argument "R"
 		"symbolic-link\0"  No_argument "s"
 		"verbose\0"        No_argument "v"
-		"parents\0"        No_argument "\xff"
+		"update\0"         No_argument "u"
+		"parents\0"        No_argument "\xfe"
+		"remove-destination\0" No_argument "\xff"
 		;
 #endif
-	flags = getopt32(argv, FILEUTILS_CP_OPTSTR "arPv");
+	flags = getopt32(argv, FILEUTILS_CP_OPTSTR "arPvu");
 	/* Options of cp from GNU coreutils 6.10:
 	 * -a, --archive
 	 * -f, --force
@@ -161,6 +166,10 @@ int cp_main(int argc, char **argv)
 				bb_error_msg_and_die("with --parents, the destination must be a directory");
 			}
 		}
+		if (flags & OPT_rmdest) {
+			flags |= FILEUTILS_FORCE;
+			flags |= FILEUTILS_RMDEST;
+		}
 #endif
 
 		/* ...if neither is a directory...  */
diff --git a/include/libbb.h b/include/libbb.h
index fd40ef7..ece5f32 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -368,6 +368,8 @@ enum {	/* DO NOT CHANGE THESE VALUES!  cp.c, mv.c, install.c depend on them. */
 	FILEUTILS_IGNORE_CHMOD_ERR = 1 << 11,
 	/* -v */
 	FILEUTILS_VERBOSE         = (1 << 12) * ENABLE_FEATURE_VERBOSE,
+	FILEUTILS_UPDATE          = 1 << 13, /* -u */
+	FILEUTILS_RMDEST          = 1 << 14, /* cp --remove-destination */
 };
 #define FILEUTILS_CP_OPTSTR "pdRfilsLH" IF_SELINUX("c")
 extern int remove_file(const char *path, int flags) FAST_FUNC;
diff --git a/libbb/copy_file.c b/libbb/copy_file.c
index a4be875..23bcf2e 100644
--- a/libbb/copy_file.c
+++ b/libbb/copy_file.c
@@ -64,6 +64,11 @@ static int ask_and_unlink(const char *dest, int flags)
 		bb_perror_msg("can't create '%s'", dest);
 		return -1; /* error */
 	}
+#if ENABLE_FEATURE_CP_LONG_OPTIONS
+	if (flags & FILEUTILS_RMDEST)
+		if (flags & FILEUTILS_VERBOSE)
+			printf("removed '%s'\n", dest);
+#endif
 	return 1; /* ok (to try again) */
 }
 
@@ -210,6 +215,22 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags)
 		goto preserve_mode_ugid_time;
 	}
 
+	if (dest_exists) {
+		if (flags & FILEUTILS_UPDATE) {
+			if (source_stat.st_mtime <= dest_stat.st_mtime) {
+				return 0; /* source file must be newer */
+			}
+		}
+#if ENABLE_FEATURE_CP_LONG_OPTIONS
+		if (flags & FILEUTILS_RMDEST) {
+			ovr = ask_and_unlink(dest, flags);
+			if (ovr <= 0)
+				return ovr;
+			dest_exists = 0;
+		}
+#endif
+	}
+
 	if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) {
 		int (*lf)(const char *oldpath, const char *newpath);
  make_links:
-- 
2.8.3

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic