diff options
author | sascha <sascha@nomad.localdomain> | 2007-10-17 11:12:57 +0200 |
---|---|---|
committer | sascha <sascha@nomad.localdomain> | 2007-10-17 11:12:57 +0200 |
commit | b36fca0cb81493c26825d4f1df1c61bebd5df942 (patch) | |
tree | 1d424e390403d160dc71a2242da9e2ee013c6dbf /commands | |
parent | 825ad81490bfc0064ffd615847c462ca41bad8bf (diff) | |
download | barebox-b36fca0cb81493c26825d4f1df1c61bebd5df942.tar.gz barebox-b36fca0cb81493c26825d4f1df1c61bebd5df942.tar.xz |
cp command: Allow to copy multiple files
Diffstat (limited to 'commands')
-rw-r--r-- | commands/cp.c | 85 |
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, |