From f6ff413cc296d79a50926a52e2bd7f3ed246d8ac Mon Sep 17 00:00:00 2001 From: millert Date: Fri, 14 Feb 1997 07:05:18 +0000 Subject: [PATCH] Deal with 64-bit offsets and report bytes copied as a 64-bit quantity. Closes OpenBSD PR system/107. --- bin/dd/args.c | 118 +++++++++++++++++++++++++++++++++++++--------- bin/dd/conv.c | 23 ++++----- bin/dd/dd.c | 28 ++++++----- bin/dd/dd.h | 32 ++++++------- bin/dd/extern.h | 8 ++-- bin/dd/misc.c | 12 ++--- bin/dd/position.c | 17 ++++--- 7 files changed, 158 insertions(+), 80 deletions(-) diff --git a/bin/dd/args.c b/bin/dd/args.c index 3d8ec3053de..84367b1583e 100644 --- a/bin/dd/args.c +++ b/bin/dd/args.c @@ -1,4 +1,4 @@ -/* $OpenBSD: args.c,v 1.5 1996/12/14 12:17:47 mickey Exp $ */ +/* $OpenBSD: args.c,v 1.6 1997/02/14 07:05:18 millert Exp $ */ /* $NetBSD: args.c,v 1.7 1996/03/01 01:18:58 jtc Exp $ */ /*- @@ -42,7 +42,7 @@ #if 0 static char sccsid[] = "@(#)args.c 8.3 (Berkeley) 4/2/94"; #else -static char rcsid[] = "$OpenBSD: args.c,v 1.5 1996/12/14 12:17:47 mickey Exp $"; +static char rcsid[] = "$OpenBSD: args.c,v 1.6 1997/02/14 07:05:18 millert Exp $"; #endif #endif /* not lint */ @@ -71,7 +71,8 @@ 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 u_long get_bsz __P((char *)); +static size_t get_bsz __P((char *)); +static off_t get_off __P((char *)); const static struct arg { char *name; @@ -106,7 +107,8 @@ jcl(argv) in.dbsz = out.dbsz = 512; while ((oper = *++argv) != NULL) { - oper = strdup(oper); + if ((oper = strdup(oper)) == NULL) + errx(1, "out of memory"); if ((arg = strchr(oper, '=')) == NULL) errx(1, "unknown operand %s", oper); *arg++ = '\0'; @@ -170,14 +172,13 @@ jcl(argv) errx(1, "buffer sizes cannot be zero"); /* - * Read, write and seek calls take ints as arguments. Seek sizes - * could be larger if we wanted to do it in stages or check only - * regular files, but it's probably not worth it. + * Read and write take size_t's as arguments. Lseek, however, + * takes an off_t (quad). */ - if (in.dbsz > INT_MAX || out.dbsz > INT_MAX) - errx(1, "buffer sizes cannot be greater than %d", INT_MAX); - if (in.offset > INT_MAX / in.dbsz || out.offset > INT_MAX / out.dbsz) - errx(1, "seek offsets cannot be larger than %d", INT_MAX); + if (in.dbsz > SIZE_T_MAX || out.dbsz > SIZE_T_MAX) + errx(1, "buffer sizes cannot be greater than %u", SIZE_T_MAX); + 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 @@ -193,7 +194,7 @@ f_bs(arg) char *arg; { - in.dbsz = out.dbsz = (int)get_bsz(arg); + in.dbsz = out.dbsz = get_bsz(arg); } static void @@ -201,7 +202,7 @@ f_cbs(arg) char *arg; { - cbsz = (int)get_bsz(arg); + cbsz = get_bsz(arg); } static void @@ -209,7 +210,7 @@ f_count(arg) char *arg; { - cpy_cnt = (u_int)get_bsz(arg); + cpy_cnt = get_bsz(arg); if (!cpy_cnt) terminate(0); } @@ -219,7 +220,7 @@ f_files(arg) char *arg; { - files_cnt = (int)get_bsz(arg); + files_cnt = get_bsz(arg); } static void @@ -228,7 +229,7 @@ f_ibs(arg) { if (!(ddflags & C_BS)) - in.dbsz = (int)get_bsz(arg); + in.dbsz = get_bsz(arg); } static void @@ -245,7 +246,7 @@ f_obs(arg) { if (!(ddflags & C_BS)) - out.dbsz = (int)get_bsz(arg); + out.dbsz = get_bsz(arg); } static void @@ -261,7 +262,7 @@ f_seek(arg) char *arg; { - out.offset = (u_int)get_bsz(arg); + out.offset = get_off(arg); } static void @@ -269,7 +270,7 @@ f_skip(arg) char *arg; { - in.offset = (u_int)get_bsz(arg); + in.offset = get_off(arg); } #ifdef NO_CONV @@ -335,7 +336,7 @@ c_conv(a, b) #endif /* NO_CONV */ /* - * Convert an expression of the following forms to an unsigned long. + * Convert an expression of the following forms to a size_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). @@ -345,15 +346,15 @@ c_conv(a, b) * seperated by x (also * for backwards compatibility), specifying * the product of the indicated values. */ -static u_long +static size_t get_bsz(val) char *val; { - u_long num, t; + size_t num, t; char *expr; num = strtoul(val, &expr, 0); - if (num == ULONG_MAX) /* Overflow. */ + if (num == SIZE_T_MAX) /* Overflow. */ err(1, "%s", oper); if (expr == val) /* No digits. */ errx(1, "%s: illegal numeric value", oper); @@ -404,3 +405,74 @@ erange: errx(1, "%s: %s", oper, strerror(ERANGE)); } return (num); } + +/* + * Convert an expression of the following forms to an off_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). + * seperated by x (also * for backwards compatibility), specifying + * the product of the indicated values. + */ +static off_t +get_off(val) + char *val; +{ + off_t num, t; + char *expr; + + num = strtoq(val, &expr, 0); + if (num == QUAD_MAX) /* Overflow. */ + err(1, "%s", oper); + if (expr == val) /* No digits. */ + errx(1, "%s: illegal numeric value", oper); + + switch(*expr) { + case 'b': + t = num; + num *= 512; + if (t > num) + goto erange; + ++expr; + break; + case 'k': + t = num; + num *= 1024; + if (t > num) + goto erange; + ++expr; + break; + case 'm': + t = num; + num *= 1048576; + if (t > num) + goto erange; + ++expr; + break; + case 'w': + t = num; + num *= sizeof(int); + if (t > num) + goto erange; + ++expr; + break; + } + + switch(*expr) { + case '\0': + break; + case '*': /* Backward compatible. */ + case 'x': + t = num; + num *= get_off(expr + 1); + if (t > num) +erange: errx(1, "%s: %s", oper, strerror(ERANGE)); + break; + default: + errx(1, "%s: illegal numeric value", oper); + } + return (num); +} diff --git a/bin/dd/conv.c b/bin/dd/conv.c index 026ccd55259..f1853cf7dd7 100644 --- a/bin/dd/conv.c +++ b/bin/dd/conv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conv.c,v 1.4 1996/12/14 12:17:48 mickey Exp $ */ +/* $OpenBSD: conv.c,v 1.5 1997/02/14 07:05:19 millert Exp $ */ /* $NetBSD: conv.c,v 1.6 1996/02/20 19:29:02 jtc Exp $ */ /*- @@ -42,7 +42,7 @@ #if 0 static char sccsid[] = "@(#)conv.c 8.3 (Berkeley) 4/2/94"; #else -static char rcsid[] = "$OpenBSD: conv.c,v 1.4 1996/12/14 12:17:48 mickey Exp $"; +static char rcsid[] = "$OpenBSD: conv.c,v 1.5 1997/02/14 07:05:19 millert Exp $"; #endif #endif /* not lint */ @@ -63,7 +63,7 @@ static char rcsid[] = "$OpenBSD: conv.c,v 1.4 1996/12/14 12:17:48 mickey Exp $"; void def() { - int cnt; + size_t cnt; u_char *inp; const u_char *t; @@ -118,7 +118,8 @@ void block() { static int intrunc; - int ch = -1, cnt, maxlen; + int ch = -1; + size_t cnt, maxlen; u_char *inp, *outp; const u_char *t; @@ -161,7 +162,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; } @@ -211,7 +212,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; @@ -228,7 +229,7 @@ block_close() void unblock() { - int cnt; + size_t cnt; u_char *inp; const u_char *t; @@ -245,7 +246,7 @@ unblock() for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t); if (t >= inp) { cnt = t - inp + 1; - memmove(out.dbp, inp, cnt); + (void)memmove(out.dbp, inp, cnt); out.dbp += cnt; out.dbcnt += cnt; } @@ -255,14 +256,14 @@ 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; + size_t cnt; u_char *t; if (in.dbcnt) { @@ -270,7 +271,7 @@ unblock_close() for (t = in.db + in.dbcnt - 1; t >= in.db && *t == ' '; --t); 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/dd.c b/bin/dd/dd.c index d89ac0d442f..0f7267fa1cc 100644 --- a/bin/dd/dd.c +++ b/bin/dd/dd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dd.c,v 1.4 1996/12/14 12:17:49 mickey Exp $ */ +/* $OpenBSD: dd.c,v 1.5 1997/02/14 07:05:20 millert Exp $ */ /* $NetBSD: dd.c,v 1.6 1996/02/20 19:29:06 jtc Exp $ */ /*- @@ -48,7 +48,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)dd.c 8.5 (Berkeley) 4/2/94"; #else -static char rcsid[] = "$OpenBSD: dd.c,v 1.4 1996/12/14 12:17:49 mickey Exp $"; +static char rcsid[] = "$OpenBSD: dd.c,v 1.5 1997/02/14 07:05:20 millert Exp $"; #endif #endif /* not lint */ @@ -78,11 +78,11 @@ static void setup __P((void)); IO in, out; /* input/output state */ STAT st; /* statistics */ void (*cfunc) __P((void)); /* conversion function */ -u_long cpy_cnt; /* # of blocks to copy */ +size_t cpy_cnt; /* # of blocks to copy */ u_int ddflags; /* conversion options */ -u_int cbsz; /* conversion block size */ -u_int files_cnt = 1; /* # of files to copy */ -const u_char *ctab; /* conversion table */ +size_t cbsz; /* conversion block size */ +size_t files_cnt = 1; /* # of files to copy */ +const u_char *ctab; /* conversion table */ int main(argc, argv) @@ -172,7 +172,7 @@ setup() * kinds of output files, tapes, for example. */ if ((ddflags & (C_OF | C_SEEK | C_NOTRUNC)) == (C_OF | C_SEEK)) - (void)ftruncate(out.fd, (off_t)out.offset * out.dbsz); + (void)ftruncate(out.fd, out.offset * out.dbsz); /* * If converting case at the same time as another conversion, build a @@ -227,7 +227,8 @@ getfdtype(io) static void dd_in() { - int flags, n; + int flags; + ssize_t n; for (flags = ddflags;;) { if (cpy_cnt && (st.in_full + st.in_part) >= cpy_cnt) @@ -240,9 +241,9 @@ dd_in() */ if ((flags & (C_NOERROR|C_SYNC)) == (C_NOERROR|C_SYNC)) if (flags & (C_BLOCK|C_UNBLOCK)) - memset(in.dbp, ' ', in.dbsz); + (void)memset(in.dbp, ' ', in.dbsz); else - memset(in.dbp, 0, in.dbsz); + (void)memset(in.dbp, 0, in.dbsz); n = read(in.fd, in.dbp, in.dbsz); if (n == 0) { @@ -333,7 +334,7 @@ dd_close() else if (cfunc == unblock) unblock_close(); if (ddflags & C_OSYNC && out.dbcnt < out.dbsz) { - memset(out.dbp, 0, out.dbsz - out.dbcnt); + (void)memset(out.dbp, 0, out.dbsz - out.dbcnt); out.dbcnt = out.dbsz; } if (out.dbcnt) @@ -345,7 +346,8 @@ dd_out(force) int force; { static int warned; - int cnt, n, nw; + size_t cnt, n; + ssize_t nw; u_char *outp; /* @@ -401,6 +403,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 f89b2c85366..461897e7651 100644 --- a/bin/dd/dd.h +++ b/bin/dd/dd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dd.h,v 1.2 1996/06/23 14:19:48 deraadt Exp $ */ +/* $OpenBSD: dd.h,v 1.3 1997/02/14 07:05:20 millert Exp $ */ /* $NetBSD: dd.h,v 1.4 1995/03/21 09:04:08 cgd Exp $ */ /*- @@ -44,9 +44,9 @@ typedef struct { u_char *db; /* buffer address */ u_char *dbp; /* current buffer I/O address */ - u_long dbcnt; /* current buffer byte count */ - int dbrcnt; /* last read byte count */ - u_long 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) */ @@ -56,22 +56,22 @@ typedef struct { char *name; /* name */ int fd; /* file descriptor */ - u_long offset; /* # of blocks to skip */ + off_t offset; /* # of blocks to skip */ - u_long f_stats; /* # of full blocks processed */ - u_long p_stats; /* # of partial blocks processed */ - u_long s_stats; /* # of odd swab blocks */ - u_long t_stats; /* # of truncations */ + size_t f_stats; /* # of full blocks processed */ + size_t p_stats; /* # of partial blocks processed */ + size_t s_stats; /* # of odd swab blocks */ + size_t t_stats; /* # of truncations */ } IO; typedef struct { - u_long in_full; /* # of full input blocks */ - u_long in_part; /* # of partial input blocks */ - u_long out_full; /* # of full output blocks */ - u_long out_part; /* # of partial output blocks */ - u_long trunc; /* # of truncated records */ - u_long swab; /* # of odd-length swab blocks */ - u_long bytes; /* # of bytes written */ + size_t in_full; /* # of full input blocks */ + size_t in_part; /* # of partial input blocks */ + size_t out_full; /* # of full output blocks */ + size_t out_part; /* # of partial output blocks */ + size_t trunc; /* # of truncated records */ + size_t swab; /* # of odd-length swab blocks */ + off_t bytes; /* # of bytes written */ time_t start; /* start time of dd */ } STAT; diff --git a/bin/dd/extern.h b/bin/dd/extern.h index 448265b53fb..2d0eca452f8 100644 --- a/bin/dd/extern.h +++ b/bin/dd/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.3 1996/06/23 14:19:48 deraadt Exp $ */ +/* $OpenBSD: extern.h,v 1.4 1997/02/14 07:05:21 millert Exp $ */ /* $NetBSD: extern.h,v 1.7 1996/02/20 19:29:07 jtc Exp $ */ /*- @@ -59,10 +59,10 @@ void unblock_close __P((void)); extern IO in, out; extern STAT st; extern void (*cfunc)(); -extern u_long cpy_cnt; -extern u_int cbsz; +extern size_t cpy_cnt; +extern size_t cbsz; extern u_int ddflags; -extern u_int files_cnt; +extern size_t files_cnt; extern const u_char *ctab; extern const u_char a2e_32V[], a2e_POSIX[]; extern const u_char e2a_32V[], e2a_POSIX[]; diff --git a/bin/dd/misc.c b/bin/dd/misc.c index 76f549ab9ab..4c501a64cee 100644 --- a/bin/dd/misc.c +++ b/bin/dd/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.3 1996/12/14 12:17:50 mickey Exp $ */ +/* $OpenBSD: misc.c,v 1.4 1997/02/14 07:05:21 millert Exp $ */ /* $NetBSD: misc.c,v 1.4 1995/03/21 09:04:10 cgd Exp $ */ /*- @@ -42,7 +42,7 @@ #if 0 static char sccsid[] = "@(#)misc.c 8.3 (Berkeley) 4/2/94"; #else -static char rcsid[] = "$OpenBSD: misc.c,v 1.3 1996/12/14 12:17:50 mickey Exp $"; +static char rcsid[] = "$OpenBSD: misc.c,v 1.4 1997/02/14 07:05:21 millert Exp $"; #endif #endif /* not lint */ @@ -69,21 +69,21 @@ summary() secs = 1; /* Use snprintf(3) so that we don't reenter stdio(3). */ (void)snprintf(buf, sizeof(buf), - "%lu+%lu records in\n%lu+%lu records out\n", + "%u+%u records in\n%u+%u records out\n", st.in_full, st.in_part, st.out_full, st.out_part); (void)write(STDERR_FILENO, buf, strlen(buf)); if (st.swab) { - (void)snprintf(buf, sizeof(buf), "%lu odd length swab %s\n", + (void)snprintf(buf, sizeof(buf), "%u odd length swab %s\n", st.swab, (st.swab == 1) ? "block" : "blocks"); (void)write(STDERR_FILENO, buf, strlen(buf)); } if (st.trunc) { - (void)snprintf(buf, sizeof(buf), "%lu truncated %s\n", + (void)snprintf(buf, sizeof(buf), "%u truncated %s\n", st.trunc, (st.trunc == 1) ? "block" : "blocks"); (void)write(STDERR_FILENO, buf, strlen(buf)); } (void)snprintf(buf, sizeof(buf), - "%lu bytes transferred in %lu secs (%lu bytes/sec)\n", + "%qd bytes transferred in %ld secs (%qd bytes/sec)\n", st.bytes, secs, st.bytes / secs); (void)write(STDERR_FILENO, buf, strlen(buf)); } diff --git a/bin/dd/position.c b/bin/dd/position.c index ca2612d2960..a02a485bb55 100644 --- a/bin/dd/position.c +++ b/bin/dd/position.c @@ -1,4 +1,4 @@ -/* $OpenBSD: position.c,v 1.2 1996/06/23 14:19:49 deraadt Exp $ */ +/* $OpenBSD: position.c,v 1.3 1997/02/14 07:05:22 millert Exp $ */ /* $NetBSD: position.c,v 1.4 1995/03/21 09:04:12 cgd Exp $ */ /*- @@ -42,7 +42,7 @@ #if 0 static char sccsid[] = "@(#)position.c 8.3 (Berkeley) 4/2/94"; #else -static char rcsid[] = "$OpenBSD: position.c,v 1.2 1996/06/23 14:19:49 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: position.c,v 1.3 1997/02/14 07:05:22 millert Exp $"; #endif #endif /* not lint */ @@ -68,11 +68,14 @@ static char rcsid[] = "$OpenBSD: position.c,v 1.2 1996/06/23 14:19:49 deraadt Ex void pos_in() { - int bcnt, cnt, nr, warned; + size_t bcnt; + 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))) { - if (lseek(in.fd, (off_t)(in.offset * in.dbsz), SEEK_CUR) == -1) + if (lseek(in.fd, in.offset * in.dbsz, SEEK_CUR) == -1) err(1, "%s", in.name); return; } @@ -123,7 +126,8 @@ void pos_out() { struct mtop t_op; - int cnt, n; + off_t cnt; + ssize_t n; /* * If not a tape, try seeking on the file. Seeking on a pipe is @@ -131,8 +135,7 @@ pos_out() * have specified the seek operand. */ if (!(out.flags & ISTAPE)) { - if (lseek(out.fd, - (off_t)out.offset * out.dbsz, SEEK_SET) == -1) + if (lseek(out.fd, out.offset * out.dbsz, SEEK_SET) == -1) err(1, "%s", out.name); return; } -- 2.20.1