summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/dd/args.c76
-rw-r--r--bin/dd/conv.c28
-rw-r--r--bin/dd/conv_tab.c23
-rw-r--r--bin/dd/dd.c58
-rw-r--r--bin/dd/dd.h28
-rw-r--r--bin/dd/extern.h10
-rw-r--r--bin/dd/position.c14
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;
OpenPOWER on IntegriCloud