- Use u_longlong_t instead of u_quad_t, u_long, or int for various buffer sizes
- Add strsuftoull(), which parses a number into a u_longlong_t, with multiplication support, and support for 'g' (GB) and 't' (TB) suffices. If an error occurs, print to stderr and exit. Based on get_blk() from args.c and strsufto*() (in other programs) - Add strsuftoullx(), which acts as per strsuftoull() but returns the error in the supplied buffer instead (if the returned buffer != "", an error occurred) - Replace get_bsz() use with strsuftoull() - Remove (now) unnecessary argument validation - Remove unused {f,p,s,t}_stats fields in struct IO
This commit is contained in:
parent
d271a36466
commit
b6ce735c04
@ -1,8 +1,8 @@
|
||||
# $NetBSD: Makefile,v 1.7 2001/11/25 06:53:48 lukem Exp $
|
||||
# $NetBSD: Makefile,v 1.8 2001/11/25 10:50:06 lukem Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
PROG= dd
|
||||
SRCS= args.c conv.c conv_tab.c dd.c misc.c position.c
|
||||
SRCS= args.c conv.c conv_tab.c dd.c misc.c position.c strsuftoull.c
|
||||
|
||||
WARNS=2
|
||||
|
||||
|
111
bin/dd/args.c
111
bin/dd/args.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: args.c,v 1.18 2001/11/25 06:57:55 lukem Exp $ */
|
||||
/* $NetBSD: args.c,v 1.19 2001/11/25 10:50:06 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
@ -42,7 +42,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)args.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: args.c,v 1.18 2001/11/25 06:57:55 lukem Exp $");
|
||||
__RCSID("$NetBSD: args.c,v 1.19 2001/11/25 10:50:06 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -58,6 +58,7 @@ __RCSID("$NetBSD: args.c,v 1.18 2001/11/25 06:57:55 lukem Exp $");
|
||||
|
||||
#include "dd.h"
|
||||
#include "extern.h"
|
||||
#include "strsuftoull.h"
|
||||
|
||||
static int c_arg(const void *, const void *);
|
||||
#ifndef NO_CONV
|
||||
@ -75,7 +76,6 @@ static void f_of(char *);
|
||||
static void f_seek(char *);
|
||||
static void f_skip(char *);
|
||||
static void f_progress(char *);
|
||||
static u_long get_bsz(const char *);
|
||||
|
||||
static const struct arg {
|
||||
const char *name;
|
||||
@ -98,8 +98,6 @@ static const struct arg {
|
||||
{ "skip", f_skip, C_SKIP, C_SKIP },
|
||||
};
|
||||
|
||||
static char *oper;
|
||||
|
||||
/*
|
||||
* args -- parse JCL syntax of dd.
|
||||
*/
|
||||
@ -107,7 +105,7 @@ void
|
||||
jcl(char **argv)
|
||||
{
|
||||
struct arg *ap, tmp;
|
||||
char *arg;
|
||||
char *oper, *arg;
|
||||
|
||||
in.dbsz = out.dbsz = 512;
|
||||
|
||||
@ -153,8 +151,6 @@ jcl(char **argv)
|
||||
if (ddflags & (C_BLOCK|C_UNBLOCK)) {
|
||||
if (!(ddflags & C_CBS))
|
||||
errx(1, "record operations require cbs");
|
||||
if (cbsz == 0)
|
||||
errx(1, "cbs cannot be zero");
|
||||
cfunc = ddflags & C_BLOCK ? block : unblock;
|
||||
} else if (ddflags & C_CBS) {
|
||||
if (ddflags & (C_ASCII|C_EBCDIC)) {
|
||||
@ -168,20 +164,9 @@ jcl(char **argv)
|
||||
} else
|
||||
errx(1,
|
||||
"cbs meaningless if not doing record operations");
|
||||
if (cbsz == 0)
|
||||
errx(1, "cbs cannot be zero");
|
||||
} else
|
||||
cfunc = def;
|
||||
|
||||
if (in.dbsz == 0 || out.dbsz == 0)
|
||||
errx(1, "buffer sizes cannot be zero");
|
||||
|
||||
/*
|
||||
* Check to make sure that the buffers are not too large.
|
||||
*/
|
||||
if (in.dbsz > INT_MAX || out.dbsz > INT_MAX)
|
||||
errx(1, "buffer sizes cannot be greater than %d", INT_MAX);
|
||||
|
||||
/* Read, write and seek calls take off_t as arguments.
|
||||
*
|
||||
* The following check is not done because an off_t is a quad
|
||||
@ -204,21 +189,21 @@ static void
|
||||
f_bs(char *arg)
|
||||
{
|
||||
|
||||
in.dbsz = out.dbsz = (int)get_bsz(arg);
|
||||
in.dbsz = out.dbsz = strsuftoull("block size", arg, 1, UINT_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
f_cbs(char *arg)
|
||||
{
|
||||
|
||||
cbsz = (int)get_bsz(arg);
|
||||
cbsz = strsuftoull("conversion record size", arg, 1, UINT_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
f_count(char *arg)
|
||||
{
|
||||
|
||||
cpy_cnt = (u_int)get_bsz(arg);
|
||||
cpy_cnt = strsuftoull("block count", arg, 0, ULLONG_MAX);
|
||||
if (!cpy_cnt)
|
||||
terminate(0);
|
||||
}
|
||||
@ -227,7 +212,9 @@ static void
|
||||
f_files(char *arg)
|
||||
{
|
||||
|
||||
files_cnt = (int)get_bsz(arg);
|
||||
files_cnt = (u_int)strsuftoull("file count", arg, 0, UINT_MAX);
|
||||
if (!files_cnt)
|
||||
terminate(0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -235,7 +222,7 @@ f_ibs(char *arg)
|
||||
{
|
||||
|
||||
if (!(ddflags & C_BS))
|
||||
in.dbsz = (int)get_bsz(arg);
|
||||
in.dbsz = strsuftoull("input block size", arg, 1, UINT_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -250,7 +237,7 @@ f_obs(char *arg)
|
||||
{
|
||||
|
||||
if (!(ddflags & C_BS))
|
||||
out.dbsz = (int)get_bsz(arg);
|
||||
out.dbsz = strsuftoull("output block size", arg, 1, UINT_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -264,14 +251,14 @@ static void
|
||||
f_seek(char *arg)
|
||||
{
|
||||
|
||||
out.offset = (u_int)get_bsz(arg);
|
||||
out.offset = strsuftoull("seek blocks", arg, 0, ULLONG_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
f_skip(char *arg)
|
||||
{
|
||||
|
||||
in.offset = (u_int)get_bsz(arg);
|
||||
in.offset = strsuftoull("skip blocks", arg, 0, ULLONG_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -342,73 +329,3 @@ c_conv(const void *a, const void *b)
|
||||
}
|
||||
|
||||
#endif /* NO_CONV */
|
||||
|
||||
/*
|
||||
* Convert an expression of the following forms to an unsigned long.
|
||||
* 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 1048576).
|
||||
* 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).
|
||||
* separated by x (also * for backwards compatibility), specifying
|
||||
* the product of the indicated values.
|
||||
*/
|
||||
static u_long
|
||||
get_bsz(const char *val)
|
||||
{
|
||||
u_long num, t;
|
||||
char *expr;
|
||||
|
||||
num = strtoul(val, &expr, 0);
|
||||
if (num == ULONG_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_bsz(expr + 1);
|
||||
if (t > num)
|
||||
erange: errx(1, "%s: %s", oper, strerror(ERANGE));
|
||||
break;
|
||||
default:
|
||||
errx(1, "%s: illegal numeric value", oper);
|
||||
}
|
||||
return (num);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: conv.c,v 1.12 2001/11/25 06:53:48 lukem Exp $ */
|
||||
/* $NetBSD: conv.c,v 1.13 2001/11/25 10:50:06 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
@ -42,7 +42,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)conv.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: conv.c,v 1.12 2001/11/25 06:53:48 lukem Exp $");
|
||||
__RCSID("$NetBSD: conv.c,v 1.13 2001/11/25 10:50:06 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -64,7 +64,7 @@ __RCSID("$NetBSD: conv.c,v 1.12 2001/11/25 06:53:48 lukem Exp $");
|
||||
void
|
||||
def(void)
|
||||
{
|
||||
int cnt;
|
||||
u_longlong_t cnt;
|
||||
u_char *inp;
|
||||
const u_char *t;
|
||||
|
||||
@ -121,7 +121,7 @@ block(void)
|
||||
{
|
||||
static int intrunc;
|
||||
int ch = 0; /* pacify gcc */
|
||||
int cnt, maxlen;
|
||||
u_longlong_t cnt, maxlen;
|
||||
u_char *inp, *outp;
|
||||
const u_char *t;
|
||||
|
||||
@ -232,7 +232,7 @@ block_close(void)
|
||||
void
|
||||
unblock(void)
|
||||
{
|
||||
int cnt;
|
||||
u_longlong_t cnt;
|
||||
u_char *inp;
|
||||
const u_char *t;
|
||||
|
||||
@ -266,7 +266,7 @@ unblock(void)
|
||||
void
|
||||
unblock_close(void)
|
||||
{
|
||||
int cnt;
|
||||
u_longlong_t cnt;
|
||||
u_char *t;
|
||||
|
||||
if (in.dbcnt) {
|
||||
|
42
bin/dd/dd.1
42
bin/dd/dd.1
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: dd.1,v 1.10 2000/09/04 07:30:08 kleink Exp $
|
||||
.\" $NetBSD: dd.1,v 1.11 2001/11/25 10:50:06 lukem Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -36,7 +36,7 @@
|
||||
.\"
|
||||
.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
|
||||
.\"
|
||||
.Dd July 28, 1999
|
||||
.Dd November 25, 2001
|
||||
.Dt DD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -140,8 +140,11 @@ distinguishing between a partial or complete block being read.
|
||||
.It Cm progress= Ns Ar n
|
||||
Switch on display of progress if
|
||||
.Va n
|
||||
is set to ``1'', i.e. a ``.'' is printed for each
|
||||
block written to the output file.
|
||||
is set to
|
||||
.Dq 1 ,
|
||||
i.e. a
|
||||
.Dq \&.
|
||||
is printed for each block written to the output file.
|
||||
.It Xo
|
||||
.Cm conv=
|
||||
.Ns Cm value Ns Op \&, Cm value \&...
|
||||
@ -285,10 +288,24 @@ appended.
|
||||
.El
|
||||
.Pp
|
||||
Where sizes are specified, a decimal number of bytes is expected.
|
||||
If the number ends with a ``b'', ``k'', ``m'' or ``w'', the number
|
||||
is multiplied by 512, 1024 (1K), 1048576 (1M) or the number of bytes
|
||||
in an integer, respectively.
|
||||
Two or more numbers may be separated by an ``x'' to indicate a product.
|
||||
Two or more numbers may be separated by an
|
||||
.Dq x
|
||||
to indicate a product.
|
||||
Each number may have one of the following optional suffices:
|
||||
.Bl -tag -width 3n -offset indent -compact
|
||||
.It b
|
||||
Block; multiply by 512
|
||||
.It k
|
||||
Kilo; multiply by 1024 (1 KB)
|
||||
.It m
|
||||
Mega; multiply by 1048576 (1 MB)
|
||||
.It g
|
||||
Giga; multiply by 1073741824 (1 GB)
|
||||
.It t
|
||||
Tera; multiply by 1099511627776 (1 TB)
|
||||
.It w
|
||||
Word; multiply by the number of bytes in an integer
|
||||
.El
|
||||
.Pp
|
||||
When finished,
|
||||
.Nm
|
||||
@ -317,9 +334,12 @@ If
|
||||
.Nm
|
||||
receives a
|
||||
.Dv SIGINFO
|
||||
(see the ``status'' argument for
|
||||
.Xr stty 1 )
|
||||
signal, the current input and output block counts will
|
||||
signal
|
||||
(see the
|
||||
.Ic status
|
||||
argument for
|
||||
.Xr stty 1 ) ,
|
||||
the current input and output block counts will
|
||||
be written to the standard error output
|
||||
in the same format as the standard completion message.
|
||||
If
|
||||
|
29
bin/dd/dd.c
29
bin/dd/dd.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dd.c,v 1.22 2001/11/25 06:57:55 lukem Exp $ */
|
||||
/* $NetBSD: dd.c,v 1.23 2001/11/25 10:50:06 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
@ -47,7 +47,7 @@ __COPYRIGHT("@(#) Copyright (c) 1991, 1993, 1994\n\
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)dd.c 8.5 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: dd.c,v 1.22 2001/11/25 06:57:55 lukem Exp $");
|
||||
__RCSID("$NetBSD: dd.c,v 1.23 2001/11/25 10:50:06 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -77,16 +77,16 @@ static void setup(void);
|
||||
|
||||
int main(int, char *[]);
|
||||
|
||||
IO in, out; /* input/output state */
|
||||
STAT st; /* statistics */
|
||||
void (*cfunc)(void); /* conversion function */
|
||||
u_long 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 */
|
||||
int progress = 0; /* display sign of life */
|
||||
const u_char *ctab; /* conversion table */
|
||||
sigset_t infoset; /* a set blocking SIGINFO */
|
||||
IO in, out; /* input/output state */
|
||||
STAT st; /* statistics */
|
||||
void (*cfunc)(void); /* conversion function */
|
||||
u_longlong_t cpy_cnt; /* # of blocks to copy */
|
||||
u_int ddflags; /* conversion options */
|
||||
u_longlong_t cbsz; /* conversion block size */
|
||||
u_int files_cnt = 1; /* # of files to copy */
|
||||
int progress = 0; /* display sign of life */
|
||||
const u_char *ctab; /* conversion table */
|
||||
sigset_t infoset; /* a set blocking SIGINFO */
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
@ -243,7 +243,8 @@ getfdtype(IO *io)
|
||||
static void
|
||||
dd_in(void)
|
||||
{
|
||||
int flags, n;
|
||||
int flags;
|
||||
u_longlong_t n;
|
||||
|
||||
for (flags = ddflags;;) {
|
||||
if (cpy_cnt && (st.in_full + st.in_part) >= cpy_cnt)
|
||||
@ -364,7 +365,7 @@ void
|
||||
dd_out(int force)
|
||||
{
|
||||
static int warned;
|
||||
int cnt, n, nw;
|
||||
u_longlong_t cnt, n, nw;
|
||||
u_char *outp;
|
||||
|
||||
/*
|
||||
|
41
bin/dd/dd.h
41
bin/dd/dd.h
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dd.h,v 1.7 2001/11/25 06:53:48 lukem Exp $ */
|
||||
/* $NetBSD: dd.h,v 1.8 2001/11/25 10:50:06 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
@ -41,37 +41,32 @@
|
||||
|
||||
/* Input/output stream state. */
|
||||
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 */
|
||||
u_char *db; /* buffer address */
|
||||
u_char *dbp; /* current buffer I/O address */
|
||||
u_longlong_t dbcnt; /* current buffer byte count */
|
||||
u_longlong_t dbrcnt; /* last read byte count */
|
||||
u_longlong_t dbsz; /* buffer size */
|
||||
|
||||
#define ISCHR 0x01 /* character device (warn on short) */
|
||||
#define ISPIPE 0x02 /* pipe (not truncatable) */
|
||||
#define ISTAPE 0x04 /* tape (not seekable) */
|
||||
#define NOREAD 0x08 /* not readable */
|
||||
u_int flags;
|
||||
u_int flags;
|
||||
|
||||
const char *name; /* name */
|
||||
int fd; /* file descriptor */
|
||||
u_long 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 */
|
||||
const char *name; /* name */
|
||||
int fd; /* file descriptor */
|
||||
u_longlong_t offset; /* # of blocks to skip */
|
||||
} 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_quad_t bytes; /* # of bytes written */
|
||||
struct timeval start; /* start time of dd */
|
||||
u_longlong_t in_full; /* # of full input blocks */
|
||||
u_longlong_t in_part; /* # of partial input blocks */
|
||||
u_longlong_t out_full; /* # of full output blocks */
|
||||
u_longlong_t out_part; /* # of partial output blocks */
|
||||
u_longlong_t trunc; /* # of truncated records */
|
||||
u_longlong_t swab; /* # of odd-length swab blocks */
|
||||
u_longlong_t bytes; /* # of bytes written */
|
||||
struct timeval start; /* start time of dd */
|
||||
} STAT;
|
||||
|
||||
/* Flags (in ddflags). */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: extern.h,v 1.11 2001/11/25 06:53:48 lukem Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.12 2001/11/25 10:50:06 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
@ -56,16 +56,16 @@ void unblock(void);
|
||||
void unblock_close(void);
|
||||
ssize_t bwrite(int, const void *, size_t);
|
||||
|
||||
extern IO in, out;
|
||||
extern STAT st;
|
||||
extern void (*cfunc)(void);
|
||||
extern u_long cpy_cnt;
|
||||
extern u_int cbsz;
|
||||
extern u_int ddflags;
|
||||
extern u_int files_cnt;
|
||||
extern int progress;
|
||||
extern const u_char *ctab;
|
||||
extern const u_char a2e_32V[], a2e_POSIX[];
|
||||
extern const u_char e2a_32V[], e2a_POSIX[];
|
||||
extern const u_char a2ibm_32V[], a2ibm_POSIX[];
|
||||
extern u_char casetab[];
|
||||
extern IO in, out;
|
||||
extern STAT st;
|
||||
extern void (*cfunc)(void);
|
||||
extern u_longlong_t cpy_cnt;
|
||||
extern u_longlong_t cbsz;
|
||||
extern u_int ddflags;
|
||||
extern u_int files_cnt;
|
||||
extern int progress;
|
||||
extern const u_char *ctab;
|
||||
extern const u_char a2e_32V[], a2e_POSIX[];
|
||||
extern const u_char e2a_32V[], e2a_POSIX[];
|
||||
extern const u_char a2ibm_32V[], a2ibm_POSIX[];
|
||||
extern u_char casetab[];
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: misc.c,v 1.12 2001/11/25 06:53:48 lukem Exp $ */
|
||||
/* $NetBSD: misc.c,v 1.13 2001/11/25 10:50:06 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
@ -42,7 +42,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)misc.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: misc.c,v 1.12 2001/11/25 06:53:48 lukem Exp $");
|
||||
__RCSID("$NetBSD: misc.c,v 1.13 2001/11/25 10:50:06 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -77,25 +77,28 @@ summary(void)
|
||||
mS = 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",
|
||||
st.in_full, st.in_part, st.out_full, st.out_part);
|
||||
"%llu+%llu records in\n%llu+%llu records out\n",
|
||||
(unsigned long long)st.in_full, (unsigned long long)st.in_part,
|
||||
(unsigned long long)st.out_full, (unsigned long long)st.out_part);
|
||||
(void)write(STDERR_FILENO, buf, strlen(buf));
|
||||
if (st.swab) {
|
||||
(void)snprintf(buf, sizeof(buf), "%lu odd length swab %s\n",
|
||||
st.swab, (st.swab == 1) ? "block" : "blocks");
|
||||
(void)snprintf(buf, sizeof(buf), "%llu odd length swab %s\n",
|
||||
(unsigned long long)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",
|
||||
st.trunc, (st.trunc == 1) ? "block" : "blocks");
|
||||
(void)snprintf(buf, sizeof(buf), "%llu truncated %s\n",
|
||||
(unsigned long long)st.trunc,
|
||||
(st.trunc == 1) ? "block" : "blocks");
|
||||
(void)write(STDERR_FILENO, buf, strlen(buf));
|
||||
}
|
||||
(void)snprintf(buf, sizeof(buf),
|
||||
"%llu bytes transferred in %lu.%03d secs (%llu bytes/sec)\n",
|
||||
(long long) st.bytes,
|
||||
(unsigned long long) st.bytes,
|
||||
(long) (mS / 1000),
|
||||
(int) (mS % 1000),
|
||||
(long long unsigned) (st.bytes * 1000LL / mS));
|
||||
(unsigned long long) (st.bytes * 1000LL / mS));
|
||||
(void)write(STDERR_FILENO, buf, strlen(buf));
|
||||
}
|
||||
|
||||
|
226
bin/dd/strsuftoull.c
Normal file
226
bin/dd/strsuftoull.c
Normal file
@ -0,0 +1,226 @@
|
||||
/* $NetBSD: strsuftoull.c,v 1.1 2001/11/25 10:50:06 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego and Lance
|
||||
* Visser of Convex Computer Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Luke Mewburn.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: strsuftoull.c,v 1.1 2001/11/25 10:50:06 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "strsuftoull.h"
|
||||
|
||||
|
||||
/*
|
||||
* Convert an expression of the following forms to a u_longlong_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 1048576).
|
||||
* 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).
|
||||
* separated by x (also * for backwards compatibility), specifying
|
||||
* the product of the indicated values.
|
||||
* Returns the result upon successful conversion, or exits with an
|
||||
* appropriate error.
|
||||
*
|
||||
*/
|
||||
u_longlong_t
|
||||
strsuftoull(const char *desc, const char *val,
|
||||
u_longlong_t min, u_longlong_t max)
|
||||
{
|
||||
u_longlong_t result;
|
||||
char errbuf[100];
|
||||
|
||||
result = strsuftoullx(desc, val, min, max, errbuf, sizeof(errbuf));
|
||||
if (*errbuf != '\0')
|
||||
errx(1, "%s", errbuf);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* As strsuftoull(), but returns the error message into the provided buffer
|
||||
* rather than exiting with it.
|
||||
*/
|
||||
u_longlong_t
|
||||
strsuftoullx(const char *desc, const char *val,
|
||||
u_longlong_t min, u_longlong_t max, char *ebuf, size_t ebuflen)
|
||||
{
|
||||
u_longlong_t num, t;
|
||||
char *expr;
|
||||
|
||||
assert(desc != NULL);
|
||||
assert(val != NULL);
|
||||
assert(ebuf != NULL);
|
||||
|
||||
errno = 0;
|
||||
if (*val == '-') /* Prevent negative numbers */
|
||||
goto badnum;
|
||||
|
||||
num = strtoull(val, &expr, 0);
|
||||
if (num == LLONG_MAX && errno == ERANGE)
|
||||
goto erange; /* Overflow */
|
||||
|
||||
if (expr == val) /* No digits */
|
||||
goto badnum;
|
||||
|
||||
switch (*expr) {
|
||||
case 'b':
|
||||
t = num;
|
||||
num *= 512; /* 1 block */
|
||||
if (t > num)
|
||||
goto erange;
|
||||
++expr;
|
||||
break;
|
||||
case 'k':
|
||||
t = num;
|
||||
num *= 1024; /* 1 kilobyte */
|
||||
if (t > num)
|
||||
goto erange;
|
||||
++expr;
|
||||
break;
|
||||
case 'm':
|
||||
t = num;
|
||||
num *= 1048576; /* 1 megabyte */
|
||||
if (t > num)
|
||||
goto erange;
|
||||
++expr;
|
||||
break;
|
||||
case 'g':
|
||||
t = num;
|
||||
num *= 1073741824; /* 1 gigabyte */
|
||||
if (t > num)
|
||||
goto erange;
|
||||
++expr;
|
||||
break;
|
||||
case 't':
|
||||
t = num;
|
||||
num *= 1099511627776; /* 1 terabyte */
|
||||
if (t > num)
|
||||
goto erange;
|
||||
++expr;
|
||||
break;
|
||||
case 'w':
|
||||
t = num;
|
||||
num *= sizeof(int); /* 1 word */
|
||||
if (t > num)
|
||||
goto erange;
|
||||
++expr;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (*expr) {
|
||||
case '\0':
|
||||
break;
|
||||
case '*': /* Backward compatible */
|
||||
case 'x':
|
||||
t = num;
|
||||
num *= strsuftoullx(desc, expr + 1, min, max, ebuf, ebuflen);
|
||||
if (*ebuf != '\0')
|
||||
return (0);
|
||||
if (t > num) {
|
||||
erange:
|
||||
snprintf(ebuf, ebuflen,
|
||||
"%s: %s", desc, strerror(ERANGE));
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
badnum: snprintf(ebuf, ebuflen,
|
||||
"%s `%s': illegal positive number", desc, val);
|
||||
return (0);
|
||||
}
|
||||
if (num < min) {
|
||||
snprintf(ebuf, ebuflen,
|
||||
"%s %lld is less than %lld.", desc, num, min);
|
||||
return (0);
|
||||
}
|
||||
if (num > max) {
|
||||
snprintf(ebuf, ebuflen,
|
||||
"%s %lld is greater than %lld.", desc, num, max);
|
||||
return (0);
|
||||
}
|
||||
*ebuf = '\0';
|
||||
return (num);
|
||||
}
|
7
bin/dd/strsuftoull.h
Normal file
7
bin/dd/strsuftoull.h
Normal file
@ -0,0 +1,7 @@
|
||||
/* $NetBSD: strsuftoull.h,v 1.1 2001/11/25 10:50:06 lukem Exp $ */
|
||||
|
||||
u_longlong_t strsuftoull(const char *, const char *,
|
||||
u_longlong_t, u_longlong_t);
|
||||
|
||||
u_longlong_t strsuftoullx(const char *, const char *,
|
||||
u_longlong_t, u_longlong_t, char *, size_t);
|
Loading…
Reference in New Issue
Block a user