mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
dd: update from Plan 9
R=rsc CC=plan9port.codebot http://codereview.appspot.com/4850052
This commit is contained in:
parent
dcdc3af143
commit
11a3ce57b1
2 changed files with 239 additions and 28 deletions
198
man/man1/dd.1
Normal file
198
man/man1/dd.1
Normal file
|
@ -0,0 +1,198 @@
|
|||
.TH DD 1
|
||||
.SH NAME
|
||||
dd \- convert and copy a file
|
||||
.SH SYNOPSIS
|
||||
.B dd
|
||||
[
|
||||
.I option value
|
||||
]
|
||||
\&...
|
||||
.SH DESCRIPTION
|
||||
.I Dd\^
|
||||
copies the specified input file
|
||||
to the specified output with
|
||||
possible conversions.
|
||||
The standard input and output are used by default.
|
||||
The input and output block size may be
|
||||
specified to take advantage of raw physical I/O.
|
||||
The options are
|
||||
.TF "quiet\ \ \fIn
|
||||
.PD
|
||||
.TP
|
||||
.BI -if\ f
|
||||
Open file
|
||||
.I f
|
||||
for input.
|
||||
.TP
|
||||
.BI -of\ f
|
||||
Open file
|
||||
.I f
|
||||
for output.
|
||||
.TP
|
||||
.BI -ibs\ n\^
|
||||
Set input block size to
|
||||
.I n\^
|
||||
bytes (default 512).
|
||||
.TP
|
||||
.BI -obs\ n\^
|
||||
Set output block size (default 512).
|
||||
.TP
|
||||
.BI -bs\ n\^
|
||||
Set both input and output block size,
|
||||
superseding
|
||||
.I ibs\^
|
||||
and
|
||||
.IR obs .
|
||||
If no conversion is specified,
|
||||
preserve the input block size instead of packing short blocks
|
||||
into the output buffer.
|
||||
This is particularly efficient since no in-core copy need be done.
|
||||
.TP
|
||||
.BI -cbs\ n\^
|
||||
Set conversion buffer size.
|
||||
.TP
|
||||
.BI -skip\ n\^
|
||||
Skip
|
||||
.I n
|
||||
input records before copying.
|
||||
.TP
|
||||
.BI -iseek\ n\^
|
||||
Seek
|
||||
.I n
|
||||
records forward on input file
|
||||
before copying.
|
||||
.TP
|
||||
.BI -files\ n\^
|
||||
Catenate
|
||||
.I n
|
||||
input files (useful only for magnetic tape or similar input device).
|
||||
.TP
|
||||
.BI -oseek\ n\^
|
||||
Seek
|
||||
.I n\^
|
||||
records from beginning of output file before copying.
|
||||
.TP
|
||||
.BI -count\ n\^
|
||||
Copy only
|
||||
.I n
|
||||
input records.
|
||||
.TP
|
||||
.BI -trunc\ n\^
|
||||
By default,
|
||||
.I dd
|
||||
truncates the output file when it opens it;
|
||||
.B -trunc
|
||||
.B 0
|
||||
opens it without truncation.
|
||||
.TP
|
||||
.BI -quiet\ n\^
|
||||
By default,
|
||||
.I dd
|
||||
prints the number of blocks read and written
|
||||
once it is finished.
|
||||
.B -quiet
|
||||
.B 1
|
||||
silences this summary.
|
||||
.HP
|
||||
\fL-conv\ ascii\ \ \ \ \fRConvert
|
||||
.SM EBCDIC
|
||||
to
|
||||
.SM ASCII.
|
||||
.PD0
|
||||
.RS "\w'\fLconv\ \fP'u"
|
||||
.TP "\w'\fLunblock\ \ \fP'u"
|
||||
.B ebcdic
|
||||
Convert
|
||||
.SM ASCII
|
||||
to
|
||||
.SM EBCDIC.
|
||||
.TP
|
||||
.B ibm
|
||||
Like
|
||||
.B ebcdic
|
||||
but with a slightly different character map.
|
||||
.TP
|
||||
.B block
|
||||
Convert variable length
|
||||
.SM ASCII
|
||||
records to fixed length.
|
||||
.TP
|
||||
.B unblock
|
||||
Convert fixed length
|
||||
.SM ASCII
|
||||
records to variable length.
|
||||
.TP
|
||||
.B lcase
|
||||
Map alphabetics to lower case.
|
||||
.TP
|
||||
.B ucase
|
||||
Map alphabetics to upper case.
|
||||
.TP
|
||||
.B swab
|
||||
Swap every pair of bytes.
|
||||
.TP
|
||||
.B noerror
|
||||
Do not stop processing on an error.
|
||||
.TP
|
||||
.B sync
|
||||
Pad every input record to
|
||||
.I ibs\^
|
||||
bytes.
|
||||
.RE
|
||||
.PD
|
||||
.PP
|
||||
.fi
|
||||
Where sizes are specified,
|
||||
a number of bytes is expected.
|
||||
A number may end with
|
||||
.L k
|
||||
or
|
||||
.LR b
|
||||
to specify multiplication by
|
||||
1024 or 512 respectively;
|
||||
a pair of numbers may be separated by
|
||||
.L x
|
||||
to indicate a product.
|
||||
Multiple conversions may be specified in the style:
|
||||
.LR "-conv ebcdic,ucase" .
|
||||
.PP
|
||||
.L Cbs\^
|
||||
is used only if
|
||||
.LR ascii\^ ,
|
||||
.LR unblock\^ ,
|
||||
.LR ebcdic\^ ,
|
||||
.LR ibm\^ ,
|
||||
or
|
||||
.L block\^
|
||||
conversion is specified.
|
||||
In the first two cases,
|
||||
.I n
|
||||
characters are copied into the conversion buffer, any specified
|
||||
character mapping is done,
|
||||
trailing blanks are trimmed and new-line is added
|
||||
before sending the line to the output.
|
||||
In the latter three cases, characters are read into the
|
||||
conversion buffer and blanks are added to make up an
|
||||
output record of size
|
||||
.IR n .
|
||||
If
|
||||
.L cbs\^
|
||||
is unspecified or zero, the
|
||||
.LR ascii\^ ,
|
||||
.LR ebcdic\^ ,
|
||||
and
|
||||
.L ibm\^
|
||||
options convert the character set without changing the block
|
||||
structure of the input file; the
|
||||
.L unblock\^
|
||||
and
|
||||
.L block\^
|
||||
options become a simple file copy.
|
||||
.SH SOURCE
|
||||
.B \*9/src/cmd/dd.c
|
||||
.SH "SEE ALSO"
|
||||
.IR cp (1)
|
||||
.SH DIAGNOSTICS
|
||||
.I Dd
|
||||
reports the number of full + partial input and output
|
||||
blocks handled.
|
69
src/cmd/dd.c
69
src/cmd/dd.c
|
@ -1,23 +1,28 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
#define BIG 2147483647
|
||||
#define BIG ((1UL<<31)-1)
|
||||
#define VBIG ((1ULL<<63)-1)
|
||||
#define LCASE (1<<0)
|
||||
#define UCASE (1<<1)
|
||||
#define SWAB (1<<2)
|
||||
#define NERR (1<<3)
|
||||
#define SYNC (1<<4)
|
||||
|
||||
int cflag;
|
||||
int fflag;
|
||||
|
||||
char *string;
|
||||
char *ifile;
|
||||
char *ofile;
|
||||
char *ibuf;
|
||||
char *obuf;
|
||||
|
||||
vlong skip;
|
||||
vlong oseekn;
|
||||
vlong iseekn;
|
||||
vlong count;
|
||||
|
||||
long files = 1;
|
||||
long ibs = 512;
|
||||
long obs = 512;
|
||||
|
@ -31,18 +36,23 @@ long nipr;
|
|||
long nofr;
|
||||
long nopr;
|
||||
long ntrunc;
|
||||
|
||||
int dotrunc = 1;
|
||||
int ibf;
|
||||
int obf;
|
||||
|
||||
char *op;
|
||||
int nspace;
|
||||
|
||||
uchar etoa[256];
|
||||
uchar atoe[256];
|
||||
uchar atoibm[256];
|
||||
|
||||
int quiet;
|
||||
|
||||
void flsh(void);
|
||||
int match(char *s);
|
||||
vlong number(long big);
|
||||
vlong number(vlong big);
|
||||
void cnull(int cc);
|
||||
void null(int c);
|
||||
void ascii(int cc);
|
||||
|
@ -50,12 +60,12 @@ void unblock(int cc);
|
|||
void ebcdic(int cc);
|
||||
void ibm(int cc);
|
||||
void block(int cc);
|
||||
void term(void);
|
||||
void term(char*);
|
||||
void stats(void);
|
||||
|
||||
#define iskey(s) ((key[0] == '-') && (strcmp(key+1, s) == 0))
|
||||
|
||||
void
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
void (*conv)(int);
|
||||
|
@ -99,20 +109,24 @@ main(int argc, char *argv[])
|
|||
dotrunc = number(BIG);
|
||||
continue;
|
||||
}
|
||||
if(iskey("quiet")) {
|
||||
quiet = number(BIG);
|
||||
continue;
|
||||
}
|
||||
if(iskey("skip")) {
|
||||
skip = number(BIG);
|
||||
skip = number(VBIG);
|
||||
continue;
|
||||
}
|
||||
if(iskey("seek") || iskey("oseek")) {
|
||||
oseekn = number(BIG);
|
||||
oseekn = number(VBIG);
|
||||
continue;
|
||||
}
|
||||
if(iskey("iseek")) {
|
||||
iseekn = number(BIG);
|
||||
iseekn = number(VBIG);
|
||||
continue;
|
||||
}
|
||||
if(iskey("count")) {
|
||||
count = number(BIG);
|
||||
count = number(VBIG);
|
||||
continue;
|
||||
}
|
||||
if(iskey("files")) {
|
||||
|
@ -165,6 +179,8 @@ main(int argc, char *argv[])
|
|||
cflag |= SYNC;
|
||||
goto cloop;
|
||||
}
|
||||
fprint(2, "dd: bad conv %s\n", argv[c]);
|
||||
exits("arg");
|
||||
}
|
||||
fprint(2, "dd: bad arg: %s\n", key);
|
||||
exits("arg");
|
||||
|
@ -243,17 +259,17 @@ loop:
|
|||
perror("read");
|
||||
if((cflag&NERR) == 0) {
|
||||
flsh();
|
||||
term();
|
||||
term("errors");
|
||||
}
|
||||
ibc = 0;
|
||||
for(c=0; c<ibs; c++)
|
||||
if(ibuf[c] != 0)
|
||||
ibc = c;
|
||||
ibc = c+1;
|
||||
seek(ibf, ibs, 1);
|
||||
stats();
|
||||
}
|
||||
if(ibc == 0 && --files<=0) {
|
||||
}else if(ibc == 0 && --files<=0) {
|
||||
flsh();
|
||||
term();
|
||||
term(nil);
|
||||
}
|
||||
if(ibc != ibs) {
|
||||
nipr++;
|
||||
|
@ -290,12 +306,14 @@ flsh(void)
|
|||
int c;
|
||||
|
||||
if(obc) {
|
||||
/* don't perror dregs of previous errors on a short write */
|
||||
werrstr("");
|
||||
c = write(obf, obuf, obc);
|
||||
if(c != obc) {
|
||||
if(c > 0)
|
||||
++nopr;
|
||||
perror("write");
|
||||
term();
|
||||
term("errors");
|
||||
}
|
||||
if(obc == obs)
|
||||
nofr++;
|
||||
|
@ -324,10 +342,10 @@ true:
|
|||
}
|
||||
|
||||
vlong
|
||||
number(long big)
|
||||
number(vlong big)
|
||||
{
|
||||
char *cs;
|
||||
vlong n;
|
||||
uvlong n;
|
||||
|
||||
cs = string;
|
||||
n = 0;
|
||||
|
@ -340,11 +358,6 @@ number(long big)
|
|||
n *= 1024;
|
||||
continue;
|
||||
|
||||
/* case 'w':
|
||||
n *= sizeof(int);
|
||||
continue;
|
||||
*/
|
||||
|
||||
case 'b':
|
||||
n *= 512;
|
||||
continue;
|
||||
|
@ -352,11 +365,11 @@ number(long big)
|
|||
/* case '*':*/
|
||||
case 'x':
|
||||
string = cs;
|
||||
n *= number(BIG);
|
||||
n *= number(VBIG);
|
||||
|
||||
case '\0':
|
||||
if(n>=big || n<0) {
|
||||
fprint(2, "dd: argument %lld out of range\n", n);
|
||||
if(n > big) {
|
||||
fprint(2, "dd: argument %llud out of range\n", n);
|
||||
exits("range");
|
||||
}
|
||||
return n;
|
||||
|
@ -536,17 +549,17 @@ block(int cc)
|
|||
}
|
||||
|
||||
void
|
||||
term(void)
|
||||
term(char *status)
|
||||
{
|
||||
|
||||
stats();
|
||||
exits(0);
|
||||
exits(status);
|
||||
}
|
||||
|
||||
void
|
||||
stats(void)
|
||||
{
|
||||
|
||||
if(quiet)
|
||||
return;
|
||||
fprint(2, "%lud+%lud records in\n", nifr, nipr);
|
||||
fprint(2, "%lud+%lud records out\n", nofr, nopr);
|
||||
if(ntrunc)
|
||||
|
|
Loading…
Reference in a new issue