diff options
-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; |