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