diff --git a/bin/dd/Makefile b/bin/dd/Makefile index ab33aed85499..20f0522a5468 100644 --- a/bin/dd/Makefile +++ b/bin/dd/Makefile @@ -15,6 +15,7 @@ MAINTAINER= green@FreeBSD.org test: ${PROG} cc ${.CURDIR}/gen.c .for conv in ascii ebcdic ibm oldascii oldebcdic oldibm \ + pareven parnone parodd parset \ swab lcase ucase @echo testing conv=${conv} @./a.out | \ diff --git a/bin/dd/args.c b/bin/dd/args.c index b629b3ad4e44..2b17f1e83999 100644 --- a/bin/dd/args.c +++ b/bin/dd/args.c @@ -299,6 +299,10 @@ static const struct conv { { "oldebcdic", C_EBCDIC, C_ASCII, a2e_32V }, { "oldibm", C_EBCDIC, C_ASCII, a2ibm_32V }, { "osync", C_OSYNC, C_BS, NULL }, + { "pareven", C_PAREVEN, C_PARODD|C_PARSET|C_PARNONE, NULL}, + { "parnone", C_PARNONE, C_PARODD|C_PARSET|C_PAREVEN, NULL}, + { "parodd", C_PARODD, C_PAREVEN|C_PARSET|C_PARNONE, NULL}, + { "parset", C_PARSET, C_PARODD|C_PAREVEN|C_PARNONE, NULL}, { "sparse", C_SPARSE, 0, NULL }, { "swab", C_SWAB, 0, NULL }, { "sync", C_SYNC, 0, NULL }, diff --git a/bin/dd/dd.1 b/bin/dd/dd.1 index 588b62f95b9b..31150fd9decb 100644 --- a/bin/dd/dd.1 +++ b/bin/dd/dd.1 @@ -231,6 +231,13 @@ and systems. .It Cm lcase Transform uppercase characters into lowercase characters. +.It Cm pareven , parnone , parodd , parset +Output data with the specified parity. +The parity bit on input is stripped unless +.Tn EBCDIC +to +.Tn ASCII +conversions is also specified. .It Cm noerror Do not stop processing on an input error. When an input error occurs, a diagnostic message followed by the current @@ -355,6 +362,19 @@ be written to the standard error output in the same format as the standard completion message and .Nm will exit. +.Sh EXAMPLES +Check that a disk drive contains no bad blocks: +.Dl dd if=/dev/ad0 of=/dev/null bs=1m +.Pp +Do a refresh of a disk drive, in order to prevent presently +recoverable read errors from progressing into unrecoverable read errors: +.Dl dd if=/dev/ad0 of=/dev/ad0 bs=1m +.Pp +Remove parity bit from a file +.Dl dd if=file conv=parnone of=file.txt +.Pp +Check for (even) parity errors on a file: +.Dl dd if=file conv=pareven | cmp -x - file .Sh DIAGNOSTICS .Ex -std .Sh SEE ALSO diff --git a/bin/dd/dd.c b/bin/dd/dd.c index 9deac8a21a68..cb6127cd37a6 100644 --- a/bin/dd/dd.c +++ b/bin/dd/dd.c @@ -104,6 +104,16 @@ main(int argc __unused, char *argv[]) exit(0); } +static int +parity(u_char c) +{ + int i; + + i = c ^ (c >> 1) ^ (c >> 2) ^ (c >> 3) ^ + (c >> 4) ^ (c >> 5) ^ (c >> 6) ^ (c >> 7); + return (i & 1); +} + static void setup(void) { @@ -176,29 +186,52 @@ setup(void) if (ftruncate(out.fd, out.offset * out.dbsz) == -1) err(1, "truncating %s", out.name); - /* - * 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)) { - if (ddflags & (C_ASCII | C_EBCDIC)) { - if (ddflags & C_LCASE) { - for (cnt = 0; cnt <= 0377; ++cnt) - casetab[cnt] = tolower(ctab[cnt]); - } else { - for (cnt = 0; cnt <= 0377; ++cnt) - casetab[cnt] = toupper(ctab[cnt]); - } + if (ddflags & (C_LCASE | C_UCASE | C_ASCII | C_EBCDIC | C_PARITY)) { + if (ctab != NULL) { + for (cnt = 0; cnt <= 0377; ++cnt) + casetab[cnt] = ctab[cnt]; } else { - if (ddflags & C_LCASE) { - for (cnt = 0; cnt <= 0377; ++cnt) - casetab[cnt] = tolower((int)cnt); - } else { - for (cnt = 0; cnt <= 0377; ++cnt) - casetab[cnt] = toupper((int)cnt); - } + for (cnt = 0; cnt <= 0377; ++cnt) + casetab[cnt] = cnt; } + if ((ddflags & C_PARITY) && !(ddflags & C_ASCII)) { + /* + * If the input is not EBCDIC, and we do parity + * processing, strip input parity. + */ + for (cnt = 200; cnt <= 0377; ++cnt) + casetab[cnt] = casetab[cnt & 0x7f]; + } + if (ddflags & C_LCASE) { + for (cnt = 0; cnt <= 0377; ++cnt) + casetab[cnt] = tolower(casetab[cnt]); + } else if (ddflags & C_UCASE) { + for (cnt = 0; cnt <= 0377; ++cnt) + casetab[cnt] = toupper(casetab[cnt]); + } + if ((ddflags & C_PARITY)) { + /* + * This should strictly speaking be a no-op, but I + * wonder what funny LANG settings could get us. + */ + for (cnt = 0; cnt <= 0377; ++cnt) + casetab[cnt] = casetab[cnt] & 0x7f; + } + if ((ddflags & C_PARSET)) { + for (cnt = 0; cnt <= 0377; ++cnt) + casetab[cnt] = casetab[cnt] | 0x80; + } + if ((ddflags & C_PAREVEN)) { + for (cnt = 0; cnt <= 0377; ++cnt) + if (parity(casetab[cnt])) + casetab[cnt] = casetab[cnt] | 0x80; + } + if ((ddflags & C_PARODD)) { + for (cnt = 0; cnt <= 0377; ++cnt) + if (!parity(casetab[cnt])) + casetab[cnt] = casetab[cnt] | 0x80; + } + ctab = casetab; } diff --git a/bin/dd/dd.h b/bin/dd/dd.h index c6211d9fb766..fbe7ce06d96f 100644 --- a/bin/dd/dd.h +++ b/bin/dd/dd.h @@ -95,3 +95,9 @@ typedef struct { #define C_UNBLOCK 0x80000 #define C_OSYNC 0x100000 #define C_SPARSE 0x200000 +#define C_PAREVEN 0x400000 +#define C_PARODD 0x800000 +#define C_PARSET 0x1000000 +#define C_PARNONE 0x2000000 + +#define C_PARITY (C_PAREVEN|C_PARODD|C_PARSET|C_PARNONE) diff --git a/bin/dd/ref.pareven b/bin/dd/ref.pareven new file mode 100644 index 000000000000..c64e63e30660 --- /dev/null +++ b/bin/dd/ref.pareven @@ -0,0 +1,18 @@ +$FreeBSD$ +00000000 00 81 82 03 84 05 06 87 88 09 0a 8b 0c 8d 8e 0f |................| +00000010 90 11 12 93 14 95 96 17 18 99 9a 1b 9c 1d 1e 9f |................| +00000020 a0 21 22 a3 24 a5 a6 27 28 a9 aa 2b ac 2d 2e af |.!".$..'(..+.-..| +00000030 30 b1 b2 33 b4 35 36 b7 b8 39 3a bb 3c bd be 3f |0..3.56..9:.<..?| +00000040 c0 41 42 c3 44 c5 c6 47 48 c9 ca 4b cc 4d 4e cf |.AB.D..GH..K.MN.| +00000050 50 d1 d2 53 d4 55 56 d7 d8 59 5a db 5c dd de 5f |P..S.UV..YZ.\.._| +00000060 60 e1 e2 63 e4 65 66 e7 e8 69 6a eb 6c ed ee 6f |`..c.ef..ij.l..o| +00000070 f0 71 72 f3 74 f5 f6 77 78 f9 fa 7b fc 7d 7e ff |.qr.t..wx..{.}~.| +00000080 00 81 82 03 84 05 06 87 88 09 0a 8b 0c 8d 8e 0f |................| +00000090 90 11 12 93 14 95 96 17 18 99 9a 1b 9c 1d 1e 9f |................| +000000a0 a0 21 22 a3 24 a5 a6 27 28 a9 aa 2b ac 2d 2e af |.!".$..'(..+.-..| +000000b0 30 b1 b2 33 b4 35 36 b7 b8 39 3a bb 3c bd be 3f |0..3.56..9:.<..?| +000000c0 c0 41 42 c3 44 c5 c6 47 48 c9 ca 4b cc 4d 4e cf |.AB.D..GH..K.MN.| +000000d0 50 d1 d2 53 d4 55 56 d7 d8 59 5a db 5c dd de 5f |P..S.UV..YZ.\.._| +000000e0 60 e1 e2 63 e4 65 66 e7 e8 69 6a eb 6c ed ee 6f |`..c.ef..ij.l..o| +000000f0 f0 71 72 f3 74 f5 f6 77 78 f9 fa 7b fc 7d 7e ff |.qr.t..wx..{.}~.| +00000100 diff --git a/bin/dd/ref.parnone b/bin/dd/ref.parnone new file mode 100644 index 000000000000..fba31c142448 --- /dev/null +++ b/bin/dd/ref.parnone @@ -0,0 +1,18 @@ +$FreeBSD$ +00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| +00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| +00000020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./| +00000030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f |0123456789:;<=>?| +00000040 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f |@ABCDEFGHIJKLMNO| +00000050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_| +00000060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno| +00000070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.| +00000080 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................| +00000090 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................| +000000a0 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f | !"#$%&'()*+,-./| +000000b0 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f |0123456789:;<=>?| +000000c0 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f |@ABCDEFGHIJKLMNO| +000000d0 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f |PQRSTUVWXYZ[\]^_| +000000e0 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f |`abcdefghijklmno| +000000f0 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f |pqrstuvwxyz{|}~.| +00000100 diff --git a/bin/dd/ref.parodd b/bin/dd/ref.parodd new file mode 100644 index 000000000000..f0bc449e3648 --- /dev/null +++ b/bin/dd/ref.parodd @@ -0,0 +1,18 @@ +$FreeBSD$ +00000000 80 01 02 83 04 85 86 07 08 89 8a 0b 8c 0d 0e 8f |................| +00000010 10 91 92 13 94 15 16 97 98 19 1a 9b 1c 9d 9e 1f |................| +00000020 20 a1 a2 23 a4 25 26 a7 a8 29 2a ab 2c ad ae 2f | ..#.%&..)*.,../| +00000030 b0 31 32 b3 34 b5 b6 37 38 b9 ba 3b bc 3d 3e bf |.12.4..78..;.=>.| +00000040 40 c1 c2 43 c4 45 46 c7 c8 49 4a cb 4c cd ce 4f |@..C.EF..IJ.L..O| +00000050 d0 51 52 d3 54 d5 d6 57 58 d9 da 5b dc 5d 5e df |.QR.T..WX..[.]^.| +00000060 e0 61 62 e3 64 e5 e6 67 68 e9 ea 6b ec 6d 6e ef |.ab.d..gh..k.mn.| +00000070 70 f1 f2 73 f4 75 76 f7 f8 79 7a fb 7c fd fe 7f |p..s.uv..yz.|...| +00000080 80 01 02 83 04 85 86 07 08 89 8a 0b 8c 0d 0e 8f |................| +00000090 10 91 92 13 94 15 16 97 98 19 1a 9b 1c 9d 9e 1f |................| +000000a0 20 a1 a2 23 a4 25 26 a7 a8 29 2a ab 2c ad ae 2f | ..#.%&..)*.,../| +000000b0 b0 31 32 b3 34 b5 b6 37 38 b9 ba 3b bc 3d 3e bf |.12.4..78..;.=>.| +000000c0 40 c1 c2 43 c4 45 46 c7 c8 49 4a cb 4c cd ce 4f |@..C.EF..IJ.L..O| +000000d0 d0 51 52 d3 54 d5 d6 57 58 d9 da 5b dc 5d 5e df |.QR.T..WX..[.]^.| +000000e0 e0 61 62 e3 64 e5 e6 67 68 e9 ea 6b ec 6d 6e ef |.ab.d..gh..k.mn.| +000000f0 70 f1 f2 73 f4 75 76 f7 f8 79 7a fb 7c fd fe 7f |p..s.uv..yz.|...| +00000100 diff --git a/bin/dd/ref.parset b/bin/dd/ref.parset new file mode 100644 index 000000000000..baa1c57163a2 --- /dev/null +++ b/bin/dd/ref.parset @@ -0,0 +1,18 @@ +$FreeBSD$ +00000000 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................| +00000010 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................| +00000020 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................| +00000030 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................| +00000040 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................| +00000050 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................| +00000060 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| +00000070 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................| +00000080 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f |................| +00000090 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f |................| +000000a0 a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af |................| +000000b0 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf |................| +000000c0 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf |................| +000000d0 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df |................| +000000e0 e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef |................| +000000f0 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff |................| +00000100