aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/lib.c7
-rw-r--r--toys/pending/dd.c46
2 files changed, 12 insertions, 41 deletions
diff --git a/lib/lib.c b/lib/lib.c
index 6e88fd25..d011af02 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -290,17 +290,18 @@ long long xstrtol(char *str, char **end, int base)
return l;
}
-// atol() with the kilo/mega/giga/tera/peta/exa extensions.
+// atol() with the kilo/mega/giga/tera/peta/exa extensions, plus word and block.
// (zetta and yotta don't fit in 64 bits.)
long long atolx(char *numstr)
{
- char *c = numstr, *suffixes="cbkmgtpe", *end;
+ char *c = numstr, *suffixes="cwbkmgtpe", *end;
long long val;
val = xstrtol(numstr, &c, 0);
if (c != numstr && *c && (end = strchr(suffixes, tolower(*c)))) {
- int shift = end-suffixes-1;
+ int shift = end-suffixes-2;
+ if (shift==-1) val *= 2;
if (!shift) val *= 512;
else if (shift>0) {
if (toupper(*++c)=='d') while (shift--) val *= 1000;
diff --git a/toys/pending/dd.c b/toys/pending/dd.c
index 0bb48494..2160e723 100644
--- a/toys/pending/dd.c
+++ b/toys/pending/dd.c
@@ -40,8 +40,7 @@ config DD
#include "toys.h"
GLOBALS(
- int show_xfer;
- int show_records;
+ int show_xfer, show_records;
unsigned long long bytes, c_count, in_full, in_part, out_full, out_part;
struct timeval start;
struct {
@@ -63,13 +62,6 @@ struct pair {
unsigned val;
};
-static struct pair suffixes[] = {
- { "c", 1 }, { "w", 2 }, { "b", 512 },
- { "kD", 1000 }, { "k", 1024 }, { "K", 1024 },
- { "MD", 1000000 }, { "M", 1048576 },
- { "GD", 1000000000 }, { "G", 1073741824 }
-};
-
static struct pair clist[] = {
{ "fsync", C_FSYNC },
{ "noerror", C_NOERROR },
@@ -77,29 +69,6 @@ static struct pair clist[] = {
{ "sync", C_SYNC },
};
-static unsigned long long strsuftoll(char *arg, int def, unsigned long long max)
-{
- unsigned long long result;
- char *p = arg;
- int i, idx = -1;
-
- while (isspace(*p)) p++;
- if (*p == '-') error_exit("invalid number '%s'", arg);
-
- errno = 0;
- result = strtoull(p, &p, 0);
- if (errno == ERANGE || result > max || result < def)
- perror_exit("invalid number '%s'", arg);
- if (*p != '\0') {
- for (i = 0; i < ARRAY_LEN(suffixes); i++)
- if (!strcmp(p, suffixes[i].name)) idx = i;
- if (idx == -1 || (max/suffixes[idx].val < result))
- error_exit("invalid number '%s'", arg);
- result *= suffixes[idx].val;
- }
- return result;
-}
-
static void status()
{
double seconds;
@@ -169,16 +138,17 @@ void dd_main()
for (args = toys.optargs; *args; args++) {
char *arg = *args;
- if (strstarteq(&arg, "bs")) bs = strsuftoll(arg, 1, LONG_MAX);
- else if (strstarteq(&arg, "ibs")) TT.in.sz = strsuftoll(arg, 1, LONG_MAX);
- else if (strstarteq(&arg, "obs")) TT.out.sz = strsuftoll(arg, 1, LONG_MAX);
- else if (strstarteq(&arg, "count")) TT.c_count = strsuftoll(arg, 0, ULLONG_MAX-1);
+ if (strstarteq(&arg, "bs")) bs = atolx_range(arg, 1, LONG_MAX);
+ else if (strstarteq(&arg, "ibs")) TT.in.sz = atolx_range(arg, 1, LONG_MAX);
+ else if (strstarteq(&arg, "obs")) TT.out.sz = atolx_range(arg, 1, LONG_MAX);
+ else if (strstarteq(&arg, "count"))
+ TT.c_count = atolx_range(arg, 0, LLONG_MAX);
else if (strstarteq(&arg, "if")) TT.in.name = arg;
else if (strstarteq(&arg, "of")) TT.out.name = arg;
else if (strstarteq(&arg, "seek"))
- TT.out.offset = strsuftoll(arg, 0, ULLONG_MAX);
+ TT.out.offset = atolx_range(arg, 0, LLONG_MAX);
else if (strstarteq(&arg, "skip"))
- TT.in.offset = strsuftoll(arg, 0, ULLONG_MAX);
+ TT.in.offset = atolx_range(arg, 0, LLONG_MAX);
else if (strstarteq(&arg, "status")) {
if (!strcmp(arg, "noxfer")) TT.show_xfer = 0;
else if (!strcmp(arg, "none")) TT.show_xfer = TT.show_records = 0;