This is the second round of dd(1) changes. Some changes made/reversed by

request of Bruce. More changes may follow later. 'g' multiplier has
been added (i.e. dd seek=5g if=bigfile.) Some minor corrections were made
as well.

Noticed by: bde
This commit is contained in:
Brian Feldman 1999-06-20 14:58:55 +00:00
parent 20510b2017
commit 54946e00b2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=48051
7 changed files with 108 additions and 83 deletions

View File

@ -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);
cbsz = (size_t)get_bsz(arg);
if (res < 1 || res > INT_MAX)
errx(1, "cbs must be between 1 and %d", INT_MAX);
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;

View File

@ -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) {

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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[];

View File

@ -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))) {