summaryrefslogtreecommitdiffstats
path: root/bin/dd/dd.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-03-05 19:35:51 +0000
committerphk <phk@FreeBSD.org>2004-03-05 19:35:51 +0000
commitd0818243a98d068bca04404ffdf26cdcfd64b0d0 (patch)
tree255c7e9c97c457694b6ee81156e5b2ffe6ab693b /bin/dd/dd.c
parent99a4684d724673ae90d63adc80a14fa2b42d2bb5 (diff)
downloadFreeBSD-src-d0818243a98d068bca04404ffdf26cdcfd64b0d0.zip
FreeBSD-src-d0818243a98d068bca04404ffdf26cdcfd64b0d0.tar.gz
Teach dd(1) about parity bits.
Diffstat (limited to 'bin/dd/dd.c')
-rw-r--r--bin/dd/dd.c75
1 files changed, 54 insertions, 21 deletions
diff --git a/bin/dd/dd.c b/bin/dd/dd.c
index 9deac8a..cb6127c 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;
}
OpenPOWER on IntegriCloud