Importing bin/dd

Change-Id: Ibdfed821aa834419c9713dc80f698c8ed74ff269
This commit is contained in:
Jacob Adams
2015-04-04 21:00:10 -04:00
committed by Lionel Sambuc
parent 9cf6cc5098
commit c19d619d42
19 changed files with 2899 additions and 481 deletions

View File

@@ -6,7 +6,7 @@ SUBDIR= add_route arp at backup btrace \
cawf cdprobe \
ci cleantmp cmp co \
compress crc cron crontab \
dd decomp16 DESCRIBE devmand devsize dhcpd \
decomp16 DESCRIBE devmand devsize dhcpd \
dhrystone diff diskctl \
eject fbdctl \
find fix format fsck.mfs \

View File

@@ -1,6 +0,0 @@
# LSC For now
NOGCCERROR:=yes
PROG= dd
MAN=
.include <bsd.prog.mk>

View File

@@ -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);
}

View File

@@ -1,7 +1,7 @@
MAN= at.1 \
bsfilt.1 cawf.1 chgrp.1 \
cmp.1 compress.1 \
crc.1 crontab.1 dd.1 \
crc.1 crontab.1 \
dhrystone.1 dosdir.1 dosread.1 doswrite.1 \
eject.1 \
flexdoc.1 format.1 \

View File

@@ -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).