Hi,

A little patch to enable --parents in cp, if the new cp long options
config is turned on.

Should you choose it, it seems to add ~150 bytes

function                                             old     new   delta
cp_main                                              273     407    +134
cp_longopts                                            -      11     +11
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/0 up/down: 145/0)             Total: 145 bytes
  text     data     bss     dec     hex filename
849561     4358    9736  863655   d2da7 busybox_old
849766     4366    9728  863860   d2e74 busybox_unstripped

Thanks,

-i

diff --git a/coreutils/Config.in b/coreutils/Config.in
index cacfb96..3cfcdeb 100644
--- a/coreutils/Config.in
+++ b/coreutils/Config.in
@@ -78,6 +78,15 @@ config CP
        help
          cp is used to copy files and directories.

+config FEATURE_CP_LONG_OPTIONS
+       bool "Enable selected long options for cp"
+       default n
+       depends on CP
+       help
+         Enable selected long options for cp.  Currently
+        supports:
+               --parents
+
config CUT
        bool "cut"
        default n
diff --git a/coreutils/cp.c b/coreutils/cp.c
index 71a2939..510dc0f 100644
--- a/coreutils/cp.c
+++ b/coreutils/cp.c
@@ -20,6 +20,12 @@

/* This is a NOEXEC applet. Be very careful! */

+#ifdef CONFIG_FEATURE_CP_LONG_OPTIONS
+static const char cp_longopts[] ALIGN1 =
+  "parents\0" No_argument "\xff";
+
+const char *applet_long_options = cp_longopts;
+#endif

int cp_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int cp_main(int argc, char **argv)
@@ -37,6 +43,10 @@ int cp_main(int argc, char **argv)
                OPT_r = 1 << (sizeof(FILEUTILS_CP_OPTSTR)),
                OPT_P = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+1),
                OPT_H = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+2),
+               OPT_v = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3),
+#ifdef CONFIG_FEATURE_CP_LONG_OPTIONS
+               OPT_parents = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+4),
+#endif
        };

        // Need at least two arguments
@@ -62,8 +72,9 @@ int cp_main(int argc, char **argv)
         * -d   same as --no-dereference --preserve=links
         * -p   same as --preserve=mode,ownership,timestamps
         * -c   same as --preserve=context
+        * --parents
+        *      use full source file name under DIRECTORY
         * NOT SUPPORTED IN BBOX:
-        * long options are not supported (even those above).
         * --backup[=CONTROL]
         *      make a backup of each existing destination file
         * -b   like --backup but does not accept an argument
@@ -73,8 +84,6 @@ int cp_main(int argc, char **argv)
         *      preserve attributes (default: mode,ownership,timestamps),
         *      if possible additional attributes: security context,links,all
         * --no-preserve=ATTR_LIST
-        * --parents
-        *      use full source file name under DIRECTORY
         * --remove-destination
         *      remove  each existing destination file before attempting to open
         * --sparse=WHEN
@@ -108,7 +117,6 @@ int cp_main(int argc, char **argv)
         * just ignore it too for fun. TODO.
        if (flags & OPT_H) ... // deref command-line params only
        */
-
#if ENABLE_SELINUX
        if (flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT) {
                selinux_or_die();
@@ -126,6 +134,14 @@ int cp_main(int argc, char **argv)
                if (d_flags < 0)
                        return EXIT_FAILURE;

+#ifdef CONFIG_FEATURE_CP_LONG_OPTIONS
+               if (flags & OPT_parents) {
+                       if (!(d_flags & 2)) {
+                               bb_error_msg_and_die("With --parents, the 
destination must be a directory");
+                       }
+               }
+#endif
+
                /* ...if neither is a directory or...  */
                if ( !((s_flags | d_flags) & 2) ||
                        /* ...recursing, the 1st is a directory, and the 2nd 
doesn't exist... */
@@ -138,6 +154,20 @@ int cp_main(int argc, char **argv)
        }

        while (1) {
+#ifdef CONFIG_FEATURE_CP_LONG_OPTIONS
+               if (flags & OPT_parents) {
+                       char *dest_dup;
+                       char *dest_dir;
+                       dest = concat_path_file(last, *argv);
+                       dest_dup = xstrdup(dest);
+                       dest_dir = dirname(dest_dup);
+                       if (bb_make_directory(dest_dir, (mode_t)(-1), 
FILEUTILS_RECUR)) {
+                               exit(EXIT_FAILURE);
+                       }
+                       free(dest_dup);
+                       goto DO_COPY;
+               }
+#endif
                dest = concat_path_file(last, 
bb_get_last_path_component_strip(*argv));
 DO_COPY:
                if (copy_file(*argv, dest, flags) < 0) {
diff --git a/testsuite/cp/cp-parents b/testsuite/cp/cp-parents
new file mode 100644
index 0000000..b25f1e8
--- /dev/null
+++ b/testsuite/cp/cp-parents
@@ -0,0 +1,5 @@
+mkdir -p foo/bar/baz
+touch foo/bar/baz/file +mkdir dir
+busybox cp --parents foo/bar/baz/file dir
+test -f dir/foo/bar/baz/file
\ No newline at end of file
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to