summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAndrey Smirnov <andrew.smirnov@gmail.com>2019-05-27 22:49:00 -0700
committerSascha Hauer <s.hauer@pengutronix.de>2019-05-28 10:28:15 +0200
commitddf4cca3397910ed8a342c1f6443637f20bae718 (patch)
tree036da05982e99d869ced7faa2396e08f21505abd /lib
parentfaf2ad1dc5a1a3fb131559c26675cecdd20b74a8 (diff)
downloadbarebox-ddf4cca3397910ed8a342c1f6443637f20bae718.tar.gz
barebox-ddf4cca3397910ed8a342c1f6443637f20bae718.tar.xz
commands: Introduce memcpy_parse_options()
Both memcpy and memcmp have identical options, so in order to share code between them, introduce memcpy_parse_options() and change both tools to use it. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'lib')
-rw-r--r--lib/misc.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/lib/misc.c b/lib/misc.c
index cd420a57d8..18153bb4dc 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -24,6 +24,7 @@
#include <string.h>
#include <linux/ctype.h>
#include <getopt.h>
+#include <libfile.h>
/*
* Like simple_strtoull() but handles an optional G, M, K or k
@@ -171,3 +172,51 @@ int mem_parse_options(int argc, char *argv[], char *optstr, int *mode,
return 0;
}
+int memcpy_parse_options(int argc, char *argv[], int *sourcefd,
+ int *destfd, loff_t *count)
+{
+ loff_t dest, src;
+ int mode = 0;
+ char *sourcefile = NULL;
+ char *destfile = NULL;
+ struct stat statbuf;
+
+ if (mem_parse_options(argc, argv, "bwlqs:d:", &mode, &sourcefile,
+ &destfile, NULL) < 0)
+ return -EINVAL;
+
+ if (optind + 2 > argc)
+ return -EINVAL;
+
+ src = strtoull_suffix(argv[optind], NULL, 0);
+ dest = strtoull_suffix(argv[optind + 1], NULL, 0);
+
+ if (optind + 2 == argc) {
+ if (!sourcefile) {
+ printf("source and count not given\n");
+ return -EINVAL;
+ }
+ if (stat(sourcefile, &statbuf)) {
+ perror("stat");
+ return -1;
+ }
+ *count = statbuf.st_size - src;
+ } else {
+ *count = strtoull_suffix(argv[optind + 2], NULL, 0);
+ }
+
+ sourcefile = sourcefile ?: "/dev/mem";
+ destfile = destfile ?: "/dev/mem";
+
+ *sourcefd = open_and_lseek(sourcefile, mode | O_RDONLY, src);
+ if (*sourcefd < 0)
+ return -1;
+
+ *destfd = open_and_lseek(destfile, O_WRONLY | O_CREAT | mode, dest);
+ if (*destfd < 0) {
+ close(*sourcefd);
+ return -1;
+ }
+
+ return 0;
+}