summaryrefslogtreecommitdiffstats
path: root/bin/dd
diff options
context:
space:
mode:
Diffstat (limited to 'bin/dd')
-rw-r--r--bin/dd/args.c99
-rw-r--r--bin/dd/conv.c15
-rw-r--r--bin/dd/dd.18
-rw-r--r--bin/dd/dd.c30
-rw-r--r--bin/dd/dd.h30
-rw-r--r--bin/dd/extern.h6
-rw-r--r--bin/dd/position.c3
7 files changed, 108 insertions, 83 deletions
diff --git a/bin/dd/args.c b/bin/dd/args.c
index b6191ab..cbdf755 100644
--- a/bin/dd/args.c
+++ b/bin/dd/args.c
@@ -67,7 +67,7 @@ static void f_obs __P((char *));
static void f_of __P((char *));
static void f_seek __P((char *));
static void f_skip __P((char *));
-static int64_t get_bsz __P((char *));
+static quad_t get_bsz __P((char *));
static struct arg {
char *name;
@@ -103,20 +103,20 @@ jcl(argv)
while ((oper = *++argv) != NULL) {
if ((oper = strdup(oper)) == NULL)
- errx(1, "unable to allocate space for the argument "
- "\"%s\"", *argv);
+ errx(1, "unable to allocate space for the argument \"%s\"", *argv);
if ((arg = strchr(oper, '=')) == NULL)
errx(1, "unknown operand %s", oper);
*arg++ = '\0';
if (!*arg)
errx(1, "no value specified for %s", oper);
tmp.name = oper;
- if (!(ap = bsearch(&tmp, args, sizeof(args)/sizeof(struct arg),
- sizeof(struct arg), c_arg)))
+ if (!(ap = (struct arg *)bsearch(&tmp, args,
+ sizeof(args)/sizeof(struct arg), sizeof(struct arg),
+ c_arg)))
errx(1, "unknown operand %s", tmp.name);
if (ddflags & ap->noset)
- errx(1, "%s: illegal argument combination or "
- "already set", tmp.name);
+ errx(1, "%s: illegal argument combination or already set",
+ tmp.name);
ddflags |= ap->set;
ap->f(arg);
}
@@ -158,13 +158,8 @@ jcl(argv)
}
} else
errx(1, "cbs meaningless if not doing record operations");
- if (cbsz == 0)
- errx(1, "cbs cannot be zero");
} else
cfunc = def;
-
- if (in.dbsz == 0 || out.dbsz == 0)
- errx(1, "buffer sizes cannot be zero");
}
static int
@@ -179,16 +174,23 @@ static void
f_bs(arg)
char *arg;
{
+ quad_t res = get_bsz(arg);
- in.dbsz = out.dbsz = (size_t)get_bsz(arg);
+ if (res < 1 || res > INT_MAX)
+ errx(1, "bs must be between 1 and %d", INT_MAX);
+ in.dbsz = out.dbsz = (int)res;
}
static void
f_cbs(arg)
char *arg;
{
+ quad_t res = get_bsz(arg);
+
+ if (res < 1 || res > INT_MAX)
+ errx(1, "cbs must be between 1 and %d", INT_MAX);
- cbsz = (size_t)get_bsz(arg);
+ cbsz = (int)res;
}
static void
@@ -196,17 +198,20 @@ f_count(arg)
char *arg;
{
- cpy_cnt = (size_t)get_bsz(arg);
+ cpy_cnt = get_bsz(arg);
if (!cpy_cnt)
terminate(0);
+ if (cpy_cnt < 0)
+ errx(1, "count cannot be negative");
}
static void
f_files(arg)
char *arg;
{
+ quad_t res = get_bsz(arg);
- files_cnt = (int)get_bsz(arg);
+ files_cnt = res;
}
static void
@@ -214,8 +219,13 @@ f_ibs(arg)
char *arg;
{
- if (!(ddflags & C_BS))
- in.dbsz = (size_t)get_bsz(arg);
+ if (!(ddflags & C_BS)) {
+ quad_t res = get_bsz(arg);
+
+ if (res < 1 || res > INT_MAX)
+ errx(1, "ibs must be between 1 and %d", INT_MAX);
+ in.dbsz = (int)res;
+ }
}
static void
@@ -231,8 +241,13 @@ f_obs(arg)
char *arg;
{
- if (!(ddflags & C_BS))
- out.dbsz = (size_t)get_bsz(arg);
+ if (!(ddflags & C_BS)) {
+ quad_t res = get_bsz(arg);
+
+ if (res < 1 || res > INT_MAX)
+ errx(1, "ibs must be between 1 and %d", INT_MAX);
+ out.dbsz = (int)res;
+ }
}
static void
@@ -290,9 +305,9 @@ f_conv(arg)
while (arg != NULL) {
tmp.name = strsep(&arg, ",");
- if (!(cp = bsearch(&tmp, clist, sizeof(clist) /
- sizeof(struct conv), sizeof(struct conv),
- c_conv)))
+ if (!(cp = (struct conv *)bsearch(&tmp, clist,
+ sizeof(clist)/sizeof(struct conv), sizeof(struct conv),
+ c_conv)))
errx(1, "unknown conversion %s", tmp.name);
if (ddflags & cp->noset)
errx(1, "%s: illegal conversion combination", tmp.name);
@@ -311,25 +326,34 @@ c_conv(a, b)
}
/*
- * Convert an expression of the following forms to a 64-bit integer.
+ * Convert an expression of the following forms to a quad_t.
* 1) A positive decimal number.
- * 2) A positive decimal number followed by a b (mult by 512).
- * 3) A positive decimal number followed by a k (mult by 1024).
- * 4) A positive decimal number followed by a m (mult by 512).
- * 5) A positive decimal number followed by a w (mult by sizeof int)
- * 6) Two or more positive decimal numbers (with/without k,b or w).
+ * 2) A positive decimal number followed by a b (mult by 512.)
+ * 3) A positive decimal number followed by a k (mult by 1 << 10.)
+ * 4) A positive decimal number followed by a m (mult by 1 << 20.)
+ * 5) A positive decimal number followed by a g (mult by 1 << 30.)
+ * 5) A positive decimal number followed by a w (mult by sizeof int.)
+ * 6) Two or more positive decimal numbers (with/without [bkmgw])
* separated by x (also * for backwards compatibility), specifying
* the product of the indicated values.
*/
-static int64_t
+static quad_t
get_bsz(val)
char *val;
{
- int64_t num, t;
+ quad_t num, t;
char *expr;
+ errno = 0;
num = strtoq(val, &expr, 0);
- if (num == QUAD_MAX || num < 0 || expr == val)
+ if (num == QUAD_MAX && errno) /* Overflow. */
+ err(1, "%s", oper);
+ /*
+ * XXX (BFF) - The checks in individual f_* functions are
+ * now redundant, but this is only temporary.
+ */
+
+ if (expr == val || num < 0) /* No digits or negative. */
errx(1, "%s: illegal numeric value", oper);
switch(*expr) {
@@ -342,14 +366,21 @@ get_bsz(val)
break;
case 'k':
t = num;
- num *= 1024;
+ num *= 1 << 10;
if (t > num)
goto erange;
++expr;
break;
case 'm':
t = num;
- num *= 1048576;
+ num *= 1 << 20;
+ if (t > num)
+ goto erange;
+ ++expr;
+ break;
+ case 'g':
+ t = num;
+ num *= 1 << 30;
if (t > num)
goto erange;
++expr;
diff --git a/bin/dd/conv.c b/bin/dd/conv.c
index d0cfe15..060b175 100644
--- a/bin/dd/conv.c
+++ b/bin/dd/conv.c
@@ -60,7 +60,7 @@ static const char rcsid[] =
void
def()
{
- size_t cnt;
+ int cnt;
u_char *inp, *t;
if ((t = ctab) != NULL)
@@ -104,8 +104,7 @@ void
block()
{
static int intrunc;
- int ch;
- size_t cnt, maxlen;
+ int ch, cnt, maxlen;
u_char *inp, *outp, *t;
/*
@@ -137,11 +136,11 @@ block()
maxlen = MIN(cbsz, in.dbcnt);
if ((t = ctab) != NULL)
for (cnt = 0; cnt < maxlen && (ch = *inp++) != '\n';
- ++cnt)
+ ++cnt)
*outp++ = t[ch];
else
for (cnt = 0; cnt < maxlen && (ch = *inp++) != '\n';
- ++cnt)
+ ++cnt)
*outp++ = ch;
/*
* Check for short record without a newline. Reassemble the
@@ -200,7 +199,7 @@ block_close()
++st.trunc;
memmove(out.dbp, in.dbp - in.dbcnt, in.dbcnt);
(void)memset(out.dbp + in.dbcnt, ctab ? ctab[' '] : ' ',
- cbsz - in.dbcnt);
+ cbsz - in.dbcnt);
out.dbcnt += cbsz;
}
}
@@ -215,7 +214,7 @@ block_close()
void
unblock()
{
- size_t cnt;
+ int cnt;
u_char *inp, *t;
/* Translation and case conversion. */
@@ -248,7 +247,7 @@ unblock()
void
unblock_close()
{
- size_t cnt;
+ int cnt;
u_char *t;
if (in.dbcnt) {
diff --git a/bin/dd/dd.1 b/bin/dd/dd.1
index e4be5ac..4fef22b 100644
--- a/bin/dd/dd.1
+++ b/bin/dd/dd.1
@@ -33,7 +33,7 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
-.\" $Id: dd.1,v 1.8 1998/11/29 13:54:20 bde Exp $
+.\" $Id: dd.1,v 1.9 1999/05/08 10:20:07 kris Exp $
.\"
.Dd January 13, 1994
.Dt DD 1
@@ -283,9 +283,9 @@ appended.
.El
.Pp
Where sizes are specified, a decimal number of bytes is expected.
-If the number ends with a ``b'', ``k'', ``m'' or ``w'', the number
-is multiplied by 512, 1024 (1K), 1048576 (1M) or the number of bytes
-in an integer, respectively.
+If the number ends with a ``b'', ``k'', ``m'', ``g'', or ``w'', the
+number is multiplied by 512, 1024 (1K), 1048576 (1M), 1073741824 (1G)
+or the number of bytes in an integer, respectively.
Two or more numbers may be separated by an ``x'' to indicate a product.
.Pp
When finished,
diff --git a/bin/dd/dd.c b/bin/dd/dd.c
index 5ffb7ec..b817b00 100644
--- a/bin/dd/dd.c
+++ b/bin/dd/dd.c
@@ -74,11 +74,11 @@ static void setup __P((void));
IO in, out; /* input/output state */
STAT st; /* statistics */
void (*cfunc) __P((void)); /* conversion function */
-size_t cpy_cnt; /* # of blocks to copy */
-size_t pending = 0; /* pending seek if sparse */
+quad_t cpy_cnt; /* # of blocks to copy */
+off_t pending = 0; /* pending seek if sparse */
u_int ddflags; /* conversion options */
-size_t cbsz; /* conversion block size */
-int files_cnt = 1; /* # of files to copy */
+int cbsz; /* conversion block size */
+quad_t files_cnt = 1; /* # of files to copy */
u_char *ctab; /* conversion table */
int
@@ -112,7 +112,7 @@ setup()
in.name = "stdin";
in.fd = STDIN_FILENO;
} else {
- in.fd = open(in.name, O_RDONLY);
+ in.fd = open(in.name, O_RDONLY, 0);
if (in.fd == -1)
err(1, "%s", in.name);
}
@@ -153,9 +153,8 @@ setup()
if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL)
err(1, NULL);
out.db = in.db;
- } else if ((in.db =
- malloc(MAX(in.dbsz, cbsz) + cbsz)) == NULL ||
- (out.db = malloc(out.dbsz + cbsz)) == NULL)
+ } else if ((in.db = malloc((u_int)(MAX(in.dbsz, cbsz) + cbsz))) == NULL
+ || (out.db = malloc((u_int)(out.dbsz + cbsz))) == NULL)
err(1, NULL);
in.dbp = in.db;
out.dbp = out.db;
@@ -359,8 +358,7 @@ dd_out(force)
int force;
{
static int warned;
- int sparse;
- size_t cnt, n, i;
+ int cnt, n, i, sparse;
ssize_t nw;
u_char *outp;
@@ -399,10 +397,10 @@ dd_out(force)
if (pending != 0) {
if (force)
pending--;
- if (lseek(out.fd, (off_t)pending,
- SEEK_CUR) == -1)
- err(2, "%s: seek error creating"
- " sparse file", out.name);
+ if (lseek(out.fd, pending, SEEK_CUR) ==
+ -1)
+ err(2, "%s: seek error creating sparse file",
+ out.name);
if (force)
write(out.fd, outp, 1);
pending = 0;
@@ -435,10 +433,10 @@ dd_out(force)
if (out.flags & ISCHR && !warned) {
warned = 1;
warnx("%s: short write on character device",
- out.name);
+ out.name);
}
if (out.flags & ISTAPE)
- errx(1, "%s: short write on tape device", out.name);
+ errx(1, "%s: short write on tape device", out.name);
}
if ((out.dbcnt -= n) < out.dbsz)
break;
diff --git a/bin/dd/dd.h b/bin/dd/dd.h
index 6269621..bc3fd60 100644
--- a/bin/dd/dd.h
+++ b/bin/dd/dd.h
@@ -38,15 +38,13 @@
* $Id: dd.h,v 1.8 1998/02/11 02:23:31 asami Exp $
*/
-#define uint64 u_int64_t
-
/* Input/output stream state. */
typedef struct {
u_char *db; /* buffer address */
u_char *dbp; /* current buffer I/O address */
- size_t dbcnt, /* current buffer byte count */
- dbrcnt, /* last read byte count */
- dbsz; /* buffer size */
+ int dbcnt; /* current buffer byte count */
+ int dbrcnt; /* last read byte count */
+ int dbsz; /* buffer size */
#define ISCHR 0x01 /* character device (warn on short) */
#define ISPIPE 0x02 /* pipe (not truncatable) */
@@ -58,20 +56,20 @@ typedef struct {
int fd; /* file descriptor */
off_t offset; /* # of blocks to skip */
- uint64 f_stats, /* # of full blocks processed */
- p_stats, /* # of partial blocks processed */
- s_stats, /* # of odd swab blocks */
- t_stats; /* # of truncations */
+ quad_t f_stats; /* # of full blocks processed */
+ quad_t p_stats; /* # of partial blocks processed */
+ quad_t s_stats; /* # of odd swab blocks */
+ quad_t t_stats; /* # of truncations */
} IO;
typedef struct {
- uint64 in_full, /* # of full input blocks */
- in_part, /* # of partial input blocks */
- out_full, /* # of full output blocks */
- out_part, /* # of partial output blocks */
- trunc, /* # of truncated records */
- swab, /* # of odd-length swab blocks */
- bytes; /* # of bytes written */
+ quad_t in_full; /* # of full input blocks */
+ quad_t in_part; /* # of partial input blocks */
+ quad_t out_full; /* # of full output blocks */
+ quad_t out_part; /* # of partial output blocks */
+ quad_t trunc; /* # of truncated records */
+ quad_t swab; /* # of odd-length swab blocks */
+ quad_t bytes; /* # of bytes written */
double start; /* start time of dd */
} STAT;
diff --git a/bin/dd/extern.h b/bin/dd/extern.h
index 9517425..311dc1c 100644
--- a/bin/dd/extern.h
+++ b/bin/dd/extern.h
@@ -57,10 +57,10 @@ void unblock_close __P((void));
extern IO in, out;
extern STAT st;
extern void (*cfunc)();
-extern size_t cpy_cnt;
-extern size_t cbsz;
+extern quad_t cpy_cnt;
+extern int cbsz;
extern u_int ddflags;
-extern int files_cnt;
+extern quad_t files_cnt;
extern u_char *ctab;
extern u_char a2e_32V[], a2e_POSIX[], a2ibm_32V[], a2ibm_POSIX[], e2a_32V[];
extern u_char e2a_POSIX[], l2u[], u2l[];
diff --git a/bin/dd/position.c b/bin/dd/position.c
index 00fd504..7bab913 100644
--- a/bin/dd/position.c
+++ b/bin/dd/position.c
@@ -61,10 +61,9 @@ static const char rcsid[] =
void
pos_in()
{
- size_t bcnt;
+ int bcnt, warned;
ssize_t nr;
off_t cnt;
- int warned;
/* If not a character, pipe or tape device, try to seek on it. */
if (!(in.flags & (ISCHR|ISPIPE|ISTAPE))) {
OpenPOWER on IntegriCloud