diff options
author | green <green@FreeBSD.org> | 1999-06-20 14:58:55 +0000 |
---|---|---|
committer | green <green@FreeBSD.org> | 1999-06-20 14:58:55 +0000 |
commit | 788bc0cf602a4339422fb952290bf85f5e320e07 (patch) | |
tree | 6d6fc3c96961d0a8f6b4ab0507fdfeac4a671380 /bin/dd | |
parent | 615565283ac17a71ab572b235e8e2ec107b6dfe1 (diff) | |
download | FreeBSD-src-788bc0cf602a4339422fb952290bf85f5e320e07.zip FreeBSD-src-788bc0cf602a4339422fb952290bf85f5e320e07.tar.gz |
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
Diffstat (limited to 'bin/dd')
-rw-r--r-- | bin/dd/args.c | 99 | ||||
-rw-r--r-- | bin/dd/conv.c | 15 | ||||
-rw-r--r-- | bin/dd/dd.1 | 8 | ||||
-rw-r--r-- | bin/dd/dd.c | 30 | ||||
-rw-r--r-- | bin/dd/dd.h | 30 | ||||
-rw-r--r-- | bin/dd/extern.h | 6 | ||||
-rw-r--r-- | bin/dd/position.c | 3 |
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))) { |