diff options
author | green <green@FreeBSD.org> | 1999-09-12 16:51:53 +0000 |
---|---|---|
committer | green <green@FreeBSD.org> | 1999-09-12 16:51:53 +0000 |
commit | 4c16a85a3ff03636818f24c79ff2bc5947df9263 (patch) | |
tree | 27ec4fb5de7c3368adcff8f419831e3fad5929a9 | |
parent | 24f1ee63f7883c5a3b659be2be4b666369e6142d (diff) | |
download | FreeBSD-src-4c16a85a3ff03636818f24c79ff2bc5947df9263.zip FreeBSD-src-4c16a85a3ff03636818f24c79ff2bc5947df9263.tar.gz |
Even more cleanups to dd(1). This is probably the culmination of the
BDEification process of dd(1). Most of the changes are from BDE's archive.
Support for negative offsets is gone again, but the case where you
lseek() onto byte -1 of something from a negative offset using seek/skip
is fixed; if you end up on -1, you won't get a false positive lseek failure.
The biggest changes are to data types (more size_t, for instance) and
argument parsing. skip/seek on /dev/{,k}mem now occurs (instead of "read
until you reach the offset") due to mem devices now being D_DISK. Some
const things are now correctly declared as such, and the "case table"
building is better. The only thing that seems to be left to make dd(1)
everything TOG wants it to be is l10n.
-rw-r--r-- | bin/dd/args.c | 76 | ||||
-rw-r--r-- | bin/dd/conv.c | 28 | ||||
-rw-r--r-- | bin/dd/conv_tab.c | 23 | ||||
-rw-r--r-- | bin/dd/dd.c | 58 | ||||
-rw-r--r-- | bin/dd/dd.h | 28 | ||||
-rw-r--r-- | bin/dd/extern.h | 10 | ||||
-rw-r--r-- | bin/dd/position.c | 14 |
7 files changed, 117 insertions, 120 deletions
diff --git a/bin/dd/args.c b/bin/dd/args.c index 08555c1..606da90 100644 --- a/bin/dd/args.c +++ b/bin/dd/args.c @@ -68,8 +68,9 @@ static void f_of __P((char *)); static void f_seek __P((char *)); static void f_skip __P((char *)); static quad_t get_num __P((char *)); +static off_t get_offset __P((char *)); -static struct arg { +static const struct arg { char *name; void (*f) __P((char *)); u_int set, noset; @@ -160,6 +161,11 @@ jcl(argv) errx(1, "cbs meaningless if not doing record operations"); } else cfunc = def; + /* + * Bail out if the calculation of a file offset would overflow. + */ + if (in.offset > QUAD_MAX / in.dbsz || out.offset > QUAD_MAX / out.dbsz) + errx(1, "seek offsets cannot be larger than %qd", QUAD_MAX); } static int @@ -174,22 +180,24 @@ static void f_bs(arg) char *arg; { - quad_t res = get_num(arg); + quad_t res; - if (res < 1 || res > INT_MAX) - errx(1, "bs must be between 1 and %d", INT_MAX); - in.dbsz = out.dbsz = (int)res; + res = get_num(arg); + if (res < 1 || res > SSIZE_MAX) + errx(1, "bs must be between 1 and %d", SSIZE_MAX); + in.dbsz = out.dbsz = (size_t)res; } static void f_cbs(arg) char *arg; { - quad_t res = get_num(arg); + quad_t res; - if (res < 1 || res > INT_MAX) - errx(1, "cbs must be between 1 and %d", INT_MAX); - cbsz = (int)res; + res = get_num(arg); + if (res < 1 || res > SSIZE_MAX) + errx(1, "cbs must be between 1 and %d", SSIZE_MAX); + cbsz = (size_t)res; } static void @@ -201,8 +209,6 @@ f_count(arg) if (!cpy_cnt) terminate(0); - if (cpy_cnt < 0) - errx(1, "count cannot be negative"); } static void @@ -211,19 +217,17 @@ f_files(arg) { files_cnt = get_num(arg); - if (files_cnt < 0) - errx(1, "files cannot be negative"); } static void f_ibs(arg) char *arg; { + quad_t res; if (!(ddflags & C_BS)) { - quad_t res = get_num(arg); - - if (res < 1 || res > INT_MAX) + res = get_num(arg); + if (res < 1 || res > SSIZE_MAX) errx(1, "ibs must be between 1 and %d", INT_MAX); in.dbsz = (int)res; } @@ -241,13 +245,13 @@ static void f_obs(arg) char *arg; { + quad_t res; if (!(ddflags & C_BS)) { - quad_t res = get_num(arg); - - if (res < 1 || res > INT_MAX) - errx(1, "ibs must be between 1 and %d", INT_MAX); - out.dbsz = (int)res; + res = get_num(arg); + if (res < 1 || res > SSIZE_MAX) + errx(1, "obs must be between 1 and %d", SSIZE_MAX); + out.dbsz = (size_t)res; } } @@ -264,7 +268,7 @@ f_seek(arg) char *arg; { - out.offset = get_num(arg); + out.offset = get_offset(arg); } static void @@ -272,13 +276,13 @@ f_skip(arg) char *arg; { - in.offset = get_num(arg); + in.offset = get_offset(arg); } -static struct conv { +static const struct conv { char *name; u_int set, noset; - u_char *ctab; + const u_char *ctab; } clist[] = { { "ascii", C_ASCII, C_EBCDIC, e2a_POSIX }, { "block", C_BLOCK, C_UNBLOCK, NULL }, @@ -306,9 +310,9 @@ f_conv(arg) while (arg != NULL) { tmp.name = strsep(&arg, ","); - if (!(cp = (struct conv *)bsearch(&tmp, clist, - sizeof(clist)/sizeof(struct conv), sizeof(struct conv), - c_conv))) + cp = bsearch(&tmp, clist, sizeof(clist) / sizeof(struct conv), + sizeof(struct conv), c_conv); + if (cp == NULL) errx(1, "unknown conversion %s", tmp.name); if (ddflags & cp->noset) errx(1, "%s: illegal conversion combination", tmp.name); @@ -347,10 +351,10 @@ get_num(val) errno = 0; num = strtoq(val, &expr, 0); - if (errno) /* Overflow or underflow. */ + if (errno != 0) /* Overflow or underflow. */ err(1, "%s", oper); - if (expr == val) /* Not a valid number */ + if (expr == val) /* No valid digits. */ errx(1, "%s: illegal numeric value", oper); switch (*expr) { @@ -407,3 +411,15 @@ erange: } return (num); } + +static off_t +get_offset(val) + char *val; +{ + quad_t num; + + num = get_num(val); + if (num > QUAD_MAX || num < 0) /* XXX quad_t != off_t */ + errx(1, "%s: illegal offset", oper); /* Too big/negative. */ + return ((off_t)num); +} diff --git a/bin/dd/conv.c b/bin/dd/conv.c index bf47410..57741aa 100644 --- a/bin/dd/conv.c +++ b/bin/dd/conv.c @@ -60,8 +60,9 @@ static const char rcsid[] = void def() { - int cnt; - u_char *inp, *t; + u_char *inp; + const u_char *t; + size_t cnt; if ((t = ctab) != NULL) for (inp = in.dbp - (cnt = in.dbrcnt); cnt--; ++inp) @@ -103,9 +104,11 @@ def_close() void block() { + u_char *inp, *outp; + const u_char *t; + size_t cnt, maxlen; static int intrunc; - int ch, cnt, maxlen; - u_char *inp, *outp, *t; + int ch = -1; /* * Record truncation can cross block boundaries. If currently in a @@ -147,7 +150,7 @@ block() * input block. */ if (ch != '\n' && in.dbcnt < cbsz) { - memmove(in.db, in.dbp - in.dbcnt, in.dbcnt); + (void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt); break; } @@ -197,7 +200,7 @@ block_close() */ if (in.dbcnt) { ++st.trunc; - memmove(out.dbp, in.dbp - in.dbcnt, in.dbcnt); + (void)memmove(out.dbp, in.dbp - in.dbcnt, in.dbcnt); (void)memset(out.dbp + in.dbcnt, ctab ? ctab[' '] : ' ', cbsz - in.dbcnt); out.dbcnt += cbsz; @@ -214,8 +217,9 @@ block_close() void unblock() { - int cnt; - u_char *inp, *t; + u_char *inp; + const u_char *t; + size_t cnt; /* Translation and case conversion. */ if ((t = ctab) != NULL) @@ -231,7 +235,7 @@ unblock() ; if (t >= inp) { cnt = t - inp + 1; - memmove(out.dbp, inp, cnt); + (void)memmove(out.dbp, inp, cnt); out.dbp += cnt; out.dbcnt += cnt; } @@ -240,15 +244,15 @@ unblock() dd_out(0); } if (in.dbcnt) - memmove(in.db, in.dbp - in.dbcnt, in.dbcnt); + (void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt); in.dbp = in.db + in.dbcnt; } void unblock_close() { - int cnt; u_char *t; + size_t cnt; if (in.dbcnt) { warnx("%s: short input record", in.name); @@ -256,7 +260,7 @@ unblock_close() ; if (t >= in.db) { cnt = t - in.db + 1; - memmove(out.dbp, in.db, cnt); + (void)memmove(out.dbp, in.db, cnt); out.dbp += cnt; out.dbcnt += cnt; } diff --git a/bin/dd/conv_tab.c b/bin/dd/conv_tab.c index 8637bdd..bd951a7 100644 --- a/bin/dd/conv_tab.c +++ b/bin/dd/conv_tab.c @@ -46,10 +46,7 @@ static const char rcsid[] = #include <sys/types.h> /* - * There are currently eight tables: - * - * lower-case -> upper-case conv=upper - * upper-case -> lower-case conv=lower + * There are currently six tables: * * ebcdic -> ascii 32V conv=oldascii * ascii -> ebcdic 32V conv=oldebcdic @@ -72,14 +69,10 @@ static const char rcsid[] = * ACM, Volume 11, Number 11, November 1968, pp. 783-789. */ -/* Lower-case to upper-case */ -u_char l2u[256]; - -/* Upper-case to lower-case */ -u_char u2l[256]; +u_char casetab[256]; /* EBCDIC to ASCII -- 32V compatible. */ -u_char e2a_32V[] = { +const u_char e2a_32V[] = { 0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177, /* 0000 */ 0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017, /* 0010 */ 0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207, /* 0020 */ @@ -115,7 +108,7 @@ u_char e2a_32V[] = { }; /* ASCII to EBCDIC -- 32V compatible. */ -u_char a2e_32V[] = { +const u_char a2e_32V[] = { 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057, /* 0000 */ 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017, /* 0010 */ 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046, /* 0020 */ @@ -151,7 +144,7 @@ u_char a2e_32V[] = { }; /* ASCII to IBM EBCDIC -- 32V compatible. */ -u_char a2ibm_32V[] = { +const u_char a2ibm_32V[] = { 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057, /* 0000 */ 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017, /* 0010 */ 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046, /* 0020 */ @@ -187,7 +180,7 @@ u_char a2ibm_32V[] = { }; /* EBCDIC to ASCII -- POSIX and System V compatible. */ -u_char e2a_POSIX[] = { +const u_char e2a_POSIX[] = { 0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177, /* 0000 */ 0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017, /* 0010 */ 0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207, /* 0020 */ @@ -223,7 +216,7 @@ u_char e2a_POSIX[] = { }; /* ASCII to EBCDIC -- POSIX and System V compatible. */ -u_char a2e_POSIX[] = { +const u_char a2e_POSIX[] = { 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057, /* 0000 */ 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017, /* 0010 */ 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046, /* 0020 */ @@ -259,7 +252,7 @@ u_char a2e_POSIX[] = { }; /* ASCII to IBM EBCDIC -- POSIX and System V compatible. */ -u_char a2ibm_POSIX[] = { +const u_char a2ibm_POSIX[] = { 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057, /* 0000 */ 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017, /* 0010 */ 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046, /* 0020 */ diff --git a/bin/dd/dd.c b/bin/dd/dd.c index 9ac4f86..617cd51 100644 --- a/bin/dd/dd.c +++ b/bin/dd/dd.c @@ -80,9 +80,9 @@ void (*cfunc) __P((void)); /* conversion function */ quad_t cpy_cnt; /* # of blocks to copy */ off_t pending = 0; /* pending seek if sparse */ u_int ddflags; /* conversion options */ -int cbsz; /* conversion block size */ +size_t cbsz; /* conversion block size */ quad_t files_cnt = 1; /* # of files to copy */ -u_char *ctab; /* conversion table */ +const u_char *ctab; /* conversion table */ int main(argc, argv) @@ -154,11 +154,11 @@ setup() */ if (!(ddflags & (C_BLOCK|C_UNBLOCK))) { if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL) - err(1, NULL); + err(1, "input buffer"); out.db = in.db; - } 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); + } else if ((in.db = malloc(MAX(in.dbsz, cbsz) + cbsz)) == NULL || + (out.db = malloc(out.dbsz + cbsz)) == NULL) + err(1, "output buffer"); in.dbp = in.db; out.dbp = out.db; @@ -181,43 +181,26 @@ setup() * built-in tables. */ if (ddflags & (C_LCASE|C_UCASE)) { - if (ddflags & C_ASCII) { + if (ddflags & (C_ASCII|C_EBCDIC)) { if (ddflags & C_LCASE) { for (cnt = 0; cnt <= 0377; ++cnt) - if (isupper(ctab[cnt])) - ctab[cnt] = tolower(ctab[cnt]); + casetab[cnt] = tolower(ctab[cnt]); } else { for (cnt = 0; cnt <= 0377; ++cnt) - if (islower(ctab[cnt])) - ctab[cnt] = toupper(ctab[cnt]); - } - } else if (ddflags & C_EBCDIC) { - if (ddflags & C_LCASE) { - for (cnt = 0; cnt <= 0377; ++cnt) - if (isupper(cnt)) - ctab[cnt] = ctab[tolower(cnt)]; - } else { - for (cnt = 0; cnt <= 0377; ++cnt) - if (islower(cnt)) - ctab[cnt] = ctab[toupper(cnt)]; + casetab[cnt] = toupper(ctab[cnt]); } } else { - ctab = ddflags & C_LCASE ? u2l : l2u; if (ddflags & C_LCASE) { for (cnt = 0; cnt <= 0377; ++cnt) - if (isupper(cnt)) - ctab[cnt] = tolower(cnt); - else - ctab[cnt] = cnt; + casetab[cnt] = tolower(cnt); } else { for (cnt = 0; cnt <= 0377; ++cnt) - if (islower(cnt)) - ctab[cnt] = toupper(cnt); - else - ctab[cnt] = cnt; + casetab[cnt] = toupper(cnt); } } + ctab = casetab; } + (void)gettimeofday(&tv, (struct timezone *)NULL); st.start = tv.tv_sec + tv.tv_usec * 1e-6; } @@ -229,7 +212,7 @@ getfdtype(io) struct stat sb; int type; - if (fstat(io->fd, &sb)) + if (fstat(io->fd, &sb) == -1) err(1, "%s", io->name); if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) { if (ioctl(io->fd, FIODTYPE, &type) == -1) { @@ -258,7 +241,7 @@ dd_in() return; /* - * Zero the buffer first if sync; If doing block operations + * Zero the buffer first if sync; if doing block operations, * use spaces. */ if (ddflags & C_SYNC) { @@ -344,7 +327,7 @@ dd_in() } /* - * Cleanup any remaining I/O and flush output. If necesssary, output file + * Clea nup any remaining I/O and flush output. If necessary, the output file * is truncated. */ static void @@ -371,10 +354,11 @@ void dd_out(force) int force; { - static int warned; - int cnt, n, i, sparse; - ssize_t nw; u_char *outp; + size_t cnt, i, n; + ssize_t nw; + static int warned; + int sparse; /* * Write one or more blocks out. The common case is writing a full @@ -458,6 +442,6 @@ dd_out(force) /* Reassemble the output block. */ if (out.dbcnt) - memmove(out.db, out.dbp - out.dbcnt, out.dbcnt); + (void)memmove(out.db, out.dbp - out.dbcnt, out.dbcnt); out.dbp = out.db + out.dbcnt; } diff --git a/bin/dd/dd.h b/bin/dd/dd.h index f629a5e..f671baa 100644 --- a/bin/dd/dd.h +++ b/bin/dd/dd.h @@ -42,9 +42,9 @@ typedef struct { u_char *db; /* buffer address */ u_char *dbp; /* current buffer I/O address */ - int dbcnt; /* current buffer byte count */ - int dbrcnt; /* last read byte count */ - int dbsz; /* buffer size */ + size_t dbcnt; /* current buffer byte count */ + size_t dbrcnt; /* last read byte count */ + size_t dbsz; /* buffer size */ #define ISCHR 0x01 /* character device (warn on short) */ #define ISPIPE 0x02 /* pipe (not truncatable) */ @@ -57,20 +57,20 @@ typedef struct { int fd; /* file descriptor */ off_t offset; /* # of blocks to skip */ - 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 */ + u_quad_t f_stats; /* # of full blocks processed */ + u_quad_t p_stats; /* # of partial blocks processed */ + u_quad_t s_stats; /* # of odd swab blocks */ + u_quad_t t_stats; /* # of truncations */ } IO; typedef struct { - 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 */ + u_quad_t in_full; /* # of full input blocks */ + u_quad_t in_part; /* # of partial input blocks */ + u_quad_t out_full; /* # of full output blocks */ + u_quad_t out_part; /* # of partial output blocks */ + u_quad_t trunc; /* # of truncated records */ + u_quad_t swab; /* # of odd-length swab blocks */ + u_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 a5495ad..c588b76 100644 --- a/bin/dd/extern.h +++ b/bin/dd/extern.h @@ -58,9 +58,11 @@ extern IO in, out; extern STAT st; extern void (*cfunc)(); extern quad_t cpy_cnt; -extern int cbsz; +extern size_t cbsz; extern u_int ddflags; 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[]; +extern const u_char *ctab; +extern const u_char a2e_32V[], a2e_POSIX[]; +extern const u_char e2a_32V[], e2a_POSIX[]; +static const u_char a2ibm_32V[], a2ibm_POSIX[]; +extern u_char casetab[]; diff --git a/bin/dd/position.c b/bin/dd/position.c index 74b612c..6c0f684 100644 --- a/bin/dd/position.c +++ b/bin/dd/position.c @@ -62,14 +62,16 @@ static const char rcsid[] = void pos_in() { - int bcnt, warned; - ssize_t nr; off_t cnt; + int warned; + ssize_t nr; + size_t bcnt; /* If not a character, pipe or tape device, try to seek on it. */ if (!(in.flags & (ISCHR|ISPIPE|ISTAPE)) || in.flags & ISDISK) { errno = 0; - if (lseek(in.fd, in.offset * in.dbsz, SEEK_CUR) == -1 && errno) + if (lseek(in.fd, in.offset * in.dbsz, SEEK_CUR) == -1 && + errno != 0) err(1, "%s", in.name); return; } @@ -79,8 +81,6 @@ pos_in() * being skipped. No differentiation for reading complete and partial * blocks for other devices. */ - if (in.offset < 0) - errx(1, "skip must be positive"); for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) { if ((nr = read(in.fd, in.db, bcnt)) > 0) { if (in.flags & ISPIPE) { @@ -129,7 +129,7 @@ pos_out() if (!(out.flags & (ISCHR|ISPIPE|ISTAPE)) || out.flags & ISDISK) { errno = 0; if (lseek(out.fd, out.offset * out.dbsz, SEEK_SET) == -1 && - errno) + errno != 0) err(1, "%s", out.name); return; } @@ -145,8 +145,6 @@ pos_out() } /* Read it. */ - if (out.offset < 0) - errx(1, "seek must be positive"); for (cnt = 0; cnt < out.offset; ++cnt) { if ((n = read(out.fd, out.db, out.dbsz)) > 0) continue; |