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