Deal with 64-bit offsets and report bytes copied as a 64-bit quantity.
authormillert <millert@openbsd.org>
Fri, 14 Feb 1997 07:05:18 +0000 (07:05 +0000)
committermillert <millert@openbsd.org>
Fri, 14 Feb 1997 07:05:18 +0000 (07:05 +0000)
Closes OpenBSD PR system/107.

bin/dd/args.c
bin/dd/conv.c
bin/dd/dd.c
bin/dd/dd.h
bin/dd/extern.h
bin/dd/misc.c
bin/dd/position.c

index 3d8ec30..84367b1 100644 (file)
@@ -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);
+}
index 026ccd5..f1853cf 100644 (file)
@@ -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;
                }
index d89ac0d..0f7267f 100644 (file)
@@ -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;
 }
index f89b2c8..461897e 100644 (file)
@@ -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;
 
index 448265b..2d0eca4 100644 (file)
@@ -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[];
index 76f549a..4c501a6 100644 (file)
@@ -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));
 }
index ca2612d..a02a485 100644 (file)
@@ -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;
        }