cp command: Allow to copy multiple files
This commit is contained in:
parent
825ad81490
commit
b36fca0cb8
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue