This is my first patch just after reviewing the code for a few
minutes,  so bear with me. It just works for me in all my tests, so I
hope it gets reviewed

On 5/21/16, wdlkmpx <[email protected]> wrote:
> This matches the behavior of GNU coreutils
> ---
>  coreutils/cp.c    | 14 +++++++++++---
>  include/libbb.h   |  2 ++
>  libbb/copy_file.c | 22 ++++++++++++++++++++++
>  3 files changed, 35 insertions(+), 3 deletions(-)
>
> diff --git a/coreutils/cp.c b/coreutils/cp.c
> index 247ed0f..cd947be 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,9 @@ 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_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..44031f2 100644
> --- a/libbb/copy_file.c
> +++ b/libbb/copy_file.c
> @@ -208,6 +208,28 @@ int FAST_FUNC copy_file(const char *source, const char
> *dest, int flags)
>                       /* retval = -1; - WRONG! copy *WAS* made */
>               }
>               goto preserve_mode_ugid_time;
> +     } else {
> +             /* Not a directory */
> +             if (dest_exists) {
> +                     if (flags & FILEUTILS_UPDATE) {
> +                             if (source_stat.st_mtime <= dest_stat.st_mtime) 
> {
> +                                     return 0; /* source file must be newer 
> */
> +                             }
> +                     }
> +                     if (flags & FILEUTILS_RMDEST) {
> +                             if (unlink(dest) < 0) {
> +                                     if (flags & FILEUTILS_VERBOSE) {
> +                                             printf("can't remove '%s'\n", 
> dest);
> +                                     }
> +                                     return -1;
> +                             } else {
> +                                     if (flags & FILEUTILS_VERBOSE) {
> +                                             printf("removed '%s'\n", dest);
> +                                     }
> +                                     dest_exists = 0;
> +                             }
> +                     }
> +             }
>       }
>
>       if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) {
> --
> 2.8.3
>
>
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to