new utilities.
the .C files compile but are renamed to avoid building automatically.
diff --git a/src/cmd/dd.c b/src/cmd/dd.c
new file mode 100644
index 0000000..1559914
--- /dev/null
+++ b/src/cmd/dd.c
@@ -0,0 +1,660 @@
+#include <u.h>
+#include <libc.h>
+
+#define	BIG	2147483647
+#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;
+long	bs;
+long	cbs;
+long	ibc;
+long	obc;
+long	cbc;
+long	nifr;
+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];
+
+void	flsh(void);
+int	match(char *s);
+vlong	number(long big);
+void	cnull(int cc);
+void	null(int c);
+void	ascii(int cc);
+void	unblock(int cc);
+void	ebcdic(int cc);
+void	ibm(int cc);
+void	block(int cc);
+void	term(void);
+void	stats(void);
+
+#define	iskey(s)	((key[0] == '-') && (strcmp(key+1, s) == 0))
+
+void
+main(int argc, char *argv[])
+{
+	void (*conv)(int);
+	char *ip;
+	char *key;
+	int a, c;
+
+	conv = null;
+	for(c=1; c<argc; c++) {
+		key = argv[c++];
+		if(c >= argc){
+			fprint(2, "dd: arg %s needs a value\n", key);
+			exits("arg");
+		}
+		string = argv[c];
+		if(iskey("ibs")) {
+			ibs = number(BIG);
+			continue;
+		}
+		if(iskey("obs")) {
+			obs = number(BIG);
+			continue;
+		}
+		if(iskey("cbs")) {
+			cbs = number(BIG);
+			continue;
+		}
+		if(iskey("bs")) {
+			bs = number(BIG);
+			continue;
+		}
+		if(iskey("if")) {
+			ifile = string;
+			continue;
+		}
+		if(iskey("of")) {
+			ofile = string;
+			continue;
+		}
+		if(iskey("trunc")) {
+			dotrunc = number(BIG);
+			continue;
+		}
+		if(iskey("skip")) {
+			skip = number(BIG);
+			continue;
+		}
+		if(iskey("seek") || iskey("oseek")) {
+			oseekn = number(BIG);
+			continue;
+		}
+		if(iskey("iseek")) {
+			iseekn = number(BIG);
+			continue;
+		}
+		if(iskey("count")) {
+			count = number(BIG);
+			continue;
+		}
+		if(iskey("files")) {
+			files = number(BIG);
+			continue;
+		}
+		if(iskey("conv")) {
+		cloop:
+			if(match(","))
+				goto cloop;
+			if(*string == '\0')
+				continue;
+			if(match("ebcdic")) {
+				conv = ebcdic;
+				goto cloop;
+			}
+			if(match("ibm")) {
+				conv = ibm;
+				goto cloop;
+			}
+			if(match("ascii")) {
+				conv = ascii;
+				goto cloop;
+			}
+			if(match("block")) {
+				conv = block;
+				goto cloop;
+			}
+			if(match("unblock")) {
+				conv = unblock;
+				goto cloop;
+			}
+			if(match("lcase")) {
+				cflag |= LCASE;
+				goto cloop;
+			}
+			if(match("ucase")) {
+				cflag |= UCASE;
+				goto cloop;
+			}
+			if(match("swab")) {
+				cflag |= SWAB;
+				goto cloop;
+			}
+			if(match("noerror")) {
+				cflag |= NERR;
+				goto cloop;
+			}
+			if(match("sync")) {
+				cflag |= SYNC;
+				goto cloop;
+			}
+		}
+		fprint(2, "dd: bad arg: %s\n", key);
+		exits("arg");
+	}
+	if(conv == null && cflag&(LCASE|UCASE))
+		conv = cnull;
+	if(ifile)
+		ibf = open(ifile, 0);
+	else
+		ibf = dup(0, -1);
+	if(ibf < 0) {
+		fprint(2, "dd: open %s: %r\n", ifile);
+		exits("open");
+	}
+	if(ofile){
+		if(dotrunc)
+			obf = create(ofile, 1, 0664);
+		else
+			obf = open(ofile, 1);
+		if(obf < 0) {
+			fprint(2, "dd: create %s: %r\n", ofile);
+			exits("create");
+		}
+	}else{
+		obf = dup(1, -1);
+		if(obf < 0) {
+			fprint(2, "dd: can't dup file descriptor: %s: %r\n", ofile);
+			exits("dup");
+		}
+	}
+	if(bs)
+		ibs = obs = bs;
+	if(ibs == obs && conv == null)
+		fflag++;
+	if(ibs == 0 || obs == 0) {
+		fprint(2, "dd: counts: cannot be zero\n");
+		exits("counts");
+	}
+	ibuf = sbrk(ibs);
+	if(fflag)
+		obuf = ibuf;
+	else
+		obuf = sbrk(obs);
+	sbrk(64);	/* For good measure */
+	if(ibuf == (char *)-1 || obuf == (char *)-1) {
+		fprint(2, "dd: not enough memory: %r\n");
+		exits("memory");
+	}
+	ibc = 0;
+	obc = 0;
+	cbc = 0;
+	op = obuf;
+
+/*
+	if(signal(SIGINT, SIG_IGN) != SIG_IGN)
+		signal(SIGINT, term);
+*/
+	seek(obf, obs*oseekn, 1);
+	seek(ibf, ibs*iseekn, 1);
+	while(skip) {
+		read(ibf, ibuf, ibs);
+		skip--;
+	}
+
+	ip = 0;
+loop:
+	if(ibc-- == 0) {
+		ibc = 0;
+		if(count==0 || nifr+nipr!=count) {
+			if(cflag&(NERR|SYNC))
+			for(ip=ibuf+ibs; ip>ibuf;)
+				*--ip = 0;
+			ibc = read(ibf, ibuf, ibs);
+		}
+		if(ibc == -1) {
+			perror("read");
+			if((cflag&NERR) == 0) {
+				flsh();
+				term();
+			}
+			ibc = 0;
+			for(c=0; c<ibs; c++)
+				if(ibuf[c] != 0)
+					ibc = c;
+			stats();
+		}
+		if(ibc == 0 && --files<=0) {
+			flsh();
+			term();
+		}
+		if(ibc != ibs) {
+			nipr++;
+			if(cflag&SYNC)
+				ibc = ibs;
+		} else
+			nifr++;
+		ip = ibuf;
+		c = (ibc>>1) & ~1;
+		if(cflag&SWAB && c)
+		do {
+			a = *ip++;
+			ip[-1] = *ip;
+			*ip++ = a;
+		} while(--c);
+		ip = ibuf;
+		if(fflag) {
+			obc = ibc;
+			flsh();
+			ibc = 0;
+		}
+		goto loop;
+	}
+	c = 0;
+	c |= *ip++;
+	c &= 0377;
+	(*conv)(c);
+	goto loop;
+}
+
+void
+flsh(void)
+{
+	int c;
+
+	if(obc) {
+		c = write(obf, obuf, obc);
+		if(c != obc) {
+			if(c > 0)
+				++nopr;
+			perror("write");
+			term();
+		}
+		if(obc == obs)
+			nofr++;
+		else
+			nopr++;
+		obc = 0;
+	}
+}
+
+int
+match(char *s)
+{
+	char *cs;
+
+	cs = string;
+	while(*cs++ == *s)
+		if(*s++ == '\0')
+			goto true;
+	if(*s != '\0')
+		return 0;
+
+true:
+	cs--;
+	string = cs;
+	return 1;
+}
+
+vlong
+number(long big)
+{
+	char *cs;
+	vlong n;
+
+	cs = string;
+	n = 0;
+	while(*cs >= '0' && *cs <= '9')
+		n = n*10 + *cs++ - '0';
+	for(;;)
+	switch(*cs++) {
+
+	case 'k':
+		n *= 1024;
+		continue;
+
+/*	case 'w':
+		n *= sizeof(int);
+		continue;
+*/
+
+	case 'b':
+		n *= 512;
+		continue;
+
+/*	case '*':*/
+	case 'x':
+		string = cs;
+		n *= number(BIG);
+
+	case '\0':
+		if(n>=big || n<0) {
+			fprint(2, "dd: argument %lld out of range\n", n);
+			exits("range");
+		}
+		return n;
+	}
+	/* never gets here */
+}
+
+void
+cnull(int cc)
+{
+	int c;
+
+	c = cc;
+	if((cflag&UCASE) && c>='a' && c<='z')
+		c += 'A'-'a';
+	if((cflag&LCASE) && c>='A' && c<='Z')
+		c += 'a'-'A';
+	null(c);
+}
+
+void
+null(int c)
+{
+
+	*op = c;
+	op++;
+	if(++obc >= obs) {
+		flsh();
+		op = obuf;
+	}
+}
+
+void
+ascii(int cc)
+{
+	int c;
+
+	c = etoa[cc];
+	if(cbs == 0) {
+		cnull(c);
+		return;
+	}
+	if(c == ' ') {
+		nspace++;
+		goto out;
+	}
+	while(nspace > 0) {
+		null(' ');
+		nspace--;
+	}
+	cnull(c);
+
+out:
+	if(++cbc >= cbs) {
+		null('\n');
+		cbc = 0;
+		nspace = 0;
+	}
+}
+
+void
+unblock(int cc)
+{
+	int c;
+
+	c = cc & 0377;
+	if(cbs == 0) {
+		cnull(c);
+		return;
+	}
+	if(c == ' ') {
+		nspace++;
+		goto out;
+	}
+	while(nspace > 0) {
+		null(' ');
+		nspace--;
+	}
+	cnull(c);
+
+out:
+	if(++cbc >= cbs) {
+		null('\n');
+		cbc = 0;
+		nspace = 0;
+	}
+}
+
+void
+ebcdic(int cc)
+{
+	int c;
+
+	c = cc;
+	if(cflag&UCASE && c>='a' && c<='z')
+		c += 'A'-'a';
+	if(cflag&LCASE && c>='A' && c<='Z')
+		c += 'a'-'A';
+	c = atoe[c];
+	if(cbs == 0) {
+		null(c);
+		return;
+	}
+	if(cc == '\n') {
+		while(cbc < cbs) {
+			null(atoe[' ']);
+			cbc++;
+		}
+		cbc = 0;
+		return;
+	}
+	if(cbc == cbs)
+		ntrunc++;
+	cbc++;
+	if(cbc <= cbs)
+		null(c);
+}
+
+void
+ibm(int cc)
+{
+	int c;
+
+	c = cc;
+	if(cflag&UCASE && c>='a' && c<='z')
+		c += 'A'-'a';
+	if(cflag&LCASE && c>='A' && c<='Z')
+		c += 'a'-'A';
+	c = atoibm[c] & 0377;
+	if(cbs == 0) {
+		null(c);
+		return;
+	}
+	if(cc == '\n') {
+		while(cbc < cbs) {
+			null(atoibm[' ']);
+			cbc++;
+		}
+		cbc = 0;
+		return;
+	}
+	if(cbc == cbs)
+		ntrunc++;
+	cbc++;
+	if(cbc <= cbs)
+		null(c);
+}
+
+void
+block(int cc)
+{
+	int c;
+
+	c = cc;
+	if(cflag&UCASE && c>='a' && c<='z')
+		c += 'A'-'a';
+	if(cflag&LCASE && c>='A' && c<='Z')
+		c += 'a'-'A';
+	c &= 0377;
+	if(cbs == 0) {
+		null(c);
+		return;
+	}
+	if(cc == '\n') {
+		while(cbc < cbs) {
+			null(' ');
+			cbc++;
+		}
+		cbc = 0;
+		return;
+	}
+	if(cbc == cbs)
+		ntrunc++;
+	cbc++;
+	if(cbc <= cbs)
+		null(c);
+}
+
+void
+term(void)
+{
+
+	stats();
+	exits(0);
+}
+
+void
+stats(void)
+{
+
+	fprint(2, "%lud+%lud records in\n", nifr, nipr);
+	fprint(2, "%lud+%lud records out\n", nofr, nopr);
+	if(ntrunc)
+		fprint(2, "%lud truncated records\n", ntrunc);
+}
+
+uchar	etoa[] =
+{
+	0000,0001,0002,0003,0234,0011,0206,0177,
+	0227,0215,0216,0013,0014,0015,0016,0017,
+	0020,0021,0022,0023,0235,0205,0010,0207,
+	0030,0031,0222,0217,0034,0035,0036,0037,
+	0200,0201,0202,0203,0204,0012,0027,0033,
+	0210,0211,0212,0213,0214,0005,0006,0007,
+	0220,0221,0026,0223,0224,0225,0226,0004,
+	0230,0231,0232,0233,0024,0025,0236,0032,
+	0040,0240,0241,0242,0243,0244,0245,0246,
+	0247,0250,0133,0056,0074,0050,0053,0041,
+	0046,0251,0252,0253,0254,0255,0256,0257,
+	0260,0261,0135,0044,0052,0051,0073,0136,
+	0055,0057,0262,0263,0264,0265,0266,0267,
+	0270,0271,0174,0054,0045,0137,0076,0077,
+	0272,0273,0274,0275,0276,0277,0300,0301,
+	0302,0140,0072,0043,0100,0047,0075,0042,
+	0303,0141,0142,0143,0144,0145,0146,0147,
+	0150,0151,0304,0305,0306,0307,0310,0311,
+	0312,0152,0153,0154,0155,0156,0157,0160,
+	0161,0162,0313,0314,0315,0316,0317,0320,
+	0321,0176,0163,0164,0165,0166,0167,0170,
+	0171,0172,0322,0323,0324,0325,0326,0327,
+	0330,0331,0332,0333,0334,0335,0336,0337,
+	0340,0341,0342,0343,0344,0345,0346,0347,
+	0173,0101,0102,0103,0104,0105,0106,0107,
+	0110,0111,0350,0351,0352,0353,0354,0355,
+	0175,0112,0113,0114,0115,0116,0117,0120,
+	0121,0122,0356,0357,0360,0361,0362,0363,
+	0134,0237,0123,0124,0125,0126,0127,0130,
+	0131,0132,0364,0365,0366,0367,0370,0371,
+	0060,0061,0062,0063,0064,0065,0066,0067,
+	0070,0071,0372,0373,0374,0375,0376,0377,
+};
+uchar	atoe[] =
+{
+	0000,0001,0002,0003,0067,0055,0056,0057,
+	0026,0005,0045,0013,0014,0015,0016,0017,
+	0020,0021,0022,0023,0074,0075,0062,0046,
+	0030,0031,0077,0047,0034,0035,0036,0037,
+	0100,0117,0177,0173,0133,0154,0120,0175,
+	0115,0135,0134,0116,0153,0140,0113,0141,
+	0360,0361,0362,0363,0364,0365,0366,0367,
+	0370,0371,0172,0136,0114,0176,0156,0157,
+	0174,0301,0302,0303,0304,0305,0306,0307,
+	0310,0311,0321,0322,0323,0324,0325,0326,
+	0327,0330,0331,0342,0343,0344,0345,0346,
+	0347,0350,0351,0112,0340,0132,0137,0155,
+	0171,0201,0202,0203,0204,0205,0206,0207,
+	0210,0211,0221,0222,0223,0224,0225,0226,
+	0227,0230,0231,0242,0243,0244,0245,0246,
+	0247,0250,0251,0300,0152,0320,0241,0007,
+	0040,0041,0042,0043,0044,0025,0006,0027,
+	0050,0051,0052,0053,0054,0011,0012,0033,
+	0060,0061,0032,0063,0064,0065,0066,0010,
+	0070,0071,0072,0073,0004,0024,0076,0341,
+	0101,0102,0103,0104,0105,0106,0107,0110,
+	0111,0121,0122,0123,0124,0125,0126,0127,
+	0130,0131,0142,0143,0144,0145,0146,0147,
+	0150,0151,0160,0161,0162,0163,0164,0165,
+	0166,0167,0170,0200,0212,0213,0214,0215,
+	0216,0217,0220,0232,0233,0234,0235,0236,
+	0237,0240,0252,0253,0254,0255,0256,0257,
+	0260,0261,0262,0263,0264,0265,0266,0267,
+	0270,0271,0272,0273,0274,0275,0276,0277,
+	0312,0313,0314,0315,0316,0317,0332,0333,
+	0334,0335,0336,0337,0352,0353,0354,0355,
+	0356,0357,0372,0373,0374,0375,0376,0377,
+};
+uchar	atoibm[] =
+{
+	0000,0001,0002,0003,0067,0055,0056,0057,
+	0026,0005,0045,0013,0014,0015,0016,0017,
+	0020,0021,0022,0023,0074,0075,0062,0046,
+	0030,0031,0077,0047,0034,0035,0036,0037,
+	0100,0132,0177,0173,0133,0154,0120,0175,
+	0115,0135,0134,0116,0153,0140,0113,0141,
+	0360,0361,0362,0363,0364,0365,0366,0367,
+	0370,0371,0172,0136,0114,0176,0156,0157,
+	0174,0301,0302,0303,0304,0305,0306,0307,
+	0310,0311,0321,0322,0323,0324,0325,0326,
+	0327,0330,0331,0342,0343,0344,0345,0346,
+	0347,0350,0351,0255,0340,0275,0137,0155,
+	0171,0201,0202,0203,0204,0205,0206,0207,
+	0210,0211,0221,0222,0223,0224,0225,0226,
+	0227,0230,0231,0242,0243,0244,0245,0246,
+	0247,0250,0251,0300,0117,0320,0241,0007,
+	0040,0041,0042,0043,0044,0025,0006,0027,
+	0050,0051,0052,0053,0054,0011,0012,0033,
+	0060,0061,0032,0063,0064,0065,0066,0010,
+	0070,0071,0072,0073,0004,0024,0076,0341,
+	0101,0102,0103,0104,0105,0106,0107,0110,
+	0111,0121,0122,0123,0124,0125,0126,0127,
+	0130,0131,0142,0143,0144,0145,0146,0147,
+	0150,0151,0160,0161,0162,0163,0164,0165,
+	0166,0167,0170,0200,0212,0213,0214,0215,
+	0216,0217,0220,0232,0233,0234,0235,0236,
+	0237,0240,0252,0253,0254,0255,0256,0257,
+	0260,0261,0262,0263,0264,0265,0266,0267,
+	0270,0271,0272,0273,0274,0275,0276,0277,
+	0312,0313,0314,0315,0316,0317,0332,0333,
+	0334,0335,0336,0337,0352,0353,0354,0355,
+	0356,0357,0372,0373,0374,0375,0376,0377,
+};