xref: /plan9/sys/src/cmd/dd.c (revision 3ff48bf5ed603850fcd251ddf13025d23d693782)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier 
43e12c5d1SDavid du Colombier #define	BIG	2147483647
53e12c5d1SDavid du Colombier #define	LCASE	(1<<0)
63e12c5d1SDavid du Colombier #define	UCASE	(1<<1)
73e12c5d1SDavid du Colombier #define	SWAB	(1<<2)
83e12c5d1SDavid du Colombier #define NERR	(1<<3)
93e12c5d1SDavid du Colombier #define SYNC	(1<<4)
103e12c5d1SDavid du Colombier int	cflag;
113e12c5d1SDavid du Colombier int	fflag;
123e12c5d1SDavid du Colombier char	*string;
133e12c5d1SDavid du Colombier char	*ifile;
143e12c5d1SDavid du Colombier char	*ofile;
153e12c5d1SDavid du Colombier char	*ibuf;
163e12c5d1SDavid du Colombier char	*obuf;
177dd7cddfSDavid du Colombier vlong	skip;
187dd7cddfSDavid du Colombier vlong	oseekn;
197dd7cddfSDavid du Colombier vlong	iseekn;
207dd7cddfSDavid du Colombier vlong	count;
213e12c5d1SDavid du Colombier long	files	= 1;
223e12c5d1SDavid du Colombier long	ibs	= 512;
233e12c5d1SDavid du Colombier long	obs	= 512;
243e12c5d1SDavid du Colombier long	bs;
253e12c5d1SDavid du Colombier long	cbs;
263e12c5d1SDavid du Colombier long	ibc;
273e12c5d1SDavid du Colombier long	obc;
283e12c5d1SDavid du Colombier long	cbc;
293e12c5d1SDavid du Colombier long	nifr;
303e12c5d1SDavid du Colombier long	nipr;
313e12c5d1SDavid du Colombier long	nofr;
323e12c5d1SDavid du Colombier long	nopr;
333e12c5d1SDavid du Colombier long	ntrunc;
349a747e4fSDavid du Colombier int dotrunc = 1;
353e12c5d1SDavid du Colombier int	ibf;
363e12c5d1SDavid du Colombier int	obf;
373e12c5d1SDavid du Colombier char	*op;
383e12c5d1SDavid du Colombier int	nspace;
393e12c5d1SDavid du Colombier uchar	etoa[256];
403e12c5d1SDavid du Colombier uchar	atoe[256];
413e12c5d1SDavid du Colombier uchar	atoibm[256];
423e12c5d1SDavid du Colombier 
433e12c5d1SDavid du Colombier void	flsh(void);
443e12c5d1SDavid du Colombier int	match(char *s);
457dd7cddfSDavid du Colombier vlong	number(long big);
463e12c5d1SDavid du Colombier void	cnull(int cc);
473e12c5d1SDavid du Colombier void	null(int c);
483e12c5d1SDavid du Colombier void	ascii(int cc);
493e12c5d1SDavid du Colombier void	unblock(int cc);
503e12c5d1SDavid du Colombier void	ebcdic(int cc);
513e12c5d1SDavid du Colombier void	ibm(int cc);
523e12c5d1SDavid du Colombier void	block(int cc);
533e12c5d1SDavid du Colombier void	term(void);
543e12c5d1SDavid du Colombier void	stats(void);
553e12c5d1SDavid du Colombier 
563e12c5d1SDavid du Colombier #define	iskey(s)	((key[0] == '-') && (strcmp(key+1, s) == 0))
573e12c5d1SDavid du Colombier 
583e12c5d1SDavid du Colombier int
593e12c5d1SDavid du Colombier main(int argc, char *argv[])
603e12c5d1SDavid du Colombier {
613e12c5d1SDavid du Colombier 	void (*conv)(int);
623e12c5d1SDavid du Colombier 	char *ip;
633e12c5d1SDavid du Colombier 	char *key;
643e12c5d1SDavid du Colombier 	int a, c;
653e12c5d1SDavid du Colombier 
663e12c5d1SDavid du Colombier 	conv = null;
673e12c5d1SDavid du Colombier 	for(c=1; c<argc; c++) {
683e12c5d1SDavid du Colombier 		key = argv[c++];
693e12c5d1SDavid du Colombier 		if(c >= argc){
70219b2ee8SDavid du Colombier 			fprint(2, "dd: arg %s needs a value\n", key);
713e12c5d1SDavid du Colombier 			exits("arg");
723e12c5d1SDavid du Colombier 		}
733e12c5d1SDavid du Colombier 		string = argv[c];
743e12c5d1SDavid du Colombier 		if(iskey("ibs")) {
753e12c5d1SDavid du Colombier 			ibs = number(BIG);
763e12c5d1SDavid du Colombier 			continue;
773e12c5d1SDavid du Colombier 		}
783e12c5d1SDavid du Colombier 		if(iskey("obs")) {
793e12c5d1SDavid du Colombier 			obs = number(BIG);
803e12c5d1SDavid du Colombier 			continue;
813e12c5d1SDavid du Colombier 		}
823e12c5d1SDavid du Colombier 		if(iskey("cbs")) {
833e12c5d1SDavid du Colombier 			cbs = number(BIG);
843e12c5d1SDavid du Colombier 			continue;
853e12c5d1SDavid du Colombier 		}
863e12c5d1SDavid du Colombier 		if(iskey("bs")) {
873e12c5d1SDavid du Colombier 			bs = number(BIG);
883e12c5d1SDavid du Colombier 			continue;
893e12c5d1SDavid du Colombier 		}
90219b2ee8SDavid du Colombier 		if(iskey("if")) {
913e12c5d1SDavid du Colombier 			ifile = string;
923e12c5d1SDavid du Colombier 			continue;
933e12c5d1SDavid du Colombier 		}
943e12c5d1SDavid du Colombier 		if(iskey("of")) {
953e12c5d1SDavid du Colombier 			ofile = string;
963e12c5d1SDavid du Colombier 			continue;
973e12c5d1SDavid du Colombier 		}
989a747e4fSDavid du Colombier 		if(iskey("trunc")) {
999a747e4fSDavid du Colombier 			dotrunc = number(BIG);
1009a747e4fSDavid du Colombier 			continue;
1019a747e4fSDavid du Colombier 		}
1023e12c5d1SDavid du Colombier 		if(iskey("skip")) {
1033e12c5d1SDavid du Colombier 			skip = number(BIG);
1043e12c5d1SDavid du Colombier 			continue;
1053e12c5d1SDavid du Colombier 		}
1063e12c5d1SDavid du Colombier 		if(iskey("seek") || iskey("oseek")) {
1073e12c5d1SDavid du Colombier 			oseekn = number(BIG);
1083e12c5d1SDavid du Colombier 			continue;
1093e12c5d1SDavid du Colombier 		}
1103e12c5d1SDavid du Colombier 		if(iskey("iseek")) {
1113e12c5d1SDavid du Colombier 			iseekn = number(BIG);
1123e12c5d1SDavid du Colombier 			continue;
1133e12c5d1SDavid du Colombier 		}
1143e12c5d1SDavid du Colombier 		if(iskey("count")) {
1153e12c5d1SDavid du Colombier 			count = number(BIG);
1163e12c5d1SDavid du Colombier 			continue;
1173e12c5d1SDavid du Colombier 		}
1183e12c5d1SDavid du Colombier 		if(iskey("files")) {
1193e12c5d1SDavid du Colombier 			files = number(BIG);
1203e12c5d1SDavid du Colombier 			continue;
1213e12c5d1SDavid du Colombier 		}
1223e12c5d1SDavid du Colombier 		if(iskey("conv")) {
1233e12c5d1SDavid du Colombier 		cloop:
1243e12c5d1SDavid du Colombier 			if(match(","))
1253e12c5d1SDavid du Colombier 				goto cloop;
1263e12c5d1SDavid du Colombier 			if(*string == '\0')
1273e12c5d1SDavid du Colombier 				continue;
1283e12c5d1SDavid du Colombier 			if(match("ebcdic")) {
1293e12c5d1SDavid du Colombier 				conv = ebcdic;
1303e12c5d1SDavid du Colombier 				goto cloop;
1313e12c5d1SDavid du Colombier 			}
1323e12c5d1SDavid du Colombier 			if(match("ibm")) {
1333e12c5d1SDavid du Colombier 				conv = ibm;
1343e12c5d1SDavid du Colombier 				goto cloop;
1353e12c5d1SDavid du Colombier 			}
1363e12c5d1SDavid du Colombier 			if(match("ascii")) {
1373e12c5d1SDavid du Colombier 				conv = ascii;
1383e12c5d1SDavid du Colombier 				goto cloop;
1393e12c5d1SDavid du Colombier 			}
1403e12c5d1SDavid du Colombier 			if(match("block")) {
1413e12c5d1SDavid du Colombier 				conv = block;
1423e12c5d1SDavid du Colombier 				goto cloop;
1433e12c5d1SDavid du Colombier 			}
1443e12c5d1SDavid du Colombier 			if(match("unblock")) {
1453e12c5d1SDavid du Colombier 				conv = unblock;
1463e12c5d1SDavid du Colombier 				goto cloop;
1473e12c5d1SDavid du Colombier 			}
1483e12c5d1SDavid du Colombier 			if(match("lcase")) {
1493e12c5d1SDavid du Colombier 				cflag |= LCASE;
1503e12c5d1SDavid du Colombier 				goto cloop;
1513e12c5d1SDavid du Colombier 			}
1523e12c5d1SDavid du Colombier 			if(match("ucase")) {
1533e12c5d1SDavid du Colombier 				cflag |= UCASE;
1543e12c5d1SDavid du Colombier 				goto cloop;
1553e12c5d1SDavid du Colombier 			}
1563e12c5d1SDavid du Colombier 			if(match("swab")) {
1573e12c5d1SDavid du Colombier 				cflag |= SWAB;
1583e12c5d1SDavid du Colombier 				goto cloop;
1593e12c5d1SDavid du Colombier 			}
1603e12c5d1SDavid du Colombier 			if(match("noerror")) {
1613e12c5d1SDavid du Colombier 				cflag |= NERR;
1623e12c5d1SDavid du Colombier 				goto cloop;
1633e12c5d1SDavid du Colombier 			}
1643e12c5d1SDavid du Colombier 			if(match("sync")) {
1653e12c5d1SDavid du Colombier 				cflag |= SYNC;
1663e12c5d1SDavid du Colombier 				goto cloop;
1673e12c5d1SDavid du Colombier 			}
1683e12c5d1SDavid du Colombier 		}
169219b2ee8SDavid du Colombier 		fprint(2, "dd: bad arg: %s\n", key);
1703e12c5d1SDavid du Colombier 		exits("arg");
1713e12c5d1SDavid du Colombier 	}
1723e12c5d1SDavid du Colombier 	if(conv == null && cflag&(LCASE|UCASE))
1733e12c5d1SDavid du Colombier 		conv = cnull;
1743e12c5d1SDavid du Colombier 	if(ifile)
1753e12c5d1SDavid du Colombier 		ibf = open(ifile, 0);
1763e12c5d1SDavid du Colombier 	else
1773e12c5d1SDavid du Colombier 		ibf = dup(0, -1);
1783e12c5d1SDavid du Colombier 	if(ibf < 0) {
179219b2ee8SDavid du Colombier 		fprint(2, "dd: open %s: %r\n", ifile);
1803e12c5d1SDavid du Colombier 		exits("open");
1813e12c5d1SDavid du Colombier 	}
182219b2ee8SDavid du Colombier 	if(ofile){
1839a747e4fSDavid du Colombier 		if(dotrunc)
1843e12c5d1SDavid du Colombier 			obf = create(ofile, 1, 0664);
1859a747e4fSDavid du Colombier 		else
1869a747e4fSDavid du Colombier 			obf = open(ofile, 1);
187219b2ee8SDavid du Colombier 		if(obf < 0) {
188219b2ee8SDavid du Colombier 			fprint(2, "dd: create %s: %r\n", ofile);
189219b2ee8SDavid du Colombier 			exits("create");
190219b2ee8SDavid du Colombier 		}
191219b2ee8SDavid du Colombier 	}else{
1923e12c5d1SDavid du Colombier 		obf = dup(1, -1);
1933e12c5d1SDavid du Colombier 		if(obf < 0) {
1947dd7cddfSDavid du Colombier 			fprint(2, "dd: can't dup file descriptor: %s: %r\n", ofile);
195219b2ee8SDavid du Colombier 			exits("dup");
196219b2ee8SDavid du Colombier 		}
1973e12c5d1SDavid du Colombier 	}
1983e12c5d1SDavid du Colombier 	if(bs)
1993e12c5d1SDavid du Colombier 		ibs = obs = bs;
2003e12c5d1SDavid du Colombier 	if(ibs == obs && conv == null)
2013e12c5d1SDavid du Colombier 		fflag++;
2023e12c5d1SDavid du Colombier 	if(ibs == 0 || obs == 0) {
203219b2ee8SDavid du Colombier 		fprint(2, "dd: counts: cannot be zero\n");
2043e12c5d1SDavid du Colombier 		exits("counts");
2053e12c5d1SDavid du Colombier 	}
2063e12c5d1SDavid du Colombier 	ibuf = sbrk(ibs);
2073e12c5d1SDavid du Colombier 	if(fflag)
2083e12c5d1SDavid du Colombier 		obuf = ibuf;
2093e12c5d1SDavid du Colombier 	else
2103e12c5d1SDavid du Colombier 		obuf = sbrk(obs);
2113e12c5d1SDavid du Colombier 	sbrk(64);	/* For good measure */
2123e12c5d1SDavid du Colombier 	if(ibuf == (char *)-1 || obuf == (char *)-1) {
213219b2ee8SDavid du Colombier 		fprint(2, "dd: not enough memory: %r\n");
2143e12c5d1SDavid du Colombier 		exits("memory");
2153e12c5d1SDavid du Colombier 	}
2163e12c5d1SDavid du Colombier 	ibc = 0;
2173e12c5d1SDavid du Colombier 	obc = 0;
2183e12c5d1SDavid du Colombier 	cbc = 0;
2193e12c5d1SDavid du Colombier 	op = obuf;
2203e12c5d1SDavid du Colombier 
2213e12c5d1SDavid du Colombier /*
2223e12c5d1SDavid du Colombier 	if(signal(SIGINT, SIG_IGN) != SIG_IGN)
2233e12c5d1SDavid du Colombier 		signal(SIGINT, term);
2243e12c5d1SDavid du Colombier */
2253e12c5d1SDavid du Colombier 	seek(obf, obs*oseekn, 1);
2263e12c5d1SDavid du Colombier 	seek(ibf, ibs*iseekn, 1);
2273e12c5d1SDavid du Colombier 	while(skip) {
2283e12c5d1SDavid du Colombier 		read(ibf, ibuf, ibs);
2293e12c5d1SDavid du Colombier 		skip--;
2303e12c5d1SDavid du Colombier 	}
2313e12c5d1SDavid du Colombier 
232219b2ee8SDavid du Colombier 	ip = 0;
2333e12c5d1SDavid du Colombier loop:
2343e12c5d1SDavid du Colombier 	if(ibc-- == 0) {
2353e12c5d1SDavid du Colombier 		ibc = 0;
2363e12c5d1SDavid du Colombier 		if(count==0 || nifr+nipr!=count) {
2373e12c5d1SDavid du Colombier 			if(cflag&(NERR|SYNC))
2383e12c5d1SDavid du Colombier 			for(ip=ibuf+ibs; ip>ibuf;)
2393e12c5d1SDavid du Colombier 				*--ip = 0;
2403e12c5d1SDavid du Colombier 			ibc = read(ibf, ibuf, ibs);
2413e12c5d1SDavid du Colombier 		}
2423e12c5d1SDavid du Colombier 		if(ibc == -1) {
2433e12c5d1SDavid du Colombier 			perror("read");
2443e12c5d1SDavid du Colombier 			if((cflag&NERR) == 0) {
2453e12c5d1SDavid du Colombier 				flsh();
2463e12c5d1SDavid du Colombier 				term();
2473e12c5d1SDavid du Colombier 			}
2483e12c5d1SDavid du Colombier 			ibc = 0;
2493e12c5d1SDavid du Colombier 			for(c=0; c<ibs; c++)
2503e12c5d1SDavid du Colombier 				if(ibuf[c] != 0)
2513e12c5d1SDavid du Colombier 					ibc = c;
2523e12c5d1SDavid du Colombier 			stats();
2533e12c5d1SDavid du Colombier 		}
2543e12c5d1SDavid du Colombier 		if(ibc == 0 && --files<=0) {
2553e12c5d1SDavid du Colombier 			flsh();
2563e12c5d1SDavid du Colombier 			term();
2573e12c5d1SDavid du Colombier 		}
2583e12c5d1SDavid du Colombier 		if(ibc != ibs) {
2593e12c5d1SDavid du Colombier 			nipr++;
2603e12c5d1SDavid du Colombier 			if(cflag&SYNC)
2613e12c5d1SDavid du Colombier 				ibc = ibs;
2623e12c5d1SDavid du Colombier 		} else
2633e12c5d1SDavid du Colombier 			nifr++;
2643e12c5d1SDavid du Colombier 		ip = ibuf;
2653e12c5d1SDavid du Colombier 		c = (ibc>>1) & ~1;
2663e12c5d1SDavid du Colombier 		if(cflag&SWAB && c)
2673e12c5d1SDavid du Colombier 		do {
2683e12c5d1SDavid du Colombier 			a = *ip++;
2693e12c5d1SDavid du Colombier 			ip[-1] = *ip;
2703e12c5d1SDavid du Colombier 			*ip++ = a;
2713e12c5d1SDavid du Colombier 		} while(--c);
2723e12c5d1SDavid du Colombier 		ip = ibuf;
2733e12c5d1SDavid du Colombier 		if(fflag) {
2743e12c5d1SDavid du Colombier 			obc = ibc;
2753e12c5d1SDavid du Colombier 			flsh();
2763e12c5d1SDavid du Colombier 			ibc = 0;
2773e12c5d1SDavid du Colombier 		}
2783e12c5d1SDavid du Colombier 		goto loop;
2793e12c5d1SDavid du Colombier 	}
2803e12c5d1SDavid du Colombier 	c = 0;
2813e12c5d1SDavid du Colombier 	c |= *ip++;
2823e12c5d1SDavid du Colombier 	c &= 0377;
2833e12c5d1SDavid du Colombier 	(*conv)(c);
2843e12c5d1SDavid du Colombier 	goto loop;
2853e12c5d1SDavid du Colombier }
2863e12c5d1SDavid du Colombier 
2873e12c5d1SDavid du Colombier void
2883e12c5d1SDavid du Colombier flsh(void)
2893e12c5d1SDavid du Colombier {
2903e12c5d1SDavid du Colombier 	int c;
2913e12c5d1SDavid du Colombier 
2923e12c5d1SDavid du Colombier 	if(obc) {
2933e12c5d1SDavid du Colombier 		c = write(obf, obuf, obc);
2943e12c5d1SDavid du Colombier 		if(c != obc) {
295*3ff48bf5SDavid du Colombier 			if(c > 0)
296*3ff48bf5SDavid du Colombier 				++nopr;
2973e12c5d1SDavid du Colombier 			perror("write");
2983e12c5d1SDavid du Colombier 			term();
2993e12c5d1SDavid du Colombier 		}
300*3ff48bf5SDavid du Colombier 		if(obc == obs)
301*3ff48bf5SDavid du Colombier 			nofr++;
302*3ff48bf5SDavid du Colombier 		else
303*3ff48bf5SDavid du Colombier 			nopr++;
3043e12c5d1SDavid du Colombier 		obc = 0;
3053e12c5d1SDavid du Colombier 	}
3063e12c5d1SDavid du Colombier }
3073e12c5d1SDavid du Colombier 
3083e12c5d1SDavid du Colombier int
3093e12c5d1SDavid du Colombier match(char *s)
3103e12c5d1SDavid du Colombier {
3113e12c5d1SDavid du Colombier 	char *cs;
3123e12c5d1SDavid du Colombier 
3133e12c5d1SDavid du Colombier 	cs = string;
3143e12c5d1SDavid du Colombier 	while(*cs++ == *s)
3153e12c5d1SDavid du Colombier 		if(*s++ == '\0')
3163e12c5d1SDavid du Colombier 			goto true;
3173e12c5d1SDavid du Colombier 	if(*s != '\0')
3183e12c5d1SDavid du Colombier 		return 0;
3193e12c5d1SDavid du Colombier 
3203e12c5d1SDavid du Colombier true:
3213e12c5d1SDavid du Colombier 	cs--;
3223e12c5d1SDavid du Colombier 	string = cs;
3233e12c5d1SDavid du Colombier 	return 1;
3243e12c5d1SDavid du Colombier }
3253e12c5d1SDavid du Colombier 
3267dd7cddfSDavid du Colombier vlong
3273e12c5d1SDavid du Colombier number(long big)
3283e12c5d1SDavid du Colombier {
3293e12c5d1SDavid du Colombier 	char *cs;
3307dd7cddfSDavid du Colombier 	vlong n;
3313e12c5d1SDavid du Colombier 
3323e12c5d1SDavid du Colombier 	cs = string;
3333e12c5d1SDavid du Colombier 	n = 0;
3343e12c5d1SDavid du Colombier 	while(*cs >= '0' && *cs <= '9')
3353e12c5d1SDavid du Colombier 		n = n*10 + *cs++ - '0';
3363e12c5d1SDavid du Colombier 	for(;;)
3373e12c5d1SDavid du Colombier 	switch(*cs++) {
3383e12c5d1SDavid du Colombier 
3393e12c5d1SDavid du Colombier 	case 'k':
3403e12c5d1SDavid du Colombier 		n *= 1024;
3413e12c5d1SDavid du Colombier 		continue;
3423e12c5d1SDavid du Colombier 
3433e12c5d1SDavid du Colombier /*	case 'w':
3443e12c5d1SDavid du Colombier 		n *= sizeof(int);
3453e12c5d1SDavid du Colombier 		continue;
3463e12c5d1SDavid du Colombier */
3473e12c5d1SDavid du Colombier 
3483e12c5d1SDavid du Colombier 	case 'b':
3493e12c5d1SDavid du Colombier 		n *= 512;
3503e12c5d1SDavid du Colombier 		continue;
3513e12c5d1SDavid du Colombier 
3523e12c5d1SDavid du Colombier /*	case '*':*/
3533e12c5d1SDavid du Colombier 	case 'x':
3543e12c5d1SDavid du Colombier 		string = cs;
3553e12c5d1SDavid du Colombier 		n *= number(BIG);
3563e12c5d1SDavid du Colombier 
3573e12c5d1SDavid du Colombier 	case '\0':
3583e12c5d1SDavid du Colombier 		if(n>=big || n<0) {
3597dd7cddfSDavid du Colombier 			fprint(2, "dd: argument %lld out of range\n", n);
3603e12c5d1SDavid du Colombier 			exits("range");
3613e12c5d1SDavid du Colombier 		}
3623e12c5d1SDavid du Colombier 		return n;
3633e12c5d1SDavid du Colombier 	}
3643e12c5d1SDavid du Colombier 	/* never gets here */
3653e12c5d1SDavid du Colombier }
3663e12c5d1SDavid du Colombier 
3673e12c5d1SDavid du Colombier void
3683e12c5d1SDavid du Colombier cnull(int cc)
3693e12c5d1SDavid du Colombier {
3703e12c5d1SDavid du Colombier 	int c;
3713e12c5d1SDavid du Colombier 
3723e12c5d1SDavid du Colombier 	c = cc;
3733e12c5d1SDavid du Colombier 	if((cflag&UCASE) && c>='a' && c<='z')
3743e12c5d1SDavid du Colombier 		c += 'A'-'a';
3753e12c5d1SDavid du Colombier 	if((cflag&LCASE) && c>='A' && c<='Z')
3763e12c5d1SDavid du Colombier 		c += 'a'-'A';
3773e12c5d1SDavid du Colombier 	null(c);
3783e12c5d1SDavid du Colombier }
3793e12c5d1SDavid du Colombier 
3803e12c5d1SDavid du Colombier void
3813e12c5d1SDavid du Colombier null(int c)
3823e12c5d1SDavid du Colombier {
3833e12c5d1SDavid du Colombier 
3843e12c5d1SDavid du Colombier 	*op = c;
3853e12c5d1SDavid du Colombier 	op++;
3863e12c5d1SDavid du Colombier 	if(++obc >= obs) {
3873e12c5d1SDavid du Colombier 		flsh();
3883e12c5d1SDavid du Colombier 		op = obuf;
3893e12c5d1SDavid du Colombier 	}
3903e12c5d1SDavid du Colombier }
3913e12c5d1SDavid du Colombier 
3923e12c5d1SDavid du Colombier void
3933e12c5d1SDavid du Colombier ascii(int cc)
3943e12c5d1SDavid du Colombier {
3953e12c5d1SDavid du Colombier 	int c;
3963e12c5d1SDavid du Colombier 
3973e12c5d1SDavid du Colombier 	c = etoa[cc];
3983e12c5d1SDavid du Colombier 	if(cbs == 0) {
3993e12c5d1SDavid du Colombier 		cnull(c);
4003e12c5d1SDavid du Colombier 		return;
4013e12c5d1SDavid du Colombier 	}
4023e12c5d1SDavid du Colombier 	if(c == ' ') {
4033e12c5d1SDavid du Colombier 		nspace++;
4043e12c5d1SDavid du Colombier 		goto out;
4053e12c5d1SDavid du Colombier 	}
4063e12c5d1SDavid du Colombier 	while(nspace > 0) {
4073e12c5d1SDavid du Colombier 		null(' ');
4083e12c5d1SDavid du Colombier 		nspace--;
4093e12c5d1SDavid du Colombier 	}
4103e12c5d1SDavid du Colombier 	cnull(c);
4113e12c5d1SDavid du Colombier 
4123e12c5d1SDavid du Colombier out:
4133e12c5d1SDavid du Colombier 	if(++cbc >= cbs) {
4143e12c5d1SDavid du Colombier 		null('\n');
4153e12c5d1SDavid du Colombier 		cbc = 0;
4163e12c5d1SDavid du Colombier 		nspace = 0;
4173e12c5d1SDavid du Colombier 	}
4183e12c5d1SDavid du Colombier }
4193e12c5d1SDavid du Colombier 
4203e12c5d1SDavid du Colombier void
4213e12c5d1SDavid du Colombier unblock(int cc)
4223e12c5d1SDavid du Colombier {
4233e12c5d1SDavid du Colombier 	int c;
4243e12c5d1SDavid du Colombier 
4253e12c5d1SDavid du Colombier 	c = cc & 0377;
4263e12c5d1SDavid du Colombier 	if(cbs == 0) {
4273e12c5d1SDavid du Colombier 		cnull(c);
4283e12c5d1SDavid du Colombier 		return;
4293e12c5d1SDavid du Colombier 	}
4303e12c5d1SDavid du Colombier 	if(c == ' ') {
4313e12c5d1SDavid du Colombier 		nspace++;
4323e12c5d1SDavid du Colombier 		goto out;
4333e12c5d1SDavid du Colombier 	}
4343e12c5d1SDavid du Colombier 	while(nspace > 0) {
4353e12c5d1SDavid du Colombier 		null(' ');
4363e12c5d1SDavid du Colombier 		nspace--;
4373e12c5d1SDavid du Colombier 	}
4383e12c5d1SDavid du Colombier 	cnull(c);
4393e12c5d1SDavid du Colombier 
4403e12c5d1SDavid du Colombier out:
4413e12c5d1SDavid du Colombier 	if(++cbc >= cbs) {
4423e12c5d1SDavid du Colombier 		null('\n');
4433e12c5d1SDavid du Colombier 		cbc = 0;
4443e12c5d1SDavid du Colombier 		nspace = 0;
4453e12c5d1SDavid du Colombier 	}
4463e12c5d1SDavid du Colombier }
4473e12c5d1SDavid du Colombier 
4483e12c5d1SDavid du Colombier void
4493e12c5d1SDavid du Colombier ebcdic(int cc)
4503e12c5d1SDavid du Colombier {
4513e12c5d1SDavid du Colombier 	int c;
4523e12c5d1SDavid du Colombier 
4533e12c5d1SDavid du Colombier 	c = cc;
4543e12c5d1SDavid du Colombier 	if(cflag&UCASE && c>='a' && c<='z')
4553e12c5d1SDavid du Colombier 		c += 'A'-'a';
4563e12c5d1SDavid du Colombier 	if(cflag&LCASE && c>='A' && c<='Z')
4573e12c5d1SDavid du Colombier 		c += 'a'-'A';
4583e12c5d1SDavid du Colombier 	c = atoe[c];
4593e12c5d1SDavid du Colombier 	if(cbs == 0) {
4603e12c5d1SDavid du Colombier 		null(c);
4613e12c5d1SDavid du Colombier 		return;
4623e12c5d1SDavid du Colombier 	}
4633e12c5d1SDavid du Colombier 	if(cc == '\n') {
4643e12c5d1SDavid du Colombier 		while(cbc < cbs) {
4653e12c5d1SDavid du Colombier 			null(atoe[' ']);
4663e12c5d1SDavid du Colombier 			cbc++;
4673e12c5d1SDavid du Colombier 		}
4683e12c5d1SDavid du Colombier 		cbc = 0;
4693e12c5d1SDavid du Colombier 		return;
4703e12c5d1SDavid du Colombier 	}
4713e12c5d1SDavid du Colombier 	if(cbc == cbs)
4723e12c5d1SDavid du Colombier 		ntrunc++;
4733e12c5d1SDavid du Colombier 	cbc++;
4743e12c5d1SDavid du Colombier 	if(cbc <= cbs)
4753e12c5d1SDavid du Colombier 		null(c);
4763e12c5d1SDavid du Colombier }
4773e12c5d1SDavid du Colombier 
4783e12c5d1SDavid du Colombier void
4793e12c5d1SDavid du Colombier ibm(int cc)
4803e12c5d1SDavid du Colombier {
4813e12c5d1SDavid du Colombier 	int c;
4823e12c5d1SDavid du Colombier 
4833e12c5d1SDavid du Colombier 	c = cc;
4843e12c5d1SDavid du Colombier 	if(cflag&UCASE && c>='a' && c<='z')
4853e12c5d1SDavid du Colombier 		c += 'A'-'a';
4863e12c5d1SDavid du Colombier 	if(cflag&LCASE && c>='A' && c<='Z')
4873e12c5d1SDavid du Colombier 		c += 'a'-'A';
4883e12c5d1SDavid du Colombier 	c = atoibm[c] & 0377;
4893e12c5d1SDavid du Colombier 	if(cbs == 0) {
4903e12c5d1SDavid du Colombier 		null(c);
4913e12c5d1SDavid du Colombier 		return;
4923e12c5d1SDavid du Colombier 	}
4933e12c5d1SDavid du Colombier 	if(cc == '\n') {
4943e12c5d1SDavid du Colombier 		while(cbc < cbs) {
4953e12c5d1SDavid du Colombier 			null(atoibm[' ']);
4963e12c5d1SDavid du Colombier 			cbc++;
4973e12c5d1SDavid du Colombier 		}
4983e12c5d1SDavid du Colombier 		cbc = 0;
4993e12c5d1SDavid du Colombier 		return;
5003e12c5d1SDavid du Colombier 	}
5013e12c5d1SDavid du Colombier 	if(cbc == cbs)
5023e12c5d1SDavid du Colombier 		ntrunc++;
5033e12c5d1SDavid du Colombier 	cbc++;
5043e12c5d1SDavid du Colombier 	if(cbc <= cbs)
5053e12c5d1SDavid du Colombier 		null(c);
5063e12c5d1SDavid du Colombier }
5073e12c5d1SDavid du Colombier 
5083e12c5d1SDavid du Colombier void
5093e12c5d1SDavid du Colombier block(int cc)
5103e12c5d1SDavid du Colombier {
5113e12c5d1SDavid du Colombier 	int c;
5123e12c5d1SDavid du Colombier 
5133e12c5d1SDavid du Colombier 	c = cc;
5143e12c5d1SDavid du Colombier 	if(cflag&UCASE && c>='a' && c<='z')
5153e12c5d1SDavid du Colombier 		c += 'A'-'a';
5163e12c5d1SDavid du Colombier 	if(cflag&LCASE && c>='A' && c<='Z')
5173e12c5d1SDavid du Colombier 		c += 'a'-'A';
5183e12c5d1SDavid du Colombier 	c &= 0377;
5193e12c5d1SDavid du Colombier 	if(cbs == 0) {
5203e12c5d1SDavid du Colombier 		null(c);
5213e12c5d1SDavid du Colombier 		return;
5223e12c5d1SDavid du Colombier 	}
5233e12c5d1SDavid du Colombier 	if(cc == '\n') {
5243e12c5d1SDavid du Colombier 		while(cbc < cbs) {
5253e12c5d1SDavid du Colombier 			null(' ');
5263e12c5d1SDavid du Colombier 			cbc++;
5273e12c5d1SDavid du Colombier 		}
5283e12c5d1SDavid du Colombier 		cbc = 0;
5293e12c5d1SDavid du Colombier 		return;
5303e12c5d1SDavid du Colombier 	}
5313e12c5d1SDavid du Colombier 	if(cbc == cbs)
5323e12c5d1SDavid du Colombier 		ntrunc++;
5333e12c5d1SDavid du Colombier 	cbc++;
5343e12c5d1SDavid du Colombier 	if(cbc <= cbs)
5353e12c5d1SDavid du Colombier 		null(c);
5363e12c5d1SDavid du Colombier }
5373e12c5d1SDavid du Colombier 
5383e12c5d1SDavid du Colombier void
5393e12c5d1SDavid du Colombier term(void)
5403e12c5d1SDavid du Colombier {
5413e12c5d1SDavid du Colombier 
5423e12c5d1SDavid du Colombier 	stats();
5433e12c5d1SDavid du Colombier 	exits(0);
5443e12c5d1SDavid du Colombier }
5453e12c5d1SDavid du Colombier 
5463e12c5d1SDavid du Colombier void
5473e12c5d1SDavid du Colombier stats(void)
5483e12c5d1SDavid du Colombier {
5493e12c5d1SDavid du Colombier 
5503e12c5d1SDavid du Colombier 	fprint(2, "%lud+%lud records in\n", nifr, nipr);
5513e12c5d1SDavid du Colombier 	fprint(2, "%lud+%lud records out\n", nofr, nopr);
5523e12c5d1SDavid du Colombier 	if(ntrunc)
5533e12c5d1SDavid du Colombier 		fprint(2, "%lud truncated records\n", ntrunc);
5543e12c5d1SDavid du Colombier }
5553e12c5d1SDavid du Colombier 
5563e12c5d1SDavid du Colombier uchar	etoa[] =
5573e12c5d1SDavid du Colombier {
5583e12c5d1SDavid du Colombier 	0000,0001,0002,0003,0234,0011,0206,0177,
5593e12c5d1SDavid du Colombier 	0227,0215,0216,0013,0014,0015,0016,0017,
5603e12c5d1SDavid du Colombier 	0020,0021,0022,0023,0235,0205,0010,0207,
5613e12c5d1SDavid du Colombier 	0030,0031,0222,0217,0034,0035,0036,0037,
5623e12c5d1SDavid du Colombier 	0200,0201,0202,0203,0204,0012,0027,0033,
5633e12c5d1SDavid du Colombier 	0210,0211,0212,0213,0214,0005,0006,0007,
5643e12c5d1SDavid du Colombier 	0220,0221,0026,0223,0224,0225,0226,0004,
5653e12c5d1SDavid du Colombier 	0230,0231,0232,0233,0024,0025,0236,0032,
5663e12c5d1SDavid du Colombier 	0040,0240,0241,0242,0243,0244,0245,0246,
5673e12c5d1SDavid du Colombier 	0247,0250,0133,0056,0074,0050,0053,0041,
5683e12c5d1SDavid du Colombier 	0046,0251,0252,0253,0254,0255,0256,0257,
5693e12c5d1SDavid du Colombier 	0260,0261,0135,0044,0052,0051,0073,0136,
5703e12c5d1SDavid du Colombier 	0055,0057,0262,0263,0264,0265,0266,0267,
5713e12c5d1SDavid du Colombier 	0270,0271,0174,0054,0045,0137,0076,0077,
5723e12c5d1SDavid du Colombier 	0272,0273,0274,0275,0276,0277,0300,0301,
5733e12c5d1SDavid du Colombier 	0302,0140,0072,0043,0100,0047,0075,0042,
5743e12c5d1SDavid du Colombier 	0303,0141,0142,0143,0144,0145,0146,0147,
5753e12c5d1SDavid du Colombier 	0150,0151,0304,0305,0306,0307,0310,0311,
5763e12c5d1SDavid du Colombier 	0312,0152,0153,0154,0155,0156,0157,0160,
5773e12c5d1SDavid du Colombier 	0161,0162,0313,0314,0315,0316,0317,0320,
5783e12c5d1SDavid du Colombier 	0321,0176,0163,0164,0165,0166,0167,0170,
5793e12c5d1SDavid du Colombier 	0171,0172,0322,0323,0324,0325,0326,0327,
5803e12c5d1SDavid du Colombier 	0330,0331,0332,0333,0334,0335,0336,0337,
5813e12c5d1SDavid du Colombier 	0340,0341,0342,0343,0344,0345,0346,0347,
5823e12c5d1SDavid du Colombier 	0173,0101,0102,0103,0104,0105,0106,0107,
5833e12c5d1SDavid du Colombier 	0110,0111,0350,0351,0352,0353,0354,0355,
5843e12c5d1SDavid du Colombier 	0175,0112,0113,0114,0115,0116,0117,0120,
5853e12c5d1SDavid du Colombier 	0121,0122,0356,0357,0360,0361,0362,0363,
5863e12c5d1SDavid du Colombier 	0134,0237,0123,0124,0125,0126,0127,0130,
5873e12c5d1SDavid du Colombier 	0131,0132,0364,0365,0366,0367,0370,0371,
5883e12c5d1SDavid du Colombier 	0060,0061,0062,0063,0064,0065,0066,0067,
5893e12c5d1SDavid du Colombier 	0070,0071,0372,0373,0374,0375,0376,0377,
5903e12c5d1SDavid du Colombier };
5913e12c5d1SDavid du Colombier uchar	atoe[] =
5923e12c5d1SDavid du Colombier {
5933e12c5d1SDavid du Colombier 	0000,0001,0002,0003,0067,0055,0056,0057,
5943e12c5d1SDavid du Colombier 	0026,0005,0045,0013,0014,0015,0016,0017,
5953e12c5d1SDavid du Colombier 	0020,0021,0022,0023,0074,0075,0062,0046,
5963e12c5d1SDavid du Colombier 	0030,0031,0077,0047,0034,0035,0036,0037,
5973e12c5d1SDavid du Colombier 	0100,0117,0177,0173,0133,0154,0120,0175,
5983e12c5d1SDavid du Colombier 	0115,0135,0134,0116,0153,0140,0113,0141,
5993e12c5d1SDavid du Colombier 	0360,0361,0362,0363,0364,0365,0366,0367,
6003e12c5d1SDavid du Colombier 	0370,0371,0172,0136,0114,0176,0156,0157,
6013e12c5d1SDavid du Colombier 	0174,0301,0302,0303,0304,0305,0306,0307,
6023e12c5d1SDavid du Colombier 	0310,0311,0321,0322,0323,0324,0325,0326,
6033e12c5d1SDavid du Colombier 	0327,0330,0331,0342,0343,0344,0345,0346,
6043e12c5d1SDavid du Colombier 	0347,0350,0351,0112,0340,0132,0137,0155,
6053e12c5d1SDavid du Colombier 	0171,0201,0202,0203,0204,0205,0206,0207,
6063e12c5d1SDavid du Colombier 	0210,0211,0221,0222,0223,0224,0225,0226,
6073e12c5d1SDavid du Colombier 	0227,0230,0231,0242,0243,0244,0245,0246,
6083e12c5d1SDavid du Colombier 	0247,0250,0251,0300,0152,0320,0241,0007,
6093e12c5d1SDavid du Colombier 	0040,0041,0042,0043,0044,0025,0006,0027,
6103e12c5d1SDavid du Colombier 	0050,0051,0052,0053,0054,0011,0012,0033,
6113e12c5d1SDavid du Colombier 	0060,0061,0032,0063,0064,0065,0066,0010,
6123e12c5d1SDavid du Colombier 	0070,0071,0072,0073,0004,0024,0076,0341,
6133e12c5d1SDavid du Colombier 	0101,0102,0103,0104,0105,0106,0107,0110,
6143e12c5d1SDavid du Colombier 	0111,0121,0122,0123,0124,0125,0126,0127,
6153e12c5d1SDavid du Colombier 	0130,0131,0142,0143,0144,0145,0146,0147,
6163e12c5d1SDavid du Colombier 	0150,0151,0160,0161,0162,0163,0164,0165,
6173e12c5d1SDavid du Colombier 	0166,0167,0170,0200,0212,0213,0214,0215,
6183e12c5d1SDavid du Colombier 	0216,0217,0220,0232,0233,0234,0235,0236,
6193e12c5d1SDavid du Colombier 	0237,0240,0252,0253,0254,0255,0256,0257,
6203e12c5d1SDavid du Colombier 	0260,0261,0262,0263,0264,0265,0266,0267,
6213e12c5d1SDavid du Colombier 	0270,0271,0272,0273,0274,0275,0276,0277,
6223e12c5d1SDavid du Colombier 	0312,0313,0314,0315,0316,0317,0332,0333,
6233e12c5d1SDavid du Colombier 	0334,0335,0336,0337,0352,0353,0354,0355,
6243e12c5d1SDavid du Colombier 	0356,0357,0372,0373,0374,0375,0376,0377,
6253e12c5d1SDavid du Colombier };
6263e12c5d1SDavid du Colombier uchar	atoibm[] =
6273e12c5d1SDavid du Colombier {
6283e12c5d1SDavid du Colombier 	0000,0001,0002,0003,0067,0055,0056,0057,
6293e12c5d1SDavid du Colombier 	0026,0005,0045,0013,0014,0015,0016,0017,
6303e12c5d1SDavid du Colombier 	0020,0021,0022,0023,0074,0075,0062,0046,
6313e12c5d1SDavid du Colombier 	0030,0031,0077,0047,0034,0035,0036,0037,
6323e12c5d1SDavid du Colombier 	0100,0132,0177,0173,0133,0154,0120,0175,
6333e12c5d1SDavid du Colombier 	0115,0135,0134,0116,0153,0140,0113,0141,
6343e12c5d1SDavid du Colombier 	0360,0361,0362,0363,0364,0365,0366,0367,
6353e12c5d1SDavid du Colombier 	0370,0371,0172,0136,0114,0176,0156,0157,
6363e12c5d1SDavid du Colombier 	0174,0301,0302,0303,0304,0305,0306,0307,
6373e12c5d1SDavid du Colombier 	0310,0311,0321,0322,0323,0324,0325,0326,
6383e12c5d1SDavid du Colombier 	0327,0330,0331,0342,0343,0344,0345,0346,
6393e12c5d1SDavid du Colombier 	0347,0350,0351,0255,0340,0275,0137,0155,
6403e12c5d1SDavid du Colombier 	0171,0201,0202,0203,0204,0205,0206,0207,
6413e12c5d1SDavid du Colombier 	0210,0211,0221,0222,0223,0224,0225,0226,
6423e12c5d1SDavid du Colombier 	0227,0230,0231,0242,0243,0244,0245,0246,
6433e12c5d1SDavid du Colombier 	0247,0250,0251,0300,0117,0320,0241,0007,
6443e12c5d1SDavid du Colombier 	0040,0041,0042,0043,0044,0025,0006,0027,
6453e12c5d1SDavid du Colombier 	0050,0051,0052,0053,0054,0011,0012,0033,
6463e12c5d1SDavid du Colombier 	0060,0061,0032,0063,0064,0065,0066,0010,
6473e12c5d1SDavid du Colombier 	0070,0071,0072,0073,0004,0024,0076,0341,
6483e12c5d1SDavid du Colombier 	0101,0102,0103,0104,0105,0106,0107,0110,
6493e12c5d1SDavid du Colombier 	0111,0121,0122,0123,0124,0125,0126,0127,
6503e12c5d1SDavid du Colombier 	0130,0131,0142,0143,0144,0145,0146,0147,
6513e12c5d1SDavid du Colombier 	0150,0151,0160,0161,0162,0163,0164,0165,
6523e12c5d1SDavid du Colombier 	0166,0167,0170,0200,0212,0213,0214,0215,
6533e12c5d1SDavid du Colombier 	0216,0217,0220,0232,0233,0234,0235,0236,
6543e12c5d1SDavid du Colombier 	0237,0240,0252,0253,0254,0255,0256,0257,
6553e12c5d1SDavid du Colombier 	0260,0261,0262,0263,0264,0265,0266,0267,
6563e12c5d1SDavid du Colombier 	0270,0271,0272,0273,0274,0275,0276,0277,
6573e12c5d1SDavid du Colombier 	0312,0313,0314,0315,0316,0317,0332,0333,
6583e12c5d1SDavid du Colombier 	0334,0335,0336,0337,0352,0353,0354,0355,
6593e12c5d1SDavid du Colombier 	0356,0357,0372,0373,0374,0375,0376,0377,
6603e12c5d1SDavid du Colombier };
661