summaryrefslogtreecommitdiffstats
path: root/commands/cp.c
diff options
context:
space:
mode:
authorsascha <sascha@nomad.localdomain>2007-10-17 11:12:57 +0200
committersascha <sascha@nomad.localdomain>2007-10-17 11:12:57 +0200
commitb36fca0cb81493c26825d4f1df1c61bebd5df942 (patch)
tree1d424e390403d160dc71a2242da9e2ee013c6dbf /commands/cp.c
parent825ad81490bfc0064ffd615847c462ca41bad8bf (diff)
downloadbarebox-b36fca0cb81493c26825d4f1df1c61bebd5df942.tar.gz
barebox-b36fca0cb81493c26825d4f1df1c61bebd5df942.tar.xz
cp command: Allow to copy multiple files
Diffstat (limited to 'commands/cp.c')
-rw-r--r--commands/cp.c85
1 files changed, 63 insertions, 22 deletions
diff --git a/commands/cp.c b/commands/cp.c
index 19fd46a4b3..ea0a91d467 100644
--- a/commands/cp.c
+++ b/commands/cp.c
@@ -27,55 +27,97 @@
#include <errno.h>
#include <malloc.h>
#include <xfuncs.h>
+#include <linux/stat.h>
+#include <libbb.h>
#define RW_BUF_SIZE (ulong)4096
-static int do_cp ( cmd_tbl_t *cmdtp, int argc, char *argv[])
+static int copy_file(const char *src, const char *dst)
{
- int r, w, ret = 1;
- int src = 0, dst = 0;
char *rw_buf = NULL;
-
- if (argc != 3) {
- u_boot_cmd_usage(cmdtp);
- return 1;
- }
+ int srcfd = 0, dstfd = 0;
+ int r, w;
+ int ret = 1;
rw_buf = xmalloc(RW_BUF_SIZE);
- src = open(argv[1], O_RDONLY);
- if (src < 0) {
- printf("could not open %s: %s\n", argv[1], errno_str());
+ srcfd = open(src, O_RDONLY);
+ if (srcfd < 0) {
+ printf("could not open %s: %s\n", src, errno_str());
goto out;
}
- dst = open(argv[2], O_WRONLY | O_CREAT);
- if ( dst < 0) {
- printf("could not open %s: %s\n", argv[2], errno_str());
+ dstfd = open(dst, O_WRONLY | O_CREAT);
+ if (dstfd < 0) {
+ printf("could not open %s: %s\n", dst, errno_str());
goto out;
}
while(1) {
- r = read(src, rw_buf, RW_BUF_SIZE);
+ r = read(srcfd, rw_buf, RW_BUF_SIZE);
if (read < 0) {
perror("read");
goto out;
}
if (!r)
break;
- w = write(dst, rw_buf, r);
+ w = write(dstfd, rw_buf, r);
if (w < 0) {
perror("write");
goto out;
}
}
+
ret = 0;
out:
free(rw_buf);
- if (src > 0)
- close(src);
- if (dst > 0)
- close(dst);
+ if (srcfd > 0)
+ close(srcfd);
+ if (dstfd > 0)
+ close(dstfd);
+
+ return ret;
+}
+
+static int do_cp ( cmd_tbl_t *cmdtp, int argc, char *argv[])
+{
+ int ret = 1;
+ struct stat statbuf;
+ int last_is_dir = 0;
+ int i;
+
+ if (argc < 3) {
+ u_boot_cmd_usage(cmdtp);
+ return 1;
+ }
+
+ if (!stat(argv[argc - 1], &statbuf)) {
+ if (S_ISDIR(statbuf.st_mode))
+ last_is_dir = 1;
+ }
+
+ if (argc > 3 && !last_is_dir) {
+ printf("cp: target `%s' is not a directory\n", argv[argc - 1]);
+ return 1;
+ }
+
+ for (i = 1; i < argc - 1; i++) {
+ if (last_is_dir) {
+ char *dst;
+ dst = concat_path_file(argv[argc - 1], argv[i]);
+ ret = copy_file(argv[i], dst);
+ if (ret)
+ goto out;
+ free(dst);
+ } else {
+ ret = copy_file(argv[i], argv[argc - 1]);
+ if (ret)
+ goto out;
+ }
+ }
+
+ ret = 0;
+out:
return ret;
}
@@ -84,8 +126,7 @@ static __maybe_unused char cmd_cp_help[] =
"cp copies file <source> to <destination>.\n"
"Currently only this form is supported and you have to specify the exact target\n"
"filename (not a target directory).\n"
-"Note: This command was previously used as memory copy. Currently there is no\n"
-"equivalent command for this. This must be fixed of course.\n";
+"This command is file based only. See memcpy for memory copy\n";
U_BOOT_CMD_START(cp)
.maxargs = CONFIG_MAXARGS,