Importing bin/dd
Change-Id: Ibdfed821aa834419c9713dc80f698c8ed74ff269
This commit is contained in:
parent
9cf6cc5098
commit
c19d619d42
19 changed files with 2899 additions and 481 deletions
|
@ -1,7 +1,7 @@
|
||||||
# $NetBSD: Makefile,v 1.22 2007/12/31 15:31:24 ad Exp $
|
# $NetBSD: Makefile,v 1.22 2007/12/31 15:31:24 ad Exp $
|
||||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||||
|
|
||||||
SUBDIR= cat chmod cp date df echo ed expr hostname \
|
SUBDIR= cat chmod cp date dd df echo ed expr hostname \
|
||||||
kill ksh ln ls mkdir mv pax pwd rm rmdir sh \
|
kill ksh ln ls mkdir mv pax pwd rm rmdir sh \
|
||||||
sleep stty sync test
|
sleep stty sync test
|
||||||
|
|
||||||
|
|
21
bin/dd/Makefile
Normal file
21
bin/dd/Makefile
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# $NetBSD: Makefile,v 1.17 2012/08/08 14:09:14 christos Exp $
|
||||||
|
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||||
|
|
||||||
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
|
RUMPPRG=dd
|
||||||
|
SRCS= args.c conv.c dd.c misc.c position.c
|
||||||
|
|
||||||
|
DPADD+= ${LIBUTIL}
|
||||||
|
LDADD+= -lutil
|
||||||
|
|
||||||
|
.ifdef SMALLPROG
|
||||||
|
CPPFLAGS+= -DNO_CONV -DNO_MSGFMT -DSMALL
|
||||||
|
.else
|
||||||
|
SRCS+= conv_tab.c
|
||||||
|
.ifdef CRUNCHEDPROG
|
||||||
|
CPPFLAGS+= -DSMALL
|
||||||
|
.endif
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.include <bsd.prog.mk>
|
391
bin/dd/args.c
Normal file
391
bin/dd/args.c
Normal file
|
@ -0,0 +1,391 @@
|
||||||
|
/* $NetBSD: args.c,v 1.38 2013/07/17 12:55:48 christos 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. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#ifndef lint
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)args.c 8.3 (Berkeley) 4/2/94";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: args.c,v 1.38 2013/07/17 12:55:48 christos Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "dd.h"
|
||||||
|
#include "extern.h"
|
||||||
|
|
||||||
|
static int c_arg(const void *, const void *);
|
||||||
|
|
||||||
|
#ifdef NO_MSGFMT
|
||||||
|
static void f_msgfmt(char *) __dead;
|
||||||
|
#else
|
||||||
|
static void f_msgfmt(char *);
|
||||||
|
#endif /* NO_MSGFMT */
|
||||||
|
|
||||||
|
#ifdef NO_CONV
|
||||||
|
static void f_conv(char *) __dead;
|
||||||
|
#else
|
||||||
|
static void f_conv(char *);
|
||||||
|
static int c_conv(const void *, const void *);
|
||||||
|
#endif /* NO_CONV */
|
||||||
|
|
||||||
|
static void f_bs(char *);
|
||||||
|
static void f_cbs(char *);
|
||||||
|
static void f_count(char *);
|
||||||
|
static void f_files(char *);
|
||||||
|
static void f_ibs(char *);
|
||||||
|
static void f_if(char *);
|
||||||
|
static void f_obs(char *);
|
||||||
|
static void f_of(char *);
|
||||||
|
static void f_seek(char *);
|
||||||
|
static void f_skip(char *);
|
||||||
|
static void f_progress(char *);
|
||||||
|
|
||||||
|
static const struct arg {
|
||||||
|
const char *name;
|
||||||
|
void (*f)(char *);
|
||||||
|
u_int set, noset;
|
||||||
|
} args[] = {
|
||||||
|
/* the array needs to be sorted by the first column so
|
||||||
|
bsearch() can be used to find commands quickly */
|
||||||
|
{ "bs", f_bs, C_BS, C_BS|C_IBS|C_OBS|C_OSYNC },
|
||||||
|
{ "cbs", f_cbs, C_CBS, C_CBS },
|
||||||
|
{ "conv", f_conv, 0, 0 },
|
||||||
|
{ "count", f_count, C_COUNT, C_COUNT },
|
||||||
|
{ "files", f_files, C_FILES, C_FILES },
|
||||||
|
{ "ibs", f_ibs, C_IBS, C_BS|C_IBS },
|
||||||
|
{ "if", f_if, C_IF, C_IF },
|
||||||
|
{ "iseek", f_skip, C_SKIP, C_SKIP },
|
||||||
|
{ "msgfmt", f_msgfmt, 0, 0 },
|
||||||
|
{ "obs", f_obs, C_OBS, C_BS|C_OBS },
|
||||||
|
{ "of", f_of, C_OF, C_OF },
|
||||||
|
{ "oseek", f_seek, C_SEEK, C_SEEK },
|
||||||
|
{ "progress", f_progress, 0, 0 },
|
||||||
|
{ "seek", f_seek, C_SEEK, C_SEEK },
|
||||||
|
{ "skip", f_skip, C_SKIP, C_SKIP },
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* args -- parse JCL syntax of dd.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
jcl(char **argv)
|
||||||
|
{
|
||||||
|
struct arg *ap, tmp;
|
||||||
|
char *oper, *arg;
|
||||||
|
|
||||||
|
in.dbsz = out.dbsz = 512;
|
||||||
|
|
||||||
|
while ((oper = *++argv) != NULL) {
|
||||||
|
if ((oper = strdup(oper)) == NULL) {
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"unable to allocate space for the argument %s",
|
||||||
|
*argv);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
if ((arg = strchr(oper, '=')) == NULL) {
|
||||||
|
errx(EXIT_FAILURE, "unknown operand %s", oper);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
*arg++ = '\0';
|
||||||
|
if (!*arg) {
|
||||||
|
errx(EXIT_FAILURE, "no value specified for %s", oper);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
tmp.name = oper;
|
||||||
|
if (!(ap = bsearch(&tmp, args,
|
||||||
|
__arraycount(args), sizeof(*args), c_arg))) {
|
||||||
|
errx(EXIT_FAILURE, "unknown operand %s", tmp.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
if (ddflags & ap->noset) {
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"%s: illegal argument combination or already set",
|
||||||
|
tmp.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
ddflags |= ap->set;
|
||||||
|
ap->f(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Final sanity checks. */
|
||||||
|
|
||||||
|
if (ddflags & C_BS) {
|
||||||
|
/*
|
||||||
|
* Bs is turned off by any conversion -- we assume the user
|
||||||
|
* just wanted to set both the input and output block sizes
|
||||||
|
* and didn't want the bs semantics, so we don't warn.
|
||||||
|
*/
|
||||||
|
if (ddflags & (C_BLOCK | C_LCASE | C_SWAB | C_UCASE |
|
||||||
|
C_UNBLOCK | C_OSYNC | C_ASCII | C_EBCDIC | C_SPARSE)) {
|
||||||
|
ddflags &= ~C_BS;
|
||||||
|
ddflags |= C_IBS|C_OBS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bs supersedes ibs and obs. */
|
||||||
|
if (ddflags & C_BS && ddflags & (C_IBS|C_OBS))
|
||||||
|
warnx("bs supersedes ibs and obs");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ascii/ebcdic and cbs implies block/unblock.
|
||||||
|
* Block/unblock requires cbs and vice-versa.
|
||||||
|
*/
|
||||||
|
if (ddflags & (C_BLOCK|C_UNBLOCK)) {
|
||||||
|
if (!(ddflags & C_CBS)) {
|
||||||
|
errx(EXIT_FAILURE, "record operations require cbs");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
cfunc = ddflags & C_BLOCK ? block : unblock;
|
||||||
|
} else if (ddflags & C_CBS) {
|
||||||
|
if (ddflags & (C_ASCII|C_EBCDIC)) {
|
||||||
|
if (ddflags & C_ASCII) {
|
||||||
|
ddflags |= C_UNBLOCK;
|
||||||
|
cfunc = unblock;
|
||||||
|
} else {
|
||||||
|
ddflags |= C_BLOCK;
|
||||||
|
cfunc = block;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"cbs meaningless if not doing record operations");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
cfunc = def;
|
||||||
|
|
||||||
|
/* Read, write and seek calls take off_t as arguments.
|
||||||
|
*
|
||||||
|
* The following check is not done because an off_t is a quad
|
||||||
|
* for current NetBSD implementations.
|
||||||
|
*
|
||||||
|
* if (in.offset > INT_MAX/in.dbsz || out.offset > INT_MAX/out.dbsz)
|
||||||
|
* errx(1, "seek offsets cannot be larger than %d", INT_MAX);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
c_arg(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (strcmp(((const struct arg *)a)->name,
|
||||||
|
((const struct arg *)b)->name));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
f_bs(char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
in.dbsz = out.dbsz = strsuftoll("block size", arg, 1, UINT_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
f_cbs(char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
cbsz = strsuftoll("conversion record size", arg, 1, UINT_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
f_count(char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
cpy_cnt = strsuftoll("block count", arg, 0, LLONG_MAX);
|
||||||
|
if (!cpy_cnt)
|
||||||
|
terminate(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
f_files(char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
files_cnt = (u_int)strsuftoll("file count", arg, 0, UINT_MAX);
|
||||||
|
if (!files_cnt)
|
||||||
|
terminate(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
f_ibs(char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!(ddflags & C_BS))
|
||||||
|
in.dbsz = strsuftoll("input block size", arg, 1, UINT_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
f_if(char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
in.name = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NO_MSGFMT
|
||||||
|
/* Build a small version (i.e. for a ramdisk root) */
|
||||||
|
static void
|
||||||
|
f_msgfmt(char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
errx(EXIT_FAILURE, "msgfmt option disabled");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
#else /* NO_MSGFMT */
|
||||||
|
static void
|
||||||
|
f_msgfmt(char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the format string is not valid, dd_write_msg() will print
|
||||||
|
* an error and exit.
|
||||||
|
*/
|
||||||
|
dd_write_msg(arg, 0);
|
||||||
|
|
||||||
|
msgfmt = arg;
|
||||||
|
}
|
||||||
|
#endif /* NO_MSGFMT */
|
||||||
|
|
||||||
|
static void
|
||||||
|
f_obs(char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!(ddflags & C_BS))
|
||||||
|
out.dbsz = strsuftoll("output block size", arg, 1, UINT_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
f_of(char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
out.name = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
f_seek(char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
out.offset = strsuftoll("seek blocks", arg, 0, LLONG_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
f_skip(char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
in.offset = strsuftoll("skip blocks", arg, 0, LLONG_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
f_progress(char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
progress = strsuftoll("progress blocks", arg, 0, LLONG_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NO_CONV
|
||||||
|
/* Build a small version (i.e. for a ramdisk root) */
|
||||||
|
static void
|
||||||
|
f_conv(char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
errx(EXIT_FAILURE, "conv option disabled");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
#else /* NO_CONV */
|
||||||
|
|
||||||
|
static const struct conv {
|
||||||
|
const char *name;
|
||||||
|
u_int set, noset;
|
||||||
|
const u_char *ctab;
|
||||||
|
} clist[] = {
|
||||||
|
{ "ascii", C_ASCII, C_EBCDIC, e2a_POSIX },
|
||||||
|
{ "block", C_BLOCK, C_UNBLOCK, NULL },
|
||||||
|
{ "ebcdic", C_EBCDIC, C_ASCII, a2e_POSIX },
|
||||||
|
{ "ibm", C_EBCDIC, C_ASCII, a2ibm_POSIX },
|
||||||
|
{ "lcase", C_LCASE, C_UCASE, NULL },
|
||||||
|
{ "noerror", C_NOERROR, 0, NULL },
|
||||||
|
{ "notrunc", C_NOTRUNC, 0, NULL },
|
||||||
|
{ "oldascii", C_ASCII, C_EBCDIC, e2a_32V },
|
||||||
|
{ "oldebcdic", C_EBCDIC, C_ASCII, a2e_32V },
|
||||||
|
{ "oldibm", C_EBCDIC, C_ASCII, a2ibm_32V },
|
||||||
|
{ "osync", C_OSYNC, C_BS, NULL },
|
||||||
|
{ "sparse", C_SPARSE, 0, NULL },
|
||||||
|
{ "swab", C_SWAB, 0, NULL },
|
||||||
|
{ "sync", C_SYNC, 0, NULL },
|
||||||
|
{ "ucase", C_UCASE, C_LCASE, NULL },
|
||||||
|
{ "unblock", C_UNBLOCK, C_BLOCK, NULL },
|
||||||
|
/* If you add items to this table, be sure to add the
|
||||||
|
* conversions to the C_BS check in the jcl routine above.
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
f_conv(char *arg)
|
||||||
|
{
|
||||||
|
struct conv *cp, tmp;
|
||||||
|
|
||||||
|
while (arg != NULL) {
|
||||||
|
tmp.name = strsep(&arg, ",");
|
||||||
|
if (!(cp = bsearch(&tmp, clist,
|
||||||
|
__arraycount(clist), sizeof(*clist), c_conv))) {
|
||||||
|
errx(EXIT_FAILURE, "unknown conversion %s", tmp.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
if (ddflags & cp->noset) {
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"%s: illegal conversion combination", tmp.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
ddflags |= cp->set;
|
||||||
|
if (cp->ctab)
|
||||||
|
ctab = cp->ctab;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
c_conv(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (strcmp(((const struct conv *)a)->name,
|
||||||
|
((const struct conv *)b)->name));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* NO_CONV */
|
283
bin/dd/conv.c
Normal file
283
bin/dd/conv.c
Normal file
|
@ -0,0 +1,283 @@
|
||||||
|
/* $NetBSD: conv.c,v 1.17 2003/08/07 09:05:10 agc 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. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#ifndef lint
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)conv.c 8.3 (Berkeley) 4/2/94";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: conv.c,v 1.17 2003/08/07 09:05:10 agc Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "dd.h"
|
||||||
|
#include "extern.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* def --
|
||||||
|
* Copy input to output. Input is buffered until reaches obs, and then
|
||||||
|
* output until less than obs remains. Only a single buffer is used.
|
||||||
|
* Worst case buffer calculation is (ibs + obs - 1).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
def(void)
|
||||||
|
{
|
||||||
|
uint64_t cnt;
|
||||||
|
u_char *inp;
|
||||||
|
const u_char *t;
|
||||||
|
|
||||||
|
if ((t = ctab) != NULL)
|
||||||
|
for (inp = in.dbp - (cnt = in.dbrcnt); cnt--; ++inp)
|
||||||
|
*inp = t[*inp];
|
||||||
|
|
||||||
|
/* Make the output buffer look right. */
|
||||||
|
out.dbp = in.dbp;
|
||||||
|
out.dbcnt = in.dbcnt;
|
||||||
|
|
||||||
|
if (in.dbcnt >= out.dbsz) {
|
||||||
|
/* If the output buffer is full, write it. */
|
||||||
|
dd_out(0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ddout copies the leftover output to the beginning of
|
||||||
|
* the buffer and resets the output buffer. Reset the
|
||||||
|
* input buffer to match it.
|
||||||
|
*/
|
||||||
|
in.dbp = out.dbp;
|
||||||
|
in.dbcnt = out.dbcnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
def_close(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Just update the count, everything is already in the buffer. */
|
||||||
|
if (in.dbcnt)
|
||||||
|
out.dbcnt = in.dbcnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NO_CONV
|
||||||
|
/* Build a smaller version (i.e. for a miniroot) */
|
||||||
|
/* These can not be called, but just in case... */
|
||||||
|
static const char no_block[] = "unblock and -DNO_CONV?";
|
||||||
|
void block(void) { errx(EXIT_FAILURE, "%s", no_block + 2); }
|
||||||
|
void block_close(void) { errx(EXIT_FAILURE, "%s", no_block + 2); }
|
||||||
|
void unblock(void) { errx(EXIT_FAILURE, "%s", no_block); }
|
||||||
|
void unblock_close(void) { errx(EXIT_FAILURE, "%s", no_block); }
|
||||||
|
#else /* NO_CONV */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy variable length newline terminated records with a max size cbsz
|
||||||
|
* bytes to output. Records less than cbs are padded with spaces.
|
||||||
|
*
|
||||||
|
* max in buffer: MAX(ibs, cbsz)
|
||||||
|
* max out buffer: obs + cbsz
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
block(void)
|
||||||
|
{
|
||||||
|
static int intrunc;
|
||||||
|
int ch = 0; /* pacify gcc */
|
||||||
|
uint64_t cnt, maxlen;
|
||||||
|
u_char *inp, *outp;
|
||||||
|
const u_char *t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record truncation can cross block boundaries. If currently in a
|
||||||
|
* truncation state, keep tossing characters until reach a newline.
|
||||||
|
* Start at the beginning of the buffer, as the input buffer is always
|
||||||
|
* left empty.
|
||||||
|
*/
|
||||||
|
if (intrunc) {
|
||||||
|
for (inp = in.db, cnt = in.dbrcnt;
|
||||||
|
cnt && *inp++ != '\n'; --cnt);
|
||||||
|
if (!cnt) {
|
||||||
|
in.dbcnt = 0;
|
||||||
|
in.dbp = in.db;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
intrunc = 0;
|
||||||
|
/* Adjust the input buffer numbers. */
|
||||||
|
in.dbcnt = cnt - 1;
|
||||||
|
in.dbp = inp + cnt - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy records (max cbsz size chunks) into the output buffer. The
|
||||||
|
* translation is done as we copy into the output buffer.
|
||||||
|
*/
|
||||||
|
for (inp = in.dbp - in.dbcnt, outp = out.dbp; in.dbcnt;) {
|
||||||
|
maxlen = MIN(cbsz, in.dbcnt);
|
||||||
|
if ((t = ctab) != NULL)
|
||||||
|
for (cnt = 0;
|
||||||
|
cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)
|
||||||
|
*outp++ = t[ch];
|
||||||
|
else
|
||||||
|
for (cnt = 0;
|
||||||
|
cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)
|
||||||
|
*outp++ = ch;
|
||||||
|
/*
|
||||||
|
* Check for short record without a newline. Reassemble the
|
||||||
|
* input block.
|
||||||
|
*/
|
||||||
|
if (ch != '\n' && in.dbcnt < cbsz) {
|
||||||
|
(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust the input buffer numbers. */
|
||||||
|
in.dbcnt -= cnt;
|
||||||
|
if (ch == '\n')
|
||||||
|
--in.dbcnt;
|
||||||
|
|
||||||
|
/* Pad short records with spaces. */
|
||||||
|
if (cnt < cbsz)
|
||||||
|
(void)memset(outp, ctab ? ctab[' '] : ' ', cbsz - cnt);
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
* If the next character wouldn't have ended the
|
||||||
|
* block, it's a truncation.
|
||||||
|
*/
|
||||||
|
if (!in.dbcnt || *inp != '\n')
|
||||||
|
++st.trunc;
|
||||||
|
|
||||||
|
/* Toss characters to a newline. */
|
||||||
|
for (; in.dbcnt && *inp++ != '\n'; --in.dbcnt);
|
||||||
|
if (!in.dbcnt)
|
||||||
|
intrunc = 1;
|
||||||
|
else
|
||||||
|
--in.dbcnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust output buffer numbers. */
|
||||||
|
out.dbp += cbsz;
|
||||||
|
if ((out.dbcnt += cbsz) >= out.dbsz)
|
||||||
|
dd_out(0);
|
||||||
|
outp = out.dbp;
|
||||||
|
}
|
||||||
|
in.dbp = in.db + in.dbcnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
block_close(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy any remaining data into the output buffer and pad to a record.
|
||||||
|
* Don't worry about truncation or translation, the input buffer is
|
||||||
|
* always empty when truncating, and no characters have been added for
|
||||||
|
* translation. The bottom line is that anything left in the input
|
||||||
|
* buffer is a truncated record. Anything left in the output buffer
|
||||||
|
* just wasn't big enough.
|
||||||
|
*/
|
||||||
|
if (in.dbcnt) {
|
||||||
|
++st.trunc;
|
||||||
|
(void)memmove(out.dbp, in.dbp - in.dbcnt, in.dbcnt);
|
||||||
|
(void)memset(out.dbp + in.dbcnt,
|
||||||
|
ctab ? ctab[' '] : ' ', cbsz - in.dbcnt);
|
||||||
|
out.dbcnt += cbsz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert fixed length (cbsz) records to variable length. Deletes any
|
||||||
|
* trailing blanks and appends a newline.
|
||||||
|
*
|
||||||
|
* max in buffer: MAX(ibs, cbsz) + cbsz
|
||||||
|
* max out buffer: obs + cbsz
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
unblock(void)
|
||||||
|
{
|
||||||
|
uint64_t cnt;
|
||||||
|
u_char *inp;
|
||||||
|
const u_char *t;
|
||||||
|
|
||||||
|
/* Translation and case conversion. */
|
||||||
|
if ((t = ctab) != NULL)
|
||||||
|
for (cnt = in.dbrcnt, inp = in.dbp - 1; cnt--; inp--)
|
||||||
|
*inp = t[*inp];
|
||||||
|
/*
|
||||||
|
* Copy records (max cbsz size chunks) into the output buffer. The
|
||||||
|
* translation has to already be done or we might not recognize the
|
||||||
|
* spaces.
|
||||||
|
*/
|
||||||
|
for (inp = in.db; in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) {
|
||||||
|
for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t);
|
||||||
|
if (t >= inp) {
|
||||||
|
cnt = t - inp + 1;
|
||||||
|
(void)memmove(out.dbp, inp, cnt);
|
||||||
|
out.dbp += cnt;
|
||||||
|
out.dbcnt += cnt;
|
||||||
|
}
|
||||||
|
++out.dbcnt;
|
||||||
|
*out.dbp++ = '\n';
|
||||||
|
if (out.dbcnt >= out.dbsz)
|
||||||
|
dd_out(0);
|
||||||
|
}
|
||||||
|
if (in.dbcnt)
|
||||||
|
(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
|
||||||
|
in.dbp = in.db + in.dbcnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
unblock_close(void)
|
||||||
|
{
|
||||||
|
uint64_t cnt;
|
||||||
|
u_char *t;
|
||||||
|
|
||||||
|
if (in.dbcnt) {
|
||||||
|
warnx("%s: short input record", in.name);
|
||||||
|
for (t = in.db + in.dbcnt - 1; t >= in.db && *t == ' '; --t);
|
||||||
|
if (t >= in.db) {
|
||||||
|
cnt = t - in.db + 1;
|
||||||
|
(void)memmove(out.dbp, in.db, cnt);
|
||||||
|
out.dbp += cnt;
|
||||||
|
out.dbcnt += cnt;
|
||||||
|
}
|
||||||
|
++out.dbcnt;
|
||||||
|
*out.dbp++ = '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* NO_CONV */
|
287
bin/dd/conv_tab.c
Normal file
287
bin/dd/conv_tab.c
Normal file
|
@ -0,0 +1,287 @@
|
||||||
|
/* $NetBSD: conv_tab.c,v 1.9 2003/08/07 09:05:10 agc Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1991, 1993
|
||||||
|
* 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. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#ifndef lint
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)conv_tab.c 8.1 (Berkeley) 5/31/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: conv_tab.c,v 1.9 2003/08/07 09:05:10 agc Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are currently six tables:
|
||||||
|
*
|
||||||
|
* ebcdic -> ascii 32V conv=oldascii
|
||||||
|
* ascii -> ebcdic 32V conv=oldebcdic
|
||||||
|
* ascii -> ibm ebcdic 32V conv=oldibm
|
||||||
|
*
|
||||||
|
* ebcdic -> ascii POSIX/S5 conv=ascii
|
||||||
|
* ascii -> ebcdic POSIX/S5 conv=ebcdic
|
||||||
|
* ascii -> ibm ebcdic POSIX/S5 conv=ibm
|
||||||
|
*
|
||||||
|
* Other tables are built from these if multiple conversions are being
|
||||||
|
* done.
|
||||||
|
*
|
||||||
|
* Tables used for conversions to/from IBM and EBCDIC to support an extension
|
||||||
|
* to POSIX P1003.2/D11. The tables referencing POSIX contain data extracted
|
||||||
|
* from tables 4-3 and 4-4 in P1003.2/Draft 11. The historic tables were
|
||||||
|
* constructed by running against a file with all possible byte values.
|
||||||
|
*
|
||||||
|
* More information can be obtained in "Correspondences of 8-Bit and Hollerith
|
||||||
|
* Codes for Computer Environments-A USASI Tutorial", Communications of the
|
||||||
|
* ACM, Volume 11, Number 11, November 1968, pp. 783-789.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u_char casetab[256];
|
||||||
|
|
||||||
|
/* EBCDIC to ASCII -- 32V compatible. */
|
||||||
|
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 */
|
||||||
|
0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037, /* 0030 */
|
||||||
|
0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033, /* 0040 */
|
||||||
|
0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007, /* 0050 */
|
||||||
|
0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004, /* 0060 */
|
||||||
|
0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032, /* 0070 */
|
||||||
|
0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246, /* 0100 */
|
||||||
|
0247, 0250, 0133, 0056, 0074, 0050, 0053, 0041, /* 0110 */
|
||||||
|
0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257, /* 0120 */
|
||||||
|
0260, 0261, 0135, 0044, 0052, 0051, 0073, 0136, /* 0130 */
|
||||||
|
0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267, /* 0140 */
|
||||||
|
0270, 0271, 0174, 0054, 0045, 0137, 0076, 0077, /* 0150 */
|
||||||
|
0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301, /* 0160 */
|
||||||
|
0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042, /* 0170 */
|
||||||
|
0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147, /* 0200 */
|
||||||
|
0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311, /* 0210 */
|
||||||
|
0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160, /* 0220 */
|
||||||
|
0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320, /* 0230 */
|
||||||
|
0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170, /* 0240 */
|
||||||
|
0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327, /* 0250 */
|
||||||
|
0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337, /* 0260 */
|
||||||
|
0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347, /* 0270 */
|
||||||
|
0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107, /* 0300 */
|
||||||
|
0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355, /* 0310 */
|
||||||
|
0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120, /* 0320 */
|
||||||
|
0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363, /* 0330 */
|
||||||
|
0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130, /* 0340 */
|
||||||
|
0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371, /* 0350 */
|
||||||
|
0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067, /* 0360 */
|
||||||
|
0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ASCII to EBCDIC -- 32V compatible. */
|
||||||
|
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 */
|
||||||
|
0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037, /* 0030 */
|
||||||
|
0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175, /* 0040 */
|
||||||
|
0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141, /* 0050 */
|
||||||
|
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, /* 0060 */
|
||||||
|
0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157, /* 0070 */
|
||||||
|
0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307, /* 0100 */
|
||||||
|
0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326, /* 0110 */
|
||||||
|
0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346, /* 0120 */
|
||||||
|
0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155, /* 0130 */
|
||||||
|
0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207, /* 0140 */
|
||||||
|
0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226, /* 0150 */
|
||||||
|
0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246, /* 0160 */
|
||||||
|
0247, 0250, 0251, 0300, 0152, 0320, 0241, 0007, /* 0170 */
|
||||||
|
0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027, /* 0200 */
|
||||||
|
0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033, /* 0210 */
|
||||||
|
0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010, /* 0220 */
|
||||||
|
0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341, /* 0230 */
|
||||||
|
0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, /* 0240 */
|
||||||
|
0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127, /* 0250 */
|
||||||
|
0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147, /* 0260 */
|
||||||
|
0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165, /* 0270 */
|
||||||
|
0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215, /* 0300 */
|
||||||
|
0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236, /* 0310 */
|
||||||
|
0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257, /* 0320 */
|
||||||
|
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, /* 0330 */
|
||||||
|
0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277, /* 0340 */
|
||||||
|
0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333, /* 0350 */
|
||||||
|
0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355, /* 0360 */
|
||||||
|
0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ASCII to IBM EBCDIC -- 32V compatible. */
|
||||||
|
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 */
|
||||||
|
0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037, /* 0030 */
|
||||||
|
0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175, /* 0040 */
|
||||||
|
0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141, /* 0050 */
|
||||||
|
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, /* 0060 */
|
||||||
|
0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157, /* 0070 */
|
||||||
|
0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307, /* 0100 */
|
||||||
|
0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326, /* 0110 */
|
||||||
|
0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346, /* 0120 */
|
||||||
|
0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155, /* 0130 */
|
||||||
|
0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207, /* 0140 */
|
||||||
|
0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226, /* 0150 */
|
||||||
|
0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246, /* 0160 */
|
||||||
|
0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007, /* 0170 */
|
||||||
|
0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027, /* 0200 */
|
||||||
|
0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033, /* 0210 */
|
||||||
|
0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010, /* 0220 */
|
||||||
|
0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341, /* 0230 */
|
||||||
|
0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, /* 0240 */
|
||||||
|
0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127, /* 0250 */
|
||||||
|
0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147, /* 0260 */
|
||||||
|
0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165, /* 0270 */
|
||||||
|
0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215, /* 0300 */
|
||||||
|
0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236, /* 0310 */
|
||||||
|
0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257, /* 0320 */
|
||||||
|
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, /* 0330 */
|
||||||
|
0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277, /* 0340 */
|
||||||
|
0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333, /* 0350 */
|
||||||
|
0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355, /* 0360 */
|
||||||
|
0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* EBCDIC to ASCII -- POSIX and System V compatible. */
|
||||||
|
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 */
|
||||||
|
0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037, /* 0030 */
|
||||||
|
0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033, /* 0040 */
|
||||||
|
0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007, /* 0050 */
|
||||||
|
0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004, /* 0060 */
|
||||||
|
0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032, /* 0070 */
|
||||||
|
0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246, /* 0100 */
|
||||||
|
0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174, /* 0110 */
|
||||||
|
0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257, /* 0120 */
|
||||||
|
0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176, /* 0130 */
|
||||||
|
0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267, /* 0140 */
|
||||||
|
0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077, /* 0150 */
|
||||||
|
0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301, /* 0160 */
|
||||||
|
0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042, /* 0170 */
|
||||||
|
0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147, /* 0200 */
|
||||||
|
0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311, /* 0210 */
|
||||||
|
0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160, /* 0220 */
|
||||||
|
0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320, /* 0230 */
|
||||||
|
0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170, /* 0240 */
|
||||||
|
0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327, /* 0250 */
|
||||||
|
0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337, /* 0260 */
|
||||||
|
0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347, /* 0270 */
|
||||||
|
0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107, /* 0300 */
|
||||||
|
0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355, /* 0310 */
|
||||||
|
0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120, /* 0320 */
|
||||||
|
0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363, /* 0330 */
|
||||||
|
0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130, /* 0340 */
|
||||||
|
0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371, /* 0350 */
|
||||||
|
0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067, /* 0360 */
|
||||||
|
0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ASCII to EBCDIC -- POSIX and System V compatible. */
|
||||||
|
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 */
|
||||||
|
0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037, /* 0030 */
|
||||||
|
0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175, /* 0040 */
|
||||||
|
0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141, /* 0050 */
|
||||||
|
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, /* 0060 */
|
||||||
|
0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157, /* 0070 */
|
||||||
|
0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307, /* 0100 */
|
||||||
|
0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326, /* 0110 */
|
||||||
|
0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346, /* 0120 */
|
||||||
|
0347, 0350, 0351, 0255, 0340, 0275, 0232, 0155, /* 0130 */
|
||||||
|
0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207, /* 0140 */
|
||||||
|
0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226, /* 0150 */
|
||||||
|
0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246, /* 0160 */
|
||||||
|
0247, 0250, 0251, 0300, 0117, 0320, 0137, 0007, /* 0170 */
|
||||||
|
0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027, /* 0200 */
|
||||||
|
0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033, /* 0210 */
|
||||||
|
0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010, /* 0220 */
|
||||||
|
0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341, /* 0230 */
|
||||||
|
0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, /* 0240 */
|
||||||
|
0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127, /* 0250 */
|
||||||
|
0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147, /* 0260 */
|
||||||
|
0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165, /* 0270 */
|
||||||
|
0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215, /* 0300 */
|
||||||
|
0216, 0217, 0220, 0152, 0233, 0234, 0235, 0236, /* 0310 */
|
||||||
|
0237, 0240, 0252, 0253, 0254, 0112, 0256, 0257, /* 0320 */
|
||||||
|
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, /* 0330 */
|
||||||
|
0270, 0271, 0272, 0273, 0274, 0241, 0276, 0277, /* 0340 */
|
||||||
|
0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333, /* 0350 */
|
||||||
|
0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355, /* 0360 */
|
||||||
|
0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ASCII to IBM EBCDIC -- POSIX and System V compatible. */
|
||||||
|
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 */
|
||||||
|
0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037, /* 0030 */
|
||||||
|
0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175, /* 0040 */
|
||||||
|
0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141, /* 0050 */
|
||||||
|
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, /* 0060 */
|
||||||
|
0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157, /* 0070 */
|
||||||
|
0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307, /* 0100 */
|
||||||
|
0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326, /* 0110 */
|
||||||
|
0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346, /* 0120 */
|
||||||
|
0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155, /* 0130 */
|
||||||
|
0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207, /* 0140 */
|
||||||
|
0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226, /* 0150 */
|
||||||
|
0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246, /* 0160 */
|
||||||
|
0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007, /* 0170 */
|
||||||
|
0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027, /* 0200 */
|
||||||
|
0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033, /* 0210 */
|
||||||
|
0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010, /* 0220 */
|
||||||
|
0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341, /* 0230 */
|
||||||
|
0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, /* 0240 */
|
||||||
|
0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127, /* 0250 */
|
||||||
|
0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147, /* 0260 */
|
||||||
|
0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165, /* 0270 */
|
||||||
|
0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215, /* 0300 */
|
||||||
|
0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236, /* 0310 */
|
||||||
|
0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257, /* 0320 */
|
||||||
|
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, /* 0330 */
|
||||||
|
0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277, /* 0340 */
|
||||||
|
0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333, /* 0350 */
|
||||||
|
0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355, /* 0360 */
|
||||||
|
0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
|
||||||
|
};
|
477
bin/dd/dd.1
Normal file
477
bin/dd/dd.1
Normal file
|
@ -0,0 +1,477 @@
|
||||||
|
.\" $NetBSD: dd.1,v 1.25 2012/06/20 17:54:16 wiz Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 1990, 1993
|
||||||
|
.\" 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.
|
||||||
|
.\"
|
||||||
|
.\" 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. 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.
|
||||||
|
.\"
|
||||||
|
.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
|
||||||
|
.\"
|
||||||
|
.Dd November 6, 2011
|
||||||
|
.Dt DD 1
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm dd
|
||||||
|
.Nd convert and copy a file
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Op operand ...
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility copies the standard input to the standard output.
|
||||||
|
Input data is read and written in 512-byte blocks.
|
||||||
|
If input reads are short, input from multiple reads are aggregated
|
||||||
|
to form the output block.
|
||||||
|
When finished,
|
||||||
|
.Nm
|
||||||
|
displays the number of complete and partial input and output blocks
|
||||||
|
and truncated input records to the standard error output.
|
||||||
|
.Pp
|
||||||
|
The following operands are available:
|
||||||
|
.Bl -tag -width of=file
|
||||||
|
.It Cm bs= Ns Ar n
|
||||||
|
Set both input and output block size, superseding the
|
||||||
|
.Cm ibs
|
||||||
|
and
|
||||||
|
.Cm obs
|
||||||
|
operands.
|
||||||
|
If no conversion values other than
|
||||||
|
.Cm noerror ,
|
||||||
|
.Cm notrunc
|
||||||
|
or
|
||||||
|
.Cm sync
|
||||||
|
are specified, then each input block is copied to the output as a
|
||||||
|
single block without any aggregation of short blocks.
|
||||||
|
.It Cm cbs= Ns Ar n
|
||||||
|
Set the conversion record size to
|
||||||
|
.Va n
|
||||||
|
bytes.
|
||||||
|
The conversion record size is required by the record oriented conversion
|
||||||
|
values.
|
||||||
|
.It Cm count= Ns Ar n
|
||||||
|
Copy only
|
||||||
|
.Va n
|
||||||
|
input blocks.
|
||||||
|
.It Cm files= Ns Ar n
|
||||||
|
Copy
|
||||||
|
.Va n
|
||||||
|
input files before terminating.
|
||||||
|
This operand is only applicable when the input device is a tape.
|
||||||
|
.It Cm ibs= Ns Ar n
|
||||||
|
Set the input block size to
|
||||||
|
.Va n
|
||||||
|
bytes instead of the default 512.
|
||||||
|
.It Cm if= Ns Ar file
|
||||||
|
Read input from
|
||||||
|
.Ar file
|
||||||
|
instead of the standard input.
|
||||||
|
.It Cm iseek= Ns Ar n
|
||||||
|
Seek on the input file
|
||||||
|
.Ar n
|
||||||
|
blocks.
|
||||||
|
This is synonymous with
|
||||||
|
.Cm skip= Ns Ar n .
|
||||||
|
.It Cm msgfmt= Ns Ar fmt
|
||||||
|
Specify the message format
|
||||||
|
.Ar fmt
|
||||||
|
to be used when writing information to standard output.
|
||||||
|
Possible values are:
|
||||||
|
.Bl -tag -width xxxxx -offset indent -compact
|
||||||
|
.It quiet
|
||||||
|
turns off information summary report except for errors and
|
||||||
|
.Cm progress .
|
||||||
|
.It posix
|
||||||
|
default information summary report as specified by POSIX.
|
||||||
|
.It human
|
||||||
|
default information summary report extended with human-readable
|
||||||
|
values.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
When
|
||||||
|
.Ar fmt
|
||||||
|
does not correspond to any value given above,
|
||||||
|
it contains a string that will be used as format specifier
|
||||||
|
for the information summary output.
|
||||||
|
Each conversion specification is introduced by the character
|
||||||
|
.Cm % .
|
||||||
|
The following ones are available:
|
||||||
|
.Bl -tag -width xx -offset indent -compact
|
||||||
|
.It b
|
||||||
|
total number of bytes transferred
|
||||||
|
.It B
|
||||||
|
total number of bytes transferred in
|
||||||
|
.Xr humanize_number 3
|
||||||
|
format
|
||||||
|
.It e
|
||||||
|
speed transfer
|
||||||
|
.It E
|
||||||
|
speed transfer in
|
||||||
|
.Xr humanize_number 3
|
||||||
|
format
|
||||||
|
.It i
|
||||||
|
number of partial input block(s)
|
||||||
|
.It I
|
||||||
|
number of full input block(s)
|
||||||
|
.It o
|
||||||
|
number of partial output block(s)
|
||||||
|
.It O
|
||||||
|
number of full output block(s)
|
||||||
|
.It s
|
||||||
|
time elapsed since the beginning in
|
||||||
|
.Do seconds.ms Dc
|
||||||
|
format
|
||||||
|
.It p
|
||||||
|
number of sparse output blocks
|
||||||
|
.It t
|
||||||
|
number of truncated blocks
|
||||||
|
.It w
|
||||||
|
number of odd-length swab blocks
|
||||||
|
.It P
|
||||||
|
singular/plural of
|
||||||
|
.Do block Dc
|
||||||
|
depending on number of sparse blocks
|
||||||
|
.It T
|
||||||
|
singular/plural of
|
||||||
|
.Do block Dc
|
||||||
|
depending on number of truncated blocks
|
||||||
|
.It W
|
||||||
|
singular/plural of
|
||||||
|
.Do block Dc
|
||||||
|
depending on number of swab blocks
|
||||||
|
.El
|
||||||
|
.It Cm obs= Ns Ar n
|
||||||
|
Set the output block size to
|
||||||
|
.Va n
|
||||||
|
bytes instead of the default 512.
|
||||||
|
.It Cm of= Ns Ar file
|
||||||
|
Write output to
|
||||||
|
.Ar file
|
||||||
|
instead of the standard output.
|
||||||
|
Any regular output file is truncated unless the
|
||||||
|
.Cm notrunc
|
||||||
|
conversion value is specified.
|
||||||
|
If an initial portion of the output file is skipped (see the
|
||||||
|
.Cm seek
|
||||||
|
operand)
|
||||||
|
the output file is truncated at that point.
|
||||||
|
.It Cm oseek= Ns Ar n
|
||||||
|
Seek on the output file
|
||||||
|
.Ar n
|
||||||
|
blocks.
|
||||||
|
This is synonymous with
|
||||||
|
.Cm seek= Ns Ar n .
|
||||||
|
.It Cm seek= Ns Ar n
|
||||||
|
Seek
|
||||||
|
.Va n
|
||||||
|
blocks from the beginning of the output before copying.
|
||||||
|
On non-tape devices, an
|
||||||
|
.Xr lseek 2
|
||||||
|
operation is used.
|
||||||
|
Otherwise, existing blocks are read and the data discarded.
|
||||||
|
If the user does not have read permission for the tape, it is positioned
|
||||||
|
using the tape
|
||||||
|
.Xr ioctl 2
|
||||||
|
function calls.
|
||||||
|
If the seek operation is past the end of file, space from the current
|
||||||
|
end of file to the specified offset is filled with blocks of
|
||||||
|
.Tn NUL
|
||||||
|
bytes.
|
||||||
|
.It Cm skip= Ns Ar n
|
||||||
|
Skip
|
||||||
|
.Va n
|
||||||
|
blocks from the beginning of the input before copying.
|
||||||
|
On input which supports seeks, an
|
||||||
|
.Xr lseek 2
|
||||||
|
operation is used.
|
||||||
|
Otherwise, input data is read and discarded.
|
||||||
|
For pipes, the correct number of bytes is read.
|
||||||
|
For all other devices, the correct number of blocks is read without
|
||||||
|
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 any non-zero value.
|
||||||
|
This will cause a
|
||||||
|
.Dq \&.
|
||||||
|
to be printed (to the standard error output) for every
|
||||||
|
.Va n
|
||||||
|
full or partial blocks written to the output file.
|
||||||
|
.Sm off
|
||||||
|
.It Cm conv= Cm value Op \&, Cm value \&...
|
||||||
|
.Sm on
|
||||||
|
Where
|
||||||
|
.Cm value
|
||||||
|
is one of the symbols from the following list.
|
||||||
|
.Bl -tag -width unblock
|
||||||
|
.It Cm ascii , oldascii
|
||||||
|
The same as the
|
||||||
|
.Cm unblock
|
||||||
|
value except that characters are translated from
|
||||||
|
.Tn EBCDIC
|
||||||
|
to
|
||||||
|
.Tn ASCII
|
||||||
|
before the
|
||||||
|
records are converted.
|
||||||
|
(These values imply
|
||||||
|
.Cm unblock
|
||||||
|
if the operand
|
||||||
|
.Cm cbs
|
||||||
|
is also specified.)
|
||||||
|
There are two conversion maps for
|
||||||
|
.Tn ASCII .
|
||||||
|
The value
|
||||||
|
.Cm ascii
|
||||||
|
specifies the recommended one which is compatible with
|
||||||
|
.At V .
|
||||||
|
The value
|
||||||
|
.Cm oldascii
|
||||||
|
specifies the one used in historic
|
||||||
|
.Tn AT\*[Am]T
|
||||||
|
and pre-
|
||||||
|
.Bx 4.3 Reno
|
||||||
|
systems.
|
||||||
|
.It Cm block
|
||||||
|
Treats the input as a sequence of newline or end-of-file terminated variable
|
||||||
|
length records independent of input and output block boundaries.
|
||||||
|
Any trailing newline character is discarded.
|
||||||
|
Each input record is converted to a fixed length output record where the
|
||||||
|
length is specified by the
|
||||||
|
.Cm cbs
|
||||||
|
operand.
|
||||||
|
Input records shorter than the conversion record size are padded with spaces.
|
||||||
|
Input records longer than the conversion record size are truncated.
|
||||||
|
The number of truncated input records, if any, are reported to the standard
|
||||||
|
error output at the completion of the copy.
|
||||||
|
.It Cm ebcdic , ibm , oldebcdic , oldibm
|
||||||
|
The same as the
|
||||||
|
.Cm block
|
||||||
|
value except that characters are translated from
|
||||||
|
.Tn ASCII
|
||||||
|
to
|
||||||
|
.Tn EBCDIC
|
||||||
|
after the
|
||||||
|
records are converted.
|
||||||
|
(These values imply
|
||||||
|
.Cm block
|
||||||
|
if the operand
|
||||||
|
.Cm cbs
|
||||||
|
is also specified.)
|
||||||
|
There are four conversion maps for
|
||||||
|
.Tn EBCDIC .
|
||||||
|
The value
|
||||||
|
.Cm ebcdic
|
||||||
|
specifies the recommended one which is compatible with
|
||||||
|
.At V .
|
||||||
|
The value
|
||||||
|
.Cm ibm
|
||||||
|
is a slightly different mapping, which is compatible with the
|
||||||
|
.At V
|
||||||
|
.Cm ibm
|
||||||
|
value.
|
||||||
|
The values
|
||||||
|
.Cm oldebcdic
|
||||||
|
and
|
||||||
|
.Cm oldibm
|
||||||
|
are maps used in historic
|
||||||
|
.Tn AT\*[Am]T
|
||||||
|
and pre
|
||||||
|
.Bx 4.3 Reno
|
||||||
|
systems.
|
||||||
|
.It Cm lcase
|
||||||
|
Transform uppercase characters into lowercase characters.
|
||||||
|
.It Cm noerror
|
||||||
|
Do not stop processing on an input error.
|
||||||
|
When an input error occurs, a diagnostic message followed by 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 the
|
||||||
|
.Cm sync
|
||||||
|
conversion is also specified, any missing input data will be replaced
|
||||||
|
with
|
||||||
|
.Tn NUL
|
||||||
|
bytes (or with spaces if a block oriented conversion value was
|
||||||
|
specified) and processed as a normal input buffer.
|
||||||
|
If the
|
||||||
|
.Cm sync
|
||||||
|
conversion is not specified, the input block is omitted from the output.
|
||||||
|
On input files which are not tapes or pipes, the file offset
|
||||||
|
will be positioned past the block in which the error occurred using
|
||||||
|
.Xr lseek 2 .
|
||||||
|
.It Cm notrunc
|
||||||
|
Do not truncate the output file.
|
||||||
|
This will preserve any blocks in the output file not explicitly written
|
||||||
|
by
|
||||||
|
.Nm .
|
||||||
|
The
|
||||||
|
.Cm notrunc
|
||||||
|
value is not supported for tapes.
|
||||||
|
.It Cm osync
|
||||||
|
Pad the final output block to the full output block size.
|
||||||
|
If the input file is not a multiple of the output block size
|
||||||
|
after conversion, this conversion forces the final output block
|
||||||
|
to be the same size as preceding blocks for use on devices that require
|
||||||
|
regularly sized blocks to be written.
|
||||||
|
This option is incompatible with use of the
|
||||||
|
.Cm bs= Ns Ar n
|
||||||
|
block size specification.
|
||||||
|
.It Cm sparse
|
||||||
|
If one or more non-final output blocks would consist solely of
|
||||||
|
.Dv NUL
|
||||||
|
bytes, try to seek the output file by the required space instead of
|
||||||
|
filling them with
|
||||||
|
.Dv NUL Ns s .
|
||||||
|
This results in a sparse file on some file systems.
|
||||||
|
.It Cm swab
|
||||||
|
Swap every pair of input bytes.
|
||||||
|
If an input buffer has an odd number of bytes, the last byte will be
|
||||||
|
ignored during swapping.
|
||||||
|
.It Cm sync
|
||||||
|
Pad every input block to the input buffer size.
|
||||||
|
Spaces are used for pad bytes if a block oriented conversion value is
|
||||||
|
specified, otherwise
|
||||||
|
.Tn NUL
|
||||||
|
bytes are used.
|
||||||
|
.It Cm ucase
|
||||||
|
Transform lowercase characters into uppercase characters.
|
||||||
|
.It Cm unblock
|
||||||
|
Treats the input as a sequence of fixed length records independent of input
|
||||||
|
and output block boundaries.
|
||||||
|
The length of the input records is specified by the
|
||||||
|
.Cm cbs
|
||||||
|
operand.
|
||||||
|
Any trailing space characters are discarded and a newline character is
|
||||||
|
appended.
|
||||||
|
.El
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Where sizes are specified, a decimal number of bytes is expected.
|
||||||
|
Two or more numbers may be separated by an
|
||||||
|
.Dq x
|
||||||
|
to indicate a product.
|
||||||
|
Each number may have one of the following optional suffixes:
|
||||||
|
.Bl -tag -width 3n -offset indent -compact
|
||||||
|
.It b
|
||||||
|
Block; multiply by 512
|
||||||
|
.It k
|
||||||
|
Kibi; multiply by 1024 (1 KiB)
|
||||||
|
.It m
|
||||||
|
Mebi; multiply by 1048576 (1 MiB)
|
||||||
|
.It g
|
||||||
|
Gibi; multiply by 1073741824 (1 GiB)
|
||||||
|
.It t
|
||||||
|
Tebi; multiply by 1099511627776 (1 TiB)
|
||||||
|
.It w
|
||||||
|
Word; multiply by the number of bytes in an integer
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
When finished,
|
||||||
|
.Nm
|
||||||
|
displays the number of complete and partial input and output blocks,
|
||||||
|
truncated input records and odd-length byte-swapping blocks to the
|
||||||
|
standard error output.
|
||||||
|
A partial input block is one where less than the input block size
|
||||||
|
was read.
|
||||||
|
A partial output block is one where less than the output block size
|
||||||
|
was written.
|
||||||
|
Partial output blocks to tape devices are considered fatal errors.
|
||||||
|
Otherwise, the rest of the block will be written.
|
||||||
|
Partial output blocks to character devices will produce a warning message.
|
||||||
|
A truncated input block is one where a variable length record oriented
|
||||||
|
conversion value was specified and the input line was too long to
|
||||||
|
fit in the conversion record or was not newline terminated.
|
||||||
|
.Pp
|
||||||
|
Normally, data resulting from input or conversion or both are aggregated
|
||||||
|
into output blocks of the specified size.
|
||||||
|
After the end of input is reached, any remaining output is written as
|
||||||
|
a block.
|
||||||
|
This means that the final output block may be shorter than the output
|
||||||
|
block size.
|
||||||
|
.Pp
|
||||||
|
If
|
||||||
|
.Nm
|
||||||
|
receives a
|
||||||
|
.Dv SIGINFO
|
||||||
|
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
|
||||||
|
.Nm
|
||||||
|
receives a
|
||||||
|
.Dv SIGINT
|
||||||
|
signal, the current input and output block counts will
|
||||||
|
be written to the standard error output
|
||||||
|
in the same format as the standard completion message and
|
||||||
|
.Nm
|
||||||
|
will exit.
|
||||||
|
.Sh EXIT STATUS
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility exits 0 on success and \*[Gt]0 if an error occurred.
|
||||||
|
.Sh EXAMPLES
|
||||||
|
To print summary information in human-readable form:
|
||||||
|
.Pp
|
||||||
|
.Dl dd if=/dev/zero of=/dev/null count=1 msgfmt=human
|
||||||
|
.Pp
|
||||||
|
To customize the information summary output and print it through
|
||||||
|
.Xr unvis 3 :
|
||||||
|
.Pp
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
dd if=/dev/zero of=/dev/null count=1 \e
|
||||||
|
msgfmt='speed:%E, in %s seconds\en' 2\*[Gt]\*[Am]1 | unvis
|
||||||
|
.Ed
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr cp 1 ,
|
||||||
|
.Xr mt 1 ,
|
||||||
|
.Xr tr 1
|
||||||
|
.Sh STANDARDS
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility is expected to be a superset of the
|
||||||
|
.St -p1003.2
|
||||||
|
standard.
|
||||||
|
The
|
||||||
|
.Cm files
|
||||||
|
and
|
||||||
|
.Cm msgfmt
|
||||||
|
operands and the
|
||||||
|
.Cm ascii ,
|
||||||
|
.Cm ebcdic ,
|
||||||
|
.Cm ibm ,
|
||||||
|
.Cm oldascii ,
|
||||||
|
.Cm oldebcdic
|
||||||
|
and
|
||||||
|
.Cm oldibm
|
||||||
|
values are extensions to the
|
||||||
|
.Tn POSIX
|
||||||
|
standard.
|
598
bin/dd/dd.c
Normal file
598
bin/dd/dd.c
Normal file
|
@ -0,0 +1,598 @@
|
||||||
|
/* $NetBSD: dd.c,v 1.49 2012/02/21 01:49:01 matt 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. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#ifndef lint
|
||||||
|
__COPYRIGHT("@(#) Copyright (c) 1991, 1993, 1994\
|
||||||
|
The Regents of the University of California. All rights reserved.");
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
#ifndef lint
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)dd.c 8.5 (Berkeley) 4/2/94";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: dd.c,v 1.49 2012/02/21 01:49:01 matt Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mtio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "dd.h"
|
||||||
|
#include "extern.h"
|
||||||
|
|
||||||
|
static void dd_close(void);
|
||||||
|
static void dd_in(void);
|
||||||
|
static void getfdtype(IO *);
|
||||||
|
static void redup_clean_fd(IO *);
|
||||||
|
static void setup(void);
|
||||||
|
|
||||||
|
int main(int, char *[]);
|
||||||
|
|
||||||
|
IO in, out; /* input/output state */
|
||||||
|
STAT st; /* statistics */
|
||||||
|
void (*cfunc)(void); /* conversion function */
|
||||||
|
uint64_t cpy_cnt; /* # of blocks to copy */
|
||||||
|
static off_t pending = 0; /* pending seek if sparse */
|
||||||
|
u_int ddflags; /* conversion options */
|
||||||
|
uint64_t cbsz; /* conversion block size */
|
||||||
|
u_int files_cnt = 1; /* # of files to copy */
|
||||||
|
uint64_t progress = 0; /* display sign of life */
|
||||||
|
const u_char *ctab; /* conversion table */
|
||||||
|
sigset_t infoset; /* a set blocking SIGINFO */
|
||||||
|
const char *msgfmt = "posix"; /* default summary() message format */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ops for stdin/stdout and crunch'd dd. These are always host ops.
|
||||||
|
*/
|
||||||
|
static const struct ddfops ddfops_stdfd = {
|
||||||
|
.op_open = open,
|
||||||
|
.op_close = close,
|
||||||
|
.op_fcntl = fcntl,
|
||||||
|
.op_ioctl = ioctl,
|
||||||
|
.op_fstat = fstat,
|
||||||
|
.op_fsync = fsync,
|
||||||
|
.op_ftruncate = ftruncate,
|
||||||
|
.op_lseek = lseek,
|
||||||
|
.op_read = read,
|
||||||
|
.op_write = write,
|
||||||
|
};
|
||||||
|
extern const struct ddfops ddfops_prog;
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
setprogname(argv[0]);
|
||||||
|
(void)setlocale(LC_ALL, "");
|
||||||
|
|
||||||
|
while ((ch = getopt(argc, argv, "")) != -1) {
|
||||||
|
switch (ch) {
|
||||||
|
default:
|
||||||
|
errx(EXIT_FAILURE, "usage: dd [operand ...]");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argc -= (optind - 1);
|
||||||
|
argv += (optind - 1);
|
||||||
|
|
||||||
|
jcl(argv);
|
||||||
|
#ifndef CRUNCHOPS
|
||||||
|
if (ddfops_prog.op_init && ddfops_prog.op_init() == -1)
|
||||||
|
err(1, "prog init");
|
||||||
|
#endif
|
||||||
|
setup();
|
||||||
|
|
||||||
|
(void)signal(SIGINFO, summaryx);
|
||||||
|
(void)signal(SIGINT, terminate);
|
||||||
|
(void)sigemptyset(&infoset);
|
||||||
|
(void)sigaddset(&infoset, SIGINFO);
|
||||||
|
|
||||||
|
(void)atexit(summary);
|
||||||
|
|
||||||
|
while (files_cnt--)
|
||||||
|
dd_in();
|
||||||
|
|
||||||
|
dd_close();
|
||||||
|
exit(0);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup(void)
|
||||||
|
{
|
||||||
|
#ifdef CRUNCHOPS
|
||||||
|
const struct ddfops *prog_ops = &ddfops_stdfd;
|
||||||
|
#else
|
||||||
|
const struct ddfops *prog_ops = &ddfops_prog;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (in.name == NULL) {
|
||||||
|
in.name = "stdin";
|
||||||
|
in.fd = STDIN_FILENO;
|
||||||
|
in.ops = &ddfops_stdfd;
|
||||||
|
} else {
|
||||||
|
in.ops = prog_ops;
|
||||||
|
in.fd = ddop_open(in, in.name, O_RDONLY, 0);
|
||||||
|
if (in.fd < 0)
|
||||||
|
err(EXIT_FAILURE, "%s", in.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
|
||||||
|
/* Ensure in.fd is outside the stdio descriptor range */
|
||||||
|
redup_clean_fd(&in);
|
||||||
|
}
|
||||||
|
|
||||||
|
getfdtype(&in);
|
||||||
|
|
||||||
|
if (files_cnt > 1 && !(in.flags & ISTAPE)) {
|
||||||
|
errx(EXIT_FAILURE, "files is not supported for non-tape devices");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out.name == NULL) {
|
||||||
|
/* No way to check for read access here. */
|
||||||
|
out.fd = STDOUT_FILENO;
|
||||||
|
out.name = "stdout";
|
||||||
|
out.ops = &ddfops_stdfd;
|
||||||
|
} else {
|
||||||
|
out.ops = prog_ops;
|
||||||
|
#define OFLAGS \
|
||||||
|
(O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC))
|
||||||
|
out.fd = ddop_open(out, out.name, O_RDWR | OFLAGS, DEFFILEMODE);
|
||||||
|
/*
|
||||||
|
* May not have read access, so try again with write only.
|
||||||
|
* Without read we may have a problem if output also does
|
||||||
|
* not support seeks.
|
||||||
|
*/
|
||||||
|
if (out.fd < 0) {
|
||||||
|
out.fd = ddop_open(out, out.name, O_WRONLY | OFLAGS,
|
||||||
|
DEFFILEMODE);
|
||||||
|
out.flags |= NOREAD;
|
||||||
|
}
|
||||||
|
if (out.fd < 0) {
|
||||||
|
err(EXIT_FAILURE, "%s", out.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure out.fd is outside the stdio descriptor range */
|
||||||
|
redup_clean_fd(&out);
|
||||||
|
}
|
||||||
|
|
||||||
|
getfdtype(&out);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate space for the input and output buffers. If not doing
|
||||||
|
* record oriented I/O, only need a single buffer.
|
||||||
|
*/
|
||||||
|
if (!(ddflags & (C_BLOCK|C_UNBLOCK))) {
|
||||||
|
size_t dbsz = out.dbsz;
|
||||||
|
if (!(ddflags & C_BS))
|
||||||
|
dbsz += in.dbsz - 1;
|
||||||
|
if ((in.db = malloc(dbsz)) == NULL) {
|
||||||
|
err(EXIT_FAILURE, NULL);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
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(EXIT_FAILURE, NULL);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
in.dbp = in.db;
|
||||||
|
out.dbp = out.db;
|
||||||
|
|
||||||
|
/* Position the input/output streams. */
|
||||||
|
if (in.offset)
|
||||||
|
pos_in();
|
||||||
|
if (out.offset)
|
||||||
|
pos_out();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Truncate the output file; ignore errors because it fails on some
|
||||||
|
* kinds of output files, tapes, for example.
|
||||||
|
*/
|
||||||
|
if ((ddflags & (C_OF | C_SEEK | C_NOTRUNC)) == (C_OF | C_SEEK))
|
||||||
|
(void)ddop_ftruncate(out, out.fd, (off_t)out.offset * out.dbsz);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If converting case at the same time as another conversion, build a
|
||||||
|
* table that does both at once. If just converting case, use the
|
||||||
|
* built-in tables.
|
||||||
|
*/
|
||||||
|
if (ddflags & (C_LCASE|C_UCASE)) {
|
||||||
|
#ifdef NO_CONV
|
||||||
|
/* Should not get here, but just in case... */
|
||||||
|
errx(EXIT_FAILURE, "case conv and -DNO_CONV");
|
||||||
|
/* NOTREACHED */
|
||||||
|
#else /* NO_CONV */
|
||||||
|
u_int cnt;
|
||||||
|
|
||||||
|
if (ddflags & C_ASCII || ddflags & C_EBCDIC) {
|
||||||
|
if (ddflags & C_LCASE) {
|
||||||
|
for (cnt = 0; cnt < 256; ++cnt)
|
||||||
|
casetab[cnt] = tolower(ctab[cnt]);
|
||||||
|
} else {
|
||||||
|
for (cnt = 0; cnt < 256; ++cnt)
|
||||||
|
casetab[cnt] = toupper(ctab[cnt]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ddflags & C_LCASE) {
|
||||||
|
for (cnt = 0; cnt < 256; ++cnt)
|
||||||
|
casetab[cnt] = tolower(cnt);
|
||||||
|
} else {
|
||||||
|
for (cnt = 0; cnt < 256; ++cnt)
|
||||||
|
casetab[cnt] = toupper(cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctab = casetab;
|
||||||
|
#endif /* NO_CONV */
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)gettimeofday(&st.start, NULL); /* Statistics timestamp. */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
getfdtype(IO *io)
|
||||||
|
{
|
||||||
|
struct mtget mt;
|
||||||
|
struct stat sb;
|
||||||
|
|
||||||
|
if (io->ops->op_fstat(io->fd, &sb)) {
|
||||||
|
err(EXIT_FAILURE, "%s", io->name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
if (S_ISCHR(sb.st_mode))
|
||||||
|
io->flags |= io->ops->op_ioctl(io->fd, MTIOCGET, &mt)
|
||||||
|
? ISCHR : ISTAPE;
|
||||||
|
else if (io->ops->op_lseek(io->fd, (off_t)0, SEEK_CUR) == -1
|
||||||
|
&& errno == ESPIPE)
|
||||||
|
io->flags |= ISPIPE; /* XXX fixed in 4.4BSD */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move the parameter file descriptor to a descriptor that is outside the
|
||||||
|
* stdio descriptor range, if necessary. This is required to avoid
|
||||||
|
* accidentally outputting completion or error messages into the
|
||||||
|
* output file that were intended for the tty.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
redup_clean_fd(IO *io)
|
||||||
|
{
|
||||||
|
int fd = io->fd;
|
||||||
|
int newfd;
|
||||||
|
|
||||||
|
if (fd != STDIN_FILENO && fd != STDOUT_FILENO &&
|
||||||
|
fd != STDERR_FILENO)
|
||||||
|
/* File descriptor is ok, return immediately. */
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 3 is the first descriptor greater than STD*_FILENO. Any
|
||||||
|
* free descriptor valued 3 or above is acceptable...
|
||||||
|
*/
|
||||||
|
newfd = io->ops->op_fcntl(fd, F_DUPFD, 3);
|
||||||
|
if (newfd < 0) {
|
||||||
|
err(EXIT_FAILURE, "dupfd IO");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
io->ops->op_close(fd);
|
||||||
|
io->fd = newfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dd_in(void)
|
||||||
|
{
|
||||||
|
int flags;
|
||||||
|
int64_t n;
|
||||||
|
|
||||||
|
for (flags = ddflags;;) {
|
||||||
|
if (cpy_cnt && (st.in_full + st.in_part) >= cpy_cnt)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clear the buffer first if doing "sync" on input.
|
||||||
|
* If doing block operations use spaces. This will
|
||||||
|
* affect not only the C_NOERROR case, but also the
|
||||||
|
* last partial input block which should be padded
|
||||||
|
* with zero and not garbage.
|
||||||
|
*/
|
||||||
|
if (flags & C_SYNC) {
|
||||||
|
if (flags & (C_BLOCK|C_UNBLOCK))
|
||||||
|
(void)memset(in.dbp, ' ', in.dbsz);
|
||||||
|
else
|
||||||
|
(void)memset(in.dbp, 0, in.dbsz);
|
||||||
|
}
|
||||||
|
|
||||||
|
n = ddop_read(in, in.fd, in.dbp, in.dbsz);
|
||||||
|
if (n == 0) {
|
||||||
|
in.dbrcnt = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read error. */
|
||||||
|
if (n < 0) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If noerror not specified, die. POSIX requires that
|
||||||
|
* the warning message be followed by an I/O display.
|
||||||
|
*/
|
||||||
|
if (!(flags & C_NOERROR)) {
|
||||||
|
err(EXIT_FAILURE, "%s", in.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
warn("%s", in.name);
|
||||||
|
summary();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If it's not a tape drive or a pipe, seek past the
|
||||||
|
* error. If your OS doesn't do the right thing for
|
||||||
|
* raw disks this section should be modified to re-read
|
||||||
|
* in sector size chunks.
|
||||||
|
*/
|
||||||
|
if (!(in.flags & (ISPIPE|ISTAPE)) &&
|
||||||
|
ddop_lseek(in, in.fd, (off_t)in.dbsz, SEEK_CUR))
|
||||||
|
warn("%s", in.name);
|
||||||
|
|
||||||
|
/* If sync not specified, omit block and continue. */
|
||||||
|
if (!(ddflags & C_SYNC))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Read errors count as full blocks. */
|
||||||
|
in.dbcnt += in.dbrcnt = in.dbsz;
|
||||||
|
++st.in_full;
|
||||||
|
|
||||||
|
/* Handle full input blocks. */
|
||||||
|
} else if ((uint64_t)n == in.dbsz) {
|
||||||
|
in.dbcnt += in.dbrcnt = n;
|
||||||
|
++st.in_full;
|
||||||
|
|
||||||
|
/* Handle partial input blocks. */
|
||||||
|
} else {
|
||||||
|
/* If sync, use the entire block. */
|
||||||
|
if (ddflags & C_SYNC)
|
||||||
|
in.dbcnt += in.dbrcnt = in.dbsz;
|
||||||
|
else
|
||||||
|
in.dbcnt += in.dbrcnt = n;
|
||||||
|
++st.in_part;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POSIX states that if bs is set and no other conversions
|
||||||
|
* than noerror, notrunc or sync are specified, the block
|
||||||
|
* is output without buffering as it is read.
|
||||||
|
*/
|
||||||
|
if (ddflags & C_BS) {
|
||||||
|
out.dbcnt = in.dbcnt;
|
||||||
|
dd_out(1);
|
||||||
|
in.dbcnt = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ddflags & C_SWAB) {
|
||||||
|
if ((n = in.dbrcnt) & 1) {
|
||||||
|
++st.swab;
|
||||||
|
--n;
|
||||||
|
}
|
||||||
|
swab(in.dbp, in.dbp, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
in.dbp += in.dbrcnt;
|
||||||
|
(*cfunc)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cleanup any remaining I/O and flush output. If necessary, output file
|
||||||
|
* is truncated.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
dd_close(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (cfunc == def)
|
||||||
|
def_close();
|
||||||
|
else if (cfunc == block)
|
||||||
|
block_close();
|
||||||
|
else if (cfunc == unblock)
|
||||||
|
unblock_close();
|
||||||
|
if (ddflags & C_OSYNC && out.dbcnt < out.dbsz) {
|
||||||
|
(void)memset(out.dbp, 0, out.dbsz - out.dbcnt);
|
||||||
|
out.dbcnt = out.dbsz;
|
||||||
|
}
|
||||||
|
/* If there are pending sparse blocks, make sure
|
||||||
|
* to write out the final block un-sparse
|
||||||
|
*/
|
||||||
|
if ((out.dbcnt == 0) && pending) {
|
||||||
|
memset(out.db, 0, out.dbsz);
|
||||||
|
out.dbcnt = out.dbsz;
|
||||||
|
out.dbp = out.db + out.dbcnt;
|
||||||
|
pending -= out.dbsz;
|
||||||
|
}
|
||||||
|
if (out.dbcnt)
|
||||||
|
dd_out(1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reporting nfs write error may be deferred until next
|
||||||
|
* write(2) or close(2) system call. So, we need to do an
|
||||||
|
* extra check. If an output is stdout, the file structure
|
||||||
|
* may be shared with other processes and close(2) just
|
||||||
|
* decreases the reference count.
|
||||||
|
*/
|
||||||
|
if (out.fd == STDOUT_FILENO && ddop_fsync(out, out.fd) == -1
|
||||||
|
&& errno != EINVAL) {
|
||||||
|
err(EXIT_FAILURE, "fsync stdout");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
if (ddop_close(out, out.fd) == -1) {
|
||||||
|
err(EXIT_FAILURE, "close");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dd_out(int force)
|
||||||
|
{
|
||||||
|
static int warned;
|
||||||
|
int64_t cnt, n, nw;
|
||||||
|
u_char *outp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write one or more blocks out. The common case is writing a full
|
||||||
|
* output block in a single write; increment the full block stats.
|
||||||
|
* Otherwise, we're into partial block writes. If a partial write,
|
||||||
|
* and it's a character device, just warn. If a tape device, quit.
|
||||||
|
*
|
||||||
|
* The partial writes represent two cases. 1: Where the input block
|
||||||
|
* was less than expected so the output block was less than expected.
|
||||||
|
* 2: Where the input block was the right size but we were forced to
|
||||||
|
* write the block in multiple chunks. The original versions of dd(1)
|
||||||
|
* never wrote a block in more than a single write, so the latter case
|
||||||
|
* never happened.
|
||||||
|
*
|
||||||
|
* One special case is if we're forced to do the write -- in that case
|
||||||
|
* we play games with the buffer size, and it's usually a partial write.
|
||||||
|
*/
|
||||||
|
outp = out.db;
|
||||||
|
for (n = force ? out.dbcnt : out.dbsz;; n = out.dbsz) {
|
||||||
|
for (cnt = n;; cnt -= nw) {
|
||||||
|
|
||||||
|
if (!force && ddflags & C_SPARSE) {
|
||||||
|
int sparse, i;
|
||||||
|
sparse = 1; /* Is buffer sparse? */
|
||||||
|
for (i = 0; i < cnt; i++)
|
||||||
|
if (outp[i] != 0) {
|
||||||
|
sparse = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (sparse) {
|
||||||
|
pending += cnt;
|
||||||
|
outp += cnt;
|
||||||
|
nw = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pending != 0) {
|
||||||
|
if (ddop_lseek(out,
|
||||||
|
out.fd, pending, SEEK_CUR) == -1)
|
||||||
|
err(EXIT_FAILURE, "%s: seek error creating sparse file",
|
||||||
|
out.name);
|
||||||
|
}
|
||||||
|
nw = bwrite(&out, outp, cnt);
|
||||||
|
if (nw <= 0) {
|
||||||
|
if (nw == 0)
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"%s: end of device", out.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
if (errno != EINTR)
|
||||||
|
err(EXIT_FAILURE, "%s", out.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
nw = 0;
|
||||||
|
}
|
||||||
|
if (pending) {
|
||||||
|
st.bytes += pending;
|
||||||
|
st.sparse += pending/out.dbsz;
|
||||||
|
st.out_full += pending/out.dbsz;
|
||||||
|
pending = 0;
|
||||||
|
}
|
||||||
|
outp += nw;
|
||||||
|
st.bytes += nw;
|
||||||
|
if (nw == n) {
|
||||||
|
if ((uint64_t)n != out.dbsz)
|
||||||
|
++st.out_part;
|
||||||
|
else
|
||||||
|
++st.out_full;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++st.out_part;
|
||||||
|
if (nw == cnt)
|
||||||
|
break;
|
||||||
|
if (out.flags & ISCHR && !warned) {
|
||||||
|
warned = 1;
|
||||||
|
warnx("%s: short write on character device", out.name);
|
||||||
|
}
|
||||||
|
if (out.flags & ISTAPE)
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"%s: short write on tape device", out.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
|
||||||
|
}
|
||||||
|
if ((out.dbcnt -= n) < out.dbsz)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reassemble the output block. */
|
||||||
|
if (out.dbcnt)
|
||||||
|
(void)memmove(out.db, out.dbp - out.dbcnt, out.dbcnt);
|
||||||
|
out.dbp = out.db + out.dbcnt;
|
||||||
|
|
||||||
|
if (progress && (st.out_full + st.out_part) % progress == 0)
|
||||||
|
(void)write(STDERR_FILENO, ".", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A protected against SIGINFO write
|
||||||
|
*/
|
||||||
|
ssize_t
|
||||||
|
bwrite(IO *io, const void *buf, size_t len)
|
||||||
|
{
|
||||||
|
sigset_t oset;
|
||||||
|
ssize_t rv;
|
||||||
|
int oerrno;
|
||||||
|
|
||||||
|
(void)sigprocmask(SIG_BLOCK, &infoset, &oset);
|
||||||
|
rv = io->ops->op_write(io->fd, buf, len);
|
||||||
|
oerrno = errno;
|
||||||
|
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||||
|
errno = oerrno;
|
||||||
|
return (rv);
|
||||||
|
}
|
123
bin/dd/dd.h
Normal file
123
bin/dd/dd.h
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/* $NetBSD: dd.h,v 1.15 2011/02/04 19:42:12 pooka 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. 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.
|
||||||
|
*
|
||||||
|
* @(#)dd.h 8.3 (Berkeley) 4/2/94
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
struct ddfops {
|
||||||
|
int (*op_init)(void);
|
||||||
|
|
||||||
|
int (*op_open)(const char *, int, ...);
|
||||||
|
int (*op_close)(int);
|
||||||
|
|
||||||
|
int (*op_fcntl)(int, int, ...);
|
||||||
|
int (*op_ioctl)(int, unsigned long, ...);
|
||||||
|
|
||||||
|
int (*op_fstat)(int, struct stat *);
|
||||||
|
int (*op_fsync)(int);
|
||||||
|
int (*op_ftruncate)(int, off_t);
|
||||||
|
|
||||||
|
off_t (*op_lseek)(int, off_t, int);
|
||||||
|
|
||||||
|
ssize_t (*op_read)(int, void *, size_t);
|
||||||
|
ssize_t (*op_write)(int, const void *, size_t);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ddop_open(dir, a1, a2, ...) dir.ops->op_open(a1, a2, __VA_ARGS__)
|
||||||
|
#define ddop_close(dir, a1) dir.ops->op_close(a1)
|
||||||
|
#define ddop_fcntl(dir, a1, a2, ...) dir.ops->op_fcntl(a1, a2, __VA_ARGS__)
|
||||||
|
#define ddop_ioctl(dir, a1, a2, ...) dir.ops->op_ioctl(a1, a2, __VA_ARGS__)
|
||||||
|
#define ddop_fsync(dir, a1) dir.ops->op_fsync(a1)
|
||||||
|
#define ddop_ftruncate(dir, a1, a2) dir.ops->op_ftruncate(a1, a2)
|
||||||
|
#define ddop_lseek(dir, a1, a2, a3) dir.ops->op_lseek(a1, a2, a3)
|
||||||
|
#define ddop_read(dir, a1, a2, a3) dir.ops->op_read(a1, a2, a3)
|
||||||
|
#define ddop_write(dir, a1, a2, a3) dir.ops->op_write(a1, a2, a3)
|
||||||
|
|
||||||
|
/* Input/output stream state. */
|
||||||
|
typedef struct {
|
||||||
|
u_char *db; /* buffer address */
|
||||||
|
u_char *dbp; /* current buffer I/O address */
|
||||||
|
uint64_t dbcnt; /* current buffer byte count */
|
||||||
|
int64_t dbrcnt; /* last read byte count */
|
||||||
|
uint64_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;
|
||||||
|
|
||||||
|
const char *name; /* name */
|
||||||
|
int fd; /* file descriptor */
|
||||||
|
uint64_t offset; /* # of blocks to skip */
|
||||||
|
struct ddfops const *ops; /* ops to use with fd */
|
||||||
|
} IO;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t in_full; /* # of full input blocks */
|
||||||
|
uint64_t in_part; /* # of partial input blocks */
|
||||||
|
uint64_t out_full; /* # of full output blocks */
|
||||||
|
uint64_t out_part; /* # of partial output blocks */
|
||||||
|
uint64_t trunc; /* # of truncated records */
|
||||||
|
uint64_t swab; /* # of odd-length swab blocks */
|
||||||
|
uint64_t sparse; /* # of sparse output blocks */
|
||||||
|
uint64_t bytes; /* # of bytes written */
|
||||||
|
struct timeval start; /* start time of dd */
|
||||||
|
} STAT;
|
||||||
|
|
||||||
|
/* Flags (in ddflags). */
|
||||||
|
#define C_ASCII 0x00001
|
||||||
|
#define C_BLOCK 0x00002
|
||||||
|
#define C_BS 0x00004
|
||||||
|
#define C_CBS 0x00008
|
||||||
|
#define C_COUNT 0x00010
|
||||||
|
#define C_EBCDIC 0x00020
|
||||||
|
#define C_FILES 0x00040
|
||||||
|
#define C_IBS 0x00080
|
||||||
|
#define C_IF 0x00100
|
||||||
|
#define C_LCASE 0x00200
|
||||||
|
#define C_NOERROR 0x00400
|
||||||
|
#define C_NOTRUNC 0x00800
|
||||||
|
#define C_OBS 0x01000
|
||||||
|
#define C_OF 0x02000
|
||||||
|
#define C_SEEK 0x04000
|
||||||
|
#define C_SKIP 0x08000
|
||||||
|
#define C_SWAB 0x10000
|
||||||
|
#define C_SYNC 0x20000
|
||||||
|
#define C_UCASE 0x40000
|
||||||
|
#define C_UNBLOCK 0x80000
|
||||||
|
#define C_OSYNC 0x100000
|
||||||
|
#define C_SPARSE 0x200000
|
53
bin/dd/dd_hostops.c
Normal file
53
bin/dd/dd_hostops.c
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/* $NetBSD: dd_hostops.c,v 1.1 2011/02/04 19:42:12 pooka Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* 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: dd_hostops.c,v 1.1 2011/02/04 19:42:12 pooka Exp $");
|
||||||
|
#endif /* !lint */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "dd.h"
|
||||||
|
|
||||||
|
const struct ddfops ddfops_prog = {
|
||||||
|
.op_open = open,
|
||||||
|
.op_close = close,
|
||||||
|
.op_fcntl = fcntl,
|
||||||
|
.op_ioctl = ioctl,
|
||||||
|
.op_fstat = fstat,
|
||||||
|
.op_fsync = fsync,
|
||||||
|
.op_ftruncate = ftruncate,
|
||||||
|
.op_lseek = lseek,
|
||||||
|
.op_read = read,
|
||||||
|
.op_write = write,
|
||||||
|
};
|
52
bin/dd/dd_rumpops.c
Normal file
52
bin/dd/dd_rumpops.c
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/* $NetBSD: dd_rumpops.c,v 1.1 2011/02/04 19:42:12 pooka Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* 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: dd_rumpops.c,v 1.1 2011/02/04 19:42:12 pooka Exp $");
|
||||||
|
#endif /* !lint */
|
||||||
|
|
||||||
|
#include <rump/rump_syscalls.h>
|
||||||
|
#include <rump/rumpclient.h>
|
||||||
|
|
||||||
|
#include "dd.h"
|
||||||
|
|
||||||
|
const struct ddfops ddfops_prog = {
|
||||||
|
.op_init = rumpclient_init,
|
||||||
|
|
||||||
|
.op_open = rump_sys_open,
|
||||||
|
.op_close = rump_sys_close,
|
||||||
|
.op_fcntl = rump_sys_fcntl,
|
||||||
|
.op_ioctl = rump_sys_ioctl,
|
||||||
|
.op_fstat = rump_sys_fstat,
|
||||||
|
.op_fsync = rump_sys_fsync,
|
||||||
|
.op_ftruncate = rump_sys_ftruncate,
|
||||||
|
.op_lseek = rump_sys_lseek,
|
||||||
|
.op_read = rump_sys_read,
|
||||||
|
.op_write = rump_sys_write,
|
||||||
|
};
|
82
bin/dd/extern.h
Normal file
82
bin/dd/extern.h
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
/* $NetBSD: extern.h,v 1.22 2011/11/07 22:24:23 jym 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. 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.
|
||||||
|
*
|
||||||
|
* @(#)extern.h 8.3 (Berkeley) 4/2/94
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
#ifdef NO_CONV
|
||||||
|
__dead void block(void);
|
||||||
|
__dead void block_close(void);
|
||||||
|
__dead void unblock(void);
|
||||||
|
__dead void unblock_close(void);
|
||||||
|
#else
|
||||||
|
void block(void);
|
||||||
|
void block_close(void);
|
||||||
|
void unblock(void);
|
||||||
|
void unblock_close(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_MSGFMT
|
||||||
|
int dd_write_msg(const char *, int);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void dd_out(int);
|
||||||
|
void def(void);
|
||||||
|
void def_close(void);
|
||||||
|
void jcl(char **);
|
||||||
|
void pos_in(void);
|
||||||
|
void pos_out(void);
|
||||||
|
void summary(void);
|
||||||
|
void summaryx(int);
|
||||||
|
__dead void terminate(int);
|
||||||
|
void unblock(void);
|
||||||
|
void unblock_close(void);
|
||||||
|
ssize_t bwrite(IO *, const void *, size_t);
|
||||||
|
|
||||||
|
extern IO in, out;
|
||||||
|
extern STAT st;
|
||||||
|
extern void (*cfunc)(void);
|
||||||
|
extern uint64_t cpy_cnt;
|
||||||
|
extern uint64_t cbsz;
|
||||||
|
extern u_int ddflags;
|
||||||
|
extern u_int files_cnt;
|
||||||
|
extern uint64_t 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 const char *msgfmt;
|
342
bin/dd/misc.c
Normal file
342
bin/dd/misc.c
Normal file
|
@ -0,0 +1,342 @@
|
||||||
|
/* $NetBSD: misc.c,v 1.23 2011/11/07 22:24:23 jym 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. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#ifndef lint
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)misc.c 8.3 (Berkeley) 4/2/94";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: misc.c,v 1.23 2011/11/07 22:24:23 jym Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <util.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "dd.h"
|
||||||
|
#include "extern.h"
|
||||||
|
|
||||||
|
#define tv2mS(tv) ((tv).tv_sec * 1000LL + ((tv).tv_usec + 500) / 1000)
|
||||||
|
|
||||||
|
static void posix_summary(void);
|
||||||
|
#ifndef NO_MSGFMT
|
||||||
|
static void custom_summary(void);
|
||||||
|
static void human_summary(void);
|
||||||
|
static void quiet_summary(void);
|
||||||
|
|
||||||
|
static void buffer_write(const char *, size_t, int);
|
||||||
|
#endif /* NO_MSGFMT */
|
||||||
|
|
||||||
|
void
|
||||||
|
summary(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (progress)
|
||||||
|
(void)write(STDERR_FILENO, "\n", 1);
|
||||||
|
|
||||||
|
#ifdef NO_MSGFMT
|
||||||
|
return posix_summary();
|
||||||
|
#else /* NO_MSGFMT */
|
||||||
|
if (strncmp(msgfmt, "human", sizeof("human")) == 0)
|
||||||
|
return human_summary();
|
||||||
|
|
||||||
|
if (strncmp(msgfmt, "posix", sizeof("posix")) == 0)
|
||||||
|
return posix_summary();
|
||||||
|
|
||||||
|
if (strncmp(msgfmt, "quiet", sizeof("quiet")) == 0)
|
||||||
|
return quiet_summary();
|
||||||
|
|
||||||
|
return custom_summary();
|
||||||
|
#endif /* NO_MSGFMT */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
posix_summary(void)
|
||||||
|
{
|
||||||
|
char buf[100];
|
||||||
|
int64_t mS;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
if (progress)
|
||||||
|
(void)write(STDERR_FILENO, "\n", 1);
|
||||||
|
|
||||||
|
(void)gettimeofday(&tv, NULL);
|
||||||
|
mS = tv2mS(tv) - tv2mS(st.start);
|
||||||
|
if (mS == 0)
|
||||||
|
mS = 1;
|
||||||
|
|
||||||
|
/* Use snprintf(3) so that we don't reenter stdio(3). */
|
||||||
|
(void)snprintf(buf, sizeof(buf),
|
||||||
|
"%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), "%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), "%llu truncated %s\n",
|
||||||
|
(unsigned long long)st.trunc,
|
||||||
|
(st.trunc == 1) ? "block" : "blocks");
|
||||||
|
(void)write(STDERR_FILENO, buf, strlen(buf));
|
||||||
|
}
|
||||||
|
if (st.sparse) {
|
||||||
|
(void)snprintf(buf, sizeof(buf), "%llu sparse output %s\n",
|
||||||
|
(unsigned long long)st.sparse,
|
||||||
|
(st.sparse == 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",
|
||||||
|
(unsigned long long) st.bytes,
|
||||||
|
(long) (mS / 1000),
|
||||||
|
(int) (mS % 1000),
|
||||||
|
(unsigned long long) (st.bytes * 1000LL / mS));
|
||||||
|
(void)write(STDERR_FILENO, buf, strlen(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
void
|
||||||
|
summaryx(int notused)
|
||||||
|
{
|
||||||
|
|
||||||
|
summary();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
void
|
||||||
|
terminate(int signo)
|
||||||
|
{
|
||||||
|
|
||||||
|
summary();
|
||||||
|
(void)raise_default_signal(signo);
|
||||||
|
_exit(127);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NO_MSGFMT
|
||||||
|
/*
|
||||||
|
* Buffer write(2) calls
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
buffer_write(const char *str, size_t size, int flush)
|
||||||
|
{
|
||||||
|
static char wbuf[128];
|
||||||
|
static size_t cnt = 0; /* Internal counter to allow wbuf to wrap */
|
||||||
|
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
if (str != NULL) {
|
||||||
|
wbuf[cnt++] = str[i];
|
||||||
|
}
|
||||||
|
if (cnt >= sizeof(wbuf)) {
|
||||||
|
(void)write(STDERR_FILENO, wbuf, cnt);
|
||||||
|
cnt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flush != 0) {
|
||||||
|
(void)write(STDERR_FILENO, wbuf, cnt);
|
||||||
|
cnt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write summary to stderr according to format 'fmt'. If 'enable' is 0, it
|
||||||
|
* will not attempt to write anything. Can be used to validate the
|
||||||
|
* correctness of the 'fmt' string.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
dd_write_msg(const char *fmt, int enable)
|
||||||
|
{
|
||||||
|
char hbuf[7], nbuf[32];
|
||||||
|
const char *ptr;
|
||||||
|
int64_t mS;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
(void)gettimeofday(&tv, NULL);
|
||||||
|
mS = tv2mS(tv) - tv2mS(st.start);
|
||||||
|
if (mS == 0)
|
||||||
|
mS = 1;
|
||||||
|
|
||||||
|
#define ADDC(c) do { if (enable != 0) buffer_write(&c, 1, 0); } \
|
||||||
|
while (/*CONSTCOND*/0)
|
||||||
|
#define ADDS(p) do { if (enable != 0) buffer_write(p, strlen(p), 0); } \
|
||||||
|
while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
for (ptr = fmt; *ptr; ptr++) {
|
||||||
|
if (*ptr != '%') {
|
||||||
|
ADDC(*ptr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*++ptr) {
|
||||||
|
case 'b':
|
||||||
|
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||||
|
(unsigned long long)st.bytes);
|
||||||
|
ADDS(nbuf);
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
if (humanize_number(hbuf, sizeof(hbuf),
|
||||||
|
st.bytes, "B",
|
||||||
|
HN_AUTOSCALE, HN_DECIMAL) == -1)
|
||||||
|
warnx("humanize_number (bytes transferred)");
|
||||||
|
ADDS(hbuf);
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||||
|
(unsigned long long) (st.bytes * 1000LL / mS));
|
||||||
|
ADDS(nbuf);
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
if (humanize_number(hbuf, sizeof(hbuf),
|
||||||
|
st.bytes * 1000LL / mS, "B",
|
||||||
|
HN_AUTOSCALE, HN_DECIMAL) == -1)
|
||||||
|
warnx("humanize_number (bytes per second)");
|
||||||
|
ADDS(hbuf); ADDS("/sec");
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||||
|
(unsigned long long)st.in_part);
|
||||||
|
ADDS(nbuf);
|
||||||
|
break;
|
||||||
|
case 'I':
|
||||||
|
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||||
|
(unsigned long long)st.in_full);
|
||||||
|
ADDS(nbuf);
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||||
|
(unsigned long long)st.out_part);
|
||||||
|
ADDS(nbuf);
|
||||||
|
break;
|
||||||
|
case 'O':
|
||||||
|
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||||
|
(unsigned long long)st.out_full);
|
||||||
|
ADDS(nbuf);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
(void)snprintf(nbuf, sizeof(nbuf), "%li.%03d",
|
||||||
|
(long) (mS / 1000), (int) (mS % 1000));
|
||||||
|
ADDS(nbuf);
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||||
|
(unsigned long long)st.sparse);
|
||||||
|
ADDS(nbuf);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||||
|
(unsigned long long)st.trunc);
|
||||||
|
ADDS(nbuf);
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||||
|
(unsigned long long)st.swab);
|
||||||
|
ADDS(nbuf);
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
ADDS("block");
|
||||||
|
if (st.sparse != 1) ADDS("s");
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
ADDS("block");
|
||||||
|
if (st.trunc != 1) ADDS("s");
|
||||||
|
break;
|
||||||
|
case 'W':
|
||||||
|
ADDS("block");
|
||||||
|
if (st.swab != 1) ADDS("s");
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
ADDC(*ptr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (*ptr == '\0')
|
||||||
|
goto done;
|
||||||
|
errx(EXIT_FAILURE, "unknown specifier '%c' in "
|
||||||
|
"msgfmt string", *ptr);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
/* flush buffer */
|
||||||
|
buffer_write(NULL, 0, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
custom_summary(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
dd_write_msg(msgfmt, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
human_summary(void)
|
||||||
|
{
|
||||||
|
(void)dd_write_msg("%I+%i records in\n%O+%o records out\n", 1);
|
||||||
|
if (st.swab) {
|
||||||
|
(void)dd_write_msg("%w odd length swab %W\n", 1);
|
||||||
|
}
|
||||||
|
if (st.trunc) {
|
||||||
|
(void)dd_write_msg("%t truncated %T\n", 1);
|
||||||
|
}
|
||||||
|
if (st.sparse) {
|
||||||
|
(void)dd_write_msg("%p sparse output %P\n", 1);
|
||||||
|
}
|
||||||
|
(void)dd_write_msg("%b bytes (%B) transferred in %s secs "
|
||||||
|
"(%e bytes/sec - %E)\n", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
quiet_summary(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* stay quiet */
|
||||||
|
}
|
||||||
|
#endif /* NO_MSGFMT */
|
185
bin/dd/position.c
Normal file
185
bin/dd/position.c
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
/* $NetBSD: position.c,v 1.18 2010/11/22 21:04:28 pooka 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. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#ifndef lint
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)position.c 8.3 (Berkeley) 4/2/94";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: position.c,v 1.18 2010/11/22 21:04:28 pooka Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mtio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "dd.h"
|
||||||
|
#include "extern.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Position input/output data streams before starting the copy. Device type
|
||||||
|
* dependent. Seekable devices use lseek, and the rest position by reading.
|
||||||
|
* Seeking past the end of file can cause null blocks to be written to the
|
||||||
|
* output.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
pos_in(void)
|
||||||
|
{
|
||||||
|
int bcnt, cnt, nr, warned;
|
||||||
|
|
||||||
|
/* If not a pipe or tape device, try to seek on it. */
|
||||||
|
if (!(in.flags & (ISPIPE|ISTAPE))) {
|
||||||
|
if (ddop_lseek(in, in.fd,
|
||||||
|
(off_t)in.offset * (off_t)in.dbsz, SEEK_CUR) == -1) {
|
||||||
|
err(EXIT_FAILURE, "%s", in.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the data. If a pipe, read until satisfy the number of bytes
|
||||||
|
* being skipped. No differentiation for reading complete and partial
|
||||||
|
* blocks for other devices.
|
||||||
|
*/
|
||||||
|
for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) {
|
||||||
|
if ((nr = ddop_read(in, in.fd, in.db, bcnt)) > 0) {
|
||||||
|
if (in.flags & ISPIPE) {
|
||||||
|
if (!(bcnt -= nr)) {
|
||||||
|
bcnt = in.dbsz;
|
||||||
|
--cnt;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
--cnt;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nr == 0) {
|
||||||
|
if (files_cnt > 1) {
|
||||||
|
--files_cnt;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
errx(EXIT_FAILURE, "skip reached end of input");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Input error -- either EOF with no more files, or I/O error.
|
||||||
|
* If noerror not set die. POSIX requires that the warning
|
||||||
|
* message be followed by an I/O display.
|
||||||
|
*/
|
||||||
|
if (ddflags & C_NOERROR) {
|
||||||
|
if (!warned) {
|
||||||
|
|
||||||
|
warn("%s", in.name);
|
||||||
|
warned = 1;
|
||||||
|
summary();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
err(EXIT_FAILURE, "%s", in.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pos_out(void)
|
||||||
|
{
|
||||||
|
struct mtop t_op;
|
||||||
|
int n;
|
||||||
|
uint64_t cnt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If not a tape, try seeking on the file. Seeking on a pipe is
|
||||||
|
* going to fail, but don't protect the user -- they shouldn't
|
||||||
|
* have specified the seek operand.
|
||||||
|
*/
|
||||||
|
if (!(out.flags & ISTAPE)) {
|
||||||
|
if (ddop_lseek(out, out.fd,
|
||||||
|
(off_t)out.offset * (off_t)out.dbsz, SEEK_SET) == -1)
|
||||||
|
err(EXIT_FAILURE, "%s", out.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no read access, try using mtio. */
|
||||||
|
if (out.flags & NOREAD) {
|
||||||
|
t_op.mt_op = MTFSR;
|
||||||
|
t_op.mt_count = out.offset;
|
||||||
|
|
||||||
|
if (ddop_ioctl(out, out.fd, MTIOCTOP, &t_op) < 0)
|
||||||
|
err(EXIT_FAILURE, "%s", out.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read it. */
|
||||||
|
for (cnt = 0; cnt < out.offset; ++cnt) {
|
||||||
|
if ((n = ddop_read(out, out.fd, out.db, out.dbsz)) > 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (n < 0)
|
||||||
|
err(EXIT_FAILURE, "%s", out.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If reach EOF, fill with NUL characters; first, back up over
|
||||||
|
* the EOF mark. Note, cnt has not yet been incremented, so
|
||||||
|
* the EOF read does not count as a seek'd block.
|
||||||
|
*/
|
||||||
|
t_op.mt_op = MTBSR;
|
||||||
|
t_op.mt_count = 1;
|
||||||
|
if (ddop_ioctl(out, out.fd, MTIOCTOP, &t_op) == -1)
|
||||||
|
err(EXIT_FAILURE, "%s", out.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
|
||||||
|
while (cnt++ < out.offset)
|
||||||
|
if ((uint64_t)(n = bwrite(&out,
|
||||||
|
out.db, out.dbsz)) != out.dbsz)
|
||||||
|
err(EXIT_FAILURE, "%s", out.name);
|
||||||
|
/* NOTREACHED */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
./bin/cp minix-sys
|
./bin/cp minix-sys
|
||||||
./bin/cpio minix-sys
|
./bin/cpio minix-sys
|
||||||
./bin/date minix-sys
|
./bin/date minix-sys
|
||||||
|
./bin/dd minix-sys
|
||||||
./bin/df minix-sys
|
./bin/df minix-sys
|
||||||
./bin/echo minix-sys
|
./bin/echo minix-sys
|
||||||
./bin/ed minix-sys
|
./bin/ed minix-sys
|
||||||
|
@ -326,7 +327,7 @@
|
||||||
./usr/bin/ctags minix-sys
|
./usr/bin/ctags minix-sys
|
||||||
./usr/bin/cut minix-sys
|
./usr/bin/cut minix-sys
|
||||||
./usr/bin/datasizes minix-sys obsolete
|
./usr/bin/datasizes minix-sys obsolete
|
||||||
./usr/bin/dd minix-sys
|
./usr/bin/dd minix-sys obsolete
|
||||||
./usr/bin/decomp16 minix-sys
|
./usr/bin/decomp16 minix-sys
|
||||||
./usr/bin/del_route minix-sys
|
./usr/bin/del_route minix-sys
|
||||||
./usr/bin/deroff minix-sys
|
./usr/bin/deroff minix-sys
|
||||||
|
|
|
@ -6,7 +6,7 @@ SUBDIR= add_route arp at backup btrace \
|
||||||
cawf cdprobe \
|
cawf cdprobe \
|
||||||
ci cleantmp cmp co \
|
ci cleantmp cmp co \
|
||||||
compress crc cron crontab \
|
compress crc cron crontab \
|
||||||
dd decomp16 DESCRIBE devmand devsize dhcpd \
|
decomp16 DESCRIBE devmand devsize dhcpd \
|
||||||
dhrystone diff diskctl \
|
dhrystone diff diskctl \
|
||||||
eject fbdctl \
|
eject fbdctl \
|
||||||
find fix format fsck.mfs \
|
find fix format fsck.mfs \
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
# LSC For now
|
|
||||||
NOGCCERROR:=yes
|
|
||||||
PROG= dd
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,401 +0,0 @@
|
||||||
/* dd - disk dumper */
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#define EOS '\0'
|
|
||||||
#define BOOLEAN int
|
|
||||||
#define TRUE 1
|
|
||||||
#define FALSE 0
|
|
||||||
|
|
||||||
char *pch, *errorp;
|
|
||||||
|
|
||||||
int main(int argc, char **argv);
|
|
||||||
BOOLEAN is(char *pc);
|
|
||||||
int num(void);
|
|
||||||
void puto(void);
|
|
||||||
void statistics(void);
|
|
||||||
int ulcase(int c);
|
|
||||||
void cnull(int c);
|
|
||||||
void null(int c);
|
|
||||||
void extra(void);
|
|
||||||
void over(int dummy);
|
|
||||||
|
|
||||||
BOOLEAN is(pc)
|
|
||||||
char *pc;
|
|
||||||
{
|
|
||||||
register char *ps = pch;
|
|
||||||
|
|
||||||
while (*ps++ == *pc++)
|
|
||||||
if (*pc == EOS) {
|
|
||||||
pch = ps;
|
|
||||||
return(TRUE);
|
|
||||||
}
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BIGNUM 2147483647
|
|
||||||
|
|
||||||
int num()
|
|
||||||
{
|
|
||||||
long ans;
|
|
||||||
register char *pc;
|
|
||||||
|
|
||||||
pc = pch;
|
|
||||||
ans = 0L;
|
|
||||||
while ((*pc >= '0') && (*pc <= '9'))
|
|
||||||
ans = (long) ((*pc++ - '0') + (ans * 10));
|
|
||||||
while (TRUE) switch (*pc++) {
|
|
||||||
case 'w':
|
|
||||||
ans *= 2L;
|
|
||||||
continue;
|
|
||||||
case 'b':
|
|
||||||
ans *= 512L;
|
|
||||||
continue;
|
|
||||||
case 'k':
|
|
||||||
ans *= 1024L;
|
|
||||||
continue;
|
|
||||||
case 'x':
|
|
||||||
pch = pc;
|
|
||||||
ans *= (long) num();
|
|
||||||
case EOS:
|
|
||||||
if ((ans >= BIGNUM) || (ans < 0)) {
|
|
||||||
fprintf(stderr, "dd: argument %s out of range\n",
|
|
||||||
errorp);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
return((int) ans);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SWAB 0x0001
|
|
||||||
#define LCASE 0x0002
|
|
||||||
#define UCASE 0x0004
|
|
||||||
#define NOERROR 0x0008
|
|
||||||
#define SYNC 0x0010
|
|
||||||
#define SILENT 0x0020
|
|
||||||
#define NOTRUNC 0x0040
|
|
||||||
#define BLANK ' '
|
|
||||||
#define DEFAULT 512
|
|
||||||
|
|
||||||
unsigned cbs, bs, skip, nseek, count;
|
|
||||||
int seekseen = FALSE;
|
|
||||||
unsigned ibs = DEFAULT;
|
|
||||||
unsigned obs = DEFAULT;
|
|
||||||
unsigned files = 1;
|
|
||||||
char *ifilename = NULL;
|
|
||||||
char *ofilename = NULL;
|
|
||||||
|
|
||||||
int convflag = 0;
|
|
||||||
int flag = 0;
|
|
||||||
int ifd, ofd, ibc;
|
|
||||||
char *ibuf, *obuf, *op;
|
|
||||||
unsigned nifull, nipartial, nofull, nopartial;
|
|
||||||
int cbc;
|
|
||||||
unsigned ntr, obc;
|
|
||||||
int ns;
|
|
||||||
char mlen[] = {64, 45, 82, 45, 83, 96, 109, 100, 109, 97, 96, 116, 108, 9};
|
|
||||||
|
|
||||||
void puto()
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
if (obc == 0) return;
|
|
||||||
if (obc == obs)
|
|
||||||
nofull++;
|
|
||||||
else
|
|
||||||
nopartial++;
|
|
||||||
if ((n = write(ofd, obuf, obc)) != obc) {
|
|
||||||
if (n == -1) {
|
|
||||||
fprintf(stderr, "dd: Write error: %s\n", strerror(errno));
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "dd: Short write, %d instead of %d\n", n, obc);
|
|
||||||
}
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
obc = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void statistics()
|
|
||||||
{
|
|
||||||
if (convflag & SILENT) return;
|
|
||||||
fprintf(stderr, "%u+%u records in\n", nifull, nipartial);
|
|
||||||
fprintf(stderr, "%u+%u records out\n", nofull, nopartial);
|
|
||||||
if (ntr) fprintf(stderr, "%d truncated records\n", ntr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(argc, argv)
|
|
||||||
int argc;
|
|
||||||
char *argv[];
|
|
||||||
{
|
|
||||||
#ifdef __STDC__
|
|
||||||
void (*convert) (int);
|
|
||||||
#else
|
|
||||||
void (*convert) ();
|
|
||||||
#endif
|
|
||||||
char *iptr;
|
|
||||||
int i, j, oflags;
|
|
||||||
|
|
||||||
convert = null;
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
while (argc-- > 0) {
|
|
||||||
pch = *(argv++);
|
|
||||||
if (is("ibs=")) {
|
|
||||||
errorp = pch;
|
|
||||||
ibs = num();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("obs=")) {
|
|
||||||
errorp = pch;
|
|
||||||
obs = num();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("bs=")) {
|
|
||||||
errorp = pch;
|
|
||||||
bs = num();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("if=")) {
|
|
||||||
ifilename = pch;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("of=")) {
|
|
||||||
ofilename = pch;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("skip=")) {
|
|
||||||
errorp = pch;
|
|
||||||
skip = num();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("seek=")) {
|
|
||||||
errorp = pch;
|
|
||||||
nseek = num();
|
|
||||||
seekseen = TRUE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("count=")) {
|
|
||||||
errorp = pch;
|
|
||||||
count = num();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("files=")) {
|
|
||||||
errorp = pch;
|
|
||||||
files = num();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("length=")) {
|
|
||||||
errorp = pch;
|
|
||||||
for (j = 0; j < 13; j++) mlen[j]++;
|
|
||||||
write(2, mlen, 14);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("conv=")) {
|
|
||||||
while (*pch != EOS) {
|
|
||||||
if (is("lcase")) {
|
|
||||||
convflag |= LCASE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("ucase")) {
|
|
||||||
convflag |= UCASE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("noerror")) {
|
|
||||||
convflag |= NOERROR;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("notrunc")) {
|
|
||||||
convflag |= NOTRUNC;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("sync")) {
|
|
||||||
convflag |= SYNC;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("swab")) {
|
|
||||||
convflag |= SWAB;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is("silent")) {
|
|
||||||
convflag |= SILENT;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is(",")) continue;
|
|
||||||
fprintf(stderr, "dd: bad argument: %s\n",
|
|
||||||
pch);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (*pch == EOS) continue;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "dd: bad argument: %s\n", pch);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if ((convert == null) && (convflag & (UCASE | LCASE))) convert = cnull;
|
|
||||||
if ((ifd = ((ifilename) ? open(ifilename, O_RDONLY) : dup(0))) < 0) {
|
|
||||||
fprintf(stderr, "dd: Can't open %s: %s\n",
|
|
||||||
(ifilename) ? ifilename : "stdin", strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
oflags = O_WRONLY | O_CREAT;
|
|
||||||
if (!seekseen && (convflag & NOTRUNC) != NOTRUNC)
|
|
||||||
oflags |= O_TRUNC;
|
|
||||||
if ((ofd = ((ofilename) ? open(ofilename, oflags, 0666)
|
|
||||||
: dup(1))) < 0) {
|
|
||||||
fprintf(stderr, "dd: Can't open %s: %s\n",
|
|
||||||
(ofilename) ? ofilename : "stdout", strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (bs) {
|
|
||||||
ibs = obs = bs;
|
|
||||||
if (convert == null) flag++;
|
|
||||||
}
|
|
||||||
if (ibs == 0) {
|
|
||||||
fprintf(stderr, "dd: ibs cannot be zero\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (obs == 0) {
|
|
||||||
fprintf(stderr, "dd: obs cannot be zero\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if ((ibuf = sbrk(ibs)) == (char *) -1) {
|
|
||||||
fprintf(stderr, "dd: not enough memory\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if ((obuf = (flag) ? ibuf : sbrk(obs)) == (char *) -1) {
|
|
||||||
fprintf(stderr, "dd: not enough memory\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
ibc = obc = cbc = 0;
|
|
||||||
op = obuf;
|
|
||||||
if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, over);
|
|
||||||
if (skip != 0) {
|
|
||||||
struct stat st;
|
|
||||||
if (fstat(ifd,&st) < 0 || !(S_ISREG(st.st_mode) || S_ISBLK(st.st_mode))
|
|
||||||
|| lseek(ifd, (off_t) ibs * (off_t) skip, SEEK_SET) == (off_t) -1) {
|
|
||||||
do {
|
|
||||||
if (read(ifd, ibuf, ibs) == -1) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"dd: Error skipping input: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
} while (--skip != 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (nseek != 0) {
|
|
||||||
if (lseek(ofd, (off_t) obs * (off_t) nseek, SEEK_SET) == (off_t) -1) {
|
|
||||||
fprintf(stderr, "dd: Seeking on output failed: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
outputall:
|
|
||||||
if (ibc-- == 0) {
|
|
||||||
ibc = 0;
|
|
||||||
if ((count == 0) || ((nifull + nipartial) != count)) {
|
|
||||||
if (convflag & (NOERROR | SYNC))
|
|
||||||
for (iptr = ibuf + ibs; iptr > ibuf;) *--iptr = 0;
|
|
||||||
ibc = read(ifd, ibuf, ibs);
|
|
||||||
}
|
|
||||||
if (ibc == -1) {
|
|
||||||
fprintf(stderr, "dd: Read error: %s\n", strerror(errno));
|
|
||||||
if ((convflag & NOERROR) == 0) {
|
|
||||||
puto();
|
|
||||||
over(0);
|
|
||||||
}
|
|
||||||
ibc = 0;
|
|
||||||
for (i = 0; i < ibs; i++)
|
|
||||||
if (ibuf[i] != 0) ibc = i;
|
|
||||||
statistics();
|
|
||||||
}
|
|
||||||
if ((ibc == 0) && (--files <= 0)) {
|
|
||||||
puto();
|
|
||||||
over(0);
|
|
||||||
}
|
|
||||||
if (ibc != ibs) {
|
|
||||||
nipartial++;
|
|
||||||
if (convflag & SYNC) ibc = ibs;
|
|
||||||
} else
|
|
||||||
nifull++;
|
|
||||||
iptr = ibuf;
|
|
||||||
i = ibc >> 1;
|
|
||||||
if ((convflag & SWAB) && i) do {
|
|
||||||
int temp;
|
|
||||||
temp = *iptr++;
|
|
||||||
iptr[-1] = *iptr;
|
|
||||||
*iptr++ = temp;
|
|
||||||
} while (--i);
|
|
||||||
iptr = ibuf;
|
|
||||||
if (flag) {
|
|
||||||
obc = ibc;
|
|
||||||
puto();
|
|
||||||
ibc = 0;
|
|
||||||
}
|
|
||||||
goto outputall;
|
|
||||||
}
|
|
||||||
i = *iptr++ & 0377;
|
|
||||||
(*convert) (i);
|
|
||||||
goto outputall;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ulcase(c)
|
|
||||||
int c;
|
|
||||||
{
|
|
||||||
int ans = c;
|
|
||||||
|
|
||||||
if ((convflag & UCASE) && (c >= 'a') &&
|
|
||||||
(c <= 'z'))
|
|
||||||
ans += 'A' - 'a';
|
|
||||||
if ((convflag & LCASE) && (c >= 'A') &&
|
|
||||||
(c <= 'Z'))
|
|
||||||
ans += 'a' - 'A';
|
|
||||||
return(ans);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cnull(c)
|
|
||||||
int c;
|
|
||||||
{
|
|
||||||
c = ulcase(c);
|
|
||||||
null(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void null(c)
|
|
||||||
int c;
|
|
||||||
{
|
|
||||||
*op++ = c;
|
|
||||||
if (++obc >= obs) {
|
|
||||||
puto();
|
|
||||||
op = obuf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void extra()
|
|
||||||
{
|
|
||||||
if (++cbc >= cbs) {
|
|
||||||
null('\n');
|
|
||||||
cbc = 0;
|
|
||||||
ns = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void over(sig)
|
|
||||||
int sig;
|
|
||||||
{
|
|
||||||
statistics();
|
|
||||||
if (sig != 0) {
|
|
||||||
signal(sig, SIG_DFL);
|
|
||||||
raise(sig);
|
|
||||||
}
|
|
||||||
exit(0);
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
MAN= at.1 \
|
MAN= at.1 \
|
||||||
bsfilt.1 cawf.1 chgrp.1 \
|
bsfilt.1 cawf.1 chgrp.1 \
|
||||||
cmp.1 compress.1 \
|
cmp.1 compress.1 \
|
||||||
crc.1 crontab.1 dd.1 \
|
crc.1 crontab.1 \
|
||||||
dhrystone.1 dosdir.1 dosread.1 doswrite.1 \
|
dhrystone.1 dosdir.1 dosread.1 doswrite.1 \
|
||||||
eject.1 \
|
eject.1 \
|
||||||
flexdoc.1 format.1 \
|
flexdoc.1 format.1 \
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
.TH DD 1
|
|
||||||
.SH NAME
|
|
||||||
dd \- convert and copy a file
|
|
||||||
.SH SYNOPSIS
|
|
||||||
\fBdd\fR [\fIoption = value\fR] ...\fR
|
|
||||||
.br
|
|
||||||
.de FL
|
|
||||||
.TP
|
|
||||||
\\fB\\$1\\fR
|
|
||||||
\\$2
|
|
||||||
..
|
|
||||||
.de EX
|
|
||||||
.TP 20
|
|
||||||
\\fB\\$1\\fR
|
|
||||||
# \\$2
|
|
||||||
..
|
|
||||||
.SH EXAMPLES
|
|
||||||
.TP 20
|
|
||||||
.B dd if=/dev/fd0 of=/dev/fd1
|
|
||||||
# Copy disk 0 to disk 1
|
|
||||||
.TP 20
|
|
||||||
.B dd if=x of=y bs=1w skip=4
|
|
||||||
# Copy \fIx\fP to \fIy\fP, skipping 4 words
|
|
||||||
.TP 20
|
|
||||||
.B dd if=x of=y count=3
|
|
||||||
# Copy three 512\-byte blocks
|
|
||||||
.SH DESCRIPTION
|
|
||||||
.PP
|
|
||||||
This command is intended for copying partial files.
|
|
||||||
The block size, skip count, and number of blocks to copy can be specified.
|
|
||||||
The options are:
|
|
||||||
.PP
|
|
||||||
.ta 0.25i 1.5i
|
|
||||||
\fBif\fR = file \- Input file (default is \fIstdin\fR)
|
|
||||||
.br
|
|
||||||
\fBof\fR = file \- Output file (default is standard output)
|
|
||||||
.br
|
|
||||||
\fBibs\fR = n \- Input block size (default 512 bytes)
|
|
||||||
.br
|
|
||||||
\fBobs\fR = n \- Output block size (default is 512 bytes)
|
|
||||||
.br
|
|
||||||
\fBbs\fR = n \- Block size; sets \fIibs\fP and \fIobs\fP (default is 512 bytes)
|
|
||||||
.br
|
|
||||||
\fBskip\fR = n \- Skip \fIn\fP input blocks before reading
|
|
||||||
.br
|
|
||||||
\fBseek\fR = n \- Skip \fIn\fP output blocks before writing
|
|
||||||
.br
|
|
||||||
\fBcount\fR = n \- Copy only \fIn\fP input blocks
|
|
||||||
.br
|
|
||||||
\fBconv = lcase\fR \- Convert upper case letters to lower case
|
|
||||||
.br
|
|
||||||
\fBconv = ucase\fR \- Convert lower case letters to upper case
|
|
||||||
.br
|
|
||||||
\fBconv = swab\fR \- Swap every pair of bytes
|
|
||||||
.br
|
|
||||||
\fBconv = noerror\fR \- Ignore errors and just keep going
|
|
||||||
.br
|
|
||||||
\fBconv = notrunc\fR \- Do not truncate unmodified blocks
|
|
||||||
.br
|
|
||||||
\fBconv = silent\fR \- Suppress statistics (MINIX 3 specific flag)
|
|
||||||
.PP
|
|
||||||
Where sizes are expected, they are in bytes.
|
|
||||||
However, the letters \fBw\fR, \fBb\fR, or \fBk\fR may be appended to the
|
|
||||||
number to indicate words (2 bytes), blocks (512 bytes), or K
|
|
||||||
(1024 bytes), respectively.
|
|
||||||
When
|
|
||||||
.I dd
|
|
||||||
is finished, it reports the number of full and partial blocks read and written.
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
.BR vol (1).
|
|
Loading…
Reference in a new issue